SymbolFileDWARF.cpp revision 99309909259eacf4693458bfe44f913c316a09c6
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#include "clang/Sema/DeclSpec.h"
24
25#include "llvm/Support/Casting.h"
26
27#include "lldb/Core/Module.h"
28#include "lldb/Core/PluginManager.h"
29#include "lldb/Core/RegularExpression.h"
30#include "lldb/Core/Scalar.h"
31#include "lldb/Core/Section.h"
32#include "lldb/Core/StreamFile.h"
33#include "lldb/Core/Timer.h"
34#include "lldb/Core/Value.h"
35
36#include "lldb/Symbol/Block.h"
37#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
38#include "lldb/Symbol/CompileUnit.h"
39#include "lldb/Symbol/LineTable.h"
40#include "lldb/Symbol/ObjectFile.h"
41#include "lldb/Symbol/SymbolVendor.h"
42#include "lldb/Symbol/VariableList.h"
43
44#include "DWARFCompileUnit.h"
45#include "DWARFDebugAbbrev.h"
46#include "DWARFDebugAranges.h"
47#include "DWARFDebugInfo.h"
48#include "DWARFDebugInfoEntry.h"
49#include "DWARFDebugLine.h"
50#include "DWARFDebugPubnames.h"
51#include "DWARFDebugRanges.h"
52#include "DWARFDIECollection.h"
53#include "DWARFFormValue.h"
54#include "DWARFLocationList.h"
55#include "LogChannelDWARF.h"
56#include "SymbolFileDWARFDebugMap.h"
57
58#include <map>
59
60//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
61
62#ifdef ENABLE_DEBUG_PRINTF
63#include <stdio.h>
64#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
65#else
66#define DEBUG_PRINTF(fmt, ...)
67#endif
68
69#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
70
71using namespace lldb;
72using namespace lldb_private;
73
74
75static AccessType
76DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
77{
78    switch (dwarf_accessibility)
79    {
80        case DW_ACCESS_public:      return eAccessPublic;
81        case DW_ACCESS_private:     return eAccessPrivate;
82        case DW_ACCESS_protected:   return eAccessProtected;
83        default:                    break;
84    }
85    return eAccessNone;
86}
87
88void
89SymbolFileDWARF::Initialize()
90{
91    LogChannelDWARF::Initialize();
92    PluginManager::RegisterPlugin (GetPluginNameStatic(),
93                                   GetPluginDescriptionStatic(),
94                                   CreateInstance);
95}
96
97void
98SymbolFileDWARF::Terminate()
99{
100    PluginManager::UnregisterPlugin (CreateInstance);
101    LogChannelDWARF::Initialize();
102}
103
104
105const char *
106SymbolFileDWARF::GetPluginNameStatic()
107{
108    return "symbol-file.dwarf2";
109}
110
111const char *
112SymbolFileDWARF::GetPluginDescriptionStatic()
113{
114    return "DWARF and DWARF3 debug symbol file reader.";
115}
116
117
118SymbolFile*
119SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
120{
121    return new SymbolFileDWARF(obj_file);
122}
123
124TypeList *
125SymbolFileDWARF::GetTypeList ()
126{
127    if (m_debug_map_symfile)
128        return m_debug_map_symfile->GetTypeList();
129    return m_obj_file->GetModule()->GetTypeList();
130
131}
132
133//----------------------------------------------------------------------
134// Gets the first parent that is a lexical block, function or inlined
135// subroutine, or compile unit.
136//----------------------------------------------------------------------
137static const DWARFDebugInfoEntry *
138GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
139{
140    const DWARFDebugInfoEntry *die;
141    for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
142    {
143        dw_tag_t tag = die->Tag();
144
145        switch (tag)
146        {
147        case DW_TAG_compile_unit:
148        case DW_TAG_subprogram:
149        case DW_TAG_inlined_subroutine:
150        case DW_TAG_lexical_block:
151            return die;
152        }
153    }
154    return NULL;
155}
156
157
158SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
159    SymbolFile (objfile),
160    m_debug_map_symfile (NULL),
161    m_clang_tu_decl (NULL),
162    m_flags(),
163    m_data_debug_abbrev(),
164    m_data_debug_frame(),
165    m_data_debug_info(),
166    m_data_debug_line(),
167    m_data_debug_loc(),
168    m_data_debug_ranges(),
169    m_data_debug_str(),
170    m_abbr(),
171    m_aranges(),
172    m_info(),
173    m_line(),
174    m_function_basename_index(),
175    m_function_fullname_index(),
176    m_function_method_index(),
177    m_function_selector_index(),
178    m_objc_class_selectors_index(),
179    m_global_index(),
180    m_type_index(),
181    m_namespace_index(),
182    m_indexed (false),
183    m_is_external_ast_source (false),
184    m_ranges(),
185    m_unique_ast_type_map ()
186{
187}
188
189SymbolFileDWARF::~SymbolFileDWARF()
190{
191    if (m_is_external_ast_source)
192        m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
193}
194
195static const ConstString &
196GetDWARFMachOSegmentName ()
197{
198    static ConstString g_dwarf_section_name ("__DWARF");
199    return g_dwarf_section_name;
200}
201
202UniqueDWARFASTTypeMap &
203SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
204{
205    if (m_debug_map_symfile)
206        return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
207    return m_unique_ast_type_map;
208}
209
210ClangASTContext &
211SymbolFileDWARF::GetClangASTContext ()
212{
213    if (m_debug_map_symfile)
214        return m_debug_map_symfile->GetClangASTContext ();
215
216    ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
217    if (!m_is_external_ast_source)
218    {
219        m_is_external_ast_source = true;
220        llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
221            new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
222                                                 SymbolFileDWARF::CompleteObjCInterfaceDecl,
223                                                 SymbolFileDWARF::FindExternalVisibleDeclsByName,
224                                                 this));
225
226        ast.SetExternalSource (ast_source_ap);
227    }
228    return ast;
229}
230
231void
232SymbolFileDWARF::InitializeObject()
233{
234    // Install our external AST source callbacks so we can complete Clang types.
235    Module *module = m_obj_file->GetModule();
236    if (module)
237    {
238        const SectionList *section_list = m_obj_file->GetSectionList();
239
240        const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
241
242        // Memory map the DWARF mach-o segment so we have everything mmap'ed
243        // to keep our heap memory usage down.
244        if (section)
245            section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
246    }
247}
248
249bool
250SymbolFileDWARF::SupportedVersion(uint16_t version)
251{
252    return version == 2 || version == 3;
253}
254
255uint32_t
256SymbolFileDWARF::GetAbilities ()
257{
258    uint32_t abilities = 0;
259    if (m_obj_file != NULL)
260    {
261        const Section* section = NULL;
262        const SectionList *section_list = m_obj_file->GetSectionList();
263        if (section_list == NULL)
264            return 0;
265
266        uint64_t debug_abbrev_file_size = 0;
267        uint64_t debug_aranges_file_size = 0;
268        uint64_t debug_frame_file_size = 0;
269        uint64_t debug_info_file_size = 0;
270        uint64_t debug_line_file_size = 0;
271        uint64_t debug_loc_file_size = 0;
272        uint64_t debug_macinfo_file_size = 0;
273        uint64_t debug_pubnames_file_size = 0;
274        uint64_t debug_pubtypes_file_size = 0;
275        uint64_t debug_ranges_file_size = 0;
276        uint64_t debug_str_file_size = 0;
277
278        section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
279
280        if (section)
281            section_list = &section->GetChildren ();
282
283        section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
284        if (section != NULL)
285        {
286            debug_info_file_size = section->GetByteSize();
287
288            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
289            if (section)
290                debug_abbrev_file_size = section->GetByteSize();
291            else
292                m_flags.Set (flagsGotDebugAbbrevData);
293
294            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
295            if (section)
296                debug_aranges_file_size = section->GetByteSize();
297            else
298                m_flags.Set (flagsGotDebugArangesData);
299
300            section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
301            if (section)
302                debug_frame_file_size = section->GetByteSize();
303            else
304                m_flags.Set (flagsGotDebugFrameData);
305
306            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
307            if (section)
308                debug_line_file_size = section->GetByteSize();
309            else
310                m_flags.Set (flagsGotDebugLineData);
311
312            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
313            if (section)
314                debug_loc_file_size = section->GetByteSize();
315            else
316                m_flags.Set (flagsGotDebugLocData);
317
318            section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
319            if (section)
320                debug_macinfo_file_size = section->GetByteSize();
321            else
322                m_flags.Set (flagsGotDebugMacInfoData);
323
324            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
325            if (section)
326                debug_pubnames_file_size = section->GetByteSize();
327            else
328                m_flags.Set (flagsGotDebugPubNamesData);
329
330            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
331            if (section)
332                debug_pubtypes_file_size = section->GetByteSize();
333            else
334                m_flags.Set (flagsGotDebugPubTypesData);
335
336            section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
337            if (section)
338                debug_ranges_file_size = section->GetByteSize();
339            else
340                m_flags.Set (flagsGotDebugRangesData);
341
342            section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
343            if (section)
344                debug_str_file_size = section->GetByteSize();
345            else
346                m_flags.Set (flagsGotDebugStrData);
347        }
348
349        if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
350            abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
351
352        if (debug_line_file_size > 0)
353            abilities |= LineTables;
354
355        if (debug_aranges_file_size > 0)
356            abilities |= AddressAcceleratorTable;
357
358        if (debug_pubnames_file_size > 0)
359            abilities |= FunctionAcceleratorTable;
360
361        if (debug_pubtypes_file_size > 0)
362            abilities |= TypeAcceleratorTable;
363
364        if (debug_macinfo_file_size > 0)
365            abilities |= MacroInformation;
366
367        if (debug_frame_file_size > 0)
368            abilities |= CallFrameInformation;
369    }
370    return abilities;
371}
372
373const DataExtractor&
374SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
375{
376    if (m_flags.IsClear (got_flag))
377    {
378        m_flags.Set (got_flag);
379        const SectionList *section_list = m_obj_file->GetSectionList();
380        if (section_list)
381        {
382            Section *section = section_list->FindSectionByType(sect_type, true).get();
383            if (section)
384            {
385                // See if we memory mapped the DWARF segment?
386                if (m_dwarf_data.GetByteSize())
387                {
388                    data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
389                }
390                else
391                {
392                    if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
393                        data.Clear();
394                }
395            }
396        }
397    }
398    return data;
399}
400
401const DataExtractor&
402SymbolFileDWARF::get_debug_abbrev_data()
403{
404    return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
405}
406
407const DataExtractor&
408SymbolFileDWARF::get_debug_frame_data()
409{
410    return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
411}
412
413const DataExtractor&
414SymbolFileDWARF::get_debug_info_data()
415{
416    return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
417}
418
419const DataExtractor&
420SymbolFileDWARF::get_debug_line_data()
421{
422    return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
423}
424
425const DataExtractor&
426SymbolFileDWARF::get_debug_loc_data()
427{
428    return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
429}
430
431const DataExtractor&
432SymbolFileDWARF::get_debug_ranges_data()
433{
434    return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
435}
436
437const DataExtractor&
438SymbolFileDWARF::get_debug_str_data()
439{
440    return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
441}
442
443
444DWARFDebugAbbrev*
445SymbolFileDWARF::DebugAbbrev()
446{
447    if (m_abbr.get() == NULL)
448    {
449        const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
450        if (debug_abbrev_data.GetByteSize() > 0)
451        {
452            m_abbr.reset(new DWARFDebugAbbrev());
453            if (m_abbr.get())
454                m_abbr->Parse(debug_abbrev_data);
455        }
456    }
457    return m_abbr.get();
458}
459
460const DWARFDebugAbbrev*
461SymbolFileDWARF::DebugAbbrev() const
462{
463    return m_abbr.get();
464}
465
466DWARFDebugAranges*
467SymbolFileDWARF::DebugAranges()
468{
469    // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
470    // and we are already parsing all of the DWARF because the .debug_pubnames
471    // is useless (it only mentions symbols that are externally visible), so
472    // don't use the .debug_aranges section, we should be using a debug aranges
473    // we got from SymbolFileDWARF::Index().
474
475    if (!m_indexed)
476        Index();
477
478
479//    if (m_aranges.get() == NULL)
480//    {
481//        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
482//        m_aranges.reset(new DWARFDebugAranges());
483//        if (m_aranges.get())
484//        {
485//            const DataExtractor &debug_aranges_data = get_debug_aranges_data();
486//            if (debug_aranges_data.GetByteSize() > 0)
487//                m_aranges->Extract(debug_aranges_data);
488//            else
489//                m_aranges->Generate(this);
490//        }
491//    }
492    return m_aranges.get();
493}
494
495const DWARFDebugAranges*
496SymbolFileDWARF::DebugAranges() const
497{
498    return m_aranges.get();
499}
500
501
502DWARFDebugInfo*
503SymbolFileDWARF::DebugInfo()
504{
505    if (m_info.get() == NULL)
506    {
507        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
508        if (get_debug_info_data().GetByteSize() > 0)
509        {
510            m_info.reset(new DWARFDebugInfo());
511            if (m_info.get())
512            {
513                m_info->SetDwarfData(this);
514            }
515        }
516    }
517    return m_info.get();
518}
519
520const DWARFDebugInfo*
521SymbolFileDWARF::DebugInfo() const
522{
523    return m_info.get();
524}
525
526DWARFCompileUnit*
527SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
528{
529    DWARFDebugInfo* info = DebugInfo();
530    if (info)
531        return info->GetCompileUnit(cu_uid).get();
532    return NULL;
533}
534
535
536DWARFDebugRanges*
537SymbolFileDWARF::DebugRanges()
538{
539    if (m_ranges.get() == NULL)
540    {
541        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
542        if (get_debug_ranges_data().GetByteSize() > 0)
543        {
544            m_ranges.reset(new DWARFDebugRanges());
545            if (m_ranges.get())
546                m_ranges->Extract(this);
547        }
548    }
549    return m_ranges.get();
550}
551
552const DWARFDebugRanges*
553SymbolFileDWARF::DebugRanges() const
554{
555    return m_ranges.get();
556}
557
558bool
559SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
560{
561    if (curr_cu != NULL)
562    {
563        const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
564        if (cu_die)
565        {
566            const char * cu_die_name = cu_die->GetName(this, curr_cu);
567            const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
568            LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
569            if (cu_die_name)
570            {
571                FileSpec cu_file_spec;
572
573                if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
574                {
575                    // If we have a full path to the compile unit, we don't need to resolve
576                    // the file.  This can be expensive e.g. when the source files are NFS mounted.
577                    cu_file_spec.SetFile (cu_die_name, false);
578                }
579                else
580                {
581                    std::string fullpath(cu_comp_dir);
582                    if (*fullpath.rbegin() != '/')
583                        fullpath += '/';
584                    fullpath += cu_die_name;
585                    cu_file_spec.SetFile (fullpath.c_str(), false);
586                }
587
588                compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), class_language));
589                if (compile_unit_sp.get())
590                {
591                    curr_cu->SetUserData(compile_unit_sp.get());
592                    return true;
593                }
594            }
595        }
596    }
597    return false;
598}
599
600uint32_t
601SymbolFileDWARF::GetNumCompileUnits()
602{
603    DWARFDebugInfo* info = DebugInfo();
604    if (info)
605        return info->GetNumCompileUnits();
606    return 0;
607}
608
609CompUnitSP
610SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
611{
612    CompUnitSP comp_unit;
613    DWARFDebugInfo* info = DebugInfo();
614    if (info)
615    {
616        DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
617        if (curr_cu != NULL)
618        {
619            // Our symbol vendor shouldn't be asking us to add a compile unit that
620            // has already been added to it, which this DWARF plug-in knows as it
621            // stores the lldb compile unit (CompileUnit) pointer in each
622            // DWARFCompileUnit object when it gets added.
623            assert(curr_cu->GetUserData() == NULL);
624            ParseCompileUnit(curr_cu, comp_unit);
625        }
626    }
627    return comp_unit;
628}
629
630static void
631AddRangesToBlock
632(
633    Block& block,
634    DWARFDebugRanges::RangeList& ranges,
635    addr_t block_base_addr
636)
637{
638    ranges.SubtractOffset (block_base_addr);
639    size_t range_idx = 0;
640    const DWARFDebugRanges::Range *debug_range;
641    for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
642    {
643        block.AddRange(debug_range->begin_offset, debug_range->end_offset);
644    }
645}
646
647
648Function *
649SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
650{
651    DWARFDebugRanges::RangeList func_ranges;
652    const char *name = NULL;
653    const char *mangled = NULL;
654    int decl_file = 0;
655    int decl_line = 0;
656    int decl_column = 0;
657    int call_file = 0;
658    int call_line = 0;
659    int call_column = 0;
660    DWARFExpression frame_base;
661
662    assert (die->Tag() == DW_TAG_subprogram);
663
664    if (die->Tag() != DW_TAG_subprogram)
665        return NULL;
666
667    const DWARFDebugInfoEntry *parent_die = die->GetParent();
668    switch (parent_die->Tag())
669    {
670    case DW_TAG_structure_type:
671    case DW_TAG_class_type:
672        // We have methods of a class or struct
673        {
674            Type *class_type = ResolveType (dwarf_cu, parent_die);
675            if (class_type)
676                class_type->GetClangFullType();
677        }
678        break;
679
680    default:
681        // Parse the function prototype as a type that can then be added to concrete function instance
682        ParseTypes (sc, dwarf_cu, die, false, false);
683        break;
684    }
685
686    //FixupTypes();
687
688    if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
689    {
690        // Union of all ranges in the function DIE (if the function is discontiguous)
691        AddressRange func_range;
692        lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
693        lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
694        if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
695        {
696            func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
697            if (func_range.GetBaseAddress().IsValid())
698                func_range.SetByteSize(highest_func_addr - lowest_func_addr);
699        }
700
701        if (func_range.GetBaseAddress().IsValid())
702        {
703            Mangled func_name;
704            if (mangled)
705                func_name.SetValue(mangled, true);
706            else if (name)
707                func_name.SetValue(name, false);
708
709            FunctionSP func_sp;
710            std::auto_ptr<Declaration> decl_ap;
711            if (decl_file != 0 || decl_line != 0 || decl_column != 0)
712                decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
713                                               decl_line,
714                                               decl_column));
715
716            Type *func_type = m_die_to_type.lookup (die);
717
718            assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
719
720            func_range.GetBaseAddress().ResolveLinkedAddress();
721
722            func_sp.reset(new Function (sc.comp_unit,
723                                        die->GetOffset(),       // UserID is the DIE offset
724                                        die->GetOffset(),
725                                        func_name,
726                                        func_type,
727                                        func_range));           // first address range
728
729            if (func_sp.get() != NULL)
730            {
731                func_sp->GetFrameBaseExpression() = frame_base;
732                sc.comp_unit->AddFunction(func_sp);
733                return func_sp.get();
734            }
735        }
736    }
737    return NULL;
738}
739
740size_t
741SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
742{
743    assert (sc.comp_unit);
744    size_t functions_added = 0;
745    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
746    if (dwarf_cu)
747    {
748        DWARFDIECollection function_dies;
749        const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
750        size_t func_idx;
751        for (func_idx = 0; func_idx < num_funtions; ++func_idx)
752        {
753            const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
754            if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
755            {
756                if (ParseCompileUnitFunction(sc, dwarf_cu, die))
757                    ++functions_added;
758            }
759        }
760        //FixupTypes();
761    }
762    return functions_added;
763}
764
765bool
766SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
767{
768    assert (sc.comp_unit);
769    DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
770    assert (curr_cu);
771    const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
772
773    if (cu_die)
774    {
775        const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
776        dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
777
778        // All file indexes in DWARF are one based and a file of index zero is
779        // supposed to be the compile unit itself.
780        support_files.Append (*sc.comp_unit);
781
782        return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
783    }
784    return false;
785}
786
787struct ParseDWARFLineTableCallbackInfo
788{
789    LineTable* line_table;
790    const SectionList *section_list;
791    lldb::addr_t prev_sect_file_base_addr;
792    lldb::addr_t curr_sect_file_base_addr;
793    bool is_oso_for_debug_map;
794    bool prev_in_final_executable;
795    DWARFDebugLine::Row prev_row;
796    SectionSP prev_section_sp;
797    SectionSP curr_section_sp;
798};
799
800//----------------------------------------------------------------------
801// ParseStatementTableCallback
802//----------------------------------------------------------------------
803static void
804ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
805{
806    LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
807    if (state.row == DWARFDebugLine::State::StartParsingLineTable)
808    {
809        // Just started parsing the line table
810    }
811    else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
812    {
813        // Done parsing line table, nothing to do for the cleanup
814    }
815    else
816    {
817        ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
818        // We have a new row, lets append it
819
820        if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
821        {
822            info->prev_section_sp = info->curr_section_sp;
823            info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
824            // If this is an end sequence entry, then we subtract one from the
825            // address to make sure we get an address that is not the end of
826            // a section.
827            if (state.end_sequence && state.address != 0)
828                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
829            else
830                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
831
832            if (info->curr_section_sp.get())
833                info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
834            else
835                info->curr_sect_file_base_addr = 0;
836        }
837        if (info->curr_section_sp.get())
838        {
839            lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
840            // Check for the fancy section magic to determine if we
841
842            if (info->is_oso_for_debug_map)
843            {
844                // When this is a debug map object file that contains DWARF
845                // (referenced from an N_OSO debug map nlist entry) we will have
846                // a file address in the file range for our section from the
847                // original .o file, and a load address in the executable that
848                // contains the debug map.
849                //
850                // If the sections for the file range and load range are
851                // different, we have a remapped section for the function and
852                // this address is resolved. If they are the same, then the
853                // function for this address didn't make it into the final
854                // executable.
855                bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
856
857                // If we are doing DWARF with debug map, then we need to carefully
858                // add each line table entry as there may be gaps as functions
859                // get moved around or removed.
860                if (!info->prev_row.end_sequence && info->prev_section_sp.get())
861                {
862                    if (info->prev_in_final_executable)
863                    {
864                        bool terminate_previous_entry = false;
865                        if (!curr_in_final_executable)
866                        {
867                            // Check for the case where the previous line entry
868                            // in a function made it into the final executable,
869                            // yet the current line entry falls in a function
870                            // that didn't. The line table used to be contiguous
871                            // through this address range but now it isn't. We
872                            // need to terminate the previous line entry so
873                            // that we can reconstruct the line range correctly
874                            // for it and to keep the line table correct.
875                            terminate_previous_entry = true;
876                        }
877                        else if (info->curr_section_sp.get() != info->prev_section_sp.get())
878                        {
879                            // Check for cases where the line entries used to be
880                            // contiguous address ranges, but now they aren't.
881                            // This can happen when order files specify the
882                            // ordering of the functions.
883                            lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
884                            Section *curr_sect = info->curr_section_sp.get();
885                            Section *prev_sect = info->prev_section_sp.get();
886                            assert (curr_sect->GetLinkedSection());
887                            assert (prev_sect->GetLinkedSection());
888                            lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
889                            lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
890                            lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
891                            lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
892                            if (object_file_addr_delta != linked_file_addr_delta)
893                                terminate_previous_entry = true;
894                        }
895
896                        if (terminate_previous_entry)
897                        {
898                            line_table->InsertLineEntry (info->prev_section_sp,
899                                                         state.address - info->prev_sect_file_base_addr,
900                                                         info->prev_row.line,
901                                                         info->prev_row.column,
902                                                         info->prev_row.file,
903                                                         false,                 // is_stmt
904                                                         false,                 // basic_block
905                                                         false,                 // state.prologue_end
906                                                         false,                 // state.epilogue_begin
907                                                         true);                 // end_sequence);
908                        }
909                    }
910                }
911
912                if (curr_in_final_executable)
913                {
914                    line_table->InsertLineEntry (info->curr_section_sp,
915                                                 curr_line_section_offset,
916                                                 state.line,
917                                                 state.column,
918                                                 state.file,
919                                                 state.is_stmt,
920                                                 state.basic_block,
921                                                 state.prologue_end,
922                                                 state.epilogue_begin,
923                                                 state.end_sequence);
924                    info->prev_section_sp = info->curr_section_sp;
925                }
926                else
927                {
928                    // If the current address didn't make it into the final
929                    // executable, the current section will be the __text
930                    // segment in the .o file, so we need to clear this so
931                    // we can catch the next function that did make it into
932                    // the final executable.
933                    info->prev_section_sp.reset();
934                    info->curr_section_sp.reset();
935                }
936
937                info->prev_in_final_executable = curr_in_final_executable;
938            }
939            else
940            {
941                // We are not in an object file that contains DWARF for an
942                // N_OSO, this is just a normal DWARF file. The DWARF spec
943                // guarantees that the addresses will be in increasing order
944                // so, since we store line tables in file address order, we
945                // can always just append the line entry without needing to
946                // search for the correct insertion point (we don't need to
947                // use LineEntry::InsertLineEntry()).
948                line_table->AppendLineEntry (info->curr_section_sp,
949                                             curr_line_section_offset,
950                                             state.line,
951                                             state.column,
952                                             state.file,
953                                             state.is_stmt,
954                                             state.basic_block,
955                                             state.prologue_end,
956                                             state.epilogue_begin,
957                                             state.end_sequence);
958            }
959        }
960
961        info->prev_row = state;
962    }
963}
964
965bool
966SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
967{
968    assert (sc.comp_unit);
969    if (sc.comp_unit->GetLineTable() != NULL)
970        return true;
971
972    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
973    if (dwarf_cu)
974    {
975        const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
976        const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
977        if (cu_line_offset != DW_INVALID_OFFSET)
978        {
979            std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
980            if (line_table_ap.get())
981            {
982                ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
983                uint32_t offset = cu_line_offset;
984                DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
985                sc.comp_unit->SetLineTable(line_table_ap.release());
986                return true;
987            }
988        }
989    }
990    return false;
991}
992
993size_t
994SymbolFileDWARF::ParseFunctionBlocks
995(
996    const SymbolContext& sc,
997    Block *parent_block,
998    DWARFCompileUnit* dwarf_cu,
999    const DWARFDebugInfoEntry *die,
1000    addr_t subprogram_low_pc,
1001    bool parse_siblings,
1002    bool parse_children
1003)
1004{
1005    size_t blocks_added = 0;
1006    while (die != NULL)
1007    {
1008        dw_tag_t tag = die->Tag();
1009
1010        switch (tag)
1011        {
1012        case DW_TAG_inlined_subroutine:
1013        case DW_TAG_subprogram:
1014        case DW_TAG_lexical_block:
1015            {
1016                DWARFDebugRanges::RangeList ranges;
1017                const char *name = NULL;
1018                const char *mangled_name = NULL;
1019                Block *block = NULL;
1020                if (tag != DW_TAG_subprogram)
1021                {
1022                    BlockSP block_sp(new Block (die->GetOffset()));
1023                    parent_block->AddChild(block_sp);
1024                    block = block_sp.get();
1025                }
1026                else
1027                {
1028                    block = parent_block;
1029                }
1030
1031                int decl_file = 0;
1032                int decl_line = 0;
1033                int decl_column = 0;
1034                int call_file = 0;
1035                int call_line = 0;
1036                int call_column = 0;
1037                if (die->GetDIENamesAndRanges (this,
1038                                               dwarf_cu,
1039                                               name,
1040                                               mangled_name,
1041                                               ranges,
1042                                               decl_file, decl_line, decl_column,
1043                                               call_file, call_line, call_column))
1044                {
1045                    if (tag == DW_TAG_subprogram)
1046                    {
1047                        assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1048                        subprogram_low_pc = ranges.LowestAddress(0);
1049                    }
1050                    else if (tag == DW_TAG_inlined_subroutine)
1051                    {
1052                        // We get called here for inlined subroutines in two ways.
1053                        // The first time is when we are making the Function object
1054                        // for this inlined concrete instance.  Since we're creating a top level block at
1055                        // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS.  So we need to
1056                        // adjust the containing address.
1057                        // The second time is when we are parsing the blocks inside the function that contains
1058                        // the inlined concrete instance.  Since these will be blocks inside the containing "real"
1059                        // function the offset will be for that function.
1060                        if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1061                        {
1062                            subprogram_low_pc = ranges.LowestAddress(0);
1063                        }
1064                    }
1065
1066                    AddRangesToBlock (*block, ranges, subprogram_low_pc);
1067
1068                    if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1069                    {
1070                        std::auto_ptr<Declaration> decl_ap;
1071                        if (decl_file != 0 || decl_line != 0 || decl_column != 0)
1072                            decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1073                                                          decl_line, decl_column));
1074
1075                        std::auto_ptr<Declaration> call_ap;
1076                        if (call_file != 0 || call_line != 0 || call_column != 0)
1077                            call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1078                                                          call_line, call_column));
1079
1080                        block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
1081                    }
1082
1083                    ++blocks_added;
1084
1085                    if (parse_children && die->HasChildren())
1086                    {
1087                        blocks_added += ParseFunctionBlocks (sc,
1088                                                             block,
1089                                                             dwarf_cu,
1090                                                             die->GetFirstChild(),
1091                                                             subprogram_low_pc,
1092                                                             true,
1093                                                             true);
1094                    }
1095                }
1096            }
1097            break;
1098        default:
1099            break;
1100        }
1101
1102        if (parse_siblings)
1103            die = die->GetSibling();
1104        else
1105            die = NULL;
1106    }
1107    return blocks_added;
1108}
1109
1110size_t
1111SymbolFileDWARF::ParseChildMembers
1112(
1113    const SymbolContext& sc,
1114    DWARFCompileUnit* dwarf_cu,
1115    const DWARFDebugInfoEntry *parent_die,
1116    clang_type_t class_clang_type,
1117    const LanguageType class_language,
1118    std::vector<clang::CXXBaseSpecifier *>& base_classes,
1119    std::vector<int>& member_accessibilities,
1120    DWARFDIECollection& member_function_dies,
1121    AccessType& default_accessibility,
1122    bool &is_a_class
1123)
1124{
1125    if (parent_die == NULL)
1126        return 0;
1127
1128    size_t count = 0;
1129    const DWARFDebugInfoEntry *die;
1130    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1131    uint32_t member_idx = 0;
1132
1133    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1134    {
1135        dw_tag_t tag = die->Tag();
1136
1137        switch (tag)
1138        {
1139        case DW_TAG_member:
1140            {
1141                DWARFDebugInfoEntry::Attributes attributes;
1142                const size_t num_attributes = die->GetAttributes (this,
1143                                                                  dwarf_cu,
1144                                                                  fixed_form_sizes,
1145                                                                  attributes);
1146                if (num_attributes > 0)
1147                {
1148                    Declaration decl;
1149                    //DWARFExpression location;
1150                    const char *name = NULL;
1151                    bool is_artificial = false;
1152                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1153                    AccessType accessibility = eAccessNone;
1154                    //off_t member_offset = 0;
1155                    size_t byte_size = 0;
1156                    size_t bit_offset = 0;
1157                    size_t bit_size = 0;
1158                    uint32_t i;
1159                    for (i=0; i<num_attributes && !is_artificial; ++i)
1160                    {
1161                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1162                        DWARFFormValue form_value;
1163                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1164                        {
1165                            switch (attr)
1166                            {
1167                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1168                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1169                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1170                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
1171                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1172                            case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break;
1173                            case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break;
1174                            case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
1175                            case DW_AT_data_member_location:
1176//                                if (form_value.BlockData())
1177//                                {
1178//                                    Value initialValue(0);
1179//                                    Value memberOffset(0);
1180//                                    const DataExtractor& debug_info_data = get_debug_info_data();
1181//                                    uint32_t block_length = form_value.Unsigned();
1182//                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1183//                                    if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1184//                                    {
1185//                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1186//                                    }
1187//                                }
1188                                break;
1189
1190                            case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
1191                            case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
1192                            case DW_AT_declaration:
1193                            case DW_AT_description:
1194                            case DW_AT_mutable:
1195                            case DW_AT_visibility:
1196                            default:
1197                            case DW_AT_sibling:
1198                                break;
1199                            }
1200                        }
1201                    }
1202
1203                    // FIXME: Make Clang ignore Objective-C accessibility for expressions
1204
1205                    if (class_language == eLanguageTypeObjC ||
1206                        class_language == eLanguageTypeObjC_plus_plus)
1207                        accessibility = eAccessNone;
1208
1209                    if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1210                    {
1211                        // Not all compilers will mark the vtable pointer
1212                        // member as artificial (llvm-gcc). We can't have
1213                        // the virtual members in our classes otherwise it
1214                        // throws off all child offsets since we end up
1215                        // having and extra pointer sized member in our
1216                        // class layouts.
1217                        is_artificial = true;
1218                    }
1219
1220                    if (is_artificial == false)
1221                    {
1222                        Type *member_type = ResolveTypeUID(encoding_uid);
1223                        if (member_type)
1224                        {
1225                            if (accessibility == eAccessNone)
1226                                accessibility = default_accessibility;
1227                            member_accessibilities.push_back(accessibility);
1228
1229                            GetClangASTContext().AddFieldToRecordType (class_clang_type,
1230                                                                       name,
1231                                                                       member_type->GetClangLayoutType(),
1232                                                                       accessibility,
1233                                                                       bit_size);
1234                        }
1235                        else
1236                        {
1237                            if (name)
1238                                ReportError ("0x%8.8x: DW_TAG_member '%s' refers to type 0x%8.8x which was unable to be parsed",
1239                                             die->GetOffset(),
1240                                             name,
1241                                             encoding_uid);
1242                            else
1243                                ReportError ("0x%8.8x: DW_TAG_member refers to type 0x%8.8x which was unable to be parsed",
1244                                             die->GetOffset(),
1245                                             encoding_uid);
1246                        }
1247                    }
1248                }
1249                ++member_idx;
1250            }
1251            break;
1252
1253        case DW_TAG_subprogram:
1254            // Let the type parsing code handle this one for us.
1255            member_function_dies.Append (die);
1256            break;
1257
1258        case DW_TAG_inheritance:
1259            {
1260                is_a_class = true;
1261                if (default_accessibility == eAccessNone)
1262                    default_accessibility = eAccessPrivate;
1263                // TODO: implement DW_TAG_inheritance type parsing
1264                DWARFDebugInfoEntry::Attributes attributes;
1265                const size_t num_attributes = die->GetAttributes (this,
1266                                                                  dwarf_cu,
1267                                                                  fixed_form_sizes,
1268                                                                  attributes);
1269                if (num_attributes > 0)
1270                {
1271                    Declaration decl;
1272                    DWARFExpression location;
1273                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1274                    AccessType accessibility = default_accessibility;
1275                    bool is_virtual = false;
1276                    bool is_base_of_class = true;
1277                    off_t member_offset = 0;
1278                    uint32_t i;
1279                    for (i=0; i<num_attributes; ++i)
1280                    {
1281                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1282                        DWARFFormValue form_value;
1283                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1284                        {
1285                            switch (attr)
1286                            {
1287                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1288                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1289                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1290                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1291                            case DW_AT_data_member_location:
1292                                if (form_value.BlockData())
1293                                {
1294                                    Value initialValue(0);
1295                                    Value memberOffset(0);
1296                                    const DataExtractor& debug_info_data = get_debug_info_data();
1297                                    uint32_t block_length = form_value.Unsigned();
1298                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1299                                    if (DWARFExpression::Evaluate (NULL,
1300                                                                   NULL,
1301                                                                   NULL,
1302                                                                   NULL,
1303                                                                   NULL,
1304                                                                   debug_info_data,
1305                                                                   block_offset,
1306                                                                   block_length,
1307                                                                   eRegisterKindDWARF,
1308                                                                   &initialValue,
1309                                                                   memberOffset,
1310                                                                   NULL))
1311                                    {
1312                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1313                                    }
1314                                }
1315                                break;
1316
1317                            case DW_AT_accessibility:
1318                                accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
1319                                break;
1320
1321                            case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1322                            default:
1323                            case DW_AT_sibling:
1324                                break;
1325                            }
1326                        }
1327                    }
1328
1329                    Type *base_class_type = ResolveTypeUID(encoding_uid);
1330                    assert(base_class_type);
1331
1332                    clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1333                    assert (base_class_clang_type);
1334                    if (class_language == eLanguageTypeObjC)
1335                    {
1336                        GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
1337                    }
1338                    else
1339                    {
1340                        base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
1341                                                                                               accessibility,
1342                                                                                               is_virtual,
1343                                                                                               is_base_of_class));
1344                    }
1345                }
1346            }
1347            break;
1348
1349        default:
1350            break;
1351        }
1352    }
1353    return count;
1354}
1355
1356
1357clang::DeclContext*
1358SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1359{
1360    DWARFDebugInfo* debug_info = DebugInfo();
1361    if (debug_info)
1362    {
1363        DWARFCompileUnitSP cu_sp;
1364        const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1365        if (die)
1366            return GetClangDeclContextForDIE (cu_sp.get(), die);
1367    }
1368    return NULL;
1369}
1370
1371Type*
1372SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
1373{
1374    DWARFDebugInfo* debug_info = DebugInfo();
1375    if (debug_info)
1376    {
1377        DWARFCompileUnitSP cu_sp;
1378        const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1379        if (type_die != NULL)
1380        {
1381            // We might be coming in in the middle of a type tree (a class
1382            // withing a class, an enum within a class), so parse any needed
1383            // parent DIEs before we get to this one...
1384            const DWARFDebugInfoEntry* parent_die = type_die->GetParent();
1385            switch (parent_die->Tag())
1386            {
1387            case DW_TAG_structure_type:
1388            case DW_TAG_union_type:
1389            case DW_TAG_class_type:
1390                ResolveType(cu_sp.get(), parent_die);
1391                break;
1392            }
1393            return ResolveType (cu_sp.get(), type_die);
1394        }
1395    }
1396    return NULL;
1397}
1398
1399// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1400// SymbolFileDWARF objects to detect if this DWARF file is the one that
1401// can resolve a clang_type.
1402bool
1403SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1404{
1405    clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1406    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1407    return die != NULL;
1408}
1409
1410
1411lldb::clang_type_t
1412SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1413{
1414    // We have a struct/union/class/enum that needs to be fully resolved.
1415    clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1416    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1417    if (die == NULL)
1418    {
1419//        if (m_debug_map_symfile)
1420//        {
1421//            Type *type = m_die_to_type[die];
1422//            if (type && type->GetSymbolFile() != this)
1423//                return type->GetClangType();
1424//        }
1425        // We have already resolved this type...
1426        return clang_type;
1427    }
1428    // Once we start resolving this type, remove it from the forward declaration
1429    // map in case anyone child members or other types require this type to get resolved.
1430    // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1431    // are done.
1432    m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
1433
1434
1435    DWARFDebugInfo* debug_info = DebugInfo();
1436
1437    DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
1438    Type *type = m_die_to_type.lookup (die);
1439
1440    const dw_tag_t tag = die->Tag();
1441
1442    DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1443                  die->GetOffset(),
1444                  DW_TAG_value_to_name(tag),
1445                  type->GetName().AsCString());
1446    assert (clang_type);
1447    DWARFDebugInfoEntry::Attributes attributes;
1448
1449    ClangASTContext &ast = GetClangASTContext();
1450
1451    switch (tag)
1452    {
1453    case DW_TAG_structure_type:
1454    case DW_TAG_union_type:
1455    case DW_TAG_class_type:
1456        ast.StartTagDeclarationDefinition (clang_type);
1457        if (die->HasChildren())
1458        {
1459            LanguageType class_language = eLanguageTypeUnknown;
1460            bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1461            if (is_objc_class)
1462                class_language = eLanguageTypeObjC;
1463
1464            int tag_decl_kind = -1;
1465            AccessType default_accessibility = eAccessNone;
1466            if (tag == DW_TAG_structure_type)
1467            {
1468                tag_decl_kind = clang::TTK_Struct;
1469                default_accessibility = eAccessPublic;
1470            }
1471            else if (tag == DW_TAG_union_type)
1472            {
1473                tag_decl_kind = clang::TTK_Union;
1474                default_accessibility = eAccessPublic;
1475            }
1476            else if (tag == DW_TAG_class_type)
1477            {
1478                tag_decl_kind = clang::TTK_Class;
1479                default_accessibility = eAccessPrivate;
1480            }
1481
1482            SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1483            std::vector<clang::CXXBaseSpecifier *> base_classes;
1484            std::vector<int> member_accessibilities;
1485            bool is_a_class = false;
1486            // Parse members and base classes first
1487            DWARFDIECollection member_function_dies;
1488
1489            ParseChildMembers (sc,
1490                               curr_cu,
1491                               die,
1492                               clang_type,
1493                               class_language,
1494                               base_classes,
1495                               member_accessibilities,
1496                               member_function_dies,
1497                               default_accessibility,
1498                               is_a_class);
1499
1500            // Now parse any methods if there were any...
1501            size_t num_functions = member_function_dies.Size();
1502            if (num_functions > 0)
1503            {
1504                for (size_t i=0; i<num_functions; ++i)
1505                {
1506                    ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
1507                }
1508            }
1509
1510            if (class_language == eLanguageTypeObjC)
1511            {
1512                std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
1513                if (!class_str.empty())
1514                {
1515
1516                    ConstString class_name (class_str.c_str());
1517                    std::vector<NameToDIE::Info> method_die_infos;
1518                    if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1519                    {
1520                        DWARFCompileUnit* method_cu = NULL;
1521                        DWARFCompileUnit* prev_method_cu = NULL;
1522                        const size_t num_objc_methods = method_die_infos.size();
1523                        for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1524                        {
1525                            method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1526
1527                            if (method_cu != prev_method_cu)
1528                                method_cu->ExtractDIEsIfNeeded (false);
1529
1530                            DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1531
1532                            ResolveType (method_cu, method_die);
1533                        }
1534                    }
1535                }
1536            }
1537
1538            // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1539            // need to tell the clang type it is actually a class.
1540            if (class_language != eLanguageTypeObjC)
1541            {
1542                if (is_a_class && tag_decl_kind != clang::TTK_Class)
1543                    ast.SetTagTypeKind (clang_type, clang::TTK_Class);
1544            }
1545
1546            // Since DW_TAG_structure_type gets used for both classes
1547            // and structures, we may need to set any DW_TAG_member
1548            // fields to have a "private" access if none was specified.
1549            // When we parsed the child members we tracked that actual
1550            // accessibility value for each DW_TAG_member in the
1551            // "member_accessibilities" array. If the value for the
1552            // member is zero, then it was set to the "default_accessibility"
1553            // which for structs was "public". Below we correct this
1554            // by setting any fields to "private" that weren't correctly
1555            // set.
1556            if (is_a_class && !member_accessibilities.empty())
1557            {
1558                // This is a class and all members that didn't have
1559                // their access specified are private.
1560                ast.SetDefaultAccessForRecordFields (clang_type,
1561                                                     eAccessPrivate,
1562                                                     &member_accessibilities.front(),
1563                                                     member_accessibilities.size());
1564            }
1565
1566            if (!base_classes.empty())
1567            {
1568                ast.SetBaseClassesForClassType (clang_type,
1569                                                &base_classes.front(),
1570                                                base_classes.size());
1571
1572                // Clang will copy each CXXBaseSpecifier in "base_classes"
1573                // so we have to free them all.
1574                ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1575                                                            base_classes.size());
1576            }
1577
1578        }
1579        ast.CompleteTagDeclarationDefinition (clang_type);
1580        return clang_type;
1581
1582    case DW_TAG_enumeration_type:
1583        ast.StartTagDeclarationDefinition (clang_type);
1584        if (die->HasChildren())
1585        {
1586            SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1587            ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
1588        }
1589        ast.CompleteTagDeclarationDefinition (clang_type);
1590        return clang_type;
1591
1592    default:
1593        assert(false && "not a forward clang type decl!");
1594        break;
1595    }
1596    return NULL;
1597}
1598
1599Type*
1600SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
1601{
1602    if (type_die != NULL)
1603    {
1604        Type *type = m_die_to_type.lookup (type_die);
1605        if (type == NULL)
1606            type = GetTypeForDIE (curr_cu, type_die).get();
1607        if (assert_not_being_parsed)
1608            assert (type != DIE_IS_BEING_PARSED);
1609        return type;
1610    }
1611    return NULL;
1612}
1613
1614CompileUnit*
1615SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
1616{
1617    // Check if the symbol vendor already knows about this compile unit?
1618    if (curr_cu->GetUserData() == NULL)
1619    {
1620        // The symbol vendor doesn't know about this compile unit, we
1621        // need to parse and add it to the symbol vendor object.
1622        CompUnitSP dc_cu;
1623        ParseCompileUnit(curr_cu, dc_cu);
1624        if (dc_cu.get())
1625        {
1626            // Figure out the compile unit index if we weren't given one
1627            if (cu_idx == UINT32_MAX)
1628                DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
1629
1630            m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
1631
1632            if (m_debug_map_symfile)
1633                m_debug_map_symfile->SetCompileUnit(this, dc_cu);
1634        }
1635    }
1636    return (CompileUnit*)curr_cu->GetUserData();
1637}
1638
1639bool
1640SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1641{
1642    sc.Clear();
1643    // Check if the symbol vendor already knows about this compile unit?
1644    sc.module_sp = m_obj_file->GetModule()->GetSP();
1645    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
1646
1647    sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1648    if (sc.function == NULL)
1649        sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
1650
1651    return sc.function != NULL;
1652}
1653
1654uint32_t
1655SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1656{
1657    Timer scoped_timer(__PRETTY_FUNCTION__,
1658                       "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1659                       so_addr.GetSection(),
1660                       so_addr.GetOffset(),
1661                       resolve_scope);
1662    uint32_t resolved = 0;
1663    if (resolve_scope & (   eSymbolContextCompUnit |
1664                            eSymbolContextFunction |
1665                            eSymbolContextBlock |
1666                            eSymbolContextLineEntry))
1667    {
1668        lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1669
1670        DWARFDebugAranges* debug_aranges = DebugAranges();
1671        DWARFDebugInfo* debug_info = DebugInfo();
1672        if (debug_aranges)
1673        {
1674            dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1675            if (cu_offset != DW_INVALID_OFFSET)
1676            {
1677                uint32_t cu_idx;
1678                DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1679                if (curr_cu)
1680                {
1681                    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
1682                    assert(sc.comp_unit != NULL);
1683                    resolved |= eSymbolContextCompUnit;
1684
1685                    if (resolve_scope & eSymbolContextLineEntry)
1686                    {
1687                        LineTable *line_table = sc.comp_unit->GetLineTable();
1688                        if (line_table == NULL)
1689                        {
1690                            if (ParseCompileUnitLineTable(sc))
1691                                line_table = sc.comp_unit->GetLineTable();
1692                        }
1693                        if (line_table != NULL)
1694                        {
1695                            if (so_addr.IsLinkedAddress())
1696                            {
1697                                Address linked_addr (so_addr);
1698                                linked_addr.ResolveLinkedAddress();
1699                                if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1700                                {
1701                                    resolved |= eSymbolContextLineEntry;
1702                                }
1703                            }
1704                            else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1705                            {
1706                                resolved |= eSymbolContextLineEntry;
1707                            }
1708                        }
1709                    }
1710
1711                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1712                    {
1713                        DWARFDebugInfoEntry *function_die = NULL;
1714                        DWARFDebugInfoEntry *block_die = NULL;
1715                        if (resolve_scope & eSymbolContextBlock)
1716                        {
1717                            curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1718                        }
1719                        else
1720                        {
1721                            curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
1722                        }
1723
1724                        if (function_die != NULL)
1725                        {
1726                            sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1727                            if (sc.function == NULL)
1728                                sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
1729                        }
1730
1731                        if (sc.function != NULL)
1732                        {
1733                            resolved |= eSymbolContextFunction;
1734
1735                            if (resolve_scope & eSymbolContextBlock)
1736                            {
1737                                Block& block = sc.function->GetBlock (true);
1738
1739                                if (block_die != NULL)
1740                                    sc.block = block.FindBlockByID (block_die->GetOffset());
1741                                else
1742                                    sc.block = block.FindBlockByID (function_die->GetOffset());
1743                                if (sc.block)
1744                                    resolved |= eSymbolContextBlock;
1745                            }
1746                        }
1747                    }
1748                }
1749            }
1750        }
1751    }
1752    return resolved;
1753}
1754
1755
1756
1757uint32_t
1758SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1759{
1760    const uint32_t prev_size = sc_list.GetSize();
1761    if (resolve_scope & eSymbolContextCompUnit)
1762    {
1763        DWARFDebugInfo* debug_info = DebugInfo();
1764        if (debug_info)
1765        {
1766            uint32_t cu_idx;
1767            DWARFCompileUnit* curr_cu = NULL;
1768
1769            for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1770            {
1771                CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
1772                bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1773                if (check_inlines || file_spec_matches_cu_file_spec)
1774                {
1775                    SymbolContext sc (m_obj_file->GetModule());
1776                    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
1777                    assert(sc.comp_unit != NULL);
1778
1779                    uint32_t file_idx = UINT32_MAX;
1780
1781                    // If we are looking for inline functions only and we don't
1782                    // find it in the support files, we are done.
1783                    if (check_inlines)
1784                    {
1785                        file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1786                        if (file_idx == UINT32_MAX)
1787                            continue;
1788                    }
1789
1790                    if (line != 0)
1791                    {
1792                        LineTable *line_table = sc.comp_unit->GetLineTable();
1793
1794                        if (line_table != NULL && line != 0)
1795                        {
1796                            // We will have already looked up the file index if
1797                            // we are searching for inline entries.
1798                            if (!check_inlines)
1799                                file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1800
1801                            if (file_idx != UINT32_MAX)
1802                            {
1803                                uint32_t found_line;
1804                                uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1805                                found_line = sc.line_entry.line;
1806
1807                                while (line_idx != UINT32_MAX)
1808                                {
1809                                    sc.function = NULL;
1810                                    sc.block = NULL;
1811                                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1812                                    {
1813                                        const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1814                                        if (file_vm_addr != LLDB_INVALID_ADDRESS)
1815                                        {
1816                                            DWARFDebugInfoEntry *function_die = NULL;
1817                                            DWARFDebugInfoEntry *block_die = NULL;
1818                                            curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1819
1820                                            if (function_die != NULL)
1821                                            {
1822                                                sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1823                                                if (sc.function == NULL)
1824                                                    sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
1825                                            }
1826
1827                                            if (sc.function != NULL)
1828                                            {
1829                                                Block& block = sc.function->GetBlock (true);
1830
1831                                                if (block_die != NULL)
1832                                                    sc.block = block.FindBlockByID (block_die->GetOffset());
1833                                                else
1834                                                    sc.block = block.FindBlockByID (function_die->GetOffset());
1835                                            }
1836                                        }
1837                                    }
1838
1839                                    sc_list.Append(sc);
1840                                    line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1841                                }
1842                            }
1843                        }
1844                        else if (file_spec_matches_cu_file_spec && !check_inlines)
1845                        {
1846                            // only append the context if we aren't looking for inline call sites
1847                            // by file and line and if the file spec matches that of the compile unit
1848                            sc_list.Append(sc);
1849                        }
1850                    }
1851                    else if (file_spec_matches_cu_file_spec && !check_inlines)
1852                    {
1853                        // only append the context if we aren't looking for inline call sites
1854                        // by file and line and if the file spec matches that of the compile unit
1855                        sc_list.Append(sc);
1856                    }
1857
1858                    if (!check_inlines)
1859                        break;
1860                }
1861            }
1862        }
1863    }
1864    return sc_list.GetSize() - prev_size;
1865}
1866
1867void
1868SymbolFileDWARF::Index ()
1869{
1870    if (m_indexed)
1871        return;
1872    m_indexed = true;
1873    Timer scoped_timer (__PRETTY_FUNCTION__,
1874                        "SymbolFileDWARF::Index (%s)",
1875                        GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1876
1877    DWARFDebugInfo* debug_info = DebugInfo();
1878    if (debug_info)
1879    {
1880        m_aranges.reset(new DWARFDebugAranges());
1881
1882        uint32_t cu_idx = 0;
1883        const uint32_t num_compile_units = GetNumCompileUnits();
1884        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1885        {
1886            DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1887
1888            bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
1889
1890            curr_cu->Index (cu_idx,
1891                            m_function_basename_index,
1892                            m_function_fullname_index,
1893                            m_function_method_index,
1894                            m_function_selector_index,
1895                            m_objc_class_selectors_index,
1896                            m_global_index,
1897                            m_type_index,
1898                            m_namespace_index,
1899                            DebugRanges(),
1900                            m_aranges.get());
1901
1902            // Keep memory down by clearing DIEs if this generate function
1903            // caused them to be parsed
1904            if (clear_dies)
1905                curr_cu->ClearDIEs (true);
1906        }
1907
1908        m_aranges->Sort();
1909
1910#if defined (ENABLE_DEBUG_PRINTF)
1911        StreamFile s(stdout, false);
1912        s.Printf ("DWARF index for (%s) '%s/%s':",
1913                  GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1914                  GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1915                  GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1916        s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
1917        s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
1918        s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
1919        s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
1920        s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
1921        s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
1922        s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
1923        s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
1924#endif
1925    }
1926}
1927
1928uint32_t
1929SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1930{
1931    DWARFDebugInfo* info = DebugInfo();
1932    if (info == NULL)
1933        return 0;
1934
1935    // If we aren't appending the results to this list, then clear the list
1936    if (!append)
1937        variables.Clear();
1938
1939    // Remember how many variables are in the list before we search in case
1940    // we are appending the results to a variable list.
1941    const uint32_t original_size = variables.GetSize();
1942
1943    // Index the DWARF if we haven't already
1944    if (!m_indexed)
1945        Index ();
1946
1947    SymbolContext sc;
1948    sc.module_sp = m_obj_file->GetModule()->GetSP();
1949    assert (sc.module_sp);
1950
1951    DWARFCompileUnit* curr_cu = NULL;
1952    DWARFCompileUnit* prev_cu = NULL;
1953    const DWARFDebugInfoEntry* die = NULL;
1954    std::vector<NameToDIE::Info> die_info_array;
1955    const size_t num_matches = m_global_index.Find(name, die_info_array);
1956    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
1957    {
1958        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1959
1960        if (curr_cu != prev_cu)
1961            curr_cu->ExtractDIEsIfNeeded (false);
1962
1963        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1964
1965        sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
1966        assert(sc.comp_unit != NULL);
1967
1968        ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
1969
1970        if (variables.GetSize() - original_size >= max_matches)
1971            break;
1972    }
1973
1974    // Return the number of variable that were appended to the list
1975    return variables.GetSize() - original_size;
1976}
1977
1978uint32_t
1979SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1980{
1981    DWARFDebugInfo* info = DebugInfo();
1982    if (info == NULL)
1983        return 0;
1984
1985    // If we aren't appending the results to this list, then clear the list
1986    if (!append)
1987        variables.Clear();
1988
1989    // Remember how many variables are in the list before we search in case
1990    // we are appending the results to a variable list.
1991    const uint32_t original_size = variables.GetSize();
1992
1993    // Index the DWARF if we haven't already
1994    if (!m_indexed)
1995        Index ();
1996
1997    SymbolContext sc;
1998    sc.module_sp = m_obj_file->GetModule()->GetSP();
1999    assert (sc.module_sp);
2000
2001    DWARFCompileUnit* curr_cu = NULL;
2002    DWARFCompileUnit* prev_cu = NULL;
2003    const DWARFDebugInfoEntry* die = NULL;
2004    std::vector<NameToDIE::Info> die_info_array;
2005    const size_t num_matches = m_global_index.Find(regex, die_info_array);
2006    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2007    {
2008        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2009
2010        if (curr_cu != prev_cu)
2011            curr_cu->ExtractDIEsIfNeeded (false);
2012
2013        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2014
2015        sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
2016        assert(sc.comp_unit != NULL);
2017
2018        ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
2019
2020        if (variables.GetSize() - original_size >= max_matches)
2021            break;
2022    }
2023
2024    // Return the number of variable that were appended to the list
2025    return variables.GetSize() - original_size;
2026}
2027
2028
2029void
2030SymbolFileDWARF::FindFunctions
2031(
2032    const ConstString &name,
2033    const NameToDIE &name_to_die,
2034    SymbolContextList& sc_list
2035)
2036{
2037    DWARFDebugInfo* info = DebugInfo();
2038    if (info == NULL)
2039        return;
2040
2041    SymbolContext sc;
2042    sc.module_sp = m_obj_file->GetModule()->GetSP();
2043    assert (sc.module_sp);
2044
2045    DWARFCompileUnit* curr_cu = NULL;
2046    DWARFCompileUnit* prev_cu = NULL;
2047    const DWARFDebugInfoEntry* die = NULL;
2048    std::vector<NameToDIE::Info> die_info_array;
2049    const size_t num_matches = name_to_die.Find (name, die_info_array);
2050    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2051    {
2052        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2053
2054        if (curr_cu != prev_cu)
2055            curr_cu->ExtractDIEsIfNeeded (false);
2056
2057        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2058
2059        const DWARFDebugInfoEntry* inlined_die = NULL;
2060        if (die->Tag() == DW_TAG_inlined_subroutine)
2061        {
2062            inlined_die = die;
2063
2064            while ((die = die->GetParent()) != NULL)
2065            {
2066                if (die->Tag() == DW_TAG_subprogram)
2067                    break;
2068            }
2069        }
2070        assert (die->Tag() == DW_TAG_subprogram);
2071        if (GetFunction (curr_cu, die, sc))
2072        {
2073            Address addr;
2074            // Parse all blocks if needed
2075            if (inlined_die)
2076            {
2077                sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2078                assert (sc.block != NULL);
2079                if (sc.block->GetStartAddress (addr) == false)
2080                    addr.Clear();
2081            }
2082            else
2083            {
2084                sc.block = NULL;
2085                addr = sc.function->GetAddressRange().GetBaseAddress();
2086            }
2087
2088            if (addr.IsValid())
2089            {
2090
2091                // We found the function, so we should find the line table
2092                // and line table entry as well
2093                LineTable *line_table = sc.comp_unit->GetLineTable();
2094                if (line_table == NULL)
2095                {
2096                    if (ParseCompileUnitLineTable(sc))
2097                        line_table = sc.comp_unit->GetLineTable();
2098                }
2099                if (line_table != NULL)
2100                    line_table->FindLineEntryByAddress (addr, sc.line_entry);
2101
2102                sc_list.Append(sc);
2103            }
2104        }
2105    }
2106}
2107
2108
2109void
2110SymbolFileDWARF::FindFunctions
2111(
2112    const RegularExpression &regex,
2113    const NameToDIE &name_to_die,
2114    SymbolContextList& sc_list
2115)
2116{
2117    DWARFDebugInfo* info = DebugInfo();
2118    if (info == NULL)
2119        return;
2120
2121    SymbolContext sc;
2122    sc.module_sp = m_obj_file->GetModule()->GetSP();
2123    assert (sc.module_sp);
2124
2125    DWARFCompileUnit* curr_cu = NULL;
2126    DWARFCompileUnit* prev_cu = NULL;
2127    const DWARFDebugInfoEntry* die = NULL;
2128    std::vector<NameToDIE::Info> die_info_array;
2129    const size_t num_matches = name_to_die.Find(regex, die_info_array);
2130    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2131    {
2132        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2133
2134        if (curr_cu != prev_cu)
2135            curr_cu->ExtractDIEsIfNeeded (false);
2136
2137        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2138
2139        const DWARFDebugInfoEntry* inlined_die = NULL;
2140        if (die->Tag() == DW_TAG_inlined_subroutine)
2141        {
2142            inlined_die = die;
2143
2144            while ((die = die->GetParent()) != NULL)
2145            {
2146                if (die->Tag() == DW_TAG_subprogram)
2147                    break;
2148            }
2149        }
2150        assert (die->Tag() == DW_TAG_subprogram);
2151        if (GetFunction (curr_cu, die, sc))
2152        {
2153            Address addr;
2154            // Parse all blocks if needed
2155            if (inlined_die)
2156            {
2157                sc.block = sc.function->GetBlock (true).FindBlockByID (inlined_die->GetOffset());
2158                assert (sc.block != NULL);
2159                if (sc.block->GetStartAddress (addr) == false)
2160                    addr.Clear();
2161            }
2162            else
2163            {
2164                sc.block = NULL;
2165                addr = sc.function->GetAddressRange().GetBaseAddress();
2166            }
2167
2168            if (addr.IsValid())
2169            {
2170
2171                // We found the function, so we should find the line table
2172                // and line table entry as well
2173                LineTable *line_table = sc.comp_unit->GetLineTable();
2174                if (line_table == NULL)
2175                {
2176                    if (ParseCompileUnitLineTable(sc))
2177                        line_table = sc.comp_unit->GetLineTable();
2178                }
2179                if (line_table != NULL)
2180                    line_table->FindLineEntryByAddress (addr, sc.line_entry);
2181
2182                sc_list.Append(sc);
2183            }
2184        }
2185    }
2186}
2187
2188uint32_t
2189SymbolFileDWARF::FindFunctions
2190(
2191    const ConstString &name,
2192    uint32_t name_type_mask,
2193    bool append,
2194    SymbolContextList& sc_list
2195)
2196{
2197    Timer scoped_timer (__PRETTY_FUNCTION__,
2198                        "SymbolFileDWARF::FindFunctions (name = '%s')",
2199                        name.AsCString());
2200
2201    // If we aren't appending the results to this list, then clear the list
2202    if (!append)
2203        sc_list.Clear();
2204
2205    // Remember how many sc_list are in the list before we search in case
2206    // we are appending the results to a variable list.
2207    uint32_t original_size = sc_list.GetSize();
2208
2209    // Index the DWARF if we haven't already
2210    if (!m_indexed)
2211        Index ();
2212
2213    if (name_type_mask & eFunctionNameTypeBase)
2214        FindFunctions (name, m_function_basename_index, sc_list);
2215
2216    if (name_type_mask & eFunctionNameTypeFull)
2217        FindFunctions (name, m_function_fullname_index, sc_list);
2218
2219    if (name_type_mask & eFunctionNameTypeMethod)
2220        FindFunctions (name, m_function_method_index, sc_list);
2221
2222    if (name_type_mask & eFunctionNameTypeSelector)
2223        FindFunctions (name, m_function_selector_index, sc_list);
2224
2225    // Return the number of variable that were appended to the list
2226    return sc_list.GetSize() - original_size;
2227}
2228
2229
2230uint32_t
2231SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2232{
2233    Timer scoped_timer (__PRETTY_FUNCTION__,
2234                        "SymbolFileDWARF::FindFunctions (regex = '%s')",
2235                        regex.GetText());
2236
2237    // If we aren't appending the results to this list, then clear the list
2238    if (!append)
2239        sc_list.Clear();
2240
2241    // Remember how many sc_list are in the list before we search in case
2242    // we are appending the results to a variable list.
2243    uint32_t original_size = sc_list.GetSize();
2244
2245    // Index the DWARF if we haven't already
2246    if (!m_indexed)
2247        Index ();
2248
2249    FindFunctions (regex, m_function_basename_index, sc_list);
2250
2251    FindFunctions (regex, m_function_fullname_index, sc_list);
2252
2253    // Return the number of variable that were appended to the list
2254    return sc_list.GetSize() - original_size;
2255}
2256void
2257SymbolFileDWARF::ReportError (const char *format, ...)
2258{
2259    ::fprintf (stderr,
2260               "error: %s/%s ",
2261               m_obj_file->GetFileSpec().GetDirectory().GetCString(),
2262               m_obj_file->GetFileSpec().GetFilename().GetCString());
2263
2264    va_list args;
2265    va_start (args, format);
2266    vfprintf (stderr, format, args);
2267    va_end (args);
2268}
2269
2270uint32_t
2271SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
2272{
2273    DWARFDebugInfo* info = DebugInfo();
2274    if (info == NULL)
2275        return 0;
2276
2277    // If we aren't appending the results to this list, then clear the list
2278    if (!append)
2279        types.Clear();
2280
2281    // Index if we already haven't to make sure the compile units
2282    // get indexed and make their global DIE index list
2283    if (!m_indexed)
2284        Index ();
2285
2286    const uint32_t initial_types_size = types.GetSize();
2287    DWARFCompileUnit* curr_cu = NULL;
2288    DWARFCompileUnit* prev_cu = NULL;
2289    const DWARFDebugInfoEntry* die = NULL;
2290    std::vector<NameToDIE::Info> die_info_array;
2291    const size_t num_matches = m_type_index.Find (name, die_info_array);
2292    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2293    {
2294        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2295
2296        if (curr_cu != prev_cu)
2297            curr_cu->ExtractDIEsIfNeeded (false);
2298
2299        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2300
2301        Type *matching_type = ResolveType (curr_cu, die);
2302        if (matching_type)
2303        {
2304            // We found a type pointer, now find the shared pointer form our type list
2305            TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
2306            if (type_sp)
2307            {
2308                types.InsertUnique (type_sp);
2309                if (types.GetSize() >= max_matches)
2310                    break;
2311            }
2312            else
2313            {
2314                fprintf (stderr, "error: can't find shared pointer for type 0x%8.8x.\n", matching_type->GetID());
2315            }
2316        }
2317    }
2318    return types.GetSize() - initial_types_size;
2319}
2320
2321
2322ClangNamespaceDecl
2323SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2324                                const ConstString &name)
2325{
2326    ClangNamespaceDecl namespace_decl;
2327    DWARFDebugInfo* info = DebugInfo();
2328    if (info)
2329    {
2330        // Index if we already haven't to make sure the compile units
2331        // get indexed and make their global DIE index list
2332        if (!m_indexed)
2333            Index ();
2334
2335        DWARFCompileUnit* curr_cu = NULL;
2336        DWARFCompileUnit* prev_cu = NULL;
2337        const DWARFDebugInfoEntry* die = NULL;
2338        std::vector<NameToDIE::Info> die_info_array;
2339        const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2340        for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2341        {
2342            curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2343
2344            if (curr_cu != prev_cu)
2345                curr_cu->ExtractDIEsIfNeeded (false);
2346
2347            die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2348
2349            clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (curr_cu, die);
2350            if (clang_namespace_decl)
2351            {
2352                namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
2353                namespace_decl.SetNamespaceDecl (clang_namespace_decl);
2354            }
2355        }
2356    }
2357    return namespace_decl;
2358}
2359
2360uint32_t
2361SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
2362{
2363    // Remember how many sc_list are in the list before we search in case
2364    // we are appending the results to a variable list.
2365    uint32_t original_size = types.GetSize();
2366
2367    const uint32_t num_die_offsets = die_offsets.size();
2368    // Parse all of the types we found from the pubtypes matches
2369    uint32_t i;
2370    uint32_t num_matches = 0;
2371    for (i = 0; i < num_die_offsets; ++i)
2372    {
2373        Type *matching_type = ResolveTypeUID (die_offsets[i]);
2374        if (matching_type)
2375        {
2376            // We found a type pointer, now find the shared pointer form our type list
2377            TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
2378            assert (type_sp.get() != NULL);
2379            types.InsertUnique (type_sp);
2380            ++num_matches;
2381            if (num_matches >= max_matches)
2382                break;
2383        }
2384    }
2385
2386    // Return the number of variable that were appended to the list
2387    return types.GetSize() - original_size;
2388}
2389
2390
2391size_t
2392SymbolFileDWARF::ParseChildParameters
2393(
2394    const SymbolContext& sc,
2395    TypeSP& type_sp,
2396    DWARFCompileUnit* dwarf_cu,
2397    const DWARFDebugInfoEntry *parent_die,
2398    bool skip_artificial,
2399    bool &is_static,
2400    TypeList* type_list,
2401    std::vector<clang_type_t>& function_param_types,
2402    std::vector<clang::ParmVarDecl*>& function_param_decls,
2403    unsigned &type_quals
2404)
2405{
2406    if (parent_die == NULL)
2407        return 0;
2408
2409    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2410
2411    size_t arg_idx = 0;
2412    const DWARFDebugInfoEntry *die;
2413    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2414    {
2415        dw_tag_t tag = die->Tag();
2416        switch (tag)
2417        {
2418        case DW_TAG_formal_parameter:
2419            {
2420                DWARFDebugInfoEntry::Attributes attributes;
2421                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
2422                if (num_attributes > 0)
2423                {
2424                    const char *name = NULL;
2425                    Declaration decl;
2426                    dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
2427                    bool is_artificial = false;
2428                    // one of None, Auto, Register, Extern, Static, PrivateExtern
2429
2430                    clang::StorageClass storage = clang::SC_None;
2431                    uint32_t i;
2432                    for (i=0; i<num_attributes; ++i)
2433                    {
2434                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2435                        DWARFFormValue form_value;
2436                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2437                        {
2438                            switch (attr)
2439                            {
2440                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2441                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2442                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2443                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
2444                            case DW_AT_type:        param_type_die_offset = form_value.Reference(dwarf_cu); break;
2445                            case DW_AT_artificial:  is_artificial = form_value.Unsigned() != 0; break;
2446                            case DW_AT_location:
2447    //                          if (form_value.BlockData())
2448    //                          {
2449    //                              const DataExtractor& debug_info_data = debug_info();
2450    //                              uint32_t block_length = form_value.Unsigned();
2451    //                              DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2452    //                          }
2453    //                          else
2454    //                          {
2455    //                          }
2456    //                          break;
2457                            case DW_AT_const_value:
2458                            case DW_AT_default_value:
2459                            case DW_AT_description:
2460                            case DW_AT_endianity:
2461                            case DW_AT_is_optional:
2462                            case DW_AT_segment:
2463                            case DW_AT_variable_parameter:
2464                            default:
2465                            case DW_AT_abstract_origin:
2466                            case DW_AT_sibling:
2467                                break;
2468                            }
2469                        }
2470                    }
2471
2472                    bool skip = false;
2473                    if (skip_artificial)
2474                    {
2475                        if (is_artificial)
2476                        {
2477                            // In order to determine if a C++ member function is
2478                            // "const" we have to look at the const-ness of "this"...
2479                            // Ugly, but that
2480                            if (arg_idx == 0)
2481                            {
2482                                const DWARFDebugInfoEntry *grandparent_die = parent_die->GetParent();
2483                                if (grandparent_die && (grandparent_die->Tag() == DW_TAG_structure_type ||
2484                                                        grandparent_die->Tag() == DW_TAG_class_type))
2485                                {
2486                                    LanguageType language = sc.comp_unit->GetLanguage();
2487                                    if (language == eLanguageTypeObjC_plus_plus || language == eLanguageTypeC_plus_plus)
2488                                    {
2489                                        // Often times compilers omit the "this" name for the
2490                                        // specification DIEs, so we can't rely upon the name
2491                                        // being in the formal parameter DIE...
2492                                        if (name == NULL || ::strcmp(name, "this")==0)
2493                                        {
2494                                            Type *this_type = ResolveTypeUID (param_type_die_offset);
2495                                            if (this_type)
2496                                            {
2497                                                uint32_t encoding_mask = this_type->GetEncodingMask();
2498                                                if (encoding_mask & Type::eEncodingIsPointerUID)
2499                                                {
2500                                                    is_static = false;
2501
2502                                                    if (encoding_mask & (1u << Type::eEncodingIsConstUID))
2503                                                        type_quals |= clang::Qualifiers::Const;
2504                                                    if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
2505                                                        type_quals |= clang::Qualifiers::Volatile;
2506                                                }
2507                                            }
2508                                        }
2509                                    }
2510                                }
2511                            }
2512                            skip = true;
2513                        }
2514                        else
2515                        {
2516
2517                            // HACK: Objective C formal parameters "self" and "_cmd"
2518                            // are not marked as artificial in the DWARF...
2519                            CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2520                            if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
2521                            {
2522                                if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2523                                    skip = true;
2524                            }
2525                        }
2526                    }
2527
2528                    if (!skip)
2529                    {
2530                        Type *type = ResolveTypeUID(param_type_die_offset);
2531                        if (type)
2532                        {
2533                            function_param_types.push_back (type->GetClangForwardType());
2534
2535                            clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
2536                            assert(param_var_decl);
2537                            function_param_decls.push_back(param_var_decl);
2538                        }
2539                    }
2540                }
2541                arg_idx++;
2542            }
2543            break;
2544
2545        default:
2546            break;
2547        }
2548    }
2549    return arg_idx;
2550}
2551
2552size_t
2553SymbolFileDWARF::ParseChildEnumerators
2554(
2555    const SymbolContext& sc,
2556    clang_type_t  enumerator_clang_type,
2557    uint32_t enumerator_byte_size,
2558    DWARFCompileUnit* dwarf_cu,
2559    const DWARFDebugInfoEntry *parent_die
2560)
2561{
2562    if (parent_die == NULL)
2563        return 0;
2564
2565    size_t enumerators_added = 0;
2566    const DWARFDebugInfoEntry *die;
2567    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2568
2569    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2570    {
2571        const dw_tag_t tag = die->Tag();
2572        if (tag == DW_TAG_enumerator)
2573        {
2574            DWARFDebugInfoEntry::Attributes attributes;
2575            const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
2576            if (num_child_attributes > 0)
2577            {
2578                const char *name = NULL;
2579                bool got_value = false;
2580                int64_t enum_value = 0;
2581                Declaration decl;
2582
2583                uint32_t i;
2584                for (i=0; i<num_child_attributes; ++i)
2585                {
2586                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
2587                    DWARFFormValue form_value;
2588                    if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2589                    {
2590                        switch (attr)
2591                        {
2592                        case DW_AT_const_value:
2593                            got_value = true;
2594                            enum_value = form_value.Unsigned();
2595                            break;
2596
2597                        case DW_AT_name:
2598                            name = form_value.AsCString(&get_debug_str_data());
2599                            break;
2600
2601                        case DW_AT_description:
2602                        default:
2603                        case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2604                        case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2605                        case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2606                        case DW_AT_sibling:
2607                            break;
2608                        }
2609                    }
2610                }
2611
2612                if (name && name[0] && got_value)
2613                {
2614                    GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2615                                                                               enumerator_clang_type,
2616                                                                               decl,
2617                                                                               name,
2618                                                                               enum_value,
2619                                                                               enumerator_byte_size * 8);
2620                    ++enumerators_added;
2621                }
2622            }
2623        }
2624    }
2625    return enumerators_added;
2626}
2627
2628void
2629SymbolFileDWARF::ParseChildArrayInfo
2630(
2631    const SymbolContext& sc,
2632    DWARFCompileUnit* dwarf_cu,
2633    const DWARFDebugInfoEntry *parent_die,
2634    int64_t& first_index,
2635    std::vector<uint64_t>& element_orders,
2636    uint32_t& byte_stride,
2637    uint32_t& bit_stride
2638)
2639{
2640    if (parent_die == NULL)
2641        return;
2642
2643    const DWARFDebugInfoEntry *die;
2644    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2645    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2646    {
2647        const dw_tag_t tag = die->Tag();
2648        switch (tag)
2649        {
2650        case DW_TAG_enumerator:
2651            {
2652                DWARFDebugInfoEntry::Attributes attributes;
2653                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
2654                if (num_child_attributes > 0)
2655                {
2656                    const char *name = NULL;
2657                    bool got_value = false;
2658                    int64_t enum_value = 0;
2659
2660                    uint32_t i;
2661                    for (i=0; i<num_child_attributes; ++i)
2662                    {
2663                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2664                        DWARFFormValue form_value;
2665                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2666                        {
2667                            switch (attr)
2668                            {
2669                            case DW_AT_const_value:
2670                                got_value = true;
2671                                enum_value = form_value.Unsigned();
2672                                break;
2673
2674                            case DW_AT_name:
2675                                name = form_value.AsCString(&get_debug_str_data());
2676                                break;
2677
2678                            case DW_AT_description:
2679                            default:
2680                            case DW_AT_decl_file:
2681                            case DW_AT_decl_line:
2682                            case DW_AT_decl_column:
2683                            case DW_AT_sibling:
2684                                break;
2685                            }
2686                        }
2687                    }
2688                }
2689            }
2690            break;
2691
2692        case DW_TAG_subrange_type:
2693            {
2694                DWARFDebugInfoEntry::Attributes attributes;
2695                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
2696                if (num_child_attributes > 0)
2697                {
2698                    const char *name = NULL;
2699                    bool got_value = false;
2700                    uint64_t byte_size = 0;
2701                    int64_t enum_value = 0;
2702                    uint64_t num_elements = 0;
2703                    uint64_t lower_bound = 0;
2704                    uint64_t upper_bound = 0;
2705                    uint32_t i;
2706                    for (i=0; i<num_child_attributes; ++i)
2707                    {
2708                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2709                        DWARFFormValue form_value;
2710                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2711                        {
2712                            switch (attr)
2713                            {
2714                            case DW_AT_const_value:
2715                                got_value = true;
2716                                enum_value = form_value.Unsigned();
2717                                break;
2718
2719                            case DW_AT_name:
2720                                name = form_value.AsCString(&get_debug_str_data());
2721                                break;
2722
2723                            case DW_AT_count:
2724                                num_elements = form_value.Unsigned();
2725                                break;
2726
2727                            case DW_AT_bit_stride:
2728                                bit_stride = form_value.Unsigned();
2729                                break;
2730
2731                            case DW_AT_byte_stride:
2732                                byte_stride = form_value.Unsigned();
2733                                break;
2734
2735                            case DW_AT_byte_size:
2736                                byte_size = form_value.Unsigned();
2737                                break;
2738
2739                            case DW_AT_lower_bound:
2740                                lower_bound = form_value.Unsigned();
2741                                break;
2742
2743                            case DW_AT_upper_bound:
2744                                upper_bound = form_value.Unsigned();
2745                                break;
2746
2747                            default:
2748                            case DW_AT_abstract_origin:
2749                            case DW_AT_accessibility:
2750                            case DW_AT_allocated:
2751                            case DW_AT_associated:
2752                            case DW_AT_data_location:
2753                            case DW_AT_declaration:
2754                            case DW_AT_description:
2755                            case DW_AT_sibling:
2756                            case DW_AT_threads_scaled:
2757                            case DW_AT_type:
2758                            case DW_AT_visibility:
2759                                break;
2760                            }
2761                        }
2762                    }
2763
2764                    if (upper_bound > lower_bound)
2765                        num_elements = upper_bound - lower_bound + 1;
2766
2767                    if (num_elements > 0)
2768                        element_orders.push_back (num_elements);
2769                }
2770            }
2771            break;
2772        }
2773    }
2774}
2775
2776TypeSP
2777SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
2778{
2779    TypeSP type_sp;
2780    if (die != NULL)
2781    {
2782        assert(curr_cu != NULL);
2783        Type *type_ptr = m_die_to_type.lookup (die);
2784        if (type_ptr == NULL)
2785        {
2786            CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
2787            assert (lldb_cu);
2788            SymbolContext sc(lldb_cu);
2789            type_sp = ParseType(sc, curr_cu, die, NULL);
2790        }
2791        else if (type_ptr != DIE_IS_BEING_PARSED)
2792        {
2793            // Grab the existing type from the master types lists
2794            type_sp = GetTypeList()->FindType(type_ptr->GetID());
2795        }
2796
2797    }
2798    return type_sp;
2799}
2800
2801clang::DeclContext *
2802SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2803{
2804    if (die_offset != DW_INVALID_OFFSET)
2805    {
2806        DWARFCompileUnitSP cu_sp;
2807        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2808        return GetClangDeclContextForDIE (cu_sp.get(), die);
2809    }
2810    return NULL;
2811}
2812
2813
2814clang::NamespaceDecl *
2815SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2816{
2817    if (die->Tag() == DW_TAG_namespace)
2818    {
2819        const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2820        if (namespace_name)
2821        {
2822            Declaration decl;   // TODO: fill in the decl object
2823            clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2824            if (namespace_decl)
2825                LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
2826            return namespace_decl;
2827        }
2828    }
2829    return NULL;
2830}
2831
2832clang::DeclContext *
2833SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2834{
2835    if (m_clang_tu_decl == NULL)
2836        m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
2837
2838    //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x )\n", die->GetOffset());
2839    const DWARFDebugInfoEntry * const decl_die = die;
2840    clang::DeclContext *decl_ctx = NULL;
2841
2842    while (die != NULL)
2843    {
2844        // If this is the original DIE that we are searching for a declaration
2845        // for, then don't look in the cache as we don't want our own decl
2846        // context to be our decl context...
2847        if (decl_die != die)
2848        {
2849            DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2850            if (pos != m_die_to_decl_ctx.end())
2851            {
2852                //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2853                return pos->second;
2854            }
2855
2856            //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) checking parent 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2857
2858            switch (die->Tag())
2859            {
2860            case DW_TAG_namespace:
2861                {
2862                    const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2863                    if (namespace_name)
2864                    {
2865                        Declaration decl;   // TODO: fill in the decl object
2866                        clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die));
2867                        if (namespace_decl)
2868                        {
2869                            //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2870                            LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
2871                        }
2872                        return namespace_decl;
2873                    }
2874                }
2875                break;
2876
2877            case DW_TAG_structure_type:
2878            case DW_TAG_union_type:
2879            case DW_TAG_class_type:
2880                {
2881                    Type* type = ResolveType (curr_cu, die);
2882                    pos = m_die_to_decl_ctx.find(die);
2883                    if (pos != m_die_to_decl_ctx.end())
2884                    {
2885                        //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), die->GetOffset());
2886                        return pos->second;
2887                    }
2888                    else
2889                    {
2890                        if (type)
2891                        {
2892                            decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
2893                            if (decl_ctx)
2894                                return decl_ctx;
2895                        }
2896                    }
2897                }
2898                break;
2899
2900            default:
2901                break;
2902            }
2903        }
2904
2905        dw_offset_t die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET);
2906        if (die_offset != DW_INVALID_OFFSET)
2907        {
2908            //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_specification 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2909            decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
2910            if (decl_ctx != m_clang_tu_decl)
2911                return decl_ctx;
2912        }
2913
2914        die_offset = die->GetAttributeValueAsReference(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
2915        if (die_offset != DW_INVALID_OFFSET)
2916        {
2917            //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) check DW_AT_abstract_origin 0x%8.8x\n", decl_die->GetOffset(), die_offset);
2918            decl_ctx = GetClangDeclContextForDIEOffset (die_offset);
2919            if (decl_ctx != m_clang_tu_decl)
2920                return decl_ctx;
2921        }
2922
2923        die = die->GetParent();
2924    }
2925    // Right now we have only one translation unit per module...
2926    //printf ("SymbolFileDWARF::GetClangDeclContextForDIE ( die = 0x%8.8x ) => 0x%8.8x\n", decl_die->GetOffset(), curr_cu->GetFirstDIEOffset());
2927    return m_clang_tu_decl;
2928}
2929
2930// This function can be used when a DIE is found that is a forward declaration
2931// DIE and we want to try and find a type that has the complete definition.
2932TypeSP
2933SymbolFileDWARF::FindDefinitionTypeForDIE (
2934    DWARFCompileUnit* cu,
2935    const DWARFDebugInfoEntry *die,
2936    const ConstString &type_name
2937)
2938{
2939    TypeSP type_sp;
2940
2941    if (cu == NULL || die == NULL || !type_name)
2942        return type_sp;
2943
2944    if (!m_indexed)
2945        Index ();
2946
2947    const dw_tag_t type_tag = die->Tag();
2948    std::vector<NameToDIE::Info> die_info_array;
2949    const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2950    if (num_matches > 0)
2951    {
2952        DWARFCompileUnit* type_cu = NULL;
2953        DWARFCompileUnit* curr_cu = cu;
2954        DWARFDebugInfo *info = DebugInfo();
2955        for (size_t i=0; i<num_matches; ++i)
2956        {
2957            type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2958
2959            if (type_cu != curr_cu)
2960            {
2961                type_cu->ExtractDIEsIfNeeded (false);
2962                curr_cu = type_cu;
2963            }
2964
2965            DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2966
2967            if (type_die != die && type_die->Tag() == type_tag)
2968            {
2969                // Hold off on comparing parent DIE tags until
2970                // we know what happens with stuff in namespaces
2971                // for gcc and clang...
2972                //DWARFDebugInfoEntry *parent_die = die->GetParent();
2973                //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2974                //if (parent_die->Tag() == parent_type_die->Tag())
2975                {
2976                    Type *resolved_type = ResolveType (type_cu, type_die, false);
2977                    if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2978                    {
2979                        DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2980                                      die->GetOffset(),
2981                                      curr_cu->GetOffset(),
2982                                      m_obj_file->GetFileSpec().GetFilename().AsCString(),
2983                                      type_die->GetOffset(),
2984                                      type_cu->GetOffset());
2985
2986                        m_die_to_type[die] = resolved_type;
2987                        type_sp = GetTypeList()->FindType(resolved_type->GetID());
2988                        if (!type_sp)
2989                        {
2990                            DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2991                        }
2992                        break;
2993                    }
2994                }
2995            }
2996        }
2997    }
2998    return type_sp;
2999}
3000
3001TypeSP
3002SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
3003{
3004    TypeSP type_sp;
3005
3006    if (type_is_new_ptr)
3007        *type_is_new_ptr = false;
3008
3009    AccessType accessibility = eAccessNone;
3010    if (die != NULL)
3011    {
3012        Type *type_ptr = m_die_to_type.lookup (die);
3013        TypeList* type_list = GetTypeList();
3014        if (type_ptr == NULL)
3015        {
3016            ClangASTContext &ast = GetClangASTContext();
3017            if (type_is_new_ptr)
3018                *type_is_new_ptr = true;
3019
3020            const dw_tag_t tag = die->Tag();
3021
3022            bool is_forward_declaration = false;
3023            DWARFDebugInfoEntry::Attributes attributes;
3024            const char *type_name_cstr = NULL;
3025            ConstString type_name_const_str;
3026            Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
3027            size_t byte_size = 0;
3028            bool byte_size_valid = false;
3029            Declaration decl;
3030
3031            Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
3032            clang_type_t clang_type = NULL;
3033
3034            dw_attr_t attr;
3035
3036            switch (tag)
3037            {
3038            case DW_TAG_base_type:
3039            case DW_TAG_pointer_type:
3040            case DW_TAG_reference_type:
3041            case DW_TAG_typedef:
3042            case DW_TAG_const_type:
3043            case DW_TAG_restrict_type:
3044            case DW_TAG_volatile_type:
3045                {
3046                    // Set a bit that lets us know that we are currently parsing this
3047                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
3048
3049                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3050                    uint32_t encoding = 0;
3051                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
3052
3053                    if (num_attributes > 0)
3054                    {
3055                        uint32_t i;
3056                        for (i=0; i<num_attributes; ++i)
3057                        {
3058                            attr = attributes.AttributeAtIndex(i);
3059                            DWARFFormValue form_value;
3060                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3061                            {
3062                                switch (attr)
3063                                {
3064                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3065                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3066                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3067                                case DW_AT_name:
3068
3069                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3070                                    // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
3071                                    // include the "&"...
3072                                    if (tag == DW_TAG_reference_type)
3073                                    {
3074                                        if (strchr (type_name_cstr, '&') == NULL)
3075                                            type_name_cstr = NULL;
3076                                    }
3077                                    if (type_name_cstr)
3078                                        type_name_const_str.SetCString(type_name_cstr);
3079                                    break;
3080                                case DW_AT_byte_size:   byte_size = form_value.Unsigned();  byte_size_valid = true; break;
3081                                case DW_AT_encoding:    encoding = form_value.Unsigned(); break;
3082                                case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
3083                                default:
3084                                case DW_AT_sibling:
3085                                    break;
3086                                }
3087                            }
3088                        }
3089                    }
3090
3091                    DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") type => 0x%8.8x\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
3092
3093                    switch (tag)
3094                    {
3095                    default:
3096                        break;
3097
3098                    case DW_TAG_base_type:
3099                        resolve_state = Type::eResolveStateFull;
3100                        clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
3101                                                                                   encoding,
3102                                                                                   byte_size * 8);
3103                        break;
3104
3105                    case DW_TAG_pointer_type:   encoding_data_type = Type::eEncodingIsPointerUID;           break;
3106                    case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID;   break;
3107                    case DW_TAG_typedef:        encoding_data_type = Type::eEncodingIsTypedefUID;           break;
3108                    case DW_TAG_const_type:     encoding_data_type = Type::eEncodingIsConstUID;             break;
3109                    case DW_TAG_restrict_type:  encoding_data_type = Type::eEncodingIsRestrictUID;          break;
3110                    case DW_TAG_volatile_type:  encoding_data_type = Type::eEncodingIsVolatileUID;          break;
3111                    }
3112
3113                    if (type_name_cstr != NULL && sc.comp_unit != NULL &&
3114                        (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
3115                    {
3116                        static ConstString g_objc_type_name_id("id");
3117                        static ConstString g_objc_type_name_Class("Class");
3118                        static ConstString g_objc_type_name_selector("SEL");
3119
3120                        if (type_name_const_str == g_objc_type_name_id)
3121                        {
3122                            clang_type = ast.GetBuiltInType_objc_id();
3123                            resolve_state = Type::eResolveStateFull;
3124
3125                        }
3126                        else if (type_name_const_str == g_objc_type_name_Class)
3127                        {
3128                            clang_type = ast.GetBuiltInType_objc_Class();
3129                            resolve_state = Type::eResolveStateFull;
3130                        }
3131                        else if (type_name_const_str == g_objc_type_name_selector)
3132                        {
3133                            clang_type = ast.GetBuiltInType_objc_selector();
3134                            resolve_state = Type::eResolveStateFull;
3135                        }
3136                    }
3137
3138                    type_sp.reset( new Type (die->GetOffset(),
3139                                             this,
3140                                             type_name_const_str,
3141                                             byte_size,
3142                                             NULL,
3143                                             encoding_uid,
3144                                             encoding_data_type,
3145                                             &decl,
3146                                             clang_type,
3147                                             resolve_state));
3148
3149                    m_die_to_type[die] = type_sp.get();
3150
3151//                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
3152//                  if (encoding_type != NULL)
3153//                  {
3154//                      if (encoding_type != DIE_IS_BEING_PARSED)
3155//                          type_sp->SetEncodingType(encoding_type);
3156//                      else
3157//                          m_indirect_fixups.push_back(type_sp.get());
3158//                  }
3159                }
3160                break;
3161
3162            case DW_TAG_structure_type:
3163            case DW_TAG_union_type:
3164            case DW_TAG_class_type:
3165                {
3166                    // Set a bit that lets us know that we are currently parsing this
3167                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
3168
3169                    LanguageType class_language = eLanguageTypeUnknown;
3170                    //bool struct_is_class = false;
3171                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3172                    if (num_attributes > 0)
3173                    {
3174                        uint32_t i;
3175                        for (i=0; i<num_attributes; ++i)
3176                        {
3177                            attr = attributes.AttributeAtIndex(i);
3178                            DWARFFormValue form_value;
3179                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3180                            {
3181                                switch (attr)
3182                                {
3183                                case DW_AT_decl_file:
3184                                    decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
3185                                    break;
3186
3187                                case DW_AT_decl_line:
3188                                    decl.SetLine(form_value.Unsigned());
3189                                    break;
3190
3191                                case DW_AT_decl_column:
3192                                    decl.SetColumn(form_value.Unsigned());
3193                                    break;
3194
3195                                case DW_AT_name:
3196                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3197                                    type_name_const_str.SetCString(type_name_cstr);
3198                                    break;
3199
3200                                case DW_AT_byte_size:
3201                                    byte_size = form_value.Unsigned();
3202                                    byte_size_valid = true;
3203                                    break;
3204
3205                                case DW_AT_accessibility:
3206                                    accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3207                                    break;
3208
3209                                case DW_AT_declaration:
3210                                    is_forward_declaration = form_value.Unsigned() != 0;
3211                                    break;
3212
3213                                case DW_AT_APPLE_runtime_class:
3214                                    class_language = (LanguageType)form_value.Signed();
3215                                    break;
3216
3217                                case DW_AT_allocated:
3218                                case DW_AT_associated:
3219                                case DW_AT_data_location:
3220                                case DW_AT_description:
3221                                case DW_AT_start_scope:
3222                                case DW_AT_visibility:
3223                                default:
3224                                case DW_AT_sibling:
3225                                    break;
3226                                }
3227                            }
3228                        }
3229                    }
3230
3231                    UniqueDWARFASTType unique_ast_entry;
3232                    if (decl.IsValid())
3233                    {
3234                        if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
3235                                                             this,
3236                                                             dwarf_cu,
3237                                                             die,
3238                                                             decl,
3239                                                             byte_size_valid ? byte_size : -1,
3240                                                             unique_ast_entry))
3241                        {
3242                            // We have already parsed this type or from another
3243                            // compile unit. GCC loves to use the "one definition
3244                            // rule" which can result in multiple definitions
3245                            // of the same class over and over in each compile
3246                            // unit.
3247                            type_sp = unique_ast_entry.m_type_sp;
3248                            if (type_sp)
3249                            {
3250                                m_die_to_type[die] = type_sp.get();
3251                                return type_sp;
3252                            }
3253                        }
3254                    }
3255
3256                    DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3257
3258                    int tag_decl_kind = -1;
3259                    AccessType default_accessibility = eAccessNone;
3260                    if (tag == DW_TAG_structure_type)
3261                    {
3262                        tag_decl_kind = clang::TTK_Struct;
3263                        default_accessibility = eAccessPublic;
3264                    }
3265                    else if (tag == DW_TAG_union_type)
3266                    {
3267                        tag_decl_kind = clang::TTK_Union;
3268                        default_accessibility = eAccessPublic;
3269                    }
3270                    else if (tag == DW_TAG_class_type)
3271                    {
3272                        tag_decl_kind = clang::TTK_Class;
3273                        default_accessibility = eAccessPrivate;
3274                    }
3275
3276
3277                    if (is_forward_declaration)
3278                    {
3279                        // We have a forward declaration to a type and we need
3280                        // to try and find a full declaration. We look in the
3281                        // current type index just in case we have a forward
3282                        // declaration followed by an actual declarations in the
3283                        // DWARF. If this fails, we need to look elsewhere...
3284
3285                        type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3286
3287                        if (!type_sp && m_debug_map_symfile)
3288                        {
3289                            // We weren't able to find a full declaration in
3290                            // this DWARF, see if we have a declaration anywhere
3291                            // else...
3292                            type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
3293                        }
3294
3295                        if (type_sp)
3296                        {
3297                            // We found a real definition for this type elsewhere
3298                            // so lets use it and cache the fact that we found
3299                            // a complete type for this die
3300                            m_die_to_type[die] = type_sp.get();
3301                            return type_sp;
3302                        }
3303                    }
3304                    assert (tag_decl_kind != -1);
3305                    bool clang_type_was_created = false;
3306                    clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3307                    if (clang_type == NULL)
3308                    {
3309                        clang_type_was_created = true;
3310                        clang_type = ast.CreateRecordType (type_name_cstr,
3311                                                           tag_decl_kind,
3312                                                           GetClangDeclContextForDIE (dwarf_cu, die),
3313                                                           class_language);
3314                    }
3315
3316                    // Store a forward declaration to this class type in case any
3317                    // parameters in any class methods need it for the clang
3318                    // types for function prototypes.
3319                    LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
3320                    type_sp.reset (new Type (die->GetOffset(),
3321                                             this,
3322                                             type_name_const_str,
3323                                             byte_size,
3324                                             NULL,
3325                                             LLDB_INVALID_UID,
3326                                             Type::eEncodingIsUID,
3327                                             &decl,
3328                                             clang_type,
3329                                             Type::eResolveStateForward));
3330
3331
3332                    // Add our type to the unique type map so we don't
3333                    // end up creating many copies of the same type over
3334                    // and over in the ASTContext for our module
3335                    unique_ast_entry.m_type_sp = type_sp;
3336                    unique_ast_entry.m_symfile = this;
3337                    unique_ast_entry.m_cu = dwarf_cu;
3338                    unique_ast_entry.m_die = die;
3339                    unique_ast_entry.m_declaration = decl;
3340                    GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
3341                                                       unique_ast_entry);
3342
3343                    if (die->HasChildren() == false && is_forward_declaration == false)
3344                    {
3345                        // No children for this struct/union/class, lets finish it
3346                        ast.StartTagDeclarationDefinition (clang_type);
3347                        ast.CompleteTagDeclarationDefinition (clang_type);
3348                    }
3349                    else if (clang_type_was_created)
3350                    {
3351                        // Leave this as a forward declaration until we need
3352                        // to know the details of the type. lldb_private::Type
3353                        // will automatically call the SymbolFile virtual function
3354                        // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3355                        // When the definition needs to be defined.
3356                        m_forward_decl_die_to_clang_type[die] = clang_type;
3357                        m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3358                        ClangASTContext::SetHasExternalStorage (clang_type, true);
3359                    }
3360                }
3361                break;
3362
3363            case DW_TAG_enumeration_type:
3364                {
3365                    // Set a bit that lets us know that we are currently parsing this
3366                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
3367
3368                    lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
3369
3370                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3371                    if (num_attributes > 0)
3372                    {
3373                        uint32_t i;
3374
3375                        for (i=0; i<num_attributes; ++i)
3376                        {
3377                            attr = attributes.AttributeAtIndex(i);
3378                            DWARFFormValue form_value;
3379                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3380                            {
3381                                switch (attr)
3382                                {
3383                                case DW_AT_decl_file:       decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3384                                case DW_AT_decl_line:       decl.SetLine(form_value.Unsigned()); break;
3385                                case DW_AT_decl_column:     decl.SetColumn(form_value.Unsigned()); break;
3386                                case DW_AT_name:
3387                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3388                                    type_name_const_str.SetCString(type_name_cstr);
3389                                    break;
3390                                case DW_AT_type:            encoding_uid = form_value.Reference(dwarf_cu); break;
3391                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); byte_size_valid = true; break;
3392                                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3393                                case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
3394                                case DW_AT_allocated:
3395                                case DW_AT_associated:
3396                                case DW_AT_bit_stride:
3397                                case DW_AT_byte_stride:
3398                                case DW_AT_data_location:
3399                                case DW_AT_description:
3400                                case DW_AT_start_scope:
3401                                case DW_AT_visibility:
3402                                case DW_AT_specification:
3403                                case DW_AT_abstract_origin:
3404                                case DW_AT_sibling:
3405                                    break;
3406                                }
3407                            }
3408                        }
3409
3410                        DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3411
3412                        clang_type_t enumerator_clang_type = NULL;
3413                        clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3414                        if (clang_type == NULL)
3415                        {
3416                            enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3417                                                                                                  DW_ATE_signed,
3418                                                                                                  byte_size * 8);
3419                            clang_type = ast.CreateEnumerationType (type_name_cstr,
3420                                                                    GetClangDeclContextForDIE (dwarf_cu, die),
3421                                                                    decl,
3422                                                                    enumerator_clang_type);
3423                        }
3424                        else
3425                        {
3426                            enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3427                            assert (enumerator_clang_type != NULL);
3428                        }
3429
3430                        LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
3431
3432                        type_sp.reset( new Type (die->GetOffset(),
3433                                                 this,
3434                                                 type_name_const_str,
3435                                                 byte_size,
3436                                                 NULL,
3437                                                 encoding_uid,
3438                                                 Type::eEncodingIsUID,
3439                                                 &decl,
3440                                                 clang_type,
3441                                                 Type::eResolveStateForward));
3442
3443#if LEAVE_ENUMS_FORWARD_DECLARED
3444                        // Leave this as a forward declaration until we need
3445                        // to know the details of the type. lldb_private::Type
3446                        // will automatically call the SymbolFile virtual function
3447                        // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3448                        // When the definition needs to be defined.
3449                        m_forward_decl_die_to_clang_type[die] = clang_type;
3450                        m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3451                        ClangASTContext::SetHasExternalStorage (clang_type, true);
3452#else
3453                        ast.StartTagDeclarationDefinition (clang_type);
3454                        if (die->HasChildren())
3455                        {
3456                            SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
3457                            ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
3458                        }
3459                        ast.CompleteTagDeclarationDefinition (clang_type);
3460#endif
3461                    }
3462                }
3463                break;
3464
3465            case DW_TAG_inlined_subroutine:
3466            case DW_TAG_subprogram:
3467            case DW_TAG_subroutine_type:
3468                {
3469                    // Set a bit that lets us know that we are currently parsing this
3470                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
3471
3472                    const char *mangled = NULL;
3473                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3474                    bool is_variadic = false;
3475                    bool is_inline = false;
3476                    bool is_static = false;
3477                    bool is_virtual = false;
3478                    bool is_explicit = false;
3479
3480                    unsigned type_quals = 0;
3481                    clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
3482
3483
3484                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3485                    if (num_attributes > 0)
3486                    {
3487                        uint32_t i;
3488                        for (i=0; i<num_attributes; ++i)
3489                        {
3490                            attr = attributes.AttributeAtIndex(i);
3491                            DWARFFormValue form_value;
3492                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3493                            {
3494                                switch (attr)
3495                                {
3496                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3497                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3498                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3499                                case DW_AT_name:
3500                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3501                                    type_name_const_str.SetCString(type_name_cstr);
3502                                    break;
3503
3504                                case DW_AT_MIPS_linkage_name:   mangled = form_value.AsCString(&get_debug_str_data()); break;
3505                                case DW_AT_type:                type_die_offset = form_value.Reference(dwarf_cu); break;
3506                                case DW_AT_accessibility:       accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3507                                case DW_AT_declaration:         is_forward_declaration = form_value.Unsigned() != 0; break;
3508                                case DW_AT_inline:              is_inline = form_value.Unsigned() != 0; break;
3509                                case DW_AT_virtuality:          is_virtual = form_value.Unsigned() != 0;  break;
3510                                case DW_AT_explicit:            is_explicit = form_value.Unsigned() != 0;  break;
3511
3512                                case DW_AT_external:
3513                                    if (form_value.Unsigned())
3514                                    {
3515                                        if (storage == clang::SC_None)
3516                                            storage = clang::SC_Extern;
3517                                        else
3518                                            storage = clang::SC_PrivateExtern;
3519                                    }
3520                                    break;
3521
3522                                case DW_AT_allocated:
3523                                case DW_AT_associated:
3524                                case DW_AT_address_class:
3525                                case DW_AT_artificial:
3526                                case DW_AT_calling_convention:
3527                                case DW_AT_data_location:
3528                                case DW_AT_elemental:
3529                                case DW_AT_entry_pc:
3530                                case DW_AT_frame_base:
3531                                case DW_AT_high_pc:
3532                                case DW_AT_low_pc:
3533                                case DW_AT_object_pointer:
3534                                case DW_AT_prototyped:
3535                                case DW_AT_pure:
3536                                case DW_AT_ranges:
3537                                case DW_AT_recursive:
3538                                case DW_AT_return_addr:
3539                                case DW_AT_segment:
3540                                case DW_AT_specification:
3541                                case DW_AT_start_scope:
3542                                case DW_AT_static_link:
3543                                case DW_AT_trampoline:
3544                                case DW_AT_visibility:
3545                                case DW_AT_vtable_elem_location:
3546                                case DW_AT_abstract_origin:
3547                                case DW_AT_description:
3548                                case DW_AT_sibling:
3549                                    break;
3550                                }
3551                            }
3552                        }
3553                    }
3554
3555                    DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3556
3557                    clang_type_t return_clang_type = NULL;
3558                    Type *func_type = NULL;
3559
3560                    if (type_die_offset != DW_INVALID_OFFSET)
3561                        func_type = ResolveTypeUID(type_die_offset);
3562
3563                    if (func_type)
3564                        return_clang_type = func_type->GetClangLayoutType();
3565                    else
3566                        return_clang_type = ast.GetBuiltInType_void();
3567
3568
3569                    std::vector<clang_type_t> function_param_types;
3570                    std::vector<clang::ParmVarDecl*> function_param_decls;
3571
3572                    // Parse the function children for the parameters
3573
3574                    const DWARFDebugInfoEntry *class_die = die->GetParent();
3575                    if (class_die && (class_die->Tag() == DW_TAG_structure_type ||
3576                                      class_die->Tag() == DW_TAG_class_type))
3577                        is_static = true;
3578
3579                    if (die->HasChildren())
3580                    {
3581                        bool skip_artificial = true;
3582                        ParseChildParameters (sc,
3583                                              type_sp,
3584                                              dwarf_cu,
3585                                              die,
3586                                              skip_artificial,
3587                                              is_static,
3588                                              type_list,
3589                                              function_param_types,
3590                                              function_param_decls,
3591                                              type_quals);
3592                    }
3593
3594                    // clang_type will get the function prototype clang type after this call
3595                    clang_type = ast.CreateFunctionType (return_clang_type,
3596                                                         &function_param_types[0],
3597                                                         function_param_types.size(),
3598                                                         is_variadic,
3599                                                         type_quals);
3600
3601                    if (type_name_cstr)
3602                    {
3603                        bool type_handled = false;
3604                        const DWARFDebugInfoEntry *parent_die = die->GetParent();
3605                        if (tag == DW_TAG_subprogram)
3606                        {
3607                            if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
3608                            {
3609                                // We need to find the DW_TAG_class_type or
3610                                // DW_TAG_struct_type by name so we can add this
3611                                // as a member function of the class.
3612                                const char *class_name_start = type_name_cstr + 2;
3613                                const char *class_name_end = ::strchr (class_name_start, ' ');
3614                                SymbolContext empty_sc;
3615                                clang_type_t class_opaque_type = NULL;
3616                                if (class_name_start < class_name_end)
3617                                {
3618                                    ConstString class_name (class_name_start, class_name_end - class_name_start);
3619                                    TypeList types;
3620                                    const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3621                                    if (match_count > 0)
3622                                    {
3623                                        for (uint32_t i=0; i<match_count; ++i)
3624                                        {
3625                                            Type *type = types.GetTypeAtIndex (i).get();
3626                                            clang_type_t type_clang_forward_type = type->GetClangForwardType();
3627                                            if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
3628                                            {
3629                                                class_opaque_type = type_clang_forward_type;
3630                                                break;
3631                                            }
3632                                        }
3633                                    }
3634                                }
3635
3636                                if (class_opaque_type)
3637                                {
3638                                    // If accessibility isn't set to anything valid, assume public for
3639                                    // now...
3640                                    if (accessibility == eAccessNone)
3641                                        accessibility = eAccessPublic;
3642
3643                                    clang::ObjCMethodDecl *objc_method_decl;
3644                                    objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3645                                                                                      type_name_cstr,
3646                                                                                      clang_type,
3647                                                                                      accessibility);
3648                                    type_handled = objc_method_decl != NULL;
3649                                }
3650                            }
3651                            else if (parent_die->Tag() == DW_TAG_class_type ||
3652                                     parent_die->Tag() == DW_TAG_structure_type)
3653                            {
3654                                // Look at the parent of this DIE and see if is is
3655                                // a class or struct and see if this is actually a
3656                                // C++ method
3657                                Type *class_type = ResolveType (dwarf_cu, parent_die);
3658                                if (class_type)
3659                                {
3660                                    clang_type_t class_opaque_type = class_type->GetClangForwardType();
3661                                    if (ClangASTContext::IsCXXClassType (class_opaque_type))
3662                                    {
3663                                        // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3664                                        // in the DWARF for C++ methods... Default to public for now...
3665                                        if (accessibility == eAccessNone)
3666                                            accessibility = eAccessPublic;
3667
3668                                        if (!is_static && !die->HasChildren())
3669                                        {
3670                                            // We have a C++ member function with no children (this pointer!)
3671                                            // and clang will get mad if we try and make a function that isn't
3672                                            // well formed in the DWARF, so we will just skip it...
3673                                            type_handled = true;
3674                                        }
3675                                        else
3676                                        {
3677                                            clang::CXXMethodDecl *cxx_method_decl;
3678                                            cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3679                                                                                            type_name_cstr,
3680                                                                                            clang_type,
3681                                                                                            accessibility,
3682                                                                                            is_virtual,
3683                                                                                            is_static,
3684                                                                                            is_inline,
3685                                                                                            is_explicit);
3686                                            type_handled = cxx_method_decl != NULL;
3687                                        }
3688                                    }
3689                                }
3690                            }
3691                        }
3692
3693                        if (!type_handled)
3694                        {
3695                            // We just have a function that isn't part of a class
3696                            clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3697                                                                                                clang_type,
3698                                                                                                storage,
3699                                                                                                is_inline);
3700
3701                            // Add the decl to our DIE to decl context map
3702                            assert (function_decl);
3703                            LinkDeclContextToDIE(function_decl, die);
3704                            if (!function_param_decls.empty())
3705                                ast.SetFunctionParameters (function_decl,
3706                                                           &function_param_decls.front(),
3707                                                           function_param_decls.size());
3708                        }
3709                    }
3710                    type_sp.reset( new Type (die->GetOffset(),
3711                                             this,
3712                                             type_name_const_str,
3713                                             0,
3714                                             NULL,
3715                                             LLDB_INVALID_UID,
3716                                             Type::eEncodingIsUID,
3717                                             &decl,
3718                                             clang_type,
3719                                             Type::eResolveStateFull));
3720                    assert(type_sp.get());
3721                }
3722                break;
3723
3724            case DW_TAG_array_type:
3725                {
3726                    // Set a bit that lets us know that we are currently parsing this
3727                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
3728
3729                    lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3730                    int64_t first_index = 0;
3731                    uint32_t byte_stride = 0;
3732                    uint32_t bit_stride = 0;
3733                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3734
3735                    if (num_attributes > 0)
3736                    {
3737                        uint32_t i;
3738                        for (i=0; i<num_attributes; ++i)
3739                        {
3740                            attr = attributes.AttributeAtIndex(i);
3741                            DWARFFormValue form_value;
3742                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3743                            {
3744                                switch (attr)
3745                                {
3746                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3747                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3748                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3749                                case DW_AT_name:
3750                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3751                                    type_name_const_str.SetCString(type_name_cstr);
3752                                    break;
3753
3754                                case DW_AT_type:            type_die_offset = form_value.Reference(dwarf_cu); break;
3755                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); byte_size_valid = true; break;
3756                                case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break;
3757                                case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break;
3758                                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3759                                case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
3760                                case DW_AT_allocated:
3761                                case DW_AT_associated:
3762                                case DW_AT_data_location:
3763                                case DW_AT_description:
3764                                case DW_AT_ordering:
3765                                case DW_AT_start_scope:
3766                                case DW_AT_visibility:
3767                                case DW_AT_specification:
3768                                case DW_AT_abstract_origin:
3769                                case DW_AT_sibling:
3770                                    break;
3771                                }
3772                            }
3773                        }
3774
3775                        DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3776
3777                        Type *element_type = ResolveTypeUID(type_die_offset);
3778
3779                        if (element_type)
3780                        {
3781                            std::vector<uint64_t> element_orders;
3782                            ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
3783                            // We have an array that claims to have no members, lets give it at least one member...
3784                            if (element_orders.empty())
3785                                element_orders.push_back (1);
3786                            if (byte_stride == 0 && bit_stride == 0)
3787                                byte_stride = element_type->GetByteSize();
3788                            clang_type_t array_element_type = element_type->GetClangFullType();
3789                            uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3790                            uint64_t num_elements = 0;
3791                            std::vector<uint64_t>::const_reverse_iterator pos;
3792                            std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3793                            for (pos = element_orders.rbegin(); pos != end; ++pos)
3794                            {
3795                                num_elements = *pos;
3796                                clang_type = ast.CreateArrayType (array_element_type,
3797                                                                  num_elements,
3798                                                                  num_elements * array_element_bit_stride);
3799                                array_element_type = clang_type;
3800                                array_element_bit_stride = array_element_bit_stride * num_elements;
3801                            }
3802                            ConstString empty_name;
3803                            type_sp.reset( new Type (die->GetOffset(),
3804                                                     this,
3805                                                     empty_name,
3806                                                     array_element_bit_stride / 8,
3807                                                     NULL,
3808                                                     type_die_offset,
3809                                                     Type::eEncodingIsUID,
3810                                                     &decl,
3811                                                     clang_type,
3812                                                     Type::eResolveStateFull));
3813                            type_sp->SetEncodingType (element_type);
3814                        }
3815                    }
3816                }
3817                break;
3818
3819            case DW_TAG_ptr_to_member_type:
3820                {
3821                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3822                    dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3823
3824                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3825
3826                    if (num_attributes > 0) {
3827                        uint32_t i;
3828                        for (i=0; i<num_attributes; ++i)
3829                        {
3830                            attr = attributes.AttributeAtIndex(i);
3831                            DWARFFormValue form_value;
3832                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3833                            {
3834                                switch (attr)
3835                                {
3836                                    case DW_AT_type:
3837                                        type_die_offset = form_value.Reference(dwarf_cu); break;
3838                                    case DW_AT_containing_type:
3839                                        containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3840                                }
3841                            }
3842                        }
3843
3844                        Type *pointee_type = ResolveTypeUID(type_die_offset);
3845                        Type *class_type = ResolveTypeUID(containing_type_die_offset);
3846
3847                        clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
3848                        clang_type_t class_clang_type = class_type->GetClangLayoutType();
3849
3850                        clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3851                                                                 class_clang_type);
3852
3853                        byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3854                                                                       clang_type) / 8;
3855
3856                        type_sp.reset( new Type (die->GetOffset(),
3857                                                 this,
3858                                                 type_name_const_str,
3859                                                 byte_size,
3860                                                 NULL,
3861                                                 LLDB_INVALID_UID,
3862                                                 Type::eEncodingIsUID,
3863                                                 NULL,
3864                                                 clang_type,
3865                                                 Type::eResolveStateForward));
3866                    }
3867
3868                    break;
3869                }
3870            default:
3871                assert(false && "Unhandled type tag!");
3872                break;
3873            }
3874
3875            if (type_sp.get())
3876            {
3877                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3878                dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3879
3880                SymbolContextScope * symbol_context_scope = NULL;
3881                if (sc_parent_tag == DW_TAG_compile_unit)
3882                {
3883                    symbol_context_scope = sc.comp_unit;
3884                }
3885                else if (sc.function != NULL)
3886                {
3887                    symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3888                    if (symbol_context_scope == NULL)
3889                        symbol_context_scope = sc.function;
3890                }
3891
3892                if (symbol_context_scope != NULL)
3893                {
3894                    type_sp->SetSymbolContextScope(symbol_context_scope);
3895                }
3896
3897                // We are ready to put this type into the uniqued list up at the module level
3898                type_list->Insert (type_sp);
3899
3900                m_die_to_type[die] = type_sp.get();
3901            }
3902        }
3903        else if (type_ptr != DIE_IS_BEING_PARSED)
3904        {
3905            type_sp = type_list->FindType(type_ptr->GetID());
3906        }
3907    }
3908    return type_sp;
3909}
3910
3911size_t
3912SymbolFileDWARF::ParseTypes
3913(
3914    const SymbolContext& sc,
3915    DWARFCompileUnit* dwarf_cu,
3916    const DWARFDebugInfoEntry *die,
3917    bool parse_siblings,
3918    bool parse_children
3919)
3920{
3921    size_t types_added = 0;
3922    while (die != NULL)
3923    {
3924        bool type_is_new = false;
3925        if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
3926        {
3927            if (type_is_new)
3928                ++types_added;
3929        }
3930
3931        if (parse_children && die->HasChildren())
3932        {
3933            if (die->Tag() == DW_TAG_subprogram)
3934            {
3935                SymbolContext child_sc(sc);
3936                child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3937                types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3938            }
3939            else
3940                types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3941        }
3942
3943        if (parse_siblings)
3944            die = die->GetSibling();
3945        else
3946            die = NULL;
3947    }
3948    return types_added;
3949}
3950
3951
3952size_t
3953SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3954{
3955    assert(sc.comp_unit && sc.function);
3956    size_t functions_added = 0;
3957    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3958    if (dwarf_cu)
3959    {
3960        dw_offset_t function_die_offset = sc.function->GetID();
3961        const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3962        if (function_die)
3963        {
3964            ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
3965        }
3966    }
3967
3968    return functions_added;
3969}
3970
3971
3972size_t
3973SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3974{
3975    // At least a compile unit must be valid
3976    assert(sc.comp_unit);
3977    size_t types_added = 0;
3978    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3979    if (dwarf_cu)
3980    {
3981        if (sc.function)
3982        {
3983            dw_offset_t function_die_offset = sc.function->GetID();
3984            const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3985            if (func_die && func_die->HasChildren())
3986            {
3987                types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3988            }
3989        }
3990        else
3991        {
3992            const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3993            if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3994            {
3995                types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3996            }
3997        }
3998    }
3999
4000    return types_added;
4001}
4002
4003size_t
4004SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
4005{
4006    if (sc.comp_unit != NULL)
4007    {
4008        DWARFDebugInfo* info = DebugInfo();
4009        if (info == NULL)
4010            return 0;
4011
4012        uint32_t cu_idx = UINT32_MAX;
4013        DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
4014
4015        if (dwarf_cu == NULL)
4016            return 0;
4017
4018        if (sc.function)
4019        {
4020            const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
4021
4022            dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
4023            assert (func_lo_pc != DW_INVALID_ADDRESS);
4024
4025            const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
4026
4027            // Let all blocks know they have parse all their variables
4028            sc.function->GetBlock (false).SetDidParseVariables (true, true);
4029
4030            return num_variables;
4031        }
4032        else if (sc.comp_unit)
4033        {
4034            uint32_t vars_added = 0;
4035            VariableListSP variables (sc.comp_unit->GetVariableList(false));
4036
4037            if (variables.get() == NULL)
4038            {
4039                variables.reset(new VariableList());
4040                sc.comp_unit->SetVariableList(variables);
4041
4042                // Index if we already haven't to make sure the compile units
4043                // get indexed and make their global DIE index list
4044                if (!m_indexed)
4045                    Index ();
4046
4047                std::vector<NameToDIE::Info> global_die_info_array;
4048                const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
4049                for (size_t idx=0; idx<num_globals; ++idx)
4050                {
4051                    VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS));
4052                    if (var_sp)
4053                    {
4054                        variables->AddVariableIfUnique (var_sp);
4055                        ++vars_added;
4056                    }
4057                }
4058            }
4059            return vars_added;
4060        }
4061    }
4062    return 0;
4063}
4064
4065
4066VariableSP
4067SymbolFileDWARF::ParseVariableDIE
4068(
4069    const SymbolContext& sc,
4070    DWARFCompileUnit* dwarf_cu,
4071    const DWARFDebugInfoEntry *die,
4072    const lldb::addr_t func_low_pc
4073)
4074{
4075
4076    VariableSP var_sp (m_die_to_variable_sp[die]);
4077    if (var_sp)
4078        return var_sp;  // Already been parsed!
4079
4080    const dw_tag_t tag = die->Tag();
4081    DWARFDebugInfoEntry::Attributes attributes;
4082    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
4083    if (num_attributes > 0)
4084    {
4085        const char *name = NULL;
4086        const char *mangled = NULL;
4087        Declaration decl;
4088        uint32_t i;
4089        Type *var_type = NULL;
4090        DWARFExpression location;
4091        bool is_external = false;
4092        bool is_artificial = false;
4093        bool location_is_const_value_data = false;
4094        AccessType accessibility = eAccessNone;
4095
4096        for (i=0; i<num_attributes; ++i)
4097        {
4098            dw_attr_t attr = attributes.AttributeAtIndex(i);
4099            DWARFFormValue form_value;
4100            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4101            {
4102                switch (attr)
4103                {
4104                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4105                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
4106                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4107                case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
4108                case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
4109                case DW_AT_type:        var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
4110                case DW_AT_external:    is_external = form_value.Unsigned() != 0; break;
4111                case DW_AT_const_value:
4112                    location_is_const_value_data = true;
4113                    // Fall through...
4114                case DW_AT_location:
4115                    {
4116                        if (form_value.BlockData())
4117                        {
4118                            const DataExtractor& debug_info_data = get_debug_info_data();
4119
4120                            uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
4121                            uint32_t block_length = form_value.Unsigned();
4122                            location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
4123                        }
4124                        else
4125                        {
4126                            const DataExtractor&    debug_loc_data = get_debug_loc_data();
4127                            const dw_offset_t debug_loc_offset = form_value.Unsigned();
4128
4129                            size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
4130                            if (loc_list_length > 0)
4131                            {
4132                                location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
4133                                assert (func_low_pc != LLDB_INVALID_ADDRESS);
4134                                location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
4135                            }
4136                        }
4137                    }
4138                    break;
4139
4140                case DW_AT_artificial:      is_artificial = form_value.Unsigned() != 0; break;
4141                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
4142                case DW_AT_declaration:
4143                case DW_AT_description:
4144                case DW_AT_endianity:
4145                case DW_AT_segment:
4146                case DW_AT_start_scope:
4147                case DW_AT_visibility:
4148                default:
4149                case DW_AT_abstract_origin:
4150                case DW_AT_sibling:
4151                case DW_AT_specification:
4152                    break;
4153                }
4154            }
4155        }
4156
4157        if (location.IsValid())
4158        {
4159            assert(var_type != DIE_IS_BEING_PARSED);
4160
4161            ValueType scope = eValueTypeInvalid;
4162
4163            const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
4164            dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4165
4166            if (tag == DW_TAG_formal_parameter)
4167                scope = eValueTypeVariableArgument;
4168            else if (is_external || parent_tag == DW_TAG_compile_unit)
4169                scope = eValueTypeVariableGlobal;
4170            else
4171                scope = eValueTypeVariableLocal;
4172
4173            SymbolContextScope * symbol_context_scope = NULL;
4174            if (parent_tag == DW_TAG_compile_unit)
4175            {
4176                symbol_context_scope = sc.comp_unit;
4177            }
4178            else if (sc.function != NULL)
4179            {
4180                symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4181                if (symbol_context_scope == NULL)
4182                    symbol_context_scope = sc.function;
4183            }
4184
4185            assert(symbol_context_scope != NULL);
4186            var_sp.reset (new Variable(die->GetOffset(),
4187                                       name,
4188                                       mangled,
4189                                       var_type,
4190                                       scope,
4191                                       symbol_context_scope,
4192                                       &decl,
4193                                       location,
4194                                       is_external,
4195                                       is_artificial));
4196
4197            var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
4198        }
4199    }
4200    // Cache var_sp even if NULL (the variable was just a specification or
4201    // was missing vital information to be able to be displayed in the debugger
4202    // (missing location due to optimization, etc)) so we don't re-parse
4203    // this DIE over and over later...
4204    m_die_to_variable_sp[die] = var_sp;
4205    return var_sp;
4206}
4207
4208
4209const DWARFDebugInfoEntry *
4210SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
4211                                                   dw_offset_t spec_block_die_offset,
4212                                                   DWARFCompileUnit **result_die_cu_handle)
4213{
4214    // Give the concrete function die specified by "func_die_offset", find the
4215    // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4216    // to "spec_block_die_offset"
4217    DWARFDebugInfo* info = DebugInfo();
4218
4219    const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
4220    if (die)
4221    {
4222        assert (*result_die_cu_handle);
4223        return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
4224    }
4225    return NULL;
4226}
4227
4228
4229const DWARFDebugInfoEntry *
4230SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
4231                                                  const DWARFDebugInfoEntry *die,
4232                                                  dw_offset_t spec_block_die_offset,
4233                                                  DWARFCompileUnit **result_die_cu_handle)
4234{
4235    if (die)
4236    {
4237        switch (die->Tag())
4238        {
4239        case DW_TAG_subprogram:
4240        case DW_TAG_inlined_subroutine:
4241        case DW_TAG_lexical_block:
4242            {
4243                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
4244                {
4245                    *result_die_cu_handle = dwarf_cu;
4246                    return die;
4247                }
4248
4249                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
4250                {
4251                    *result_die_cu_handle = dwarf_cu;
4252                    return die;
4253                }
4254            }
4255            break;
4256        }
4257
4258        // Give the concrete function die specified by "func_die_offset", find the
4259        // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
4260        // to "spec_block_die_offset"
4261        for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
4262        {
4263            const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
4264                                                                                      child_die,
4265                                                                                      spec_block_die_offset,
4266                                                                                      result_die_cu_handle);
4267            if (result_die)
4268                return result_die;
4269        }
4270    }
4271
4272    *result_die_cu_handle = NULL;
4273    return NULL;
4274}
4275
4276size_t
4277SymbolFileDWARF::ParseVariables
4278(
4279    const SymbolContext& sc,
4280    DWARFCompileUnit* dwarf_cu,
4281    const lldb::addr_t func_low_pc,
4282    const DWARFDebugInfoEntry *orig_die,
4283    bool parse_siblings,
4284    bool parse_children,
4285    VariableList* cc_variable_list
4286)
4287{
4288    if (orig_die == NULL)
4289        return 0;
4290
4291    VariableListSP variable_list_sp;
4292
4293    size_t vars_added = 0;
4294    const DWARFDebugInfoEntry *die = orig_die;
4295    while (die != NULL)
4296    {
4297        dw_tag_t tag = die->Tag();
4298
4299        // Check to see if we have already parsed this variable or constant?
4300        if (m_die_to_variable_sp[die])
4301        {
4302            if (cc_variable_list)
4303                cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
4304        }
4305        else
4306        {
4307            // We haven't already parsed it, lets do that now.
4308            if ((tag == DW_TAG_variable) ||
4309                (tag == DW_TAG_constant) ||
4310                (tag == DW_TAG_formal_parameter && sc.function))
4311            {
4312                if (variable_list_sp.get() == NULL)
4313                {
4314                    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
4315                    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
4316                    switch (parent_tag)
4317                    {
4318                        case DW_TAG_compile_unit:
4319                            if (sc.comp_unit != NULL)
4320                            {
4321                                variable_list_sp = sc.comp_unit->GetVariableList(false);
4322                                if (variable_list_sp.get() == NULL)
4323                                {
4324                                    variable_list_sp.reset(new VariableList());
4325                                    sc.comp_unit->SetVariableList(variable_list_sp);
4326                                }
4327                            }
4328                            else
4329                            {
4330                                fprintf (stderr,
4331                                         "error: parent 0x%8.8x %s with no valid compile unit in symbol context for 0x%8.8x %s.\n",
4332                                         sc_parent_die->GetOffset(),
4333                                         DW_TAG_value_to_name (parent_tag),
4334                                         orig_die->GetOffset(),
4335                                         DW_TAG_value_to_name (orig_die->Tag()));
4336                            }
4337                            break;
4338
4339                        case DW_TAG_subprogram:
4340                        case DW_TAG_inlined_subroutine:
4341                        case DW_TAG_lexical_block:
4342                            if (sc.function != NULL)
4343                            {
4344                                // Check to see if we already have parsed the variables for the given scope
4345
4346                                Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
4347                                if (block == NULL)
4348                                {
4349                                    // This must be a specification or abstract origin with
4350                                    // a concrete block couterpart in the current function. We need
4351                                    // to find the concrete block so we can correctly add the
4352                                    // variable to it
4353                                    DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
4354                                    const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
4355                                                                                                                      sc_parent_die->GetOffset(),
4356                                                                                                                      &concrete_block_die_cu);
4357                                    if (concrete_block_die)
4358                                        block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die->GetOffset());
4359                                }
4360
4361                                if (block != NULL)
4362                                {
4363                                    const bool can_create = false;
4364                                    variable_list_sp = block->GetBlockVariableList (can_create);
4365                                    if (variable_list_sp.get() == NULL)
4366                                    {
4367                                        variable_list_sp.reset(new VariableList());
4368                                        block->SetVariableList(variable_list_sp);
4369                                    }
4370                                }
4371                            }
4372                            break;
4373
4374                        default:
4375                            fprintf (stderr,
4376                                     "error: didn't find appropriate parent DIE for variable list for 0x%8.8x %s.\n",
4377                                     orig_die->GetOffset(),
4378                                     DW_TAG_value_to_name (orig_die->Tag()));
4379                            break;
4380                    }
4381                }
4382
4383                if (variable_list_sp)
4384                {
4385                    VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
4386                    if (var_sp)
4387                    {
4388                        variable_list_sp->AddVariableIfUnique (var_sp);
4389                        if (cc_variable_list)
4390                            cc_variable_list->AddVariableIfUnique (var_sp);
4391                        ++vars_added;
4392                    }
4393                }
4394            }
4395        }
4396
4397        bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
4398
4399        if (!skip_children && parse_children && die->HasChildren())
4400        {
4401            vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
4402        }
4403
4404        if (parse_siblings)
4405            die = die->GetSibling();
4406        else
4407            die = NULL;
4408    }
4409    return vars_added;
4410}
4411
4412//------------------------------------------------------------------
4413// PluginInterface protocol
4414//------------------------------------------------------------------
4415const char *
4416SymbolFileDWARF::GetPluginName()
4417{
4418    return "SymbolFileDWARF";
4419}
4420
4421const char *
4422SymbolFileDWARF::GetShortPluginName()
4423{
4424    return GetPluginNameStatic();
4425}
4426
4427uint32_t
4428SymbolFileDWARF::GetPluginVersion()
4429{
4430    return 1;
4431}
4432
4433void
4434SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
4435{
4436    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4437    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4438    if (clang_type)
4439        symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4440}
4441
4442void
4443SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
4444{
4445    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4446    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
4447    if (clang_type)
4448        symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
4449}
4450
4451void
4452SymbolFileDWARF::DumpIndexes ()
4453{
4454    StreamFile s(stdout, false);
4455
4456    s.Printf ("DWARF index for (%s) '%s/%s':",
4457              GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
4458              GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
4459              GetObjectFile()->GetFileSpec().GetFilename().AsCString());
4460    s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
4461    s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
4462    s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
4463    s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
4464    s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
4465    s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
4466    s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
4467    s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
4468}
4469
4470void
4471SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
4472                                    const char *name,
4473                                    llvm::SmallVectorImpl <clang::NamedDecl *> *results)
4474{
4475    DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
4476
4477    if (iter == m_decl_ctx_to_die.end())
4478        return;
4479
4480    const DWARFDebugInfoEntry *context_die = iter->second;
4481
4482    if (!results)
4483        return;
4484
4485    DWARFDebugInfo* info = DebugInfo();
4486
4487    std::vector<NameToDIE::Info> die_info_array;
4488
4489    size_t num_matches = m_type_index.Find (ConstString(name), die_info_array);
4490
4491    if (num_matches)
4492    {
4493        for (int i = 0;
4494             i < num_matches;
4495             ++i)
4496        {
4497            DWARFCompileUnit* compile_unit = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
4498            compile_unit->ExtractDIEsIfNeeded (false);
4499            const DWARFDebugInfoEntry *die = compile_unit->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
4500
4501            if (die->GetParent() != context_die)
4502                continue;
4503
4504            Type *matching_type = ResolveType (compile_unit, die);
4505
4506            lldb::clang_type_t type = matching_type->GetClangFullType();
4507            clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
4508
4509            if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
4510            {
4511                clang::TagDecl *tag_decl = tag_type->getDecl();
4512                results->push_back(tag_decl);
4513            }
4514            else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
4515            {
4516                clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
4517                results->push_back(typedef_decl);
4518            }
4519        }
4520    }
4521}
4522
4523void
4524SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
4525                                                 const clang::DeclContext *DC,
4526                                                 clang::DeclarationName Name,
4527                                                 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
4528{
4529    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
4530
4531    symbol_file_dwarf->SearchDeclContext (DC, Name.getAsString().c_str(), results);
4532}
4533