blob: 268caf200a81da167681c1d3c2a726e951b46cef [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- SymbolContext.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/SymbolContext.h"
Greg Clayton12bec712010-06-28 21:30:43 +000011
Chris Lattner24943d22010-06-08 16:52:24 +000012#include "lldb/Core/Module.h"
Greg Clayton12bec712010-06-28 21:30:43 +000013#include "lldb/Symbol/CompileUnit.h"
Chris Lattner24943d22010-06-08 16:52:24 +000014#include "lldb/Symbol/ObjectFile.h"
15#include "lldb/Symbol/Symbol.h"
Chris Lattner24943d22010-06-08 16:52:24 +000016#include "lldb/Symbol/SymbolVendor.h"
Greg Clayton12bec712010-06-28 21:30:43 +000017#include "lldb/Target/Target.h"
Chris Lattner24943d22010-06-08 16:52:24 +000018
19using namespace lldb;
20using namespace lldb_private;
21
22SymbolContext::SymbolContext() :
23 target_sp (),
24 module_sp (),
25 comp_unit (NULL),
26 function (NULL),
27 block (NULL),
28 line_entry (),
29 symbol (NULL)
30{
31}
32
33SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
34 target_sp (),
35 module_sp (m),
36 comp_unit (cu),
37 function (f),
38 block (b),
39 line_entry (),
40 symbol (s)
41{
42 if (le)
43 line_entry = *le;
44}
45
46SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
47 target_sp (t),
48 module_sp (m),
49 comp_unit (cu),
50 function (f),
51 block (b),
52 line_entry (),
53 symbol (s)
54{
55 if (le)
56 line_entry = *le;
57}
58
59SymbolContext::SymbolContext(const SymbolContext& rhs) :
60 target_sp (rhs.target_sp),
61 module_sp (rhs.module_sp),
62 comp_unit (rhs.comp_unit),
63 function (rhs.function),
64 block (rhs.block),
65 line_entry (rhs.line_entry),
66 symbol (rhs.symbol)
67{
68}
69
70
71SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
72 target_sp (),
73 module_sp (),
74 comp_unit (NULL),
75 function (NULL),
76 block (NULL),
77 line_entry (),
78 symbol (NULL)
79{
80 sc_scope->CalculateSymbolContext (this);
81}
82
83const SymbolContext&
84SymbolContext::operator= (const SymbolContext& rhs)
85{
86 if (this != &rhs)
87 {
88 target_sp = rhs.target_sp;
89 module_sp = rhs.module_sp;
90 comp_unit = rhs.comp_unit;
91 function = rhs.function;
92 block = rhs.block;
93 line_entry = rhs.line_entry;
94 symbol = rhs.symbol;
95 }
96 return *this;
97}
98
99void
100SymbolContext::Clear()
101{
102 target_sp.reset();
103 module_sp.reset();
104 comp_unit = NULL;
105 function = NULL;
106 block = NULL;
107 line_entry.Clear();
108 symbol = NULL;
109}
110
111void
112SymbolContext::DumpStopContext
113(
114 Stream *s,
115 ExecutionContextScope *exe_scope,
116 const Address &addr,
117 bool show_module
118) const
119{
Chris Lattner24943d22010-06-08 16:52:24 +0000120 if (show_module && module_sp)
121 {
122 *s << module_sp->GetFileSpec().GetFilename() << '`';
123 }
124
125 if (function != NULL)
126 {
127 if (function->GetMangled().GetName())
128 function->GetMangled().GetName().Dump(s);
129
Greg Clayton70436352010-06-30 23:03:03 +0000130 const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
131 if (function_offset)
132 s->Printf(" + %llu", function_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000133
134 if (block != NULL)
135 {
136 s->IndentMore();
137 block->DumpStopContext(s, this);
138 s->IndentLess();
139 }
140 else
141 {
142 if (line_entry.IsValid())
143 {
144 s->PutCString(" at ");
145 if (line_entry.DumpStopContext(s))
146 return;
147 }
148 }
149 }
150 else if (symbol != NULL)
151 {
152 symbol->GetMangled().GetName().Dump(s);
153
154 if (symbol->GetAddressRangePtr())
155 {
Greg Clayton70436352010-06-30 23:03:03 +0000156 const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRangePtr()->GetBaseAddress().GetOffset();
157 if (symbol_offset)
158 s->Printf(" + %llu", symbol_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000159 }
160 }
161 else
162 {
163 addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
164 }
165}
166
167void
Greg Clayton12bec712010-06-28 21:30:43 +0000168SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Process *process) const
169{
170 if (module_sp)
171 {
172 s->Indent(" Module: \"");
173 module_sp->GetFileSpec().Dump(s);
174 s->PutChar('"');
175 s->EOL();
176 }
177
178 if (comp_unit != NULL)
179 {
180 s->Indent("CompileUnit: ");
181 comp_unit->GetDescription (s, level);
182 s->EOL();
183 }
184
185 if (function != NULL)
186 {
187 s->Indent(" Function: ");
188 function->GetDescription (s, level, process);
189 s->EOL();
190
191 Type *func_type = function->GetType();
192 if (func_type)
193 {
194 s->Indent(" FuncType: ");
195 func_type->GetDescription (s, level, false);
196 s->EOL();
197 }
198 }
199
200 if (block != NULL)
201 {
202 std::vector<Block *> blocks;
203 blocks.push_back (block);
204 Block *parent_block = block->GetParent();
205
206 while (parent_block)
207 {
208 blocks.push_back (parent_block);
209 parent_block = parent_block->GetParent();
210 }
211 std::vector<Block *>::reverse_iterator pos;
212 std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
213 std::vector<Block *>::reverse_iterator end = blocks.rend();
214 for (pos = begin; pos != end; ++pos)
215 {
216 if (pos == begin)
217 s->Indent(" Blocks: ");
218 else
219 s->Indent(" ");
Greg Clayton75ccf502010-08-21 02:22:51 +0000220 (*pos)->GetDescription(s, function, level, process);
Greg Clayton12bec712010-06-28 21:30:43 +0000221 s->EOL();
222 }
223 }
224
225 if (line_entry.IsValid())
226 {
227 s->Indent(" LineEntry: ");
228 line_entry.GetDescription (s, level, comp_unit, process, false);
229 s->EOL();
230 }
231
232 if (symbol != NULL)
233 {
234 s->Indent(" Symbol: ");
235 symbol->GetDescription(s, level, process);
236 s->EOL();
237 }
238}
239
240
241
242void
Chris Lattner24943d22010-06-08 16:52:24 +0000243SymbolContext::Dump(Stream *s, Process *process) const
244{
245 *s << (void *)this << ": ";
246 s->Indent();
247 s->PutCString("SymbolContext");
248 s->IndentMore();
249 s->EOL();
250 s->IndentMore();
251 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000252 *s << "Module = " << (void *)module_sp.get() << ' ';
Chris Lattner24943d22010-06-08 16:52:24 +0000253 if (module_sp)
254 module_sp->GetFileSpec().Dump(s);
255 s->EOL();
256 s->Indent();
257 *s << "CompileUnit = " << (void *)comp_unit;
258 if (comp_unit != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000259 *s << " {0x" << comp_unit->GetID() << "} " << *(dynamic_cast<FileSpec*> (comp_unit));
Chris Lattner24943d22010-06-08 16:52:24 +0000260 s->EOL();
261 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000262 *s << "Function = " << (void *)function;
Chris Lattner24943d22010-06-08 16:52:24 +0000263 if (function != NULL)
264 {
Greg Clayton12bec712010-06-28 21:30:43 +0000265 *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
266 function->GetAddressRange().Dump(s, process, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
267 s->EOL();
268 s->Indent();
269 Type* func_type = function->GetType();
270 if (func_type)
271 {
272 *s << " Type = ";
273 func_type->Dump (s, false);
274 }
Chris Lattner24943d22010-06-08 16:52:24 +0000275 }
276 s->EOL();
277 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000278 *s << "Block = " << (void *)block;
Chris Lattner24943d22010-06-08 16:52:24 +0000279 if (block != NULL)
Greg Clayton12bec712010-06-28 21:30:43 +0000280 *s << " {0x" << block->GetID() << '}';
Chris Lattner24943d22010-06-08 16:52:24 +0000281 // Dump the block and pass it a negative depth to we print all the parent blocks
282 //if (block != NULL)
283 // block->Dump(s, function->GetFileAddress(), INT_MIN);
284 s->EOL();
285 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000286 *s << "LineEntry = ";
Chris Lattner24943d22010-06-08 16:52:24 +0000287 line_entry.Dump (s, process, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
288 s->EOL();
289 s->Indent();
Greg Clayton12bec712010-06-28 21:30:43 +0000290 *s << "Symbol = " << (void *)symbol;
Chris Lattner24943d22010-06-08 16:52:24 +0000291 if (symbol != NULL && symbol->GetMangled())
292 *s << ' ' << symbol->GetMangled().GetName().AsCString();
293 s->EOL();
294 s->IndentLess();
295 s->IndentLess();
296}
297
298bool
299lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
300{
301 return lhs.target_sp.get() == rhs.target_sp.get() &&
302 lhs.module_sp.get() == rhs.module_sp.get() &&
303 lhs.comp_unit == rhs.comp_unit &&
304 lhs.function == rhs.function &&
305 LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0 &&
306 lhs.symbol == rhs.symbol;
307}
308
309bool
310lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
311{
312 return lhs.target_sp.get() != rhs.target_sp.get() ||
313 lhs.module_sp.get() != rhs.module_sp.get() ||
314 lhs.comp_unit != rhs.comp_unit ||
315 lhs.function != rhs.function ||
316 LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 ||
317 lhs.symbol != rhs.symbol;
318}
319
320bool
321SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
322{
323 if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
324 {
325 range = line_entry.range;
326 return true;
327 }
328 else if ((scope & eSymbolContextFunction) && function != NULL)
329 {
330 range = function->GetAddressRange();
331 return true;
332 }
333 else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
334 {
335 range = *symbol->GetAddressRangePtr();
336
337 if (range.GetByteSize() == 0)
338 {
339 if (module_sp)
340 {
341 ObjectFile *objfile = module_sp->GetObjectFile();
342 if (objfile)
343 {
344 Symtab *symtab = objfile->GetSymtab();
345 if (symtab)
346 range.SetByteSize(symtab->CalculateSymbolSize (symbol));
347 }
348 }
349 }
350 return true;
351 }
352 range.Clear();
353 return false;
354}
355
356
Sean Callanan0fc73582010-07-27 00:55:47 +0000357size_t
358SymbolContext::FindFunctionsByName (const ConstString &name, bool append, SymbolContextList &sc_list) const
359{
360 if (!append)
361 sc_list.Clear();
362
Chris Lattner24943d22010-06-08 16:52:24 +0000363 if (function != NULL)
364 {
365 // FIXME: Look in the class of the current function, if it exists,
366 // for methods matching name.
367 }
368
Chris Lattner24943d22010-06-08 16:52:24 +0000369 if (comp_unit != NULL)
370 {
371 // Make sure we've read in all the functions. We should be able to check and see
372 // if there's one by this name present before we do this...
373 module_sp->GetSymbolVendor()->ParseCompileUnitFunctions(*this);
374 uint32_t func_idx;
375 lldb::FunctionSP func_sp;
376 for (func_idx = 0; (func_sp = comp_unit->GetFunctionAtIndex(func_idx)) != NULL; ++func_idx)
377 {
Sean Callanan0fc73582010-07-27 00:55:47 +0000378 if (func_sp->GetMangled().GetName() == name)
379 {
380 SymbolContext sym_ctx(target_sp,
381 module_sp,
382 comp_unit,
383 func_sp.get());
384 sc_list.Append(sym_ctx);
385 }
Chris Lattner24943d22010-06-08 16:52:24 +0000386 }
387 }
Sean Callanan0fc73582010-07-27 00:55:47 +0000388
Chris Lattner24943d22010-06-08 16:52:24 +0000389 if (module_sp != NULL)
Sean Callanan0fc73582010-07-27 00:55:47 +0000390 module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000391
392 if (target_sp)
Sean Callanan0fc73582010-07-27 00:55:47 +0000393 target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000394
Sean Callanan0fc73582010-07-27 00:55:47 +0000395 return sc_list.GetSize();
Chris Lattner24943d22010-06-08 16:52:24 +0000396}
397
398lldb::VariableSP
399SymbolContext::FindVariableByName (const char *name) const
400{
401 lldb::VariableSP return_value;
402 return return_value;
403}
404
405lldb::TypeSP
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000406SymbolContext::FindTypeByName (const ConstString &name) const
Chris Lattner24943d22010-06-08 16:52:24 +0000407{
408 lldb::TypeSP return_value;
Sean Callanan93a4b1a2010-08-04 01:02:13 +0000409
410 TypeList types;
411
412 if (module_sp && module_sp->FindTypes (*this, name, false, 1, types))
413 return types.GetTypeAtIndex(0);
414
415 if (!return_value.get() && target_sp && target_sp->GetImages().FindTypes (*this, name, false, 1, types))
416 return types.GetTypeAtIndex(0);
417
Chris Lattner24943d22010-06-08 16:52:24 +0000418 return return_value;
419}
420
421//----------------------------------------------------------------------
422//
423// SymbolContextList
424//
425//----------------------------------------------------------------------
426
427
428SymbolContextList::SymbolContextList() :
429 m_symbol_contexts()
430{
431}
432
433SymbolContextList::~SymbolContextList()
434{
435}
436
437void
438SymbolContextList::Append(const SymbolContext& sc)
439{
440 m_symbol_contexts.push_back(sc);
441}
442
443void
444SymbolContextList::Clear()
445{
446 m_symbol_contexts.clear();
447}
448
449void
450SymbolContextList::Dump(Stream *s, Process *process) const
451{
452
453 *s << (void *)this << ": ";
454 s->Indent();
455 s->PutCString("SymbolContextList");
456 s->EOL();
457 s->IndentMore();
458
459 collection::const_iterator pos, end = m_symbol_contexts.end();
460 for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
461 {
462 pos->Dump(s, process);
463 }
464 s->IndentLess();
465}
466
467bool
468SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
469{
470 if (idx < m_symbol_contexts.size())
471 {
472 sc = m_symbol_contexts[idx];
473 return true;
474 }
475 return false;
476}
477
478bool
479SymbolContextList::RemoveContextAtIndex (uint32_t idx)
480{
481 if (idx < m_symbol_contexts.size())
482 {
483 m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
484 return true;
485 }
486 return false;
487}
488
489uint32_t
490SymbolContextList::GetSize() const
491{
492 return m_symbol_contexts.size();
493}