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