blob: 43c4150a0f9736360c27cff57b0638a108e57202 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/ClangExpressionDeclMap.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Sean Callanan47a5c4c2010-09-23 03:01:22 +000016#include "clang/AST/DeclarationName.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/lldb-private.h"
18#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000019#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000020#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000021#include "lldb/Core/Module.h"
22#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000023#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000024#include "lldb/Symbol/ClangASTContext.h"
25#include "lldb/Symbol/CompileUnit.h"
26#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/ObjectFile.h"
28#include "lldb/Symbol/SymbolContext.h"
29#include "lldb/Symbol/Type.h"
30#include "lldb/Symbol/TypeList.h"
31#include "lldb/Symbol/Variable.h"
32#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000033#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000034#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000035#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000036#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000037
Chris Lattner24943d22010-06-08 16:52:24 +000038using namespace lldb_private;
39using namespace clang;
40
Sean Callanana48fe162010-08-11 03:57:18 +000041ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
42 m_exe_ctx(exe_ctx), m_struct_laid_out(false),
Sean Callanan810f22d2010-07-16 00:09:46 +000043 m_materialized_location(0)
Chris Lattner24943d22010-06-08 16:52:24 +000044{
45 if (exe_ctx && exe_ctx->frame)
46 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
47 else
48 m_sym_ctx = NULL;
Sean Callanana48fe162010-08-11 03:57:18 +000049
50 if (exe_ctx && exe_ctx->process)
51 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
Chris Lattner24943d22010-06-08 16:52:24 +000052}
53
54ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000055{
56 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
57 entity_index < num_entities;
58 ++entity_index)
59 {
60 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
61 if (entity.m_parser_vars.get() &&
62 entity.m_parser_vars->m_lldb_value)
63 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000064
65 entity.DisableParserVars();
66 }
67
68 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
69 pvar_index < num_pvars;
70 ++pvar_index)
71 {
72 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
73 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000074 }
Chris Lattner24943d22010-06-08 16:52:24 +000075
76 if (m_sym_ctx)
77 delete m_sym_ctx;
78}
79
Sean Callanan8bce6652010-07-13 21:41:46 +000080// Interface for IRForTarget
81
Sean Callanan82b74c82010-08-12 01:56:52 +000082void
83ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
84{
85 m_persistent_vars->GetNextResultName(m_result_name);
86
87 name = m_result_name;
88}
89
Sean Callanan8bce6652010-07-13 21:41:46 +000090bool
Sean Callanan8c127202010-08-23 23:09:38 +000091ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl,
92 const char *name,
93 TypeFromParser parser_type)
Sean Callanana48fe162010-08-11 03:57:18 +000094{
95 clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
96
Sean Callanana48fe162010-08-11 03:57:18 +000097 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +000098 parser_type.GetASTContext(),
99 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000100 context);
101
Sean Callanan8c127202010-08-23 23:09:38 +0000102 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
103 return false;
104
105 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
106
107 if (!var)
108 return false;
109
110 var->EnableParserVars();
111
112 var->m_parser_vars->m_named_decl = decl;
113 var->m_parser_vars->m_parser_type = parser_type;
114
115 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000116}
117
118bool
Sean Callanan8c127202010-08-23 23:09:38 +0000119ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl,
Sean Callanan45690fe2010-08-30 22:17:16 +0000120 const char *name,
Sean Callanan8c127202010-08-23 23:09:38 +0000121 llvm::Value *value,
Sean Callanan8bce6652010-07-13 21:41:46 +0000122 size_t size,
123 off_t alignment)
124{
Sean Callanan45690fe2010-08-30 22:17:16 +0000125 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
126
Sean Callanan8bce6652010-07-13 21:41:46 +0000127 m_struct_laid_out = false;
128
Sean Callanan8c127202010-08-23 23:09:38 +0000129 if (m_struct_members.GetVariable(decl))
130 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000131
Sean Callanan8c127202010-08-23 23:09:38 +0000132 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000133
Sean Callanan8c127202010-08-23 23:09:38 +0000134 if (!var)
135 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000136
Sean Callanan8c127202010-08-23 23:09:38 +0000137 if (!var)
138 return false;
139
Sean Callanan45690fe2010-08-30 22:17:16 +0000140 if (log)
141 log->Printf("Adding value for decl %p [%s - %s] to the structure",
142 decl,
143 name,
144 var->m_name.c_str());
145
Sean Callanan8c127202010-08-23 23:09:38 +0000146 // We know entity->m_parser_vars is valid because we used a parser variable
147 // to find it
148 var->m_parser_vars->m_llvm_value = value;
149
150 var->EnableJITVars();
151 var->m_jit_vars->m_alignment = alignment;
152 var->m_jit_vars->m_size = size;
153
154 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000155
156 return true;
157}
158
159bool
160ClangExpressionDeclMap::DoStructLayout ()
161{
162 if (m_struct_laid_out)
163 return true;
164
Sean Callanan8bce6652010-07-13 21:41:46 +0000165 off_t cursor = 0;
166
167 m_struct_alignment = 0;
168 m_struct_size = 0;
169
Sean Callanan8c127202010-08-23 23:09:38 +0000170 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
171 member_index < num_members;
172 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000173 {
Sean Callanan8c127202010-08-23 23:09:38 +0000174 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000175
Sean Callanan8c127202010-08-23 23:09:38 +0000176 if (!member.m_jit_vars.get())
177 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000178
Sean Callanan8c127202010-08-23 23:09:38 +0000179 if (member_index == 0)
180 m_struct_alignment = member.m_jit_vars->m_alignment;
181
182 if (cursor % member.m_jit_vars->m_alignment)
183 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
184
185 member.m_jit_vars->m_offset = cursor;
186 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000187 }
188
189 m_struct_size = cursor;
190
191 m_struct_laid_out = true;
192 return true;
193}
194
195bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
196 size_t &size,
197 off_t &alignment)
198{
199 if (!m_struct_laid_out)
200 return false;
201
Sean Callanan8c127202010-08-23 23:09:38 +0000202 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000203 size = m_struct_size;
204 alignment = m_struct_alignment;
205
206 return true;
207}
208
209bool
210ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
211 llvm::Value *&value,
212 off_t &offset,
Sean Callanan45690fe2010-08-30 22:17:16 +0000213 const char *&name,
Sean Callanan8bce6652010-07-13 21:41:46 +0000214 uint32_t index)
215{
216 if (!m_struct_laid_out)
217 return false;
218
Sean Callanan8c127202010-08-23 23:09:38 +0000219 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000220 return false;
221
Sean Callanan8c127202010-08-23 23:09:38 +0000222 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000223
Sean Callanan8c127202010-08-23 23:09:38 +0000224 if (!member.m_parser_vars.get() ||
225 !member.m_jit_vars.get())
226 return false;
227
228 decl = member.m_parser_vars->m_named_decl;
229 value = member.m_parser_vars->m_llvm_value;
230 offset = member.m_jit_vars->m_offset;
Sean Callanan45690fe2010-08-30 22:17:16 +0000231 name = member.m_name.c_str();
Sean Callanan8c127202010-08-23 23:09:38 +0000232
Sean Callanan8bce6652010-07-13 21:41:46 +0000233 return true;
234}
235
Sean Callanan02fbafa2010-07-27 21:39:39 +0000236bool
237ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
238 llvm::Value**& value,
239 uint64_t &ptr)
Sean Callananba992c52010-07-27 02:07:53 +0000240{
Sean Callanan8c127202010-08-23 23:09:38 +0000241 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
242
243 if (!entity)
244 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000245
Sean Callanan8c127202010-08-23 23:09:38 +0000246 // We know m_parser_vars is valid since we searched for the variable by
247 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000248
Sean Callanan8c127202010-08-23 23:09:38 +0000249 value = &entity->m_parser_vars->m_llvm_value;
250 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
251
252 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000253}
254
Sean Callananf5857a02010-07-31 01:32:05 +0000255bool
256ClangExpressionDeclMap::GetFunctionAddress (const char *name,
257 uint64_t &ptr)
258{
259 // Back out in all cases where we're not fully initialized
260 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
261 return false;
262
263 ConstString name_cs(name);
264 SymbolContextList sym_ctxs;
265
266 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
267
268 if (!sym_ctxs.GetSize())
269 return false;
270
271 SymbolContext sym_ctx;
272 sym_ctxs.GetContextAtIndex(0, sym_ctx);
273
274 const Address *fun_address;
275
276 if (sym_ctx.function)
277 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
278 else if (sym_ctx.symbol)
279 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
280 else
281 return false;
282
Greg Claytoneea26402010-09-14 23:36:40 +0000283 ptr = fun_address->GetLoadAddress(m_exe_ctx->target);
Sean Callananf5857a02010-07-31 01:32:05 +0000284
285 return true;
286}
287
Sean Callanan810f22d2010-07-16 00:09:46 +0000288// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000289
290bool
291ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
292 lldb::addr_t &struct_address,
293 Error &err)
294{
295 bool result = DoMaterialize(false, exe_ctx, NULL, err);
296
297 if (result)
298 struct_address = m_materialized_location;
299
300 return result;
301}
302
303bool
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000304ClangExpressionDeclMap::GetObjectPointer(lldb::addr_t &object_ptr,
305 ExecutionContext *exe_ctx,
306 Error &err)
307{
308 if (!exe_ctx || !exe_ctx->frame || !exe_ctx->target || !exe_ctx->process)
309 {
310 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
311 return false;
312 }
313
314 if (!m_object_pointer_type.GetOpaqueQualType())
315 {
316 err.SetErrorString("Couldn't load 'this' because its type is unknown");
317 return false;
318 }
319
320 Variable *object_ptr_var = FindVariableInScope(*exe_ctx->frame, "this", &m_object_pointer_type);
321
322 if (!object_ptr_var)
323 {
324 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
325 return false;
326 }
327
328 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(*exe_ctx,
329 object_ptr_var,
330 m_object_pointer_type.GetASTContext()));
331
332 if (!location_value.get())
333 {
334 err.SetErrorString("Couldn't get the location for 'this'");
335 return false;
336 }
337
338 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
339 {
340 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
341 uint32_t address_byte_size = exe_ctx->target->GetArchitecture().GetAddressByteSize();
342 lldb::ByteOrder address_byte_order = exe_ctx->process->GetByteOrder();
343
344 if (ClangASTType::GetClangTypeBitWidth(m_object_pointer_type.GetASTContext(), m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
345 {
346 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
347 return false;
348 }
349
350 DataBufferHeap data;
351 data.SetByteSize(address_byte_size);
352 Error read_error;
353
354 if (exe_ctx->process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
355 {
356 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
357 return false;
358 }
359
360 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
361
362 uint32_t offset = 0;
363
364 object_ptr = extractor.GetPointer(&offset);
365
366 return true;
367 }
368 else
369 {
370 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
371 return false;
372 }
373}
374
375bool
Sean Callananf328c9f2010-07-20 23:31:16 +0000376ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000377 ClangExpressionVariable *&result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000378 Error &err)
379{
Sean Callanan82b74c82010-08-12 01:56:52 +0000380 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000381}
382
Sean Callanan32824aa2010-07-23 22:19:18 +0000383bool
384ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
385 Stream &s,
386 Error &err)
387{
388 if (!m_struct_laid_out)
389 {
390 err.SetErrorString("Structure hasn't been laid out yet");
391 return false;
392 }
393
394 if (!exe_ctx)
395 {
396 err.SetErrorString("Received null execution context");
397 return false;
398 }
399
400
401 if (!exe_ctx->process)
402 {
403 err.SetErrorString("Couldn't find the process");
404 return false;
405 }
406
407 if (!exe_ctx->target)
408 {
409 err.SetErrorString("Couldn't find the target");
410 return false;
411 }
412
413 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
414
415 Error error;
416 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
417 {
418 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
419 return false;
420 }
421
422 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
423
Sean Callanan8c127202010-08-23 23:09:38 +0000424 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
425 member_index < num_members;
426 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000427 {
Sean Callanan8c127202010-08-23 23:09:38 +0000428 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000429
Sean Callanan8c127202010-08-23 23:09:38 +0000430 s.Printf("[%s]\n", member.m_name.c_str());
431
432 if (!member.m_jit_vars.get())
433 return false;
434
435 extractor.Dump(&s, // stream
436 member.m_jit_vars->m_offset, // offset
437 lldb::eFormatBytesWithASCII, // format
438 1, // byte size of individual entries
439 member.m_jit_vars->m_size, // number of entries
440 16, // entries per line
441 m_materialized_location + member.m_jit_vars->m_offset, // address to print
442 0, // bit size (bitfields only; 0 means ignore)
443 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000444
445 s.PutChar('\n');
446 }
447
448 return true;
449}
450
Sean Callananf328c9f2010-07-20 23:31:16 +0000451bool
452ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
453 ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000454 ClangExpressionVariable **result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000455 Error &err)
Sean Callanan810f22d2010-07-16 00:09:46 +0000456{
Sean Callanan336a0002010-07-17 00:43:37 +0000457 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000458
Sean Callanan810f22d2010-07-16 00:09:46 +0000459 if (!m_struct_laid_out)
460 {
461 err.SetErrorString("Structure hasn't been laid out yet");
462 return LLDB_INVALID_ADDRESS;
463 }
464
Sean Callanan810f22d2010-07-16 00:09:46 +0000465 if (!exe_ctx)
466 {
467 err.SetErrorString("Received null execution context");
468 return LLDB_INVALID_ADDRESS;
469 }
470
Sean Callanan45839272010-07-24 01:37:44 +0000471 if (!exe_ctx->frame)
472 {
473 err.SetErrorString("Received null execution frame");
474 return LLDB_INVALID_ADDRESS;
475 }
476
Sean Callanane8a59a82010-09-13 21:34:21 +0000477 if (!m_struct_size)
478 {
479 if (log)
480 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
481
482 m_allocated_area = NULL;
483
484 return true;
485 }
486
Sean Callanan810f22d2010-07-16 00:09:46 +0000487 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
488
Sean Callananf328c9f2010-07-20 23:31:16 +0000489 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000490 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000491 if (m_materialized_location)
492 {
493 exe_ctx->process->DeallocateMemory(m_materialized_location);
494 m_materialized_location = 0;
495 }
496
497 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
498 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
499 err);
500
501 if (mem == LLDB_INVALID_ADDRESS)
502 return false;
503
504 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000505 }
506
Sean Callananf328c9f2010-07-20 23:31:16 +0000507 m_materialized_location = m_allocated_area;
508
509 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000510 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000511
Sean Callanan8c127202010-08-23 23:09:38 +0000512 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
513 member_index < num_members;
514 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000515 {
Sean Callanan8c127202010-08-23 23:09:38 +0000516 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000517
Sean Callanan8c127202010-08-23 23:09:38 +0000518 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000519 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000520
521 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
522 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str());
523
524 if (entity)
525 {
526 if (!member.m_jit_vars.get())
527 return false;
528
529 if (!DoMaterializeOneVariable(dematerialize, *exe_ctx, sym_ctx, member.m_name.c_str(), member.m_user_type, m_materialized_location + member.m_jit_vars->m_offset, err))
530 return false;
531 }
532 else if (persistent_variable)
533 {
Sean Callanan45690fe2010-08-30 22:17:16 +0000534 if (!member.m_name.compare(m_result_name))
535 {
536 if (!dematerialize)
537 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000538
Sean Callanan8c127202010-08-23 23:09:38 +0000539 if (log)
540 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000541
Sean Callanan8c127202010-08-23 23:09:38 +0000542 *result = &member;
543 }
544
Sean Callanan45690fe2010-08-30 22:17:16 +0000545 if (log)
546 log->Printf("Searched for persistent variable %s and found %s", member.m_name.c_str(), persistent_variable->m_name.c_str());
547
Sean Callanan8c127202010-08-23 23:09:38 +0000548 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err))
549 return false;
550 }
551 else
552 {
553 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str());
554 return false;
555 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000556 }
557
Sean Callananf328c9f2010-07-20 23:31:16 +0000558 return true;
559}
560
Sean Callanana48fe162010-08-11 03:57:18 +0000561bool
562ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
563 ExecutionContext &exe_ctx,
564 const char *name,
565 lldb::addr_t addr,
566 Error &err)
Sean Callanan45690fe2010-08-30 22:17:16 +0000567{
Sean Callanana6223432010-08-20 01:02:30 +0000568 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000569
570 if (!pvar)
571 {
572 err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
573 return LLDB_INVALID_ADDRESS;
574 }
575
576 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000577
578 if (!pvar->m_data_vars.get())
579 return false;
580
581 uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000582 Error error;
583
584 if (dematerialize)
585 {
586 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
587 {
588 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
589 return false;
590 }
591 }
592 else
593 {
594 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
595 {
596 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
597 return false;
598 }
599 }
600
601 return true;
602}
603
Sean Callananf328c9f2010-07-20 23:31:16 +0000604bool
605ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
606 ExecutionContext &exe_ctx,
607 const SymbolContext &sym_ctx,
608 const char *name,
609 TypeFromUser type,
610 lldb::addr_t addr,
611 Error &err)
612{
613 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
614
Sean Callanancc074622010-09-14 21:59:34 +0000615 if (!exe_ctx.frame)
616 return false;
617
618 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000619
620 if (!var)
621 {
622 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
623 return false;
624 }
625
Sean Callanan841026f2010-07-23 00:16:21 +0000626 if (log)
627 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000628
629 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
630 var,
631 type.GetASTContext()));
632
633 if (!location_value.get())
634 {
635 err.SetErrorStringWithFormat("Couldn't get value for %s", name);
636 return false;
637 }
638
639 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
640 {
641 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
642
Greg Clayton960d6a42010-08-03 00:35:52 +0000643 size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000644 size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
645
646 DataBufferHeap data;
647 data.SetByteSize(byte_size);
648
649 lldb::addr_t src_addr;
650 lldb::addr_t dest_addr;
651
652 if (dematerialize)
653 {
654 src_addr = addr;
655 dest_addr = value_addr;
656 }
657 else
658 {
659 src_addr = value_addr;
660 dest_addr = addr;
661 }
662
663 Error error;
664 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
665 {
666 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
667 return false;
668 }
669
670 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
671 {
672 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
673 return false;
674 }
675
676 if (log)
677 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
678 }
679 else
680 {
681 StreamString ss;
682
683 location_value->Dump(&ss);
684
685 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
686 }
687
688 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000689}
690
Sean Callanancc074622010-09-14 21:59:34 +0000691Variable *
692ClangExpressionDeclMap::FindVariableInScope(StackFrame &frame,
693 const char *name,
694 TypeFromUser *type)
695{
696 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
697
698 ConstString name_cs(name);
699
700 VariableList *var_list = frame.GetVariableList(true);
701
702 lldb::VariableSP var = var_list->FindVariable(name_cs);
703
704 if (!var)
705 return NULL;
706
707 if (!type)
708 return var.get();
709
710 if (type->GetASTContext() == var->GetType()->GetClangAST())
711 {
Greg Clayton462d4142010-09-29 01:12:09 +0000712 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetClangType()))
Sean Callanancc074622010-09-14 21:59:34 +0000713 return NULL;
714 }
715 else
716 {
717 if (log)
718 log->PutCString("Skipping a candidate variable because of different AST contexts");
719 return NULL;
720 }
721
722 return var.get();
723
724 return NULL;
725}
Sean Callanan336a0002010-07-17 00:43:37 +0000726
Chris Lattner24943d22010-06-08 16:52:24 +0000727// Interface for ClangASTSource
728void
729ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
730 const char *name)
731{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000732 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000733
Sean Callanan810f22d2010-07-16 00:09:46 +0000734 if (log)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000735 log->Printf("Hunting for a definition for %s", name);
Chris Lattner24943d22010-06-08 16:52:24 +0000736
737 // Back out in all cases where we're not fully initialized
738 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
739 return;
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000740
741 ConstString name_cs(name);
Sean Callanancc074622010-09-14 21:59:34 +0000742
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000743 if (!strcmp(name, "___clang_class"))
744 {
745 // Clang is looking for the type of "this"
746
747 VariableList *vars = m_exe_ctx->frame->GetVariableList(false);
748
749 if (!vars)
750 return;
751
752 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
753
754 if (!this_var)
755 return;
756
757 Type *this_type = this_var->GetType();
758
759 if (!this_type)
760 return;
761
Greg Clayton462d4142010-09-29 01:12:09 +0000762 TypeFromUser this_user_type(this_type->GetClangType(),
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000763 this_type->GetClangAST());
764
765 m_object_pointer_type = this_user_type;
766
767 void *pointer_target_type;
768
769 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
770 &pointer_target_type))
771 return;
772
773 TypeFromUser class_user_type(pointer_target_type,
774 this_type->GetClangAST());
775
776 AddOneType(context, class_user_type, true);
777
778 return;
779 }
780
Sean Callanan0fc73582010-07-27 00:55:47 +0000781 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +0000782
Sean Callanan0fc73582010-07-27 00:55:47 +0000783 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000784
Sean Callanan92aa6662010-09-07 21:49:41 +0000785 bool found_generic = false;
786 bool found_specific = false;
787
Sean Callanan0fc73582010-07-27 00:55:47 +0000788 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
789 index < num_indices;
790 ++index)
791 {
792 SymbolContext sym_ctx;
793 sym_ctxs.GetContextAtIndex(index, sym_ctx);
794
795 if (sym_ctx.function)
Sean Callanan92aa6662010-09-07 21:49:41 +0000796 {
797 // TODO only do this if it's a C function; C++ functions may be
798 // overloaded
799 if (!found_specific)
800 AddOneFunction(context, sym_ctx.function, NULL);
801 found_specific = true;
802 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000803 else if(sym_ctx.symbol)
Sean Callanan92aa6662010-09-07 21:49:41 +0000804 {
805 if (!found_generic && !found_specific)
806 {
807 AddOneFunction(context, NULL, sym_ctx.symbol);
808 found_generic = true;
809 }
810 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000811 }
812
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000813 Variable *var = FindVariableInScope(*m_exe_ctx->frame, name);
Sean Callanan336a0002010-07-17 00:43:37 +0000814
815 if (var)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000816 AddOneVariable(context, var);
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000817
Sean Callanana6223432010-08-20 01:02:30 +0000818 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000819
820 if (pvar)
821 AddOneVariable(context, pvar);
822
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000823
Sean Callanan6df08402010-09-27 23:54:58 +0000824 // See information on gating of this operation next to the definition for
825 // m_lookedup_types.
826
827 const char *name_uniq = name_cs.GetCString();
828
829 if (m_lookedup_types.find(name_uniq) == m_lookedup_types.end())
830 {
831 // 1 The name is added to m_lookedup_types.
832 m_lookedup_types.insert(std::pair<const char*, bool>(name_uniq, true));
833
834 // 2 The type is looked up and added, potentially causing more type loookups.
835 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
836
837 if (type.get())
838 {
Greg Clayton462d4142010-09-29 01:12:09 +0000839 TypeFromUser user_type(type->GetClangType(),
Sean Callanan6df08402010-09-27 23:54:58 +0000840 type->GetClangAST());
841
842 AddOneType(context, user_type, false);
843 }
844
845 // 3 The name is removed from m_lookedup_types.
846 m_lookedup_types.erase(name_uniq);
847 }
848
Sean Callanan336a0002010-07-17 00:43:37 +0000849}
850
851Value *
852ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
853 Variable *var,
Sean Callananf328c9f2010-07-20 23:31:16 +0000854 clang::ASTContext *parser_ast_context,
855 TypeFromUser *user_type,
856 TypeFromParser *parser_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000857{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000858 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
859
Chris Lattner24943d22010-06-08 16:52:24 +0000860 Type *var_type = var->GetType();
861
862 if (!var_type)
863 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000864 if (log)
865 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +0000866 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000867 }
868
Greg Clayton462d4142010-09-29 01:12:09 +0000869 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +0000870
871 if (!var_opaque_type)
872 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000873 if (log)
874 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +0000875 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000876 }
877
Chris Lattner24943d22010-06-08 16:52:24 +0000878 TypeList *type_list = var_type->GetTypeList();
879
880 if (!type_list)
881 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000882 if (log)
883 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +0000884 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000885 }
886
887 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
888
889 if (!exe_ast_ctx)
890 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000891 if (log)
892 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +0000893 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000894 }
895
Sean Callanan336a0002010-07-17 00:43:37 +0000896 DWARFExpression &var_location_expr = var->LocationExpression();
897
Chris Lattner24943d22010-06-08 16:52:24 +0000898 std::auto_ptr<Value> var_location(new Value);
899
Greg Clayton178710c2010-09-14 02:20:48 +0000900 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
901
902 if (var_location_expr.IsLocationList())
903 {
904 SymbolContext var_sc;
905 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +0000906 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +0000907 }
Chris Lattner24943d22010-06-08 16:52:24 +0000908 Error err;
909
Greg Clayton178710c2010-09-14 02:20:48 +0000910 if (!var_location_expr.Evaluate(&exe_ctx, exe_ast_ctx, loclist_base_load_addr, NULL, *var_location.get(), &err))
Chris Lattner24943d22010-06-08 16:52:24 +0000911 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000912 if (log)
913 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +0000914 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000915 }
916
Sean Callanan810f22d2010-07-16 00:09:46 +0000917 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
918
Sean Callanan336a0002010-07-17 00:43:37 +0000919 void *type_to_use;
920
Sean Callananf328c9f2010-07-20 23:31:16 +0000921 if (parser_ast_context)
922 {
923 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
924
925 if (parser_type)
926 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
927 }
Sean Callanan336a0002010-07-17 00:43:37 +0000928 else
929 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000930
931 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +0000932 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +0000933
934 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
935 {
936 SymbolContext var_sc;
937 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +0000938
Chris Lattner24943d22010-06-08 16:52:24 +0000939 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +0000940 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000941
942 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
943
944 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +0000945 return NULL;
946
Chris Lattner24943d22010-06-08 16:52:24 +0000947 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
948
Greg Claytoneea26402010-09-14 23:36:40 +0000949 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->target);
Chris Lattner24943d22010-06-08 16:52:24 +0000950
951 var_location->GetScalar() = load_addr;
952 var_location->SetValueType(Value::eValueTypeLoadAddress);
953 }
954
Sean Callananf328c9f2010-07-20 23:31:16 +0000955 if (user_type)
956 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +0000957
958 return var_location.release();
959}
960
961void
962ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000963 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +0000964{
965 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
966
Sean Callananf328c9f2010-07-20 23:31:16 +0000967 TypeFromUser ut;
968 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +0000969
970 Value *var_location = GetVariableValue(*m_exe_ctx,
971 var,
972 context.GetASTContext(),
Sean Callananf328c9f2010-07-20 23:31:16 +0000973 &ut,
974 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +0000975
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000976 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +0000977
Sean Callanan8c127202010-08-23 23:09:38 +0000978 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000979 entity.m_name = context.Name.getAsString();
Sean Callanan8c127202010-08-23 23:09:38 +0000980 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +0000981
Sean Callanan8c127202010-08-23 23:09:38 +0000982 entity.EnableParserVars();
983 entity.m_parser_vars->m_parser_type = pt;
984 entity.m_parser_vars->m_named_decl = var_decl;
985 entity.m_parser_vars->m_llvm_value = NULL;
986 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +0000987
Sean Callanan810f22d2010-07-16 00:09:46 +0000988 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +0000989 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000990}
991
992void
Sean Callanana48fe162010-08-11 03:57:18 +0000993ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +0000994 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +0000995{
Sean Callanan45690fe2010-08-30 22:17:16 +0000996 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
997
Sean Callanana6223432010-08-20 01:02:30 +0000998 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +0000999
1000 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
1001 user_type.GetASTContext(),
1002 user_type.GetOpaqueQualType()),
1003 context.GetASTContext());
1004
Sean Callanan8c127202010-08-23 23:09:38 +00001005 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1006
1007 pvar->EnableParserVars();
1008 pvar->m_parser_vars->m_parser_type = parser_type;
1009 pvar->m_parser_vars->m_named_decl = var_decl;
1010 pvar->m_parser_vars->m_llvm_value = NULL;
1011 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001012
1013 if (log)
1014 log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.c_str(), var_decl);
Sean Callanana48fe162010-08-11 03:57:18 +00001015}
1016
1017void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001018ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001019 Function* fun,
1020 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001021{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001022 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001023
Sean Callanan0fc73582010-07-27 00:55:47 +00001024 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001025 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001026 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001027
Sean Callanan0fc73582010-07-27 00:55:47 +00001028 // only valid for Functions, not for Symbols
1029 void *fun_opaque_type = NULL;
1030 clang::ASTContext *fun_ast_context = NULL;
1031
1032 if (fun)
1033 {
Sean Callanan55261a12010-09-08 22:38:54 +00001034#define BROKEN_OVERLOADING
1035 // Awaiting a fix on the Clang side
1036#ifndef BROKEN_OVERLOADING
Sean Callanan0fc73582010-07-27 00:55:47 +00001037 Type *fun_type = fun->GetType();
1038
1039 if (!fun_type)
1040 {
1041 if (log)
1042 log->PutCString("Skipped a function because it has no type");
1043 return;
1044 }
1045
Greg Clayton462d4142010-09-29 01:12:09 +00001046 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001047
1048 if (!fun_opaque_type)
1049 {
1050 if (log)
1051 log->PutCString("Skipped a function because it has no Clang type");
1052 return;
1053 }
1054
1055 fun_address = &fun->GetAddressRange().GetBaseAddress();
1056
1057 TypeList *type_list = fun_type->GetTypeList();
1058 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1059 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1060
1061 fun_decl = context.AddFunDecl(copied_type);
Sean Callanan55261a12010-09-08 22:38:54 +00001062#else
1063 fun_address = &fun->GetAddressRange().GetBaseAddress();
1064
1065 fun_decl = context.AddGenericFunDecl();
1066#endif
Sean Callanan0fc73582010-07-27 00:55:47 +00001067 }
1068 else if (symbol)
1069 {
1070 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1071
1072 fun_decl = context.AddGenericFunDecl();
1073 }
1074 else
1075 {
1076 if (log)
1077 log->PutCString("AddOneFunction called with no function and no symbol");
1078 return;
1079 }
1080
Greg Claytoneea26402010-09-14 23:36:40 +00001081 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001082 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1083 fun_location->GetScalar() = load_addr;
1084
Sean Callanan8c127202010-08-23 23:09:38 +00001085 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1086 entity.m_name = context.Name.getAsString();
1087 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001088
Sean Callanan8c127202010-08-23 23:09:38 +00001089 entity.EnableParserVars();
1090 entity.m_parser_vars->m_named_decl = fun_decl;
1091 entity.m_parser_vars->m_llvm_value = NULL;
1092 entity.m_parser_vars->m_lldb_value = fun_location.release();
1093
Sean Callanan810f22d2010-07-16 00:09:46 +00001094 if (log)
Sean Callanan92aa6662010-09-07 21:49:41 +00001095 log->Printf("Found %s function %s, returned (NamedDecl)%p", (fun ? "specific" : "generic"), context.Name.getAsString().c_str(), fun_decl);
Chris Lattner24943d22010-06-08 16:52:24 +00001096}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001097
1098void
1099ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001100 TypeFromUser &ut,
1101 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001102{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001103 clang::ASTContext *parser_ast_context = context.GetASTContext();
1104 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001105
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001106 void *copied_type = ClangASTContext::CopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
1107
1108 TypeFromParser parser_type(copied_type, parser_ast_context);
1109
1110 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1111 {
1112 void *args[1];
1113
1114 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1115
1116 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1117 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1118 args,
1119 1,
1120 false,
1121 ClangASTContext::GetTypeQualifiers(copied_type));
1122
Greg Clayton1d8173f2010-09-24 05:15:53 +00001123 const bool is_virtual = false;
1124 const bool is_static = false;
1125 const bool is_inline = false;
1126
1127 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1128 copied_type,
1129 "___clang_expr",
1130 method_type,
1131 lldb::eAccessPublic,
1132 is_virtual,
1133 is_static,
1134 is_inline);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001135 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001136
1137 context.AddTypeDecl(copied_type);
1138}