blob: 00e33bef10b0d7025ec04a0ebcbde35389b81288 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/ClangExpressionDeclMap.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Sean Callanan47a5c4c2010-09-23 03:01:22 +000016#include "clang/AST/DeclarationName.h"
Sean Callanana0744822010-11-01 23:22:47 +000017#include "clang/AST/Decl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018#include "lldb/lldb-private.h"
19#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000020#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000021#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Core/Module.h"
23#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000024#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Symbol/ClangASTContext.h"
Greg Clayton6916e352010-11-13 03:52:47 +000026#include "lldb/Symbol/ClangNamespaceDecl.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Symbol/CompileUnit.h"
28#include "lldb/Symbol/Function.h"
29#include "lldb/Symbol/ObjectFile.h"
30#include "lldb/Symbol/SymbolContext.h"
31#include "lldb/Symbol/Type.h"
32#include "lldb/Symbol/TypeList.h"
33#include "lldb/Symbol/Variable.h"
34#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000035#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000036#include "lldb/Target/Process.h"
Sean Callanan17c6a052010-10-05 20:18:48 +000037#include "lldb/Target/RegisterContext.h"
Chris Lattner24943d22010-06-08 16:52:24 +000038#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000039#include "lldb/Target/Target.h"
Sean Callanana0744822010-11-01 23:22:47 +000040#include "llvm/Support/raw_ostream.h"
Chris Lattner24943d22010-06-08 16:52:24 +000041
Greg Clayton3bc52d02010-11-14 22:13:40 +000042using namespace lldb;
Chris Lattner24943d22010-06-08 16:52:24 +000043using namespace lldb_private;
44using namespace clang;
45
Greg Clayton8de27c72010-10-15 22:48:33 +000046ClangExpressionDeclMap::ClangExpressionDeclMap (ExecutionContext *exe_ctx) :
47 m_found_entities (),
48 m_struct_members (),
49 m_exe_ctx (),
50 m_sym_ctx (),
51 m_persistent_vars (NULL),
52 m_struct_alignment (0),
53 m_struct_size (0),
54 m_struct_laid_out (false),
55 m_enable_lookups (false),
56 m_allocated_area (0),
57 m_materialized_location (0),
58 m_result_name (),
59 m_object_pointer_type (),
Sean Callananee8fc722010-11-19 20:20:02 +000060 m_ignore_lookups (false)
Chris Lattner24943d22010-06-08 16:52:24 +000061{
Greg Clayton8de27c72010-10-15 22:48:33 +000062 if (exe_ctx)
63 {
64 m_exe_ctx = *exe_ctx;
65 if (exe_ctx->frame)
66 m_sym_ctx = exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything);
67 if (exe_ctx->process)
68 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
69 }
Chris Lattner24943d22010-06-08 16:52:24 +000070}
71
72ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000073{
74 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
75 entity_index < num_entities;
76 ++entity_index)
77 {
78 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
79 if (entity.m_parser_vars.get() &&
80 entity.m_parser_vars->m_lldb_value)
81 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000082
83 entity.DisableParserVars();
84 }
85
86 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
87 pvar_index < num_pvars;
88 ++pvar_index)
89 {
90 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
91 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000092 }
Chris Lattner24943d22010-06-08 16:52:24 +000093
Sean Callanan7a60b942010-10-08 01:58:41 +000094 if (m_materialized_location)
Sean Callananc2c6f772010-10-26 00:31:56 +000095 {
96//#define SINGLE_STEP_EXPRESSIONS
97
98#ifndef SINGLE_STEP_EXPRESSIONS
Greg Clayton8de27c72010-10-15 22:48:33 +000099 m_exe_ctx.process->DeallocateMemory(m_materialized_location);
Sean Callananc2c6f772010-10-26 00:31:56 +0000100#endif
Sean Callanan7a60b942010-10-08 01:58:41 +0000101 m_materialized_location = 0;
102 }
Chris Lattner24943d22010-06-08 16:52:24 +0000103}
104
Sean Callanan8bce6652010-07-13 21:41:46 +0000105// Interface for IRForTarget
106
Greg Clayton8de27c72010-10-15 22:48:33 +0000107const ConstString &
108ClangExpressionDeclMap::GetPersistentResultName ()
Sean Callanan82b74c82010-08-12 01:56:52 +0000109{
Greg Clayton8de27c72010-10-15 22:48:33 +0000110 if (!m_result_name)
111 m_persistent_vars->GetNextResultName(m_result_name);
112 return m_result_name;
Sean Callanan82b74c82010-08-12 01:56:52 +0000113}
114
Sean Callanan8bce6652010-07-13 21:41:46 +0000115bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000116ClangExpressionDeclMap::AddPersistentVariable
117(
118 const clang::NamedDecl *decl,
119 const ConstString &name,
120 TypeFromParser parser_type
121)
Sean Callanana48fe162010-08-11 03:57:18 +0000122{
Greg Clayton8de27c72010-10-15 22:48:33 +0000123 clang::ASTContext *context(m_exe_ctx.target->GetScratchClangASTContext()->getASTContext());
Sean Callanana48fe162010-08-11 03:57:18 +0000124
Sean Callanana48fe162010-08-11 03:57:18 +0000125 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000126 parser_type.GetASTContext(),
127 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000128 context);
129
Sean Callanan8c127202010-08-23 23:09:38 +0000130 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
131 return false;
132
133 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
134
135 if (!var)
136 return false;
137
138 var->EnableParserVars();
139
140 var->m_parser_vars->m_named_decl = decl;
141 var->m_parser_vars->m_parser_type = parser_type;
142
143 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000144}
145
146bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000147ClangExpressionDeclMap::AddValueToStruct
148(
149 const clang::NamedDecl *decl,
150 const ConstString &name,
151 llvm::Value *value,
152 size_t size,
153 off_t alignment
154)
Sean Callanan8bce6652010-07-13 21:41:46 +0000155{
Greg Claytone005f2c2010-11-06 01:53:30 +0000156 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +0000157
Sean Callanan8bce6652010-07-13 21:41:46 +0000158 m_struct_laid_out = false;
159
Sean Callanan8c127202010-08-23 23:09:38 +0000160 if (m_struct_members.GetVariable(decl))
161 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000162
Sean Callanan8c127202010-08-23 23:09:38 +0000163 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000164
Sean Callanan8c127202010-08-23 23:09:38 +0000165 if (!var)
166 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000167
Sean Callanan8c127202010-08-23 23:09:38 +0000168 if (!var)
169 return false;
170
Sean Callanan45690fe2010-08-30 22:17:16 +0000171 if (log)
172 log->Printf("Adding value for decl %p [%s - %s] to the structure",
173 decl,
Greg Clayton8de27c72010-10-15 22:48:33 +0000174 name.GetCString(),
175 var->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000176
Sean Callanan8c127202010-08-23 23:09:38 +0000177 // We know entity->m_parser_vars is valid because we used a parser variable
178 // to find it
179 var->m_parser_vars->m_llvm_value = value;
180
181 var->EnableJITVars();
182 var->m_jit_vars->m_alignment = alignment;
183 var->m_jit_vars->m_size = size;
184
185 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000186
187 return true;
188}
189
190bool
191ClangExpressionDeclMap::DoStructLayout ()
192{
193 if (m_struct_laid_out)
194 return true;
195
Sean Callanan8bce6652010-07-13 21:41:46 +0000196 off_t cursor = 0;
197
198 m_struct_alignment = 0;
199 m_struct_size = 0;
200
Sean Callanan8c127202010-08-23 23:09:38 +0000201 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
202 member_index < num_members;
203 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000204 {
Sean Callanan8c127202010-08-23 23:09:38 +0000205 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000206
Sean Callanan8c127202010-08-23 23:09:38 +0000207 if (!member.m_jit_vars.get())
208 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000209
Sean Callanan8c127202010-08-23 23:09:38 +0000210 if (member_index == 0)
211 m_struct_alignment = member.m_jit_vars->m_alignment;
212
213 if (cursor % member.m_jit_vars->m_alignment)
214 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
215
216 member.m_jit_vars->m_offset = cursor;
217 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000218 }
219
220 m_struct_size = cursor;
221
222 m_struct_laid_out = true;
223 return true;
224}
225
Greg Clayton8de27c72010-10-15 22:48:33 +0000226bool ClangExpressionDeclMap::GetStructInfo
227(
228 uint32_t &num_elements,
229 size_t &size,
230 off_t &alignment
231)
Sean Callanan8bce6652010-07-13 21:41:46 +0000232{
233 if (!m_struct_laid_out)
234 return false;
235
Sean Callanan8c127202010-08-23 23:09:38 +0000236 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000237 size = m_struct_size;
238 alignment = m_struct_alignment;
239
240 return true;
241}
242
243bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000244ClangExpressionDeclMap::GetStructElement
245(
246 const clang::NamedDecl *&decl,
247 llvm::Value *&value,
248 off_t &offset,
249 ConstString &name,
250 uint32_t index
251)
Sean Callanan8bce6652010-07-13 21:41:46 +0000252{
253 if (!m_struct_laid_out)
254 return false;
255
Sean Callanan8c127202010-08-23 23:09:38 +0000256 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000257 return false;
258
Sean Callanan8c127202010-08-23 23:09:38 +0000259 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000260
Sean Callanan8c127202010-08-23 23:09:38 +0000261 if (!member.m_parser_vars.get() ||
262 !member.m_jit_vars.get())
263 return false;
264
265 decl = member.m_parser_vars->m_named_decl;
266 value = member.m_parser_vars->m_llvm_value;
267 offset = member.m_jit_vars->m_offset;
Greg Clayton8de27c72010-10-15 22:48:33 +0000268 name = member.m_name;
Sean Callanan8c127202010-08-23 23:09:38 +0000269
Sean Callanan8bce6652010-07-13 21:41:46 +0000270 return true;
271}
272
Sean Callanan02fbafa2010-07-27 21:39:39 +0000273bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000274ClangExpressionDeclMap::GetFunctionInfo
275(
276 const clang::NamedDecl *decl,
277 llvm::Value**& value,
278 uint64_t &ptr
279)
Sean Callananba992c52010-07-27 02:07:53 +0000280{
Sean Callanan8c127202010-08-23 23:09:38 +0000281 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
282
283 if (!entity)
284 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000285
Sean Callanan8c127202010-08-23 23:09:38 +0000286 // We know m_parser_vars is valid since we searched for the variable by
287 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000288
Sean Callanan8c127202010-08-23 23:09:38 +0000289 value = &entity->m_parser_vars->m_llvm_value;
290 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
291
292 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000293}
294
Sean Callananf5857a02010-07-31 01:32:05 +0000295bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000296ClangExpressionDeclMap::GetFunctionAddress
297(
298 const ConstString &name,
299 uint64_t &ptr
300)
Sean Callananf5857a02010-07-31 01:32:05 +0000301{
302 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +0000303 if (m_exe_ctx.frame == NULL)
Sean Callananf5857a02010-07-31 01:32:05 +0000304 return false;
305
Greg Claytone5748d82010-11-09 23:46:37 +0000306 SymbolContextList sc_list;
Sean Callananf5857a02010-07-31 01:32:05 +0000307
Greg Claytone5748d82010-11-09 23:46:37 +0000308 m_sym_ctx.FindFunctionsByName(name, false, sc_list);
Sean Callananf5857a02010-07-31 01:32:05 +0000309
Greg Claytone5748d82010-11-09 23:46:37 +0000310 if (!sc_list.GetSize())
Sean Callananf5857a02010-07-31 01:32:05 +0000311 return false;
312
313 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +0000314 sc_list.GetContextAtIndex(0, sym_ctx);
Sean Callananf5857a02010-07-31 01:32:05 +0000315
316 const Address *fun_address;
317
318 if (sym_ctx.function)
319 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
320 else if (sym_ctx.symbol)
321 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
322 else
323 return false;
324
Greg Clayton8de27c72010-10-15 22:48:33 +0000325 ptr = fun_address->GetLoadAddress (m_exe_ctx.target);
Sean Callananf5857a02010-07-31 01:32:05 +0000326
327 return true;
328}
329
Sean Callanan810f22d2010-07-16 00:09:46 +0000330// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000331
332bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000333ClangExpressionDeclMap::Materialize
334(
335 ExecutionContext *exe_ctx,
336 lldb::addr_t &struct_address,
337 Error &err
338)
Sean Callananf328c9f2010-07-20 23:31:16 +0000339{
340 bool result = DoMaterialize(false, exe_ctx, NULL, err);
341
342 if (result)
343 struct_address = m_materialized_location;
344
345 return result;
346}
347
348bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000349ClangExpressionDeclMap::GetObjectPointer
350(
351 lldb::addr_t &object_ptr,
352 ExecutionContext *exe_ctx,
353 Error &err
354)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000355{
356 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
357 {
358 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
359 return false;
360 }
361
362 if (!m_object_pointer_type.GetOpaqueQualType())
363 {
364 err.SetErrorString("Couldn't load 'this' because its type is unknown");
365 return false;
366 }
367
Greg Clayton3bc52d02010-11-14 22:13:40 +0000368 static ConstString g_this_const_str ("this");
369 Variable *object_ptr_var = FindVariableInScope (*exe_ctx->frame, g_this_const_str, &m_object_pointer_type);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000370
371 if (!object_ptr_var)
372 {
373 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
374 return false;
375 }
376
377 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
378 object_ptr_var,
379 m_object_pointer_type.GetASTContext()));
380
381 if (!location_value.get())
382 {
383 err.SetErrorString("Couldn't get the location for 'this'");
384 return false;
385 }
386
387 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
388 {
389 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
390 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
391 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
392
393 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
394 {
395 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
396 return false;
397 }
398
399 DataBufferHeap data;
400 data.SetByteSize(address_byte_size);
401 Error read_error;
402
403 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
404 {
405 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
406 return false;
407 }
408
409 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
410
411 uint32_t offset = 0;
412
413 object_ptr = extractor.GetPointer(&offset);
414
415 return true;
416 }
417 else
418 {
419 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
420 return false;
421 }
422}
423
424bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000425ClangExpressionDeclMap::Dematerialize
426(
427 ExecutionContext *exe_ctx,
428 ClangExpressionVariable *&result,
429 Error &err
430)
Sean Callananf328c9f2010-07-20 23:31:16 +0000431{
Sean Callanan82b74c82010-08-12 01:56:52 +0000432 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000433}
434
Sean Callanan32824aa2010-07-23 22:19:18 +0000435bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000436ClangExpressionDeclMap::DumpMaterializedStruct
437(
438 ExecutionContext *exe_ctx,
439 Stream &s,
440 Error &err
441)
Sean Callanan32824aa2010-07-23 22:19:18 +0000442{
443 if (!m_struct_laid_out)
444 {
445 err.SetErrorString("Structure hasn't been laid out yet");
446 return false;
447 }
448
449 if (!exe_ctx)
450 {
451 err.SetErrorString("Received null execution context");
452 return false;
453 }
454
455
456 if (!exe_ctx->process)
457 {
458 err.SetErrorString("Couldn't find the process");
459 return false;
460 }
461
462 if (!exe_ctx->target)
463 {
464 err.SetErrorString("Couldn't find the target");
465 return false;
466 }
467
468 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
469
470 Error error;
471 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
472 {
473 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
474 return false;
475 }
476
477 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
478
Sean Callanan8c127202010-08-23 23:09:38 +0000479 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
480 member_index < num_members;
481 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000482 {
Sean Callanan8c127202010-08-23 23:09:38 +0000483 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000484
Greg Clayton8de27c72010-10-15 22:48:33 +0000485 s.Printf("[%s]\n", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000486
487 if (!member.m_jit_vars.get())
488 return false;
489
490 extractor.Dump(&s, // stream
491 member.m_jit_vars->m_offset, // offset
492 lldb::eFormatBytesWithASCII, // format
493 1, // byte size of individual entries
494 member.m_jit_vars->m_size, // number of entries
495 16, // entries per line
496 m_materialized_location + member.m_jit_vars->m_offset, // address to print
497 0, // bit size (bitfields only; 0 means ignore)
498 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000499
500 s.PutChar('\n');
501 }
502
503 return true;
504}
505
Sean Callananf328c9f2010-07-20 23:31:16 +0000506bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000507ClangExpressionDeclMap::DoMaterialize
508(
509 bool dematerialize,
510 ExecutionContext *exe_ctx,
511 ClangExpressionVariable **result,
512 Error &err
513)
Sean Callanan810f22d2010-07-16 00:09:46 +0000514{
Greg Claytone005f2c2010-11-06 01:53:30 +0000515 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan82b74c82010-08-12 01:56:52 +0000516
Sean Callanan810f22d2010-07-16 00:09:46 +0000517 if (!m_struct_laid_out)
518 {
519 err.SetErrorString("Structure hasn't been laid out yet");
520 return LLDB_INVALID_ADDRESS;
521 }
522
Sean Callanan810f22d2010-07-16 00:09:46 +0000523 if (!exe_ctx)
524 {
525 err.SetErrorString("Received null execution context");
526 return LLDB_INVALID_ADDRESS;
527 }
528
Sean Callanan45839272010-07-24 01:37:44 +0000529 if (!exe_ctx->frame)
530 {
531 err.SetErrorString("Received null execution frame");
532 return LLDB_INVALID_ADDRESS;
533 }
534
Sean Callanane8a59a82010-09-13 21:34:21 +0000535 if (!m_struct_size)
536 {
537 if (log)
538 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
539
540 m_allocated_area = NULL;
541
542 return true;
543 }
544
Sean Callanan810f22d2010-07-16 00:09:46 +0000545 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
546
Sean Callananf328c9f2010-07-20 23:31:16 +0000547 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000548 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000549 if (m_materialized_location)
550 {
551 exe_ctx->process->DeallocateMemory(m_materialized_location);
552 m_materialized_location = 0;
553 }
554
Sean Callanan7a60b942010-10-08 01:58:41 +0000555 if (log)
556 log->PutCString("Allocating memory for materialized argument struct");
557
Sean Callananf328c9f2010-07-20 23:31:16 +0000558 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
559 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
560 err);
561
562 if (mem == LLDB_INVALID_ADDRESS)
563 return false;
564
565 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000566 }
567
Sean Callananf328c9f2010-07-20 23:31:16 +0000568 m_materialized_location = m_allocated_area;
569
570 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000571 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000572
Sean Callanan8c127202010-08-23 23:09:38 +0000573 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
574 member_index < num_members;
575 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000576 {
Sean Callanan8c127202010-08-23 23:09:38 +0000577 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000578
Sean Callanan4d0b1102010-12-01 01:29:06 +0000579 ClangExpressionVariable *entity = NULL;
Sean Callanan8c127202010-08-23 23:09:38 +0000580
Sean Callanan4d0b1102010-12-01 01:29:06 +0000581 if (member.m_parser_vars.get())
582 entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
583
Greg Clayton8de27c72010-10-15 22:48:33 +0000584 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name);
Sean Callanan8c127202010-08-23 23:09:38 +0000585
586 if (entity)
587 {
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000588 if (entity->m_register_info)
589 {
590 // This is a register variable
591
592 RegisterContext *reg_ctx = exe_ctx->GetRegisterContext();
593
594 if (!reg_ctx)
595 return false;
596
597 if (!DoMaterializeOneRegister(dematerialize, *exe_ctx, *reg_ctx, *entity->m_register_info, m_materialized_location + member.m_jit_vars->m_offset, err))
598 return false;
599 }
600 else
601 {
602 if (!member.m_jit_vars.get())
603 return false;
604
605 if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err))
606 return false;
607 }
Sean Callanan8c127202010-08-23 23:09:38 +0000608 }
609 else if (persistent_variable)
610 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000611 if (member.m_name == m_result_name)
Sean Callanan45690fe2010-08-30 22:17:16 +0000612 {
613 if (!dematerialize)
614 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000615
Sean Callanan8c127202010-08-23 23:09:38 +0000616 if (log)
617 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000618
Sean Callanan8c127202010-08-23 23:09:38 +0000619 *result = &member;
620 }
621
Sean Callanan45690fe2010-08-30 22:17:16 +0000622 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000623 log->Printf("Searched for persistent variable %s and found %s", member.m_name.GetCString(), persistent_variable->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000624
Greg Clayton8de27c72010-10-15 22:48:33 +0000625 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name, m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan8c127202010-08-23 23:09:38 +0000626 return false;
627 }
628 else
629 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000630 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000631 return false;
632 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000633 }
634
Sean Callananf328c9f2010-07-20 23:31:16 +0000635 return true;
636}
637
Sean Callanana48fe162010-08-11 03:57:18 +0000638bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000639ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
640(
641 bool dematerialize,
642 ExecutionContext &exe_ctx,
643 const ConstString &name,
644 lldb::addr_t addr,
645 Error &err
646)
Sean Callanan45690fe2010-08-30 22:17:16 +0000647{
Sean Callanana6223432010-08-20 01:02:30 +0000648 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000649
650 if (!pvar)
651 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000652 err.SetErrorStringWithFormat("Undefined persistent variable %s", name.GetCString());
Sean Callanana48fe162010-08-11 03:57:18 +0000653 return LLDB_INVALID_ADDRESS;
654 }
655
656 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000657
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000658 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000659 return false;
660
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000661 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000662 Error error;
663
664 if (dematerialize)
665 {
666 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
667 {
668 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
669 return false;
670 }
671 }
672 else
673 {
674 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
675 {
676 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
677 return false;
678 }
679 }
680
681 return true;
682}
683
Sean Callananf328c9f2010-07-20 23:31:16 +0000684bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000685ClangExpressionDeclMap::DoMaterializeOneVariable
686(
687 bool dematerialize,
688 ExecutionContext &exe_ctx,
689 const SymbolContext &sym_ctx,
690 const ConstString &name,
691 TypeFromUser type,
692 lldb::addr_t addr,
693 Error &err
694)
Sean Callananf328c9f2010-07-20 23:31:16 +0000695{
Greg Claytone005f2c2010-11-06 01:53:30 +0000696 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananf328c9f2010-07-20 23:31:16 +0000697
Sean Callanan17c6a052010-10-05 20:18:48 +0000698 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000699 return false;
700
Greg Clayton3bc52d02010-11-14 22:13:40 +0000701 Variable *var = FindVariableInScope (*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000702
703 if (!var)
704 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000705 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000706 return false;
707 }
708
Sean Callanan841026f2010-07-23 00:16:21 +0000709 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000710 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000711
712 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
713 var,
714 type.GetASTContext()));
715
716 if (!location_value.get())
717 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000718 err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000719 return false;
720 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000721
722 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000723
Sean Callanan17c6a052010-10-05 20:18:48 +0000724 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
725 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
726
727 Value::ValueType value_type = location_value->GetValueType();
728
729 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000730 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000731 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000732 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000733 StreamString ss;
734
735 location_value->Dump(&ss);
736
Greg Clayton8de27c72010-10-15 22:48:33 +0000737 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000738 return false;
739 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000740 break;
741 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000742 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000743 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
744
745 DataBufferHeap data;
746 data.SetByteSize(addr_byte_size);
747
748 lldb::addr_t src_addr;
749 lldb::addr_t dest_addr;
750
751 if (dematerialize)
752 {
753 src_addr = addr;
754 dest_addr = value_addr;
755 }
756 else
757 {
758 src_addr = value_addr;
759 dest_addr = addr;
760 }
761
762 Error error;
763 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
764 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000765 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000766 return false;
767 }
768
769 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
770 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000771 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000772 return false;
773 }
774
775 if (log)
776 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000777 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000778 break;
779 case Value::eValueTypeScalar:
780 {
Greg Clayton6916e352010-11-13 03:52:47 +0000781 if (location_value->GetContextType() != Value::eContextTypeRegisterInfo)
Sean Callanan17c6a052010-10-05 20:18:48 +0000782 {
783 StreamString ss;
784
785 location_value->Dump(&ss);
786
Greg Clayton8de27c72010-10-15 22:48:33 +0000787 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callanan17c6a052010-10-05 20:18:48 +0000788 return false;
789 }
790
791 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
792
793 if (!register_info)
794 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000795 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000796 return false;
797 }
798
799 RegisterContext *register_context = exe_ctx.GetRegisterContext();
800
801 if (!register_context)
802 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000803 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000804 return false;
805 }
806
807 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
808 uint32_t register_byte_size = register_info->byte_size;
809
810 if (dematerialize)
811 {
812 // Moving from addr into a register
813 //
814 // Case 1: addr_byte_size and register_byte_size are the same
815 //
816 // |AABBCCDD| Address contents
817 // |AABBCCDD| Register contents
818 //
819 // Case 2: addr_byte_size is bigger than register_byte_size
820 //
821 // Error! (The register should always be big enough to hold the data)
822 //
823 // Case 3: register_byte_size is bigger than addr_byte_size
824 //
825 // |AABB| Address contents
826 // |AABB0000| Register contents [on little-endian hardware]
827 // |0000AABB| Register contents [on big-endian hardware]
828
829 if (addr_byte_size > register_byte_size)
830 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000831 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000832 return false;
833 }
834
835 uint32_t register_offset;
836
837 switch (exe_ctx.process->GetByteOrder())
838 {
839 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000840 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000841 return false;
842 case lldb::eByteOrderLittle:
843 register_offset = 0;
844 break;
845 case lldb::eByteOrderBig:
846 register_offset = register_byte_size - addr_byte_size;
847 break;
848 }
849
850 DataBufferHeap register_data (register_byte_size, 0);
851
852 Error error;
853 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
854 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000855 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000856 return false;
857 }
858
859 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
860
861 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
862 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000863 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000864 return false;
865 }
866 }
867 else
868 {
869 // Moving from a register into addr
870 //
871 // Case 1: addr_byte_size and register_byte_size are the same
872 //
873 // |AABBCCDD| Register contents
874 // |AABBCCDD| Address contents
875 //
876 // Case 2: addr_byte_size is bigger than register_byte_size
877 //
878 // Error! (The register should always be big enough to hold the data)
879 //
880 // Case 3: register_byte_size is bigger than addr_byte_size
881 //
882 // |AABBCCDD| Register contents
883 // |AABB| Address contents on little-endian hardware
884 // |CCDD| Address contents on big-endian hardware
885
886 if (addr_byte_size > register_byte_size)
887 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000888 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000889 return false;
890 }
891
892 uint32_t register_offset;
893
894 switch (exe_ctx.process->GetByteOrder())
895 {
896 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000897 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000898 return false;
899 case lldb::eByteOrderLittle:
900 register_offset = 0;
901 break;
902 case lldb::eByteOrderBig:
903 register_offset = register_byte_size - addr_byte_size;
904 break;
905 }
906
907 DataExtractor register_extractor;
908
909 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
910 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000911 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000912 return false;
913 }
914
915 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
916
917 if (!register_data)
918 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000919 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000920 return false;
921 }
922
923 Error error;
924 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
925 {
926 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
927 return false;
928 }
929 }
930 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000931 }
932
933 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000934}
935
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000936bool
937ClangExpressionDeclMap::DoMaterializeOneRegister
938(
939 bool dematerialize,
940 ExecutionContext &exe_ctx,
941 RegisterContext &reg_ctx,
942 const lldb::RegisterInfo &reg_info,
943 lldb::addr_t addr,
944 Error &err
945)
946{
947 uint32_t register_number = reg_info.kinds[lldb::eRegisterKindLLDB];
948 uint32_t register_byte_size = reg_info.byte_size;
949
950 Error error;
951
952 if (dematerialize)
953 {
954 DataBufferHeap register_data (register_byte_size, 0);
955
956 Error error;
957 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes(), register_byte_size, error) != register_byte_size)
958 {
959 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, error.AsCString());
960 return false;
961 }
962
963 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
964
965 if (!reg_ctx.WriteRegisterBytes(register_number, register_extractor, 0))
966 {
967 err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name);
968 return false;
969 }
970 }
971 else
972 {
973 DataExtractor register_extractor;
974
975 if (!reg_ctx.ReadRegisterBytes(register_number, register_extractor))
976 {
977 err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name);
978 return false;
979 }
980
981 uint32_t register_offset = 0;
982
983 const void *register_data = register_extractor.GetData(&register_offset, register_byte_size);
984
985 if (!register_data)
986 {
987 err.SetErrorStringWithFormat("Read but couldn't extract data for %s", reg_info.name);
988 return false;
989 }
990
991 Error error;
992 if (exe_ctx.process->WriteMemory (addr, register_data, register_byte_size, error) != register_byte_size)
993 {
994 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
995 return false;
996 }
997 }
998
999 return true;
1000}
1001
Sean Callanancc074622010-09-14 21:59:34 +00001002Variable *
Greg Clayton8de27c72010-10-15 22:48:33 +00001003ClangExpressionDeclMap::FindVariableInScope
1004(
1005 StackFrame &frame,
1006 const ConstString &name,
1007 TypeFromUser *type
1008)
Sean Callanancc074622010-09-14 21:59:34 +00001009{
Greg Claytone005f2c2010-11-06 01:53:30 +00001010 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanancc074622010-09-14 21:59:34 +00001011
Sean Callanancc074622010-09-14 21:59:34 +00001012 VariableList *var_list = frame.GetVariableList(true);
1013
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001014 if (!var_list)
1015 return NULL;
1016
Greg Clayton3bc52d02010-11-14 22:13:40 +00001017 lldb::VariableSP var_sp (var_list->FindVariable(name));
1018
1019 const bool append = true;
1020 const uint32_t max_matches = 1;
1021 if (!var_sp)
Sean Callanancc074622010-09-14 21:59:34 +00001022 {
Greg Clayton3bc52d02010-11-14 22:13:40 +00001023 // Look for globals elsewhere in the module for the frame
1024 ModuleSP module_sp (m_exe_ctx.frame->GetSymbolContext(eSymbolContextModule).module_sp);
1025 if (module_sp)
1026 {
1027 VariableList module_globals;
1028 if (module_sp->FindGlobalVariables (name, append, max_matches, module_globals))
1029 var_sp = module_globals.GetVariableAtIndex (0);
1030 }
1031 }
1032
1033 if (!var_sp)
1034 {
1035 // Look for globals elsewhere in the program (all images)
1036 TargetSP target_sp (m_exe_ctx.frame->GetSymbolContext(eSymbolContextTarget).target_sp);
1037 if (target_sp)
1038 {
1039 VariableList program_globals;
1040 if (target_sp->GetImages().FindGlobalVariables (name, append, max_matches, program_globals))
1041 var_sp = program_globals.GetVariableAtIndex (0);
1042 }
1043 }
1044
1045 if (var_sp && type)
1046 {
1047 if (type->GetASTContext() == var_sp->GetType()->GetClangAST())
1048 {
1049 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var_sp->GetType()->GetClangType()))
1050 return NULL;
1051 }
1052 else
1053 {
1054 if (log)
1055 log->PutCString("Skipping a candidate variable because of different AST contexts");
Sean Callanancc074622010-09-14 21:59:34 +00001056 return NULL;
Greg Clayton3bc52d02010-11-14 22:13:40 +00001057 }
Sean Callanancc074622010-09-14 21:59:34 +00001058 }
Greg Clayton3bc52d02010-11-14 22:13:40 +00001059
1060 return var_sp.get();
Sean Callanancc074622010-09-14 21:59:34 +00001061}
Sean Callanan336a0002010-07-17 00:43:37 +00001062
Chris Lattner24943d22010-06-08 16:52:24 +00001063// Interface for ClangASTSource
1064void
Greg Claytone5748d82010-11-09 23:46:37 +00001065ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name)
Chris Lattner24943d22010-06-08 16:52:24 +00001066{
Greg Claytone005f2c2010-11-06 01:53:30 +00001067 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001068
Sean Callanan810f22d2010-07-16 00:09:46 +00001069 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001070 log->Printf("Hunting for a definition for '%s'", name.GetCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001071
1072 // Back out in all cases where we're not fully initialized
Greg Clayton8de27c72010-10-15 22:48:33 +00001073 if (m_exe_ctx.frame == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001074 return;
Sean Callananee8fc722010-11-19 20:20:02 +00001075
1076 if (m_ignore_lookups)
1077 {
1078 if (log)
1079 log->Printf("Ignoring a query during an import");
1080 return;
1081 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001082
Greg Claytone5748d82010-11-09 23:46:37 +00001083 SymbolContextList sc_list;
Chris Lattner24943d22010-06-08 16:52:24 +00001084
Greg Clayton3bc52d02010-11-14 22:13:40 +00001085 const char *name_unique_cstr = name.GetCString();
1086
1087 if (name_unique_cstr == NULL)
1088 return;
1089
Greg Clayton8de27c72010-10-15 22:48:33 +00001090 // Only look for functions by name out in our symbols if the function
1091 // doesn't start with our phony prefix of '$'
Greg Clayton3bc52d02010-11-14 22:13:40 +00001092 if (name_unique_cstr[0] != '$')
Sean Callanan0fc73582010-07-27 00:55:47 +00001093 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001094 Variable *var = FindVariableInScope(*m_exe_ctx.frame, name);
1095
1096 // If we found a variable in scope, no need to pull up function names
1097 if (var != NULL)
1098 {
1099 AddOneVariable(context, var);
1100 }
1101 else
1102 {
Greg Claytone5748d82010-11-09 23:46:37 +00001103 m_sym_ctx.FindFunctionsByName (name, false, sc_list);
Greg Clayton8de27c72010-10-15 22:48:33 +00001104
1105 bool found_specific = false;
1106 Symbol *generic_symbol = NULL;
1107 Symbol *non_extern_symbol = NULL;
1108
Greg Claytone5748d82010-11-09 23:46:37 +00001109 for (uint32_t index = 0, num_indices = sc_list.GetSize();
Greg Clayton8de27c72010-10-15 22:48:33 +00001110 index < num_indices;
1111 ++index)
1112 {
1113 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +00001114 sc_list.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +00001115
Greg Clayton8de27c72010-10-15 22:48:33 +00001116 if (sym_ctx.function)
1117 {
1118 // TODO only do this if it's a C function; C++ functions may be
1119 // overloaded
1120 if (!found_specific)
1121 AddOneFunction(context, sym_ctx.function, NULL);
1122 found_specific = true;
1123 }
1124 else if (sym_ctx.symbol)
1125 {
1126 if (sym_ctx.symbol->IsExternal())
1127 generic_symbol = sym_ctx.symbol;
1128 else
1129 non_extern_symbol = sym_ctx.symbol;
1130 }
1131 }
1132
Sean Callanan92aa6662010-09-07 21:49:41 +00001133 if (!found_specific)
Greg Clayton8de27c72010-10-15 22:48:33 +00001134 {
1135 if (generic_symbol)
1136 AddOneFunction(context, NULL, generic_symbol);
1137 else if (non_extern_symbol)
1138 AddOneFunction(context, NULL, non_extern_symbol);
1139 }
Greg Clayton6916e352010-11-13 03:52:47 +00001140
1141 ClangNamespaceDecl namespace_decl (m_sym_ctx.FindNamespace(name));
1142 if (namespace_decl)
1143 {
Greg Clayton9ceed1e2010-11-13 04:18:24 +00001144 clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl);
1145 if (clang_namespace_decl)
1146 {
1147 // TODO: is this how we get the decl lookups to be called for
1148 // this namespace??
1149 clang_namespace_decl->setHasExternalLexicalStorage();
1150 }
Greg Clayton6916e352010-11-13 03:52:47 +00001151 }
Sean Callanan92aa6662010-09-07 21:49:41 +00001152 }
Sean Callanan0fc73582010-07-27 00:55:47 +00001153 }
Greg Clayton8de27c72010-10-15 22:48:33 +00001154 else
Sean Callanan3cfbd332010-10-06 00:10:07 +00001155 {
Greg Clayton57452832010-11-09 04:42:43 +00001156 static ConstString g_lldb_class_name ("$__lldb_class");
1157 if (name == g_lldb_class_name)
1158 {
1159 // Clang is looking for the type of "this"
1160
1161 VariableList *vars = m_exe_ctx.frame->GetVariableList(false);
1162
1163 if (!vars)
1164 return;
1165
1166 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
1167
1168 if (!this_var)
1169 return;
1170
1171 Type *this_type = this_var->GetType();
1172
1173 if (!this_type)
1174 return;
1175
Greg Clayton2403b5e2010-11-16 02:10:54 +00001176 if (log)
1177 {
1178 log->PutCString ("Type for \"this\" is: ");
1179 StreamString strm;
1180 this_type->Dump(&strm, true);
1181 log->PutCString (strm.GetData());
1182 }
1183
Greg Clayton57452832010-11-09 04:42:43 +00001184 TypeFromUser this_user_type(this_type->GetClangType(),
1185 this_type->GetClangAST());
1186
1187 m_object_pointer_type = this_user_type;
1188
1189 void *pointer_target_type;
1190
1191 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
1192 &pointer_target_type))
1193 return;
1194
1195 TypeFromUser class_user_type(pointer_target_type,
1196 this_type->GetClangAST());
1197
1198 AddOneType(context, class_user_type, true);
1199
1200 return;
1201 }
1202
Greg Clayton8de27c72010-10-15 22:48:33 +00001203 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
1204
1205 if (pvar)
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001206 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001207 AddOneVariable(context, pvar);
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001208 return;
1209 }
1210
1211 const char *reg_name(&name.GetCString()[1]);
1212
1213 if (m_exe_ctx.GetRegisterContext())
1214 {
1215 const lldb::RegisterInfo *reg_info(m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(reg_name));
1216
1217 if (reg_info)
1218 AddOneRegister(context, reg_info);
1219 }
Sean Callanan3cfbd332010-10-06 00:10:07 +00001220 }
1221
Sean Callananee8fc722010-11-19 20:20:02 +00001222 lldb::TypeSP type_sp (m_sym_ctx.FindTypeByName (name));
1223
1224 if (type_sp)
Sean Callanan6df08402010-09-27 23:54:58 +00001225 {
Sean Callananee8fc722010-11-19 20:20:02 +00001226 if (log)
Sean Callanan6df08402010-09-27 23:54:58 +00001227 {
Sean Callananee8fc722010-11-19 20:20:02 +00001228 log->Printf ("Matching type found for \"%s\": ", name.GetCString());
1229 StreamString strm;
1230 type_sp->Dump(&strm, true);
1231 log->PutCString (strm.GetData());
1232 }
Greg Clayton2403b5e2010-11-16 02:10:54 +00001233
Sean Callananee8fc722010-11-19 20:20:02 +00001234 TypeFromUser user_type(type_sp->GetClangType(),
Greg Clayton2403b5e2010-11-16 02:10:54 +00001235 type_sp->GetClangAST());
Sean Callanan6df08402010-09-27 23:54:58 +00001236
Sean Callananee8fc722010-11-19 20:20:02 +00001237 AddOneType(context, user_type, false);
Sean Callanan6df08402010-09-27 23:54:58 +00001238 }
Sean Callanan336a0002010-07-17 00:43:37 +00001239}
1240
1241Value *
Greg Clayton8de27c72010-10-15 22:48:33 +00001242ClangExpressionDeclMap::GetVariableValue
1243(
1244 ExecutionContext &exe_ctx,
1245 Variable *var,
1246 clang::ASTContext *parser_ast_context,
1247 TypeFromUser *user_type,
1248 TypeFromParser *parser_type
1249)
Chris Lattner24943d22010-06-08 16:52:24 +00001250{
Greg Claytone005f2c2010-11-06 01:53:30 +00001251 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan6184dfe2010-06-23 00:47:48 +00001252
Chris Lattner24943d22010-06-08 16:52:24 +00001253 Type *var_type = var->GetType();
1254
1255 if (!var_type)
1256 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001257 if (log)
1258 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +00001259 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001260 }
1261
Greg Clayton462d4142010-09-29 01:12:09 +00001262 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +00001263
1264 if (!var_opaque_type)
1265 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001266 if (log)
1267 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +00001268 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001269 }
1270
Chris Lattner24943d22010-06-08 16:52:24 +00001271 TypeList *type_list = var_type->GetTypeList();
1272
1273 if (!type_list)
1274 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001275 if (log)
1276 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +00001277 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001278 }
1279
1280 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
1281
1282 if (!exe_ast_ctx)
1283 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001284 if (log)
1285 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +00001286 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001287 }
1288
Sean Callanan336a0002010-07-17 00:43:37 +00001289 DWARFExpression &var_location_expr = var->LocationExpression();
1290
Chris Lattner24943d22010-06-08 16:52:24 +00001291 std::auto_ptr<Value> var_location(new Value);
1292
Greg Clayton178710c2010-09-14 02:20:48 +00001293 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
1294
1295 if (var_location_expr.IsLocationList())
1296 {
1297 SymbolContext var_sc;
1298 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +00001299 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +00001300 }
Chris Lattner24943d22010-06-08 16:52:24 +00001301 Error err;
1302
Jason Molenda8e69de42010-11-20 01:28:30 +00001303 if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, NULL, loclist_base_load_addr, NULL, *var_location.get(), &err))
Chris Lattner24943d22010-06-08 16:52:24 +00001304 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001305 if (log)
1306 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +00001307 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001308 }
1309
Sean Callanan810f22d2010-07-16 00:09:46 +00001310 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1311
Sean Callanan336a0002010-07-17 00:43:37 +00001312 void *type_to_use;
1313
Sean Callananf328c9f2010-07-20 23:31:16 +00001314 if (parser_ast_context)
1315 {
Sean Callananee8fc722010-11-19 20:20:02 +00001316 type_to_use = GuardedCopyType(parser_ast_context, var_ast_context, var_opaque_type);
Sean Callananf328c9f2010-07-20 23:31:16 +00001317
Sean Callanan4b5eec62010-11-20 02:19:29 +00001318 if (!type_to_use)
1319 {
1320 if (log)
1321 log->Printf("Couldn't copy a variable's type into the parser's AST context");
1322
1323 return NULL;
1324 }
1325
Sean Callananf328c9f2010-07-20 23:31:16 +00001326 if (parser_type)
1327 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1328 }
Sean Callanan336a0002010-07-17 00:43:37 +00001329 else
1330 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001331
1332 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Greg Clayton6916e352010-11-13 03:52:47 +00001333 var_location.get()->SetContext(Value::eContextTypeClangType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001334
1335 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1336 {
1337 SymbolContext var_sc;
1338 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001339
Chris Lattner24943d22010-06-08 16:52:24 +00001340 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001341 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001342
1343 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1344
1345 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001346 return NULL;
1347
Chris Lattner24943d22010-06-08 16:52:24 +00001348 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1349
Greg Clayton8de27c72010-10-15 22:48:33 +00001350 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx.target);
Chris Lattner24943d22010-06-08 16:52:24 +00001351
1352 var_location->GetScalar() = load_addr;
1353 var_location->SetValueType(Value::eValueTypeLoadAddress);
1354 }
1355
Sean Callananf328c9f2010-07-20 23:31:16 +00001356 if (user_type)
1357 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001358
1359 return var_location.release();
1360}
1361
1362void
1363ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001364 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001365{
Greg Claytone005f2c2010-11-06 01:53:30 +00001366 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan336a0002010-07-17 00:43:37 +00001367
Sean Callananf328c9f2010-07-20 23:31:16 +00001368 TypeFromUser ut;
1369 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001370
Greg Clayton8de27c72010-10-15 22:48:33 +00001371 Value *var_location = GetVariableValue (m_exe_ctx,
1372 var,
1373 context.GetASTContext(),
1374 &ut,
1375 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001376
Sean Callanan4b5eec62010-11-20 02:19:29 +00001377 if (!var_location)
1378 return;
1379
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001380 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001381
Sean Callanan8c127202010-08-23 23:09:38 +00001382 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001383 std::string decl_name(context.m_decl_name.getAsString());
1384 entity.m_name.SetCString (decl_name.c_str());
1385 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001386
Sean Callanan8c127202010-08-23 23:09:38 +00001387 entity.EnableParserVars();
1388 entity.m_parser_vars->m_parser_type = pt;
1389 entity.m_parser_vars->m_named_decl = var_decl;
1390 entity.m_parser_vars->m_llvm_value = NULL;
1391 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001392
Sean Callanan810f22d2010-07-16 00:09:46 +00001393 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001394 {
Sean Callanana0744822010-11-01 23:22:47 +00001395 std::string var_decl_print_string;
1396 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1397 var_decl->print(var_decl_print_stream);
1398 var_decl_print_stream.flush();
1399
1400 log->Printf("Found variable %s, returned %s", decl_name.c_str(), var_decl_print_string.c_str());
Greg Clayton8de27c72010-10-15 22:48:33 +00001401 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001402}
1403
1404void
Sean Callanana48fe162010-08-11 03:57:18 +00001405ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001406 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001407{
Greg Claytone005f2c2010-11-06 01:53:30 +00001408 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +00001409
Sean Callanana6223432010-08-20 01:02:30 +00001410 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001411
Sean Callananee8fc722010-11-19 20:20:02 +00001412 TypeFromParser parser_type(GuardedCopyType(context.GetASTContext(),
1413 user_type.GetASTContext(),
1414 user_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +00001415 context.GetASTContext());
1416
Sean Callanan8c127202010-08-23 23:09:38 +00001417 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1418
1419 pvar->EnableParserVars();
1420 pvar->m_parser_vars->m_parser_type = parser_type;
1421 pvar->m_parser_vars->m_named_decl = var_decl;
1422 pvar->m_parser_vars->m_llvm_value = NULL;
1423 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001424
1425 if (log)
Sean Callanana0744822010-11-01 23:22:47 +00001426 {
1427 std::string var_decl_print_string;
1428 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1429 var_decl->print(var_decl_print_stream);
1430 var_decl_print_stream.flush();
1431
1432 log->Printf("Added pvar %s, returned %s", pvar->m_name.GetCString(), var_decl_print_string.c_str());
1433 }
Sean Callanana48fe162010-08-11 03:57:18 +00001434}
1435
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001436void
1437ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
1438 const RegisterInfo *reg_info)
1439{
1440 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1441
1442 void *ast_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(context.GetASTContext(),
1443 reg_info->encoding,
1444 reg_info->byte_size * 8);
1445
1446 if (!ast_type)
1447 {
1448 log->Printf("Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str());
1449 return;
1450 }
1451
1452 TypeFromParser parser_type(ast_type,
1453 context.GetASTContext());
1454
1455 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1456
1457 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1458 std::string decl_name(context.m_decl_name.getAsString());
1459 entity.m_name.SetCString (decl_name.c_str());
1460 entity.m_register_info = reg_info;
1461
1462 entity.EnableParserVars();
1463 entity.m_parser_vars->m_parser_type = parser_type;
1464 entity.m_parser_vars->m_named_decl = var_decl;
1465 entity.m_parser_vars->m_llvm_value = NULL;
1466 entity.m_parser_vars->m_lldb_value = NULL;
1467
1468 if (log)
1469 {
1470 std::string var_decl_print_string;
1471 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1472 var_decl->print(var_decl_print_stream);
1473 var_decl_print_stream.flush();
1474
1475 log->Printf("Added register %s, returned %s", context.m_decl_name.getAsString().c_str(), var_decl_print_string.c_str());
1476 }
1477}
1478
Greg Clayton6916e352010-11-13 03:52:47 +00001479clang::NamespaceDecl *
1480ClangExpressionDeclMap::AddNamespace (NameSearchContext &context, const ClangNamespaceDecl &namespace_decl)
1481{
1482 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1483
1484
1485 clang::Decl *copied_decl = ClangASTContext::CopyDecl (context.GetASTContext(),
1486 namespace_decl.GetASTContext(),
1487 namespace_decl.GetNamespaceDecl());
1488
1489 return dyn_cast<clang::NamespaceDecl>(copied_decl);
1490}
1491
Sean Callanana48fe162010-08-11 03:57:18 +00001492void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001493ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001494 Function* fun,
1495 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001496{
Greg Claytone005f2c2010-11-06 01:53:30 +00001497 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001498
Sean Callanan0fc73582010-07-27 00:55:47 +00001499 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001500 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001501 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001502
Sean Callanan0fc73582010-07-27 00:55:47 +00001503 // only valid for Functions, not for Symbols
1504 void *fun_opaque_type = NULL;
1505 clang::ASTContext *fun_ast_context = NULL;
1506
1507 if (fun)
1508 {
1509 Type *fun_type = fun->GetType();
1510
1511 if (!fun_type)
1512 {
1513 if (log)
1514 log->PutCString("Skipped a function because it has no type");
1515 return;
1516 }
1517
Greg Clayton462d4142010-09-29 01:12:09 +00001518 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001519
1520 if (!fun_opaque_type)
1521 {
1522 if (log)
1523 log->PutCString("Skipped a function because it has no Clang type");
1524 return;
1525 }
1526
1527 fun_address = &fun->GetAddressRange().GetBaseAddress();
1528
1529 TypeList *type_list = fun_type->GetTypeList();
1530 fun_ast_context = type_list->GetClangASTContext().getASTContext();
Sean Callananee8fc722010-11-19 20:20:02 +00001531 void *copied_type = GuardedCopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
Sean Callanan0fc73582010-07-27 00:55:47 +00001532
1533 fun_decl = context.AddFunDecl(copied_type);
1534 }
1535 else if (symbol)
1536 {
1537 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1538
1539 fun_decl = context.AddGenericFunDecl();
1540 }
1541 else
1542 {
1543 if (log)
1544 log->PutCString("AddOneFunction called with no function and no symbol");
1545 return;
1546 }
1547
Greg Clayton8de27c72010-10-15 22:48:33 +00001548 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx.target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001549 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1550 fun_location->GetScalar() = load_addr;
1551
Sean Callanan8c127202010-08-23 23:09:38 +00001552 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001553 std::string decl_name(context.m_decl_name.getAsString());
1554 entity.m_name.SetCString(decl_name.c_str());
Sean Callanan8c127202010-08-23 23:09:38 +00001555 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001556
Sean Callanan8c127202010-08-23 23:09:38 +00001557 entity.EnableParserVars();
1558 entity.m_parser_vars->m_named_decl = fun_decl;
1559 entity.m_parser_vars->m_llvm_value = NULL;
1560 entity.m_parser_vars->m_lldb_value = fun_location.release();
1561
Sean Callanan810f22d2010-07-16 00:09:46 +00001562 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001563 {
Sean Callanana0744822010-11-01 23:22:47 +00001564 std::string fun_decl_print_string;
1565 llvm::raw_string_ostream fun_decl_print_stream(fun_decl_print_string);
1566 fun_decl->print(fun_decl_print_stream);
1567 fun_decl_print_stream.flush();
1568
1569 log->Printf("Found %s function %s, returned %s", (fun ? "specific" : "generic"), decl_name.c_str(), fun_decl_print_string.c_str());
Greg Clayton8de27c72010-10-15 22:48:33 +00001570 }
Chris Lattner24943d22010-06-08 16:52:24 +00001571}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001572
1573void
1574ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001575 TypeFromUser &ut,
1576 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001577{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001578 clang::ASTContext *parser_ast_context = context.GetASTContext();
1579 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001580
Sean Callananee8fc722010-11-19 20:20:02 +00001581 void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001582
1583 TypeFromParser parser_type(copied_type, parser_ast_context);
1584
1585 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1586 {
1587 void *args[1];
1588
1589 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1590
1591 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1592 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1593 args,
1594 1,
1595 false,
1596 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001597
Greg Clayton1d8173f2010-09-24 05:15:53 +00001598 const bool is_virtual = false;
1599 const bool is_static = false;
1600 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001601 const bool is_explicit = false;
1602
Greg Clayton1d8173f2010-09-24 05:15:53 +00001603 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1604 copied_type,
Greg Clayton8de27c72010-10-15 22:48:33 +00001605 "$__lldb_expr",
Greg Clayton1d8173f2010-09-24 05:15:53 +00001606 method_type,
1607 lldb::eAccessPublic,
1608 is_virtual,
1609 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001610 is_inline,
1611 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001612 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001613
1614 context.AddTypeDecl(copied_type);
1615}
Sean Callananee8fc722010-11-19 20:20:02 +00001616
1617void *
1618ClangExpressionDeclMap::GuardedCopyType (ASTContext *dest_context,
1619 ASTContext *source_context,
1620 void *clang_type)
1621{
1622 m_ignore_lookups = true;
1623
1624 void *ret = ClangASTContext::CopyType (dest_context,
1625 source_context,
1626 clang_type);
1627
1628 m_ignore_lookups = false;
1629
1630 return ret;
1631}