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