1 //===-- SymbolFileDWARF.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 "SymbolFileDWARF.h"
11 
12 // Other libraries and framework includes
13 #include "clang/AST/ASTConsumer.h"
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclGroup.h"
17 #include "clang/Basic/Builtins.h"
18 #include "clang/Basic/IdentifierTable.h"
19 #include "clang/Basic/LangOptions.h"
20 #include "clang/Basic/SourceManager.h"
21 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Basic/Specifiers.h"
23 
24 #include "lldb/Core/Module.h"
25 #include "lldb/Core/PluginManager.h"
26 #include "lldb/Core/RegularExpression.h"
27 #include "lldb/Core/Scalar.h"
28 #include "lldb/Core/Section.h"
29 #include "lldb/Core/Timer.h"
30 #include "lldb/Core/Value.h"
31 
32 #include "lldb/Symbol/Block.h"
33 #include "lldb/Symbol/CompileUnit.h"
34 #include "lldb/Symbol/LineTable.h"
35 #include "lldb/Symbol/ObjectFile.h"
36 #include "lldb/Symbol/SymbolVendor.h"
37 #include "lldb/Symbol/VariableList.h"
38 
39 #include "DWARFCompileUnit.h"
40 #include "DWARFDebugAbbrev.h"
41 #include "DWARFDebugAranges.h"
42 #include "DWARFDebugInfo.h"
43 #include "DWARFDebugInfoEntry.h"
44 #include "DWARFDebugLine.h"
45 #include "DWARFDebugPubnames.h"
46 #include "DWARFDebugRanges.h"
47 #include "DWARFDIECollection.h"
48 #include "DWARFFormValue.h"
49 #include "DWARFLocationList.h"
50 #include "LogChannelDWARF.h"
51 
52 #include <map>
53 
54 #define DIE_IS_BEING_PARSED ((void*)1)
55 
56 using namespace lldb;
57 using namespace lldb_private;
58 
59 
60 static const ConstString&
61 GetSectionNameDebugInfo()
62 {
63     static const ConstString g_sect_name("__debug_info");
64     return g_sect_name;
65 }
66 
67 static const ConstString&
68 GetSectionNameDebugAbbrev()
69 {
70     static const ConstString g_sect_name ("__debug_abbrev");
71     return g_sect_name;
72 }
73 
74 static const ConstString&
75 GetSectionNameDebugAranges()
76 {
77     static const ConstString g_sect_name ("__debug_aranges");
78     return g_sect_name;
79 }
80 
81 static const ConstString&
82 GetSectionNameDebugFrame()
83 {
84     static const ConstString g_sect_name ("__debug_frame");
85     return g_sect_name;
86 }
87 
88 static const ConstString&
89 GetSectionNameDebugLine()
90 {
91     static const ConstString g_sect_name ("__debug_line");
92     return g_sect_name;
93 }
94 
95 static const ConstString&
96 GetSectionNameDebugLoc()
97 {
98     static const ConstString g_sect_name ("__debug_loc");
99     return g_sect_name;
100 }
101 
102 static const ConstString&
103 GetSectionNameDebugMacInfo()
104 {
105     static const ConstString g_sect_name ("__debug_macinfo");
106     return g_sect_name;
107 }
108 
109 static const ConstString&
110 GetSectionNameDebugPubNames()
111 {
112     static const ConstString g_sect_name ("__debug_pubnames");
113     return g_sect_name;
114 }
115 
116 static const ConstString&
117 GetSectionNameDebugPubTypes()
118 {
119     static const ConstString g_sect_name ("__debug_pubtypes");
120     return g_sect_name;
121 }
122 
123 static const ConstString&
124 GetSectionNameDebugRanges()
125 {
126     static const ConstString g_sect_name ("__debug_ranges");
127     return g_sect_name;
128 }
129 
130 static const ConstString&
131 GetSectionNameDebugStr()
132 {
133     static const ConstString g_sect_name ("__debug_str");
134     return g_sect_name;
135 }
136 
137 static uint32_t
138 DwarfToClangAccessibility (uint32_t dwarf_accessibility)
139 {
140     switch (dwarf_accessibility)
141     {
142         case DW_ACCESS_public:
143             return clang::AS_public;
144         case DW_ACCESS_private:
145             return clang::AS_private;
146         case DW_ACCESS_protected:
147             return clang::AS_protected;
148         default:
149             return clang::AS_none;
150     }
151 }
152 
153 void
154 SymbolFileDWARF::Initialize()
155 {
156     LogChannelDWARF::Initialize();
157     PluginManager::RegisterPlugin (GetPluginNameStatic(),
158                                    GetPluginDescriptionStatic(),
159                                    CreateInstance);
160 }
161 
162 void
163 SymbolFileDWARF::Terminate()
164 {
165     PluginManager::UnregisterPlugin (CreateInstance);
166     LogChannelDWARF::Initialize();
167 }
168 
169 
170 const char *
171 SymbolFileDWARF::GetPluginNameStatic()
172 {
173     return "symbol-file.dwarf2";
174 }
175 
176 const char *
177 SymbolFileDWARF::GetPluginDescriptionStatic()
178 {
179     return "DWARF and DWARF3 debug symbol file reader.";
180 }
181 
182 
183 SymbolFile*
184 SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
185 {
186     return new SymbolFileDWARF(obj_file);
187 }
188 
189 //----------------------------------------------------------------------
190 // Gets the first parent that is a lexical block, function or inlined
191 // subroutine, or compile unit.
192 //----------------------------------------------------------------------
193 static const DWARFDebugInfoEntry *
194 GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
195 {
196     const DWARFDebugInfoEntry *die;
197     for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
198     {
199         dw_tag_t tag = die->Tag();
200 
201         switch (tag)
202         {
203         case DW_TAG_compile_unit:
204         case DW_TAG_subprogram:
205         case DW_TAG_inlined_subroutine:
206         case DW_TAG_lexical_block:
207             return die;
208         }
209     }
210     return NULL;
211 }
212 
213 
214 SymbolFileDWARF::SymbolFileDWARF(ObjectFile* ofile) :
215     SymbolFile(ofile),
216     m_flags(),
217     m_data_debug_abbrev(),
218     m_data_debug_aranges(),
219     m_data_debug_frame(),
220     m_data_debug_info(),
221     m_data_debug_line(),
222     m_data_debug_loc(),
223     m_data_debug_macinfo(),
224     m_data_debug_pubnames(),
225     m_data_debug_pubtypes(),
226     m_data_debug_ranges(),
227     m_data_debug_str(),
228     m_abbr(),
229     m_aranges(),
230     m_info(),
231     m_line(),
232     m_base_name_to_function_die(),
233     m_full_name_to_function_die(),
234     m_method_name_to_function_die(),
235     m_selector_name_to_function_die(),
236     m_name_to_global_die(),
237     m_name_to_type_die(),
238     m_indexed(false),
239 //    m_pubnames(),
240 //    m_pubtypes(),
241 //    m_pubbasetypes(),
242     m_ranges()//,
243 //  m_type_fixups(),
244 //  m_indirect_fixups()
245 {
246 }
247 
248 SymbolFileDWARF::~SymbolFileDWARF()
249 {
250 }
251 
252 bool
253 SymbolFileDWARF::SupportedVersion(uint16_t version)
254 {
255     return version == 2 || version == 3;
256 }
257 
258 uint32_t
259 SymbolFileDWARF::GetAbilities ()
260 {
261     uint32_t abilities = 0;
262     if (m_obj_file != NULL)
263     {
264         const Section* section = NULL;
265         const SectionList *section_list = m_obj_file->GetSectionList();
266         if (section_list == NULL)
267             return 0;
268 
269         uint64_t debug_abbrev_file_size = 0;
270         uint64_t debug_aranges_file_size = 0;
271         uint64_t debug_frame_file_size = 0;
272         uint64_t debug_info_file_size = 0;
273         uint64_t debug_line_file_size = 0;
274         uint64_t debug_loc_file_size = 0;
275         uint64_t debug_macinfo_file_size = 0;
276         uint64_t debug_pubnames_file_size = 0;
277         uint64_t debug_pubtypes_file_size = 0;
278         uint64_t debug_ranges_file_size = 0;
279         uint64_t debug_str_file_size = 0;
280 
281         static ConstString g_dwarf_section_name ("__DWARF");
282 
283         section = section_list->FindSectionByName(g_dwarf_section_name).get();
284 
285         if (section)
286             section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
287 
288         section = section_list->FindSectionByName (GetSectionNameDebugInfo()).get();
289         if (section != NULL)
290         {
291             debug_info_file_size = section->GetByteSize();
292 
293             section = section_list->FindSectionByName (GetSectionNameDebugAbbrev()).get();
294             if (section)
295                 debug_abbrev_file_size = section->GetByteSize();
296             else
297                 m_flags.Set (flagsGotDebugAbbrevData);
298 
299             section = section_list->FindSectionByName (GetSectionNameDebugAranges()).get();
300             if (section)
301                 debug_aranges_file_size = section->GetByteSize();
302             else
303                 m_flags.Set (flagsGotDebugArangesData);
304 
305             section = section_list->FindSectionByName (GetSectionNameDebugFrame()).get();
306             if (section)
307                 debug_frame_file_size = section->GetByteSize();
308             else
309                 m_flags.Set (flagsGotDebugFrameData);
310 
311             section = section_list->FindSectionByName (GetSectionNameDebugLine()).get();
312             if (section)
313                 debug_line_file_size = section->GetByteSize();
314             else
315                 m_flags.Set (flagsGotDebugLineData);
316 
317             section = section_list->FindSectionByName (GetSectionNameDebugLoc()).get();
318             if (section)
319                 debug_loc_file_size = section->GetByteSize();
320             else
321                 m_flags.Set (flagsGotDebugLocData);
322 
323             section = section_list->FindSectionByName (GetSectionNameDebugMacInfo()).get();
324             if (section)
325                 debug_macinfo_file_size = section->GetByteSize();
326             else
327                 m_flags.Set (flagsGotDebugMacInfoData);
328 
329             section = section_list->FindSectionByName (GetSectionNameDebugPubNames()).get();
330             if (section)
331                 debug_pubnames_file_size = section->GetByteSize();
332             else
333                 m_flags.Set (flagsGotDebugPubNamesData);
334 
335             section = section_list->FindSectionByName (GetSectionNameDebugPubTypes()).get();
336             if (section)
337                 debug_pubtypes_file_size = section->GetByteSize();
338             else
339                 m_flags.Set (flagsGotDebugPubTypesData);
340 
341             section = section_list->FindSectionByName (GetSectionNameDebugRanges()).get();
342             if (section)
343                 debug_ranges_file_size = section->GetByteSize();
344             else
345                 m_flags.Set (flagsGotDebugRangesData);
346 
347             section = section_list->FindSectionByName (GetSectionNameDebugStr()).get();
348             if (section)
349                 debug_str_file_size = section->GetByteSize();
350             else
351                 m_flags.Set (flagsGotDebugStrData);
352         }
353 
354         if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
355             abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
356 
357         if (debug_line_file_size > 0)
358             abilities |= LineTables;
359 
360         if (debug_aranges_file_size > 0)
361             abilities |= AddressAcceleratorTable;
362 
363         if (debug_pubnames_file_size > 0)
364             abilities |= FunctionAcceleratorTable;
365 
366         if (debug_pubtypes_file_size > 0)
367             abilities |= TypeAcceleratorTable;
368 
369         if (debug_macinfo_file_size > 0)
370             abilities |= MacroInformation;
371 
372         if (debug_frame_file_size > 0)
373             abilities |= CallFrameInformation;
374     }
375     return abilities;
376 }
377 
378 const DataExtractor&
379 SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, const ConstString &section_name, DataExtractor &data)
380 {
381     if (m_flags.IsClear (got_flag))
382     {
383         m_flags.Set (got_flag);
384         const SectionList *section_list = m_obj_file->GetSectionList();
385         if (section_list)
386         {
387             Section *section = section_list->FindSectionByName (section_name).get();
388             if (section )
389             {
390                 // See if we memory mapped the DWARF segment?
391                 if (m_dwarf_data.GetByteSize())
392                 {
393                     data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
394                 }
395                 else
396                 {
397                     if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
398                         data.Clear();
399                 }
400             }
401         }
402     }
403     return data;
404 }
405 
406 const DataExtractor&
407 SymbolFileDWARF::get_debug_abbrev_data()
408 {
409     return GetCachedSectionData (flagsGotDebugAbbrevData, GetSectionNameDebugAbbrev(), m_data_debug_abbrev);
410 }
411 
412 const DataExtractor&
413 SymbolFileDWARF::get_debug_aranges_data()
414 {
415     return GetCachedSectionData (flagsGotDebugArangesData, GetSectionNameDebugAranges(), m_data_debug_aranges);
416 }
417 
418 const DataExtractor&
419 SymbolFileDWARF::get_debug_frame_data()
420 {
421     return GetCachedSectionData (flagsGotDebugFrameData, GetSectionNameDebugFrame(), m_data_debug_frame);
422 }
423 
424 const DataExtractor&
425 SymbolFileDWARF::get_debug_info_data()
426 {
427     return GetCachedSectionData (flagsGotDebugInfoData, GetSectionNameDebugInfo(), m_data_debug_info);
428 }
429 
430 const DataExtractor&
431 SymbolFileDWARF::get_debug_line_data()
432 {
433     return GetCachedSectionData (flagsGotDebugLineData, GetSectionNameDebugLine(), m_data_debug_line);
434 }
435 
436 const DataExtractor&
437 SymbolFileDWARF::get_debug_loc_data()
438 {
439     return GetCachedSectionData (flagsGotDebugLocData, GetSectionNameDebugLoc(), m_data_debug_loc);
440 }
441 
442 const DataExtractor&
443 SymbolFileDWARF::get_debug_macinfo_data()
444 {
445     return GetCachedSectionData (flagsGotDebugMacInfoData, GetSectionNameDebugMacInfo(), m_data_debug_macinfo);
446 }
447 
448 const DataExtractor&
449 SymbolFileDWARF::get_debug_pubnames_data()
450 {
451     return GetCachedSectionData (flagsGotDebugPubNamesData, GetSectionNameDebugPubNames(), m_data_debug_pubnames);
452 }
453 
454 const DataExtractor&
455 SymbolFileDWARF::get_debug_pubtypes_data()
456 {
457     return GetCachedSectionData (flagsGotDebugPubTypesData, GetSectionNameDebugPubTypes(), m_data_debug_pubtypes);
458 }
459 
460 const DataExtractor&
461 SymbolFileDWARF::get_debug_ranges_data()
462 {
463     return GetCachedSectionData (flagsGotDebugRangesData, GetSectionNameDebugRanges(), m_data_debug_ranges);
464 }
465 
466 const DataExtractor&
467 SymbolFileDWARF::get_debug_str_data()
468 {
469     return GetCachedSectionData (flagsGotDebugStrData, GetSectionNameDebugStr(), m_data_debug_str);
470 }
471 
472 
473 DWARFDebugAbbrev*
474 SymbolFileDWARF::DebugAbbrev()
475 {
476     if (m_abbr.get() == NULL)
477     {
478         const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
479         if (debug_abbrev_data.GetByteSize() > 0)
480         {
481             m_abbr.reset(new DWARFDebugAbbrev());
482             if (m_abbr.get())
483                 m_abbr->Parse(debug_abbrev_data);
484         }
485     }
486     return m_abbr.get();
487 }
488 
489 const DWARFDebugAbbrev*
490 SymbolFileDWARF::DebugAbbrev() const
491 {
492     return m_abbr.get();
493 }
494 
495 DWARFDebugAranges*
496 SymbolFileDWARF::DebugAranges()
497 {
498     if (m_aranges.get() == NULL)
499     {
500         Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
501         m_aranges.reset(new DWARFDebugAranges());
502         if (m_aranges.get())
503         {
504             const DataExtractor &debug_aranges_data = get_debug_aranges_data();
505             if (debug_aranges_data.GetByteSize() > 0)
506                 m_aranges->Extract(debug_aranges_data);
507             else
508                 m_aranges->Generate(this);
509         }
510     }
511     return m_aranges.get();
512 }
513 
514 const DWARFDebugAranges*
515 SymbolFileDWARF::DebugAranges() const
516 {
517     return m_aranges.get();
518 }
519 
520 
521 DWARFDebugInfo*
522 SymbolFileDWARF::DebugInfo()
523 {
524     if (m_info.get() == NULL)
525     {
526         Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
527         if (get_debug_info_data().GetByteSize() > 0)
528         {
529             m_info.reset(new DWARFDebugInfo());
530             if (m_info.get())
531             {
532                 m_info->SetDwarfData(this);
533             }
534         }
535     }
536     return m_info.get();
537 }
538 
539 const DWARFDebugInfo*
540 SymbolFileDWARF::DebugInfo() const
541 {
542     return m_info.get();
543 }
544 
545 //DWARFDebugLine*
546 //SymbolFileDWARF::DebugLine()
547 //{
548 //  if (m_line.get() == NULL)
549 //  {
550 //      Timer scoped_timer(__PRETTY_FUNCTION__);
551 //      const DataExtractor &debug_line_data = debug_line();
552 //      if (debug_line_data.GetByteSize() > 0)
553 //      {
554 //          m_line.reset(new DWARFDebugLine());
555 //          if (m_line.get())
556 //              m_line->Parse(debug_line_data);
557 //      }
558 //  }
559 //  return m_line.get();
560 //}
561 //
562 //const DWARFDebugLine*
563 //SymbolFileDWARF::DebugLine() const
564 //{
565 //  return m_line.get();
566 //}
567 
568 
569 DWARFCompileUnit*
570 SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
571 {
572     DWARFDebugInfo* info = DebugInfo();
573     if (info)
574         return info->GetCompileUnit(cu_uid).get();
575     return NULL;
576 }
577 
578 //DWARFCompileUnit*
579 //SymbolFileDWARF::GetNextUnparsedDWARFCompileUnit(DWARFCompileUnit* prev_cu)
580 //{
581 //  DWARFCompileUnit* cu = NULL;
582 //  DWARFDebugInfo* info = DebugInfo();
583 //  if (info)
584 //  {
585 //      uint32_t cu_idx = 0;
586 //      if (prev_cu != NULL)
587 //      {
588 //          // Find the index of the previus DWARF compile unit if one was provided
589 //          while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL)
590 //          {
591 //              ++cu_idx;
592 //              if (cu == prev_cu)
593 //                  break;
594 //          }
595 //      }
596 //
597 //      // Now find the next unparsed DWARF compile unit. We do this by checking the
598 //      // user data in the DWARFCompileUnit class that starts as NULL, and eventually
599 //      // holds a pointer to the CompileUnit that was created for it after it has
600 //      // been parsed.
601 //      while ((cu = info->GetCompileUnitAtIndex(cu_idx)) != NULL)
602 //      {
603 //          if (cu->GetUserData() == NULL)
604 //              break;
605 //      }
606 //  }
607 //  return cu;
608 //}
609 
610 DWARFDebugRanges*
611 SymbolFileDWARF::DebugRanges()
612 {
613     if (m_ranges.get() == NULL)
614     {
615         Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
616         if (get_debug_ranges_data().GetByteSize() > 0)
617         {
618             m_ranges.reset(new DWARFDebugRanges());
619             if (m_ranges.get())
620                 m_ranges->Extract(this);
621         }
622     }
623     return m_ranges.get();
624 }
625 
626 const DWARFDebugRanges*
627 SymbolFileDWARF::DebugRanges() const
628 {
629     return m_ranges.get();
630 }
631 //
632 //DWARFDebugPubnames*
633 //SymbolFileDWARF::DebugPubnames()
634 //{
635 //    if (m_pubnames.get() == NULL)
636 //    {
637 //        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
638 //        const DataExtractor &debug_pubnames_data = get_debug_pubnames_data();
639 //        if (debug_pubnames_data.GetByteSize() > 0)
640 //        {
641 //            // Pass false to indicate this is a pubnames section
642 //            m_pubnames.reset(new DWARFDebugPubnames());
643 //            if (m_pubnames.get())
644 //            {
645 //                // "m_pubnames->GeneratePubnames" is costly, but needed for global variables
646 //                m_pubnames->GeneratePubnames(this);
647 //
648 //#if 0
649 //                StreamFile s(stdout);
650 //                s.Printf (".debug_pubnames for %s/%s:\n",
651 //                          m_obj_file->GetModule()->GetFileSpec().GetDirectory().AsCString(),
652 //                          m_obj_file->GetModule()->GetFileSpec().GetFilename().AsCString());
653 //                m_pubnames->Dump (&s);
654 //#endif
655 //                // "m_pubnames->Extract" is quicker, but the pubnames don't always contain what we need.
656 //                //m_pubnames->Extract(debug_pubnames_data);
657 //            }
658 //        }
659 //    }
660 //    return m_pubnames.get();
661 //}
662 //
663 //const DWARFDebugPubnames*
664 //SymbolFileDWARF::DebugPubnames() const
665 //{
666 //    return m_pubnames.get();
667 //}
668 
669 //DWARFDebugPubnames*
670 //SymbolFileDWARF::DebugPubBaseTypes()
671 //{
672 //    if (m_pubbasetypes.get() == NULL)
673 //    {
674 //        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
675 //        // Pass false to indicate this is a pubnames section
676 //        m_pubbasetypes.reset(new DWARFDebugPubnames());
677 //        if (m_pubbasetypes.get())
678 //            m_pubbasetypes->GeneratePubBaseTypes(this);
679 //    }
680 //    return m_pubbasetypes.get();
681 //}
682 //
683 //const DWARFDebugPubnames*
684 //SymbolFileDWARF::DebugPubBaseTypes() const
685 //{
686 //    return m_pubbasetypes.get();
687 //}
688 //
689 //const DWARFDebugPubnames*
690 //SymbolFileDWARF::DebugPubtypes() const
691 //{
692 //    return m_pubtypes.get();
693 //}
694 //
695 //DWARFDebugPubnames*
696 //SymbolFileDWARF::DebugPubtypes()
697 //{
698 //    if (m_pubtypes.get() == NULL)
699 //    {
700 //        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
701 //        const DataExtractor &debug_pubtypes_data = get_debug_pubtypes_data();
702 //        if (debug_pubtypes_data.GetByteSize() > 0)
703 //        {
704 //            // Pass false to indicate this is a pubnames section
705 //            m_pubtypes.reset(new DWARFDebugPubnames());
706 //            if (m_pubtypes.get())
707 //                m_pubtypes->Extract(debug_pubtypes_data);
708 //        }
709 //    }
710 //    return m_pubtypes.get();
711 //}
712 //
713 
714 bool
715 SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit* cu, CompUnitSP& compile_unit_sp)
716 {
717     if (cu != NULL)
718     {
719         const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly ();
720         if (cu_die)
721         {
722             const char * cu_die_name = cu_die->GetName(this, cu);
723             const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
724             Language::Type language = (Language::Type)cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_language, 0);
725             if (cu_die_name)
726             {
727                 if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
728                 {
729                     compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, cu_die_name, cu->GetOffset(), language));
730                 }
731                 else
732                 {
733                     std::string fullpath(cu_comp_dir);
734                     if (*fullpath.rbegin() != '/')
735                         fullpath += '/';
736                     fullpath += cu_die_name;
737 
738                     compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), cu, fullpath.c_str(), cu->GetOffset(), language));
739                 }
740 
741                 if (compile_unit_sp.get())
742                 {
743                     cu->SetUserData(compile_unit_sp.get());
744                     return true;
745                 }
746             }
747         }
748     }
749     return false;
750 }
751 
752 #if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST
753 
754 void
755 SymbolFileDWARF::ShrinkDSYM(CompileUnit *dc_cu, DWARFCompileUnit *dw_cu, const FileSpec& cu_fspec, const FileSpec& base_types_fspec, FSToDIES& fs_to_dies, const DWARFDebugInfoEntry *die)
756 {
757     while (die != NULL)
758     {
759         dw_tag_t tag = die->Tag();
760 
761         switch (tag)
762         {
763         case DW_TAG_base_type:
764             // Put all base types into the base type compile unit
765             fs_to_dies[base_types_fspec].Insert(die);
766             break;
767 
768         default:
769             {
770                 uint32_t decl_file = die->GetAttributeValueAsUnsigned(this, dw_cu, DW_AT_decl_file, 0);
771                 if (decl_file)
772                 {
773                     fs_to_dies[dc_cu->GetSupportFiles().GetFileSpecAtIndex(decl_file)].Insert(die);
774                 }
775                 else
776                 {
777                     // add this to the current compile unit
778                     fs_to_dies[cu_fspec].Insert(die);
779                 }
780             }
781             break;
782         }
783 
784         die = die->GetSibling();
785     }
786 }
787 
788 
789 
790 #endif
791 
792 uint32_t
793 SymbolFileDWARF::GetNumCompileUnits()
794 {
795     DWARFDebugInfo* info = DebugInfo();
796     if (info)
797     {
798 #if defined LLDB_SYMBOL_FILE_DWARF_SHRINK_TEST
799         uint32_t cu_idx;
800         FSToDIES fs_to_dies;
801 
802         FileSpec base_type_fspec("DW_TAG_base_type");
803         const uint32_t num_comp_units = info->GetNumCompileUnits();
804 
805         for (cu_idx=0; cu_idx < num_comp_units; ++cu_idx)
806         {
807             DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
808             if (cu != NULL)
809             {
810                 const DWARFDebugInfoEntry *cu_die = cu->DIE();
811                 if (cu_die)
812                 {
813                     CompUnitSP dc_cu_sp;
814                     ParseCompileUnit(cu, dc_cu_sp);
815                     if (dc_cu_sp.get())
816                     {
817                         FileSpec cu_fspec(*dc_cu_sp.get());
818 
819                         ShrinkDSYM(dc_cu_sp.get(), cu, cu_fspec, base_type_fspec, fs_to_dies, cu->DIE()->GetFirstChild());
820                     }
821                 }
822             }
823         }
824 
825         Stream strm(stdout);
826         FSToDIES::const_iterator pos, end = fs_to_dies.end();
827         for (pos = fs_to_dies.begin(); pos != end; ++pos)
828         {
829             strm << "\n\nMinimal Compile Unit: " << pos->first << ":\n";
830             const DWARFDIECollection& dies = pos->second;
831             dies.Dump(strm, NULL);
832         }
833         return num_comp_units;
834 #else
835         return info->GetNumCompileUnits();
836 #endif
837     }
838     return 0;
839 }
840 
841 CompUnitSP
842 SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
843 {
844     CompUnitSP comp_unit;
845     DWARFDebugInfo* info = DebugInfo();
846     if (info)
847     {
848         DWARFCompileUnit* cu = info->GetCompileUnitAtIndex(cu_idx);
849         if (cu != NULL)
850         {
851             // Our symbol vendor shouldn't be asking us to add a compile unit that
852             // has already been added to it, which this DWARF plug-in knows as it
853             // stores the lldb compile unit (CompileUnit) pointer in each
854             // DWARFCompileUnit object when it gets added.
855             assert(cu->GetUserData() == NULL);
856             ParseCompileUnit(cu, comp_unit);
857         }
858     }
859     return comp_unit;
860 }
861 
862 static void
863 AddRangesToBlock
864 (
865     BlockList& blocks,
866     lldb::user_id_t blockID,
867     DWARFDebugRanges::RangeList& ranges,
868     addr_t block_base_addr
869 )
870 {
871     ranges.SubtractOffset (block_base_addr);
872     size_t range_idx = 0;
873     const DWARFDebugRanges::Range *debug_range;
874     for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
875     {
876         blocks.AddRange(blockID, debug_range->begin_offset, debug_range->end_offset);
877     }
878 }
879 
880 
881 Function *
882 SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
883 {
884     DWARFDebugRanges::RangeList func_ranges;
885     const char *name = NULL;
886     const char *mangled = NULL;
887     int decl_file = 0;
888     int decl_line = 0;
889     int decl_column = 0;
890     int call_file = 0;
891     int call_line = 0;
892     int call_column = 0;
893     DWARFExpression frame_base;
894 
895     // Parse the function prototype as a type that can then be added to concrete function instance
896     ParseTypes (sc, dwarf_cu, die, false, false);
897     //FixupTypes();
898 
899     if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
900     {
901         // Union of all ranges in the function DIE (if the function is discontiguous)
902         AddressRange func_range;
903         lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
904         lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
905         if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
906         {
907             func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
908             if (func_range.GetBaseAddress().IsValid())
909                 func_range.SetByteSize(highest_func_addr - lowest_func_addr);
910         }
911 
912         if (func_range.GetBaseAddress().IsValid())
913         {
914             Mangled func_name;
915             if (mangled)
916                 func_name.SetValue(mangled, true);
917             else if (name)
918                 func_name.SetValue(name, false);
919 
920             FunctionSP func_sp;
921             std::auto_ptr<Declaration> decl_ap;
922             if (decl_file != 0 || decl_line != 0 || decl_column != 0)
923                 decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
924 
925             Type *func_type = NULL;
926 
927             if (die->GetUserData() != DIE_IS_BEING_PARSED)
928                 func_type = (Type*)die->GetUserData();
929 
930             assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
931 
932             func_range.GetBaseAddress().ResolveLinkedAddress();
933 
934             func_sp.reset(new Function (sc.comp_unit,
935                                         die->GetOffset(),       // UserID is the DIE offset
936                                         die->GetOffset(),
937                                         func_name,
938                                         func_type,
939                                         func_range));           // first address range
940 
941             if (func_sp.get() != NULL)
942             {
943                 func_sp->GetFrameBaseExpression() = frame_base;
944                 sc.comp_unit->AddFunction(func_sp);
945                 return func_sp.get();
946             }
947         }
948     }
949     return NULL;
950 }
951 
952 size_t
953 SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
954 {
955     assert (sc.comp_unit);
956     size_t functions_added = 0;
957     const DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
958     if (dwarf_cu)
959     {
960         DWARFDIECollection function_dies;
961         const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
962         size_t func_idx;
963         for (func_idx = 0; func_idx < num_funtions; ++func_idx)
964         {
965             const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
966             if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
967             {
968                 if (ParseCompileUnitFunction(sc, dwarf_cu, die))
969                     ++functions_added;
970             }
971         }
972         //FixupTypes();
973     }
974     return functions_added;
975 }
976 
977 bool
978 SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
979 {
980     assert (sc.comp_unit);
981     DWARFCompileUnit* cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
982     assert (cu);
983     const DWARFDebugInfoEntry * cu_die = cu->GetCompileUnitDIEOnly();
984 
985     if (cu_die)
986     {
987         const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, cu, DW_AT_comp_dir, NULL);
988         dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
989 
990         // All file indexes in DWARF are one based and a file of index zero is
991         // supposed to be the compile unit itself.
992         support_files.Append (*sc.comp_unit);
993 
994         return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
995     }
996     return false;
997 }
998 
999 struct ParseDWARFLineTableCallbackInfo
1000 {
1001     LineTable* line_table;
1002     const SectionList *section_list;
1003     lldb::addr_t prev_sect_file_base_addr;
1004     lldb::addr_t curr_sect_file_base_addr;
1005     bool is_oso_for_debug_map;
1006     bool prev_in_final_executable;
1007     DWARFDebugLine::Row prev_row;
1008     SectionSP prev_section_sp;
1009     SectionSP curr_section_sp;
1010 };
1011 
1012 //----------------------------------------------------------------------
1013 // ParseStatementTableCallback
1014 //----------------------------------------------------------------------
1015 static void
1016 ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
1017 {
1018     LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
1019     if (state.row == DWARFDebugLine::State::StartParsingLineTable)
1020     {
1021         // Just started parsing the line table
1022     }
1023     else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
1024     {
1025         // Done parsing line table, nothing to do for the cleanup
1026     }
1027     else
1028     {
1029         ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
1030         // We have a new row, lets append it
1031 
1032         if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
1033         {
1034             info->prev_section_sp = info->curr_section_sp;
1035             info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
1036             // If this is an end sequence entry, then we subtract one from the
1037             // address to make sure we get an address that is not the end of
1038             // a section.
1039             if (state.end_sequence && state.address != 0)
1040                 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
1041             else
1042                 info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
1043 
1044             if (info->curr_section_sp.get())
1045                 info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
1046             else
1047                 info->curr_sect_file_base_addr = 0;
1048         }
1049         if (info->curr_section_sp.get())
1050         {
1051             lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
1052             // Check for the fancy section magic to determine if we
1053 
1054             if (info->is_oso_for_debug_map)
1055             {
1056                 // When this is a debug map object file that contains DWARF
1057                 // (referenced from an N_OSO debug map nlist entry) we will have
1058                 // a file address in the file range for our section from the
1059                 // original .o file, and a load address in the executable that
1060                 // contains the debug map.
1061                 //
1062                 // If the sections for the file range and load range are
1063                 // different, we have a remapped section for the function and
1064                 // this address is resolved. If they are the same, then the
1065                 // function for this address didn't make it into the final
1066                 // executable.
1067                 bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
1068 
1069                 // If we are doing DWARF with debug map, then we need to carefully
1070                 // add each line table entry as there may be gaps as functions
1071                 // get moved around or removed.
1072                 if (!info->prev_row.end_sequence && info->prev_section_sp.get())
1073                 {
1074                     if (info->prev_in_final_executable)
1075                     {
1076                         bool terminate_previous_entry = false;
1077                         if (!curr_in_final_executable)
1078                         {
1079                             // Check for the case where the previous line entry
1080                             // in a function made it into the final executable,
1081                             // yet the current line entry falls in a function
1082                             // that didn't. The line table used to be contiguous
1083                             // through this address range but now it isn't. We
1084                             // need to terminate the previous line entry so
1085                             // that we can reconstruct the line range correctly
1086                             // for it and to keep the line table correct.
1087                             terminate_previous_entry = true;
1088                         }
1089                         else if (info->curr_section_sp.get() != info->prev_section_sp.get())
1090                         {
1091                             // Check for cases where the line entries used to be
1092                             // contiguous address ranges, but now they aren't.
1093                             // This can happen when order files specify the
1094                             // ordering of the functions.
1095                             lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
1096                             Section *curr_sect = info->curr_section_sp.get();
1097                             Section *prev_sect = info->prev_section_sp.get();
1098                             assert (curr_sect->GetLinkedSection());
1099                             assert (prev_sect->GetLinkedSection());
1100                             lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
1101                             lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
1102                             lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
1103                             lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
1104                             if (object_file_addr_delta != linked_file_addr_delta)
1105                                 terminate_previous_entry = true;
1106                         }
1107 
1108                         if (terminate_previous_entry)
1109                         {
1110                             line_table->InsertLineEntry (info->prev_section_sp,
1111                                                          state.address - info->prev_sect_file_base_addr,
1112                                                          info->prev_row.line,
1113                                                          info->prev_row.column,
1114                                                          info->prev_row.file,
1115                                                          false,                 // is_stmt
1116                                                          false,                 // basic_block
1117                                                          false,                 // state.prologue_end
1118                                                          false,                 // state.epilogue_begin
1119                                                          true);                 // end_sequence);
1120                         }
1121                     }
1122                 }
1123 
1124                 if (curr_in_final_executable)
1125                 {
1126                     line_table->InsertLineEntry (info->curr_section_sp,
1127                                                  curr_line_section_offset,
1128                                                  state.line,
1129                                                  state.column,
1130                                                  state.file,
1131                                                  state.is_stmt,
1132                                                  state.basic_block,
1133                                                  state.prologue_end,
1134                                                  state.epilogue_begin,
1135                                                  state.end_sequence);
1136                     info->prev_section_sp = info->curr_section_sp;
1137                 }
1138                 else
1139                 {
1140                     // If the current address didn't make it into the final
1141                     // executable, the current section will be the __text
1142                     // segment in the .o file, so we need to clear this so
1143                     // we can catch the next function that did make it into
1144                     // the final executable.
1145                     info->prev_section_sp.reset();
1146                     info->curr_section_sp.reset();
1147                 }
1148 
1149                 info->prev_in_final_executable = curr_in_final_executable;
1150             }
1151             else
1152             {
1153                 // We are not in an object file that contains DWARF for an
1154                 // N_OSO, this is just a normal DWARF file. The DWARF spec
1155                 // guarantees that the addresses will be in increasing order
1156                 // so, since we store line tables in file address order, we
1157                 // can always just append the line entry without needing to
1158                 // search for the correct insertion point (we don't need to
1159                 // use LineEntry::InsertLineEntry()).
1160                 line_table->AppendLineEntry (info->curr_section_sp,
1161                                              curr_line_section_offset,
1162                                              state.line,
1163                                              state.column,
1164                                              state.file,
1165                                              state.is_stmt,
1166                                              state.basic_block,
1167                                              state.prologue_end,
1168                                              state.epilogue_begin,
1169                                              state.end_sequence);
1170             }
1171         }
1172 
1173         info->prev_row = state;
1174     }
1175 }
1176 
1177 bool
1178 SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1179 {
1180     assert (sc.comp_unit);
1181     if (sc.comp_unit->GetLineTable() != NULL)
1182         return true;
1183 
1184     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
1185     if (dwarf_cu)
1186     {
1187         const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1188         const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
1189         if (cu_line_offset != DW_INVALID_OFFSET)
1190         {
1191             std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
1192             if (line_table_ap.get())
1193             {
1194                 ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_flags.IsSet (flagsDWARFIsOSOForDebugMap), false};
1195                 uint32_t offset = cu_line_offset;
1196                 DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1197                 sc.comp_unit->SetLineTable(line_table_ap.release());
1198                 return true;
1199             }
1200         }
1201     }
1202     return false;
1203 }
1204 
1205 size_t
1206 SymbolFileDWARF::ParseFunctionBlocks
1207 (
1208     const SymbolContext& sc,
1209     lldb::user_id_t parentBlockID,
1210     const DWARFCompileUnit* dwarf_cu,
1211     const DWARFDebugInfoEntry *die,
1212     addr_t subprogram_low_pc,
1213     bool parse_siblings,
1214     bool parse_children
1215 )
1216 {
1217     size_t blocks_added = 0;
1218     while (die != NULL)
1219     {
1220         dw_tag_t tag = die->Tag();
1221 
1222         switch (tag)
1223         {
1224         case DW_TAG_subprogram:
1225         case DW_TAG_inlined_subroutine:
1226         case DW_TAG_lexical_block:
1227             {
1228                 DWARFDebugRanges::RangeList ranges;
1229                 const char *name = NULL;
1230                 const char *mangled_name = NULL;
1231                 BlockList& blocks = sc.function->GetBlocks(false);
1232 
1233                 lldb::user_id_t blockID = blocks.AddChild(parentBlockID, die->GetOffset());
1234                 int decl_file = 0;
1235                 int decl_line = 0;
1236                 int decl_column = 0;
1237                 int call_file = 0;
1238                 int call_line = 0;
1239                 int call_column = 0;
1240                 if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column))
1241                 {
1242                     if (tag == DW_TAG_subprogram)
1243                     {
1244                         assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1245                         subprogram_low_pc = ranges.LowestAddress(0);
1246                     }
1247 
1248                     AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc);
1249 
1250                     if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1251                     {
1252                         std::auto_ptr<Declaration> decl_ap;
1253                         if (decl_file != 0 || decl_line != 0 || decl_column != 0)
1254                             decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
1255 
1256                         std::auto_ptr<Declaration> call_ap;
1257                         if (call_file != 0 || call_line != 0 || call_column != 0)
1258                             call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column));
1259 
1260                         blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get());
1261                     }
1262 
1263                     ++blocks_added;
1264 
1265                     if (parse_children && die->HasChildren())
1266                     {
1267                         blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true);
1268                     }
1269                 }
1270             }
1271             break;
1272         default:
1273             break;
1274         }
1275 
1276         if (parse_siblings)
1277             die = die->GetSibling();
1278         else
1279             die = NULL;
1280     }
1281     return blocks_added;
1282 }
1283 
1284 size_t
1285 SymbolFileDWARF::ParseChildMembers
1286 (
1287     const SymbolContext& sc,
1288     TypeSP& type_sp,
1289     const DWARFCompileUnit* dwarf_cu,
1290     const DWARFDebugInfoEntry *parent_die,
1291     std::vector<clang::CXXBaseSpecifier *>& base_classes,
1292     std::vector<int>& member_accessibilities,
1293     int& default_accessibility,
1294     bool &is_a_class
1295 )
1296 {
1297     if (parent_die == NULL)
1298         return 0;
1299 
1300     TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1301 
1302     size_t count = 0;
1303     const DWARFDebugInfoEntry *die;
1304     for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1305     {
1306         dw_tag_t tag = die->Tag();
1307 
1308         switch (tag)
1309         {
1310         case DW_TAG_member:
1311             {
1312                 DWARFDebugInfoEntry::Attributes attributes;
1313                 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1314                 if (num_attributes > 0)
1315                 {
1316                     Declaration decl;
1317                     DWARFExpression location;
1318                     const char *name = NULL;
1319                     lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1320                     uint32_t accessibility = clang::AS_none;
1321                     off_t member_offset = 0;
1322                     size_t byte_size = 0;
1323                     size_t bit_offset = 0;
1324                     size_t bit_size = 0;
1325                     uint32_t i;
1326                     for (i=0; i<num_attributes; ++i)
1327                     {
1328                         const dw_attr_t attr = attributes.AttributeAtIndex(i);
1329                         DWARFFormValue form_value;
1330                         if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1331                         {
1332                             switch (attr)
1333                             {
1334                             case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1335                             case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1336                             case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1337                             case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
1338                             case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1339                             case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break;
1340                             case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break;
1341                             case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
1342                             case DW_AT_data_member_location:
1343                                 if (form_value.BlockData())
1344                                 {
1345                                     Value initialValue(0);
1346                                     Value memberOffset(0);
1347                                     const DataExtractor& debug_info_data = get_debug_info_data();
1348                                     uint32_t block_length = form_value.Unsigned();
1349                                     uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1350                                     if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1351                                     {
1352                                         member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1353                                     }
1354                                 }
1355                                 break;
1356 
1357                             case DW_AT_accessibility: accessibility = DwarfToClangAccessibility (form_value.Unsigned()); break;
1358                             case DW_AT_declaration:
1359                             case DW_AT_description:
1360                             case DW_AT_mutable:
1361                             case DW_AT_visibility:
1362                             default:
1363                             case DW_AT_sibling:
1364                                 break;
1365                             }
1366                         }
1367                     }
1368 
1369                     Type *member_type = ResolveTypeUID(encoding_uid);
1370                     assert(member_type);
1371                     if (accessibility == clang::AS_none)
1372                         accessibility = default_accessibility;
1373                     member_accessibilities.push_back(accessibility);
1374 
1375                     type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size);
1376                 }
1377             }
1378             break;
1379 
1380         case DW_TAG_subprogram:
1381             {
1382                 is_a_class = true;
1383                 if (default_accessibility == clang::AS_none)
1384                     default_accessibility = clang::AS_private;
1385                 // TODO: implement DW_TAG_subprogram type parsing
1386 //              UserDefTypeChildInfo method_info(die->GetOffset());
1387 //
1388 //              FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset()));
1389 //              if (func_sp.get() == NULL)
1390 //                  ParseCompileUnitFunction(sc, dwarf_cu, die);
1391 //
1392 //              method_info.SetEncodingTypeUID(die->GetOffset());
1393 //              struct_udt->AddMethod(method_info);
1394             }
1395             break;
1396 
1397         case DW_TAG_inheritance:
1398             {
1399                 is_a_class = true;
1400                 if (default_accessibility == clang::AS_none)
1401                     default_accessibility = clang::AS_private;
1402                 // TODO: implement DW_TAG_inheritance type parsing
1403                 DWARFDebugInfoEntry::Attributes attributes;
1404                 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1405                 if (num_attributes > 0)
1406                 {
1407                     Declaration decl;
1408                     DWARFExpression location;
1409                     lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1410                     uint32_t accessibility = default_accessibility;
1411                     bool is_virtual = false;
1412                     bool is_base_of_class = true;
1413                     off_t member_offset = 0;
1414                     uint32_t i;
1415                     for (i=0; i<num_attributes; ++i)
1416                     {
1417                         const dw_attr_t attr = attributes.AttributeAtIndex(i);
1418                         DWARFFormValue form_value;
1419                         if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1420                         {
1421                             switch (attr)
1422                             {
1423                             case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1424                             case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1425                             case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1426                             case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1427                             case DW_AT_data_member_location:
1428                                 if (form_value.BlockData())
1429                                 {
1430                                     Value initialValue(0);
1431                                     Value memberOffset(0);
1432                                     const DataExtractor& debug_info_data = get_debug_info_data();
1433                                     uint32_t block_length = form_value.Unsigned();
1434                                     uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1435                                     if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1436                                     {
1437                                         member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1438                                     }
1439                                 }
1440                                 break;
1441 
1442                             case DW_AT_accessibility:
1443                                 accessibility = DwarfToClangAccessibility(form_value.Unsigned());
1444                                 break;
1445 
1446                             case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1447                             default:
1448                             case DW_AT_sibling:
1449                                 break;
1450                             }
1451                         }
1452                     }
1453 
1454                     Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1455                     assert(base_class_dctype);
1456                     base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class));
1457                     assert(base_classes.back());
1458                 }
1459             }
1460             break;
1461 
1462         default:
1463             break;
1464         }
1465     }
1466     return count;
1467 }
1468 
1469 
1470 clang::DeclContext*
1471 SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1472 {
1473     DWARFDebugInfo* debug_info = DebugInfo();
1474     if (debug_info)
1475     {
1476         DWARFCompileUnitSP cu_sp;
1477         const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1478         if (die)
1479             return GetClangDeclContextForDIE (cu_sp.get(), die);
1480     }
1481     return NULL;
1482 }
1483 
1484 Type*
1485 SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid)
1486 {
1487     DWARFDebugInfo* debug_info = DebugInfo();
1488     if (debug_info)
1489     {
1490         const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL);
1491         if (type_die != NULL)
1492         {
1493             void *type = type_die->GetUserData();
1494             if (type == NULL)
1495             {
1496                 DWARFCompileUnitSP cu_sp;
1497                 const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1498                 if (die != NULL)
1499                 {
1500                     TypeSP owning_type_sp;
1501                     TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0));
1502                 }
1503                 type = type_die->GetUserData();
1504             }
1505             if (type != DIE_IS_BEING_PARSED)
1506                 return (Type *)type;
1507         }
1508     }
1509     return NULL;
1510 }
1511 
1512 CompileUnit*
1513 SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx)
1514 {
1515     // Check if the symbol vendor already knows about this compile unit?
1516     if (cu->GetUserData() == NULL)
1517     {
1518         // The symbol vendor doesn't know about this compile unit, we
1519         // need to parse and add it to the symbol vendor object.
1520         CompUnitSP dc_cu;
1521         ParseCompileUnit(cu, dc_cu);
1522         if (dc_cu.get())
1523         {
1524             // Figure out the compile unit index if we weren't given one
1525             if (cu_idx == UINT_MAX)
1526                 DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
1527 
1528             m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
1529         }
1530     }
1531     return (CompileUnit*)cu->GetUserData();
1532 }
1533 
1534 bool
1535 SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1536 {
1537     sc.Clear();
1538     // Check if the symbol vendor already knows about this compile unit?
1539     sc.module_sp = m_obj_file->GetModule()->GetSP();
1540     sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1541 
1542     sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1543     if (sc.function == NULL)
1544         sc.function = ParseCompileUnitFunction(sc, cu, func_die);
1545 
1546     return sc.function != NULL;
1547 }
1548 
1549 uint32_t
1550 SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1551 {
1552     Timer scoped_timer(__PRETTY_FUNCTION__,
1553                        "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1554                        so_addr.GetSection(),
1555                        so_addr.GetOffset(),
1556                        resolve_scope);
1557     uint32_t resolved = 0;
1558     if (resolve_scope & (   eSymbolContextCompUnit |
1559                             eSymbolContextFunction |
1560                             eSymbolContextBlock |
1561                             eSymbolContextLineEntry))
1562     {
1563         lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1564 
1565         DWARFDebugAranges* debug_aranges = DebugAranges();
1566         DWARFDebugInfo* debug_info = DebugInfo();
1567         if (debug_aranges)
1568         {
1569             dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1570             if (cu_offset != DW_INVALID_OFFSET)
1571             {
1572                 uint32_t cu_idx;
1573                 DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1574                 if (cu)
1575                 {
1576                     sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1577                     assert(sc.comp_unit != NULL);
1578                     resolved |= eSymbolContextCompUnit;
1579 
1580                     if (resolve_scope & eSymbolContextLineEntry)
1581                     {
1582                         LineTable *line_table = sc.comp_unit->GetLineTable();
1583                         if (line_table == NULL)
1584                         {
1585                             if (ParseCompileUnitLineTable(sc))
1586                                 line_table = sc.comp_unit->GetLineTable();
1587                         }
1588                         if (line_table != NULL)
1589                         {
1590                             if (so_addr.IsLinkedAddress())
1591                             {
1592                                 Address linked_addr (so_addr);
1593                                 linked_addr.ResolveLinkedAddress();
1594                                 if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1595                                 {
1596                                     resolved |= eSymbolContextLineEntry;
1597                                 }
1598                             }
1599                             else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1600                             {
1601                                 resolved |= eSymbolContextLineEntry;
1602                             }
1603                         }
1604                     }
1605 
1606                     if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1607                     {
1608                         DWARFDebugInfoEntry *function_die = NULL;
1609                         DWARFDebugInfoEntry *block_die = NULL;
1610                         if (resolve_scope & eSymbolContextBlock)
1611                         {
1612                             cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1613                         }
1614                         else
1615                         {
1616                             cu->LookupAddress(file_vm_addr, &function_die, NULL);
1617                         }
1618 
1619                         if (function_die != NULL)
1620                         {
1621                             sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1622                             if (sc.function == NULL)
1623                                 sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1624                         }
1625 
1626                         if (sc.function != NULL)
1627                         {
1628                             resolved |= eSymbolContextFunction;
1629 
1630                             if (resolve_scope & eSymbolContextBlock)
1631                             {
1632                                 BlockList& blocks = sc.function->GetBlocks(true);
1633 
1634                                 if (block_die != NULL)
1635                                     sc.block = blocks.GetBlockByID(block_die->GetOffset());
1636                                 else
1637                                     sc.block = blocks.GetBlockByID(function_die->GetOffset());
1638                                 if (sc.block)
1639                                     resolved |= eSymbolContextBlock;
1640                             }
1641                         }
1642                     }
1643                 }
1644             }
1645         }
1646     }
1647     return resolved;
1648 }
1649 
1650 
1651 
1652 uint32_t
1653 SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1654 {
1655     const uint32_t prev_size = sc_list.GetSize();
1656     if (resolve_scope & eSymbolContextCompUnit)
1657     {
1658         DWARFDebugInfo* debug_info = DebugInfo();
1659         if (debug_info)
1660         {
1661             uint32_t cu_idx;
1662             DWARFCompileUnit* cu = NULL;
1663 
1664             for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1665             {
1666                 CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1667                 bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1668                 if (check_inlines || file_spec_matches_cu_file_spec)
1669                 {
1670                     SymbolContext sc (m_obj_file->GetModule());
1671                     sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1672                     assert(sc.comp_unit != NULL);
1673 
1674                     uint32_t file_idx = UINT32_MAX;
1675 
1676                     // If we are looking for inline functions only and we don't
1677                     // find it in the support files, we are done.
1678                     if (check_inlines)
1679                     {
1680                         file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1681                         if (file_idx == UINT32_MAX)
1682                             continue;
1683                     }
1684 
1685                     if (line != 0)
1686                     {
1687                         LineTable *line_table = sc.comp_unit->GetLineTable();
1688 
1689                         if (line_table != NULL && line != 0)
1690                         {
1691                             // We will have already looked up the file index if
1692                             // we are searching for inline entries.
1693                             if (!check_inlines)
1694                                 file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1695 
1696                             if (file_idx != UINT32_MAX)
1697                             {
1698                                 uint32_t found_line;
1699                                 uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1700                                 found_line = sc.line_entry.line;
1701 
1702                                 while (line_idx != UINT_MAX)
1703                                 {
1704                                     sc.function = NULL;
1705                                     sc.block = NULL;
1706                                     if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1707                                     {
1708                                         const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1709                                         if (file_vm_addr != LLDB_INVALID_ADDRESS)
1710                                         {
1711                                             DWARFDebugInfoEntry *function_die = NULL;
1712                                             DWARFDebugInfoEntry *block_die = NULL;
1713                                             cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1714 
1715                                             if (function_die != NULL)
1716                                             {
1717                                                 sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1718                                                 if (sc.function == NULL)
1719                                                     sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1720                                             }
1721 
1722                                             if (sc.function != NULL)
1723                                             {
1724                                                 BlockList& blocks = sc.function->GetBlocks(true);
1725 
1726                                                 if (block_die != NULL)
1727                                                     sc.block = blocks.GetBlockByID(block_die->GetOffset());
1728                                                 else
1729                                                     sc.block = blocks.GetBlockByID(function_die->GetOffset());
1730                                             }
1731                                         }
1732                                     }
1733 
1734                                     sc_list.Append(sc);
1735                                     line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1736                                 }
1737                             }
1738                         }
1739                         else if (file_spec_matches_cu_file_spec && !check_inlines)
1740                         {
1741                             // only append the context if we aren't looking for inline call sites
1742                             // by file and line and if the file spec matches that of the compile unit
1743                             sc_list.Append(sc);
1744                         }
1745                     }
1746                     else if (file_spec_matches_cu_file_spec && !check_inlines)
1747                     {
1748                         // only append the context if we aren't looking for inline call sites
1749                         // by file and line and if the file spec matches that of the compile unit
1750                         sc_list.Append(sc);
1751                     }
1752 
1753                     if (!check_inlines)
1754                         break;
1755                 }
1756             }
1757         }
1758     }
1759     return sc_list.GetSize() - prev_size;
1760 }
1761 
1762 void
1763 SymbolFileDWARF::Index ()
1764 {
1765     if (m_indexed)
1766         return;
1767     m_indexed = true;
1768     Timer scoped_timer (__PRETTY_FUNCTION__,
1769                         "SymbolFileDWARF::Index (%s)",
1770                         GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1771 
1772     DWARFDebugInfo* debug_info = DebugInfo();
1773     if (debug_info)
1774     {
1775         uint32_t cu_idx = 0;
1776         const uint32_t num_compile_units = GetNumCompileUnits();
1777         for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1778         {
1779             DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1780 
1781             bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
1782 
1783             cu->Index (m_base_name_to_function_die,
1784                        m_full_name_to_function_die,
1785                        m_method_name_to_function_die,
1786                        m_selector_name_to_function_die,
1787                        m_name_to_global_die,
1788                        m_name_to_type_die);
1789 
1790             // Keep memory down by clearing DIEs if this generate function
1791             // caused them to be parsed
1792             if (clear_dies)
1793                 cu->ClearDIEs (true);
1794         }
1795 
1796         m_base_name_to_function_die.Sort();
1797         m_full_name_to_function_die.Sort();
1798         m_method_name_to_function_die.Sort();
1799         m_selector_name_to_function_die.Sort();
1800         m_name_to_global_die.Sort();
1801         m_name_to_type_die.Sort();
1802     }
1803 }
1804 
1805 uint32_t
1806 SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1807 {
1808     std::vector<dw_offset_t> die_offsets;
1809 
1810     // If we aren't appending the results to this list, then clear the list
1811     if (!append)
1812         variables.Clear();
1813 
1814     // Remember how many variables are in the list before we search in case
1815     // we are appending the results to a variable list.
1816     const uint32_t original_size = variables.GetSize();
1817 
1818     // Index the DWARF if we haven't already
1819     if (!m_indexed)
1820         Index ();
1821 
1822     const UniqueCStringMap<dw_offset_t>::Entry *entry;
1823 
1824     for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString());
1825          entry != NULL;
1826          entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry))
1827     {
1828         DWARFCompileUnitSP cu_sp;
1829         const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1830         DWARFCompileUnit* cu = cu_sp.get();
1831         if (die)
1832         {
1833             SymbolContext sc;
1834             sc.module_sp = m_obj_file->GetModule()->GetSP();
1835             assert (sc.module_sp);
1836 
1837             sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1838             assert(sc.comp_unit != NULL);
1839 
1840             ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1841 
1842             if (variables.GetSize() - original_size >= max_matches)
1843                 break;
1844         }
1845     }
1846 
1847     // Return the number of variable that were appended to the list
1848     return variables.GetSize() - original_size;
1849 }
1850 
1851 uint32_t
1852 SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1853 {
1854     std::vector<dw_offset_t> die_offsets;
1855 
1856     // If we aren't appending the results to this list, then clear the list
1857     if (!append)
1858         variables.Clear();
1859 
1860     // Remember how many variables are in the list before we search in case
1861     // we are appending the results to a variable list.
1862     const uint32_t original_size = variables.GetSize();
1863 
1864     // Index the DWARF if we haven't already
1865     if (!m_indexed)
1866         Index ();
1867 
1868     // Create the pubnames information so we can quickly lookup external symbols by name
1869     const size_t num_entries = m_name_to_global_die.GetSize();
1870     for (size_t i=0; i<num_entries; i++)
1871     {
1872         if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i)))
1873             continue;
1874 
1875         const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i);
1876 
1877         DWARFCompileUnitSP cu_sp;
1878         const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1879         DWARFCompileUnit* cu = cu_sp.get();
1880         if (die)
1881         {
1882             SymbolContext sc;
1883             sc.module_sp = m_obj_file->GetModule()->GetSP();
1884             assert (sc.module_sp);
1885 
1886 
1887             sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1888             assert(sc.comp_unit != NULL);
1889 
1890             ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1891 
1892             if (variables.GetSize() - original_size >= max_matches)
1893                 break;
1894         }
1895     }
1896 
1897     // Return the number of variable that were appended to the list
1898     return variables.GetSize() - original_size;
1899 }
1900 
1901 
1902 void
1903 SymbolFileDWARF::FindFunctions
1904 (
1905     const ConstString &name,
1906     UniqueCStringMap<dw_offset_t> &name_to_die,
1907     SymbolContextList& sc_list
1908 )
1909 {
1910     const UniqueCStringMap<dw_offset_t>::Entry *entry;
1911 
1912     SymbolContext sc;
1913     for (entry = name_to_die.FindFirstValueForName (name.AsCString());
1914          entry != NULL;
1915          entry = name_to_die.FindNextValueForName (name.AsCString(), entry))
1916     {
1917         DWARFCompileUnitSP cu_sp;
1918         const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1919         if (die)
1920         {
1921             if (GetFunction (cu_sp.get(), die, sc))
1922             {
1923                 // We found the function, so we should find the line table
1924                 // and line table entry as well
1925                 LineTable *line_table = sc.comp_unit->GetLineTable();
1926                 if (line_table == NULL)
1927                 {
1928                     if (ParseCompileUnitLineTable(sc))
1929                         line_table = sc.comp_unit->GetLineTable();
1930                 }
1931                 if (line_table != NULL)
1932                     line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1933 
1934                 sc_list.Append(sc);
1935             }
1936         }
1937     }
1938 
1939 }
1940 
1941 uint32_t
1942 SymbolFileDWARF::FindFunctions
1943 (
1944     const ConstString &name,
1945     uint32_t name_type_mask,
1946     bool append,
1947     SymbolContextList& sc_list
1948 )
1949 {
1950     Timer scoped_timer (__PRETTY_FUNCTION__,
1951                         "SymbolFileDWARF::FindFunctions (name = '%s')",
1952                         name.AsCString());
1953 
1954     std::vector<dw_offset_t> die_offsets;
1955 
1956     // If we aren't appending the results to this list, then clear the list
1957     if (!append)
1958         sc_list.Clear();
1959 
1960     // Remember how many sc_list are in the list before we search in case
1961     // we are appending the results to a variable list.
1962     uint32_t original_size = sc_list.GetSize();
1963 
1964     // Index the DWARF if we haven't already
1965     if (!m_indexed)
1966         Index ();
1967 
1968     if (name_type_mask & eFunctionNameTypeBase)
1969         FindFunctions (name, m_base_name_to_function_die, sc_list);
1970 
1971     if (name_type_mask & eFunctionNameTypeFull)
1972         FindFunctions (name, m_full_name_to_function_die, sc_list);
1973 
1974     if (name_type_mask & eFunctionNameTypeMethod)
1975         FindFunctions (name, m_method_name_to_function_die, sc_list);
1976 
1977     if (name_type_mask & eFunctionNameTypeSelector)
1978         FindFunctions (name, m_selector_name_to_function_die, sc_list);
1979 
1980     // Return the number of variable that were appended to the list
1981     return sc_list.GetSize() - original_size;
1982 }
1983 
1984 
1985 uint32_t
1986 SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
1987 {
1988     Timer scoped_timer (__PRETTY_FUNCTION__,
1989                         "SymbolFileDWARF::FindFunctions (regex = '%s')",
1990                         regex.GetText());
1991 
1992     std::vector<dw_offset_t> die_offsets;
1993 
1994     // If we aren't appending the results to this list, then clear the list
1995     if (!append)
1996         sc_list.Clear();
1997 
1998     // Remember how many sc_list are in the list before we search in case
1999     // we are appending the results to a variable list.
2000     uint32_t original_size = sc_list.GetSize();
2001 
2002     // Index the DWARF if we haven't already
2003     if (!m_indexed)
2004         Index ();
2005 
2006     // Create the pubnames information so we can quickly lookup external symbols by name
2007     // Create the pubnames information so we can quickly lookup external symbols by name
2008     const size_t num_entries = m_full_name_to_function_die.GetSize();
2009     SymbolContext sc;
2010     for (size_t i=0; i<num_entries; i++)
2011     {
2012         if (!regex.Execute(m_full_name_to_function_die.GetCStringAtIndex (i)))
2013             continue;
2014 
2015         const dw_offset_t die_offset = *m_full_name_to_function_die.GetValueAtIndex (i);
2016 
2017         DWARFCompileUnitSP cu_sp;
2018         const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
2019         if (die)
2020         {
2021             if (GetFunction (cu_sp.get(), die, sc))
2022             {
2023                 // We found the function, so we should find the line table
2024                 // and line table entry as well
2025                 LineTable *line_table = sc.comp_unit->GetLineTable();
2026                 if (line_table == NULL)
2027                 {
2028                     if (ParseCompileUnitLineTable(sc))
2029                         line_table = sc.comp_unit->GetLineTable();
2030                 }
2031                 if (line_table != NULL)
2032                     line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
2033 
2034 
2035                 sc_list.Append(sc);
2036             }
2037         }
2038     }
2039 
2040     // Return the number of variable that were appended to the list
2041     return sc_list.GetSize() - original_size;
2042 }
2043 
2044 #if 0
2045 uint32_t
2046 SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
2047 {
2048     // If we aren't appending the results to this list, then clear the list
2049     if (!append)
2050         types.Clear();
2051 
2052     // Create the pubnames information so we can quickly lookup external symbols by name
2053     DWARFDebugPubnames* pubtypes = DebugPubtypes();
2054     if (pubtypes)
2055     {
2056         std::vector<dw_offset_t> die_offsets;
2057         if (!pubtypes->Find(name.AsCString(), false, die_offsets))
2058         {
2059             DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
2060             if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets))
2061                 return 0;
2062         }
2063         return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
2064     }
2065     return 0;
2066 }
2067 
2068 
2069 uint32_t
2070 SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
2071 {
2072     // If we aren't appending the results to this list, then clear the list
2073     if (!append)
2074         types.Clear();
2075 
2076     // Create the pubnames information so we can quickly lookup external symbols by name
2077     DWARFDebugPubnames* pubtypes = DebugPubtypes();
2078     if (pubtypes)
2079     {
2080         std::vector<dw_offset_t> die_offsets;
2081         if (!pubtypes->Find(regex, die_offsets))
2082         {
2083             DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
2084             if (pub_base_types && !pub_base_types->Find(regex, die_offsets))
2085                 return 0;
2086         }
2087 
2088         return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
2089     }
2090 
2091     return 0;
2092 }
2093 
2094 
2095 
2096 uint32_t
2097 SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
2098 {
2099     // Remember how many sc_list are in the list before we search in case
2100     // we are appending the results to a variable list.
2101     uint32_t original_size = types.Size();
2102 
2103     const uint32_t num_die_offsets = die_offsets.size();
2104     // Parse all of the types we found from the pubtypes matches
2105     uint32_t i;
2106     uint32_t num_matches = 0;
2107     for (i = 0; i < num_die_offsets; ++i)
2108     {
2109         dw_offset_t die_offset = die_offsets[i];
2110         DWARFCompileUnitSP cu_sp;
2111         const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2112 
2113         assert(die != NULL);
2114 
2115         bool get_type_for_die = true;
2116         if (encoding)
2117         {
2118             // Check if this type has already been uniqued and registers with the module?
2119             Type* type = (Type*)die->GetUserData();
2120             if (type != NULL && type != DIE_IS_BEING_PARSED)
2121             {
2122                 get_type_for_die = type->GetEncoding() == encoding;
2123             }
2124             else
2125             {
2126                 dw_tag_t tag = die->Tag();
2127                 switch (encoding)
2128                 {
2129                 case Type::address:
2130                 case Type::boolean:
2131                 case Type::complex_float:
2132                 case Type::float_type:
2133                 case Type::signed_int:
2134                 case Type::signed_char:
2135                 case Type::unsigned_int:
2136                 case Type::unsigned_char:
2137                 case Type::imaginary_float:
2138                 case Type::packed_decimal:
2139                 case Type::numeric_string:
2140                 case Type::edited_string:
2141                 case Type::signed_fixed:
2142                 case Type::unsigned_fixed:
2143                 case Type::decimal_float:
2144                     if (tag != DW_TAG_base_type)
2145                         get_type_for_die = false;
2146                     else
2147                     {
2148                         if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding)
2149                             get_type_for_die = false;
2150                     }
2151                     break;
2152 
2153                 case Type::indirect_const:      get_type_for_die = tag == DW_TAG_const_type; break;
2154                 case Type::indirect_restrict:       get_type_for_die = tag == DW_TAG_restrict_type; break;
2155                 case Type::indirect_volatile:       get_type_for_die = tag == DW_TAG_volatile_type; break;
2156                 case Type::indirect_typedef:        get_type_for_die = tag == DW_TAG_typedef; break;
2157                 case Type::indirect_pointer:        get_type_for_die = tag == DW_TAG_pointer_type; break;
2158                 case Type::indirect_reference:  get_type_for_die = tag == DW_TAG_reference_type; break;
2159 
2160                 case Type::user_defined_type:
2161                     switch (tag)
2162                     {
2163                     case DW_TAG_array_type:
2164                         get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid);
2165                         break;
2166 
2167                     case DW_TAG_structure_type:
2168                     case DW_TAG_union_type:
2169                     case DW_TAG_class_type:
2170                         get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid);
2171                         break;
2172 
2173                     case DW_TAG_enumeration_type:
2174                         get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid);
2175                         break;
2176 
2177                     case DW_TAG_subprogram:
2178                     case DW_TAG_subroutine_type:
2179                         get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid);
2180                         break;
2181                     }
2182                 }
2183             }
2184         }
2185 
2186         if (get_type_for_die)
2187         {
2188             TypeSP owning_type_sp;
2189             TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0));
2190 
2191             if (type_sp.get())
2192             {
2193                 // See if we are filtering results based on encoding?
2194                 bool add_type = (encoding == Type::invalid);
2195                 if (!add_type)
2196                 {
2197                     // We are filtering base on encoding, so lets check the resulting type encoding
2198                     add_type = (encoding == type_sp->GetEncoding());
2199                     if (add_type)
2200                     {
2201                         // The type encoding matches, if this is a user defined type, lets
2202                         // make sure the exact user define type uid matches if one was provided
2203                         if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID)
2204                         {
2205                             UserDefType* udt = type_sp->GetUserDefinedType().get();
2206                             if (udt)
2207                                 add_type = udt->UserDefinedTypeUID() == udt_uid;
2208                         }
2209                     }
2210                 }
2211                 // Add the type to our list as long as everything matched
2212                 if (add_type)
2213                 {
2214                     types.InsertUnique(type_sp);
2215                     if (++num_matches >= max_matches)
2216                         break;
2217                 }
2218             }
2219         }
2220     }
2221 
2222     // Return the number of variable that were appended to the list
2223     return types.Size() - original_size;
2224 }
2225 
2226 #endif
2227 
2228 
2229 size_t
2230 SymbolFileDWARF::ParseChildParameters
2231 (
2232     const SymbolContext& sc,
2233     TypeSP& type_sp,
2234     const DWARFCompileUnit* dwarf_cu,
2235     const DWARFDebugInfoEntry *parent_die,
2236     TypeList* type_list,
2237     std::vector<void *>& function_param_types,
2238     std::vector<clang::ParmVarDecl*>& function_param_decls
2239 )
2240 {
2241     if (parent_die == NULL)
2242         return 0;
2243 
2244     size_t count = 0;
2245     const DWARFDebugInfoEntry *die;
2246     for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2247     {
2248         dw_tag_t tag = die->Tag();
2249         switch (tag)
2250         {
2251         case DW_TAG_formal_parameter:
2252             {
2253                 DWARFDebugInfoEntry::Attributes attributes;
2254                 const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2255                 if (num_attributes > 0)
2256                 {
2257                     const char *name = NULL;
2258                     Declaration decl;
2259                     dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
2260                     // one of None, Auto, Register, Extern, Static, PrivateExtern
2261 
2262                     clang::VarDecl::StorageClass storage = clang::VarDecl::None;
2263                     uint32_t i;
2264                     for (i=0; i<num_attributes; ++i)
2265                     {
2266                         const dw_attr_t attr = attributes.AttributeAtIndex(i);
2267                         DWARFFormValue form_value;
2268                         if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2269                         {
2270                             switch (attr)
2271                             {
2272                             case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2273                             case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2274                             case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2275                             case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
2276                             case DW_AT_type:        param_type_die_offset = form_value.Reference(dwarf_cu); break;
2277                             case DW_AT_location:
2278     //                          if (form_value.BlockData())
2279     //                          {
2280     //                              const DataExtractor& debug_info_data = debug_info();
2281     //                              uint32_t block_length = form_value.Unsigned();
2282     //                              DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2283     //                          }
2284     //                          else
2285     //                          {
2286     //                          }
2287     //                          break;
2288                             case DW_AT_artificial:
2289                             case DW_AT_const_value:
2290                             case DW_AT_default_value:
2291                             case DW_AT_description:
2292                             case DW_AT_endianity:
2293                             case DW_AT_is_optional:
2294                             case DW_AT_segment:
2295                             case DW_AT_variable_parameter:
2296                             default:
2297                             case DW_AT_abstract_origin:
2298                             case DW_AT_sibling:
2299                                 break;
2300                             }
2301                         }
2302                     }
2303                     Type *dc_type = ResolveTypeUID(param_type_die_offset);
2304                     if (dc_type)
2305                     {
2306                         function_param_types.push_back (dc_type->GetOpaqueClangQualType());
2307 
2308                         clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage);
2309                         assert(param_var_decl);
2310                         function_param_decls.push_back(param_var_decl);
2311                     }
2312                 }
2313             }
2314             break;
2315 
2316         default:
2317             break;
2318         }
2319     }
2320     return count;
2321 }
2322 
2323 size_t
2324 SymbolFileDWARF::ParseChildEnumerators
2325 (
2326     const SymbolContext& sc,
2327     TypeSP& type_sp,
2328     void * enumerator_qual_type,
2329     uint32_t enumerator_byte_size,
2330     const DWARFCompileUnit* dwarf_cu,
2331     const DWARFDebugInfoEntry *parent_die
2332 )
2333 {
2334     if (parent_die == NULL)
2335         return 0;
2336 
2337     size_t enumerators_added = 0;
2338     const DWARFDebugInfoEntry *die;
2339     for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2340     {
2341         const dw_tag_t tag = die->Tag();
2342         if (tag == DW_TAG_enumerator)
2343         {
2344             DWARFDebugInfoEntry::Attributes attributes;
2345             const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2346             if (num_child_attributes > 0)
2347             {
2348                 const char *name = NULL;
2349                 bool got_value = false;
2350                 int64_t enum_value = 0;
2351                 Declaration decl;
2352 
2353                 uint32_t i;
2354                 for (i=0; i<num_child_attributes; ++i)
2355                 {
2356                     const dw_attr_t attr = attributes.AttributeAtIndex(i);
2357                     DWARFFormValue form_value;
2358                     if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2359                     {
2360                         switch (attr)
2361                         {
2362                         case DW_AT_const_value:
2363                             got_value = true;
2364                             enum_value = form_value.Unsigned();
2365                             break;
2366 
2367                         case DW_AT_name:
2368                             name = form_value.AsCString(&get_debug_str_data());
2369                             break;
2370 
2371                         case DW_AT_description:
2372                         default:
2373                         case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2374                         case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2375                         case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2376                         case DW_AT_sibling:
2377                             break;
2378                         }
2379                     }
2380                 }
2381 
2382                 if (name && name[0] && got_value)
2383                 {
2384                     TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2385                     type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8);
2386                     ++enumerators_added;
2387                 }
2388             }
2389         }
2390     }
2391     return enumerators_added;
2392 }
2393 
2394 void
2395 SymbolFileDWARF::ParseChildArrayInfo
2396 (
2397     const SymbolContext& sc,
2398     const DWARFCompileUnit* dwarf_cu,
2399     const DWARFDebugInfoEntry *parent_die,
2400     int64_t& first_index,
2401     std::vector<uint64_t>& element_orders,
2402     uint32_t& byte_stride,
2403     uint32_t& bit_stride
2404 )
2405 {
2406     if (parent_die == NULL)
2407         return;
2408 
2409     const DWARFDebugInfoEntry *die;
2410     for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2411     {
2412         const dw_tag_t tag = die->Tag();
2413         switch (tag)
2414         {
2415         case DW_TAG_enumerator:
2416             {
2417                 DWARFDebugInfoEntry::Attributes attributes;
2418                 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2419                 if (num_child_attributes > 0)
2420                 {
2421                     const char *name = NULL;
2422                     bool got_value = false;
2423                     int64_t enum_value = 0;
2424 
2425                     uint32_t i;
2426                     for (i=0; i<num_child_attributes; ++i)
2427                     {
2428                         const dw_attr_t attr = attributes.AttributeAtIndex(i);
2429                         DWARFFormValue form_value;
2430                         if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2431                         {
2432                             switch (attr)
2433                             {
2434                             case DW_AT_const_value:
2435                                 got_value = true;
2436                                 enum_value = form_value.Unsigned();
2437                                 break;
2438 
2439                             case DW_AT_name:
2440                                 name = form_value.AsCString(&get_debug_str_data());
2441                                 break;
2442 
2443                             case DW_AT_description:
2444                             default:
2445                             case DW_AT_decl_file:
2446                             case DW_AT_decl_line:
2447                             case DW_AT_decl_column:
2448                             case DW_AT_sibling:
2449                                 break;
2450                             }
2451                         }
2452                     }
2453                 }
2454             }
2455             break;
2456 
2457         case DW_TAG_subrange_type:
2458             {
2459                 DWARFDebugInfoEntry::Attributes attributes;
2460                 const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2461                 if (num_child_attributes > 0)
2462                 {
2463                     const char *name = NULL;
2464                     bool got_value = false;
2465                     uint64_t byte_size = 0;
2466                     int64_t enum_value = 0;
2467                     uint64_t num_elements = 0;
2468                     uint64_t lower_bound = 0;
2469                     uint64_t upper_bound = 0;
2470                     uint32_t i;
2471                     for (i=0; i<num_child_attributes; ++i)
2472                     {
2473                         const dw_attr_t attr = attributes.AttributeAtIndex(i);
2474                         DWARFFormValue form_value;
2475                         if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2476                         {
2477                             switch (attr)
2478                             {
2479                             case DW_AT_const_value:
2480                                 got_value = true;
2481                                 enum_value = form_value.Unsigned();
2482                                 break;
2483 
2484                             case DW_AT_name:
2485                                 name = form_value.AsCString(&get_debug_str_data());
2486                                 break;
2487 
2488                             case DW_AT_count:
2489                                 num_elements = form_value.Unsigned();
2490                                 break;
2491 
2492                             case DW_AT_bit_stride:
2493                                 bit_stride = form_value.Unsigned();
2494                                 break;
2495 
2496                             case DW_AT_byte_stride:
2497                                 byte_stride = form_value.Unsigned();
2498                                 break;
2499 
2500                             case DW_AT_byte_size:
2501                                 byte_size = form_value.Unsigned();
2502                                 break;
2503 
2504                             case DW_AT_lower_bound:
2505                                 lower_bound = form_value.Unsigned();
2506                                 break;
2507 
2508                             case DW_AT_upper_bound:
2509                                 upper_bound = form_value.Unsigned();
2510                                 break;
2511 
2512                             default:
2513                                 //printf("0x%8.8x: %-30s skipping attribute at 0x%8.8x: %s\n", die->GetOffset(), DW_TAG_value_to_name(tag), attributes.die_offsets[i], DW_AT_value_to_name(attr));  // remove this, debug only
2514 
2515                             case DW_AT_abstract_origin:
2516                             case DW_AT_accessibility:
2517                             case DW_AT_allocated:
2518                             case DW_AT_associated:
2519                             case DW_AT_data_location:
2520                             case DW_AT_declaration:
2521                             case DW_AT_description:
2522                             case DW_AT_sibling:
2523                             case DW_AT_threads_scaled:
2524                             case DW_AT_type:
2525                             case DW_AT_visibility:
2526                                 break;
2527                             }
2528                         }
2529                     }
2530 
2531                     if (upper_bound > lower_bound)
2532                         num_elements = upper_bound - lower_bound + 1;
2533 
2534                     if (num_elements > 0)
2535                         element_orders.push_back (num_elements);
2536                 }
2537             }
2538             break;
2539         }
2540     }
2541 }
2542 
2543 Type*
2544 SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe)
2545 {
2546     if (type_die_offset != DW_INVALID_OFFSET)
2547     {
2548         DWARFCompileUnitSP cu_sp;
2549         const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp);
2550         assert(type_die != NULL);
2551         GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx);
2552         // Return the uniqued type if there is one
2553         Type* type = (Type*)type_die->GetUserData();
2554         if (type == DIE_IS_BEING_PARSED && safe)
2555             return NULL;
2556         return type;
2557     }
2558     return NULL;
2559 }
2560 
2561 TypeSP
2562 SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx)
2563 {
2564     TypeSP type_sp;
2565     if (die != NULL)
2566     {
2567         assert(cu != NULL);
2568         Type *type_ptr = (Type *)die->GetUserData();
2569         if (type_ptr == NULL)
2570         {
2571             SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
2572             bool type_is_new = false;
2573             type_sp = ParseType(sc, cu, die, type_is_new);
2574             type_ptr = (Type *)die->GetUserData();
2575             if (owning_type_sp.get() == NULL)
2576                 owning_type_sp = type_sp;
2577         }
2578         else if (type_ptr != DIE_IS_BEING_PARSED)
2579         {
2580             // Grab the existing type from the master types lists
2581             type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
2582         }
2583 
2584     }
2585     return type_sp;
2586 }
2587 
2588 clang::DeclContext *
2589 SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2590 {
2591     if (die_offset != DW_INVALID_OFFSET)
2592     {
2593         DWARFCompileUnitSP cu_sp;
2594         const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2595         return GetClangDeclContextForDIE (cu_sp.get(), die);
2596     }
2597     return NULL;
2598 }
2599 
2600 
2601 
2602 clang::DeclContext *
2603 SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
2604 {
2605     DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2606     if (pos != m_die_to_decl_ctx.end())
2607         return pos->second;
2608 
2609     while (die != NULL)
2610     {
2611         switch (die->Tag())
2612         {
2613         case DW_TAG_namespace:
2614             {
2615                 const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
2616                 if (namespace_name)
2617                 {
2618                     TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2619                     assert(type_list);
2620                     Declaration decl;   // TODO: fill in the decl object
2621                     clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
2622                     if (namespace_decl)
2623                         m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2624                     return namespace_decl;
2625                 }
2626             }
2627             break;
2628 
2629         default:
2630             break;
2631         }
2632         clang::DeclContext *decl_ctx;
2633         decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
2634         if (decl_ctx)
2635             return decl_ctx;
2636 
2637         decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2638         if (decl_ctx)
2639             return decl_ctx;
2640 
2641         die = die->GetParent();
2642     }
2643     return NULL;
2644 }
2645 
2646 TypeSP
2647 SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new)
2648 {
2649     TypeSP type_sp;
2650 
2651     uint32_t accessibility = clang::AS_none;
2652     if (die != NULL)
2653     {
2654         dw_tag_t tag = die->Tag();
2655         if (die->GetUserData() == NULL)
2656         {
2657             type_is_new = true;
2658 
2659             bool is_forward_declaration = false;
2660             DWARFDebugInfoEntry::Attributes attributes;
2661             const char *type_name_cstr = NULL;
2662             ConstString type_name_dbstr;
2663             Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID;
2664             void *clang_type = NULL;
2665 
2666             TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2667             dw_attr_t attr;
2668 
2669             switch (tag)
2670             {
2671             case DW_TAG_base_type:
2672             case DW_TAG_pointer_type:
2673             case DW_TAG_reference_type:
2674             case DW_TAG_typedef:
2675             case DW_TAG_const_type:
2676             case DW_TAG_restrict_type:
2677             case DW_TAG_volatile_type:
2678                 {
2679                     //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2680                     // Set a bit that lets us know that we are currently parsing this
2681                     const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2682 
2683                     const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2684                     Declaration decl;
2685                     uint32_t encoding = 0;
2686                     size_t byte_size = 0;
2687                     lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2688 
2689                     if (num_attributes > 0)
2690                     {
2691                         uint32_t i;
2692                         for (i=0; i<num_attributes; ++i)
2693                         {
2694                             attr = attributes.AttributeAtIndex(i);
2695                             DWARFFormValue form_value;
2696                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2697                             {
2698                                 switch (attr)
2699                                 {
2700                                 case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2701                                 case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2702                                 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2703                                 case DW_AT_name:
2704                                     type_name_cstr = form_value.AsCString(&get_debug_str_data());
2705                                     type_name_dbstr.SetCString(type_name_cstr);
2706                                     break;
2707                                 case DW_AT_byte_size:   byte_size = form_value.Unsigned();  break;
2708                                 case DW_AT_encoding:    encoding = form_value.Unsigned(); break;
2709                                 case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
2710                                 default:
2711                                 case DW_AT_sibling:
2712                                     break;
2713                                 }
2714                             }
2715                         }
2716                     }
2717 
2718                     switch (tag)
2719                     {
2720                     default:
2721                     case DW_TAG_base_type:
2722                         clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8);
2723                         break;
2724 
2725                     case DW_TAG_pointer_type:
2726                         // The encoding_uid will be embedded into the
2727                         // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2728                         encoding_uid_type = Type::ePointerToTypeWithUID;
2729                         break;
2730 
2731                     case DW_TAG_reference_type:
2732                         // The encoding_uid will be embedded into the
2733                         // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2734                         encoding_uid_type = Type::eLValueReferenceToTypeWithUID;
2735                         break;
2736 
2737                     case DW_TAG_typedef:
2738                         // The encoding_uid will be embedded into the
2739                         // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2740                         encoding_uid_type = Type::eTypedefToTypeWithUID;
2741                         break;
2742 
2743                     case DW_TAG_const_type:
2744                         // The encoding_uid will be embedded into the
2745                         // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2746                         encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type);
2747                         break;
2748 
2749                     case DW_TAG_restrict_type:
2750                         // The encoding_uid will be embedded into the
2751                         // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2752                         encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type);
2753                         break;
2754 
2755                     case DW_TAG_volatile_type:
2756                         // The encoding_uid will be embedded into the
2757                         // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2758                         encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type);
2759                         break;
2760                     }
2761 
2762                     type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type));
2763 
2764                     const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2765 
2766 
2767 //                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2768 //                  if (encoding_type != NULL)
2769 //                  {
2770 //                      if (encoding_type != DIE_IS_BEING_PARSED)
2771 //                          type_sp->SetEncodingType(encoding_type);
2772 //                      else
2773 //                          m_indirect_fixups.push_back(type_sp.get());
2774 //                  }
2775                 }
2776                 break;
2777 
2778             case DW_TAG_structure_type:
2779             case DW_TAG_union_type:
2780             case DW_TAG_class_type:
2781                 {
2782                     //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2783                     // Set a bit that lets us know that we are currently parsing this
2784                     const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2785 
2786                     size_t byte_size = 0;
2787                     //bool struct_is_class = false;
2788                     Declaration decl;
2789                     const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2790                     if (num_attributes > 0)
2791                     {
2792                         uint32_t i;
2793                         for (i=0; i<num_attributes; ++i)
2794                         {
2795                             attr = attributes.AttributeAtIndex(i);
2796                             DWARFFormValue form_value;
2797                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2798                             {
2799                                 switch (attr)
2800                                 {
2801                                 case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2802                                 case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2803                                 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2804                                 case DW_AT_name:
2805                                     type_name_cstr = form_value.AsCString(&get_debug_str_data());
2806                                     type_name_dbstr.SetCString(type_name_cstr);
2807                                     break;
2808                                 case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
2809                                 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break; break;
2810                                 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2811                                 case DW_AT_allocated:
2812                                 case DW_AT_associated:
2813                                 case DW_AT_data_location:
2814                                 case DW_AT_description:
2815                                 case DW_AT_start_scope:
2816                                 case DW_AT_visibility:
2817                                 default:
2818                                 case DW_AT_sibling:
2819                                     break;
2820                                 }
2821                             }
2822                         }
2823                     }
2824 
2825                     int tag_decl_kind = -1;
2826                     int default_accessibility = clang::AS_none;
2827                     if (tag == DW_TAG_structure_type)
2828                     {
2829                         tag_decl_kind = clang::TTK_Struct;
2830                         default_accessibility = clang::AS_public;
2831                     }
2832                     else if (tag == DW_TAG_union_type)
2833                     {
2834                         tag_decl_kind = clang::TTK_Union;
2835                         default_accessibility = clang::AS_public;
2836                     }
2837                     else if (tag == DW_TAG_class_type)
2838                     {
2839                         tag_decl_kind = clang::TTK_Class;
2840                         default_accessibility = clang::AS_private;
2841                     }
2842 
2843                     assert (tag_decl_kind != -1);
2844                     clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die));
2845 
2846                     m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2847                     type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
2848 
2849                     const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2850 
2851 //                  assert(type_sp.get());
2852 //                  if (accessibility)
2853 //                      type_sp->SetAccess(accessibility);
2854 //
2855                     type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2856                     if (die->HasChildren())
2857                     {
2858                         std::vector<clang::CXXBaseSpecifier *> base_classes;
2859                         std::vector<int> member_accessibilities;
2860                         bool is_a_class = false;
2861                         ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class);
2862                         // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2863                         // need to tell the clang type it is actually a class.
2864                         if (is_a_class && tag_decl_kind != clang::TTK_Class)
2865                             type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
2866 
2867                         // Since DW_TAG_structure_type gets used for both classes
2868                         // and structures, we may need to set any DW_TAG_member
2869                         // fields to have a "private" access if none was specified.
2870                         // When we parsed the child members we tracked that actual
2871                         // accessibility value for each DW_TAG_member in the
2872                         // "member_accessibilities" array. If the value for the
2873                         // member is zero, then it was set to the "default_accessibility"
2874                         // which for structs was "public". Below we correct this
2875                         // by setting any fields to "private" that weren't correctly
2876                         // set.
2877                         if (is_a_class && !member_accessibilities.empty())
2878                         {
2879                             // This is a class and all members that didn't have
2880                             // their access specified are private.
2881                             type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, clang::AS_private, member_accessibilities.data(), member_accessibilities.size());
2882                         }
2883 
2884                         if (!base_classes.empty())
2885                         {
2886                             type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, base_classes.data(), base_classes.size());
2887                         }
2888                     }
2889                     type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2890                 }
2891                 break;
2892 
2893             case DW_TAG_enumeration_type:
2894                 {
2895                     //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2896                     // Set a bit that lets us know that we are currently parsing this
2897                     const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2898 
2899                     size_t byte_size = 0;
2900                     lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2901                     Declaration decl;
2902 
2903                     const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2904                     if (num_attributes > 0)
2905                     {
2906                         uint32_t i;
2907 
2908                         for (i=0; i<num_attributes; ++i)
2909                         {
2910                             attr = attributes.AttributeAtIndex(i);
2911                             DWARFFormValue form_value;
2912                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2913                             {
2914                                 switch (attr)
2915                                 {
2916                                 case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2917                                 case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2918                                 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2919                                 case DW_AT_name:
2920                                     type_name_cstr = form_value.AsCString(&get_debug_str_data());
2921                                     type_name_dbstr.SetCString(type_name_cstr);
2922                                     break;
2923                                 case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
2924                                 case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
2925                                 case DW_AT_accessibility: accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
2926                                 case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2927                                 case DW_AT_allocated:
2928                                 case DW_AT_associated:
2929                                 case DW_AT_bit_stride:
2930                                 case DW_AT_byte_stride:
2931                                 case DW_AT_data_location:
2932                                 case DW_AT_description:
2933                                 case DW_AT_start_scope:
2934                                 case DW_AT_visibility:
2935                                 case DW_AT_specification:
2936                                 case DW_AT_abstract_origin:
2937                                 case DW_AT_sibling:
2938                                     break;
2939                                 }
2940                             }
2941                         }
2942 
2943                         clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr);
2944                         m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2945                         type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type));
2946 
2947                         const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2948 
2949                         if (die->HasChildren())
2950                         {
2951                             type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2952                             void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
2953                             ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die);
2954                             type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2955                         }
2956                     }
2957                 }
2958                 break;
2959 
2960             case DW_TAG_subprogram:
2961             case DW_TAG_subroutine_type:
2962                 {
2963                     //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2964                     // Set a bit that lets us know that we are currently parsing this
2965                     const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2966 
2967                     const char *mangled = NULL;
2968                     dw_offset_t type_die_offset = DW_INVALID_OFFSET;
2969                     Declaration decl;
2970                     bool isVariadic = false;
2971                     bool is_inline = false;
2972                     unsigned type_quals = 0;
2973                     clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern
2974 
2975 
2976                     const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2977                     if (num_attributes > 0)
2978                     {
2979                         uint32_t i;
2980                         for (i=0; i<num_attributes; ++i)
2981                         {
2982                             attr = attributes.AttributeAtIndex(i);
2983                             DWARFFormValue form_value;
2984                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2985                             {
2986                                 switch (attr)
2987                                 {
2988                                 case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2989                                 case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2990                                 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2991                                 case DW_AT_name:
2992                                     type_name_cstr = form_value.AsCString(&get_debug_str_data());
2993                                     type_name_dbstr.SetCString(type_name_cstr);
2994                                     break;
2995 
2996                                 case DW_AT_MIPS_linkage_name:   mangled = form_value.AsCString(&get_debug_str_data()); break;
2997                                 case DW_AT_type:                type_die_offset = form_value.Reference(dwarf_cu); break;
2998                                 case DW_AT_accessibility:       accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
2999                                 case DW_AT_declaration:         is_forward_declaration = form_value.Unsigned() != 0; break;
3000                                 case DW_AT_external:
3001                                     if (form_value.Unsigned())
3002                                     {
3003                                         if (storage == clang::FunctionDecl::None)
3004                                             storage = clang::FunctionDecl::Extern;
3005                                         else
3006                                             storage = clang::FunctionDecl::PrivateExtern;
3007                                     }
3008                                     break;
3009                                 case DW_AT_inline:
3010                                     is_inline = form_value.Unsigned() != 0;
3011                                     break;
3012 
3013                                 case DW_AT_allocated:
3014                                 case DW_AT_associated:
3015                                 case DW_AT_address_class:
3016                                 case DW_AT_artificial:
3017                                 case DW_AT_calling_convention:
3018                                 case DW_AT_data_location:
3019                                 case DW_AT_elemental:
3020                                 case DW_AT_entry_pc:
3021                                 case DW_AT_explicit:
3022                                 case DW_AT_frame_base:
3023                                 case DW_AT_high_pc:
3024                                 case DW_AT_low_pc:
3025                                 case DW_AT_object_pointer:
3026                                 case DW_AT_prototyped:
3027                                 case DW_AT_pure:
3028                                 case DW_AT_ranges:
3029                                 case DW_AT_recursive:
3030                                 case DW_AT_return_addr:
3031                                 case DW_AT_segment:
3032                                 case DW_AT_specification:
3033                                 case DW_AT_start_scope:
3034                                 case DW_AT_static_link:
3035                                 case DW_AT_trampoline:
3036                                 case DW_AT_visibility:
3037                                 case DW_AT_virtuality:
3038                                 case DW_AT_vtable_elem_location:
3039                                 case DW_AT_abstract_origin:
3040                                 case DW_AT_description:
3041                                 case DW_AT_sibling:
3042                                     break;
3043                                 }
3044                             }
3045                         }
3046 
3047                         void *return_clang_type = NULL;
3048                         Type *func_type = ResolveTypeUID(type_die_offset);
3049                         if (func_type)
3050                             return_clang_type = func_type->GetOpaqueClangQualType();
3051                         else
3052                             return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType();
3053 
3054                         std::vector<void *> function_param_types;
3055                         std::vector<clang::ParmVarDecl*> function_param_decls;
3056 
3057                         // Parse the function children for the parameters
3058                         ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls);
3059 
3060                         clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals);
3061                         if (type_name_cstr)
3062                         {
3063                             clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
3064                             // Add the decl to our DIE to decl context map
3065                             assert (function_decl);
3066                             m_die_to_decl_ctx[die] = function_decl;
3067                             if (!function_param_decls.empty())
3068                                 type_list->GetClangASTContext().SetFunctionParameters (function_decl, function_param_decls.data(), function_param_decls.size());
3069                         }
3070                         type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3071 
3072                         const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3073                         assert(type_sp.get());
3074                     }
3075                 }
3076                 break;
3077 
3078             case DW_TAG_array_type:
3079                 {
3080                     //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
3081                     // Set a bit that lets us know that we are currently parsing this
3082                     const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
3083 
3084                     size_t byte_size = 0;
3085                     lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3086                     Declaration decl;
3087                     int64_t first_index = 0;
3088                     uint32_t byte_stride = 0;
3089                     uint32_t bit_stride = 0;
3090                     const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3091 
3092                     if (num_attributes > 0)
3093                     {
3094                         uint32_t i;
3095                         for (i=0; i<num_attributes; ++i)
3096                         {
3097                             attr = attributes.AttributeAtIndex(i);
3098                             DWARFFormValue form_value;
3099                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3100                             {
3101                                 switch (attr)
3102                                 {
3103                                 case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3104                                 case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3105                                 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3106                                 case DW_AT_name:
3107                                     type_name_cstr = form_value.AsCString(&get_debug_str_data());
3108                                     type_name_dbstr.SetCString(type_name_cstr);
3109                                     break;
3110 
3111                                 case DW_AT_type:            type_die_offset = form_value.Reference(dwarf_cu); break;
3112                                 case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;
3113                                 case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break;
3114                                 case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break;
3115                                 case DW_AT_accessibility:   accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
3116                                 case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
3117                                 case DW_AT_allocated:
3118                                 case DW_AT_associated:
3119                                 case DW_AT_data_location:
3120                                 case DW_AT_description:
3121                                 case DW_AT_ordering:
3122                                 case DW_AT_start_scope:
3123                                 case DW_AT_visibility:
3124                                 case DW_AT_specification:
3125                                 case DW_AT_abstract_origin:
3126                                 case DW_AT_sibling:
3127                                     break;
3128                                 }
3129                             }
3130                         }
3131 
3132                         Type *element_type = ResolveTypeUID(type_die_offset);
3133 
3134                         if (element_type)
3135                         {
3136                             std::vector<uint64_t> element_orders;
3137                             ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
3138                             if (byte_stride == 0 && bit_stride == 0)
3139                                 byte_stride = element_type->GetByteSize();
3140                             void *array_element_type = element_type->GetOpaqueClangQualType();
3141                             uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3142                             uint64_t num_elements = 0;
3143                             std::vector<uint64_t>::const_reverse_iterator pos;
3144                             std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3145                             for (pos = element_orders.rbegin(); pos != end; ++pos)
3146                             {
3147                                 num_elements = *pos;
3148                                 clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
3149                                 array_element_type = clang_type;
3150                                 array_element_bit_stride = array_element_bit_stride * num_elements;
3151                             }
3152                             ConstString empty_name;
3153                             type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3154                             const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3155                         }
3156                     }
3157                 }
3158                 break;
3159 
3160             case DW_TAG_ptr_to_member_type:
3161                 {
3162                     dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3163                     dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3164 
3165                     const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3166 
3167                     if (num_attributes > 0) {
3168                         uint32_t i;
3169                         for (i=0; i<num_attributes; ++i)
3170                         {
3171                             attr = attributes.AttributeAtIndex(i);
3172                             DWARFFormValue form_value;
3173                             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3174                             {
3175                                 switch (attr)
3176                                 {
3177                                     case DW_AT_type:
3178                                         type_die_offset = form_value.Reference(dwarf_cu); break;
3179                                     case DW_AT_containing_type:
3180                                         containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3181                                 }
3182                             }
3183                         }
3184 
3185                         Type *pointee_type = ResolveTypeUID(type_die_offset);
3186                         Type *class_type = ResolveTypeUID(containing_type_die_offset);
3187 
3188                         void *pointee_clang_type = pointee_type->GetOpaqueClangQualType();
3189                         void *class_clang_type = class_type->GetOpaqueClangQualType();
3190 
3191                         void *clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type);
3192 
3193                         size_t byte_size = ClangASTContext::GetTypeBitSize(type_list->GetClangASTContext().getASTContext(), clang_type) / 8;
3194 
3195                         type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type));
3196                         const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3197                     }
3198 
3199                     break;
3200                 }
3201             default:
3202                 assert(false && "Unhandled type tag!");
3203                 break;
3204             }
3205 
3206             if (type_sp.get())
3207             {
3208                 const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3209                 dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3210 
3211                 SymbolContextScope * symbol_context_scope = NULL;
3212                 if (sc_parent_tag == DW_TAG_compile_unit)
3213                 {
3214                     symbol_context_scope = sc.comp_unit;
3215                 }
3216                 else if (sc.function != NULL)
3217                 {
3218                     symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3219                     if (symbol_context_scope == NULL)
3220                         symbol_context_scope = sc.function;
3221                 }
3222 
3223                 if (symbol_context_scope != NULL)
3224                 {
3225                     type_sp->SetSymbolContextScope(symbol_context_scope);
3226                 }
3227 
3228 //              if (udt_sp.get())
3229 //              {
3230 //                  if (is_forward_declaration)
3231 //                      udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3232 //                  type_sp->SetUserDefinedType(udt_sp);
3233 //              }
3234 
3235                 if (type_sp.unique())
3236                 {
3237                     // We are ready to put this type into the uniqued list up at the module level
3238                     TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
3239 
3240                     const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get());
3241 
3242                     type_sp = uniqued_type_sp;
3243                 }
3244             }
3245         }
3246         else
3247         {
3248             switch (tag)
3249             {
3250             case DW_TAG_base_type:
3251             case DW_TAG_pointer_type:
3252             case DW_TAG_reference_type:
3253             case DW_TAG_typedef:
3254             case DW_TAG_const_type:
3255             case DW_TAG_restrict_type:
3256             case DW_TAG_volatile_type:
3257             case DW_TAG_structure_type:
3258             case DW_TAG_union_type:
3259             case DW_TAG_class_type:
3260             case DW_TAG_enumeration_type:
3261             case DW_TAG_subprogram:
3262             case DW_TAG_subroutine_type:
3263             case DW_TAG_array_type:
3264                 {
3265                     Type *existing_type = (Type*)die->GetUserData();
3266                     if (existing_type != DIE_IS_BEING_PARSED)
3267                     {
3268                         type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID());
3269                     }
3270                 }
3271                 break;
3272             default:
3273                 //assert(!"invalid type tag...");
3274                 break;
3275             }
3276         }
3277     }
3278     return type_sp;
3279 }
3280 
3281 size_t
3282 SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children)
3283 {
3284     size_t types_added = 0;
3285     while (die != NULL)
3286     {
3287         bool type_is_new = false;
3288         if (ParseType(sc, dwarf_cu, die, type_is_new).get())
3289         {
3290             if (type_is_new)
3291                 ++types_added;
3292         }
3293 
3294         if (parse_children && die->HasChildren())
3295         {
3296             if (die->Tag() == DW_TAG_subprogram)
3297             {
3298                 SymbolContext child_sc(sc);
3299                 child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3300                 types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3301             }
3302             else
3303                 types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3304         }
3305 
3306         if (parse_siblings)
3307             die = die->GetSibling();
3308         else
3309             die = NULL;
3310     }
3311     return types_added;
3312 }
3313 
3314 
3315 size_t
3316 SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3317 {
3318     assert(sc.comp_unit && sc.function);
3319     size_t functions_added = 0;
3320     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3321     if (dwarf_cu)
3322     {
3323         dw_offset_t function_die_offset = sc.function->GetID();
3324         const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3325         if (function_die)
3326         {
3327             ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
3328         }
3329     }
3330 
3331     return functions_added;
3332 }
3333 
3334 
3335 size_t
3336 SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3337 {
3338     // At least a compile unit must be valid
3339     assert(sc.comp_unit);
3340     size_t types_added = 0;
3341     DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3342     if (dwarf_cu)
3343     {
3344         if (sc.function)
3345         {
3346             dw_offset_t function_die_offset = sc.function->GetID();
3347             const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3348             if (func_die && func_die->HasChildren())
3349             {
3350                 types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3351             }
3352         }
3353         else
3354         {
3355             const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3356             if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3357             {
3358                 types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3359             }
3360         }
3361     }
3362 
3363     return types_added;
3364 }
3365 
3366 size_t
3367 SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3368 {
3369     if (sc.comp_unit != NULL)
3370     {
3371         DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3372 
3373         if (dwarf_cu == NULL)
3374             return 0;
3375 
3376         if (sc.function)
3377         {
3378             const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
3379             return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true);
3380         }
3381         else if (sc.comp_unit)
3382         {
3383             uint32_t vars_added = 0;
3384             VariableListSP variables (sc.comp_unit->GetVariableList(false));
3385 
3386             if (variables.get() == NULL)
3387             {
3388                 variables.reset(new VariableList());
3389                 sc.comp_unit->SetVariableList(variables);
3390 
3391                 // Index if we already haven't to make sure the compile units
3392                 // get indexed and make their global DIE index list
3393                 if (!m_indexed)
3394                     Index ();
3395 
3396                 const size_t num_globals = dwarf_cu->GetNumGlobals();
3397                 for (size_t idx=0; idx<num_globals; ++idx)
3398                 {
3399                     VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx)));
3400                     if (var_sp)
3401                     {
3402                         variables->AddVariable(var_sp);
3403                         ++vars_added;
3404                     }
3405                 }
3406             }
3407             return vars_added;
3408         }
3409     }
3410     return 0;
3411 }
3412 
3413 
3414 VariableSP
3415 SymbolFileDWARF::ParseVariableDIE
3416 (
3417     const SymbolContext& sc,
3418     const DWARFCompileUnit* dwarf_cu,
3419     const DWARFDebugInfoEntry *die
3420 )
3421 {
3422 
3423     VariableSP var_sp;
3424 
3425     const dw_tag_t tag = die->Tag();
3426     DWARFDebugInfoEntry::Attributes attributes;
3427     const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3428     if (num_attributes > 0)
3429     {
3430         const char *name = NULL;
3431         Declaration decl;
3432         uint32_t i;
3433         TypeSP type_sp;
3434         Type *var_type = NULL;
3435         DWARFExpression location;
3436         bool is_external = false;
3437         bool is_artificial = false;
3438         uint32_t accessibility = clang::AS_none;
3439 
3440         for (i=0; i<num_attributes; ++i)
3441         {
3442             dw_attr_t attr = attributes.AttributeAtIndex(i);
3443             DWARFFormValue form_value;
3444             if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3445             {
3446                 switch (attr)
3447                 {
3448                 case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3449                 case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3450                 case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3451                 case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
3452                 case DW_AT_type:        var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break;
3453                 case DW_AT_external:    is_external = form_value.Unsigned() != 0; break;
3454                 case DW_AT_location:
3455                     {
3456                         if (form_value.BlockData())
3457                         {
3458                             const DataExtractor& debug_info_data = get_debug_info_data();
3459 
3460                             uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3461                             uint32_t block_length = form_value.Unsigned();
3462                             location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL);
3463                         }
3464                         else
3465                         {
3466                             const DataExtractor&    debug_loc_data = get_debug_loc_data();
3467                             const dw_offset_t debug_loc_offset = form_value.Unsigned();
3468 
3469                             size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3470                             if (loc_list_length > 0)
3471                             {
3472                                 Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList());
3473                                 location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address);
3474                             }
3475                         }
3476                     }
3477                     break;
3478 
3479                 case DW_AT_artificial:      is_artificial = form_value.Unsigned() != 0; break;
3480                 case DW_AT_accessibility:   accessibility = DwarfToClangAccessibility(form_value.Unsigned()); break;
3481                 case DW_AT_const_value:
3482                 case DW_AT_declaration:
3483                 case DW_AT_description:
3484                 case DW_AT_endianity:
3485                 case DW_AT_segment:
3486                 case DW_AT_start_scope:
3487                 case DW_AT_visibility:
3488                 default:
3489                 case DW_AT_abstract_origin:
3490                 case DW_AT_sibling:
3491                 case DW_AT_specification:
3492                     break;
3493                 }
3494             }
3495         }
3496 
3497         if (location.IsValid())
3498         {
3499             assert(var_type != DIE_IS_BEING_PARSED);
3500 
3501             ConstString var_name(name);
3502 
3503             ValueType scope = eValueTypeInvalid;
3504 
3505             const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3506             dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3507 
3508             if (tag == DW_TAG_formal_parameter)
3509                 scope = eValueTypeVariableArgument;
3510             else if (is_external || parent_tag == DW_TAG_compile_unit)
3511                 scope = eValueTypeVariableGlobal;
3512             else
3513                 scope = eValueTypeVariableLocal;
3514 
3515             SymbolContextScope * symbol_context_scope = NULL;
3516             if (parent_tag == DW_TAG_compile_unit)
3517             {
3518                 symbol_context_scope = sc.comp_unit;
3519             }
3520             else if (sc.function != NULL)
3521             {
3522                 symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3523                 if (symbol_context_scope == NULL)
3524                     symbol_context_scope = sc.function;
3525             }
3526 
3527             assert(symbol_context_scope != NULL);
3528             var_sp.reset (new Variable(die->GetOffset(),
3529                                        var_name,
3530                                        var_type,
3531                                        scope,
3532                                        symbol_context_scope,
3533                                        &decl,
3534                                        location,
3535                                        is_external,
3536                                        is_artificial));
3537             const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get());
3538         }
3539     }
3540     return var_sp;
3541 }
3542 
3543 size_t
3544 SymbolFileDWARF::ParseVariables
3545 (
3546     const SymbolContext& sc,
3547     const DWARFCompileUnit* dwarf_cu,
3548     const DWARFDebugInfoEntry *orig_die,
3549     bool parse_siblings,
3550     bool parse_children,
3551     VariableList* cc_variable_list
3552 )
3553 {
3554     if (orig_die == NULL)
3555         return 0;
3556 
3557     size_t vars_added = 0;
3558     const DWARFDebugInfoEntry *die = orig_die;
3559     const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3560     dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3561     VariableListSP variables;
3562     switch (parent_tag)
3563     {
3564     case DW_TAG_compile_unit:
3565         if (sc.comp_unit != NULL)
3566         {
3567             variables = sc.comp_unit->GetVariableList(false);
3568             if (variables.get() == NULL)
3569             {
3570                 variables.reset(new VariableList());
3571                 sc.comp_unit->SetVariableList(variables);
3572             }
3573         }
3574         else
3575         {
3576             assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3577             vars_added = 0;
3578         }
3579         break;
3580 
3581     case DW_TAG_subprogram:
3582     case DW_TAG_inlined_subroutine:
3583     case DW_TAG_lexical_block:
3584         if (sc.function != NULL)
3585         {
3586             // Check to see if we already have parsed the variables for the given scope
3587             variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false);
3588             if (variables.get() == NULL)
3589             {
3590                 variables.reset(new VariableList());
3591                 sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables);
3592             }
3593         }
3594         else
3595         {
3596             assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3597             vars_added = 0;
3598         }
3599         break;
3600 
3601     default:
3602         assert(!"Didn't find appropriate parent DIE for variable list...");
3603         break;
3604     }
3605 
3606     // We need to have a variable list at this point that we can add variables to
3607     assert(variables.get());
3608 
3609     while (die != NULL)
3610     {
3611         dw_tag_t tag = die->Tag();
3612 
3613         // Check to see if we have already parsed this variable or constant?
3614         if (die->GetUserData() == NULL)
3615         {
3616             // We haven't already parsed it, lets do that now.
3617             if ((tag == DW_TAG_variable) ||
3618                 (tag == DW_TAG_constant) ||
3619                 (tag == DW_TAG_formal_parameter && sc.function))
3620             {
3621                 VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die));
3622                 if (var_sp)
3623                 {
3624                     variables->AddVariable(var_sp);
3625                     ++vars_added;
3626                 }
3627             }
3628         }
3629 
3630         bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3631 
3632         if (!skip_children && parse_children && die->HasChildren())
3633         {
3634             vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true);
3635             //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
3636         }
3637 
3638         if (parse_siblings)
3639             die = die->GetSibling();
3640         else
3641             die = NULL;
3642     }
3643 
3644     if (cc_variable_list)
3645     {
3646         cc_variable_list->AddVariables(variables.get());
3647     }
3648 
3649     return vars_added;
3650 }
3651 
3652 //------------------------------------------------------------------
3653 // PluginInterface protocol
3654 //------------------------------------------------------------------
3655 const char *
3656 SymbolFileDWARF::GetPluginName()
3657 {
3658     return "SymbolFileDWARF";
3659 }
3660 
3661 const char *
3662 SymbolFileDWARF::GetShortPluginName()
3663 {
3664     return GetPluginNameStatic();
3665 }
3666 
3667 uint32_t
3668 SymbolFileDWARF::GetPluginVersion()
3669 {
3670     return 1;
3671 }
3672 
3673 void
3674 SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3675 {
3676 }
3677 
3678 Error
3679 SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3680 {
3681     Error error;
3682     error.SetErrorString("No plug-in command are currently supported.");
3683     return error;
3684 }
3685 
3686 Log *
3687 SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3688 {
3689     return NULL;
3690 }
3691 
3692