SymbolFileDWARF.cpp revision 84f8075072eef306234f8109573067647735c111
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            Language::Type language = (Language::Type)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(), 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(), 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    std::vector<clang::CXXBaseSpecifier *>& base_classes,
1215    std::vector<int>& member_accessibilities,
1216    ClangASTContext::AccessType& default_accessibility,
1217    bool &is_a_class
1218)
1219{
1220    if (parent_die == NULL)
1221        return 0;
1222
1223    TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
1224
1225    size_t count = 0;
1226    const DWARFDebugInfoEntry *die;
1227    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1228    {
1229        dw_tag_t tag = die->Tag();
1230
1231        switch (tag)
1232        {
1233        case DW_TAG_member:
1234            {
1235                DWARFDebugInfoEntry::Attributes attributes;
1236                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1237                if (num_attributes > 0)
1238                {
1239                    Declaration decl;
1240                    DWARFExpression location;
1241                    const char *name = NULL;
1242                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1243                    ClangASTContext::AccessType accessibility = ClangASTContext::eAccessNone;
1244                    off_t member_offset = 0;
1245                    size_t byte_size = 0;
1246                    size_t bit_offset = 0;
1247                    size_t bit_size = 0;
1248                    uint32_t i;
1249                    for (i=0; i<num_attributes; ++i)
1250                    {
1251                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1252                        DWARFFormValue form_value;
1253                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1254                        {
1255                            switch (attr)
1256                            {
1257                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1258                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1259                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1260                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
1261                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1262                            case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break;
1263                            case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break;
1264                            case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
1265                            case DW_AT_data_member_location:
1266                                if (form_value.BlockData())
1267                                {
1268                                    Value initialValue(0);
1269                                    Value memberOffset(0);
1270                                    const DataExtractor& debug_info_data = get_debug_info_data();
1271                                    uint32_t block_length = form_value.Unsigned();
1272                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1273                                    if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1274                                    {
1275                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1276                                    }
1277                                }
1278                                break;
1279
1280                            case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
1281                            case DW_AT_declaration:
1282                            case DW_AT_description:
1283                            case DW_AT_mutable:
1284                            case DW_AT_visibility:
1285                            default:
1286                            case DW_AT_sibling:
1287                                break;
1288                            }
1289                        }
1290                    }
1291
1292                    Type *member_type = ResolveTypeUID(encoding_uid);
1293                    assert(member_type);
1294                    if (accessibility == ClangASTContext::eAccessNone)
1295                        accessibility = default_accessibility;
1296                    member_accessibilities.push_back(accessibility);
1297
1298                    type_list->GetClangASTContext().AddFieldToRecordType (type_sp->GetOpaqueClangQualType(), name, member_type->GetOpaqueClangQualType(), accessibility, bit_size);
1299                }
1300            }
1301            break;
1302
1303        case DW_TAG_subprogram:
1304            {
1305                is_a_class = true;
1306                if (default_accessibility == ClangASTContext::eAccessNone)
1307                    default_accessibility = ClangASTContext::eAccessPrivate;
1308                // TODO: implement DW_TAG_subprogram type parsing
1309//              UserDefTypeChildInfo method_info(die->GetOffset());
1310//
1311//              FunctionSP func_sp (sc.comp_unit->FindFunctionByUID (die->GetOffset()));
1312//              if (func_sp.get() == NULL)
1313//                  ParseCompileUnitFunction(sc, dwarf_cu, die);
1314//
1315//              method_info.SetEncodingTypeUID(die->GetOffset());
1316//              struct_udt->AddMethod(method_info);
1317            }
1318            break;
1319
1320        case DW_TAG_inheritance:
1321            {
1322                is_a_class = true;
1323                if (default_accessibility == ClangASTContext::eAccessNone)
1324                    default_accessibility = ClangASTContext::eAccessPrivate;
1325                // TODO: implement DW_TAG_inheritance type parsing
1326                DWARFDebugInfoEntry::Attributes attributes;
1327                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
1328                if (num_attributes > 0)
1329                {
1330                    Declaration decl;
1331                    DWARFExpression location;
1332                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1333                    ClangASTContext::AccessType accessibility = default_accessibility;
1334                    bool is_virtual = false;
1335                    bool is_base_of_class = true;
1336                    off_t member_offset = 0;
1337                    uint32_t i;
1338                    for (i=0; i<num_attributes; ++i)
1339                    {
1340                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1341                        DWARFFormValue form_value;
1342                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1343                        {
1344                            switch (attr)
1345                            {
1346                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1347                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1348                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1349                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1350                            case DW_AT_data_member_location:
1351                                if (form_value.BlockData())
1352                                {
1353                                    Value initialValue(0);
1354                                    Value memberOffset(0);
1355                                    const DataExtractor& debug_info_data = get_debug_info_data();
1356                                    uint32_t block_length = form_value.Unsigned();
1357                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1358                                    if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1359                                    {
1360                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1361                                    }
1362                                }
1363                                break;
1364
1365                            case DW_AT_accessibility:
1366                                accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
1367                                break;
1368
1369                            case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1370                            default:
1371                            case DW_AT_sibling:
1372                                break;
1373                            }
1374                        }
1375                    }
1376
1377                    Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1378                    assert(base_class_dctype);
1379                    base_classes.push_back (type_list->GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetOpaqueClangQualType(), accessibility, is_virtual, is_base_of_class));
1380                    assert(base_classes.back());
1381                }
1382            }
1383            break;
1384
1385        default:
1386            break;
1387        }
1388    }
1389    return count;
1390}
1391
1392
1393clang::DeclContext*
1394SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1395{
1396    DWARFDebugInfo* debug_info = DebugInfo();
1397    if (debug_info)
1398    {
1399        DWARFCompileUnitSP cu_sp;
1400        const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1401        if (die)
1402            return GetClangDeclContextForDIE (cu_sp.get(), die);
1403    }
1404    return NULL;
1405}
1406
1407Type*
1408SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid)
1409{
1410    DWARFDebugInfo* debug_info = DebugInfo();
1411    if (debug_info)
1412    {
1413        const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, NULL);
1414        if (type_die != NULL)
1415        {
1416            void *type = type_die->GetUserData();
1417            if (type == NULL)
1418            {
1419                DWARFCompileUnitSP cu_sp;
1420                const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1421                if (die != NULL)
1422                {
1423                    TypeSP owning_type_sp;
1424                    TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, 0, 0));
1425                }
1426                type = type_die->GetUserData();
1427            }
1428            if (type != DIE_IS_BEING_PARSED)
1429                return (Type *)type;
1430        }
1431    }
1432    return NULL;
1433}
1434
1435CompileUnit*
1436SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit* cu, uint32_t cu_idx)
1437{
1438    // Check if the symbol vendor already knows about this compile unit?
1439    if (cu->GetUserData() == NULL)
1440    {
1441        // The symbol vendor doesn't know about this compile unit, we
1442        // need to parse and add it to the symbol vendor object.
1443        CompUnitSP dc_cu;
1444        ParseCompileUnit(cu, dc_cu);
1445        if (dc_cu.get())
1446        {
1447            // Figure out the compile unit index if we weren't given one
1448            if (cu_idx == UINT_MAX)
1449                DebugInfo()->GetCompileUnit(cu->GetOffset(), &cu_idx);
1450
1451            m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
1452        }
1453    }
1454    return (CompileUnit*)cu->GetUserData();
1455}
1456
1457bool
1458SymbolFileDWARF::GetFunction (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1459{
1460    sc.Clear();
1461    // Check if the symbol vendor already knows about this compile unit?
1462    sc.module_sp = m_obj_file->GetModule()->GetSP();
1463    sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1464
1465    sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1466    if (sc.function == NULL)
1467        sc.function = ParseCompileUnitFunction(sc, cu, func_die);
1468
1469    return sc.function != NULL;
1470}
1471
1472uint32_t
1473SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1474{
1475    Timer scoped_timer(__PRETTY_FUNCTION__,
1476                       "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1477                       so_addr.GetSection(),
1478                       so_addr.GetOffset(),
1479                       resolve_scope);
1480    uint32_t resolved = 0;
1481    if (resolve_scope & (   eSymbolContextCompUnit |
1482                            eSymbolContextFunction |
1483                            eSymbolContextBlock |
1484                            eSymbolContextLineEntry))
1485    {
1486        lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1487
1488        DWARFDebugAranges* debug_aranges = DebugAranges();
1489        DWARFDebugInfo* debug_info = DebugInfo();
1490        if (debug_aranges)
1491        {
1492            dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1493            if (cu_offset != DW_INVALID_OFFSET)
1494            {
1495                uint32_t cu_idx;
1496                DWARFCompileUnit* cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1497                if (cu)
1498                {
1499                    sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1500                    assert(sc.comp_unit != NULL);
1501                    resolved |= eSymbolContextCompUnit;
1502
1503                    if (resolve_scope & eSymbolContextLineEntry)
1504                    {
1505                        LineTable *line_table = sc.comp_unit->GetLineTable();
1506                        if (line_table == NULL)
1507                        {
1508                            if (ParseCompileUnitLineTable(sc))
1509                                line_table = sc.comp_unit->GetLineTable();
1510                        }
1511                        if (line_table != NULL)
1512                        {
1513                            if (so_addr.IsLinkedAddress())
1514                            {
1515                                Address linked_addr (so_addr);
1516                                linked_addr.ResolveLinkedAddress();
1517                                if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1518                                {
1519                                    resolved |= eSymbolContextLineEntry;
1520                                }
1521                            }
1522                            else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1523                            {
1524                                resolved |= eSymbolContextLineEntry;
1525                            }
1526                        }
1527                    }
1528
1529                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1530                    {
1531                        DWARFDebugInfoEntry *function_die = NULL;
1532                        DWARFDebugInfoEntry *block_die = NULL;
1533                        if (resolve_scope & eSymbolContextBlock)
1534                        {
1535                            cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1536                        }
1537                        else
1538                        {
1539                            cu->LookupAddress(file_vm_addr, &function_die, NULL);
1540                        }
1541
1542                        if (function_die != NULL)
1543                        {
1544                            sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1545                            if (sc.function == NULL)
1546                                sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1547                        }
1548
1549                        if (sc.function != NULL)
1550                        {
1551                            resolved |= eSymbolContextFunction;
1552
1553                            if (resolve_scope & eSymbolContextBlock)
1554                            {
1555                                BlockList& blocks = sc.function->GetBlocks(true);
1556
1557                                if (block_die != NULL)
1558                                    sc.block = blocks.GetBlockByID(block_die->GetOffset());
1559                                else
1560                                    sc.block = blocks.GetBlockByID(function_die->GetOffset());
1561                                if (sc.block)
1562                                    resolved |= eSymbolContextBlock;
1563                            }
1564                        }
1565                    }
1566                }
1567            }
1568        }
1569    }
1570    return resolved;
1571}
1572
1573
1574
1575uint32_t
1576SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1577{
1578    const uint32_t prev_size = sc_list.GetSize();
1579    if (resolve_scope & eSymbolContextCompUnit)
1580    {
1581        DWARFDebugInfo* debug_info = DebugInfo();
1582        if (debug_info)
1583        {
1584            uint32_t cu_idx;
1585            DWARFCompileUnit* cu = NULL;
1586
1587            for (cu_idx = 0; (cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1588            {
1589                CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1590                bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1591                if (check_inlines || file_spec_matches_cu_file_spec)
1592                {
1593                    SymbolContext sc (m_obj_file->GetModule());
1594                    sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, cu_idx);
1595                    assert(sc.comp_unit != NULL);
1596
1597                    uint32_t file_idx = UINT32_MAX;
1598
1599                    // If we are looking for inline functions only and we don't
1600                    // find it in the support files, we are done.
1601                    if (check_inlines)
1602                    {
1603                        file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1604                        if (file_idx == UINT32_MAX)
1605                            continue;
1606                    }
1607
1608                    if (line != 0)
1609                    {
1610                        LineTable *line_table = sc.comp_unit->GetLineTable();
1611
1612                        if (line_table != NULL && line != 0)
1613                        {
1614                            // We will have already looked up the file index if
1615                            // we are searching for inline entries.
1616                            if (!check_inlines)
1617                                file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1618
1619                            if (file_idx != UINT32_MAX)
1620                            {
1621                                uint32_t found_line;
1622                                uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1623                                found_line = sc.line_entry.line;
1624
1625                                while (line_idx != UINT_MAX)
1626                                {
1627                                    sc.function = NULL;
1628                                    sc.block = NULL;
1629                                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1630                                    {
1631                                        const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1632                                        if (file_vm_addr != LLDB_INVALID_ADDRESS)
1633                                        {
1634                                            DWARFDebugInfoEntry *function_die = NULL;
1635                                            DWARFDebugInfoEntry *block_die = NULL;
1636                                            cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1637
1638                                            if (function_die != NULL)
1639                                            {
1640                                                sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1641                                                if (sc.function == NULL)
1642                                                    sc.function = ParseCompileUnitFunction(sc, cu, function_die);
1643                                            }
1644
1645                                            if (sc.function != NULL)
1646                                            {
1647                                                BlockList& blocks = sc.function->GetBlocks(true);
1648
1649                                                if (block_die != NULL)
1650                                                    sc.block = blocks.GetBlockByID(block_die->GetOffset());
1651                                                else
1652                                                    sc.block = blocks.GetBlockByID(function_die->GetOffset());
1653                                            }
1654                                        }
1655                                    }
1656
1657                                    sc_list.Append(sc);
1658                                    line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1659                                }
1660                            }
1661                        }
1662                        else if (file_spec_matches_cu_file_spec && !check_inlines)
1663                        {
1664                            // only append the context if we aren't looking for inline call sites
1665                            // by file and line and if the file spec matches that of the compile unit
1666                            sc_list.Append(sc);
1667                        }
1668                    }
1669                    else if (file_spec_matches_cu_file_spec && !check_inlines)
1670                    {
1671                        // only append the context if we aren't looking for inline call sites
1672                        // by file and line and if the file spec matches that of the compile unit
1673                        sc_list.Append(sc);
1674                    }
1675
1676                    if (!check_inlines)
1677                        break;
1678                }
1679            }
1680        }
1681    }
1682    return sc_list.GetSize() - prev_size;
1683}
1684
1685void
1686SymbolFileDWARF::Index ()
1687{
1688    if (m_indexed)
1689        return;
1690    m_indexed = true;
1691    Timer scoped_timer (__PRETTY_FUNCTION__,
1692                        "SymbolFileDWARF::Index (%s)",
1693                        GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1694
1695    DWARFDebugInfo* debug_info = DebugInfo();
1696    if (debug_info)
1697    {
1698        uint32_t cu_idx = 0;
1699        const uint32_t num_compile_units = GetNumCompileUnits();
1700        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1701        {
1702            DWARFCompileUnit* cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1703
1704            bool clear_dies = cu->ExtractDIEsIfNeeded (false) > 1;
1705
1706            cu->Index (m_base_name_to_function_die,
1707                       m_full_name_to_function_die,
1708                       m_method_name_to_function_die,
1709                       m_selector_name_to_function_die,
1710                       m_name_to_global_die,
1711                       m_name_to_type_die);
1712
1713            // Keep memory down by clearing DIEs if this generate function
1714            // caused them to be parsed
1715            if (clear_dies)
1716                cu->ClearDIEs (true);
1717        }
1718
1719        m_base_name_to_function_die.Sort();
1720        m_full_name_to_function_die.Sort();
1721        m_method_name_to_function_die.Sort();
1722        m_selector_name_to_function_die.Sort();
1723        m_name_to_global_die.Sort();
1724        m_name_to_type_die.Sort();
1725    }
1726}
1727
1728uint32_t
1729SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1730{
1731    std::vector<dw_offset_t> die_offsets;
1732
1733    // If we aren't appending the results to this list, then clear the list
1734    if (!append)
1735        variables.Clear();
1736
1737    // Remember how many variables are in the list before we search in case
1738    // we are appending the results to a variable list.
1739    const uint32_t original_size = variables.GetSize();
1740
1741    // Index the DWARF if we haven't already
1742    if (!m_indexed)
1743        Index ();
1744
1745    const UniqueCStringMap<dw_offset_t>::Entry *entry;
1746
1747    for (entry = m_name_to_global_die.FindFirstValueForName (name.AsCString());
1748         entry != NULL;
1749         entry = m_name_to_global_die.FindNextValueForName (name.AsCString(), entry))
1750    {
1751        DWARFCompileUnitSP cu_sp;
1752        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1753        DWARFCompileUnit* cu = cu_sp.get();
1754        if (die)
1755        {
1756            SymbolContext sc;
1757            sc.module_sp = m_obj_file->GetModule()->GetSP();
1758            assert (sc.module_sp);
1759
1760            sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1761            assert(sc.comp_unit != NULL);
1762
1763            ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1764
1765            if (variables.GetSize() - original_size >= max_matches)
1766                break;
1767        }
1768    }
1769
1770    // Return the number of variable that were appended to the list
1771    return variables.GetSize() - original_size;
1772}
1773
1774uint32_t
1775SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1776{
1777    std::vector<dw_offset_t> die_offsets;
1778
1779    // If we aren't appending the results to this list, then clear the list
1780    if (!append)
1781        variables.Clear();
1782
1783    // Remember how many variables are in the list before we search in case
1784    // we are appending the results to a variable list.
1785    const uint32_t original_size = variables.GetSize();
1786
1787    // Index the DWARF if we haven't already
1788    if (!m_indexed)
1789        Index ();
1790
1791    // Create the pubnames information so we can quickly lookup external symbols by name
1792    const size_t num_entries = m_name_to_global_die.GetSize();
1793    for (size_t i=0; i<num_entries; i++)
1794    {
1795        if (!regex.Execute(m_name_to_global_die.GetCStringAtIndex (i)))
1796            continue;
1797
1798        const dw_offset_t die_offset = *m_name_to_global_die.GetValueAtIndex (i);
1799
1800        DWARFCompileUnitSP cu_sp;
1801        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1802        DWARFCompileUnit* cu = cu_sp.get();
1803        if (die)
1804        {
1805            SymbolContext sc;
1806            sc.module_sp = m_obj_file->GetModule()->GetSP();
1807            assert (sc.module_sp);
1808
1809
1810            sc.comp_unit = GetCompUnitForDWARFCompUnit(cu, UINT_MAX);
1811            assert(sc.comp_unit != NULL);
1812
1813            ParseVariables(sc, cu_sp.get(), die, false, false, &variables);
1814
1815            if (variables.GetSize() - original_size >= max_matches)
1816                break;
1817        }
1818    }
1819
1820    // Return the number of variable that were appended to the list
1821    return variables.GetSize() - original_size;
1822}
1823
1824
1825void
1826SymbolFileDWARF::FindFunctions
1827(
1828    const ConstString &name,
1829    UniqueCStringMap<dw_offset_t> &name_to_die,
1830    SymbolContextList& sc_list
1831)
1832{
1833    const UniqueCStringMap<dw_offset_t>::Entry *entry;
1834
1835    SymbolContext sc;
1836    for (entry = name_to_die.FindFirstValueForName (name.AsCString());
1837         entry != NULL;
1838         entry = name_to_die.FindNextValueForName (name.AsCString(), entry))
1839    {
1840        DWARFCompileUnitSP cu_sp;
1841        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (entry->value, &cu_sp);
1842        if (die)
1843        {
1844            if (GetFunction (cu_sp.get(), die, sc))
1845            {
1846                // We found the function, so we should find the line table
1847                // and line table entry as well
1848                LineTable *line_table = sc.comp_unit->GetLineTable();
1849                if (line_table == NULL)
1850                {
1851                    if (ParseCompileUnitLineTable(sc))
1852                        line_table = sc.comp_unit->GetLineTable();
1853                }
1854                if (line_table != NULL)
1855                    line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1856
1857                sc_list.Append(sc);
1858            }
1859        }
1860    }
1861
1862}
1863
1864uint32_t
1865SymbolFileDWARF::FindFunctions
1866(
1867    const ConstString &name,
1868    uint32_t name_type_mask,
1869    bool append,
1870    SymbolContextList& sc_list
1871)
1872{
1873    Timer scoped_timer (__PRETTY_FUNCTION__,
1874                        "SymbolFileDWARF::FindFunctions (name = '%s')",
1875                        name.AsCString());
1876
1877    std::vector<dw_offset_t> die_offsets;
1878
1879    // If we aren't appending the results to this list, then clear the list
1880    if (!append)
1881        sc_list.Clear();
1882
1883    // Remember how many sc_list are in the list before we search in case
1884    // we are appending the results to a variable list.
1885    uint32_t original_size = sc_list.GetSize();
1886
1887    // Index the DWARF if we haven't already
1888    if (!m_indexed)
1889        Index ();
1890
1891    if (name_type_mask & eFunctionNameTypeBase)
1892        FindFunctions (name, m_base_name_to_function_die, sc_list);
1893
1894    if (name_type_mask & eFunctionNameTypeFull)
1895        FindFunctions (name, m_full_name_to_function_die, sc_list);
1896
1897    if (name_type_mask & eFunctionNameTypeMethod)
1898        FindFunctions (name, m_method_name_to_function_die, sc_list);
1899
1900    if (name_type_mask & eFunctionNameTypeSelector)
1901        FindFunctions (name, m_selector_name_to_function_die, sc_list);
1902
1903    // Return the number of variable that were appended to the list
1904    return sc_list.GetSize() - original_size;
1905}
1906
1907
1908uint32_t
1909SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
1910{
1911    Timer scoped_timer (__PRETTY_FUNCTION__,
1912                        "SymbolFileDWARF::FindFunctions (regex = '%s')",
1913                        regex.GetText());
1914
1915    std::vector<dw_offset_t> die_offsets;
1916
1917    // If we aren't appending the results to this list, then clear the list
1918    if (!append)
1919        sc_list.Clear();
1920
1921    // Remember how many sc_list are in the list before we search in case
1922    // we are appending the results to a variable list.
1923    uint32_t original_size = sc_list.GetSize();
1924
1925    // Index the DWARF if we haven't already
1926    if (!m_indexed)
1927        Index ();
1928
1929    // Create the pubnames information so we can quickly lookup external symbols by name
1930    // Create the pubnames information so we can quickly lookup external symbols by name
1931    const size_t num_entries = m_full_name_to_function_die.GetSize();
1932    SymbolContext sc;
1933    for (size_t i=0; i<num_entries; i++)
1934    {
1935        if (!regex.Execute(m_full_name_to_function_die.GetCStringAtIndex (i)))
1936            continue;
1937
1938        const dw_offset_t die_offset = *m_full_name_to_function_die.GetValueAtIndex (i);
1939
1940        DWARFCompileUnitSP cu_sp;
1941        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr (die_offset, &cu_sp);
1942        if (die)
1943        {
1944            if (GetFunction (cu_sp.get(), die, sc))
1945            {
1946                // We found the function, so we should find the line table
1947                // and line table entry as well
1948                LineTable *line_table = sc.comp_unit->GetLineTable();
1949                if (line_table == NULL)
1950                {
1951                    if (ParseCompileUnitLineTable(sc))
1952                        line_table = sc.comp_unit->GetLineTable();
1953                }
1954                if (line_table != NULL)
1955                    line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1956
1957
1958                sc_list.Append(sc);
1959            }
1960        }
1961    }
1962
1963    // Return the number of variable that were appended to the list
1964    return sc_list.GetSize() - original_size;
1965}
1966
1967#if 0
1968uint32_t
1969SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
1970{
1971    // If we aren't appending the results to this list, then clear the list
1972    if (!append)
1973        types.Clear();
1974
1975    // Create the pubnames information so we can quickly lookup external symbols by name
1976    DWARFDebugPubnames* pubtypes = DebugPubtypes();
1977    if (pubtypes)
1978    {
1979        std::vector<dw_offset_t> die_offsets;
1980        if (!pubtypes->Find(name.AsCString(), false, die_offsets))
1981        {
1982            DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
1983            if (pub_base_types && !pub_base_types->Find(name.AsCString(), false, die_offsets))
1984                return 0;
1985        }
1986        return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
1987    }
1988    return 0;
1989}
1990
1991
1992uint32_t
1993SymbolFileDWARF::FindTypes(const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
1994{
1995    // If we aren't appending the results to this list, then clear the list
1996    if (!append)
1997        types.Clear();
1998
1999    // Create the pubnames information so we can quickly lookup external symbols by name
2000    DWARFDebugPubnames* pubtypes = DebugPubtypes();
2001    if (pubtypes)
2002    {
2003        std::vector<dw_offset_t> die_offsets;
2004        if (!pubtypes->Find(regex, die_offsets))
2005        {
2006            DWARFDebugPubnames* pub_base_types = DebugPubBaseTypes();
2007            if (pub_base_types && !pub_base_types->Find(regex, die_offsets))
2008                return 0;
2009        }
2010
2011        return FindTypes(die_offsets, max_matches, encoding, udt_uid, types);
2012    }
2013
2014    return 0;
2015}
2016
2017
2018
2019uint32_t
2020SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, Type::Encoding encoding, lldb::user_id_t udt_uid, TypeList& types)
2021{
2022    // Remember how many sc_list are in the list before we search in case
2023    // we are appending the results to a variable list.
2024    uint32_t original_size = types.Size();
2025
2026    const uint32_t num_die_offsets = die_offsets.size();
2027    // Parse all of the types we found from the pubtypes matches
2028    uint32_t i;
2029    uint32_t num_matches = 0;
2030    for (i = 0; i < num_die_offsets; ++i)
2031    {
2032        dw_offset_t die_offset = die_offsets[i];
2033        DWARFCompileUnitSP cu_sp;
2034        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2035
2036        assert(die != NULL);
2037
2038        bool get_type_for_die = true;
2039        if (encoding)
2040        {
2041            // Check if this type has already been uniqued and registers with the module?
2042            Type* type = (Type*)die->GetUserData();
2043            if (type != NULL && type != DIE_IS_BEING_PARSED)
2044            {
2045                get_type_for_die = type->GetEncoding() == encoding;
2046            }
2047            else
2048            {
2049                dw_tag_t tag = die->Tag();
2050                switch (encoding)
2051                {
2052                case Type::address:
2053                case Type::boolean:
2054                case Type::complex_float:
2055                case Type::float_type:
2056                case Type::signed_int:
2057                case Type::signed_char:
2058                case Type::unsigned_int:
2059                case Type::unsigned_char:
2060                case Type::imaginary_float:
2061                case Type::packed_decimal:
2062                case Type::numeric_string:
2063                case Type::edited_string:
2064                case Type::signed_fixed:
2065                case Type::unsigned_fixed:
2066                case Type::decimal_float:
2067                    if (tag != DW_TAG_base_type)
2068                        get_type_for_die = false;
2069                    else
2070                    {
2071                        if (die->GetAttributeValueAsUnsigned(this, cu_sp.get(), DW_AT_encoding, Type::invalid) != encoding)
2072                            get_type_for_die = false;
2073                    }
2074                    break;
2075
2076                case Type::indirect_const:      get_type_for_die = tag == DW_TAG_const_type; break;
2077                case Type::indirect_restrict:       get_type_for_die = tag == DW_TAG_restrict_type; break;
2078                case Type::indirect_volatile:       get_type_for_die = tag == DW_TAG_volatile_type; break;
2079                case Type::indirect_typedef:        get_type_for_die = tag == DW_TAG_typedef; break;
2080                case Type::indirect_pointer:        get_type_for_die = tag == DW_TAG_pointer_type; break;
2081                case Type::indirect_reference:  get_type_for_die = tag == DW_TAG_reference_type; break;
2082
2083                case Type::user_defined_type:
2084                    switch (tag)
2085                    {
2086                    case DW_TAG_array_type:
2087                        get_type_for_die = UserDefTypeArray::OwnsUserDefTypeUID(udt_uid);
2088                        break;
2089
2090                    case DW_TAG_structure_type:
2091                    case DW_TAG_union_type:
2092                    case DW_TAG_class_type:
2093                        get_type_for_die = UserDefTypeStruct::OwnsUserDefTypeUID(udt_uid);
2094                        break;
2095
2096                    case DW_TAG_enumeration_type:
2097                        get_type_for_die = UserDefTypeEnum::OwnsUserDefTypeUID(udt_uid);
2098                        break;
2099
2100                    case DW_TAG_subprogram:
2101                    case DW_TAG_subroutine_type:
2102                        get_type_for_die = UserDefTypeFunction::OwnsUserDefTypeUID(udt_uid);
2103                        break;
2104                    }
2105                }
2106            }
2107        }
2108
2109        if (get_type_for_die)
2110        {
2111            TypeSP owning_type_sp;
2112            TypeSP type_sp(GetTypeForDIE(cu_sp.get(), die, owning_type_sp, NULL, 0, 0));
2113
2114            if (type_sp.get())
2115            {
2116                // See if we are filtering results based on encoding?
2117                bool add_type = (encoding == Type::invalid);
2118                if (!add_type)
2119                {
2120                    // We are filtering base on encoding, so lets check the resulting type encoding
2121                    add_type = (encoding == type_sp->GetEncoding());
2122                    if (add_type)
2123                    {
2124                        // The type encoding matches, if this is a user defined type, lets
2125                        // make sure the exact user define type uid matches if one was provided
2126                        if (encoding == Type::user_defined_type && udt_uid != LLDB_INVALID_UID)
2127                        {
2128                            UserDefType* udt = type_sp->GetUserDefinedType().get();
2129                            if (udt)
2130                                add_type = udt->UserDefinedTypeUID() == udt_uid;
2131                        }
2132                    }
2133                }
2134                // Add the type to our list as long as everything matched
2135                if (add_type)
2136                {
2137                    types.InsertUnique(type_sp);
2138                    if (++num_matches >= max_matches)
2139                        break;
2140                }
2141            }
2142        }
2143    }
2144
2145    // Return the number of variable that were appended to the list
2146    return types.Size() - original_size;
2147}
2148
2149#endif
2150
2151
2152size_t
2153SymbolFileDWARF::ParseChildParameters
2154(
2155    const SymbolContext& sc,
2156    TypeSP& type_sp,
2157    const DWARFCompileUnit* dwarf_cu,
2158    const DWARFDebugInfoEntry *parent_die,
2159    TypeList* type_list,
2160    std::vector<void *>& function_param_types,
2161    std::vector<clang::ParmVarDecl*>& function_param_decls
2162)
2163{
2164    if (parent_die == NULL)
2165        return 0;
2166
2167    size_t count = 0;
2168    const DWARFDebugInfoEntry *die;
2169    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2170    {
2171        dw_tag_t tag = die->Tag();
2172        switch (tag)
2173        {
2174        case DW_TAG_formal_parameter:
2175            {
2176                DWARFDebugInfoEntry::Attributes attributes;
2177                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2178                if (num_attributes > 0)
2179                {
2180                    const char *name = NULL;
2181                    Declaration decl;
2182                    dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
2183                    // one of None, Auto, Register, Extern, Static, PrivateExtern
2184
2185                    clang::VarDecl::StorageClass storage = clang::VarDecl::None;
2186                    uint32_t i;
2187                    for (i=0; i<num_attributes; ++i)
2188                    {
2189                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2190                        DWARFFormValue form_value;
2191                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2192                        {
2193                            switch (attr)
2194                            {
2195                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2196                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2197                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2198                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
2199                            case DW_AT_type:        param_type_die_offset = form_value.Reference(dwarf_cu); break;
2200                            case DW_AT_location:
2201    //                          if (form_value.BlockData())
2202    //                          {
2203    //                              const DataExtractor& debug_info_data = debug_info();
2204    //                              uint32_t block_length = form_value.Unsigned();
2205    //                              DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2206    //                          }
2207    //                          else
2208    //                          {
2209    //                          }
2210    //                          break;
2211                            case DW_AT_artificial:
2212                            case DW_AT_const_value:
2213                            case DW_AT_default_value:
2214                            case DW_AT_description:
2215                            case DW_AT_endianity:
2216                            case DW_AT_is_optional:
2217                            case DW_AT_segment:
2218                            case DW_AT_variable_parameter:
2219                            default:
2220                            case DW_AT_abstract_origin:
2221                            case DW_AT_sibling:
2222                                break;
2223                            }
2224                        }
2225                    }
2226                    Type *dc_type = ResolveTypeUID(param_type_die_offset);
2227                    if (dc_type)
2228                    {
2229                        function_param_types.push_back (dc_type->GetOpaqueClangQualType());
2230
2231                        clang::ParmVarDecl *param_var_decl = type_list->GetClangASTContext().CreateParmeterDeclaration (name, dc_type->GetOpaqueClangQualType(), storage);
2232                        assert(param_var_decl);
2233                        function_param_decls.push_back(param_var_decl);
2234                    }
2235                }
2236            }
2237            break;
2238
2239        default:
2240            break;
2241        }
2242    }
2243    return count;
2244}
2245
2246size_t
2247SymbolFileDWARF::ParseChildEnumerators
2248(
2249    const SymbolContext& sc,
2250    TypeSP& type_sp,
2251    void * enumerator_qual_type,
2252    uint32_t enumerator_byte_size,
2253    const DWARFCompileUnit* dwarf_cu,
2254    const DWARFDebugInfoEntry *parent_die
2255)
2256{
2257    if (parent_die == NULL)
2258        return 0;
2259
2260    size_t enumerators_added = 0;
2261    const DWARFDebugInfoEntry *die;
2262    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2263    {
2264        const dw_tag_t tag = die->Tag();
2265        if (tag == DW_TAG_enumerator)
2266        {
2267            DWARFDebugInfoEntry::Attributes attributes;
2268            const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2269            if (num_child_attributes > 0)
2270            {
2271                const char *name = NULL;
2272                bool got_value = false;
2273                int64_t enum_value = 0;
2274                Declaration decl;
2275
2276                uint32_t i;
2277                for (i=0; i<num_child_attributes; ++i)
2278                {
2279                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
2280                    DWARFFormValue form_value;
2281                    if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2282                    {
2283                        switch (attr)
2284                        {
2285                        case DW_AT_const_value:
2286                            got_value = true;
2287                            enum_value = form_value.Unsigned();
2288                            break;
2289
2290                        case DW_AT_name:
2291                            name = form_value.AsCString(&get_debug_str_data());
2292                            break;
2293
2294                        case DW_AT_description:
2295                        default:
2296                        case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2297                        case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2298                        case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2299                        case DW_AT_sibling:
2300                            break;
2301                        }
2302                    }
2303                }
2304
2305                if (name && name[0] && got_value)
2306                {
2307                    TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2308                    type_list->GetClangASTContext().AddEnumerationValueToEnumerationType (type_sp->GetOpaqueClangQualType(), enumerator_qual_type, decl, name, enum_value, enumerator_byte_size * 8);
2309                    ++enumerators_added;
2310                }
2311            }
2312        }
2313    }
2314    return enumerators_added;
2315}
2316
2317void
2318SymbolFileDWARF::ParseChildArrayInfo
2319(
2320    const SymbolContext& sc,
2321    const DWARFCompileUnit* dwarf_cu,
2322    const DWARFDebugInfoEntry *parent_die,
2323    int64_t& first_index,
2324    std::vector<uint64_t>& element_orders,
2325    uint32_t& byte_stride,
2326    uint32_t& bit_stride
2327)
2328{
2329    if (parent_die == NULL)
2330        return;
2331
2332    const DWARFDebugInfoEntry *die;
2333    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2334    {
2335        const dw_tag_t tag = die->Tag();
2336        switch (tag)
2337        {
2338        case DW_TAG_enumerator:
2339            {
2340                DWARFDebugInfoEntry::Attributes attributes;
2341                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2342                if (num_child_attributes > 0)
2343                {
2344                    const char *name = NULL;
2345                    bool got_value = false;
2346                    int64_t enum_value = 0;
2347
2348                    uint32_t i;
2349                    for (i=0; i<num_child_attributes; ++i)
2350                    {
2351                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2352                        DWARFFormValue form_value;
2353                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2354                        {
2355                            switch (attr)
2356                            {
2357                            case DW_AT_const_value:
2358                                got_value = true;
2359                                enum_value = form_value.Unsigned();
2360                                break;
2361
2362                            case DW_AT_name:
2363                                name = form_value.AsCString(&get_debug_str_data());
2364                                break;
2365
2366                            case DW_AT_description:
2367                            default:
2368                            case DW_AT_decl_file:
2369                            case DW_AT_decl_line:
2370                            case DW_AT_decl_column:
2371                            case DW_AT_sibling:
2372                                break;
2373                            }
2374                        }
2375                    }
2376                }
2377            }
2378            break;
2379
2380        case DW_TAG_subrange_type:
2381            {
2382                DWARFDebugInfoEntry::Attributes attributes;
2383                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2384                if (num_child_attributes > 0)
2385                {
2386                    const char *name = NULL;
2387                    bool got_value = false;
2388                    uint64_t byte_size = 0;
2389                    int64_t enum_value = 0;
2390                    uint64_t num_elements = 0;
2391                    uint64_t lower_bound = 0;
2392                    uint64_t upper_bound = 0;
2393                    uint32_t i;
2394                    for (i=0; i<num_child_attributes; ++i)
2395                    {
2396                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2397                        DWARFFormValue form_value;
2398                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2399                        {
2400                            switch (attr)
2401                            {
2402                            case DW_AT_const_value:
2403                                got_value = true;
2404                                enum_value = form_value.Unsigned();
2405                                break;
2406
2407                            case DW_AT_name:
2408                                name = form_value.AsCString(&get_debug_str_data());
2409                                break;
2410
2411                            case DW_AT_count:
2412                                num_elements = form_value.Unsigned();
2413                                break;
2414
2415                            case DW_AT_bit_stride:
2416                                bit_stride = form_value.Unsigned();
2417                                break;
2418
2419                            case DW_AT_byte_stride:
2420                                byte_stride = form_value.Unsigned();
2421                                break;
2422
2423                            case DW_AT_byte_size:
2424                                byte_size = form_value.Unsigned();
2425                                break;
2426
2427                            case DW_AT_lower_bound:
2428                                lower_bound = form_value.Unsigned();
2429                                break;
2430
2431                            case DW_AT_upper_bound:
2432                                upper_bound = form_value.Unsigned();
2433                                break;
2434
2435                            default:
2436                                //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
2437
2438                            case DW_AT_abstract_origin:
2439                            case DW_AT_accessibility:
2440                            case DW_AT_allocated:
2441                            case DW_AT_associated:
2442                            case DW_AT_data_location:
2443                            case DW_AT_declaration:
2444                            case DW_AT_description:
2445                            case DW_AT_sibling:
2446                            case DW_AT_threads_scaled:
2447                            case DW_AT_type:
2448                            case DW_AT_visibility:
2449                                break;
2450                            }
2451                        }
2452                    }
2453
2454                    if (upper_bound > lower_bound)
2455                        num_elements = upper_bound - lower_bound + 1;
2456
2457                    if (num_elements > 0)
2458                        element_orders.push_back (num_elements);
2459                }
2460            }
2461            break;
2462        }
2463    }
2464}
2465
2466Type*
2467SymbolFileDWARF::GetUniquedTypeForDIEOffset(dw_offset_t type_die_offset, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx, bool safe)
2468{
2469    if (type_die_offset != DW_INVALID_OFFSET)
2470    {
2471        DWARFCompileUnitSP cu_sp;
2472        const DWARFDebugInfoEntry* type_die = DebugInfo()->GetDIEPtr(type_die_offset, &cu_sp);
2473        assert(type_die != NULL);
2474        GetTypeForDIE(cu_sp.get(), type_die, owning_type_sp, child_type, idx);
2475        // Return the uniqued type if there is one
2476        Type* type = (Type*)type_die->GetUserData();
2477        if (type == DIE_IS_BEING_PARSED && safe)
2478            return NULL;
2479        return type;
2480    }
2481    return NULL;
2482}
2483
2484TypeSP
2485SymbolFileDWARF::GetTypeForDIE(DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die, TypeSP& owning_type_sp, int32_t child_type, uint32_t idx)
2486{
2487    TypeSP type_sp;
2488    if (die != NULL)
2489    {
2490        assert(cu != NULL);
2491        Type *type_ptr = (Type *)die->GetUserData();
2492        if (type_ptr == NULL)
2493        {
2494            SymbolContext sc(GetCompUnitForDWARFCompUnit(cu));
2495            bool type_is_new = false;
2496            type_sp = ParseType(sc, cu, die, type_is_new);
2497            type_ptr = (Type *)die->GetUserData();
2498            if (owning_type_sp.get() == NULL)
2499                owning_type_sp = type_sp;
2500        }
2501        else if (type_ptr != DIE_IS_BEING_PARSED)
2502        {
2503            // Grab the existing type from the master types lists
2504            type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(type_ptr->GetID());
2505        }
2506
2507    }
2508    return type_sp;
2509}
2510
2511clang::DeclContext *
2512SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2513{
2514    if (die_offset != DW_INVALID_OFFSET)
2515    {
2516        DWARFCompileUnitSP cu_sp;
2517        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2518        return GetClangDeclContextForDIE (cu_sp.get(), die);
2519    }
2520    return NULL;
2521}
2522
2523
2524
2525clang::DeclContext *
2526SymbolFileDWARF::GetClangDeclContextForDIE (const DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
2527{
2528    DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2529    if (pos != m_die_to_decl_ctx.end())
2530        return pos->second;
2531
2532    while (die != NULL)
2533    {
2534        switch (die->Tag())
2535        {
2536        case DW_TAG_namespace:
2537            {
2538                const char *namespace_name = die->GetAttributeValueAsString(this, cu, DW_AT_name, NULL);
2539                if (namespace_name)
2540                {
2541                    TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2542                    assert(type_list);
2543                    Declaration decl;   // TODO: fill in the decl object
2544                    clang::NamespaceDecl *namespace_decl = type_list->GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (cu, die->GetParent()));
2545                    if (namespace_decl)
2546                        m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2547                    return namespace_decl;
2548                }
2549            }
2550            break;
2551
2552        default:
2553            break;
2554        }
2555        clang::DeclContext *decl_ctx;
2556        decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_specification, DW_INVALID_OFFSET));
2557        if (decl_ctx)
2558            return decl_ctx;
2559
2560        decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2561        if (decl_ctx)
2562            return decl_ctx;
2563
2564        die = die->GetParent();
2565    }
2566    return NULL;
2567}
2568
2569TypeSP
2570SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool &type_is_new)
2571{
2572    TypeSP type_sp;
2573
2574    ClangASTContext::AccessType accessibility = ClangASTContext::eAccessNone;
2575    if (die != NULL)
2576    {
2577        dw_tag_t tag = die->Tag();
2578        if (die->GetUserData() == NULL)
2579        {
2580            type_is_new = true;
2581
2582            bool is_forward_declaration = false;
2583            DWARFDebugInfoEntry::Attributes attributes;
2584            const char *type_name_cstr = NULL;
2585            ConstString type_name_dbstr;
2586            Type::EncodingUIDType encoding_uid_type = Type::eIsTypeWithUID;
2587            void *clang_type = NULL;
2588
2589            TypeList* type_list = m_obj_file->GetModule()->GetTypeList();
2590            dw_attr_t attr;
2591
2592            switch (tag)
2593            {
2594            case DW_TAG_base_type:
2595            case DW_TAG_pointer_type:
2596            case DW_TAG_reference_type:
2597            case DW_TAG_typedef:
2598            case DW_TAG_const_type:
2599            case DW_TAG_restrict_type:
2600            case DW_TAG_volatile_type:
2601                {
2602                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2603                    // Set a bit that lets us know that we are currently parsing this
2604                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2605
2606                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2607                    Declaration decl;
2608                    uint32_t encoding = 0;
2609                    size_t byte_size = 0;
2610                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2611
2612                    if (num_attributes > 0)
2613                    {
2614                        uint32_t i;
2615                        for (i=0; i<num_attributes; ++i)
2616                        {
2617                            attr = attributes.AttributeAtIndex(i);
2618                            DWARFFormValue form_value;
2619                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2620                            {
2621                                switch (attr)
2622                                {
2623                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2624                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2625                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2626                                case DW_AT_name:
2627                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
2628                                    type_name_dbstr.SetCString(type_name_cstr);
2629                                    break;
2630                                case DW_AT_byte_size:   byte_size = form_value.Unsigned();  break;
2631                                case DW_AT_encoding:    encoding = form_value.Unsigned(); break;
2632                                case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
2633                                default:
2634                                case DW_AT_sibling:
2635                                    break;
2636                                }
2637                            }
2638                        }
2639                    }
2640
2641                    switch (tag)
2642                    {
2643                    default:
2644                    case DW_TAG_base_type:
2645                        clang_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, encoding, byte_size * 8);
2646                        break;
2647
2648                    case DW_TAG_pointer_type:
2649                        // The encoding_uid will be embedded into the
2650                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2651                        encoding_uid_type = Type::ePointerToTypeWithUID;
2652                        break;
2653
2654                    case DW_TAG_reference_type:
2655                        // The encoding_uid will be embedded into the
2656                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2657                        encoding_uid_type = Type::eLValueReferenceToTypeWithUID;
2658                        break;
2659
2660                    case DW_TAG_typedef:
2661                        // The encoding_uid will be embedded into the
2662                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2663                        encoding_uid_type = Type::eTypedefToTypeWithUID;
2664                        break;
2665
2666                    case DW_TAG_const_type:
2667                        // The encoding_uid will be embedded into the
2668                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2669                        encoding_uid_type = Type::eIsConstTypeWithUID; //ClangASTContext::AddConstModifier (clang_type);
2670                        break;
2671
2672                    case DW_TAG_restrict_type:
2673                        // The encoding_uid will be embedded into the
2674                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2675                        encoding_uid_type = Type::eIsRestrictTypeWithUID; //ClangASTContext::AddRestrictModifier (clang_type);
2676                        break;
2677
2678                    case DW_TAG_volatile_type:
2679                        // The encoding_uid will be embedded into the
2680                        // Type object and will be looked up when the Type::GetOpaqueClangQualType()
2681                        encoding_uid_type = Type::eIsVolatileTypeWithUID; //ClangASTContext::AddVolatileModifier (clang_type);
2682                        break;
2683                    }
2684
2685                    type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, encoding_uid_type, &decl, clang_type));
2686
2687                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2688
2689
2690//                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2691//                  if (encoding_type != NULL)
2692//                  {
2693//                      if (encoding_type != DIE_IS_BEING_PARSED)
2694//                          type_sp->SetEncodingType(encoding_type);
2695//                      else
2696//                          m_indirect_fixups.push_back(type_sp.get());
2697//                  }
2698                }
2699                break;
2700
2701            case DW_TAG_structure_type:
2702            case DW_TAG_union_type:
2703            case DW_TAG_class_type:
2704                {
2705                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2706                    // Set a bit that lets us know that we are currently parsing this
2707                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2708
2709                    size_t byte_size = 0;
2710                    //bool struct_is_class = false;
2711                    Declaration decl;
2712                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2713                    if (num_attributes > 0)
2714                    {
2715                        uint32_t i;
2716                        for (i=0; i<num_attributes; ++i)
2717                        {
2718                            attr = attributes.AttributeAtIndex(i);
2719                            DWARFFormValue form_value;
2720                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2721                            {
2722                                switch (attr)
2723                                {
2724                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2725                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2726                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2727                                case DW_AT_name:
2728                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
2729                                    type_name_dbstr.SetCString(type_name_cstr);
2730                                    break;
2731                                case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
2732                                case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break; break;
2733                                case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2734                                case DW_AT_allocated:
2735                                case DW_AT_associated:
2736                                case DW_AT_data_location:
2737                                case DW_AT_description:
2738                                case DW_AT_start_scope:
2739                                case DW_AT_visibility:
2740                                default:
2741                                case DW_AT_sibling:
2742                                    break;
2743                                }
2744                            }
2745                        }
2746                    }
2747
2748                    int tag_decl_kind = -1;
2749                    ClangASTContext::AccessType default_accessibility = ClangASTContext::eAccessNone;
2750                    if (tag == DW_TAG_structure_type)
2751                    {
2752                        tag_decl_kind = clang::TTK_Struct;
2753                        default_accessibility = ClangASTContext::eAccessPublic;
2754                    }
2755                    else if (tag == DW_TAG_union_type)
2756                    {
2757                        tag_decl_kind = clang::TTK_Union;
2758                        default_accessibility = ClangASTContext::eAccessPublic;
2759                    }
2760                    else if (tag == DW_TAG_class_type)
2761                    {
2762                        tag_decl_kind = clang::TTK_Class;
2763                        default_accessibility = ClangASTContext::eAccessPrivate;
2764                    }
2765
2766                    assert (tag_decl_kind != -1);
2767                    clang_type = type_list->GetClangASTContext().CreateRecordType (type_name_cstr, tag_decl_kind, GetClangDeclContextForDIE (dwarf_cu, die));
2768
2769                    m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2770                    type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
2771
2772                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2773
2774//                  assert(type_sp.get());
2775//                  if (accessibility)
2776//                      type_sp->SetAccess(accessibility);
2777//
2778                    type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2779                    if (die->HasChildren())
2780                    {
2781                        std::vector<clang::CXXBaseSpecifier *> base_classes;
2782                        std::vector<int> member_accessibilities;
2783                        bool is_a_class = false;
2784                        ParseChildMembers(sc, type_sp, dwarf_cu, die, base_classes, member_accessibilities, default_accessibility, is_a_class);
2785                        // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2786                        // need to tell the clang type it is actually a class.
2787                        if (is_a_class && tag_decl_kind != clang::TTK_Class)
2788                            type_list->GetClangASTContext().SetTagTypeKind (clang_type, clang::TTK_Class);
2789
2790                        // Since DW_TAG_structure_type gets used for both classes
2791                        // and structures, we may need to set any DW_TAG_member
2792                        // fields to have a "private" access if none was specified.
2793                        // When we parsed the child members we tracked that actual
2794                        // accessibility value for each DW_TAG_member in the
2795                        // "member_accessibilities" array. If the value for the
2796                        // member is zero, then it was set to the "default_accessibility"
2797                        // which for structs was "public". Below we correct this
2798                        // by setting any fields to "private" that weren't correctly
2799                        // set.
2800                        if (is_a_class && !member_accessibilities.empty())
2801                        {
2802                            // This is a class and all members that didn't have
2803                            // their access specified are private.
2804                            type_list->GetClangASTContext().SetDefaultAccessForRecordFields (clang_type, ClangASTContext::eAccessPrivate, &member_accessibilities.front(), member_accessibilities.size());
2805                        }
2806
2807                        if (!base_classes.empty())
2808                        {
2809                            type_list->GetClangASTContext().SetBaseClassesForClassType (clang_type, &base_classes.front(), base_classes.size());
2810
2811                            // Clang will copy each CXXBaseSpecifier in "base_classes"
2812                            // so we have to free them all.
2813                            ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(), base_classes.size());
2814                        }
2815
2816                    }
2817                    type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2818                }
2819                break;
2820
2821            case DW_TAG_enumeration_type:
2822                {
2823                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2824                    // Set a bit that lets us know that we are currently parsing this
2825                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2826
2827                    size_t byte_size = 0;
2828                    lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
2829                    Declaration decl;
2830
2831                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2832                    if (num_attributes > 0)
2833                    {
2834                        uint32_t i;
2835
2836                        for (i=0; i<num_attributes; ++i)
2837                        {
2838                            attr = attributes.AttributeAtIndex(i);
2839                            DWARFFormValue form_value;
2840                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2841                            {
2842                                switch (attr)
2843                                {
2844                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2845                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2846                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2847                                case DW_AT_name:
2848                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
2849                                    type_name_dbstr.SetCString(type_name_cstr);
2850                                    break;
2851                                case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
2852                                case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
2853                                case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
2854                                case DW_AT_declaration: is_forward_declaration = form_value.Unsigned() != 0; break;
2855                                case DW_AT_allocated:
2856                                case DW_AT_associated:
2857                                case DW_AT_bit_stride:
2858                                case DW_AT_byte_stride:
2859                                case DW_AT_data_location:
2860                                case DW_AT_description:
2861                                case DW_AT_start_scope:
2862                                case DW_AT_visibility:
2863                                case DW_AT_specification:
2864                                case DW_AT_abstract_origin:
2865                                case DW_AT_sibling:
2866                                    break;
2867                                }
2868                            }
2869                        }
2870
2871                        clang_type = type_list->GetClangASTContext().CreateEnumerationType(decl, type_name_cstr);
2872                        m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2873                        type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, encoding_uid, Type::eIsTypeWithUID, &decl, clang_type));
2874
2875                        const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
2876
2877                        if (die->HasChildren())
2878                        {
2879                            type_list->GetClangASTContext().StartTagDeclarationDefinition (clang_type);
2880                            void *enumerator_qual_type = type_list->GetClangASTContext().GetBuiltinTypeForDWARFEncodingAndBitSize (NULL, DW_ATE_signed, byte_size * 8);
2881                            ParseChildEnumerators(sc, type_sp, enumerator_qual_type, byte_size, dwarf_cu, die);
2882                            type_list->GetClangASTContext().CompleteTagDeclarationDefinition (clang_type);
2883                        }
2884                    }
2885                }
2886                break;
2887
2888            case DW_TAG_subprogram:
2889            case DW_TAG_subroutine_type:
2890                {
2891                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
2892                    // Set a bit that lets us know that we are currently parsing this
2893                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
2894
2895                    const char *mangled = NULL;
2896                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
2897                    Declaration decl;
2898                    bool isVariadic = false;
2899                    bool is_inline = false;
2900                    unsigned type_quals = 0;
2901                    clang::FunctionDecl::StorageClass storage = clang::FunctionDecl::None;//, Extern, Static, PrivateExtern
2902
2903
2904                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
2905                    if (num_attributes > 0)
2906                    {
2907                        uint32_t i;
2908                        for (i=0; i<num_attributes; ++i)
2909                        {
2910                            attr = attributes.AttributeAtIndex(i);
2911                            DWARFFormValue form_value;
2912                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2913                            {
2914                                switch (attr)
2915                                {
2916                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2917                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2918                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2919                                case DW_AT_name:
2920                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
2921                                    type_name_dbstr.SetCString(type_name_cstr);
2922                                    break;
2923
2924                                case DW_AT_MIPS_linkage_name:   mangled = form_value.AsCString(&get_debug_str_data()); break;
2925                                case DW_AT_type:                type_die_offset = form_value.Reference(dwarf_cu); break;
2926                                case DW_AT_accessibility:       accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
2927                                case DW_AT_declaration:         is_forward_declaration = form_value.Unsigned() != 0; break;
2928                                case DW_AT_external:
2929                                    if (form_value.Unsigned())
2930                                    {
2931                                        if (storage == clang::FunctionDecl::None)
2932                                            storage = clang::FunctionDecl::Extern;
2933                                        else
2934                                            storage = clang::FunctionDecl::PrivateExtern;
2935                                    }
2936                                    break;
2937                                case DW_AT_inline:
2938                                    is_inline = form_value.Unsigned() != 0;
2939                                    break;
2940
2941                                case DW_AT_allocated:
2942                                case DW_AT_associated:
2943                                case DW_AT_address_class:
2944                                case DW_AT_artificial:
2945                                case DW_AT_calling_convention:
2946                                case DW_AT_data_location:
2947                                case DW_AT_elemental:
2948                                case DW_AT_entry_pc:
2949                                case DW_AT_explicit:
2950                                case DW_AT_frame_base:
2951                                case DW_AT_high_pc:
2952                                case DW_AT_low_pc:
2953                                case DW_AT_object_pointer:
2954                                case DW_AT_prototyped:
2955                                case DW_AT_pure:
2956                                case DW_AT_ranges:
2957                                case DW_AT_recursive:
2958                                case DW_AT_return_addr:
2959                                case DW_AT_segment:
2960                                case DW_AT_specification:
2961                                case DW_AT_start_scope:
2962                                case DW_AT_static_link:
2963                                case DW_AT_trampoline:
2964                                case DW_AT_visibility:
2965                                case DW_AT_virtuality:
2966                                case DW_AT_vtable_elem_location:
2967                                case DW_AT_abstract_origin:
2968                                case DW_AT_description:
2969                                case DW_AT_sibling:
2970                                    break;
2971                                }
2972                            }
2973                        }
2974
2975                        void *return_clang_type = NULL;
2976                        Type *func_type = ResolveTypeUID(type_die_offset);
2977                        if (func_type)
2978                            return_clang_type = func_type->GetOpaqueClangQualType();
2979                        else
2980                            return_clang_type = type_list->GetClangASTContext().GetVoidBuiltInType();
2981
2982                        std::vector<void *> function_param_types;
2983                        std::vector<clang::ParmVarDecl*> function_param_decls;
2984
2985                        // Parse the function children for the parameters
2986                        ParseChildParameters(sc, type_sp, dwarf_cu, die, type_list, function_param_types, function_param_decls);
2987
2988                        clang_type = type_list->GetClangASTContext().CreateFunctionType (return_clang_type, &function_param_types[0], function_param_types.size(), isVariadic, type_quals);
2989                        if (type_name_cstr)
2990                        {
2991                            clang::FunctionDecl *function_decl = type_list->GetClangASTContext().CreateFunctionDeclaration (type_name_cstr, clang_type, storage, is_inline);
2992                            // Add the decl to our DIE to decl context map
2993                            assert (function_decl);
2994                            m_die_to_decl_ctx[die] = function_decl;
2995                            if (!function_param_decls.empty())
2996                                type_list->GetClangASTContext().SetFunctionParameters (function_decl, &function_param_decls.front(), function_param_decls.size());
2997                        }
2998                        type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, 0, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
2999
3000                        const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3001                        assert(type_sp.get());
3002                    }
3003                }
3004                break;
3005
3006            case DW_TAG_array_type:
3007                {
3008                    //printf("0x%8.8x: %s (ParesTypes)\n", die->GetOffset(), DW_TAG_value_to_name(tag));
3009                    // Set a bit that lets us know that we are currently parsing this
3010                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(DIE_IS_BEING_PARSED);
3011
3012                    size_t byte_size = 0;
3013                    lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3014                    Declaration decl;
3015                    int64_t first_index = 0;
3016                    uint32_t byte_stride = 0;
3017                    uint32_t bit_stride = 0;
3018                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3019
3020                    if (num_attributes > 0)
3021                    {
3022                        uint32_t i;
3023                        for (i=0; i<num_attributes; ++i)
3024                        {
3025                            attr = attributes.AttributeAtIndex(i);
3026                            DWARFFormValue form_value;
3027                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3028                            {
3029                                switch (attr)
3030                                {
3031                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3032                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3033                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3034                                case DW_AT_name:
3035                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3036                                    type_name_dbstr.SetCString(type_name_cstr);
3037                                    break;
3038
3039                                case DW_AT_type:            type_die_offset = form_value.Reference(dwarf_cu); break;
3040                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;
3041                                case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break;
3042                                case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break;
3043                                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3044                                case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
3045                                case DW_AT_allocated:
3046                                case DW_AT_associated:
3047                                case DW_AT_data_location:
3048                                case DW_AT_description:
3049                                case DW_AT_ordering:
3050                                case DW_AT_start_scope:
3051                                case DW_AT_visibility:
3052                                case DW_AT_specification:
3053                                case DW_AT_abstract_origin:
3054                                case DW_AT_sibling:
3055                                    break;
3056                                }
3057                            }
3058                        }
3059
3060                        Type *element_type = ResolveTypeUID(type_die_offset);
3061
3062                        if (element_type)
3063                        {
3064                            std::vector<uint64_t> element_orders;
3065                            ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
3066                            if (byte_stride == 0 && bit_stride == 0)
3067                                byte_stride = element_type->GetByteSize();
3068                            void *array_element_type = element_type->GetOpaqueClangQualType();
3069                            uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3070                            uint64_t num_elements = 0;
3071                            std::vector<uint64_t>::const_reverse_iterator pos;
3072                            std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3073                            for (pos = element_orders.rbegin(); pos != end; ++pos)
3074                            {
3075                                num_elements = *pos;
3076                                clang_type = type_list->GetClangASTContext().CreateArrayType (array_element_type, num_elements, num_elements * array_element_bit_stride);
3077                                array_element_type = clang_type;
3078                                array_element_bit_stride = array_element_bit_stride * num_elements;
3079                            }
3080                            ConstString empty_name;
3081                            type_sp.reset( new Type(die->GetOffset(), this, empty_name, array_element_bit_stride / 8, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, &decl, clang_type));
3082                            const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3083                        }
3084                    }
3085                }
3086                break;
3087
3088            case DW_TAG_ptr_to_member_type:
3089                {
3090                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3091                    dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3092
3093                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3094
3095                    if (num_attributes > 0) {
3096                        uint32_t i;
3097                        for (i=0; i<num_attributes; ++i)
3098                        {
3099                            attr = attributes.AttributeAtIndex(i);
3100                            DWARFFormValue form_value;
3101                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3102                            {
3103                                switch (attr)
3104                                {
3105                                    case DW_AT_type:
3106                                        type_die_offset = form_value.Reference(dwarf_cu); break;
3107                                    case DW_AT_containing_type:
3108                                        containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3109                                }
3110                            }
3111                        }
3112
3113                        Type *pointee_type = ResolveTypeUID(type_die_offset);
3114                        Type *class_type = ResolveTypeUID(containing_type_die_offset);
3115
3116                        void *pointee_clang_type = pointee_type->GetOpaqueClangQualType();
3117                        void *class_clang_type = class_type->GetOpaqueClangQualType();
3118
3119                        clang_type = type_list->GetClangASTContext().CreateMemberPointerType(pointee_clang_type, class_clang_type);
3120
3121                        size_t byte_size = ClangASTContext::GetTypeBitSize(type_list->GetClangASTContext().getASTContext(), clang_type) / 8;
3122
3123                        type_sp.reset( new Type(die->GetOffset(), this, type_name_dbstr, byte_size, NULL, LLDB_INVALID_UID, Type::eIsTypeWithUID, NULL, clang_type));
3124                        const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(type_sp.get());
3125                    }
3126
3127                    break;
3128                }
3129            default:
3130                assert(false && "Unhandled type tag!");
3131                break;
3132            }
3133
3134            if (type_sp.get())
3135            {
3136                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3137                dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3138
3139                SymbolContextScope * symbol_context_scope = NULL;
3140                if (sc_parent_tag == DW_TAG_compile_unit)
3141                {
3142                    symbol_context_scope = sc.comp_unit;
3143                }
3144                else if (sc.function != NULL)
3145                {
3146                    symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3147                    if (symbol_context_scope == NULL)
3148                        symbol_context_scope = sc.function;
3149                }
3150
3151                if (symbol_context_scope != NULL)
3152                {
3153                    type_sp->SetSymbolContextScope(symbol_context_scope);
3154                }
3155
3156//              if (udt_sp.get())
3157//              {
3158//                  if (is_forward_declaration)
3159//                      udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3160//                  type_sp->SetUserDefinedType(udt_sp);
3161//              }
3162
3163                if (type_sp.unique())
3164                {
3165                    // We are ready to put this type into the uniqued list up at the module level
3166                    TypeSP uniqued_type_sp(m_obj_file->GetModule()->GetTypeList()->InsertUnique(type_sp));
3167
3168                    const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(uniqued_type_sp.get());
3169
3170                    type_sp = uniqued_type_sp;
3171                }
3172            }
3173        }
3174        else
3175        {
3176            switch (tag)
3177            {
3178            case DW_TAG_base_type:
3179            case DW_TAG_pointer_type:
3180            case DW_TAG_reference_type:
3181            case DW_TAG_typedef:
3182            case DW_TAG_const_type:
3183            case DW_TAG_restrict_type:
3184            case DW_TAG_volatile_type:
3185            case DW_TAG_structure_type:
3186            case DW_TAG_union_type:
3187            case DW_TAG_class_type:
3188            case DW_TAG_enumeration_type:
3189            case DW_TAG_subprogram:
3190            case DW_TAG_subroutine_type:
3191            case DW_TAG_array_type:
3192                {
3193                    Type *existing_type = (Type*)die->GetUserData();
3194                    if (existing_type != DIE_IS_BEING_PARSED)
3195                    {
3196                        type_sp = m_obj_file->GetModule()->GetTypeList()->FindType(existing_type->GetID());
3197                    }
3198                }
3199                break;
3200            default:
3201                //assert(!"invalid type tag...");
3202                break;
3203            }
3204        }
3205    }
3206    return type_sp;
3207}
3208
3209size_t
3210SymbolFileDWARF::ParseTypes (const SymbolContext& sc, const DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool parse_siblings, bool parse_children)
3211{
3212    size_t types_added = 0;
3213    while (die != NULL)
3214    {
3215        bool type_is_new = false;
3216        if (ParseType(sc, dwarf_cu, die, type_is_new).get())
3217        {
3218            if (type_is_new)
3219                ++types_added;
3220        }
3221
3222        if (parse_children && die->HasChildren())
3223        {
3224            if (die->Tag() == DW_TAG_subprogram)
3225            {
3226                SymbolContext child_sc(sc);
3227                child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3228                types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3229            }
3230            else
3231                types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3232        }
3233
3234        if (parse_siblings)
3235            die = die->GetSibling();
3236        else
3237            die = NULL;
3238    }
3239    return types_added;
3240}
3241
3242
3243size_t
3244SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3245{
3246    assert(sc.comp_unit && sc.function);
3247    size_t functions_added = 0;
3248    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3249    if (dwarf_cu)
3250    {
3251        dw_offset_t function_die_offset = sc.function->GetID();
3252        const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3253        if (function_die)
3254        {
3255            ParseFunctionBlocks(sc, Block::RootID, dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
3256        }
3257    }
3258
3259    return functions_added;
3260}
3261
3262
3263size_t
3264SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3265{
3266    // At least a compile unit must be valid
3267    assert(sc.comp_unit);
3268    size_t types_added = 0;
3269    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3270    if (dwarf_cu)
3271    {
3272        if (sc.function)
3273        {
3274            dw_offset_t function_die_offset = sc.function->GetID();
3275            const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3276            if (func_die && func_die->HasChildren())
3277            {
3278                types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3279            }
3280        }
3281        else
3282        {
3283            const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3284            if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3285            {
3286                types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3287            }
3288        }
3289    }
3290
3291    return types_added;
3292}
3293
3294size_t
3295SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3296{
3297    if (sc.comp_unit != NULL)
3298    {
3299        DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3300
3301        if (dwarf_cu == NULL)
3302            return 0;
3303
3304        if (sc.function)
3305        {
3306            const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
3307            return ParseVariables(sc, dwarf_cu, function_die->GetFirstChild(), true, true);
3308        }
3309        else if (sc.comp_unit)
3310        {
3311            uint32_t vars_added = 0;
3312            VariableListSP variables (sc.comp_unit->GetVariableList(false));
3313
3314            if (variables.get() == NULL)
3315            {
3316                variables.reset(new VariableList());
3317                sc.comp_unit->SetVariableList(variables);
3318
3319                // Index if we already haven't to make sure the compile units
3320                // get indexed and make their global DIE index list
3321                if (!m_indexed)
3322                    Index ();
3323
3324                const size_t num_globals = dwarf_cu->GetNumGlobals();
3325                for (size_t idx=0; idx<num_globals; ++idx)
3326                {
3327                    VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetGlobalDIEAtIndex (idx)));
3328                    if (var_sp)
3329                    {
3330                        variables->AddVariable(var_sp);
3331                        ++vars_added;
3332                    }
3333                }
3334            }
3335            return vars_added;
3336        }
3337    }
3338    return 0;
3339}
3340
3341
3342VariableSP
3343SymbolFileDWARF::ParseVariableDIE
3344(
3345    const SymbolContext& sc,
3346    const DWARFCompileUnit* dwarf_cu,
3347    const DWARFDebugInfoEntry *die
3348)
3349{
3350
3351    VariableSP var_sp;
3352
3353    const dw_tag_t tag = die->Tag();
3354    DWARFDebugInfoEntry::Attributes attributes;
3355    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, attributes);
3356    if (num_attributes > 0)
3357    {
3358        const char *name = NULL;
3359        Declaration decl;
3360        uint32_t i;
3361        TypeSP type_sp;
3362        Type *var_type = NULL;
3363        DWARFExpression location;
3364        bool is_external = false;
3365        bool is_artificial = false;
3366        ClangASTContext::AccessType accessibility = ClangASTContext::eAccessNone;
3367
3368        for (i=0; i<num_attributes; ++i)
3369        {
3370            dw_attr_t attr = attributes.AttributeAtIndex(i);
3371            DWARFFormValue form_value;
3372            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3373            {
3374                switch (attr)
3375                {
3376                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3377                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3378                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3379                case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
3380                case DW_AT_type:        var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break;
3381                case DW_AT_external:    is_external = form_value.Unsigned() != 0; break;
3382                case DW_AT_location:
3383                    {
3384                        if (form_value.BlockData())
3385                        {
3386                            const DataExtractor& debug_info_data = get_debug_info_data();
3387
3388                            uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3389                            uint32_t block_length = form_value.Unsigned();
3390                            location.SetOpcodeData(get_debug_info_data(), block_offset, block_length, NULL);
3391                        }
3392                        else
3393                        {
3394                            const DataExtractor&    debug_loc_data = get_debug_loc_data();
3395                            const dw_offset_t debug_loc_offset = form_value.Unsigned();
3396
3397                            size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3398                            if (loc_list_length > 0)
3399                            {
3400                                Address base_address(dwarf_cu->GetBaseAddress(), m_obj_file->GetSectionList());
3401                                location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length, &base_address);
3402                            }
3403                        }
3404                    }
3405                    break;
3406
3407                case DW_AT_artificial:      is_artificial = form_value.Unsigned() != 0; break;
3408                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3409                case DW_AT_const_value:
3410                case DW_AT_declaration:
3411                case DW_AT_description:
3412                case DW_AT_endianity:
3413                case DW_AT_segment:
3414                case DW_AT_start_scope:
3415                case DW_AT_visibility:
3416                default:
3417                case DW_AT_abstract_origin:
3418                case DW_AT_sibling:
3419                case DW_AT_specification:
3420                    break;
3421                }
3422            }
3423        }
3424
3425        if (location.IsValid())
3426        {
3427            assert(var_type != DIE_IS_BEING_PARSED);
3428
3429            ConstString var_name(name);
3430
3431            ValueType scope = eValueTypeInvalid;
3432
3433            const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3434            dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3435
3436            if (tag == DW_TAG_formal_parameter)
3437                scope = eValueTypeVariableArgument;
3438            else if (is_external || parent_tag == DW_TAG_compile_unit)
3439                scope = eValueTypeVariableGlobal;
3440            else
3441                scope = eValueTypeVariableLocal;
3442
3443            SymbolContextScope * symbol_context_scope = NULL;
3444            if (parent_tag == DW_TAG_compile_unit)
3445            {
3446                symbol_context_scope = sc.comp_unit;
3447            }
3448            else if (sc.function != NULL)
3449            {
3450                symbol_context_scope = sc.function->GetBlocks(true).GetBlockByID(sc_parent_die->GetOffset());
3451                if (symbol_context_scope == NULL)
3452                    symbol_context_scope = sc.function;
3453            }
3454
3455            assert(symbol_context_scope != NULL);
3456            var_sp.reset (new Variable(die->GetOffset(),
3457                                       var_name,
3458                                       var_type,
3459                                       scope,
3460                                       symbol_context_scope,
3461                                       &decl,
3462                                       location,
3463                                       is_external,
3464                                       is_artificial));
3465            const_cast<DWARFDebugInfoEntry*>(die)->SetUserData(var_sp.get());
3466        }
3467    }
3468    return var_sp;
3469}
3470
3471size_t
3472SymbolFileDWARF::ParseVariables
3473(
3474    const SymbolContext& sc,
3475    const DWARFCompileUnit* dwarf_cu,
3476    const DWARFDebugInfoEntry *orig_die,
3477    bool parse_siblings,
3478    bool parse_children,
3479    VariableList* cc_variable_list
3480)
3481{
3482    if (orig_die == NULL)
3483        return 0;
3484
3485    size_t vars_added = 0;
3486    const DWARFDebugInfoEntry *die = orig_die;
3487    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3488    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3489    VariableListSP variables;
3490    switch (parent_tag)
3491    {
3492    case DW_TAG_compile_unit:
3493        if (sc.comp_unit != NULL)
3494        {
3495            variables = sc.comp_unit->GetVariableList(false);
3496            if (variables.get() == NULL)
3497            {
3498                variables.reset(new VariableList());
3499                sc.comp_unit->SetVariableList(variables);
3500            }
3501        }
3502        else
3503        {
3504            assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3505            vars_added = 0;
3506        }
3507        break;
3508
3509    case DW_TAG_subprogram:
3510    case DW_TAG_inlined_subroutine:
3511    case DW_TAG_lexical_block:
3512        if (sc.function != NULL)
3513        {
3514            // Check to see if we already have parsed the variables for the given scope
3515            variables = sc.function->GetBlocks(true).GetVariableList(sc_parent_die->GetOffset(), false, false);
3516            if (variables.get() == NULL)
3517            {
3518                variables.reset(new VariableList());
3519                sc.function->GetBlocks(true).SetVariableList(sc_parent_die->GetOffset(), variables);
3520            }
3521        }
3522        else
3523        {
3524            assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3525            vars_added = 0;
3526        }
3527        break;
3528
3529    default:
3530        assert(!"Didn't find appropriate parent DIE for variable list...");
3531        break;
3532    }
3533
3534    // We need to have a variable list at this point that we can add variables to
3535    assert(variables.get());
3536
3537    while (die != NULL)
3538    {
3539        dw_tag_t tag = die->Tag();
3540
3541        // Check to see if we have already parsed this variable or constant?
3542        if (die->GetUserData() == NULL)
3543        {
3544            // We haven't already parsed it, lets do that now.
3545            if ((tag == DW_TAG_variable) ||
3546                (tag == DW_TAG_constant) ||
3547                (tag == DW_TAG_formal_parameter && sc.function))
3548            {
3549                VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die));
3550                if (var_sp)
3551                {
3552                    variables->AddVariable(var_sp);
3553                    ++vars_added;
3554                }
3555            }
3556        }
3557
3558        bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3559
3560        if (!skip_children && parse_children && die->HasChildren())
3561        {
3562            vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), true, true);
3563            //vars_added += ParseVariables(sc, dwarf_cu, die->GetFirstChild(), parse_siblings, parse_children);
3564        }
3565
3566        if (parse_siblings)
3567            die = die->GetSibling();
3568        else
3569            die = NULL;
3570    }
3571
3572    if (cc_variable_list)
3573    {
3574        cc_variable_list->AddVariables(variables.get());
3575    }
3576
3577    return vars_added;
3578}
3579
3580//------------------------------------------------------------------
3581// PluginInterface protocol
3582//------------------------------------------------------------------
3583const char *
3584SymbolFileDWARF::GetPluginName()
3585{
3586    return "SymbolFileDWARF";
3587}
3588
3589const char *
3590SymbolFileDWARF::GetShortPluginName()
3591{
3592    return GetPluginNameStatic();
3593}
3594
3595uint32_t
3596SymbolFileDWARF::GetPluginVersion()
3597{
3598    return 1;
3599}
3600
3601void
3602SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3603{
3604}
3605
3606Error
3607SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3608{
3609    Error error;
3610    error.SetErrorString("No plug-in command are currently supported.");
3611    return error;
3612}
3613
3614Log *
3615SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3616{
3617    return NULL;
3618}
3619
3620