blob: a8bf0974d16f4ed2a3cc21aef165c18134e0d388 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- Variable.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/Symbol/Variable.h"
11
Greg Clayton1f746072012-08-29 21:13:06 +000012#include "lldb/Core/Module.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include "lldb/Core/Stream.h"
Greg Clayton83c5cd92010-11-14 22:13:40 +000014#include "lldb/Core/RegularExpression.h"
Greg Clayton884fb692011-07-08 21:46:14 +000015#include "lldb/Core/ValueObject.h"
16#include "lldb/Core/ValueObjectVariable.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Symbol/Block.h"
Paul Hermand628cbb2015-09-15 23:44:17 +000018#include "lldb/Symbol/CompilerDecl.h"
19#include "lldb/Symbol/CompilerDeclContext.h"
Greg Claytonddaf6a72015-07-08 22:32:23 +000020#include "lldb/Symbol/CompileUnit.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Symbol/Function.h"
22#include "lldb/Symbol/SymbolContext.h"
Paul Hermand628cbb2015-09-15 23:44:17 +000023#include "lldb/Symbol/SymbolFile.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Symbol/Type.h"
Greg Clayton884fb692011-07-08 21:46:14 +000025#include "lldb/Symbol/VariableList.h"
Greg Claytonafacd142011-09-02 01:15:17 +000026#include "lldb/Target/ABI.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000027#include "lldb/Target/Process.h"
Greg Clayton9da7bd02010-08-24 21:05:24 +000028#include "lldb/Target/RegisterContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000029#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Target/Thread.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000031#include "lldb/Target/Target.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032
33using namespace lldb;
34using namespace lldb_private;
35
36//----------------------------------------------------------------------
37// Variable constructor
38//----------------------------------------------------------------------
Greg Clayton83c5cd92010-11-14 22:13:40 +000039Variable::Variable
40(
41 lldb::user_id_t uid,
42 const char *name,
Siva Chandra0783ab92015-03-24 18:32:27 +000043 const char *mangled, // The mangled or fully qualified name of the variable.
Greg Claytond1767f02011-12-08 02:13:16 +000044 const lldb::SymbolFileTypeSP &symfile_type_sp,
Greg Clayton83c5cd92010-11-14 22:13:40 +000045 ValueType scope,
46 SymbolContextScope *context,
47 Declaration* decl_ptr,
48 const DWARFExpression& location,
49 bool external,
Paul Herman10bc1a42015-08-18 22:46:57 +000050 bool artificial,
51 bool static_member
Greg Clayton83c5cd92010-11-14 22:13:40 +000052) :
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053 UserID(uid),
54 m_name(name),
Siva Chandra0783ab92015-03-24 18:32:27 +000055 m_mangled (ConstString(mangled)),
Greg Claytond1767f02011-12-08 02:13:16 +000056 m_symfile_type_sp(symfile_type_sp),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057 m_scope(scope),
Greg Clayton59e8fc1c2010-08-30 18:11:35 +000058 m_owner_scope(context),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059 m_declaration(decl_ptr),
60 m_location(location),
61 m_external(external),
Paul Herman10bc1a42015-08-18 22:46:57 +000062 m_artificial(artificial),
63 m_static_member(static_member)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064{
65}
66
67//----------------------------------------------------------------------
68// Destructor
69//----------------------------------------------------------------------
70Variable::~Variable()
71{
72}
73
Greg Claytonddaf6a72015-07-08 22:32:23 +000074lldb::LanguageType
75Variable::GetLanguage () const
76{
77 SymbolContext variable_sc;
78 m_owner_scope->CalculateSymbolContext(&variable_sc);
79 if (variable_sc.comp_unit)
80 return variable_sc.comp_unit->GetLanguage();
81 return lldb::eLanguageTypeUnknown;
82}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000083
Greg Claytonddaf6a72015-07-08 22:32:23 +000084
85
86ConstString
Greg Clayton83c5cd92010-11-14 22:13:40 +000087Variable::GetName() const
88{
Pavel Labath89ad5942015-07-09 10:57:54 +000089 ConstString name = m_mangled.GetName(GetLanguage());
90 if (name)
91 return name;
Greg Clayton83c5cd92010-11-14 22:13:40 +000092 return m_name;
93}
94
Paul Hermand628cbb2015-09-15 23:44:17 +000095ConstString
96Variable::GetUnqualifiedName() const
97{
98 return m_name;
99}
100
101
Greg Clayton83c5cd92010-11-14 22:13:40 +0000102bool
Greg Claytonddaf6a72015-07-08 22:32:23 +0000103Variable::NameMatches (const ConstString &name) const
104{
105 if (m_name == name)
106 return true;
107 SymbolContext variable_sc;
108 m_owner_scope->CalculateSymbolContext(&variable_sc);
109
110 LanguageType language = eLanguageTypeUnknown;
111 if (variable_sc.comp_unit)
112 language = variable_sc.comp_unit->GetLanguage();
113 return m_mangled.NameMatches (name, language);
114}
115bool
Greg Clayton83c5cd92010-11-14 22:13:40 +0000116Variable::NameMatches (const RegularExpression& regex) const
117{
118 if (regex.Execute (m_name.AsCString()))
119 return true;
Greg Claytonddaf6a72015-07-08 22:32:23 +0000120 if (m_mangled)
121 return m_mangled.NameMatches (regex, GetLanguage());
122 return false;
Greg Clayton83c5cd92010-11-14 22:13:40 +0000123}
124
Greg Claytond1767f02011-12-08 02:13:16 +0000125Type *
126Variable::GetType()
127{
128 if (m_symfile_type_sp)
129 return m_symfile_type_sp->GetType();
Ed Masted4612ad2014-04-20 13:17:36 +0000130 return nullptr;
Greg Claytond1767f02011-12-08 02:13:16 +0000131}
132
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000133void
134Variable::Dump(Stream *s, bool show_context) const
135{
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000136 s->Printf("%p: ", static_cast<const void*>(this));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000137 s->Indent();
138 *s << "Variable" << (const UserID&)*this;
139
140 if (m_name)
141 *s << ", name = \"" << m_name << "\"";
142
Greg Claytond1767f02011-12-08 02:13:16 +0000143 if (m_symfile_type_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000144 {
Greg Claytond1767f02011-12-08 02:13:16 +0000145 Type *type = m_symfile_type_sp->GetType();
146 if (type)
147 {
148 *s << ", type = {" << type->GetID() << "} " << (void*)type << " (";
149 type->DumpTypeName(s);
150 s->PutChar(')');
151 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000152 }
153
154 if (m_scope != eValueTypeInvalid)
155 {
156 s->PutCString(", scope = ");
157 switch (m_scope)
158 {
159 case eValueTypeVariableGlobal: s->PutCString(m_external ? "global" : "static"); break;
160 case eValueTypeVariableArgument: s->PutCString("parameter"); break;
161 case eValueTypeVariableLocal: s->PutCString("local"); break;
162 default: *s << "??? (" << m_scope << ')';
163 }
164 }
165
Ed Masted4612ad2014-04-20 13:17:36 +0000166 if (show_context && m_owner_scope != nullptr)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000167 {
168 s->PutCString(", context = ( ");
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000169 m_owner_scope->DumpSymbolContext(s);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000170 s->PutCString(" )");
171 }
172
Greg Clayton6dbd3982010-09-15 05:51:24 +0000173 bool show_fullpaths = false;
174 m_declaration.Dump(s, show_fullpaths);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000175
176 if (m_location.IsValid())
177 {
178 s->PutCString(", location = ");
Greg Clayton016a95e2010-09-14 02:20:48 +0000179 lldb::addr_t loclist_base_addr = LLDB_INVALID_ADDRESS;
180 if (m_location.IsLocationList())
181 {
182 SymbolContext variable_sc;
183 m_owner_scope->CalculateSymbolContext(&variable_sc);
184 if (variable_sc.function)
185 loclist_base_addr = variable_sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
186 }
Ed Masted4612ad2014-04-20 13:17:36 +0000187 ABI *abi = nullptr;
Greg Claytonafacd142011-09-02 01:15:17 +0000188 if (m_owner_scope)
189 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000190 ModuleSP module_sp (m_owner_scope->CalculateSymbolContextModule());
191 if (module_sp)
192 abi = ABI::FindPlugin (module_sp->GetArchitecture()).get();
Greg Claytonafacd142011-09-02 01:15:17 +0000193 }
194 m_location.GetDescription(s, lldb::eDescriptionLevelBrief, loclist_base_addr, abi);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000195 }
196
197 if (m_external)
198 s->PutCString(", external");
199
200 if (m_artificial)
201 s->PutCString(", artificial");
202
203 s->EOL();
204}
205
Greg Clayton45ba8542011-07-10 19:21:23 +0000206bool
207Variable::DumpDeclaration (Stream *s, bool show_fullpaths, bool show_module)
208{
209 bool dumped_declaration_info = false;
210 if (m_owner_scope)
211 {
212 SymbolContext sc;
213 m_owner_scope->CalculateSymbolContext(&sc);
Ed Masted4612ad2014-04-20 13:17:36 +0000214 sc.block = nullptr;
Greg Clayton45ba8542011-07-10 19:21:23 +0000215 sc.line_entry.Clear();
216 bool show_inlined_frames = false;
Jason Molendaaff1b352014-10-10 23:07:36 +0000217 const bool show_function_arguments = true;
Jason Molendac980fa92015-02-13 23:24:21 +0000218 const bool show_function_name = true;
Greg Clayton45ba8542011-07-10 19:21:23 +0000219
220 dumped_declaration_info = sc.DumpStopContext (s,
Ed Masted4612ad2014-04-20 13:17:36 +0000221 nullptr,
Greg Clayton45ba8542011-07-10 19:21:23 +0000222 Address(),
223 show_fullpaths,
224 show_module,
Jason Molendaaff1b352014-10-10 23:07:36 +0000225 show_inlined_frames,
Jason Molendac980fa92015-02-13 23:24:21 +0000226 show_function_arguments,
227 show_function_name);
Greg Clayton45ba8542011-07-10 19:21:23 +0000228
229 if (sc.function)
230 s->PutChar(':');
231 }
232 if (m_declaration.DumpStopContext (s, false))
233 dumped_declaration_info = true;
234 return dumped_declaration_info;
235}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000236
237size_t
238Variable::MemorySize() const
239{
240 return sizeof(Variable);
241}
242
Paul Hermand628cbb2015-09-15 23:44:17 +0000243CompilerDeclContext
244Variable::GetDeclContext ()
245{
246 Type *type = GetType();
247 return type->GetSymbolFile()->GetDeclContextContainingUID(GetID());
248}
249
250CompilerDecl
251Variable::GetDecl ()
252{
253 Type *type = GetType();
254 CompilerDecl decl = type->GetSymbolFile()->GetDeclForUID(GetID());
255 if (decl)
256 decl.GetTypeSystem()->DeclLinkToObject(decl.GetOpaqueDecl(), shared_from_this());
257 return decl;
258}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000259
260void
261Variable::CalculateSymbolContext (SymbolContext *sc)
262{
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000263 if (m_owner_scope)
Greg Clayton2501e5e2015-01-15 02:59:20 +0000264 {
Greg Clayton59e8fc1c2010-08-30 18:11:35 +0000265 m_owner_scope->CalculateSymbolContext(sc);
Greg Clayton2501e5e2015-01-15 02:59:20 +0000266 sc->variable = this;
267 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000268 else
Greg Clayton72310352013-02-23 04:12:47 +0000269 sc->Clear(false);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270}
271
Greg Clayton007d5be2011-05-30 00:49:24 +0000272bool
Jason Molendab57e4a12013-11-04 09:33:30 +0000273Variable::LocationIsValidForFrame (StackFrame *frame)
Greg Clayton007d5be2011-05-30 00:49:24 +0000274{
275 // Is the variable is described by a single location?
276 if (!m_location.IsLocationList())
277 {
278 // Yes it is, the location is valid.
279 return true;
280 }
281
282 if (frame)
283 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000284 Function *function = frame->GetSymbolContext(eSymbolContextFunction).function;
285 if (function)
286 {
Greg Claytond9e416c2012-02-18 05:35:26 +0000287 TargetSP target_sp (frame->CalculateTarget());
288
289 addr_t loclist_base_load_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress (target_sp.get());
Greg Clayton007d5be2011-05-30 00:49:24 +0000290 if (loclist_base_load_addr == LLDB_INVALID_ADDRESS)
291 return false;
292 // It is a location list. We just need to tell if the location
293 // list contains the current address when converted to a load
294 // address
295 return m_location.LocationListContainsAddress (loclist_base_load_addr,
Greg Claytond9e416c2012-02-18 05:35:26 +0000296 frame->GetFrameCodeAddress().GetLoadAddress (target_sp.get()));
Greg Clayton007d5be2011-05-30 00:49:24 +0000297 }
298 }
299 return false;
300}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000301
302bool
Greg Claytonc749eb82011-07-11 05:12:02 +0000303Variable::LocationIsValidForAddress (const Address &address)
304{
305 // Be sure to resolve the address to section offset prior to
306 // calling this function.
307 if (address.IsSectionOffset())
308 {
309 SymbolContext sc;
310 CalculateSymbolContext(&sc);
Greg Claytone72dfb32012-02-24 01:59:29 +0000311 if (sc.module_sp == address.GetModule())
Greg Claytonc749eb82011-07-11 05:12:02 +0000312 {
313 // Is the variable is described by a single location?
314 if (!m_location.IsLocationList())
315 {
316 // Yes it is, the location is valid.
317 return true;
318 }
319
320 if (sc.function)
321 {
322 addr_t loclist_base_file_addr = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
323 if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
324 return false;
325 // It is a location list. We just need to tell if the location
326 // list contains the current address when converted to a load
327 // address
328 return m_location.LocationListContainsAddress (loclist_base_file_addr,
329 address.GetFileAddress());
330 }
331 }
332 }
333 return false;
334}
335
336bool
Jason Molendab57e4a12013-11-04 09:33:30 +0000337Variable::IsInScope (StackFrame *frame)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000338{
339 switch (m_scope)
340 {
Greg Clayton007d5be2011-05-30 00:49:24 +0000341 case eValueTypeRegister:
342 case eValueTypeRegisterSet:
Ed Masted4612ad2014-04-20 13:17:36 +0000343 return frame != nullptr;
Greg Clayton007d5be2011-05-30 00:49:24 +0000344
345 case eValueTypeConstResult:
Greg Clayton007d5be2011-05-30 00:49:24 +0000346 case eValueTypeVariableGlobal:
347 case eValueTypeVariableStatic:
Greg Claytondaf515f2011-07-09 20:12:33 +0000348 return true;
349
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000350 case eValueTypeVariableArgument:
351 case eValueTypeVariableLocal:
Greg Clayton007d5be2011-05-30 00:49:24 +0000352 if (frame)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000353 {
354 // We don't have a location list, we just need to see if the block
355 // that this variable was defined in is currently
Greg Clayton6f00abd2010-09-14 03:16:58 +0000356 Block *deepest_frame_block = frame->GetSymbolContext(eSymbolContextBlock).block;
357 if (deepest_frame_block)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000358 {
359 SymbolContext variable_sc;
360 CalculateSymbolContext (&variable_sc);
Greg Clayton007d5be2011-05-30 00:49:24 +0000361 // Check for static or global variable defined at the compile unit
362 // level that wasn't defined in a block
Ed Masted4612ad2014-04-20 13:17:36 +0000363 if (variable_sc.block == nullptr)
Greg Clayton007d5be2011-05-30 00:49:24 +0000364 return true;
365
Greg Clayton6f00abd2010-09-14 03:16:58 +0000366 if (variable_sc.block == deepest_frame_block)
Greg Clayton016a95e2010-09-14 02:20:48 +0000367 return true;
Greg Clayton6f00abd2010-09-14 03:16:58 +0000368 return variable_sc.block->Contains (deepest_frame_block);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369 }
370 }
371 break;
372
373 default:
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374 break;
375 }
376 return false;
377}
378
Greg Clayton884fb692011-07-08 21:46:14 +0000379Error
380Variable::GetValuesForVariableExpressionPath (const char *variable_expr_path,
381 ExecutionContextScope *scope,
382 GetVariableCallback callback,
383 void *baton,
384 VariableList &variable_list,
385 ValueObjectList &valobj_list)
386{
387 Error error;
388 if (variable_expr_path && callback)
389 {
390 switch (variable_expr_path[0])
391 {
392 case '*':
393 {
394 error = Variable::GetValuesForVariableExpressionPath (variable_expr_path + 1,
395 scope,
396 callback,
397 baton,
398 variable_list,
399 valobj_list);
400 if (error.Success())
401 {
402 for (uint32_t i=0; i<valobj_list.GetSize(); )
403 {
404 Error tmp_error;
405 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(i)->Dereference(tmp_error));
406 if (tmp_error.Fail())
407 {
408 variable_list.RemoveVariableAtIndex (i);
409 valobj_list.RemoveValueObjectAtIndex (i);
410 }
411 else
412 {
413 valobj_list.SetValueObjectAtIndex (i, valobj_sp);
414 ++i;
415 }
416 }
417 }
418 else
419 {
420 error.SetErrorString ("unknown error");
421 }
422 return error;
423 }
424 break;
425
426 case '&':
427 {
428 error = Variable::GetValuesForVariableExpressionPath (variable_expr_path + 1,
429 scope,
430 callback,
431 baton,
432 variable_list,
433 valobj_list);
434 if (error.Success())
435 {
436 for (uint32_t i=0; i<valobj_list.GetSize(); )
437 {
438 Error tmp_error;
439 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(i)->AddressOf(tmp_error));
440 if (tmp_error.Fail())
441 {
442 variable_list.RemoveVariableAtIndex (i);
443 valobj_list.RemoveValueObjectAtIndex (i);
444 }
445 else
446 {
447 valobj_list.SetValueObjectAtIndex (i, valobj_sp);
448 ++i;
449 }
450 }
451 }
452 else
453 {
454 error.SetErrorString ("unknown error");
455 }
456 return error;
457 }
458 break;
459
460 default:
461 {
Greg Claytonbc43cab2013-04-03 21:37:16 +0000462 static RegularExpression g_regex ("^([A-Za-z_:][A-Za-z_0-9:]*)(.*)");
463 RegularExpression::Match regex_match(1);
464 if (g_regex.Execute(variable_expr_path, &regex_match))
Greg Clayton884fb692011-07-08 21:46:14 +0000465 {
466 std::string variable_name;
Greg Claytonbc43cab2013-04-03 21:37:16 +0000467 if (regex_match.GetMatchAtIndex(variable_expr_path, 1, variable_name))
Greg Clayton884fb692011-07-08 21:46:14 +0000468 {
469 variable_list.Clear();
470 if (callback (baton, variable_name.c_str(), variable_list))
471 {
472 uint32_t i=0;
473 while (i < variable_list.GetSize())
474 {
475 VariableSP var_sp (variable_list.GetVariableAtIndex (i));
476 ValueObjectSP valobj_sp;
477 if (var_sp)
478 {
479 ValueObjectSP variable_valobj_sp(ValueObjectVariable::Create (scope, var_sp));
480 if (variable_valobj_sp)
481 {
Greg Clayton958d4eb2013-05-20 16:50:51 +0000482 const char *variable_sub_expr_path = variable_expr_path + variable_name.size();
483 if (*variable_sub_expr_path)
Greg Clayton884fb692011-07-08 21:46:14 +0000484 {
Ed Masted4612ad2014-04-20 13:17:36 +0000485 const char* first_unparsed = nullptr;
Greg Clayton884fb692011-07-08 21:46:14 +0000486 ValueObject::ExpressionPathScanEndReason reason_to_stop;
487 ValueObject::ExpressionPathEndResultType final_value_type;
488 ValueObject::GetValueForExpressionPathOptions options;
489 ValueObject::ExpressionPathAftermath final_task_on_target;
490
Greg Clayton958d4eb2013-05-20 16:50:51 +0000491 valobj_sp = variable_valobj_sp->GetValueForExpressionPath (variable_sub_expr_path,
Greg Clayton884fb692011-07-08 21:46:14 +0000492 &first_unparsed,
493 &reason_to_stop,
494 &final_value_type,
495 options,
496 &final_task_on_target);
497 if (!valobj_sp)
498 {
499 error.SetErrorStringWithFormat ("invalid expression path '%s' for variable '%s'",
Greg Clayton958d4eb2013-05-20 16:50:51 +0000500 variable_sub_expr_path,
Greg Clayton884fb692011-07-08 21:46:14 +0000501 var_sp->GetName().GetCString());
502 }
503 }
504 else
505 {
506 // Just the name of a variable with no extras
507 valobj_sp = variable_valobj_sp;
508 }
509 }
510 }
511
512 if (!var_sp || !valobj_sp)
513 {
514 variable_list.RemoveVariableAtIndex (i);
515 }
516 else
517 {
518 valobj_list.Append(valobj_sp);
519 ++i;
520 }
521 }
522
523 if (variable_list.GetSize() > 0)
524 {
525 error.Clear();
526 return error;
527 }
528 }
529 }
530 }
Greg Clayton885b4b72013-05-20 16:52:10 +0000531 error.SetErrorStringWithFormat ("unable to extract a variable name from '%s'", variable_expr_path);
Greg Clayton884fb692011-07-08 21:46:14 +0000532 }
533 break;
534 }
535 }
536 error.SetErrorString ("unknown error");
537 return error;
538}
539
Greg Claytonc749eb82011-07-11 05:12:02 +0000540bool
541Variable::DumpLocationForAddress (Stream *s, const Address &address)
542{
543 // Be sure to resolve the address to section offset prior to
544 // calling this function.
545 if (address.IsSectionOffset())
546 {
547 SymbolContext sc;
548 CalculateSymbolContext(&sc);
Greg Claytone72dfb32012-02-24 01:59:29 +0000549 if (sc.module_sp == address.GetModule())
Greg Claytonc749eb82011-07-11 05:12:02 +0000550 {
Ed Masted4612ad2014-04-20 13:17:36 +0000551 ABI *abi = nullptr;
Greg Claytonafacd142011-09-02 01:15:17 +0000552 if (m_owner_scope)
553 {
Greg Claytone72dfb32012-02-24 01:59:29 +0000554 ModuleSP module_sp (m_owner_scope->CalculateSymbolContextModule());
555 if (module_sp)
556 abi = ABI::FindPlugin (module_sp->GetArchitecture()).get();
Greg Claytonafacd142011-09-02 01:15:17 +0000557 }
558
Greg Claytonc749eb82011-07-11 05:12:02 +0000559 const addr_t file_addr = address.GetFileAddress();
560 if (sc.function)
561 {
562 if (sc.function->GetAddressRange().ContainsFileAddress(address))
563 {
564 addr_t loclist_base_file_addr = sc.function->GetAddressRange().GetBaseAddress().GetFileAddress();
565 if (loclist_base_file_addr == LLDB_INVALID_ADDRESS)
566 return false;
567 return m_location.DumpLocationForAddress (s,
568 eDescriptionLevelBrief,
569 loclist_base_file_addr,
Greg Claytonafacd142011-09-02 01:15:17 +0000570 file_addr,
571 abi);
Greg Claytonc749eb82011-07-11 05:12:02 +0000572 }
573 }
574 return m_location.DumpLocationForAddress (s,
575 eDescriptionLevelBrief,
576 LLDB_INVALID_ADDRESS,
Greg Claytonafacd142011-09-02 01:15:17 +0000577 file_addr,
578 abi);
Greg Claytonc749eb82011-07-11 05:12:02 +0000579 }
580 }
581 return false;
Greg Claytonf21fead2013-05-14 23:43:18 +0000582}
Greg Claytonc749eb82011-07-11 05:12:02 +0000583
Greg Claytonf21fead2013-05-14 23:43:18 +0000584
585static void
Jason Molendab57e4a12013-11-04 09:33:30 +0000586PrivateAutoComplete (StackFrame *frame,
Greg Claytonf21fead2013-05-14 23:43:18 +0000587 const std::string &partial_path,
588 const std::string &prefix_path, // Anything that has been resolved already will be in here
Greg Claytona1e5dc82015-08-11 22:53:00 +0000589 const CompilerType& clang_type,
Greg Claytonf21fead2013-05-14 23:43:18 +0000590 StringList &matches,
591 bool &word_complete);
592
593static void
Jason Molendab57e4a12013-11-04 09:33:30 +0000594PrivateAutoCompleteMembers (StackFrame *frame,
Greg Claytonf21fead2013-05-14 23:43:18 +0000595 const std::string &partial_member_name,
596 const std::string &partial_path,
597 const std::string &prefix_path, // Anything that has been resolved already will be in here
Greg Claytona1e5dc82015-08-11 22:53:00 +0000598 const CompilerType& clang_type,
Greg Claytonf21fead2013-05-14 23:43:18 +0000599 StringList &matches,
600 bool &word_complete);
601
602static void
Jason Molendab57e4a12013-11-04 09:33:30 +0000603PrivateAutoCompleteMembers (StackFrame *frame,
Greg Claytonf21fead2013-05-14 23:43:18 +0000604 const std::string &partial_member_name,
605 const std::string &partial_path,
606 const std::string &prefix_path, // Anything that has been resolved already will be in here
Greg Claytona1e5dc82015-08-11 22:53:00 +0000607 const CompilerType& clang_type,
Greg Claytonf21fead2013-05-14 23:43:18 +0000608 StringList &matches,
609 bool &word_complete)
610{
611
612 // We are in a type parsing child members
Greg Clayton99558cc42015-08-24 23:46:31 +0000613 const uint32_t num_bases = clang_type.GetNumDirectBaseClasses();
Greg Claytonf21fead2013-05-14 23:43:18 +0000614
615 if (num_bases > 0)
616 {
617 for (uint32_t i = 0; i < num_bases; ++i)
618 {
Greg Clayton99558cc42015-08-24 23:46:31 +0000619 CompilerType base_class_type = clang_type.GetDirectBaseClassAtIndex(i, nullptr);
Greg Claytonf21fead2013-05-14 23:43:18 +0000620
621 PrivateAutoCompleteMembers (frame,
622 partial_member_name,
623 partial_path,
624 prefix_path,
625 base_class_type.GetCanonicalType(),
626 matches,
627 word_complete);
628 }
629 }
630
Greg Clayton99558cc42015-08-24 23:46:31 +0000631 const uint32_t num_vbases = clang_type.GetNumVirtualBaseClasses();
Greg Claytonf21fead2013-05-14 23:43:18 +0000632
633 if (num_vbases > 0)
634 {
635 for (uint32_t i = 0; i < num_vbases; ++i)
636 {
Greg Clayton99558cc42015-08-24 23:46:31 +0000637 CompilerType vbase_class_type = clang_type.GetVirtualBaseClassAtIndex(i,nullptr);
Greg Claytonf21fead2013-05-14 23:43:18 +0000638
639 PrivateAutoCompleteMembers (frame,
640 partial_member_name,
641 partial_path,
642 prefix_path,
643 vbase_class_type.GetCanonicalType(),
644 matches,
645 word_complete);
646 }
647 }
648
649 // We are in a type parsing child members
Greg Clayton57ee3062013-07-11 22:46:58 +0000650 const uint32_t num_fields = clang_type.GetNumFields();
Greg Claytonf21fead2013-05-14 23:43:18 +0000651
652 if (num_fields > 0)
653 {
654 for (uint32_t i = 0; i < num_fields; ++i)
655 {
656 std::string member_name;
657
Greg Claytona1e5dc82015-08-11 22:53:00 +0000658 CompilerType member_clang_type = clang_type.GetFieldAtIndex (i, member_name, nullptr, nullptr, nullptr);
Greg Claytonf21fead2013-05-14 23:43:18 +0000659
660 if (partial_member_name.empty() ||
661 member_name.find(partial_member_name) == 0)
662 {
663 if (member_name == partial_member_name)
664 {
Greg Claytonf21fead2013-05-14 23:43:18 +0000665 PrivateAutoComplete (frame,
666 partial_path,
667 prefix_path + member_name, // Anything that has been resolved already will be in here
668 member_clang_type.GetCanonicalType(),
669 matches,
670 word_complete);
671 }
672 else
673 {
674 matches.AppendString (prefix_path + member_name);
675 }
676 }
677 }
678 }
679}
680
681static void
Jason Molendab57e4a12013-11-04 09:33:30 +0000682PrivateAutoComplete (StackFrame *frame,
Greg Claytonf21fead2013-05-14 23:43:18 +0000683 const std::string &partial_path,
684 const std::string &prefix_path, // Anything that has been resolved already will be in here
Greg Claytona1e5dc82015-08-11 22:53:00 +0000685 const CompilerType& clang_type,
Greg Claytonf21fead2013-05-14 23:43:18 +0000686 StringList &matches,
687 bool &word_complete)
688{
689// printf ("\nPrivateAutoComplete()\n\tprefix_path = '%s'\n\tpartial_path = '%s'\n", prefix_path.c_str(), partial_path.c_str());
690 std::string remaining_partial_path;
691
692 const lldb::TypeClass type_class = clang_type.GetTypeClass();
693 if (partial_path.empty())
694 {
695 if (clang_type.IsValid())
696 {
697 switch (type_class)
698 {
699 default:
700 case eTypeClassArray:
701 case eTypeClassBlockPointer:
702 case eTypeClassBuiltin:
703 case eTypeClassComplexFloat:
704 case eTypeClassComplexInteger:
705 case eTypeClassEnumeration:
706 case eTypeClassFunction:
707 case eTypeClassMemberPointer:
708 case eTypeClassReference:
709 case eTypeClassTypedef:
710 case eTypeClassVector:
711 {
712 matches.AppendString (prefix_path);
713 word_complete = matches.GetSize() == 1;
714 }
715 break;
716
717 case eTypeClassClass:
718 case eTypeClassStruct:
719 case eTypeClassUnion:
720 if (prefix_path.back() != '.')
721 matches.AppendString (prefix_path + '.');
722 break;
723
724 case eTypeClassObjCObject:
725 case eTypeClassObjCInterface:
726 break;
727 case eTypeClassObjCObjectPointer:
728 case eTypeClassPointer:
729 {
730 bool omit_empty_base_classes = true;
Greg Clayton57ee3062013-07-11 22:46:58 +0000731 if (clang_type.GetNumChildren (omit_empty_base_classes) > 0)
Greg Claytonf21fead2013-05-14 23:43:18 +0000732 matches.AppendString (prefix_path + "->");
733 else
734 {
735 matches.AppendString (prefix_path);
736 word_complete = true;
737 }
738 }
739 break;
740 }
741 }
742 else
743 {
744 if (frame)
745 {
746 const bool get_file_globals = true;
747
748 VariableList *variable_list = frame->GetVariableList(get_file_globals);
749
Jason Molendaa3a542f2013-10-09 02:39:26 +0000750 if (variable_list)
Greg Claytonf21fead2013-05-14 23:43:18 +0000751 {
Jason Molendaa3a542f2013-10-09 02:39:26 +0000752 const size_t num_variables = variable_list->GetSize();
753 for (size_t i=0; i<num_variables; ++i)
754 {
755 Variable *variable = variable_list->GetVariableAtIndex(i).get();
756 matches.AppendString (variable->GetName().AsCString());
757 }
Greg Claytonf21fead2013-05-14 23:43:18 +0000758 }
759 }
760 }
761 }
762 else
763 {
764 const char ch = partial_path[0];
765 switch (ch)
766 {
767 case '*':
768 if (prefix_path.empty())
769 {
770 PrivateAutoComplete (frame,
771 partial_path.substr(1),
772 std::string("*"),
773 clang_type,
774 matches,
775 word_complete);
776 }
777 break;
778
779 case '&':
780 if (prefix_path.empty())
781 {
782 PrivateAutoComplete (frame,
783 partial_path.substr(1),
784 std::string("&"),
785 clang_type,
786 matches,
787 word_complete);
788 }
789 break;
790
791 case '-':
792 if (partial_path[1] == '>' && !prefix_path.empty())
793 {
794 switch (type_class)
795 {
796 case lldb::eTypeClassPointer:
797 {
Greg Claytona1e5dc82015-08-11 22:53:00 +0000798 CompilerType pointee_type(clang_type.GetPointeeType());
Greg Claytonf21fead2013-05-14 23:43:18 +0000799 if (partial_path[2])
800 {
801 // If there is more after the "->", then search deeper
802 PrivateAutoComplete (frame,
803 partial_path.substr(2),
804 prefix_path + "->",
805 pointee_type.GetCanonicalType(),
806 matches,
807 word_complete);
808 }
809 else
810 {
811 // Nothing after the "->", so list all members
812 PrivateAutoCompleteMembers (frame,
813 std::string(),
814 std::string(),
815 prefix_path + "->",
816 pointee_type.GetCanonicalType(),
817 matches,
818 word_complete);
819 }
820 }
821 default:
822 break;
823 }
824 }
825 break;
826
827 case '.':
828 if (clang_type.IsValid())
829 {
830 switch (type_class)
831 {
832 case lldb::eTypeClassUnion:
833 case lldb::eTypeClassStruct:
834 case lldb::eTypeClassClass:
835 if (partial_path[1])
836 {
837 // If there is more after the ".", then search deeper
838 PrivateAutoComplete (frame,
839 partial_path.substr(1),
840 prefix_path + ".",
841 clang_type,
842 matches,
843 word_complete);
844
845 }
846 else
847 {
848 // Nothing after the ".", so list all members
849 PrivateAutoCompleteMembers (frame,
850 std::string(),
851 partial_path,
852 prefix_path + ".",
853 clang_type,
854 matches,
855 word_complete);
856 }
857 default:
858 break;
859 }
860 }
861 break;
862 default:
863 if (isalpha(ch) || ch == '_' || ch == '$')
864 {
865 const size_t partial_path_len = partial_path.size();
866 size_t pos = 1;
867 while (pos < partial_path_len)
868 {
869 const char curr_ch = partial_path[pos];
870 if (isalnum(curr_ch) || curr_ch == '_' || curr_ch == '$')
871 {
872 ++pos;
873 continue;
874 }
875 break;
876 }
877
878 std::string token(partial_path, 0, pos);
879 remaining_partial_path = partial_path.substr(pos);
880
881 if (clang_type.IsValid())
882 {
883 PrivateAutoCompleteMembers (frame,
884 token,
885 remaining_partial_path,
886 prefix_path,
887 clang_type,
888 matches,
889 word_complete);
890 }
891 else if (frame)
892 {
893 // We haven't found our variable yet
894 const bool get_file_globals = true;
895
896 VariableList *variable_list = frame->GetVariableList(get_file_globals);
897
Enrico Granata16f35ea2013-12-21 08:44:28 +0000898 if (!variable_list)
899 break;
900
Greg Claytonf21fead2013-05-14 23:43:18 +0000901 const size_t num_variables = variable_list->GetSize();
902 for (size_t i=0; i<num_variables; ++i)
903 {
904 Variable *variable = variable_list->GetVariableAtIndex(i).get();
Enrico Granata16f35ea2013-12-21 08:44:28 +0000905
906 if (!variable)
907 continue;
908
Greg Claytonf21fead2013-05-14 23:43:18 +0000909 const char *variable_name = variable->GetName().AsCString();
910 if (strstr(variable_name, token.c_str()) == variable_name)
911 {
912 if (strcmp (variable_name, token.c_str()) == 0)
913 {
914 Type *variable_type = variable->GetType();
915 if (variable_type)
916 {
Greg Clayton99558cc42015-08-24 23:46:31 +0000917 CompilerType variable_clang_type (variable_type->GetForwardCompilerType ());
Greg Claytonf21fead2013-05-14 23:43:18 +0000918 PrivateAutoComplete (frame,
919 remaining_partial_path,
920 prefix_path + token, // Anything that has been resolved already will be in here
921 variable_clang_type.GetCanonicalType(),
922 matches,
923 word_complete);
924 }
925 else
926 {
927 matches.AppendString (prefix_path + variable_name);
928 }
929 }
930 else if (remaining_partial_path.empty())
931 {
932 matches.AppendString (prefix_path + variable_name);
933 }
934 }
935 }
936 }
937 }
938 break;
939 }
940 }
941}
942
943
944
945size_t
946Variable::AutoComplete (const ExecutionContext &exe_ctx,
947 const char *partial_path_cstr,
948 StringList &matches,
949 bool &word_complete)
950{
951 word_complete = false;
952 std::string partial_path;
953 std::string prefix_path;
Greg Claytona1e5dc82015-08-11 22:53:00 +0000954 CompilerType clang_type;
Greg Claytonf21fead2013-05-14 23:43:18 +0000955 if (partial_path_cstr && partial_path_cstr[0])
956 partial_path = partial_path_cstr;
957
958 PrivateAutoComplete (exe_ctx.GetFramePtr(),
959 partial_path,
960 prefix_path,
961 clang_type,
962 matches,
963 word_complete);
964
965 return matches.GetSize();
Greg Claytonc749eb82011-07-11 05:12:02 +0000966}
967