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