blob: bd68b7b0439bc81b1866a5854dd166430aecc839 [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
Sean Callananaa301c42010-12-03 01:38:59 +000046ClangExpressionDeclMap::ClangExpressionDeclMap () :
Greg Clayton8de27c72010-10-15 22:48:33 +000047 m_found_entities (),
48 m_struct_members (),
Sean Callananaa301c42010-12-03 01:38:59 +000049 m_parser_vars (),
50 m_struct_vars ()
Chris Lattner24943d22010-06-08 16:52:24 +000051{
Sean Callananaa301c42010-12-03 01:38:59 +000052 EnableStructVars();
Chris Lattner24943d22010-06-08 16:52:24 +000053}
54
55ClangExpressionDeclMap::~ClangExpressionDeclMap()
Sean Callananaa301c42010-12-03 01:38:59 +000056{
57 DidDematerialize();
58 DisableStructVars();
59}
Sean Callananc2c6f772010-10-26 00:31:56 +000060
Sean Callananaa301c42010-12-03 01:38:59 +000061void ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx)
62{
63 EnableParserVars();
64 m_parser_vars->m_exe_ctx = &exe_ctx;
65
66 if (exe_ctx.frame)
67 m_parser_vars->m_sym_ctx = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything);
68
69 if (exe_ctx.process)
70 m_parser_vars->m_persistent_vars = &exe_ctx.process->GetPersistentVariables();
71}
72
73void ClangExpressionDeclMap::DidParse()
74{
75 if (m_parser_vars.get())
76 {
77 for (uint64_t entity_index = 0, num_entities = m_found_entities.Size();
78 entity_index < num_entities;
79 ++entity_index)
80 {
81 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(entity_index));
82 if (entity.m_parser_vars.get() &&
83 entity.m_parser_vars->m_lldb_value)
84 delete entity.m_parser_vars->m_lldb_value;
85
86 entity.DisableParserVars();
87 }
88
89 for (uint64_t pvar_index = 0, num_pvars = m_parser_vars->m_persistent_vars->Size();
90 pvar_index < num_pvars;
91 ++pvar_index)
92 {
93 ClangExpressionVariable &pvar(m_parser_vars->m_persistent_vars->VariableAtIndex(pvar_index));
94 pvar.DisableParserVars();
95 }
96
97 DisableParserVars();
Sean Callanan7a60b942010-10-08 01:58:41 +000098 }
Chris Lattner24943d22010-06-08 16:52:24 +000099}
100
Sean Callanan8bce6652010-07-13 21:41:46 +0000101// Interface for IRForTarget
102
Greg Clayton8de27c72010-10-15 22:48:33 +0000103const ConstString &
104ClangExpressionDeclMap::GetPersistentResultName ()
Sean Callanan82b74c82010-08-12 01:56:52 +0000105{
Sean Callananaa301c42010-12-03 01:38:59 +0000106 assert (m_struct_vars.get());
107 assert (m_parser_vars.get());
108
109 if (!m_struct_vars->m_result_name)
110 m_parser_vars->m_persistent_vars->GetNextResultName(m_struct_vars->m_result_name);
111
112 return m_struct_vars->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{
Sean Callananaa301c42010-12-03 01:38:59 +0000123 assert (m_parser_vars.get());
124
125 clang::ASTContext *context(m_parser_vars->m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
Sean Callanana48fe162010-08-11 03:57:18 +0000126
Sean Callanana48fe162010-08-11 03:57:18 +0000127 TypeFromUser user_type(ClangASTContext::CopyType(context,
Sean Callanan82b74c82010-08-12 01:56:52 +0000128 parser_type.GetASTContext(),
129 parser_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +0000130 context);
131
Sean Callananaa301c42010-12-03 01:38:59 +0000132 if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (name, user_type))
Sean Callanan8c127202010-08-23 23:09:38 +0000133 return false;
134
Sean Callananaa301c42010-12-03 01:38:59 +0000135 ClangExpressionVariable *var = m_parser_vars->m_persistent_vars->GetVariable(name);
Sean Callanan8c127202010-08-23 23:09:38 +0000136
137 if (!var)
138 return false;
139
140 var->EnableParserVars();
141
142 var->m_parser_vars->m_named_decl = decl;
143 var->m_parser_vars->m_parser_type = parser_type;
144
145 return true;
Sean Callanana48fe162010-08-11 03:57:18 +0000146}
147
148bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000149ClangExpressionDeclMap::AddValueToStruct
150(
151 const clang::NamedDecl *decl,
152 const ConstString &name,
153 llvm::Value *value,
154 size_t size,
155 off_t alignment
156)
Sean Callanan8bce6652010-07-13 21:41:46 +0000157{
Sean Callananaa301c42010-12-03 01:38:59 +0000158 assert (m_struct_vars.get());
159 assert (m_parser_vars.get());
160
Greg Claytone005f2c2010-11-06 01:53:30 +0000161 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +0000162
Sean Callananaa301c42010-12-03 01:38:59 +0000163 m_struct_vars->m_struct_laid_out = false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000164
Sean Callanan8c127202010-08-23 23:09:38 +0000165 if (m_struct_members.GetVariable(decl))
166 return true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000167
Sean Callanan8c127202010-08-23 23:09:38 +0000168 ClangExpressionVariable *var = m_found_entities.GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000169
Sean Callanan8c127202010-08-23 23:09:38 +0000170 if (!var)
Sean Callananaa301c42010-12-03 01:38:59 +0000171 var = m_parser_vars->m_persistent_vars->GetVariable(decl);
Sean Callanan8bce6652010-07-13 21:41:46 +0000172
Sean Callanan8c127202010-08-23 23:09:38 +0000173 if (!var)
174 return false;
175
Sean Callanan45690fe2010-08-30 22:17:16 +0000176 if (log)
177 log->Printf("Adding value for decl %p [%s - %s] to the structure",
178 decl,
Greg Clayton8de27c72010-10-15 22:48:33 +0000179 name.GetCString(),
180 var->m_name.GetCString());
Sean Callanan45690fe2010-08-30 22:17:16 +0000181
Sean Callanan8c127202010-08-23 23:09:38 +0000182 // We know entity->m_parser_vars is valid because we used a parser variable
183 // to find it
184 var->m_parser_vars->m_llvm_value = value;
185
186 var->EnableJITVars();
187 var->m_jit_vars->m_alignment = alignment;
188 var->m_jit_vars->m_size = size;
189
190 m_struct_members.AddVariable(*var);
Sean Callanan8bce6652010-07-13 21:41:46 +0000191
192 return true;
193}
194
195bool
196ClangExpressionDeclMap::DoStructLayout ()
197{
Sean Callananaa301c42010-12-03 01:38:59 +0000198 assert (m_struct_vars.get());
199
200 if (m_struct_vars->m_struct_laid_out)
Sean Callanan8bce6652010-07-13 21:41:46 +0000201 return true;
202
Sean Callanan8bce6652010-07-13 21:41:46 +0000203 off_t cursor = 0;
204
Sean Callananaa301c42010-12-03 01:38:59 +0000205 m_struct_vars->m_struct_alignment = 0;
206 m_struct_vars->m_struct_size = 0;
Sean Callanan8bce6652010-07-13 21:41:46 +0000207
Sean Callanan8c127202010-08-23 23:09:38 +0000208 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
209 member_index < num_members;
210 ++member_index)
Sean Callanan8bce6652010-07-13 21:41:46 +0000211 {
Sean Callanan8c127202010-08-23 23:09:38 +0000212 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(member_index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000213
Sean Callanan8c127202010-08-23 23:09:38 +0000214 if (!member.m_jit_vars.get())
215 return false;
Sean Callanan8bce6652010-07-13 21:41:46 +0000216
Sean Callanan8c127202010-08-23 23:09:38 +0000217 if (member_index == 0)
Sean Callananaa301c42010-12-03 01:38:59 +0000218 m_struct_vars->m_struct_alignment = member.m_jit_vars->m_alignment;
Sean Callanan8c127202010-08-23 23:09:38 +0000219
220 if (cursor % member.m_jit_vars->m_alignment)
221 cursor += (member.m_jit_vars->m_alignment - (cursor % member.m_jit_vars->m_alignment));
222
223 member.m_jit_vars->m_offset = cursor;
224 cursor += member.m_jit_vars->m_size;
Sean Callanan8bce6652010-07-13 21:41:46 +0000225 }
226
Sean Callananaa301c42010-12-03 01:38:59 +0000227 m_struct_vars->m_struct_size = cursor;
Sean Callanan8bce6652010-07-13 21:41:46 +0000228
Sean Callananaa301c42010-12-03 01:38:59 +0000229 m_struct_vars->m_struct_laid_out = true;
Sean Callanan8bce6652010-07-13 21:41:46 +0000230 return true;
231}
232
Greg Clayton8de27c72010-10-15 22:48:33 +0000233bool ClangExpressionDeclMap::GetStructInfo
234(
235 uint32_t &num_elements,
236 size_t &size,
237 off_t &alignment
238)
Sean Callanan8bce6652010-07-13 21:41:46 +0000239{
Sean Callananaa301c42010-12-03 01:38:59 +0000240 assert (m_struct_vars.get());
241
242 if (!m_struct_vars->m_struct_laid_out)
Sean Callanan8bce6652010-07-13 21:41:46 +0000243 return false;
244
Sean Callanan8c127202010-08-23 23:09:38 +0000245 num_elements = m_struct_members.Size();
Sean Callananaa301c42010-12-03 01:38:59 +0000246 size = m_struct_vars->m_struct_size;
247 alignment = m_struct_vars->m_struct_alignment;
Sean Callanan8bce6652010-07-13 21:41:46 +0000248
249 return true;
250}
251
252bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000253ClangExpressionDeclMap::GetStructElement
254(
255 const clang::NamedDecl *&decl,
256 llvm::Value *&value,
257 off_t &offset,
258 ConstString &name,
259 uint32_t index
260)
Sean Callanan8bce6652010-07-13 21:41:46 +0000261{
Sean Callananaa301c42010-12-03 01:38:59 +0000262 assert (m_struct_vars.get());
263
264 if (!m_struct_vars->m_struct_laid_out)
Sean Callanan8bce6652010-07-13 21:41:46 +0000265 return false;
266
Sean Callanan8c127202010-08-23 23:09:38 +0000267 if (index >= m_struct_members.Size())
Sean Callanan8bce6652010-07-13 21:41:46 +0000268 return false;
269
Sean Callanan8c127202010-08-23 23:09:38 +0000270 ClangExpressionVariable &member(m_struct_members.VariableAtIndex(index));
Sean Callanan8bce6652010-07-13 21:41:46 +0000271
Sean Callanan8c127202010-08-23 23:09:38 +0000272 if (!member.m_parser_vars.get() ||
273 !member.m_jit_vars.get())
274 return false;
275
276 decl = member.m_parser_vars->m_named_decl;
277 value = member.m_parser_vars->m_llvm_value;
278 offset = member.m_jit_vars->m_offset;
Greg Clayton8de27c72010-10-15 22:48:33 +0000279 name = member.m_name;
Sean Callanan8c127202010-08-23 23:09:38 +0000280
Sean Callanan8bce6652010-07-13 21:41:46 +0000281 return true;
282}
283
Sean Callanan02fbafa2010-07-27 21:39:39 +0000284bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000285ClangExpressionDeclMap::GetFunctionInfo
286(
287 const clang::NamedDecl *decl,
288 llvm::Value**& value,
289 uint64_t &ptr
290)
Sean Callananba992c52010-07-27 02:07:53 +0000291{
Sean Callanan8c127202010-08-23 23:09:38 +0000292 ClangExpressionVariable *entity = m_found_entities.GetVariable(decl);
293
294 if (!entity)
295 return false;
Sean Callananba992c52010-07-27 02:07:53 +0000296
Sean Callanan8c127202010-08-23 23:09:38 +0000297 // We know m_parser_vars is valid since we searched for the variable by
298 // its NamedDecl
Sean Callananba992c52010-07-27 02:07:53 +0000299
Sean Callanan8c127202010-08-23 23:09:38 +0000300 value = &entity->m_parser_vars->m_llvm_value;
301 ptr = entity->m_parser_vars->m_lldb_value->GetScalar().ULongLong();
302
303 return true;
Sean Callananba992c52010-07-27 02:07:53 +0000304}
305
Sean Callananf5857a02010-07-31 01:32:05 +0000306bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000307ClangExpressionDeclMap::GetFunctionAddress
308(
309 const ConstString &name,
310 uint64_t &ptr
311)
Sean Callananf5857a02010-07-31 01:32:05 +0000312{
Sean Callananaa301c42010-12-03 01:38:59 +0000313 assert (m_parser_vars.get());
314
Sean Callananf5857a02010-07-31 01:32:05 +0000315 // Back out in all cases where we're not fully initialized
Sean Callananaa301c42010-12-03 01:38:59 +0000316 if (m_parser_vars->m_exe_ctx->frame == NULL)
Sean Callananf5857a02010-07-31 01:32:05 +0000317 return false;
318
Greg Claytone5748d82010-11-09 23:46:37 +0000319 SymbolContextList sc_list;
Sean Callananf5857a02010-07-31 01:32:05 +0000320
Sean Callananaa301c42010-12-03 01:38:59 +0000321 m_parser_vars->m_sym_ctx.FindFunctionsByName(name, false, sc_list);
Sean Callananf5857a02010-07-31 01:32:05 +0000322
Greg Claytone5748d82010-11-09 23:46:37 +0000323 if (!sc_list.GetSize())
Sean Callananf5857a02010-07-31 01:32:05 +0000324 return false;
325
326 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +0000327 sc_list.GetContextAtIndex(0, sym_ctx);
Sean Callananf5857a02010-07-31 01:32:05 +0000328
329 const Address *fun_address;
330
331 if (sym_ctx.function)
332 fun_address = &sym_ctx.function->GetAddressRange().GetBaseAddress();
333 else if (sym_ctx.symbol)
334 fun_address = &sym_ctx.symbol->GetAddressRangeRef().GetBaseAddress();
335 else
336 return false;
337
Sean Callananaa301c42010-12-03 01:38:59 +0000338 ptr = fun_address->GetLoadAddress (m_parser_vars->m_exe_ctx->target);
Sean Callananf5857a02010-07-31 01:32:05 +0000339
340 return true;
341}
342
Sean Callanan810f22d2010-07-16 00:09:46 +0000343// Interface for CommandObjectExpression
Sean Callananf328c9f2010-07-20 23:31:16 +0000344
345bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000346ClangExpressionDeclMap::Materialize
347(
Sean Callananaa301c42010-12-03 01:38:59 +0000348 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000349 lldb::addr_t &struct_address,
350 Error &err
351)
Sean Callananf328c9f2010-07-20 23:31:16 +0000352{
Sean Callananaa301c42010-12-03 01:38:59 +0000353 EnableMaterialVars();
354
355 m_material_vars->m_process = exe_ctx.process;
356
Sean Callananf328c9f2010-07-20 23:31:16 +0000357 bool result = DoMaterialize(false, exe_ctx, NULL, err);
358
359 if (result)
Sean Callananaa301c42010-12-03 01:38:59 +0000360 struct_address = m_material_vars->m_materialized_location;
Sean Callananf328c9f2010-07-20 23:31:16 +0000361
362 return result;
363}
364
365bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000366ClangExpressionDeclMap::GetObjectPointer
367(
368 lldb::addr_t &object_ptr,
Sean Callananaa301c42010-12-03 01:38:59 +0000369 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000370 Error &err
371)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000372{
Sean Callananaa301c42010-12-03 01:38:59 +0000373 assert (m_struct_vars.get());
374
375 if (!exe_ctx.frame || !exe_ctx.target || !exe_ctx.process)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000376 {
377 err.SetErrorString("Couldn't load 'this' because the context is incomplete");
378 return false;
379 }
380
Sean Callananaa301c42010-12-03 01:38:59 +0000381 if (!m_struct_vars->m_object_pointer_type.GetOpaqueQualType())
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000382 {
383 err.SetErrorString("Couldn't load 'this' because its type is unknown");
384 return false;
385 }
386
Greg Clayton3bc52d02010-11-14 22:13:40 +0000387 static ConstString g_this_const_str ("this");
Sean Callananaa301c42010-12-03 01:38:59 +0000388 Variable *object_ptr_var = FindVariableInScope (*exe_ctx.frame, g_this_const_str, &m_struct_vars->m_object_pointer_type);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000389
390 if (!object_ptr_var)
391 {
392 err.SetErrorString("Couldn't find 'this' with appropriate type in scope");
393 return false;
394 }
395
Sean Callananaa301c42010-12-03 01:38:59 +0000396 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000397 object_ptr_var,
Sean Callananaa301c42010-12-03 01:38:59 +0000398 NULL));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000399
400 if (!location_value.get())
401 {
402 err.SetErrorString("Couldn't get the location for 'this'");
403 return false;
404 }
405
406 if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
407 {
408 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
Sean Callananaa301c42010-12-03 01:38:59 +0000409 uint32_t address_byte_size = exe_ctx.target->GetArchitecture().GetAddressByteSize();
410 lldb::ByteOrder address_byte_order = exe_ctx.process->GetByteOrder();
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000411
Sean Callananaa301c42010-12-03 01:38:59 +0000412 if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(),
413 m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000414 {
415 err.SetErrorStringWithFormat("'this' is not of an expected pointer size");
416 return false;
417 }
418
419 DataBufferHeap data;
420 data.SetByteSize(address_byte_size);
421 Error read_error;
422
Sean Callananaa301c42010-12-03 01:38:59 +0000423 if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
Sean Callanan3c9c5eb2010-09-21 00:44:12 +0000424 {
425 err.SetErrorStringWithFormat("Coldn't read 'this' from the target: %s", read_error.AsCString());
426 return false;
427 }
428
429 DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
430
431 uint32_t offset = 0;
432
433 object_ptr = extractor.GetPointer(&offset);
434
435 return true;
436 }
437 else
438 {
439 err.SetErrorString("'this' is not in memory; LLDB must be extended to handle registers");
440 return false;
441 }
442}
443
444bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000445ClangExpressionDeclMap::Dematerialize
446(
Sean Callananaa301c42010-12-03 01:38:59 +0000447 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000448 ClangExpressionVariable *&result,
449 Error &err
450)
Sean Callananf328c9f2010-07-20 23:31:16 +0000451{
Sean Callanan82b74c82010-08-12 01:56:52 +0000452 return DoMaterialize(true, exe_ctx, &result, err);
Sean Callananaa301c42010-12-03 01:38:59 +0000453
454 DidDematerialize();
455}
456
457void
458ClangExpressionDeclMap::DidDematerialize()
459{
460 if (m_material_vars.get())
461 {
462 if (m_material_vars->m_materialized_location)
463 {
464 //#define SINGLE_STEP_EXPRESSIONS
465
466#ifndef SINGLE_STEP_EXPRESSIONS
467 m_material_vars->m_process->DeallocateMemory(m_material_vars->m_materialized_location);
468#endif
469 m_material_vars->m_materialized_location = 0;
470 }
471
472 DisableMaterialVars();
473 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000474}
475
Sean Callanan32824aa2010-07-23 22:19:18 +0000476bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000477ClangExpressionDeclMap::DumpMaterializedStruct
478(
Sean Callananaa301c42010-12-03 01:38:59 +0000479 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000480 Stream &s,
481 Error &err
482)
Sean Callanan32824aa2010-07-23 22:19:18 +0000483{
Sean Callananaa301c42010-12-03 01:38:59 +0000484 assert (m_struct_vars.get());
485 assert (m_material_vars.get());
486
487 if (!m_struct_vars->m_struct_laid_out)
Sean Callanan32824aa2010-07-23 22:19:18 +0000488 {
489 err.SetErrorString("Structure hasn't been laid out yet");
490 return false;
491 }
492
Sean Callananaa301c42010-12-03 01:38:59 +0000493 if (!exe_ctx.process)
Sean Callanan32824aa2010-07-23 22:19:18 +0000494 {
495 err.SetErrorString("Couldn't find the process");
496 return false;
497 }
498
Sean Callananaa301c42010-12-03 01:38:59 +0000499 if (!exe_ctx.target)
Sean Callanan32824aa2010-07-23 22:19:18 +0000500 {
501 err.SetErrorString("Couldn't find the target");
502 return false;
503 }
504
Sean Callananaa301c42010-12-03 01:38:59 +0000505 lldb::DataBufferSP data(new DataBufferHeap(m_struct_vars->m_struct_size, 0));
Sean Callanan32824aa2010-07-23 22:19:18 +0000506
507 Error error;
Sean Callananaa301c42010-12-03 01:38:59 +0000508 if (exe_ctx.process->ReadMemory (m_material_vars->m_materialized_location, data->GetBytes(), data->GetByteSize(), error) != data->GetByteSize())
Sean Callanan32824aa2010-07-23 22:19:18 +0000509 {
510 err.SetErrorStringWithFormat ("Couldn't read struct from the target: %s", error.AsCString());
511 return false;
512 }
513
Sean Callananaa301c42010-12-03 01:38:59 +0000514 DataExtractor extractor(data, exe_ctx.process->GetByteOrder(), exe_ctx.target->GetArchitecture().GetAddressByteSize());
Sean Callanan32824aa2010-07-23 22:19:18 +0000515
Sean Callanan8c127202010-08-23 23:09:38 +0000516 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
517 member_index < num_members;
518 ++member_index)
Sean Callanan32824aa2010-07-23 22:19:18 +0000519 {
Sean Callanan8c127202010-08-23 23:09:38 +0000520 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan32824aa2010-07-23 22:19:18 +0000521
Greg Clayton8de27c72010-10-15 22:48:33 +0000522 s.Printf("[%s]\n", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000523
524 if (!member.m_jit_vars.get())
525 return false;
526
Sean Callananaa301c42010-12-03 01:38:59 +0000527 extractor.Dump(&s, // stream
528 member.m_jit_vars->m_offset, // offset
529 lldb::eFormatBytesWithASCII, // format
530 1, // byte size of individual entries
531 member.m_jit_vars->m_size, // number of entries
532 16, // entries per line
533 m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, // address to print
534 0, // bit size (bitfields only; 0 means ignore)
535 0); // bit alignment (bitfields only; 0 means ignore)
Sean Callanan32824aa2010-07-23 22:19:18 +0000536
537 s.PutChar('\n');
538 }
539
540 return true;
541}
542
Sean Callananf328c9f2010-07-20 23:31:16 +0000543bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000544ClangExpressionDeclMap::DoMaterialize
545(
546 bool dematerialize,
Sean Callananaa301c42010-12-03 01:38:59 +0000547 ExecutionContext &exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +0000548 ClangExpressionVariable **result,
549 Error &err
550)
Sean Callanan810f22d2010-07-16 00:09:46 +0000551{
Sean Callananaa301c42010-12-03 01:38:59 +0000552 assert (m_struct_vars.get());
553
Greg Claytone005f2c2010-11-06 01:53:30 +0000554 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan82b74c82010-08-12 01:56:52 +0000555
Sean Callananaa301c42010-12-03 01:38:59 +0000556 if (!m_struct_vars->m_struct_laid_out)
Sean Callanan810f22d2010-07-16 00:09:46 +0000557 {
558 err.SetErrorString("Structure hasn't been laid out yet");
559 return LLDB_INVALID_ADDRESS;
560 }
561
Sean Callananaa301c42010-12-03 01:38:59 +0000562 if (!exe_ctx.frame)
Sean Callanan45839272010-07-24 01:37:44 +0000563 {
564 err.SetErrorString("Received null execution frame");
565 return LLDB_INVALID_ADDRESS;
566 }
567
Sean Callananaa301c42010-12-03 01:38:59 +0000568 ClangPersistentVariables &persistent_vars = exe_ctx.process->GetPersistentVariables();
569
570 if (!m_struct_vars->m_struct_size)
Sean Callanane8a59a82010-09-13 21:34:21 +0000571 {
572 if (log)
573 log->PutCString("Not bothering to allocate a struct because no arguments are needed");
574
Sean Callananaa301c42010-12-03 01:38:59 +0000575 m_material_vars->m_allocated_area = NULL;
Sean Callanane8a59a82010-09-13 21:34:21 +0000576
577 return true;
578 }
579
Sean Callananaa301c42010-12-03 01:38:59 +0000580 const SymbolContext &sym_ctx(exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything));
Sean Callanan810f22d2010-07-16 00:09:46 +0000581
Sean Callananf328c9f2010-07-20 23:31:16 +0000582 if (!dematerialize)
Sean Callanan810f22d2010-07-16 00:09:46 +0000583 {
Sean Callananaa301c42010-12-03 01:38:59 +0000584 if (m_material_vars->m_materialized_location)
Sean Callananf328c9f2010-07-20 23:31:16 +0000585 {
Sean Callananaa301c42010-12-03 01:38:59 +0000586 exe_ctx.process->DeallocateMemory(m_material_vars->m_materialized_location);
587 m_material_vars->m_materialized_location = 0;
Sean Callananf328c9f2010-07-20 23:31:16 +0000588 }
589
Sean Callanan7a60b942010-10-08 01:58:41 +0000590 if (log)
591 log->PutCString("Allocating memory for materialized argument struct");
592
Sean Callananaa301c42010-12-03 01:38:59 +0000593 lldb::addr_t mem = exe_ctx.process->AllocateMemory(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size,
594 lldb::ePermissionsReadable | lldb::ePermissionsWritable,
595 err);
Sean Callananf328c9f2010-07-20 23:31:16 +0000596
597 if (mem == LLDB_INVALID_ADDRESS)
598 return false;
599
Sean Callananaa301c42010-12-03 01:38:59 +0000600 m_material_vars->m_allocated_area = mem;
Sean Callanan810f22d2010-07-16 00:09:46 +0000601 }
602
Sean Callananaa301c42010-12-03 01:38:59 +0000603 m_material_vars->m_materialized_location = m_material_vars->m_allocated_area;
Sean Callananf328c9f2010-07-20 23:31:16 +0000604
Sean Callananaa301c42010-12-03 01:38:59 +0000605 if (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment)
606 m_material_vars->m_materialized_location += (m_struct_vars->m_struct_alignment - (m_material_vars->m_materialized_location % m_struct_vars->m_struct_alignment));
Sean Callananf328c9f2010-07-20 23:31:16 +0000607
Sean Callanan8c127202010-08-23 23:09:38 +0000608 for (uint64_t member_index = 0, num_members = m_struct_members.Size();
609 member_index < num_members;
610 ++member_index)
Sean Callanan810f22d2010-07-16 00:09:46 +0000611 {
Sean Callanan8c127202010-08-23 23:09:38 +0000612 ClangExpressionVariable &member (m_struct_members.VariableAtIndex(member_index));
Sean Callanan810f22d2010-07-16 00:09:46 +0000613
Sean Callanan4d0b1102010-12-01 01:29:06 +0000614 ClangExpressionVariable *entity = NULL;
Sean Callanan8c127202010-08-23 23:09:38 +0000615
Sean Callananaa301c42010-12-03 01:38:59 +0000616 /*
Sean Callanan4d0b1102010-12-01 01:29:06 +0000617 if (member.m_parser_vars.get())
618 entity = m_found_entities.GetVariable(member.m_parser_vars->m_named_decl);
Sean Callananaa301c42010-12-03 01:38:59 +0000619 */
Sean Callanan4d0b1102010-12-01 01:29:06 +0000620
Sean Callananaa301c42010-12-03 01:38:59 +0000621 entity = m_found_entities.GetVariable(member.m_name);
622
623 ClangExpressionVariable *persistent_variable = persistent_vars.GetVariable(member.m_name);
Sean Callanan8c127202010-08-23 23:09:38 +0000624
625 if (entity)
626 {
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000627 if (entity->m_register_info)
628 {
629 // This is a register variable
630
Sean Callananaa301c42010-12-03 01:38:59 +0000631 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000632
633 if (!reg_ctx)
634 return false;
635
Sean Callananaa301c42010-12-03 01:38:59 +0000636 if (!DoMaterializeOneRegister(dematerialize, exe_ctx, *reg_ctx, *entity->m_register_info, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000637 return false;
638 }
639 else
640 {
641 if (!member.m_jit_vars.get())
642 return false;
643
Sean Callananaa301c42010-12-03 01:38:59 +0000644 if (!DoMaterializeOneVariable(dematerialize, exe_ctx, sym_ctx, member.m_name, member.m_user_type, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000645 return false;
646 }
Sean Callanan8c127202010-08-23 23:09:38 +0000647 }
648 else if (persistent_variable)
649 {
Sean Callananaa301c42010-12-03 01:38:59 +0000650 if (member.m_name == m_struct_vars->m_result_name)
Sean Callanan45690fe2010-08-30 22:17:16 +0000651 {
652 if (!dematerialize)
653 continue;
Sean Callanan8c127202010-08-23 23:09:38 +0000654
Sean Callanan8c127202010-08-23 23:09:38 +0000655 if (log)
656 log->PutCString("Found result member in the struct");
Sean Callanan45690fe2010-08-30 22:17:16 +0000657
Sean Callanan8c127202010-08-23 23:09:38 +0000658 *result = &member;
659 }
660
Sean Callanan45690fe2010-08-30 22:17:16 +0000661 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000662 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 +0000663
Sean Callananaa301c42010-12-03 01:38:59 +0000664 if (!DoMaterializeOnePersistentVariable(dematerialize, exe_ctx, persistent_variable->m_name, m_material_vars->m_materialized_location + member.m_jit_vars->m_offset, err))
Sean Callanan8c127202010-08-23 23:09:38 +0000665 return false;
666 }
667 else
668 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000669 err.SetErrorStringWithFormat("Unexpected variable %s", member.m_name.GetCString());
Sean Callanan8c127202010-08-23 23:09:38 +0000670 return false;
671 }
Sean Callanan810f22d2010-07-16 00:09:46 +0000672 }
673
Sean Callananf328c9f2010-07-20 23:31:16 +0000674 return true;
675}
676
Sean Callanana48fe162010-08-11 03:57:18 +0000677bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000678ClangExpressionDeclMap::DoMaterializeOnePersistentVariable
679(
680 bool dematerialize,
681 ExecutionContext &exe_ctx,
682 const ConstString &name,
683 lldb::addr_t addr,
684 Error &err
685)
Sean Callananaa301c42010-12-03 01:38:59 +0000686{
687 ClangPersistentVariables &persistent_vars = exe_ctx.process->GetPersistentVariables();
688
689 ClangExpressionVariable *pvar(persistent_vars.GetVariable(name));
Sean Callanana48fe162010-08-11 03:57:18 +0000690
691 if (!pvar)
692 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000693 err.SetErrorStringWithFormat("Undefined persistent variable %s", name.GetCString());
Sean Callanana48fe162010-08-11 03:57:18 +0000694 return LLDB_INVALID_ADDRESS;
695 }
696
697 size_t pvar_size = pvar->Size();
Sean Callanana6223432010-08-20 01:02:30 +0000698
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000699 if (!pvar->m_data_sp.get())
Sean Callanana6223432010-08-20 01:02:30 +0000700 return false;
701
Greg Clayton66ed2fb2010-10-05 00:00:42 +0000702 uint8_t *pvar_data = pvar->m_data_sp->GetBytes();
Sean Callanana48fe162010-08-11 03:57:18 +0000703 Error error;
704
705 if (dematerialize)
706 {
707 if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size)
708 {
709 err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString());
710 return false;
711 }
712 }
713 else
714 {
715 if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size)
716 {
717 err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString());
718 return false;
719 }
720 }
721
722 return true;
723}
724
Sean Callananf328c9f2010-07-20 23:31:16 +0000725bool
Greg Clayton8de27c72010-10-15 22:48:33 +0000726ClangExpressionDeclMap::DoMaterializeOneVariable
727(
728 bool dematerialize,
729 ExecutionContext &exe_ctx,
730 const SymbolContext &sym_ctx,
731 const ConstString &name,
732 TypeFromUser type,
733 lldb::addr_t addr,
734 Error &err
735)
Sean Callananf328c9f2010-07-20 23:31:16 +0000736{
Greg Claytone005f2c2010-11-06 01:53:30 +0000737 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callananf328c9f2010-07-20 23:31:16 +0000738
Sean Callanan17c6a052010-10-05 20:18:48 +0000739 if (!exe_ctx.frame || !exe_ctx.process)
Sean Callanancc074622010-09-14 21:59:34 +0000740 return false;
741
Greg Clayton3bc52d02010-11-14 22:13:40 +0000742 Variable *var = FindVariableInScope (*exe_ctx.frame, name, &type);
Sean Callananf328c9f2010-07-20 23:31:16 +0000743
744 if (!var)
745 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000746 err.SetErrorStringWithFormat("Couldn't find %s with appropriate type", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000747 return false;
748 }
749
Sean Callanan841026f2010-07-23 00:16:21 +0000750 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +0000751 log->Printf("%s %s with type %p", (dematerialize ? "Dematerializing" : "Materializing"), name.GetCString(), type.GetOpaqueQualType());
Sean Callananf328c9f2010-07-20 23:31:16 +0000752
753 std::auto_ptr<lldb_private::Value> location_value(GetVariableValue(exe_ctx,
754 var,
Sean Callananaa301c42010-12-03 01:38:59 +0000755 NULL));
Sean Callananf328c9f2010-07-20 23:31:16 +0000756
757 if (!location_value.get())
758 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000759 err.SetErrorStringWithFormat("Couldn't get value for %s", name.GetCString());
Sean Callananf328c9f2010-07-20 23:31:16 +0000760 return false;
761 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000762
763 // The size of the type contained in addr
Sean Callananf328c9f2010-07-20 23:31:16 +0000764
Sean Callanan17c6a052010-10-05 20:18:48 +0000765 size_t addr_bit_size = ClangASTType::GetClangTypeBitWidth(type.GetASTContext(), type.GetOpaqueQualType());
766 size_t addr_byte_size = addr_bit_size % 8 ? ((addr_bit_size + 8) / 8) : (addr_bit_size / 8);
767
768 Value::ValueType value_type = location_value->GetValueType();
769
770 switch (value_type)
Sean Callananf328c9f2010-07-20 23:31:16 +0000771 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000772 default:
Sean Callananf328c9f2010-07-20 23:31:16 +0000773 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000774 StreamString ss;
775
776 location_value->Dump(&ss);
777
Greg Clayton8de27c72010-10-15 22:48:33 +0000778 err.SetErrorStringWithFormat("%s has a value of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callananf328c9f2010-07-20 23:31:16 +0000779 return false;
780 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000781 break;
782 case Value::eValueTypeLoadAddress:
Sean Callananf328c9f2010-07-20 23:31:16 +0000783 {
Sean Callanan17c6a052010-10-05 20:18:48 +0000784 lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
785
786 DataBufferHeap data;
787 data.SetByteSize(addr_byte_size);
788
789 lldb::addr_t src_addr;
790 lldb::addr_t dest_addr;
791
792 if (dematerialize)
793 {
794 src_addr = addr;
795 dest_addr = value_addr;
796 }
797 else
798 {
799 src_addr = value_addr;
800 dest_addr = addr;
801 }
802
803 Error error;
804 if (exe_ctx.process->ReadMemory (src_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
805 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000806 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000807 return false;
808 }
809
810 if (exe_ctx.process->WriteMemory (dest_addr, data.GetBytes(), addr_byte_size, error) != addr_byte_size)
811 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000812 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000813 return false;
814 }
815
816 if (log)
817 log->Printf("Copied from 0x%llx to 0x%llx", (uint64_t)src_addr, (uint64_t)addr);
Sean Callananf328c9f2010-07-20 23:31:16 +0000818 }
Sean Callanan17c6a052010-10-05 20:18:48 +0000819 break;
820 case Value::eValueTypeScalar:
821 {
Greg Clayton6916e352010-11-13 03:52:47 +0000822 if (location_value->GetContextType() != Value::eContextTypeRegisterInfo)
Sean Callanan17c6a052010-10-05 20:18:48 +0000823 {
824 StreamString ss;
825
826 location_value->Dump(&ss);
827
Greg Clayton8de27c72010-10-15 22:48:33 +0000828 err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", name.GetCString(), ss.GetString().c_str());
Sean Callanan17c6a052010-10-05 20:18:48 +0000829 return false;
830 }
831
832 lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
833
834 if (!register_info)
835 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000836 err.SetErrorStringWithFormat("Couldn't get the register information for %s", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000837 return false;
838 }
839
840 RegisterContext *register_context = exe_ctx.GetRegisterContext();
841
842 if (!register_context)
843 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000844 err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000845 return false;
846 }
847
848 uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
849 uint32_t register_byte_size = register_info->byte_size;
850
851 if (dematerialize)
852 {
853 // Moving from addr into a register
854 //
855 // Case 1: addr_byte_size and register_byte_size are the same
856 //
857 // |AABBCCDD| Address contents
858 // |AABBCCDD| Register contents
859 //
860 // Case 2: addr_byte_size is bigger than register_byte_size
861 //
862 // Error! (The register should always be big enough to hold the data)
863 //
864 // Case 3: register_byte_size is bigger than addr_byte_size
865 //
866 // |AABB| Address contents
867 // |AABB0000| Register contents [on little-endian hardware]
868 // |0000AABB| Register contents [on big-endian hardware]
869
870 if (addr_byte_size > register_byte_size)
871 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000872 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000873 return false;
874 }
875
876 uint32_t register_offset;
877
878 switch (exe_ctx.process->GetByteOrder())
879 {
880 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000881 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000882 return false;
883 case lldb::eByteOrderLittle:
884 register_offset = 0;
885 break;
886 case lldb::eByteOrderBig:
887 register_offset = register_byte_size - addr_byte_size;
888 break;
889 }
890
891 DataBufferHeap register_data (register_byte_size, 0);
892
893 Error error;
894 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes() + register_offset, addr_byte_size, error) != addr_byte_size)
895 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000896 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", name.GetCString(), error.AsCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000897 return false;
898 }
899
900 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
901
902 if (!register_context->WriteRegisterBytes(register_number, register_extractor, 0))
903 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000904 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000905 return false;
906 }
907 }
908 else
909 {
910 // Moving from a register into addr
911 //
912 // Case 1: addr_byte_size and register_byte_size are the same
913 //
914 // |AABBCCDD| Register contents
915 // |AABBCCDD| Address contents
916 //
917 // Case 2: addr_byte_size is bigger than register_byte_size
918 //
919 // Error! (The register should always be big enough to hold the data)
920 //
921 // Case 3: register_byte_size is bigger than addr_byte_size
922 //
923 // |AABBCCDD| Register contents
924 // |AABB| Address contents on little-endian hardware
925 // |CCDD| Address contents on big-endian hardware
926
927 if (addr_byte_size > register_byte_size)
928 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000929 err.SetErrorStringWithFormat("%s is too big to store in %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000930 return false;
931 }
932
933 uint32_t register_offset;
934
935 switch (exe_ctx.process->GetByteOrder())
936 {
937 default:
Greg Clayton8de27c72010-10-15 22:48:33 +0000938 err.SetErrorStringWithFormat("%s is stored with an unhandled byte order", name.GetCString());
Sean Callanan17c6a052010-10-05 20:18:48 +0000939 return false;
940 case lldb::eByteOrderLittle:
941 register_offset = 0;
942 break;
943 case lldb::eByteOrderBig:
944 register_offset = register_byte_size - addr_byte_size;
945 break;
946 }
947
948 DataExtractor register_extractor;
949
950 if (!register_context->ReadRegisterBytes(register_number, register_extractor))
951 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000952 err.SetErrorStringWithFormat("Couldn't read %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000953 return false;
954 }
955
956 const void *register_data = register_extractor.GetData(&register_offset, addr_byte_size);
957
958 if (!register_data)
959 {
Greg Clayton8de27c72010-10-15 22:48:33 +0000960 err.SetErrorStringWithFormat("Read but couldn't extract data for %s from %s", name.GetCString(), register_info->name);
Sean Callanan17c6a052010-10-05 20:18:48 +0000961 return false;
962 }
963
964 Error error;
965 if (exe_ctx.process->WriteMemory (addr, register_data, addr_byte_size, error) != addr_byte_size)
966 {
967 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
968 return false;
969 }
970 }
971 }
Sean Callananf328c9f2010-07-20 23:31:16 +0000972 }
973
974 return true;
Sean Callanan810f22d2010-07-16 00:09:46 +0000975}
976
Sean Callanan1ddd9fe2010-11-30 00:27:43 +0000977bool
978ClangExpressionDeclMap::DoMaterializeOneRegister
979(
980 bool dematerialize,
981 ExecutionContext &exe_ctx,
982 RegisterContext &reg_ctx,
983 const lldb::RegisterInfo &reg_info,
984 lldb::addr_t addr,
985 Error &err
986)
987{
988 uint32_t register_number = reg_info.kinds[lldb::eRegisterKindLLDB];
989 uint32_t register_byte_size = reg_info.byte_size;
990
991 Error error;
992
993 if (dematerialize)
994 {
995 DataBufferHeap register_data (register_byte_size, 0);
996
997 Error error;
998 if (exe_ctx.process->ReadMemory (addr, register_data.GetBytes(), register_byte_size, error) != register_byte_size)
999 {
1000 err.SetErrorStringWithFormat ("Couldn't read %s from the target: %s", reg_info.name, error.AsCString());
1001 return false;
1002 }
1003
1004 DataExtractor register_extractor (register_data.GetBytes(), register_byte_size, exe_ctx.process->GetByteOrder(), exe_ctx.process->GetAddressByteSize());
1005
1006 if (!reg_ctx.WriteRegisterBytes(register_number, register_extractor, 0))
1007 {
1008 err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name);
1009 return false;
1010 }
1011 }
1012 else
1013 {
1014 DataExtractor register_extractor;
1015
1016 if (!reg_ctx.ReadRegisterBytes(register_number, register_extractor))
1017 {
1018 err.SetErrorStringWithFormat("Couldn't read %s", reg_info.name);
1019 return false;
1020 }
1021
1022 uint32_t register_offset = 0;
1023
1024 const void *register_data = register_extractor.GetData(&register_offset, register_byte_size);
1025
1026 if (!register_data)
1027 {
1028 err.SetErrorStringWithFormat("Read but couldn't extract data for %s", reg_info.name);
1029 return false;
1030 }
1031
1032 Error error;
1033 if (exe_ctx.process->WriteMemory (addr, register_data, register_byte_size, error) != register_byte_size)
1034 {
1035 err.SetErrorStringWithFormat ("Couldn't write %s to the target: %s", error.AsCString());
1036 return false;
1037 }
1038 }
1039
1040 return true;
1041}
1042
Sean Callanancc074622010-09-14 21:59:34 +00001043Variable *
Greg Clayton8de27c72010-10-15 22:48:33 +00001044ClangExpressionDeclMap::FindVariableInScope
1045(
1046 StackFrame &frame,
1047 const ConstString &name,
1048 TypeFromUser *type
1049)
Sean Callananaa301c42010-12-03 01:38:59 +00001050{
Greg Claytone005f2c2010-11-06 01:53:30 +00001051 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanancc074622010-09-14 21:59:34 +00001052
Sean Callanancc074622010-09-14 21:59:34 +00001053 VariableList *var_list = frame.GetVariableList(true);
1054
Greg Claytonbf8e42b2010-10-14 22:52:14 +00001055 if (!var_list)
1056 return NULL;
1057
Greg Clayton3bc52d02010-11-14 22:13:40 +00001058 lldb::VariableSP var_sp (var_list->FindVariable(name));
1059
1060 const bool append = true;
1061 const uint32_t max_matches = 1;
1062 if (!var_sp)
Sean Callanancc074622010-09-14 21:59:34 +00001063 {
Greg Clayton3bc52d02010-11-14 22:13:40 +00001064 // Look for globals elsewhere in the module for the frame
Sean Callananaa301c42010-12-03 01:38:59 +00001065 ModuleSP module_sp (frame.GetSymbolContext(eSymbolContextModule).module_sp);
Greg Clayton3bc52d02010-11-14 22:13:40 +00001066 if (module_sp)
1067 {
1068 VariableList module_globals;
1069 if (module_sp->FindGlobalVariables (name, append, max_matches, module_globals))
1070 var_sp = module_globals.GetVariableAtIndex (0);
1071 }
1072 }
1073
1074 if (!var_sp)
1075 {
1076 // Look for globals elsewhere in the program (all images)
Sean Callananaa301c42010-12-03 01:38:59 +00001077 TargetSP target_sp (frame.GetSymbolContext(eSymbolContextTarget).target_sp);
Greg Clayton3bc52d02010-11-14 22:13:40 +00001078 if (target_sp)
1079 {
1080 VariableList program_globals;
1081 if (target_sp->GetImages().FindGlobalVariables (name, append, max_matches, program_globals))
1082 var_sp = program_globals.GetVariableAtIndex (0);
1083 }
1084 }
1085
1086 if (var_sp && type)
1087 {
1088 if (type->GetASTContext() == var_sp->GetType()->GetClangAST())
1089 {
1090 if (!ClangASTContext::AreTypesSame(type->GetASTContext(), type->GetOpaqueQualType(), var_sp->GetType()->GetClangType()))
1091 return NULL;
1092 }
1093 else
1094 {
1095 if (log)
1096 log->PutCString("Skipping a candidate variable because of different AST contexts");
Sean Callanancc074622010-09-14 21:59:34 +00001097 return NULL;
Greg Clayton3bc52d02010-11-14 22:13:40 +00001098 }
Sean Callanancc074622010-09-14 21:59:34 +00001099 }
Greg Clayton3bc52d02010-11-14 22:13:40 +00001100
1101 return var_sp.get();
Sean Callanancc074622010-09-14 21:59:34 +00001102}
Sean Callanan336a0002010-07-17 00:43:37 +00001103
Chris Lattner24943d22010-06-08 16:52:24 +00001104// Interface for ClangASTSource
1105void
Greg Claytone5748d82010-11-09 23:46:37 +00001106ClangExpressionDeclMap::GetDecls (NameSearchContext &context, const ConstString &name)
Chris Lattner24943d22010-06-08 16:52:24 +00001107{
Sean Callananaa301c42010-12-03 01:38:59 +00001108 assert (m_struct_vars.get());
1109 assert (m_parser_vars.get());
1110
Greg Claytone005f2c2010-11-06 01:53:30 +00001111 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001112
Sean Callanan810f22d2010-07-16 00:09:46 +00001113 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001114 log->Printf("Hunting for a definition for '%s'", name.GetCString());
Chris Lattner24943d22010-06-08 16:52:24 +00001115
1116 // Back out in all cases where we're not fully initialized
Sean Callananaa301c42010-12-03 01:38:59 +00001117 if (m_parser_vars->m_exe_ctx->frame == NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001118 return;
Sean Callananee8fc722010-11-19 20:20:02 +00001119
Sean Callananaa301c42010-12-03 01:38:59 +00001120 if (m_parser_vars->m_ignore_lookups)
Sean Callananee8fc722010-11-19 20:20:02 +00001121 {
1122 if (log)
1123 log->Printf("Ignoring a query during an import");
1124 return;
1125 }
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001126
Greg Claytone5748d82010-11-09 23:46:37 +00001127 SymbolContextList sc_list;
Chris Lattner24943d22010-06-08 16:52:24 +00001128
Greg Clayton3bc52d02010-11-14 22:13:40 +00001129 const char *name_unique_cstr = name.GetCString();
1130
1131 if (name_unique_cstr == NULL)
1132 return;
1133
Greg Clayton8de27c72010-10-15 22:48:33 +00001134 // Only look for functions by name out in our symbols if the function
1135 // doesn't start with our phony prefix of '$'
Greg Clayton3bc52d02010-11-14 22:13:40 +00001136 if (name_unique_cstr[0] != '$')
Sean Callanan0fc73582010-07-27 00:55:47 +00001137 {
Sean Callananaa301c42010-12-03 01:38:59 +00001138 Variable *var = FindVariableInScope(*m_parser_vars->m_exe_ctx->frame, name);
Greg Clayton8de27c72010-10-15 22:48:33 +00001139
1140 // If we found a variable in scope, no need to pull up function names
1141 if (var != NULL)
1142 {
1143 AddOneVariable(context, var);
1144 }
1145 else
1146 {
Sean Callananaa301c42010-12-03 01:38:59 +00001147 m_parser_vars->m_sym_ctx.FindFunctionsByName (name, false, sc_list);
Greg Clayton8de27c72010-10-15 22:48:33 +00001148
1149 bool found_specific = false;
1150 Symbol *generic_symbol = NULL;
1151 Symbol *non_extern_symbol = NULL;
1152
Greg Claytone5748d82010-11-09 23:46:37 +00001153 for (uint32_t index = 0, num_indices = sc_list.GetSize();
Greg Clayton8de27c72010-10-15 22:48:33 +00001154 index < num_indices;
1155 ++index)
1156 {
1157 SymbolContext sym_ctx;
Greg Claytone5748d82010-11-09 23:46:37 +00001158 sc_list.GetContextAtIndex(index, sym_ctx);
Sean Callanan3cfbd332010-10-06 00:10:07 +00001159
Greg Clayton8de27c72010-10-15 22:48:33 +00001160 if (sym_ctx.function)
1161 {
1162 // TODO only do this if it's a C function; C++ functions may be
1163 // overloaded
1164 if (!found_specific)
1165 AddOneFunction(context, sym_ctx.function, NULL);
1166 found_specific = true;
1167 }
1168 else if (sym_ctx.symbol)
1169 {
1170 if (sym_ctx.symbol->IsExternal())
1171 generic_symbol = sym_ctx.symbol;
1172 else
1173 non_extern_symbol = sym_ctx.symbol;
1174 }
1175 }
1176
Sean Callanan92aa6662010-09-07 21:49:41 +00001177 if (!found_specific)
Greg Clayton8de27c72010-10-15 22:48:33 +00001178 {
1179 if (generic_symbol)
1180 AddOneFunction(context, NULL, generic_symbol);
1181 else if (non_extern_symbol)
1182 AddOneFunction(context, NULL, non_extern_symbol);
1183 }
Greg Clayton6916e352010-11-13 03:52:47 +00001184
Sean Callananaa301c42010-12-03 01:38:59 +00001185 ClangNamespaceDecl namespace_decl (m_parser_vars->m_sym_ctx.FindNamespace(name));
Greg Clayton6916e352010-11-13 03:52:47 +00001186 if (namespace_decl)
1187 {
Greg Clayton9ceed1e2010-11-13 04:18:24 +00001188 clang::NamespaceDecl *clang_namespace_decl = AddNamespace(context, namespace_decl);
1189 if (clang_namespace_decl)
1190 {
1191 // TODO: is this how we get the decl lookups to be called for
1192 // this namespace??
1193 clang_namespace_decl->setHasExternalLexicalStorage();
1194 }
Greg Clayton6916e352010-11-13 03:52:47 +00001195 }
Sean Callanan92aa6662010-09-07 21:49:41 +00001196 }
Sean Callanan0fc73582010-07-27 00:55:47 +00001197 }
Greg Clayton8de27c72010-10-15 22:48:33 +00001198 else
Sean Callanan3cfbd332010-10-06 00:10:07 +00001199 {
Greg Clayton57452832010-11-09 04:42:43 +00001200 static ConstString g_lldb_class_name ("$__lldb_class");
1201 if (name == g_lldb_class_name)
1202 {
1203 // Clang is looking for the type of "this"
1204
Sean Callananaa301c42010-12-03 01:38:59 +00001205 VariableList *vars = m_parser_vars->m_exe_ctx->frame->GetVariableList(false);
Greg Clayton57452832010-11-09 04:42:43 +00001206
1207 if (!vars)
1208 return;
1209
1210 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
1211
1212 if (!this_var)
1213 return;
1214
1215 Type *this_type = this_var->GetType();
1216
1217 if (!this_type)
1218 return;
1219
Greg Clayton2403b5e2010-11-16 02:10:54 +00001220 if (log)
1221 {
1222 log->PutCString ("Type for \"this\" is: ");
1223 StreamString strm;
1224 this_type->Dump(&strm, true);
1225 log->PutCString (strm.GetData());
1226 }
1227
Greg Clayton57452832010-11-09 04:42:43 +00001228 TypeFromUser this_user_type(this_type->GetClangType(),
1229 this_type->GetClangAST());
1230
Sean Callananaa301c42010-12-03 01:38:59 +00001231 m_struct_vars->m_object_pointer_type = this_user_type;
Greg Clayton57452832010-11-09 04:42:43 +00001232
1233 void *pointer_target_type;
1234
1235 if (!ClangASTContext::IsPointerType(this_user_type.GetOpaqueQualType(),
1236 &pointer_target_type))
1237 return;
1238
1239 TypeFromUser class_user_type(pointer_target_type,
1240 this_type->GetClangAST());
1241
1242 AddOneType(context, class_user_type, true);
1243
1244 return;
1245 }
1246
Sean Callananaa301c42010-12-03 01:38:59 +00001247 ClangExpressionVariable *pvar(m_parser_vars->m_persistent_vars->GetVariable(name));
Greg Clayton8de27c72010-10-15 22:48:33 +00001248
1249 if (pvar)
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001250 {
Greg Clayton8de27c72010-10-15 22:48:33 +00001251 AddOneVariable(context, pvar);
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001252 return;
1253 }
1254
1255 const char *reg_name(&name.GetCString()[1]);
1256
Sean Callananaa301c42010-12-03 01:38:59 +00001257 if (m_parser_vars->m_exe_ctx->GetRegisterContext())
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001258 {
Sean Callananaa301c42010-12-03 01:38:59 +00001259 const lldb::RegisterInfo *reg_info(m_parser_vars->m_exe_ctx->GetRegisterContext()->GetRegisterInfoByName(reg_name));
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001260
1261 if (reg_info)
1262 AddOneRegister(context, reg_info);
1263 }
Sean Callanan3cfbd332010-10-06 00:10:07 +00001264 }
1265
Sean Callananaa301c42010-12-03 01:38:59 +00001266 lldb::TypeSP type_sp (m_parser_vars->m_sym_ctx.FindTypeByName (name));
Sean Callananee8fc722010-11-19 20:20:02 +00001267
1268 if (type_sp)
Sean Callanan6df08402010-09-27 23:54:58 +00001269 {
Sean Callananee8fc722010-11-19 20:20:02 +00001270 if (log)
Sean Callanan6df08402010-09-27 23:54:58 +00001271 {
Sean Callananee8fc722010-11-19 20:20:02 +00001272 log->Printf ("Matching type found for \"%s\": ", name.GetCString());
1273 StreamString strm;
1274 type_sp->Dump(&strm, true);
1275 log->PutCString (strm.GetData());
1276 }
Greg Clayton2403b5e2010-11-16 02:10:54 +00001277
Sean Callananee8fc722010-11-19 20:20:02 +00001278 TypeFromUser user_type(type_sp->GetClangType(),
Greg Clayton2403b5e2010-11-16 02:10:54 +00001279 type_sp->GetClangAST());
Sean Callanan6df08402010-09-27 23:54:58 +00001280
Sean Callananee8fc722010-11-19 20:20:02 +00001281 AddOneType(context, user_type, false);
Sean Callanan6df08402010-09-27 23:54:58 +00001282 }
Sean Callanan336a0002010-07-17 00:43:37 +00001283}
1284
1285Value *
Greg Clayton8de27c72010-10-15 22:48:33 +00001286ClangExpressionDeclMap::GetVariableValue
1287(
1288 ExecutionContext &exe_ctx,
1289 Variable *var,
1290 clang::ASTContext *parser_ast_context,
1291 TypeFromUser *user_type,
1292 TypeFromParser *parser_type
1293)
Chris Lattner24943d22010-06-08 16:52:24 +00001294{
Greg Claytone005f2c2010-11-06 01:53:30 +00001295 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan6184dfe2010-06-23 00:47:48 +00001296
Chris Lattner24943d22010-06-08 16:52:24 +00001297 Type *var_type = var->GetType();
1298
1299 if (!var_type)
1300 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001301 if (log)
1302 log->PutCString("Skipped a definition because it has no type");
Sean Callanan336a0002010-07-17 00:43:37 +00001303 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001304 }
1305
Greg Clayton462d4142010-09-29 01:12:09 +00001306 void *var_opaque_type = var_type->GetClangType();
Chris Lattner24943d22010-06-08 16:52:24 +00001307
1308 if (!var_opaque_type)
1309 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001310 if (log)
1311 log->PutCString("Skipped a definition because it has no Clang type");
Sean Callanan336a0002010-07-17 00:43:37 +00001312 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001313 }
1314
Chris Lattner24943d22010-06-08 16:52:24 +00001315 TypeList *type_list = var_type->GetTypeList();
1316
1317 if (!type_list)
1318 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001319 if (log)
1320 log->PutCString("Skipped a definition because the type has no associated type list");
Sean Callanan336a0002010-07-17 00:43:37 +00001321 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001322 }
1323
1324 clang::ASTContext *exe_ast_ctx = type_list->GetClangASTContext().getASTContext();
1325
1326 if (!exe_ast_ctx)
1327 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001328 if (log)
1329 log->PutCString("There is no AST context for the current execution context");
Sean Callanan336a0002010-07-17 00:43:37 +00001330 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001331 }
1332
Sean Callanan336a0002010-07-17 00:43:37 +00001333 DWARFExpression &var_location_expr = var->LocationExpression();
1334
Chris Lattner24943d22010-06-08 16:52:24 +00001335 std::auto_ptr<Value> var_location(new Value);
1336
Greg Clayton178710c2010-09-14 02:20:48 +00001337 lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
1338
1339 if (var_location_expr.IsLocationList())
1340 {
1341 SymbolContext var_sc;
1342 var->CalculateSymbolContext (&var_sc);
Greg Claytoneea26402010-09-14 23:36:40 +00001343 loclist_base_load_addr = var_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (exe_ctx.target);
Greg Clayton178710c2010-09-14 02:20:48 +00001344 }
Chris Lattner24943d22010-06-08 16:52:24 +00001345 Error err;
1346
Jason Molenda8e69de42010-11-20 01:28:30 +00001347 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 +00001348 {
Sean Callanan810f22d2010-07-16 00:09:46 +00001349 if (log)
1350 log->Printf("Error evaluating location: %s", err.AsCString());
Sean Callanan336a0002010-07-17 00:43:37 +00001351 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001352 }
1353
Sean Callanan810f22d2010-07-16 00:09:46 +00001354 clang::ASTContext *var_ast_context = type_list->GetClangASTContext().getASTContext();
1355
Sean Callanan336a0002010-07-17 00:43:37 +00001356 void *type_to_use;
1357
Sean Callananf328c9f2010-07-20 23:31:16 +00001358 if (parser_ast_context)
1359 {
Sean Callananee8fc722010-11-19 20:20:02 +00001360 type_to_use = GuardedCopyType(parser_ast_context, var_ast_context, var_opaque_type);
Sean Callananf328c9f2010-07-20 23:31:16 +00001361
Sean Callanan4b5eec62010-11-20 02:19:29 +00001362 if (!type_to_use)
1363 {
1364 if (log)
1365 log->Printf("Couldn't copy a variable's type into the parser's AST context");
1366
1367 return NULL;
1368 }
1369
Sean Callananf328c9f2010-07-20 23:31:16 +00001370 if (parser_type)
1371 *parser_type = TypeFromParser(type_to_use, parser_ast_context);
1372 }
Sean Callanan336a0002010-07-17 00:43:37 +00001373 else
1374 type_to_use = var_opaque_type;
Chris Lattner24943d22010-06-08 16:52:24 +00001375
1376 if (var_location.get()->GetContextType() == Value::eContextTypeInvalid)
Greg Clayton6916e352010-11-13 03:52:47 +00001377 var_location.get()->SetContext(Value::eContextTypeClangType, type_to_use);
Chris Lattner24943d22010-06-08 16:52:24 +00001378
1379 if (var_location.get()->GetValueType() == Value::eValueTypeFileAddress)
1380 {
1381 SymbolContext var_sc;
1382 var->CalculateSymbolContext(&var_sc);
Sean Callanan336a0002010-07-17 00:43:37 +00001383
Chris Lattner24943d22010-06-08 16:52:24 +00001384 if (!var_sc.module_sp)
Sean Callanan336a0002010-07-17 00:43:37 +00001385 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +00001386
1387 ObjectFile *object_file = var_sc.module_sp->GetObjectFile();
1388
1389 if (!object_file)
Sean Callanan336a0002010-07-17 00:43:37 +00001390 return NULL;
1391
Chris Lattner24943d22010-06-08 16:52:24 +00001392 Address so_addr(var_location->GetScalar().ULongLong(), object_file->GetSectionList());
1393
Sean Callananaa301c42010-12-03 01:38:59 +00001394 lldb::addr_t load_addr = so_addr.GetLoadAddress(exe_ctx.target);
Chris Lattner24943d22010-06-08 16:52:24 +00001395
1396 var_location->GetScalar() = load_addr;
1397 var_location->SetValueType(Value::eValueTypeLoadAddress);
1398 }
1399
Sean Callananf328c9f2010-07-20 23:31:16 +00001400 if (user_type)
1401 *user_type = TypeFromUser(var_opaque_type, var_ast_context);
Sean Callanan336a0002010-07-17 00:43:37 +00001402
1403 return var_location.release();
1404}
1405
1406void
1407ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001408 Variable* var)
Sean Callanan336a0002010-07-17 00:43:37 +00001409{
Sean Callananaa301c42010-12-03 01:38:59 +00001410 assert (m_parser_vars.get());
1411
Greg Claytone005f2c2010-11-06 01:53:30 +00001412 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan336a0002010-07-17 00:43:37 +00001413
Sean Callananf328c9f2010-07-20 23:31:16 +00001414 TypeFromUser ut;
1415 TypeFromParser pt;
Sean Callanan336a0002010-07-17 00:43:37 +00001416
Sean Callananaa301c42010-12-03 01:38:59 +00001417 Value *var_location = GetVariableValue (*m_parser_vars->m_exe_ctx,
Greg Clayton8de27c72010-10-15 22:48:33 +00001418 var,
1419 context.GetASTContext(),
1420 &ut,
1421 &pt);
Sean Callanan336a0002010-07-17 00:43:37 +00001422
Sean Callanan4b5eec62010-11-20 02:19:29 +00001423 if (!var_location)
1424 return;
1425
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001426 NamedDecl *var_decl = context.AddVarDecl(pt.GetOpaqueQualType());
Chris Lattner24943d22010-06-08 16:52:24 +00001427
Sean Callanan8c127202010-08-23 23:09:38 +00001428 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001429 std::string decl_name(context.m_decl_name.getAsString());
1430 entity.m_name.SetCString (decl_name.c_str());
1431 entity.m_user_type = ut;
Chris Lattner24943d22010-06-08 16:52:24 +00001432
Sean Callanan8c127202010-08-23 23:09:38 +00001433 entity.EnableParserVars();
1434 entity.m_parser_vars->m_parser_type = pt;
1435 entity.m_parser_vars->m_named_decl = var_decl;
1436 entity.m_parser_vars->m_llvm_value = NULL;
1437 entity.m_parser_vars->m_lldb_value = var_location;
Chris Lattner24943d22010-06-08 16:52:24 +00001438
Sean Callanan810f22d2010-07-16 00:09:46 +00001439 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001440 {
Sean Callanana0744822010-11-01 23:22:47 +00001441 std::string var_decl_print_string;
1442 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1443 var_decl->print(var_decl_print_stream);
1444 var_decl_print_stream.flush();
1445
1446 log->Printf("Found variable %s, returned %s", decl_name.c_str(), var_decl_print_string.c_str());
Greg Clayton8de27c72010-10-15 22:48:33 +00001447 }
Sean Callanan8f0dc342010-06-22 23:46:24 +00001448}
1449
1450void
Sean Callanana48fe162010-08-11 03:57:18 +00001451ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
Sean Callanana6223432010-08-20 01:02:30 +00001452 ClangExpressionVariable *pvar)
Sean Callanana48fe162010-08-11 03:57:18 +00001453{
Greg Claytone005f2c2010-11-06 01:53:30 +00001454 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan45690fe2010-08-30 22:17:16 +00001455
Sean Callanana6223432010-08-20 01:02:30 +00001456 TypeFromUser user_type = pvar->m_user_type;
Sean Callanana48fe162010-08-11 03:57:18 +00001457
Sean Callananee8fc722010-11-19 20:20:02 +00001458 TypeFromParser parser_type(GuardedCopyType(context.GetASTContext(),
1459 user_type.GetASTContext(),
1460 user_type.GetOpaqueQualType()),
Sean Callanana48fe162010-08-11 03:57:18 +00001461 context.GetASTContext());
1462
Sean Callanan8c127202010-08-23 23:09:38 +00001463 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1464
1465 pvar->EnableParserVars();
1466 pvar->m_parser_vars->m_parser_type = parser_type;
1467 pvar->m_parser_vars->m_named_decl = var_decl;
1468 pvar->m_parser_vars->m_llvm_value = NULL;
1469 pvar->m_parser_vars->m_lldb_value = NULL;
Sean Callanan45690fe2010-08-30 22:17:16 +00001470
1471 if (log)
Sean Callanana0744822010-11-01 23:22:47 +00001472 {
1473 std::string var_decl_print_string;
1474 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1475 var_decl->print(var_decl_print_stream);
1476 var_decl_print_stream.flush();
1477
1478 log->Printf("Added pvar %s, returned %s", pvar->m_name.GetCString(), var_decl_print_string.c_str());
1479 }
Sean Callanana48fe162010-08-11 03:57:18 +00001480}
1481
Sean Callanan1ddd9fe2010-11-30 00:27:43 +00001482void
1483ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
1484 const RegisterInfo *reg_info)
1485{
1486 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1487
1488 void *ast_type = ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(context.GetASTContext(),
1489 reg_info->encoding,
1490 reg_info->byte_size * 8);
1491
1492 if (!ast_type)
1493 {
1494 log->Printf("Tried to add a type for %s, but couldn't get one", context.m_decl_name.getAsString().c_str());
1495 return;
1496 }
1497
1498 TypeFromParser parser_type(ast_type,
1499 context.GetASTContext());
1500
1501 NamedDecl *var_decl = context.AddVarDecl(parser_type.GetOpaqueQualType());
1502
1503 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
1504 std::string decl_name(context.m_decl_name.getAsString());
1505 entity.m_name.SetCString (decl_name.c_str());
1506 entity.m_register_info = reg_info;
1507
1508 entity.EnableParserVars();
1509 entity.m_parser_vars->m_parser_type = parser_type;
1510 entity.m_parser_vars->m_named_decl = var_decl;
1511 entity.m_parser_vars->m_llvm_value = NULL;
1512 entity.m_parser_vars->m_lldb_value = NULL;
1513
1514 if (log)
1515 {
1516 std::string var_decl_print_string;
1517 llvm::raw_string_ostream var_decl_print_stream(var_decl_print_string);
1518 var_decl->print(var_decl_print_stream);
1519 var_decl_print_stream.flush();
1520
1521 log->Printf("Added register %s, returned %s", context.m_decl_name.getAsString().c_str(), var_decl_print_string.c_str());
1522 }
1523}
1524
Greg Clayton6916e352010-11-13 03:52:47 +00001525clang::NamespaceDecl *
1526ClangExpressionDeclMap::AddNamespace (NameSearchContext &context, const ClangNamespaceDecl &namespace_decl)
1527{
1528 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1529
1530
1531 clang::Decl *copied_decl = ClangASTContext::CopyDecl (context.GetASTContext(),
1532 namespace_decl.GetASTContext(),
1533 namespace_decl.GetNamespaceDecl());
1534
1535 return dyn_cast<clang::NamespaceDecl>(copied_decl);
1536}
1537
Sean Callanana48fe162010-08-11 03:57:18 +00001538void
Sean Callanan8f0dc342010-06-22 23:46:24 +00001539ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Sean Callanan0fc73582010-07-27 00:55:47 +00001540 Function* fun,
1541 Symbol* symbol)
Sean Callanan8f0dc342010-06-22 23:46:24 +00001542{
Sean Callananaa301c42010-12-03 01:38:59 +00001543 assert (m_parser_vars.get());
1544
Greg Claytone005f2c2010-11-06 01:53:30 +00001545 lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8f0dc342010-06-22 23:46:24 +00001546
Sean Callanan0fc73582010-07-27 00:55:47 +00001547 NamedDecl *fun_decl;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001548 std::auto_ptr<Value> fun_location(new Value);
Sean Callanan0fc73582010-07-27 00:55:47 +00001549 const Address *fun_address;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001550
Sean Callanan0fc73582010-07-27 00:55:47 +00001551 // only valid for Functions, not for Symbols
1552 void *fun_opaque_type = NULL;
1553 clang::ASTContext *fun_ast_context = NULL;
1554
1555 if (fun)
1556 {
1557 Type *fun_type = fun->GetType();
1558
1559 if (!fun_type)
1560 {
1561 if (log)
1562 log->PutCString("Skipped a function because it has no type");
1563 return;
1564 }
1565
Greg Clayton462d4142010-09-29 01:12:09 +00001566 fun_opaque_type = fun_type->GetClangType();
Sean Callanan0fc73582010-07-27 00:55:47 +00001567
1568 if (!fun_opaque_type)
1569 {
1570 if (log)
1571 log->PutCString("Skipped a function because it has no Clang type");
1572 return;
1573 }
1574
1575 fun_address = &fun->GetAddressRange().GetBaseAddress();
1576
1577 TypeList *type_list = fun_type->GetTypeList();
1578 fun_ast_context = type_list->GetClangASTContext().getASTContext();
Sean Callananee8fc722010-11-19 20:20:02 +00001579 void *copied_type = GuardedCopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
Sean Callanan0fc73582010-07-27 00:55:47 +00001580
1581 fun_decl = context.AddFunDecl(copied_type);
1582 }
1583 else if (symbol)
1584 {
1585 fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
1586
1587 fun_decl = context.AddGenericFunDecl();
1588 }
1589 else
1590 {
1591 if (log)
1592 log->PutCString("AddOneFunction called with no function and no symbol");
1593 return;
1594 }
1595
Sean Callananaa301c42010-12-03 01:38:59 +00001596 lldb::addr_t load_addr = fun_address->GetLoadAddress(m_parser_vars->m_exe_ctx->target);
Sean Callanan8f0dc342010-06-22 23:46:24 +00001597 fun_location->SetValueType(Value::eValueTypeLoadAddress);
1598 fun_location->GetScalar() = load_addr;
1599
Sean Callanan8c127202010-08-23 23:09:38 +00001600 ClangExpressionVariable &entity(m_found_entities.VariableAtIndex(m_found_entities.CreateVariable()));
Greg Clayton8de27c72010-10-15 22:48:33 +00001601 std::string decl_name(context.m_decl_name.getAsString());
1602 entity.m_name.SetCString(decl_name.c_str());
Sean Callanan8c127202010-08-23 23:09:38 +00001603 entity.m_user_type = TypeFromUser(fun_opaque_type, fun_ast_context);;
Sean Callanan8f0dc342010-06-22 23:46:24 +00001604
Sean Callanan8c127202010-08-23 23:09:38 +00001605 entity.EnableParserVars();
1606 entity.m_parser_vars->m_named_decl = fun_decl;
1607 entity.m_parser_vars->m_llvm_value = NULL;
1608 entity.m_parser_vars->m_lldb_value = fun_location.release();
1609
Sean Callanan810f22d2010-07-16 00:09:46 +00001610 if (log)
Greg Clayton8de27c72010-10-15 22:48:33 +00001611 {
Sean Callanana0744822010-11-01 23:22:47 +00001612 std::string fun_decl_print_string;
1613 llvm::raw_string_ostream fun_decl_print_stream(fun_decl_print_string);
1614 fun_decl->print(fun_decl_print_stream);
1615 fun_decl_print_stream.flush();
1616
1617 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 +00001618 }
Chris Lattner24943d22010-06-08 16:52:24 +00001619}
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001620
1621void
1622ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001623 TypeFromUser &ut,
1624 bool add_method)
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001625{
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001626 clang::ASTContext *parser_ast_context = context.GetASTContext();
1627 clang::ASTContext *user_ast_context = ut.GetASTContext();
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001628
Sean Callananee8fc722010-11-19 20:20:02 +00001629 void *copied_type = GuardedCopyType(parser_ast_context, user_ast_context, ut.GetOpaqueQualType());
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001630
1631 TypeFromParser parser_type(copied_type, parser_ast_context);
1632
1633 if (add_method && ClangASTContext::IsAggregateType(copied_type))
1634 {
1635 void *args[1];
1636
1637 args[0] = ClangASTContext::GetVoidPtrType(parser_ast_context, false);
1638
1639 void *method_type = ClangASTContext::CreateFunctionType (parser_ast_context,
1640 ClangASTContext::GetBuiltInType_void(parser_ast_context),
1641 args,
1642 1,
1643 false,
1644 ClangASTContext::GetTypeQualifiers(copied_type));
Greg Clayton30449d52010-10-01 02:31:07 +00001645
Greg Clayton1d8173f2010-09-24 05:15:53 +00001646 const bool is_virtual = false;
1647 const bool is_static = false;
1648 const bool is_inline = false;
Greg Clayton30449d52010-10-01 02:31:07 +00001649 const bool is_explicit = false;
1650
Greg Clayton1d8173f2010-09-24 05:15:53 +00001651 ClangASTContext::AddMethodToCXXRecordType (parser_ast_context,
1652 copied_type,
Greg Clayton8de27c72010-10-15 22:48:33 +00001653 "$__lldb_expr",
Greg Clayton1d8173f2010-09-24 05:15:53 +00001654 method_type,
1655 lldb::eAccessPublic,
1656 is_virtual,
1657 is_static,
Greg Clayton30449d52010-10-01 02:31:07 +00001658 is_inline,
1659 is_explicit);
Sean Callanan3c9c5eb2010-09-21 00:44:12 +00001660 }
Sean Callanan93a4b1a2010-08-04 01:02:13 +00001661
1662 context.AddTypeDecl(copied_type);
1663}
Sean Callananee8fc722010-11-19 20:20:02 +00001664
1665void *
1666ClangExpressionDeclMap::GuardedCopyType (ASTContext *dest_context,
1667 ASTContext *source_context,
1668 void *clang_type)
1669{
Sean Callananaa301c42010-12-03 01:38:59 +00001670 assert (m_parser_vars.get());
1671
1672 m_parser_vars->m_ignore_lookups = true;
Sean Callananee8fc722010-11-19 20:20:02 +00001673
1674 void *ret = ClangASTContext::CopyType (dest_context,
1675 source_context,
1676 clang_type);
1677
Sean Callananaa301c42010-12-03 01:38:59 +00001678 m_parser_vars->m_ignore_lookups = false;
Sean Callananee8fc722010-11-19 20:20:02 +00001679
1680 return ret;
1681}