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