1 //===-- 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"
11 
12 #include "lldb/Core/Log.h"
13 #include "lldb/Core/Module.h"
14 #include "lldb/Core/ModuleSpec.h"
15 #include "lldb/Host/Host.h"
16 #include "lldb/Interpreter/Args.h"
17 #include "lldb/Symbol/Block.h"
18 #include "lldb/Symbol/ClangASTContext.h"
19 #include "lldb/Symbol/CompileUnit.h"
20 #include "lldb/Symbol/ObjectFile.h"
21 #include "lldb/Symbol/Symbol.h"
22 #include "lldb/Symbol/SymbolFile.h"
23 #include "lldb/Symbol/SymbolVendor.h"
24 #include "lldb/Target/Target.h"
25 
26 using namespace lldb;
27 using namespace lldb_private;
28 
29 SymbolContext::SymbolContext() :
30     target_sp   (),
31     module_sp   (),
32     comp_unit   (NULL),
33     function    (NULL),
34     block       (NULL),
35     line_entry  (),
36     symbol      (NULL)
37 {
38 }
39 
40 SymbolContext::SymbolContext(const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
41     target_sp   (),
42     module_sp   (m),
43     comp_unit   (cu),
44     function    (f),
45     block       (b),
46     line_entry  (),
47     symbol      (s)
48 {
49     if (le)
50         line_entry = *le;
51 }
52 
53 SymbolContext::SymbolContext(const TargetSP &t, const ModuleSP& m, CompileUnit *cu, Function *f, Block *b, LineEntry *le, Symbol *s) :
54     target_sp   (t),
55     module_sp   (m),
56     comp_unit   (cu),
57     function    (f),
58     block       (b),
59     line_entry  (),
60     symbol      (s)
61 {
62     if (le)
63         line_entry = *le;
64 }
65 
66 SymbolContext::SymbolContext(const SymbolContext& rhs) :
67     target_sp   (rhs.target_sp),
68     module_sp   (rhs.module_sp),
69     comp_unit   (rhs.comp_unit),
70     function    (rhs.function),
71     block       (rhs.block),
72     line_entry  (rhs.line_entry),
73     symbol      (rhs.symbol)
74 {
75 }
76 
77 
78 SymbolContext::SymbolContext (SymbolContextScope *sc_scope) :
79     target_sp   (),
80     module_sp   (),
81     comp_unit   (NULL),
82     function    (NULL),
83     block       (NULL),
84     line_entry  (),
85     symbol      (NULL)
86 {
87     sc_scope->CalculateSymbolContext (this);
88 }
89 
90 SymbolContext::~SymbolContext ()
91 {
92 }
93 
94 const SymbolContext&
95 SymbolContext::operator= (const SymbolContext& rhs)
96 {
97     if (this != &rhs)
98     {
99         target_sp   = rhs.target_sp;
100         module_sp   = rhs.module_sp;
101         comp_unit   = rhs.comp_unit;
102         function    = rhs.function;
103         block       = rhs.block;
104         line_entry  = rhs.line_entry;
105         symbol      = rhs.symbol;
106     }
107     return *this;
108 }
109 
110 void
111 SymbolContext::Clear()
112 {
113     target_sp.reset();
114     module_sp.reset();
115     comp_unit   = NULL;
116     function    = NULL;
117     block       = NULL;
118     line_entry.Clear();
119     symbol      = NULL;
120 }
121 
122 bool
123 SymbolContext::DumpStopContext
124 (
125     Stream *s,
126     ExecutionContextScope *exe_scope,
127     const Address &addr,
128     bool show_fullpaths,
129     bool show_module,
130     bool show_inlined_frames
131 ) const
132 {
133     bool dumped_something = false;
134     if (show_module && module_sp)
135     {
136         if (show_fullpaths)
137             *s << module_sp->GetFileSpec();
138         else
139             *s << module_sp->GetFileSpec().GetFilename();
140         s->PutChar('`');
141         dumped_something = true;
142     }
143 
144     if (function != NULL)
145     {
146         SymbolContext inline_parent_sc;
147         Address inline_parent_addr;
148         if (function->GetMangled().GetName())
149         {
150             dumped_something = true;
151             function->GetMangled().GetName().Dump(s);
152         }
153 
154         if (addr.IsValid())
155         {
156             const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset();
157             if (function_offset)
158             {
159                 dumped_something = true;
160                 s->Printf(" + %" PRIu64, function_offset);
161             }
162         }
163 
164         if (GetParentOfInlinedScope (addr, inline_parent_sc, inline_parent_addr))
165         {
166             dumped_something = true;
167             Block *inlined_block = block->GetContainingInlinedBlock();
168             const InlineFunctionInfo* inlined_block_info = inlined_block->GetInlinedFunctionInfo();
169             s->Printf (" [inlined] %s", inlined_block_info->GetName().GetCString());
170 
171             lldb_private::AddressRange block_range;
172             if (inlined_block->GetRangeContainingAddress(addr, block_range))
173             {
174                 const addr_t inlined_function_offset = addr.GetOffset() - block_range.GetBaseAddress().GetOffset();
175                 if (inlined_function_offset)
176                 {
177                     s->Printf(" + %" PRIu64, inlined_function_offset);
178                 }
179             }
180             const Declaration &call_site = inlined_block_info->GetCallSite();
181             if (call_site.IsValid())
182             {
183                 s->PutCString(" at ");
184                 call_site.DumpStopContext (s, show_fullpaths);
185             }
186             if (show_inlined_frames)
187             {
188                 s->EOL();
189                 s->Indent();
190                 return inline_parent_sc.DumpStopContext (s, exe_scope, inline_parent_addr, show_fullpaths, show_module, show_inlined_frames);
191             }
192         }
193         else
194         {
195             if (line_entry.IsValid())
196             {
197                 dumped_something = true;
198                 s->PutCString(" at ");
199                 if (line_entry.DumpStopContext(s, show_fullpaths))
200                     dumped_something = true;
201             }
202         }
203     }
204     else if (symbol != NULL)
205     {
206         if (symbol->GetMangled().GetName())
207         {
208             dumped_something = true;
209             if (symbol->GetType() == eSymbolTypeTrampoline)
210                 s->PutCString("symbol stub for: ");
211             symbol->GetMangled().GetName().Dump(s);
212         }
213 
214         if (addr.IsValid() && symbol->ValueIsAddress())
215         {
216             const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddress().GetOffset();
217             if (symbol_offset)
218             {
219                 dumped_something = true;
220                 s->Printf(" + %" PRIu64, symbol_offset);
221             }
222         }
223     }
224     else if (addr.IsValid())
225     {
226         addr.Dump(s, exe_scope, Address::DumpStyleModuleWithFileAddress);
227         dumped_something = true;
228     }
229     return dumped_something;
230 }
231 
232 void
233 SymbolContext::GetDescription(Stream *s, lldb::DescriptionLevel level, Target *target) const
234 {
235     if (module_sp)
236     {
237         s->Indent("     Module: file = \"");
238         module_sp->GetFileSpec().Dump(s);
239         *s << '"';
240         if (module_sp->GetArchitecture().IsValid())
241             s->Printf (", arch = \"%s\"", module_sp->GetArchitecture().GetArchitectureName());
242         s->EOL();
243     }
244 
245     if (comp_unit != NULL)
246     {
247         s->Indent("CompileUnit: ");
248         comp_unit->GetDescription (s, level);
249         s->EOL();
250     }
251 
252     if (function != NULL)
253     {
254         s->Indent("   Function: ");
255         function->GetDescription (s, level, target);
256         s->EOL();
257 
258         Type *func_type = function->GetType();
259         if (func_type)
260         {
261             s->Indent("   FuncType: ");
262             func_type->GetDescription (s, level, false);
263             s->EOL();
264         }
265     }
266 
267     if (block != NULL)
268     {
269         std::vector<Block *> blocks;
270         blocks.push_back (block);
271         Block *parent_block = block->GetParent();
272 
273         while (parent_block)
274         {
275             blocks.push_back (parent_block);
276             parent_block = parent_block->GetParent();
277         }
278         std::vector<Block *>::reverse_iterator pos;
279         std::vector<Block *>::reverse_iterator begin = blocks.rbegin();
280         std::vector<Block *>::reverse_iterator end = blocks.rend();
281         for (pos = begin; pos != end; ++pos)
282         {
283             if (pos == begin)
284                 s->Indent("     Blocks: ");
285             else
286                 s->Indent("             ");
287             (*pos)->GetDescription(s, function, level, target);
288             s->EOL();
289         }
290     }
291 
292     if (line_entry.IsValid())
293     {
294         s->Indent("  LineEntry: ");
295         line_entry.GetDescription (s, level, comp_unit, target, false);
296         s->EOL();
297     }
298 
299     if (symbol != NULL)
300     {
301         s->Indent("     Symbol: ");
302         symbol->GetDescription(s, level, target);
303         s->EOL();
304     }
305 }
306 
307 uint32_t
308 SymbolContext::GetResolvedMask () const
309 {
310     uint32_t resolved_mask = 0;
311     if (target_sp)              resolved_mask |= eSymbolContextTarget;
312     if (module_sp)              resolved_mask |= eSymbolContextModule;
313     if (comp_unit)              resolved_mask |= eSymbolContextCompUnit;
314     if (function)               resolved_mask |= eSymbolContextFunction;
315     if (block)                  resolved_mask |= eSymbolContextBlock;
316     if (line_entry.IsValid())   resolved_mask |= eSymbolContextLineEntry;
317     if (symbol)                 resolved_mask |= eSymbolContextSymbol;
318     return resolved_mask;
319 }
320 
321 
322 void
323 SymbolContext::Dump(Stream *s, Target *target) const
324 {
325     *s << (void *)this << ": ";
326     s->Indent();
327     s->PutCString("SymbolContext");
328     s->IndentMore();
329     s->EOL();
330     s->IndentMore();
331     s->Indent();
332     *s << "Module       = " << (void *)module_sp.get() << ' ';
333     if (module_sp)
334         module_sp->GetFileSpec().Dump(s);
335     s->EOL();
336     s->Indent();
337     *s << "CompileUnit  = " << (void *)comp_unit;
338     if (comp_unit != NULL)
339         *s << " {0x" << comp_unit->GetID() << "} " << *(static_cast<FileSpec*> (comp_unit));
340     s->EOL();
341     s->Indent();
342     *s << "Function     = " << (void *)function;
343     if (function != NULL)
344     {
345         *s << " {0x" << function->GetID() << "} " << function->GetType()->GetName() << ", address-range = ";
346         function->GetAddressRange().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
347         s->EOL();
348         s->Indent();
349         Type* func_type = function->GetType();
350         if (func_type)
351         {
352             *s << "        Type = ";
353             func_type->Dump (s, false);
354         }
355     }
356     s->EOL();
357     s->Indent();
358     *s << "Block        = " << (void *)block;
359     if (block != NULL)
360         *s << " {0x" << block->GetID() << '}';
361     // Dump the block and pass it a negative depth to we print all the parent blocks
362     //if (block != NULL)
363     //  block->Dump(s, function->GetFileAddress(), INT_MIN);
364     s->EOL();
365     s->Indent();
366     *s << "LineEntry    = ";
367     line_entry.Dump (s, target, true, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, true);
368     s->EOL();
369     s->Indent();
370     *s << "Symbol       = " << (void *)symbol;
371     if (symbol != NULL && symbol->GetMangled())
372         *s << ' ' << symbol->GetMangled().GetName().AsCString();
373     s->EOL();
374     s->IndentLess();
375     s->IndentLess();
376 }
377 
378 bool
379 lldb_private::operator== (const SymbolContext& lhs, const SymbolContext& rhs)
380 {
381     return  lhs.function == rhs.function
382             && lhs.symbol == rhs.symbol
383             && lhs.module_sp.get() == rhs.module_sp.get()
384             && lhs.comp_unit == rhs.comp_unit
385             && lhs.target_sp.get() == rhs.target_sp.get()
386             && LineEntry::Compare(lhs.line_entry, rhs.line_entry) == 0;
387 }
388 
389 bool
390 lldb_private::operator!= (const SymbolContext& lhs, const SymbolContext& rhs)
391 {
392     return  lhs.function != rhs.function
393             || lhs.symbol != rhs.symbol
394             || lhs.module_sp.get() != rhs.module_sp.get()
395             || lhs.comp_unit != rhs.comp_unit
396             || lhs.target_sp.get() != rhs.target_sp.get()
397             || LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0;
398 }
399 
400 bool
401 SymbolContext::GetAddressRange (uint32_t scope,
402                                 uint32_t range_idx,
403                                 bool use_inline_block_range,
404                                 AddressRange &range) const
405 {
406     if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
407     {
408         range = line_entry.range;
409         return true;
410     }
411 
412     if ((scope & eSymbolContextBlock) && (block != NULL))
413     {
414         if (use_inline_block_range)
415         {
416             Block *inline_block = block->GetContainingInlinedBlock();
417             if (inline_block)
418                 return inline_block->GetRangeAtIndex (range_idx, range);
419         }
420         else
421         {
422             return block->GetRangeAtIndex (range_idx, range);
423         }
424     }
425 
426     if ((scope & eSymbolContextFunction) && (function != NULL))
427     {
428         if (range_idx == 0)
429         {
430             range = function->GetAddressRange();
431             return true;
432         }
433     }
434 
435     if ((scope & eSymbolContextSymbol) && (symbol != NULL))
436     {
437         if (range_idx == 0)
438         {
439             if (symbol->ValueIsAddress())
440             {
441                 range.GetBaseAddress() = symbol->GetAddress();
442                 range.SetByteSize (symbol->GetByteSize());
443                 return true;
444             }
445         }
446     }
447     range.Clear();
448     return false;
449 }
450 
451 bool
452 SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc,
453                                         SymbolContext &next_frame_sc,
454                                         Address &next_frame_pc) const
455 {
456     next_frame_sc.Clear();
457     next_frame_pc.Clear();
458 
459     if (block)
460     {
461         //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
462 
463         // In order to get the parent of an inlined function we first need to
464         // see if we are in an inlined block as "this->block" could be an
465         // inlined block, or a parent of "block" could be. So lets check if
466         // this block or one of this blocks parents is an inlined function.
467         Block *curr_inlined_block = block->GetContainingInlinedBlock();
468         if (curr_inlined_block)
469         {
470             // "this->block" is contained in an inline function block, so to
471             // get the scope above the inlined block, we get the parent of the
472             // inlined block itself
473             Block *next_frame_block = curr_inlined_block->GetParent();
474             // Now calculate the symbol context of the containing block
475             next_frame_block->CalculateSymbolContext (&next_frame_sc);
476 
477             // If we get here we weren't able to find the return line entry using the nesting of the blocks and
478             // the line table.  So just use the call site info from our inlined block.
479 
480             AddressRange range;
481             if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range))
482             {
483                 // To see there this new frame block it, we need to look at the
484                 // call site information from
485                 const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo();
486                 next_frame_pc = range.GetBaseAddress();
487                 next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
488                 next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
489                 next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
490                 next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
491                 return true;
492             }
493             else
494             {
495                 LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
496 
497                 if (log)
498                 {
499                     log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64,
500                                  curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
501                 }
502 #ifdef LLDB_CONFIGURATION_DEBUG
503                 else
504                 {
505                     ObjectFile *objfile = NULL;
506                     if (module_sp)
507                     {
508                         SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
509                         if (symbol_vendor)
510                         {
511                             SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
512                             if (symbol_file)
513                                 objfile = symbol_file->GetObjectFile();
514                         }
515                     }
516                     if (objfile)
517                     {
518                         Host::SystemLog (Host::eSystemLogWarning,
519                                          "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s/%s\n",
520                                          curr_inlined_block->GetID(),
521                                          curr_frame_pc.GetFileAddress(),
522                                          objfile->GetFileSpec().GetDirectory().GetCString(),
523                                          objfile->GetFileSpec().GetFilename().GetCString());
524                     }
525                     else
526                     {
527                         Host::SystemLog (Host::eSystemLogWarning,
528                                          "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n",
529                                          curr_inlined_block->GetID(),
530                                          curr_frame_pc.GetFileAddress());
531                     }
532                 }
533 #endif
534             }
535         }
536     }
537 
538     return false;
539 }
540 
541 Block *
542 SymbolContext::GetFunctionBlock ()
543 {
544     if (function)
545     {
546         if (block)
547         {
548             // If this symbol context has a block, check to see if this block
549             // is itself, or is contained within a block with inlined function
550             // information. If so, then the inlined block is the block that
551             // defines the function.
552             Block *inlined_block = block->GetContainingInlinedBlock();
553             if (inlined_block)
554                 return inlined_block;
555 
556             // The block in this symbol context is not inside an inlined
557             // block, so the block that defines the function is the function's
558             // top level block, which is returned below.
559         }
560 
561         // There is no block information in this symbol context, so we must
562         // assume that the block that is desired is the top level block of
563         // the function itself.
564         return &function->GetBlock(true);
565     }
566     return NULL;
567 }
568 
569 bool
570 SymbolContext::GetFunctionMethodInfo (lldb::LanguageType &language,
571                                       bool &is_instance_method,
572                                       ConstString &language_object_name)
573 
574 
575 {
576     Block *function_block = GetFunctionBlock ();
577     if (function_block)
578     {
579         clang::DeclContext *decl_context = function_block->GetClangDeclContext();
580 
581         if (decl_context)
582         {
583             return ClangASTContext::GetClassMethodInfoForDeclContext (decl_context,
584                                                                       language,
585                                                                       is_instance_method,
586                                                                       language_object_name);
587         }
588     }
589     language = eLanguageTypeUnknown;
590     is_instance_method = false;
591     language_object_name.Clear();
592     return false;
593 }
594 
595 ConstString
596 SymbolContext::GetFunctionName (Mangled::NamePreference preference)
597 {
598     if (function)
599     {
600         if (block)
601         {
602             Block *inlined_block = block->GetContainingInlinedBlock();
603 
604             if (inlined_block)
605             {
606                 const InlineFunctionInfo *inline_info = inlined_block->GetInlinedFunctionInfo();
607                 if (inline_info)
608                     return inline_info->GetName();
609             }
610         }
611         return function->GetMangled().GetName(preference);
612     }
613     else if (symbol && symbol->ValueIsAddress())
614     {
615         return symbol->GetMangled().GetName(preference);
616     }
617     else
618     {
619         // No function, return an empty string.
620         return ConstString();
621     }
622 }
623 
624 //----------------------------------------------------------------------
625 //
626 //  SymbolContextSpecifier
627 //
628 //----------------------------------------------------------------------
629 
630 SymbolContextSpecifier::SymbolContextSpecifier (const TargetSP &target_sp) :
631     m_target_sp (target_sp),
632     m_module_spec (),
633     m_module_sp (),
634     m_file_spec_ap (),
635     m_start_line (0),
636     m_end_line (0),
637     m_function_spec (),
638     m_class_name (),
639     m_address_range_ap (),
640     m_type (eNothingSpecified)
641 {
642 }
643 
644 SymbolContextSpecifier::~SymbolContextSpecifier()
645 {
646 }
647 
648 bool
649 SymbolContextSpecifier::AddLineSpecification (uint32_t line_no, SpecificationType type)
650 {
651     bool return_value = true;
652     switch (type)
653     {
654     case eNothingSpecified:
655         Clear();
656         break;
657     case eLineStartSpecified:
658         m_start_line = line_no;
659         m_type |= eLineStartSpecified;
660         break;
661     case eLineEndSpecified:
662         m_end_line = line_no;
663         m_type |= eLineEndSpecified;
664         break;
665     default:
666         return_value = false;
667         break;
668     }
669     return return_value;
670 }
671 
672 bool
673 SymbolContextSpecifier::AddSpecification (const char *spec_string, SpecificationType type)
674 {
675     bool return_value = true;
676     switch (type)
677     {
678     case eNothingSpecified:
679         Clear();
680         break;
681     case eModuleSpecified:
682         {
683             // See if we can find the Module, if so stick it in the SymbolContext.
684             FileSpec module_file_spec(spec_string, false);
685             ModuleSpec module_spec (module_file_spec);
686             lldb::ModuleSP module_sp (m_target_sp->GetImages().FindFirstModule (module_spec));
687             m_type |= eModuleSpecified;
688             if (module_sp)
689                 m_module_sp = module_sp;
690             else
691                 m_module_spec.assign (spec_string);
692         }
693         break;
694     case eFileSpecified:
695         // CompUnits can't necessarily be resolved here, since an inlined function might show up in
696         // a number of CompUnits.  Instead we just convert to a FileSpec and store it away.
697         m_file_spec_ap.reset (new FileSpec (spec_string, false));
698         m_type |= eFileSpecified;
699         break;
700     case eLineStartSpecified:
701         m_start_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
702         if (return_value)
703             m_type |= eLineStartSpecified;
704         break;
705     case eLineEndSpecified:
706         m_end_line = Args::StringToSInt32(spec_string, 0, 0, &return_value);
707         if (return_value)
708             m_type |= eLineEndSpecified;
709         break;
710     case eFunctionSpecified:
711         m_function_spec.assign(spec_string);
712         m_type |= eFunctionSpecified;
713         break;
714     case eClassOrNamespaceSpecified:
715         Clear();
716         m_class_name.assign (spec_string);
717         m_type = eClassOrNamespaceSpecified;
718         break;
719     case eAddressRangeSpecified:
720         // Not specified yet...
721         break;
722     }
723 
724     return return_value;
725 }
726 
727 void
728 SymbolContextSpecifier::Clear()
729 {
730     m_module_spec.clear();
731     m_file_spec_ap.reset();
732     m_function_spec.clear();
733     m_class_name.clear();
734     m_start_line = 0;
735     m_end_line = 0;
736     m_address_range_ap.reset();
737 
738     m_type = eNothingSpecified;
739 }
740 
741 bool
742 SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc)
743 {
744     if (m_type == eNothingSpecified)
745         return true;
746 
747     if (m_target_sp.get() != sc.target_sp.get())
748         return false;
749 
750     if (m_type & eModuleSpecified)
751     {
752         if (sc.module_sp)
753         {
754             if (m_module_sp.get() != NULL)
755             {
756                 if (m_module_sp.get() != sc.module_sp.get())
757                     return false;
758             }
759             else
760             {
761                 FileSpec module_file_spec (m_module_spec.c_str(), false);
762                 if (!FileSpec::Equal (module_file_spec, sc.module_sp->GetFileSpec(), false))
763                     return false;
764             }
765         }
766     }
767     if (m_type & eFileSpecified)
768     {
769         if (m_file_spec_ap.get())
770         {
771             // If we don't have a block or a comp_unit, then we aren't going to match a source file.
772             if (sc.block == NULL && sc.comp_unit == NULL)
773                 return false;
774 
775             // Check if the block is present, and if so is it inlined:
776             bool was_inlined = false;
777             if (sc.block != NULL)
778             {
779                 const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
780                 if (inline_info != NULL)
781                 {
782                     was_inlined = true;
783                     if (!FileSpec::Equal (inline_info->GetDeclaration().GetFile(), *(m_file_spec_ap.get()), false))
784                         return false;
785                 }
786             }
787 
788             // Next check the comp unit, but only if the SymbolContext was not inlined.
789             if (!was_inlined && sc.comp_unit != NULL)
790             {
791                 if (!FileSpec::Equal (*(sc.comp_unit), *(m_file_spec_ap.get()), false))
792                     return false;
793             }
794         }
795     }
796     if (m_type & eLineStartSpecified
797         || m_type & eLineEndSpecified)
798     {
799         if (sc.line_entry.line < m_start_line || sc.line_entry.line > m_end_line)
800             return false;
801     }
802 
803     if (m_type & eFunctionSpecified)
804     {
805         // First check the current block, and if it is inlined, get the inlined function name:
806         bool was_inlined = false;
807         ConstString func_name(m_function_spec.c_str());
808 
809         if (sc.block != NULL)
810         {
811             const InlineFunctionInfo *inline_info = sc.block->GetInlinedFunctionInfo();
812             if (inline_info != NULL)
813             {
814                 was_inlined = true;
815                 const Mangled &name = inline_info->GetMangled();
816                 if (!name.NameMatches (func_name))
817                     return false;
818             }
819         }
820         //  If it wasn't inlined, check the name in the function or symbol:
821         if (!was_inlined)
822         {
823             if (sc.function != NULL)
824             {
825                 if (!sc.function->GetMangled().NameMatches(func_name))
826                     return false;
827             }
828             else if (sc.symbol != NULL)
829             {
830                 if (!sc.symbol->GetMangled().NameMatches(func_name))
831                     return false;
832             }
833         }
834 
835 
836     }
837 
838     return true;
839 }
840 
841 bool
842 SymbolContextSpecifier::AddressMatches(lldb::addr_t addr)
843 {
844     if (m_type & eAddressRangeSpecified)
845     {
846 
847     }
848     else
849     {
850         Address match_address (addr, NULL);
851         SymbolContext sc;
852         m_target_sp->GetImages().ResolveSymbolContextForAddress(match_address, eSymbolContextEverything, sc);
853         return SymbolContextMatches(sc);
854     }
855     return true;
856 }
857 
858 void
859 SymbolContextSpecifier::GetDescription (Stream *s, lldb::DescriptionLevel level) const
860 {
861     char path_str[PATH_MAX + 1];
862 
863     if (m_type == eNothingSpecified)
864     {
865         s->Printf ("Nothing specified.\n");
866     }
867 
868     if (m_type == eModuleSpecified)
869     {
870         s->Indent();
871         if (m_module_sp)
872         {
873             m_module_sp->GetFileSpec().GetPath (path_str, PATH_MAX);
874             s->Printf ("Module: %s\n", path_str);
875         }
876         else
877             s->Printf ("Module: %s\n", m_module_spec.c_str());
878     }
879 
880     if (m_type == eFileSpecified  && m_file_spec_ap.get() != NULL)
881     {
882         m_file_spec_ap->GetPath (path_str, PATH_MAX);
883         s->Indent();
884         s->Printf ("File: %s", path_str);
885         if (m_type == eLineStartSpecified)
886         {
887             s->Printf (" from line %lu", m_start_line);
888             if (m_type == eLineEndSpecified)
889                 s->Printf ("to line %lu", m_end_line);
890             else
891                 s->Printf ("to end");
892         }
893         else if (m_type == eLineEndSpecified)
894         {
895             s->Printf (" from start to line %ld", m_end_line);
896         }
897         s->Printf (".\n");
898     }
899 
900     if (m_type == eLineStartSpecified)
901     {
902         s->Indent();
903         s->Printf ("From line %lu", m_start_line);
904         if (m_type == eLineEndSpecified)
905             s->Printf ("to line %lu", m_end_line);
906         else
907             s->Printf ("to end");
908         s->Printf (".\n");
909     }
910     else if (m_type == eLineEndSpecified)
911     {
912         s->Printf ("From start to line %ld.\n", m_end_line);
913     }
914 
915     if (m_type == eFunctionSpecified)
916     {
917         s->Indent();
918         s->Printf ("Function: %s.\n", m_function_spec.c_str());
919     }
920 
921     if (m_type == eClassOrNamespaceSpecified)
922     {
923         s->Indent();
924         s->Printf ("Class name: %s.\n", m_class_name.c_str());
925     }
926 
927     if (m_type == eAddressRangeSpecified && m_address_range_ap.get() != NULL)
928     {
929         s->Indent();
930         s->PutCString ("Address range: ");
931         m_address_range_ap->Dump (s, m_target_sp.get(), Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
932         s->PutCString ("\n");
933     }
934 }
935 
936 //----------------------------------------------------------------------
937 //
938 //  SymbolContextList
939 //
940 //----------------------------------------------------------------------
941 
942 
943 SymbolContextList::SymbolContextList() :
944     m_symbol_contexts()
945 {
946 }
947 
948 SymbolContextList::~SymbolContextList()
949 {
950 }
951 
952 void
953 SymbolContextList::Append(const SymbolContext& sc)
954 {
955     m_symbol_contexts.push_back(sc);
956 }
957 
958 void
959 SymbolContextList::Append (const SymbolContextList& sc_list)
960 {
961     collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
962     for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
963         m_symbol_contexts.push_back (*pos);
964 }
965 
966 
967 uint32_t
968 SymbolContextList::AppendIfUnique (const SymbolContextList& sc_list, bool merge_symbol_into_function)
969 {
970     uint32_t unique_sc_add_count = 0;
971     collection::const_iterator pos, end = sc_list.m_symbol_contexts.end();
972     for (pos = sc_list.m_symbol_contexts.begin(); pos != end; ++pos)
973     {
974         if (AppendIfUnique (*pos, merge_symbol_into_function))
975             ++unique_sc_add_count;
976     }
977     return unique_sc_add_count;
978 }
979 
980 bool
981 SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_into_function)
982 {
983     collection::iterator pos, end = m_symbol_contexts.end();
984     for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
985     {
986         if (*pos == sc)
987             return false;
988     }
989     if (merge_symbol_into_function
990         && sc.symbol    != NULL
991         && sc.comp_unit == NULL
992         && sc.function  == NULL
993         && sc.block     == NULL
994         && sc.line_entry.IsValid() == false)
995     {
996         if (sc.symbol->ValueIsAddress())
997         {
998             for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
999             {
1000                 if (pos->function)
1001                 {
1002                     if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress())
1003                     {
1004                         // Do we already have a function with this symbol?
1005                         if (pos->symbol == sc.symbol)
1006                             return false;
1007                         if (pos->symbol == NULL)
1008                         {
1009                             pos->symbol = sc.symbol;
1010                             return false;
1011                         }
1012                     }
1013                 }
1014             }
1015         }
1016     }
1017     m_symbol_contexts.push_back(sc);
1018     return true;
1019 }
1020 
1021 void
1022 SymbolContextList::Clear()
1023 {
1024     m_symbol_contexts.clear();
1025 }
1026 
1027 void
1028 SymbolContextList::Dump(Stream *s, Target *target) const
1029 {
1030 
1031     *s << (void *)this << ": ";
1032     s->Indent();
1033     s->PutCString("SymbolContextList");
1034     s->EOL();
1035     s->IndentMore();
1036 
1037     collection::const_iterator pos, end = m_symbol_contexts.end();
1038     for (pos = m_symbol_contexts.begin(); pos != end; ++pos)
1039     {
1040         //pos->Dump(s, target);
1041         pos->GetDescription(s, eDescriptionLevelVerbose, target);
1042     }
1043     s->IndentLess();
1044 }
1045 
1046 bool
1047 SymbolContextList::GetContextAtIndex(uint32_t idx, SymbolContext& sc) const
1048 {
1049     if (idx < m_symbol_contexts.size())
1050     {
1051         sc = m_symbol_contexts[idx];
1052         return true;
1053     }
1054     return false;
1055 }
1056 
1057 bool
1058 SymbolContextList::RemoveContextAtIndex (uint32_t idx)
1059 {
1060     if (idx < m_symbol_contexts.size())
1061     {
1062         m_symbol_contexts.erase(m_symbol_contexts.begin() + idx);
1063         return true;
1064     }
1065     return false;
1066 }
1067 
1068 uint32_t
1069 SymbolContextList::GetSize() const
1070 {
1071     return m_symbol_contexts.size();
1072 }
1073 
1074 uint32_t
1075 SymbolContextList::NumLineEntriesWithLine (uint32_t line) const
1076 {
1077     uint32_t match_count = 0;
1078     const uint32_t size = m_symbol_contexts.size();
1079     for (uint32_t idx = 0; idx<size; ++idx)
1080     {
1081         if (m_symbol_contexts[idx].line_entry.line == line)
1082             ++match_count;
1083     }
1084     return match_count;
1085 }
1086 
1087 void
1088 SymbolContextList::GetDescription(Stream *s,
1089                                   lldb::DescriptionLevel level,
1090                                   Target *target) const
1091 {
1092     const uint32_t size = m_symbol_contexts.size();
1093     for (uint32_t idx = 0; idx<size; ++idx)
1094         m_symbol_contexts[idx].GetDescription (s, level, target);
1095 }
1096 
1097 bool
1098 lldb_private::operator== (const SymbolContextList& lhs, const SymbolContextList& rhs)
1099 {
1100     const uint32_t size = lhs.GetSize();
1101     if (size != rhs.GetSize())
1102         return false;
1103 
1104     SymbolContext lhs_sc;
1105     SymbolContext rhs_sc;
1106     for (uint32_t i=0; i<size; ++i)
1107     {
1108         lhs.GetContextAtIndex(i, lhs_sc);
1109         rhs.GetContextAtIndex(i, rhs_sc);
1110         if (lhs_sc != rhs_sc)
1111             return false;
1112     }
1113     return true;
1114 }
1115 
1116 bool
1117 lldb_private::operator!= (const SymbolContextList& lhs, const SymbolContextList& rhs)
1118 {
1119     return !(lhs == rhs);
1120 }
1121 
1122