blob: 3846a7f7392a0f754c8742ac99c992f8c4b1c5c9 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lldb/Expression/ClangExpressionDeclMap.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
16#include "lldb/lldb-private.h"
17#include "lldb/Core/Address.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000018#include "lldb/Core/Error.h"
Sean Callanan6184dfe2010-06-23 00:47:48 +000019#include "lldb/Core/Log.h"
Chris Lattner24943d22010-06-08 16:52:24 +000020#include "lldb/Core/Module.h"
21#include "lldb/Expression/ClangASTSource.h"
Sean Callanana48fe162010-08-11 03:57:18 +000022#include "lldb/Expression/ClangPersistentVariables.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Symbol/ClangASTContext.h"
24#include "lldb/Symbol/CompileUnit.h"
25#include "lldb/Symbol/Function.h"
26#include "lldb/Symbol/ObjectFile.h"
27#include "lldb/Symbol/SymbolContext.h"
28#include "lldb/Symbol/Type.h"
29#include "lldb/Symbol/TypeList.h"
30#include "lldb/Symbol/Variable.h"
31#include "lldb/Symbol/VariableList.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000032#include "lldb/Target/ExecutionContext.h"
Sean Callanan810f22d2010-07-16 00:09:46 +000033#include "lldb/Target/Process.h"
Chris Lattner24943d22010-06-08 16:52:24 +000034#include "lldb/Target/StackFrame.h"
Sean Callananf328c9f2010-07-20 23:31:16 +000035#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000036
Chris Lattner24943d22010-06-08 16:52:24 +000037using namespace lldb_private;
38using namespace clang;
39
Sean Callanana48fe162010-08-11 03:57:18 +000040ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) :
41 m_exe_ctx(exe_ctx), m_struct_laid_out(false),
Sean Callanan810f22d2010-07-16 00:09:46 +000042 m_materialized_location(0)
Chris Lattner24943d22010-06-08 16:52:24 +000043{
44 if (exe_ctx && exe_ctx->frame)
45 m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
46 else
47 m_sym_ctx = NULL;
Sean Callanana48fe162010-08-11 03:57:18 +000048
49 if (exe_ctx && exe_ctx->process)
50 m_persistent_vars = &exe_ctx->process->GetPersistentVariables();
Chris Lattner24943d22010-06-08 16:52:24 +000051}
52
53ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callanan8c127202010-08-23 23:09:38 +000054{
55 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
56 entity_index < num_entities;
57 ++entity_index)
58 {
59 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
60 if (entity.m_parser_vars.get() &&
61 entity.m_parser_vars->m_lldb_value)
62 delete entity.m_parser_vars->m_lldb_value;
Sean Callanan45690fe2010-08-30 22:17:16 +000063
64 entity.DisableParserVars();
65 }
66
67 for (uint64_t pvar_index = 0, num_pvars = m_persistent_vars->Size();
68 pvar_index < num_pvars;
69 ++pvar_index)
70 {
71 ClangExpressionVariable &pvar(m_persistent_vars->VariableAtIndex(pvar_index));
72 pvar.DisableParserVars();
Sean Callanan8c127202010-08-23 23:09:38 +000073 }
Chris Lattner24943d22010-06-08 16:52:24 +000074
75 if (m_sym_ctx)
76 delete m_sym_ctx;
77}
78
Sean Callanan8bce6652010-07-13 21:41:46 +000079// Interface for IRForTarget
80
Sean Callanan82b74c82010-08-12 01:56:52 +000081void
82ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
83{
84 m_persistent_vars->GetNextResultName(m_result_name);
85
86 name = m_result_name;
87}
88
Sean Callanan8bce6652010-07-13 21:41:46 +000089bool
Sean Callanan8c127202010-08-23 23:09:38 +000090ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl,
91 const char *name,
92 TypeFromParser parser_type)
Sean Callanana48fe162010-08-11 03:57:18 +000093{
94 clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
95
Sean Callanana48fe162010-08-11 03:57:18 +000096 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +000097 parser_type.GetASTContext(),
98 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +000099 context);
100
Sean Callanan8c127202010-08-23 23:09:38 +0000101 if (!m_persistent_vars->CreatePersistentVariable (name, user_type))
102 return false;
103
104 ClangExpressionVariable *var = m_persistent_vars->GetVariable(name);
105
106 if (!var)
107 return false;
108
109 var->EnableParserVars();
110
111 var->m_parser_vars->m_named_decl = decl;
112 var->m_parser_vars->m_parser_type = parser_type;
113
114 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000115}
116
117bool
Sean Callanan8c127202010-08-23 23:09:38 +0000118ClangExpressionDeclMap::AddValueToStruct (const clang::NamedDecl *decl,
Sean Callanan45690fe2010-08-30 22:17:16 +0000119 const char *name,
Sean Callanan8c127202010-08-23 23:09:38 +0000120 llvm::Value *value,
Sean Callanan8bce6652010-07-13 21:41:46 +0000121 size_t size,
122 off_t alignment)
123{
Sean Callanan45690fe2010-08-30 22:17:16 +0000124 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
125
Sean Callanan8bce6652010-07-13 21:41:46 +0000126 m_struct_laid_out = false;
127
Sean Callanan8c127202010-08-23 23:09:38 +0000128 if (m_struct_members.GetVariable(decl))
129 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000130
Sean Callanan8c127202010-08-23 23:09:38 +0000131 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000132
Sean Callanan8c127202010-08-23 23:09:38 +0000133 if (!var)
134 var = m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000135
Sean Callanan8c127202010-08-23 23:09:38 +0000136 if (!var)
137 return false;
138
Sean Callanan45690fe2010-08-30 22:17:16 +0000139 if (log)
140 log->Printf("Adding value for decl %p [%s - %s] to the structure",
141 decl,
142 name,
143 var->m_name.c_str());
144
Sean Callanan8c127202010-08-23 23:09:38 +0000145 // We know entity->m_parser_vars is valid because we used a parser variable
146 // to find it
147 var->m_parser_vars->m_llvm_value = value;
148
149 var->EnableJITVars();
150 var->m_jit_vars->m_alignment = alignment;
151 var->m_jit_vars->m_size = size;
152
153 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000154
155 return true;
156}
157
158bool
159ClangExpressionDeclMap::DoStructLayout ()
160{
161 if (m_struct_laid_out)
162 return true;
163
Sean Callanan8bce6652010-07-13 21:41:46 +0000164 off_t cursor = 0;
165
166 m_struct_alignment = 0;
167 m_struct_size = 0;
168
Sean Callanan8c127202010-08-23 23:09:38 +0000169 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
170 member_index < num_members;
171 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000172 {
Sean Callanan8c127202010-08-23 23:09:38 +0000173 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000174
Sean Callanan8c127202010-08-23 23:09:38 +0000175 if (!member.m_jit_vars.get())
176 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000177
Sean Callanan8c127202010-08-23 23:09:38 +0000178 if (member_index == 0)
179 m_struct_alignment = member.m_jit_vars->m_alignment;
180
181 if (cursor % member.m_jit_vars->m_alignment)
182 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
183
184 member.m_jit_vars->m_offset = cursor;
185 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000186 }
187
188 m_struct_size = cursor;
189
190 m_struct_laid_out = true;
191 return true;
192}
193
194bool ClangExpressionDeclMap::GetStructInfo (uint32_t &num_elements,
195 size_t &size,
196 off_t &alignment)
197{
198 if (!m_struct_laid_out)
199 return false;
200
Sean Callanan8c127202010-08-23 23:09:38 +0000201 num_elements = m_struct_members.Size();
Sean Callanan8bce6652010-07-13 21:41:46 +0000202 size = m_struct_size;
203 alignment = m_struct_alignment;
204
205 return true;
206}
207
208bool
209ClangExpressionDeclMap::GetStructElement (const clang::NamedDecl *&decl,
210 llvm::Value *&value,
211 off_t &offset,
Sean Callanan45690fe2010-08-30 22:17:16 +0000212 const char *&name,
Sean Callanan8bce6652010-07-13 21:41:46 +0000213 uint32_t index)
214{
215 if (!m_struct_laid_out)
216 return false;
217
Sean Callanan8c127202010-08-23 23:09:38 +0000218 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000219 return false;
220
Sean Callanan8c127202010-08-23 23:09:38 +0000221 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000222
Sean Callanan8c127202010-08-23 23:09:38 +0000223 if (!member.m_parser_vars.get() ||
224 !member.m_jit_vars.get())
225 return false;
226
227 decl = member.m_parser_vars->m_named_decl;
228 value = member.m_parser_vars->m_llvm_value;
229 offset = member.m_jit_vars->m_offset;
Sean Callanan45690fe2010-08-30 22:17:16 +0000230 name = member.m_name.c_str();
Sean Callanan8c127202010-08-23 23:09:38 +0000231
Sean Callanan8bce6652010-07-13 21:41:46 +0000232 return true;
233}
234
Sean Callanan02fbafa2010-07-27 21:39:39 +0000235bool
236ClangExpressionDeclMap::GetFunctionInfo (const clang::NamedDecl *decl,
237 llvm::Value**& value,
238 uint64_t &ptr)
Sean Callananba992c52010-07-27 02:07:53 +0000239{
Sean Callanan8c127202010-08-23 23:09:38 +0000240 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
241
242 if (!entity)
243 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000244
Sean Callanan8c127202010-08-23 23:09:38 +0000245 // We know m_parser_vars is valid since we searched for the variable by
246 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000247
Sean Callanan8c127202010-08-23 23:09:38 +0000248 value = &entity->m_parser_vars->m_llvm_value;
249 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
250
251 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000252}
253
Sean Callananf5857a02010-07-31 01:32:05 +0000254bool
255ClangExpressionDeclMap::GetFunctionAddress (const char *name,
256 uint64_t &ptr)
257{
258 // Back out in all cases where we're not fully initialized
259 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
260 return false;
261
262 ConstString name_cs(name);
263 SymbolContextList sym_ctxs;
264
265 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
266
267 if (!sym_ctxs.GetSize())
268 return false;
269
270 SymbolContext sym_ctx;
271 sym_ctxs.GetContextAtIndex(0, sym_ctx);
272
273 const Address *fun_address;
274
275 if (sym_ctx.function)
276 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
277 else if (sym_ctx.symbol)
278 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
279 else
280 return false;
281
282 ptr = fun_address->GetLoadAddress(m_exe_ctx->process);
283
284 return true;
285}
286
Sean Callanan810f22d2010-07-16 00:09:46 +0000287// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000288
289bool
290ClangExpressionDeclMap::Materialize (ExecutionContext *exe_ctx,
291 lldb::addr_t &struct_address,
292 Error &err)
293{
294 bool result = DoMaterialize(false, exe_ctx, NULL, err);
295
296 if (result)
297 struct_address = m_materialized_location;
298
299 return result;
300}
301
302bool
303ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000304 ClangExpressionVariable *&result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000305 Error &err)
306{
Sean Callanan82b74c82010-08-12 01:56:52 +0000307 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000308}
309
Sean Callanan32824aa2010-07-23 22:19:18 +0000310bool
311ClangExpressionDeclMap::DumpMaterializedStruct(ExecutionContext *exe_ctx,
312 Stream &s,
313 Error &err)
314{
315 if (!m_struct_laid_out)
316 {
317 err.SetErrorString("Structure hasn't been laid out yet");
318 return false;
319 }
320
321 if (!exe_ctx)
322 {
323 err.SetErrorString("Received null execution context");
324 return false;
325 }
326
327
328 if (!exe_ctx->process)
329 {
330 err.SetErrorString("Couldn't find the process");
331 return false;
332 }
333
334 if (!exe_ctx->target)
335 {
336 err.SetErrorString("Couldn't find the target");
337 return false;
338 }
339
340 lldb::DataBufferSP data(new DataBufferHeap(m_struct_size, 0));
341
342 Error error;
343 if (exe_ctx->process->ReadMemory (m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
344 {
345 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
346 return false;
347 }
348
349 DataExtractor extractor(data, exe_ctx->process->GetByteOrder(), exe_ctx->target->GetArchitecture().GetAddressByteSize());
350
Sean Callanan8c127202010-08-23 23:09:38 +0000351 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
352 member_index < num_members;
353 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000354 {
Sean Callanan8c127202010-08-23 23:09:38 +0000355 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000356
Sean Callanan8c127202010-08-23 23:09:38 +0000357 s.Printf("[%s]\n", member.m_name.c_str());
358
359 if (!member.m_jit_vars.get())
360 return false;
361
362 extractor.Dump(&s, // stream
363 member.m_jit_vars->m_offset, // offset
364 lldb::eFormatBytesWithASCII, // format
365 1, // byte size of individual entries
366 member.m_jit_vars->m_size, // number of entries
367 16, // entries per line
368 m_materialized_location + member.m_jit_vars->m_offset, // address to print
369 0, // bit size (bitfields only; 0 means ignore)
370 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000371
372 s.PutChar('\n');
373 }
374
375 return true;
376}
377
Sean Callananf328c9f2010-07-20 23:31:16 +0000378bool
379ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
380 ExecutionContext *exe_ctx,
Sean Callanana6223432010-08-20 01:02:30 +0000381 ClangExpressionVariable **result,
Sean Callananf328c9f2010-07-20 23:31:16 +0000382 Error &err)
Sean Callanan810f22d2010-07-16 00:09:46 +0000383{
Sean Callanan336a0002010-07-17 00:43:37 +0000384 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan82b74c82010-08-12 01:56:52 +0000385
Sean Callanan810f22d2010-07-16 00:09:46 +0000386 if (!m_struct_laid_out)
387 {
388 err.SetErrorString("Structure hasn't been laid out yet");
389 return LLDB_INVALID_ADDRESS;
390 }
391
Sean Callanan810f22d2010-07-16 00:09:46 +0000392 if (!exe_ctx)
393 {
394 err.SetErrorString("Received null execution context");
395 return LLDB_INVALID_ADDRESS;
396 }
397
Sean Callanan45839272010-07-24 01:37:44 +0000398 if (!exe_ctx->frame)
399 {
400 err.SetErrorString("Received null execution frame");
401 return LLDB_INVALID_ADDRESS;
402 }
403
Sean Callanane8a59a82010-09-13 21:34:21 +0000404 if (!m_struct_size)
405 {
406 if (log)
407 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
408
409 m_allocated_area = NULL;
410
411 return true;
412 }
413
Sean Callanan810f22d2010-07-16 00:09:46 +0000414 const SymbolContext &sym_ctx(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything));
415
Sean Callananf328c9f2010-07-20 23:31:16 +0000416 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000417 {
Sean Callananf328c9f2010-07-20 23:31:16 +0000418 if (m_materialized_location)
419 {
420 exe_ctx->process->DeallocateMemory(m_materialized_location);
421 m_materialized_location = 0;
422 }
423
424 lldb::addr_t mem = exe_ctx->process->AllocateMemory(m_struct_alignment + m_struct_size,
425 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
426 err);
427
428 if (mem == LLDB_INVALID_ADDRESS)
429 return false;
430
431 m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000432 }
433
Sean Callananf328c9f2010-07-20 23:31:16 +0000434 m_materialized_location = m_allocated_area;
435
436 if (m_materialized_location % m_struct_alignment)
Sean Callananf328c9f2010-07-20 23:31:16 +0000437 m_materialized_location += (m_struct_alignment - (m_materialized_location % m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000438
Sean Callanan8c127202010-08-23 23:09:38 +0000439 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
440 member_index < num_members;
441 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000442 {
Sean Callanan8c127202010-08-23 23:09:38 +0000443 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000444
Sean Callanan8c127202010-08-23 23:09:38 +0000445 if (!member.m_parser_vars.get())
Sean Callanan336a0002010-07-17 00:43:37 +0000446 return false;
Sean Callanan8c127202010-08-23 23:09:38 +0000447
448 ClangExpressionVariable *entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
449 ClangExpressionVariable *persistent_variable = m_persistent_vars->GetVariable(member.m_name.c_str());
450
451 if (entity)
452 {
453 if (!member.m_jit_vars.get())
454 return false;
455
456 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))
457 return false;
458 }
459 else if (persistent_variable)
460 {
Sean Callanan45690fe2010-08-30 22:17:16 +0000461 if (!member.m_name.compare(m_result_name))
462 {
463 if (!dematerialize)
464 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000465
Sean Callanan8c127202010-08-23 23:09:38 +0000466 if (log)
467 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000468
Sean Callanan8c127202010-08-23 23:09:38 +0000469 *result = &member;
470 }
471
Sean Callanan45690fe2010-08-30 22:17:16 +0000472 if (log)
473 log->Printf("Searched for persistent variable %s and found %s", member.m_name.c_str(), persistent_variable->m_name.c_str());
474
Sean Callanan8c127202010-08-23 23:09:38 +0000475 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, persistent_variable->m_name.c_str(), m_materialized_location + member.m_jit_vars->m_offset, err))
476 return false;
477 }
478 else
479 {
480 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.c_str());
481 return false;
482 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000483 }
484
Sean Callananf328c9f2010-07-20 23:31:16 +0000485 return true;
486}
487
Sean Callanana48fe162010-08-11 03:57:18 +0000488bool
489ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize,
490 ExecutionContext &exe_ctx,
491 const char *name,
492 lldb::addr_t addr,
493 Error &err)
Sean Callanan45690fe2010-08-30 22:17:16 +0000494{
Sean Callanana6223432010-08-20 01:02:30 +0000495 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000496
497 if (!pvar)
498 {
499 err.SetErrorStringWithFormat("Undefined persistent variable %s", name);
500 return LLDB_INVALID_ADDRESS;
501 }
502
503 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000504
505 if (!pvar->m_data_vars.get())
506 return false;
507
508 uint8_t *pvar_data = pvar->m_data_vars->m_data->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000509 Error error;
510
511 if (dematerialize)
512 {
513 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
514 {
515 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
516 return false;
517 }
518 }
519 else
520 {
521 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
522 {
523 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
524 return false;
525 }
526 }
527
528 return true;
529}
530
Sean Callananf328c9f2010-07-20 23:31:16 +0000531bool
532ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize,
533 ExecutionContext &exe_ctx,
534 const SymbolContext &sym_ctx,
535 const char *name,
536 TypeFromUser type,
537 lldb::addr_t addr,
538 Error &err)
539{
540 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
541
Sean Callanancc074622010-09-14 21:59:34 +0000542 if (!exe_ctx.frame)
543 return false;
544
545 Variable *var = FindVariableInScope(*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000546
547 if (!var)
548 {
549 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name);
550 return false;
551 }
552
Sean Callanan841026f2010-07-23 00:16:21 +0000553 if (log)
554 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name, type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000555
556 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
557 var,
558 type.GetASTContext()));
559
560 if (!location_value.get())
561 {
562 err.SetErrorStringWithFormat("Couldn't get value for %s", name);
563 return false;
564 }
565
566 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
567 {
568 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
569
Greg Clayton960d6a42010-08-03 00:35:52 +0000570 size_t bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000571 size_t byte_size = bit_size % 8 ? ((bit_size + 8) / 8) : (bit_size / 8);
572
573 DataBufferHeap data;
574 data.SetByteSize(byte_size);
575
576 lldb::addr_t src_addr;
577 lldb::addr_t dest_addr;
578
579 if (dematerialize)
580 {
581 src_addr = addr;
582 dest_addr = value_addr;
583 }
584 else
585 {
586 src_addr = value_addr;
587 dest_addr = addr;
588 }
589
590 Error error;
591 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), byte_size, error) != byte_size)
592 {
593 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
594 return false;
595 }
596
597 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), byte_size, error) != byte_size)
598 {
599 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
600 return false;
601 }
602
603 if (log)
604 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
605 }
606 else
607 {
608 StreamString ss;
609
610 location_value->Dump(&ss);
611
612 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name, ss.GetString().c_str());
613 }
614
615 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000616}
617
Sean Callanancc074622010-09-14 21:59:34 +0000618#ifdef OLD_CODE
Sean Callanan336a0002010-07-17 00:43:37 +0000619Variable*
620ClangExpressionDeclMap::FindVariableInScope(const SymbolContext &sym_ctx,
621 const char *name,
Sean Callananf328c9f2010-07-20 23:31:16 +0000622 TypeFromUser *type)
Sean Callanan810f22d2010-07-16 00:09:46 +0000623{
624 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
625
Greg Clayton75ccf502010-08-21 02:22:51 +0000626 if (m_sym_ctx->function == NULL || m_sym_ctx->block == NULL)
Sean Callanan810f22d2010-07-16 00:09:46 +0000627 {
628 if (log)
Greg Clayton75ccf502010-08-21 02:22:51 +0000629 log->Printf("function = %p, block = %p", m_sym_ctx->function, m_sym_ctx->block);
Sean Callanan336a0002010-07-17 00:43:37 +0000630 return NULL;
Sean Callanan810f22d2010-07-16 00:09:46 +0000631 }
632
Sean Callanan336a0002010-07-17 00:43:37 +0000633 ConstString name_cs(name);
634
Greg Clayton75ccf502010-08-21 02:22:51 +0000635 Block *current_block;
Sean Callanan810f22d2010-07-16 00:09:46 +0000636
Greg Clayton75ccf502010-08-21 02:22:51 +0000637 for (current_block = m_sym_ctx->block;
638 current_block != NULL;
639 current_block = current_block->GetParent())
640 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000641 lldb::VariableListSP var_list = current_block->GetVariableList(false, true);
642
643 if (!var_list)
644 continue;
645
Sean Callanan336a0002010-07-17 00:43:37 +0000646 lldb::VariableSP var = var_list->FindVariable(name_cs);
Sean Callanan810f22d2010-07-16 00:09:46 +0000647
648 if (!var)
649 continue;
650
651 // var->GetType()->GetClangAST() is the program's AST context and holds
652 // var->GetType()->GetOpaqueClangQualType().
653
654 // type is m_type for one of the struct members, which was added by
655 // AddValueToStruct. That type was extracted from the AST context of
656 // the compiler in IRForTarget. The original for the type was copied
657 // out of the program's AST context by AddOneVariable.
658
Sean Callanan336a0002010-07-17 00:43:37 +0000659 // So that we can compare these two without having to copy back
660 // something we already had in the original AST context, we maintain
661 // m_orig_type and m_ast_context (which are passed into
662 // MaterializeOneVariable by Materialize) for each variable.
663
664 if (!type)
665 return var.get();
Sean Callanan810f22d2010-07-16 00:09:46 +0000666
Sean Callananf328c9f2010-07-20 23:31:16 +0000667 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan810f22d2010-07-16 00:09:46 +0000668 {
Sean Callananf5857a02010-07-31 01:32:05 +0000669 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan810f22d2010-07-16 00:09:46 +0000670 continue;
671 }
672 else
673 {
674 if (log)
675 log->PutCString("Skipping a candidate variable because of different AST contexts");
676 continue;
677 }
678
Sean Callanan336a0002010-07-17 00:43:37 +0000679 return var.get();
680 }
681
682 {
683 CompileUnit *compile_unit = m_sym_ctx->comp_unit;
Sean Callanan810f22d2010-07-16 00:09:46 +0000684
Sean Callanan336a0002010-07-17 00:43:37 +0000685 if (!compile_unit)
686 {
687 if (log)
688 log->Printf("compile_unit = %p", compile_unit);
689 return NULL;
690 }
691
692 lldb::VariableListSP var_list = compile_unit->GetVariableList(true);
693
694 if (!var_list)
695 return NULL;
696
697 lldb::VariableSP var = var_list->FindVariable(name_cs);
698
699 if (!var)
700 return NULL;
701
702 if (!type)
703 return var.get();
704
Sean Callananf328c9f2010-07-20 23:31:16 +0000705 if (type->GetASTContext() == var->GetType()->GetClangAST())
Sean Callanan336a0002010-07-17 00:43:37 +0000706 {
Sean Callanan841026f2010-07-23 00:16:21 +0000707 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
Sean Callanan336a0002010-07-17 00:43:37 +0000708 return NULL;
709 }
710 else
711 {
712 if (log)
713 log->PutCString("Skipping a candidate variable because of different AST contexts");
714 return NULL;
715 }
716
717 return var.get();
718 }
719
720 return NULL;
721}
Sean Callanancc074622010-09-14 21:59:34 +0000722#endif
723
724Variable *
725ClangExpressionDeclMap::FindVariableInScope(StackFrame &frame,
726 const char *name,
727 TypeFromUser *type)
728{
729 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
730
731 ConstString name_cs(name);
732
733 VariableList *var_list = frame.GetVariableList(true);
734
735 lldb::VariableSP var = var_list->FindVariable(name_cs);
736
737 if (!var)
738 return NULL;
739
740 if (!type)
741 return var.get();
742
743 if (type->GetASTContext() == var->GetType()->GetClangAST())
744 {
745 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var->GetType()->GetOpaqueClangQualType()))
746 return NULL;
747 }
748 else
749 {
750 if (log)
751 log->PutCString("Skipping a candidate variable because of different AST contexts");
752 return NULL;
753 }
754
755 return var.get();
756
757 return NULL;
758}
Sean Callanan336a0002010-07-17 00:43:37 +0000759
Chris Lattner24943d22010-06-08 16:52:24 +0000760// Interface for ClangASTSource
761void
762ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
763 const char *name)
764{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000765 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
766
Sean Callanancc074622010-09-14 21:59:34 +0000767 const char* override_name = NULL;
768
769 if (!strcmp(name, "___clang_this"))
770 override_name = "this";
771 if (!strcmp(name, "___clang_self"))
772 override_name = "self";
773
774 const char *search_name = (override_name ? override_name : name);
775
Sean Callanan810f22d2010-07-16 00:09:46 +0000776 if (log)
Sean Callanancc074622010-09-14 21:59:34 +0000777 log->Printf("Hunting for a definition for %s", search_name);
Chris Lattner24943d22010-06-08 16:52:24 +0000778
779 // Back out in all cases where we're not fully initialized
780 if (!m_exe_ctx || !m_exe_ctx->frame || !m_sym_ctx)
781 return;
Sean Callanancc074622010-09-14 21:59:34 +0000782
783 ConstString name_cs(search_name);
Sean Callanan0fc73582010-07-27 00:55:47 +0000784 SymbolContextList sym_ctxs;
Chris Lattner24943d22010-06-08 16:52:24 +0000785
Sean Callanan0fc73582010-07-27 00:55:47 +0000786 m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000787
Sean Callanan92aa6662010-09-07 21:49:41 +0000788 bool found_generic = false;
789 bool found_specific = false;
790
Sean Callanan0fc73582010-07-27 00:55:47 +0000791 for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
792 index < num_indices;
793 ++index)
794 {
795 SymbolContext sym_ctx;
796 sym_ctxs.GetContextAtIndex(index, sym_ctx);
797
798 if (sym_ctx.function)
Sean Callanan92aa6662010-09-07 21:49:41 +0000799 {
800 // TODO only do this if it's a C function; C++ functions may be
801 // overloaded
802 if (!found_specific)
803 AddOneFunction(context, sym_ctx.function, NULL);
804 found_specific = true;
805 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000806 else if(sym_ctx.symbol)
Sean Callanan92aa6662010-09-07 21:49:41 +0000807 {
808 if (!found_generic && !found_specific)
809 {
810 AddOneFunction(context, NULL, sym_ctx.symbol);
811 found_generic = true;
812 }
813 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000814 }
815
Sean Callanancc074622010-09-14 21:59:34 +0000816 Variable *var = FindVariableInScope(*m_exe_ctx->frame, search_name);
Sean Callanan336a0002010-07-17 00:43:37 +0000817
818 if (var)
Sean Callanancc074622010-09-14 21:59:34 +0000819 AddOneVariable(context, var, override_name);
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000820
Sean Callanana6223432010-08-20 01:02:30 +0000821 ClangExpressionVariable *pvar(m_persistent_vars->GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000822
823 if (pvar)
824 AddOneVariable(context, pvar);
825
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000826 /* Commented out pending resolution of a loop when the TagType is imported
827 lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs);
828
829 if (type.get())
830 AddOneType(context, type.get());
831 */
Sean Callanan336a0002010-07-17 00:43:37 +0000832}
833
834Value *
835ClangExpressionDeclMap::GetVariableValue(ExecutionContext &exe_ctx,
836 Variable *var,
Sean Callananf328c9f2010-07-20 23:31:16 +0000837 clang::ASTContext *parser_ast_context,
838 TypeFromUser *user_type,
839 TypeFromParser *parser_type)
Chris Lattner24943d22010-06-08 16:52:24 +0000840{
Sean Callanan6184dfe2010-06-23 00:47:48 +0000841 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
842
Chris Lattner24943d22010-06-08 16:52:24 +0000843 Type *var_type = var->GetType();
844
845 if (!var_type)
846 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000847 if (log)
848 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +0000849 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000850 }
851
852 void *var_opaque_type = var_type->GetOpaqueClangQualType();
853
854 if (!var_opaque_type)
855 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000856 if (log)
857 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +0000858 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000859 }
860
Chris Lattner24943d22010-06-08 16:52:24 +0000861 TypeList *type_list = var_type->GetTypeList();
862
863 if (!type_list)
864 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000865 if (log)
866 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +0000867 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000868 }
869
870 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
871
872 if (!exe_ast_ctx)
873 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000874 if (log)
875 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +0000876 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000877 }
878
Sean Callanan336a0002010-07-17 00:43:37 +0000879 DWARFExpression &var_location_expr = var->LocationExpression();
880
Chris Lattner24943d22010-06-08 16:52:24 +0000881 std::auto_ptr<Value> var_location(new Value);
882
Greg Clayton178710c2010-09-14 02:20:48 +0000883 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
884
885 if (var_location_expr.IsLocationList())
886 {
887 SymbolContext var_sc;
888 var->CalculateSymbolContext (&var_sc);
889 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.process);
890 }
Chris Lattner24943d22010-06-08 16:52:24 +0000891 Error err;
892
Greg Clayton178710c2010-09-14 02:20:48 +0000893 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 +0000894 {
Sean Callanan810f22d2010-07-16 00:09:46 +0000895 if (log)
896 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +0000897 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000898 }
899
Sean Callanan810f22d2010-07-16 00:09:46 +0000900 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
901
Sean Callanan336a0002010-07-17 00:43:37 +0000902 void *type_to_use;
903
Sean Callananf328c9f2010-07-20 23:31:16 +0000904 if (parser_ast_context)
905 {
906 type_to_use = ClangASTContext::CopyType(parser_ast_context, var_ast_context, var_opaque_type);
907
908 if (parser_type)
909 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
910 }
Sean Callanan336a0002010-07-17 00:43:37 +0000911 else
912 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +0000913
914 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Sean Callanan336a0002010-07-17 00:43:37 +0000915 var_location.get()->SetContext(Value::eContextTypeOpaqueClangQualType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +0000916
917 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
918 {
919 SymbolContext var_sc;
920 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +0000921
Chris Lattner24943d22010-06-08 16:52:24 +0000922 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +0000923 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000924
925 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
926
927 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +0000928 return NULL;
929
Chris Lattner24943d22010-06-08 16:52:24 +0000930 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
931
932 lldb::addr_t load_addr = so_addr.GetLoadAddress(m_exe_ctx->process);
933
934 var_location->GetScalar() = load_addr;
935 var_location->SetValueType(Value::eValueTypeLoadAddress);
936 }
937
Sean Callananf328c9f2010-07-20 23:31:16 +0000938 if (user_type)
939 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +0000940
941 return var_location.release();
942}
943
944void
945ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanancc074622010-09-14 21:59:34 +0000946 Variable* var,
947 const char *override_name)
Sean Callanan336a0002010-07-17 00:43:37 +0000948{
949 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
950
Sean Callananf328c9f2010-07-20 23:31:16 +0000951 TypeFromUser ut;
952 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +0000953
954 Value *var_location = GetVariableValue(*m_exe_ctx,
955 var,
956 context.GetASTContext(),
Sean Callananf328c9f2010-07-20 23:31:16 +0000957 &ut,
958 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +0000959
Sean Callanancc074622010-09-14 21:59:34 +0000960 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType(), override_name);
Chris Lattner24943d22010-06-08 16:52:24 +0000961
Sean Callanan8c127202010-08-23 23:09:38 +0000962 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Sean Callanancc074622010-09-14 21:59:34 +0000963 entity.m_name = (override_name ? override_name : context.Name.getAsString());
Sean Callanan8c127202010-08-23 23:09:38 +0000964 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +0000965
Sean Callanan8c127202010-08-23 23:09:38 +0000966 entity.EnableParserVars();
967 entity.m_parser_vars->m_parser_type = pt;
968 entity.m_parser_vars->m_named_decl = var_decl;
969 entity.m_parser_vars->m_llvm_value = NULL;
970 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +0000971
Sean Callanan810f22d2010-07-16 00:09:46 +0000972 if (log)
Sean Callananf5857a02010-07-31 01:32:05 +0000973 log->Printf("Found variable %s, returned (NamedDecl)%p", context.Name.getAsString().c_str(), var_decl);
Sean Callanan8f0dc342010-06-22 23:46:24 +0000974}
975
976void
Sean Callanana48fe162010-08-11 03:57:18 +0000977ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +0000978 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +0000979{
Sean Callanan45690fe2010-08-30 22:17:16 +0000980 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
981
Sean Callanana6223432010-08-20 01:02:30 +0000982 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +0000983
984 TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(),
985 user_type.GetASTContext(),
986 user_type.GetOpaqueQualType()),
987 context.GetASTContext());
988
Sean Callanan8c127202010-08-23 23:09:38 +0000989 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
990
991 pvar->EnableParserVars();
992 pvar->m_parser_vars->m_parser_type = parser_type;
993 pvar->m_parser_vars->m_named_decl = var_decl;
994 pvar->m_parser_vars->m_llvm_value = NULL;
995 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +0000996
997 if (log)
998 log->Printf("Added pvar %s, returned (NamedDecl)%p", pvar->m_name.c_str(), var_decl);
Sean Callanana48fe162010-08-11 03:57:18 +0000999}
1000
1001void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001002ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001003 Function* fun,
1004 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001005{
Sean Callanan6184dfe2010-06-23 00:47:48 +00001006 Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001007
Sean Callanan0fc73582010-07-27 00:55:47 +00001008 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001009 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001010 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001011
Sean Callanan0fc73582010-07-27 00:55:47 +00001012 // only valid for Functions, not for Symbols
1013 void *fun_opaque_type = NULL;
1014 clang::ASTContext *fun_ast_context = NULL;
1015
1016 if (fun)
1017 {
Sean Callanan55261a12010-09-08 22:38:54 +00001018#define BROKEN_OVERLOADING
1019 // Awaiting a fix on the Clang side
1020#ifndef BROKEN_OVERLOADING
Sean Callanan0fc73582010-07-27 00:55:47 +00001021 Type *fun_type = fun->GetType();
1022
1023 if (!fun_type)
1024 {
1025 if (log)
1026 log->PutCString("Skipped a function because it has no type");
1027 return;
1028 }
1029
1030 fun_opaque_type = fun_type->GetOpaqueClangQualType();
1031
1032 if (!fun_opaque_type)
1033 {
1034 if (log)
1035 log->PutCString("Skipped a function because it has no Clang type");
1036 return;
1037 }
1038
1039 fun_address = &fun->GetAddressRange().GetBaseAddress();
1040
1041 TypeList *type_list = fun_type->GetTypeList();
1042 fun_ast_context = type_list->GetClangASTContext().getASTContext();
1043 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
1044
1045 fun_decl = context.AddFunDecl(copied_type);
Sean Callanan55261a12010-09-08 22:38:54 +00001046#else
1047 fun_address = &fun->GetAddressRange().GetBaseAddress();
1048
1049 fun_decl = context.AddGenericFunDecl();
1050#endif
Sean Callanan0fc73582010-07-27 00:55:47 +00001051 }
1052 else if (symbol)
1053 {
1054 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1055
1056 fun_decl = context.AddGenericFunDecl();
1057 }
1058 else
1059 {
1060 if (log)
1061 log->PutCString("AddOneFunction called with no function and no symbol");
1062 return;
1063 }
1064
1065 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->process);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001066 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1067 fun_location->GetScalar() = load_addr;
1068
Sean Callanan8c127202010-08-23 23:09:38 +00001069 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1070 entity.m_name = context.Name.getAsString();
1071 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001072
Sean Callanan8c127202010-08-23 23:09:38 +00001073 entity.EnableParserVars();
1074 entity.m_parser_vars->m_named_decl = fun_decl;
1075 entity.m_parser_vars->m_llvm_value = NULL;
1076 entity.m_parser_vars->m_lldb_value = fun_location.release();
1077
Sean Callanan810f22d2010-07-16 00:09:46 +00001078 if (log)
Sean Callanan92aa6662010-09-07 21:49:41 +00001079 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 +00001080}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001081
1082void
1083ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
1084 Type *type)
1085{
1086 TypeFromUser ut(type->GetOpaqueClangQualType(),
1087 type->GetClangAST());
1088
1089 void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), ut.GetASTContext(), ut.GetOpaqueQualType());
1090
1091 context.AddTypeDecl(copied_type);
1092}