SymbolFileDWARF.cpp revision caffddc39bf640bb1fce58b0cc5791d6c42dce28
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/AST/DeclObjC.h"
18#include "clang/AST/DeclTemplate.h"
19#include "clang/Basic/Builtins.h"
20#include "clang/Basic/IdentifierTable.h"
21#include "clang/Basic/LangOptions.h"
22#include "clang/Basic/SourceManager.h"
23#include "clang/Basic/TargetInfo.h"
24#include "clang/Basic/Specifiers.h"
25#include "clang/Sema/DeclSpec.h"
26
27#include "llvm/Support/Casting.h"
28
29#include "lldb/Core/Module.h"
30#include "lldb/Core/PluginManager.h"
31#include "lldb/Core/RegularExpression.h"
32#include "lldb/Core/Scalar.h"
33#include "lldb/Core/Section.h"
34#include "lldb/Core/StreamFile.h"
35#include "lldb/Core/StreamString.h"
36#include "lldb/Core/Timer.h"
37#include "lldb/Core/Value.h"
38
39#include "lldb/Host/Host.h"
40
41#include "lldb/Symbol/Block.h"
42#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
43#include "lldb/Symbol/CompileUnit.h"
44#include "lldb/Symbol/LineTable.h"
45#include "lldb/Symbol/ObjectFile.h"
46#include "lldb/Symbol/SymbolVendor.h"
47#include "lldb/Symbol/VariableList.h"
48
49#include "lldb/Target/ObjCLanguageRuntime.h"
50#include "lldb/Target/CPPLanguageRuntime.h"
51
52#include "DWARFCompileUnit.h"
53#include "DWARFDebugAbbrev.h"
54#include "DWARFDebugAranges.h"
55#include "DWARFDebugInfo.h"
56#include "DWARFDebugInfoEntry.h"
57#include "DWARFDebugLine.h"
58#include "DWARFDebugPubnames.h"
59#include "DWARFDebugRanges.h"
60#include "DWARFDIECollection.h"
61#include "DWARFFormValue.h"
62#include "DWARFLocationList.h"
63#include "LogChannelDWARF.h"
64#include "SymbolFileDWARFDebugMap.h"
65
66#include <map>
67
68//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
69
70#ifdef ENABLE_DEBUG_PRINTF
71#include <stdio.h>
72#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
73#else
74#define DEBUG_PRINTF(fmt, ...)
75#endif
76
77#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
78
79using namespace lldb;
80using namespace lldb_private;
81
82static inline bool
83child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
84{
85    switch (tag)
86    {
87    default:
88        break;
89    case DW_TAG_subprogram:
90    case DW_TAG_inlined_subroutine:
91    case DW_TAG_class_type:
92    case DW_TAG_structure_type:
93    case DW_TAG_union_type:
94        return true;
95    }
96    return false;
97}
98
99static AccessType
100DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
101{
102    switch (dwarf_accessibility)
103    {
104        case DW_ACCESS_public:      return eAccessPublic;
105        case DW_ACCESS_private:     return eAccessPrivate;
106        case DW_ACCESS_protected:   return eAccessProtected;
107        default:                    break;
108    }
109    return eAccessNone;
110}
111
112#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE)
113
114class DIEStack
115{
116public:
117
118    void Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
119    {
120        m_dies.push_back (DIEInfo(cu, die));
121    }
122
123
124    void LogDIEs (Log *log, SymbolFileDWARF *dwarf)
125    {
126        StreamString log_strm;
127        const size_t n = m_dies.size();
128        log_strm.Printf("DIEStack[%zu]:\n", n);
129        for (size_t i=0; i<n; i++)
130        {
131            DWARFCompileUnit *cu = m_dies[i].cu;
132            const DWARFDebugInfoEntry *die = m_dies[i].die;
133            std::string qualified_name;
134            die->GetQualifiedName(dwarf, cu, qualified_name);
135            log_strm.Printf ("[%zu] 0x%8.8x: %s name='%s'\n",
136                             i,
137                             die->GetOffset(),
138                             DW_TAG_value_to_name(die->Tag()),
139                             qualified_name.c_str());
140        }
141        log->PutCString(log_strm.GetData());
142    }
143    void Pop ()
144    {
145        m_dies.pop_back();
146    }
147
148    class ScopedPopper
149    {
150    public:
151        ScopedPopper (DIEStack &die_stack) :
152            m_die_stack (die_stack),
153            m_valid (false)
154        {
155        }
156
157        void
158        Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
159        {
160            m_valid = true;
161            m_die_stack.Push (cu, die);
162        }
163
164        ~ScopedPopper ()
165        {
166            if (m_valid)
167                m_die_stack.Pop();
168        }
169
170
171
172    protected:
173        DIEStack &m_die_stack;
174        bool m_valid;
175    };
176
177protected:
178    struct DIEInfo {
179        DIEInfo (DWARFCompileUnit *c, const DWARFDebugInfoEntry *d) :
180            cu(c),
181            die(d)
182        {
183        }
184        DWARFCompileUnit *cu;
185        const DWARFDebugInfoEntry *die;
186    };
187    typedef std::vector<DIEInfo> Stack;
188    Stack m_dies;
189};
190#endif
191
192void
193SymbolFileDWARF::Initialize()
194{
195    LogChannelDWARF::Initialize();
196    PluginManager::RegisterPlugin (GetPluginNameStatic(),
197                                   GetPluginDescriptionStatic(),
198                                   CreateInstance);
199}
200
201void
202SymbolFileDWARF::Terminate()
203{
204    PluginManager::UnregisterPlugin (CreateInstance);
205    LogChannelDWARF::Initialize();
206}
207
208
209const char *
210SymbolFileDWARF::GetPluginNameStatic()
211{
212    return "dwarf";
213}
214
215const char *
216SymbolFileDWARF::GetPluginDescriptionStatic()
217{
218    return "DWARF and DWARF3 debug symbol file reader.";
219}
220
221
222SymbolFile*
223SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
224{
225    return new SymbolFileDWARF(obj_file);
226}
227
228TypeList *
229SymbolFileDWARF::GetTypeList ()
230{
231    if (m_debug_map_symfile)
232        return m_debug_map_symfile->GetTypeList();
233    return m_obj_file->GetModule()->GetTypeList();
234
235}
236
237//----------------------------------------------------------------------
238// Gets the first parent that is a lexical block, function or inlined
239// subroutine, or compile unit.
240//----------------------------------------------------------------------
241static const DWARFDebugInfoEntry *
242GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
243{
244    const DWARFDebugInfoEntry *die;
245    for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
246    {
247        dw_tag_t tag = die->Tag();
248
249        switch (tag)
250        {
251        case DW_TAG_compile_unit:
252        case DW_TAG_subprogram:
253        case DW_TAG_inlined_subroutine:
254        case DW_TAG_lexical_block:
255            return die;
256        }
257    }
258    return NULL;
259}
260
261
262SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
263    SymbolFile (objfile),
264    UserID (0),  // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
265    m_debug_map_symfile (NULL),
266    m_clang_tu_decl (NULL),
267    m_flags(),
268    m_data_debug_abbrev (),
269    m_data_debug_aranges (),
270    m_data_debug_frame (),
271    m_data_debug_info (),
272    m_data_debug_line (),
273    m_data_debug_loc (),
274    m_data_debug_ranges (),
275    m_data_debug_str (),
276    m_data_apple_names (),
277    m_data_apple_types (),
278    m_data_apple_namespaces (),
279    m_abbr(),
280    m_info(),
281    m_line(),
282    m_apple_names_ap (),
283    m_apple_types_ap (),
284    m_apple_namespaces_ap (),
285    m_apple_objc_ap (),
286    m_function_basename_index(),
287    m_function_fullname_index(),
288    m_function_method_index(),
289    m_function_selector_index(),
290    m_objc_class_selectors_index(),
291    m_global_index(),
292    m_type_index(),
293    m_namespace_index(),
294    m_indexed (false),
295    m_is_external_ast_source (false),
296    m_using_apple_tables (false),
297    m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
298    m_ranges(),
299    m_unique_ast_type_map ()
300{
301}
302
303SymbolFileDWARF::~SymbolFileDWARF()
304{
305    if (m_is_external_ast_source)
306        m_obj_file->GetModule()->GetClangASTContext().RemoveExternalSource ();
307}
308
309static const ConstString &
310GetDWARFMachOSegmentName ()
311{
312    static ConstString g_dwarf_section_name ("__DWARF");
313    return g_dwarf_section_name;
314}
315
316UniqueDWARFASTTypeMap &
317SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
318{
319    if (m_debug_map_symfile)
320        return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
321    return m_unique_ast_type_map;
322}
323
324ClangASTContext &
325SymbolFileDWARF::GetClangASTContext ()
326{
327    if (m_debug_map_symfile)
328        return m_debug_map_symfile->GetClangASTContext ();
329
330    ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
331    if (!m_is_external_ast_source)
332    {
333        m_is_external_ast_source = true;
334        llvm::OwningPtr<clang::ExternalASTSource> ast_source_ap (
335            new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
336                                                 SymbolFileDWARF::CompleteObjCInterfaceDecl,
337                                                 SymbolFileDWARF::FindExternalVisibleDeclsByName,
338                                                 SymbolFileDWARF::LayoutRecordType,
339                                                 this));
340        ast.SetExternalSource (ast_source_ap);
341    }
342    return ast;
343}
344
345void
346SymbolFileDWARF::InitializeObject()
347{
348    // Install our external AST source callbacks so we can complete Clang types.
349    Module *module = m_obj_file->GetModule();
350    if (module)
351    {
352        const SectionList *section_list = m_obj_file->GetSectionList();
353
354        const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
355
356        // Memory map the DWARF mach-o segment so we have everything mmap'ed
357        // to keep our heap memory usage down.
358        if (section)
359            m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
360    }
361    get_apple_names_data();
362    if (m_data_apple_names.GetByteSize() > 0)
363    {
364        m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
365        if (m_apple_names_ap->IsValid())
366            m_using_apple_tables = true;
367        else
368            m_apple_names_ap.reset();
369    }
370    get_apple_types_data();
371    if (m_data_apple_types.GetByteSize() > 0)
372    {
373        m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
374        if (m_apple_types_ap->IsValid())
375            m_using_apple_tables = true;
376        else
377            m_apple_types_ap.reset();
378    }
379
380    get_apple_namespaces_data();
381    if (m_data_apple_namespaces.GetByteSize() > 0)
382    {
383        m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
384        if (m_apple_namespaces_ap->IsValid())
385            m_using_apple_tables = true;
386        else
387            m_apple_namespaces_ap.reset();
388    }
389
390    get_apple_objc_data();
391    if (m_data_apple_objc.GetByteSize() > 0)
392    {
393        m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
394        if (m_apple_objc_ap->IsValid())
395            m_using_apple_tables = true;
396        else
397            m_apple_objc_ap.reset();
398    }
399}
400
401bool
402SymbolFileDWARF::SupportedVersion(uint16_t version)
403{
404    return version == 2 || version == 3;
405}
406
407uint32_t
408SymbolFileDWARF::CalculateAbilities ()
409{
410    uint32_t abilities = 0;
411    if (m_obj_file != NULL)
412    {
413        const Section* section = NULL;
414        const SectionList *section_list = m_obj_file->GetSectionList();
415        if (section_list == NULL)
416            return 0;
417
418        uint64_t debug_abbrev_file_size = 0;
419        uint64_t debug_aranges_file_size = 0;
420        uint64_t debug_frame_file_size = 0;
421        uint64_t debug_info_file_size = 0;
422        uint64_t debug_line_file_size = 0;
423        uint64_t debug_loc_file_size = 0;
424        uint64_t debug_macinfo_file_size = 0;
425        uint64_t debug_pubnames_file_size = 0;
426        uint64_t debug_pubtypes_file_size = 0;
427        uint64_t debug_ranges_file_size = 0;
428        uint64_t debug_str_file_size = 0;
429
430        section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
431
432        if (section)
433            section_list = &section->GetChildren ();
434
435        section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
436        if (section != NULL)
437        {
438            debug_info_file_size = section->GetByteSize();
439
440            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
441            if (section)
442                debug_abbrev_file_size = section->GetByteSize();
443            else
444                m_flags.Set (flagsGotDebugAbbrevData);
445
446            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
447            if (section)
448                debug_aranges_file_size = section->GetByteSize();
449            else
450                m_flags.Set (flagsGotDebugArangesData);
451
452            section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
453            if (section)
454                debug_frame_file_size = section->GetByteSize();
455            else
456                m_flags.Set (flagsGotDebugFrameData);
457
458            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
459            if (section)
460                debug_line_file_size = section->GetByteSize();
461            else
462                m_flags.Set (flagsGotDebugLineData);
463
464            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
465            if (section)
466                debug_loc_file_size = section->GetByteSize();
467            else
468                m_flags.Set (flagsGotDebugLocData);
469
470            section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
471            if (section)
472                debug_macinfo_file_size = section->GetByteSize();
473            else
474                m_flags.Set (flagsGotDebugMacInfoData);
475
476            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
477            if (section)
478                debug_pubnames_file_size = section->GetByteSize();
479            else
480                m_flags.Set (flagsGotDebugPubNamesData);
481
482            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
483            if (section)
484                debug_pubtypes_file_size = section->GetByteSize();
485            else
486                m_flags.Set (flagsGotDebugPubTypesData);
487
488            section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
489            if (section)
490                debug_ranges_file_size = section->GetByteSize();
491            else
492                m_flags.Set (flagsGotDebugRangesData);
493
494            section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
495            if (section)
496                debug_str_file_size = section->GetByteSize();
497            else
498                m_flags.Set (flagsGotDebugStrData);
499        }
500
501        if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
502            abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
503
504        if (debug_line_file_size > 0)
505            abilities |= LineTables;
506
507        if (debug_aranges_file_size > 0)
508            abilities |= AddressAcceleratorTable;
509
510        if (debug_pubnames_file_size > 0)
511            abilities |= FunctionAcceleratorTable;
512
513        if (debug_pubtypes_file_size > 0)
514            abilities |= TypeAcceleratorTable;
515
516        if (debug_macinfo_file_size > 0)
517            abilities |= MacroInformation;
518
519        if (debug_frame_file_size > 0)
520            abilities |= CallFrameInformation;
521    }
522    return abilities;
523}
524
525const DataExtractor&
526SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
527{
528    if (m_flags.IsClear (got_flag))
529    {
530        m_flags.Set (got_flag);
531        const SectionList *section_list = m_obj_file->GetSectionList();
532        if (section_list)
533        {
534            Section *section = section_list->FindSectionByType(sect_type, true).get();
535            if (section)
536            {
537                // See if we memory mapped the DWARF segment?
538                if (m_dwarf_data.GetByteSize())
539                {
540                    data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
541                }
542                else
543                {
544                    if (m_obj_file->ReadSectionData (section, data) == 0)
545                        data.Clear();
546                }
547            }
548        }
549    }
550    return data;
551}
552
553const DataExtractor&
554SymbolFileDWARF::get_debug_abbrev_data()
555{
556    return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
557}
558
559const DataExtractor&
560SymbolFileDWARF::get_debug_aranges_data()
561{
562    return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
563}
564
565const DataExtractor&
566SymbolFileDWARF::get_debug_frame_data()
567{
568    return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
569}
570
571const DataExtractor&
572SymbolFileDWARF::get_debug_info_data()
573{
574    return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
575}
576
577const DataExtractor&
578SymbolFileDWARF::get_debug_line_data()
579{
580    return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
581}
582
583const DataExtractor&
584SymbolFileDWARF::get_debug_loc_data()
585{
586    return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
587}
588
589const DataExtractor&
590SymbolFileDWARF::get_debug_ranges_data()
591{
592    return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
593}
594
595const DataExtractor&
596SymbolFileDWARF::get_debug_str_data()
597{
598    return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
599}
600
601const DataExtractor&
602SymbolFileDWARF::get_apple_names_data()
603{
604    return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
605}
606
607const DataExtractor&
608SymbolFileDWARF::get_apple_types_data()
609{
610    return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
611}
612
613const DataExtractor&
614SymbolFileDWARF::get_apple_namespaces_data()
615{
616    return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
617}
618
619const DataExtractor&
620SymbolFileDWARF::get_apple_objc_data()
621{
622    return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
623}
624
625
626DWARFDebugAbbrev*
627SymbolFileDWARF::DebugAbbrev()
628{
629    if (m_abbr.get() == NULL)
630    {
631        const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
632        if (debug_abbrev_data.GetByteSize() > 0)
633        {
634            m_abbr.reset(new DWARFDebugAbbrev());
635            if (m_abbr.get())
636                m_abbr->Parse(debug_abbrev_data);
637        }
638    }
639    return m_abbr.get();
640}
641
642const DWARFDebugAbbrev*
643SymbolFileDWARF::DebugAbbrev() const
644{
645    return m_abbr.get();
646}
647
648
649DWARFDebugInfo*
650SymbolFileDWARF::DebugInfo()
651{
652    if (m_info.get() == NULL)
653    {
654        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
655        if (get_debug_info_data().GetByteSize() > 0)
656        {
657            m_info.reset(new DWARFDebugInfo());
658            if (m_info.get())
659            {
660                m_info->SetDwarfData(this);
661            }
662        }
663    }
664    return m_info.get();
665}
666
667const DWARFDebugInfo*
668SymbolFileDWARF::DebugInfo() const
669{
670    return m_info.get();
671}
672
673DWARFCompileUnit*
674SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
675{
676    DWARFDebugInfo* info = DebugInfo();
677    if (info && UserIDMatches(cu_uid))
678        return info->GetCompileUnit((dw_offset_t)cu_uid).get();
679    return NULL;
680}
681
682
683DWARFDebugRanges*
684SymbolFileDWARF::DebugRanges()
685{
686    if (m_ranges.get() == NULL)
687    {
688        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
689        if (get_debug_ranges_data().GetByteSize() > 0)
690        {
691            m_ranges.reset(new DWARFDebugRanges());
692            if (m_ranges.get())
693                m_ranges->Extract(this);
694        }
695    }
696    return m_ranges.get();
697}
698
699const DWARFDebugRanges*
700SymbolFileDWARF::DebugRanges() const
701{
702    return m_ranges.get();
703}
704
705bool
706SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
707{
708    if (curr_cu != NULL)
709    {
710        const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
711        if (cu_die)
712        {
713            const char * cu_die_name = cu_die->GetName(this, curr_cu);
714            const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
715            LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
716            if (cu_die_name)
717            {
718                FileSpec cu_file_spec;
719
720                if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0')
721                {
722                    // If we have a full path to the compile unit, we don't need to resolve
723                    // the file.  This can be expensive e.g. when the source files are NFS mounted.
724                    cu_file_spec.SetFile (cu_die_name, false);
725                }
726                else
727                {
728                    std::string fullpath(cu_comp_dir);
729                    if (*fullpath.rbegin() != '/')
730                        fullpath += '/';
731                    fullpath += cu_die_name;
732                    cu_file_spec.SetFile (fullpath.c_str(), false);
733                }
734
735                compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
736                                                       curr_cu,
737                                                       cu_file_spec,
738                                                       MakeUserID(curr_cu->GetOffset()),
739                                                       cu_language));
740                if (compile_unit_sp.get())
741                {
742                    curr_cu->SetUserData(compile_unit_sp.get());
743                    return true;
744                }
745            }
746        }
747    }
748    return false;
749}
750
751uint32_t
752SymbolFileDWARF::GetNumCompileUnits()
753{
754    DWARFDebugInfo* info = DebugInfo();
755    if (info)
756        return info->GetNumCompileUnits();
757    return 0;
758}
759
760CompUnitSP
761SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
762{
763    CompUnitSP comp_unit;
764    DWARFDebugInfo* info = DebugInfo();
765    if (info)
766    {
767        DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
768        if (curr_cu != NULL)
769        {
770            // Our symbol vendor shouldn't be asking us to add a compile unit that
771            // has already been added to it, which this DWARF plug-in knows as it
772            // stores the lldb compile unit (CompileUnit) pointer in each
773            // DWARFCompileUnit object when it gets added.
774            assert(curr_cu->GetUserData() == NULL);
775            ParseCompileUnit(curr_cu, comp_unit);
776        }
777    }
778    return comp_unit;
779}
780
781static void
782AddRangesToBlock (Block& block,
783                  DWARFDebugRanges::RangeList& ranges,
784                  addr_t block_base_addr)
785{
786    const size_t num_ranges = ranges.GetSize();
787    for (size_t i = 0; i<num_ranges; ++i)
788    {
789        const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
790        const addr_t range_base = range.GetRangeBase();
791        assert (range_base >= block_base_addr);
792        block.AddRange(Block::Range (range_base - block_base_addr, range.GetByteSize()));;
793    }
794    block.FinalizeRanges ();
795}
796
797
798Function *
799SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
800{
801    DWARFDebugRanges::RangeList func_ranges;
802    const char *name = NULL;
803    const char *mangled = NULL;
804    int decl_file = 0;
805    int decl_line = 0;
806    int decl_column = 0;
807    int call_file = 0;
808    int call_line = 0;
809    int call_column = 0;
810    DWARFExpression frame_base;
811
812    assert (die->Tag() == DW_TAG_subprogram);
813
814    if (die->Tag() != DW_TAG_subprogram)
815        return NULL;
816
817    if (die->GetDIENamesAndRanges (this,
818                                   dwarf_cu,
819                                   name,
820                                   mangled,
821                                   func_ranges,
822                                   decl_file,
823                                   decl_line,
824                                   decl_column,
825                                   call_file,
826                                   call_line,
827                                   call_column,
828                                   &frame_base))
829    {
830        // Union of all ranges in the function DIE (if the function is discontiguous)
831        AddressRange func_range;
832        lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
833        lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
834        if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
835        {
836            func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
837            if (func_range.GetBaseAddress().IsValid())
838                func_range.SetByteSize(highest_func_addr - lowest_func_addr);
839        }
840
841        if (func_range.GetBaseAddress().IsValid())
842        {
843            Mangled func_name;
844            if (mangled)
845                func_name.SetValue(mangled, true);
846            else if (name)
847                func_name.SetValue(name, false);
848
849            FunctionSP func_sp;
850            std::auto_ptr<Declaration> decl_ap;
851            if (decl_file != 0 || decl_line != 0 || decl_column != 0)
852                decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
853                                               decl_line,
854                                               decl_column));
855
856            // Supply the type _only_ if it has already been parsed
857            Type *func_type = m_die_to_type.lookup (die);
858
859            assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
860
861            func_range.GetBaseAddress().ResolveLinkedAddress();
862
863            const user_id_t func_user_id = MakeUserID(die->GetOffset());
864            func_sp.reset(new Function (sc.comp_unit,
865                                        func_user_id,       // UserID is the DIE offset
866                                        func_user_id,
867                                        func_name,
868                                        func_type,
869                                        func_range));           // first address range
870
871            if (func_sp.get() != NULL)
872            {
873                if (frame_base.IsValid())
874                    func_sp->GetFrameBaseExpression() = frame_base;
875                sc.comp_unit->AddFunction(func_sp);
876                return func_sp.get();
877            }
878        }
879    }
880    return NULL;
881}
882
883size_t
884SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
885{
886    assert (sc.comp_unit);
887    size_t functions_added = 0;
888    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
889    if (dwarf_cu)
890    {
891        DWARFDIECollection function_dies;
892        const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
893        size_t func_idx;
894        for (func_idx = 0; func_idx < num_funtions; ++func_idx)
895        {
896            const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
897            if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
898            {
899                if (ParseCompileUnitFunction(sc, dwarf_cu, die))
900                    ++functions_added;
901            }
902        }
903        //FixupTypes();
904    }
905    return functions_added;
906}
907
908bool
909SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
910{
911    assert (sc.comp_unit);
912    DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
913    assert (curr_cu);
914    const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
915
916    if (cu_die)
917    {
918        const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
919        dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
920
921        // All file indexes in DWARF are one based and a file of index zero is
922        // supposed to be the compile unit itself.
923        support_files.Append (*sc.comp_unit);
924
925        return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
926    }
927    return false;
928}
929
930struct ParseDWARFLineTableCallbackInfo
931{
932    LineTable* line_table;
933    const SectionList *section_list;
934    lldb::addr_t prev_sect_file_base_addr;
935    lldb::addr_t curr_sect_file_base_addr;
936    bool is_oso_for_debug_map;
937    bool prev_in_final_executable;
938    DWARFDebugLine::Row prev_row;
939    SectionSP prev_section_sp;
940    SectionSP curr_section_sp;
941};
942
943//----------------------------------------------------------------------
944// ParseStatementTableCallback
945//----------------------------------------------------------------------
946static void
947ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
948{
949    LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
950    if (state.row == DWARFDebugLine::State::StartParsingLineTable)
951    {
952        // Just started parsing the line table
953    }
954    else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
955    {
956        // Done parsing line table, nothing to do for the cleanup
957    }
958    else
959    {
960        ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
961        // We have a new row, lets append it
962
963        if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
964        {
965            info->prev_section_sp = info->curr_section_sp;
966            info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
967            // If this is an end sequence entry, then we subtract one from the
968            // address to make sure we get an address that is not the end of
969            // a section.
970            if (state.end_sequence && state.address != 0)
971                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
972            else
973                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
974
975            if (info->curr_section_sp.get())
976                info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
977            else
978                info->curr_sect_file_base_addr = 0;
979        }
980        if (info->curr_section_sp.get())
981        {
982            lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
983            // Check for the fancy section magic to determine if we
984
985            if (info->is_oso_for_debug_map)
986            {
987                // When this is a debug map object file that contains DWARF
988                // (referenced from an N_OSO debug map nlist entry) we will have
989                // a file address in the file range for our section from the
990                // original .o file, and a load address in the executable that
991                // contains the debug map.
992                //
993                // If the sections for the file range and load range are
994                // different, we have a remapped section for the function and
995                // this address is resolved. If they are the same, then the
996                // function for this address didn't make it into the final
997                // executable.
998                bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
999
1000                // If we are doing DWARF with debug map, then we need to carefully
1001                // add each line table entry as there may be gaps as functions
1002                // get moved around or removed.
1003                if (!info->prev_row.end_sequence && info->prev_section_sp.get())
1004                {
1005                    if (info->prev_in_final_executable)
1006                    {
1007                        bool terminate_previous_entry = false;
1008                        if (!curr_in_final_executable)
1009                        {
1010                            // Check for the case where the previous line entry
1011                            // in a function made it into the final executable,
1012                            // yet the current line entry falls in a function
1013                            // that didn't. The line table used to be contiguous
1014                            // through this address range but now it isn't. We
1015                            // need to terminate the previous line entry so
1016                            // that we can reconstruct the line range correctly
1017                            // for it and to keep the line table correct.
1018                            terminate_previous_entry = true;
1019                        }
1020                        else if (info->curr_section_sp.get() != info->prev_section_sp.get())
1021                        {
1022                            // Check for cases where the line entries used to be
1023                            // contiguous address ranges, but now they aren't.
1024                            // This can happen when order files specify the
1025                            // ordering of the functions.
1026                            lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
1027                            Section *curr_sect = info->curr_section_sp.get();
1028                            Section *prev_sect = info->prev_section_sp.get();
1029                            assert (curr_sect->GetLinkedSection());
1030                            assert (prev_sect->GetLinkedSection());
1031                            lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
1032                            lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
1033                            lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
1034                            lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
1035                            if (object_file_addr_delta != linked_file_addr_delta)
1036                                terminate_previous_entry = true;
1037                        }
1038
1039                        if (terminate_previous_entry)
1040                        {
1041                            line_table->InsertLineEntry (info->prev_section_sp,
1042                                                         state.address - info->prev_sect_file_base_addr,
1043                                                         info->prev_row.line,
1044                                                         info->prev_row.column,
1045                                                         info->prev_row.file,
1046                                                         false,                 // is_stmt
1047                                                         false,                 // basic_block
1048                                                         false,                 // state.prologue_end
1049                                                         false,                 // state.epilogue_begin
1050                                                         true);                 // end_sequence);
1051                        }
1052                    }
1053                }
1054
1055                if (curr_in_final_executable)
1056                {
1057                    line_table->InsertLineEntry (info->curr_section_sp,
1058                                                 curr_line_section_offset,
1059                                                 state.line,
1060                                                 state.column,
1061                                                 state.file,
1062                                                 state.is_stmt,
1063                                                 state.basic_block,
1064                                                 state.prologue_end,
1065                                                 state.epilogue_begin,
1066                                                 state.end_sequence);
1067                    info->prev_section_sp = info->curr_section_sp;
1068                }
1069                else
1070                {
1071                    // If the current address didn't make it into the final
1072                    // executable, the current section will be the __text
1073                    // segment in the .o file, so we need to clear this so
1074                    // we can catch the next function that did make it into
1075                    // the final executable.
1076                    info->prev_section_sp.reset();
1077                    info->curr_section_sp.reset();
1078                }
1079
1080                info->prev_in_final_executable = curr_in_final_executable;
1081            }
1082            else
1083            {
1084                // We are not in an object file that contains DWARF for an
1085                // N_OSO, this is just a normal DWARF file. The DWARF spec
1086                // guarantees that the addresses will be in increasing order
1087                // so, since we store line tables in file address order, we
1088                // can always just append the line entry without needing to
1089                // search for the correct insertion point (we don't need to
1090                // use LineEntry::InsertLineEntry()).
1091                line_table->AppendLineEntry (info->curr_section_sp,
1092                                             curr_line_section_offset,
1093                                             state.line,
1094                                             state.column,
1095                                             state.file,
1096                                             state.is_stmt,
1097                                             state.basic_block,
1098                                             state.prologue_end,
1099                                             state.epilogue_begin,
1100                                             state.end_sequence);
1101            }
1102        }
1103
1104        info->prev_row = state;
1105    }
1106}
1107
1108bool
1109SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
1110{
1111    assert (sc.comp_unit);
1112    if (sc.comp_unit->GetLineTable() != NULL)
1113        return true;
1114
1115    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
1116    if (dwarf_cu)
1117    {
1118        const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
1119        if (dwarf_cu_die)
1120        {
1121            const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
1122            if (cu_line_offset != DW_INVALID_OFFSET)
1123            {
1124                std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
1125                if (line_table_ap.get())
1126                {
1127                    ParseDWARFLineTableCallbackInfo info = {
1128                        line_table_ap.get(),
1129                        m_obj_file->GetSectionList(),
1130                        0,
1131                        0,
1132                        m_debug_map_symfile != NULL,
1133                        false,
1134                        DWARFDebugLine::Row(),
1135                        SectionSP(),
1136                        SectionSP()
1137                    };
1138                    uint32_t offset = cu_line_offset;
1139                    DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
1140                    sc.comp_unit->SetLineTable(line_table_ap.release());
1141                    return true;
1142                }
1143            }
1144        }
1145    }
1146    return false;
1147}
1148
1149size_t
1150SymbolFileDWARF::ParseFunctionBlocks
1151(
1152    const SymbolContext& sc,
1153    Block *parent_block,
1154    DWARFCompileUnit* dwarf_cu,
1155    const DWARFDebugInfoEntry *die,
1156    addr_t subprogram_low_pc,
1157    uint32_t depth
1158)
1159{
1160    size_t blocks_added = 0;
1161    while (die != NULL)
1162    {
1163        dw_tag_t tag = die->Tag();
1164
1165        switch (tag)
1166        {
1167        case DW_TAG_inlined_subroutine:
1168        case DW_TAG_subprogram:
1169        case DW_TAG_lexical_block:
1170            {
1171                Block *block = NULL;
1172                if (tag == DW_TAG_subprogram)
1173                {
1174                    // Skip any DW_TAG_subprogram DIEs that are inside
1175                    // of a normal or inlined functions. These will be
1176                    // parsed on their own as separate entities.
1177
1178                    if (depth > 0)
1179                        break;
1180
1181                    block = parent_block;
1182                }
1183                else
1184                {
1185                    BlockSP block_sp(new Block (MakeUserID(die->GetOffset())));
1186                    parent_block->AddChild(block_sp);
1187                    block = block_sp.get();
1188                }
1189                DWARFDebugRanges::RangeList ranges;
1190                const char *name = NULL;
1191                const char *mangled_name = NULL;
1192
1193                int decl_file = 0;
1194                int decl_line = 0;
1195                int decl_column = 0;
1196                int call_file = 0;
1197                int call_line = 0;
1198                int call_column = 0;
1199                if (die->GetDIENamesAndRanges (this,
1200                                               dwarf_cu,
1201                                               name,
1202                                               mangled_name,
1203                                               ranges,
1204                                               decl_file, decl_line, decl_column,
1205                                               call_file, call_line, call_column))
1206                {
1207                    if (tag == DW_TAG_subprogram)
1208                    {
1209                        assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
1210                        subprogram_low_pc = ranges.GetMinRangeBase(0);
1211                    }
1212                    else if (tag == DW_TAG_inlined_subroutine)
1213                    {
1214                        // We get called here for inlined subroutines in two ways.
1215                        // The first time is when we are making the Function object
1216                        // for this inlined concrete instance.  Since we're creating a top level block at
1217                        // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS.  So we need to
1218                        // adjust the containing address.
1219                        // The second time is when we are parsing the blocks inside the function that contains
1220                        // the inlined concrete instance.  Since these will be blocks inside the containing "real"
1221                        // function the offset will be for that function.
1222                        if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1223                        {
1224                            subprogram_low_pc = ranges.GetMinRangeBase(0);
1225                        }
1226                    }
1227
1228                    AddRangesToBlock (*block, ranges, subprogram_low_pc);
1229
1230                    if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1231                    {
1232                        std::auto_ptr<Declaration> decl_ap;
1233                        if (decl_file != 0 || decl_line != 0 || decl_column != 0)
1234                            decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1235                                                          decl_line, decl_column));
1236
1237                        std::auto_ptr<Declaration> call_ap;
1238                        if (call_file != 0 || call_line != 0 || call_column != 0)
1239                            call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1240                                                          call_line, call_column));
1241
1242                        block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
1243                    }
1244
1245                    ++blocks_added;
1246
1247                    if (die->HasChildren())
1248                    {
1249                        blocks_added += ParseFunctionBlocks (sc,
1250                                                             block,
1251                                                             dwarf_cu,
1252                                                             die->GetFirstChild(),
1253                                                             subprogram_low_pc,
1254                                                             depth + 1);
1255                    }
1256                }
1257            }
1258            break;
1259        default:
1260            break;
1261        }
1262
1263        // Only parse siblings of the block if we are not at depth zero. A depth
1264        // of zero indicates we are currently parsing the top level
1265        // DW_TAG_subprogram DIE
1266
1267        if (depth == 0)
1268            die = NULL;
1269        else
1270            die = die->GetSibling();
1271    }
1272    return blocks_added;
1273}
1274
1275bool
1276SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu,
1277                                   const DWARFDebugInfoEntry *die,
1278                                   ClangASTContext::TemplateParameterInfos &template_param_infos)
1279{
1280    const dw_tag_t tag = die->Tag();
1281
1282    switch (tag)
1283    {
1284    case DW_TAG_template_type_parameter:
1285    case DW_TAG_template_value_parameter:
1286        {
1287            const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1288
1289            DWARFDebugInfoEntry::Attributes attributes;
1290            const size_t num_attributes = die->GetAttributes (this,
1291                                                              dwarf_cu,
1292                                                              fixed_form_sizes,
1293                                                              attributes);
1294            const char *name = NULL;
1295            Type *lldb_type = NULL;
1296            clang_type_t clang_type = NULL;
1297            uint64_t uval64 = 0;
1298            bool uval64_valid = false;
1299            if (num_attributes > 0)
1300            {
1301                DWARFFormValue form_value;
1302                for (size_t i=0; i<num_attributes; ++i)
1303                {
1304                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
1305
1306                    switch (attr)
1307                    {
1308                        case DW_AT_name:
1309                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1310                                name = form_value.AsCString(&get_debug_str_data());
1311                            break;
1312
1313                        case DW_AT_type:
1314                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1315                            {
1316                                const dw_offset_t type_die_offset = form_value.Reference(dwarf_cu);
1317                                lldb_type = ResolveTypeUID(type_die_offset);
1318                                if (lldb_type)
1319                                    clang_type = lldb_type->GetClangForwardType();
1320                            }
1321                            break;
1322
1323                        case DW_AT_const_value:
1324                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1325                            {
1326                                uval64_valid = true;
1327                                uval64 = form_value.Unsigned();
1328                            }
1329                            break;
1330                        default:
1331                            break;
1332                    }
1333                }
1334
1335                if (name && lldb_type && clang_type)
1336                {
1337                    bool is_signed = false;
1338                    template_param_infos.names.push_back(name);
1339                    clang::QualType clang_qual_type (clang::QualType::getFromOpaquePtr (clang_type));
1340                    if (tag == DW_TAG_template_value_parameter && ClangASTContext::IsIntegerType (clang_type, is_signed) && uval64_valid)
1341                    {
1342                        llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
1343                        template_param_infos.args.push_back (clang::TemplateArgument (llvm::APSInt(apint), clang_qual_type));
1344                    }
1345                    else
1346                    {
1347                        template_param_infos.args.push_back (clang::TemplateArgument (clang_qual_type));
1348                    }
1349                }
1350                else
1351                {
1352                    return false;
1353                }
1354
1355            }
1356        }
1357        return true;
1358
1359    default:
1360        break;
1361    }
1362    return false;
1363}
1364
1365bool
1366SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
1367                                              const DWARFDebugInfoEntry *parent_die,
1368                                              ClangASTContext::TemplateParameterInfos &template_param_infos)
1369{
1370
1371    if (parent_die == NULL)
1372        return NULL;
1373
1374    Args template_parameter_names;
1375    for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild();
1376         die != NULL;
1377         die = die->GetSibling())
1378    {
1379        const dw_tag_t tag = die->Tag();
1380
1381        switch (tag)
1382        {
1383            case DW_TAG_template_type_parameter:
1384            case DW_TAG_template_value_parameter:
1385                ParseTemplateDIE (dwarf_cu, die, template_param_infos);
1386            break;
1387
1388        default:
1389            break;
1390        }
1391    }
1392    if (template_param_infos.args.empty())
1393        return false;
1394    return template_param_infos.args.size() == template_param_infos.names.size();
1395}
1396
1397clang::ClassTemplateDecl *
1398SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
1399                                         lldb::AccessType access_type,
1400                                         const char *parent_name,
1401                                         int tag_decl_kind,
1402                                         const ClangASTContext::TemplateParameterInfos &template_param_infos)
1403{
1404    if (template_param_infos.IsValid())
1405    {
1406        std::string template_basename(parent_name);
1407        template_basename.erase (template_basename.find('<'));
1408        ClangASTContext &ast = GetClangASTContext();
1409
1410        return ast.CreateClassTemplateDecl (decl_ctx,
1411                                            access_type,
1412                                            template_basename.c_str(),
1413                                            tag_decl_kind,
1414                                            template_param_infos);
1415    }
1416    return NULL;
1417}
1418
1419size_t
1420SymbolFileDWARF::ParseChildMembers
1421(
1422    const SymbolContext& sc,
1423    DWARFCompileUnit* dwarf_cu,
1424    const DWARFDebugInfoEntry *parent_die,
1425    clang_type_t class_clang_type,
1426    const LanguageType class_language,
1427    std::vector<clang::CXXBaseSpecifier *>& base_classes,
1428    std::vector<int>& member_accessibilities,
1429    DWARFDIECollection& member_function_dies,
1430    AccessType& default_accessibility,
1431    bool &is_a_class,
1432    LayoutInfo &layout_info
1433)
1434{
1435    if (parent_die == NULL)
1436        return 0;
1437
1438    size_t count = 0;
1439    const DWARFDebugInfoEntry *die;
1440    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1441    uint32_t member_idx = 0;
1442
1443    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1444    {
1445        dw_tag_t tag = die->Tag();
1446
1447        switch (tag)
1448        {
1449        case DW_TAG_member:
1450            {
1451                DWARFDebugInfoEntry::Attributes attributes;
1452                const size_t num_attributes = die->GetAttributes (this,
1453                                                                  dwarf_cu,
1454                                                                  fixed_form_sizes,
1455                                                                  attributes);
1456                if (num_attributes > 0)
1457                {
1458                    Declaration decl;
1459                    //DWARFExpression location;
1460                    const char *name = NULL;
1461                    const char *prop_name = NULL;
1462                    const char *prop_getter_name = NULL;
1463                    const char *prop_setter_name = NULL;
1464                    uint32_t        prop_attributes = 0;
1465
1466
1467                    bool is_artificial = false;
1468                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1469                    AccessType accessibility = eAccessNone;
1470                    uint32_t member_byte_offset = UINT32_MAX;
1471                    size_t byte_size = 0;
1472                    size_t bit_offset = 0;
1473                    size_t bit_size = 0;
1474                    uint32_t i;
1475                    for (i=0; i<num_attributes && !is_artificial; ++i)
1476                    {
1477                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1478                        DWARFFormValue form_value;
1479                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1480                        {
1481                            switch (attr)
1482                            {
1483                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1484                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1485                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1486                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
1487                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1488                            case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break;
1489                            case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break;
1490                            case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
1491                            case DW_AT_data_member_location:
1492                                if (form_value.BlockData())
1493                                {
1494                                    Value initialValue(0);
1495                                    Value memberOffset(0);
1496                                    const DataExtractor& debug_info_data = get_debug_info_data();
1497                                    uint32_t block_length = form_value.Unsigned();
1498                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1499                                    if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
1500                                                                  NULL, // clang::ASTContext *
1501                                                                  NULL, // ClangExpressionVariableList *
1502                                                                  NULL, // ClangExpressionDeclMap *
1503                                                                  NULL, // RegisterContext *
1504                                                                  debug_info_data,
1505                                                                  block_offset,
1506                                                                  block_length,
1507                                                                  eRegisterKindDWARF,
1508                                                                  &initialValue,
1509                                                                  memberOffset,
1510                                                                  NULL))
1511                                    {
1512                                        member_byte_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1513                                    }
1514                                }
1515                                break;
1516
1517                            case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
1518                            case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
1519                            case DW_AT_declaration:
1520                            case DW_AT_description:
1521                            case DW_AT_mutable:
1522                            case DW_AT_visibility:
1523
1524                            case DW_AT_APPLE_property_name:      prop_name = form_value.AsCString(&get_debug_str_data()); break;
1525                            case DW_AT_APPLE_property_getter:    prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
1526                            case DW_AT_APPLE_property_setter:    prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
1527                            case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
1528
1529                            default:
1530                            case DW_AT_sibling:
1531                                break;
1532                            }
1533                        }
1534                    }
1535
1536                    // Clang has a DWARF generation bug where sometimes it
1537                    // represents fields that are references with bad byte size
1538                    // and bit size/offset information such as:
1539                    //
1540                    //  DW_AT_byte_size( 0x00 )
1541                    //  DW_AT_bit_size( 0x40 )
1542                    //  DW_AT_bit_offset( 0xffffffffffffffc0 )
1543                    //
1544                    // So check the bit offset to make sure it is sane, and if
1545                    // the values are not sane, remove them. If we don't do this
1546                    // then we will end up with a crash if we try to use this
1547                    // type in an expression when clang becomes unhappy with its
1548                    // recycled debug info.
1549
1550                    if (bit_offset > 128)
1551                    {
1552                        bit_size = 0;
1553                        bit_offset = 0;
1554                    }
1555
1556                    // FIXME: Make Clang ignore Objective-C accessibility for expressions
1557                    if (class_language == eLanguageTypeObjC ||
1558                        class_language == eLanguageTypeObjC_plus_plus)
1559                        accessibility = eAccessNone;
1560
1561                    if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
1562                    {
1563                        // Not all compilers will mark the vtable pointer
1564                        // member as artificial (llvm-gcc). We can't have
1565                        // the virtual members in our classes otherwise it
1566                        // throws off all child offsets since we end up
1567                        // having and extra pointer sized member in our
1568                        // class layouts.
1569                        is_artificial = true;
1570                    }
1571
1572                    if (is_artificial == false)
1573                    {
1574                        Type *member_type = ResolveTypeUID(encoding_uid);
1575                        clang::FieldDecl *field_decl = NULL;
1576                        if (member_type)
1577                        {
1578                            if (accessibility == eAccessNone)
1579                                accessibility = default_accessibility;
1580                            member_accessibilities.push_back(accessibility);
1581
1582                            field_decl = GetClangASTContext().AddFieldToRecordType (class_clang_type,
1583                                                                                    name,
1584                                                                                    member_type->GetClangLayoutType(),
1585                                                                                    accessibility,
1586                                                                                    bit_size);
1587                        }
1588                        else
1589                        {
1590                            if (name)
1591                                GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member '%s' refers to type 0x%8.8llx which was unable to be parsed",
1592                                                                           MakeUserID(die->GetOffset()),
1593                                                                           name,
1594                                                                           encoding_uid);
1595                            else
1596                                GetObjectFile()->GetModule()->ReportError ("0x%8.8llx: DW_TAG_member refers to type 0x%8.8llx which was unable to be parsed",
1597                                                                           MakeUserID(die->GetOffset()),
1598                                                                           encoding_uid);
1599                        }
1600
1601                        if (member_byte_offset != UINT32_MAX || bit_size != 0)
1602                        {
1603                            /////////////////////////////////////////////////////////////
1604                            // How to locate a field given the DWARF debug information
1605                            //
1606                            // AT_byte_size indicates the size of the word in which the
1607                            // bit offset must be interpreted.
1608                            //
1609                            // AT_data_member_location indicates the byte offset of the
1610                            // word from the base address of the structure.
1611                            //
1612                            // AT_bit_offset indicates how many bits into the word
1613                            // (according to the host endianness) the low-order bit of
1614                            // the field starts.  AT_bit_offset can be negative.
1615                            //
1616                            // AT_bit_size indicates the size of the field in bits.
1617                            /////////////////////////////////////////////////////////////
1618
1619                            ByteOrder object_endian = GetObjectFile()->GetModule()->GetArchitecture().GetDefaultEndian();
1620
1621                            uint64_t total_bit_offset = 0;
1622
1623                            total_bit_offset += (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
1624
1625                            if (object_endian == eByteOrderLittle)
1626                            {
1627                                total_bit_offset += byte_size * 8;
1628                                total_bit_offset -= (bit_offset + bit_size);
1629                            }
1630                            else
1631                            {
1632                                total_bit_offset += bit_offset;
1633                            }
1634
1635                            layout_info.field_offsets.insert(std::make_pair(field_decl, total_bit_offset));
1636                        }
1637                        if (prop_name != NULL)
1638                        {
1639
1640                            clang::ObjCIvarDecl *ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
1641                            assert (ivar_decl != NULL);
1642
1643
1644                            GetClangASTContext().AddObjCClassProperty (class_clang_type,
1645                                                                       prop_name,
1646                                                                       0,
1647                                                                       ivar_decl,
1648                                                                       prop_setter_name,
1649                                                                       prop_getter_name,
1650                                                                       prop_attributes);
1651                        }
1652                    }
1653                }
1654                ++member_idx;
1655            }
1656            break;
1657
1658        case DW_TAG_subprogram:
1659            // Let the type parsing code handle this one for us.
1660            member_function_dies.Append (die);
1661            break;
1662
1663        case DW_TAG_inheritance:
1664            {
1665                is_a_class = true;
1666                if (default_accessibility == eAccessNone)
1667                    default_accessibility = eAccessPrivate;
1668                // TODO: implement DW_TAG_inheritance type parsing
1669                DWARFDebugInfoEntry::Attributes attributes;
1670                const size_t num_attributes = die->GetAttributes (this,
1671                                                                  dwarf_cu,
1672                                                                  fixed_form_sizes,
1673                                                                  attributes);
1674                if (num_attributes > 0)
1675                {
1676                    Declaration decl;
1677                    DWARFExpression location;
1678                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1679                    AccessType accessibility = default_accessibility;
1680                    bool is_virtual = false;
1681                    bool is_base_of_class = true;
1682                    off_t member_offset = 0;
1683                    uint32_t i;
1684                    for (i=0; i<num_attributes; ++i)
1685                    {
1686                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1687                        DWARFFormValue form_value;
1688                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1689                        {
1690                            switch (attr)
1691                            {
1692                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1693                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1694                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1695                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1696                            case DW_AT_data_member_location:
1697                                if (form_value.BlockData())
1698                                {
1699                                    Value initialValue(0);
1700                                    Value memberOffset(0);
1701                                    const DataExtractor& debug_info_data = get_debug_info_data();
1702                                    uint32_t block_length = form_value.Unsigned();
1703                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1704                                    if (DWARFExpression::Evaluate (NULL,
1705                                                                   NULL,
1706                                                                   NULL,
1707                                                                   NULL,
1708                                                                   NULL,
1709                                                                   debug_info_data,
1710                                                                   block_offset,
1711                                                                   block_length,
1712                                                                   eRegisterKindDWARF,
1713                                                                   &initialValue,
1714                                                                   memberOffset,
1715                                                                   NULL))
1716                                    {
1717                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1718                                    }
1719                                }
1720                                break;
1721
1722                            case DW_AT_accessibility:
1723                                accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
1724                                break;
1725
1726                            case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1727                            default:
1728                            case DW_AT_sibling:
1729                                break;
1730                            }
1731                        }
1732                    }
1733
1734                    Type *base_class_type = ResolveTypeUID(encoding_uid);
1735                    assert(base_class_type);
1736
1737                    clang_type_t base_class_clang_type = base_class_type->GetClangFullType();
1738                    assert (base_class_clang_type);
1739                    if (class_language == eLanguageTypeObjC)
1740                    {
1741                        GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_clang_type);
1742                    }
1743                    else
1744                    {
1745                        base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_clang_type,
1746                                                                                               accessibility,
1747                                                                                               is_virtual,
1748                                                                                               is_base_of_class));
1749                    }
1750                }
1751            }
1752            break;
1753
1754        default:
1755            break;
1756        }
1757    }
1758    return count;
1759}
1760
1761
1762clang::DeclContext*
1763SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
1764{
1765    DWARFDebugInfo* debug_info = DebugInfo();
1766    if (debug_info && UserIDMatches(type_uid))
1767    {
1768        DWARFCompileUnitSP cu_sp;
1769        const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1770        if (die)
1771            return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
1772    }
1773    return NULL;
1774}
1775
1776clang::DeclContext*
1777SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
1778{
1779    if (UserIDMatches(type_uid))
1780        return GetClangDeclContextForDIEOffset (sc, type_uid);
1781    return NULL;
1782}
1783
1784Type*
1785SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
1786{
1787    if (UserIDMatches(type_uid))
1788    {
1789        DWARFDebugInfo* debug_info = DebugInfo();
1790        if (debug_info)
1791        {
1792            DWARFCompileUnitSP cu_sp;
1793            const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1794            const bool assert_not_being_parsed = true;
1795            return ResolveTypeUID (cu_sp.get(), type_die, assert_not_being_parsed);
1796        }
1797    }
1798    return NULL;
1799}
1800
1801Type*
1802SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed)
1803{
1804    if (die != NULL)
1805    {
1806        LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
1807        if (log)
1808            GetObjectFile()->GetModule()->LogMessage (log.get(),
1809                                                      "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'",
1810                                                      die->GetOffset(),
1811                                                      DW_TAG_value_to_name(die->Tag()),
1812                                                      die->GetName(this, cu));
1813
1814        // We might be coming in in the middle of a type tree (a class
1815        // withing a class, an enum within a class), so parse any needed
1816        // parent DIEs before we get to this one...
1817        const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
1818        switch (decl_ctx_die->Tag())
1819        {
1820            case DW_TAG_structure_type:
1821            case DW_TAG_union_type:
1822            case DW_TAG_class_type:
1823            {
1824                // Get the type, which could be a forward declaration
1825                if (log)
1826                    GetObjectFile()->GetModule()->LogMessage (log.get(),
1827                                                              "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x",
1828                                                              die->GetOffset(),
1829                                                              DW_TAG_value_to_name(die->Tag()),
1830                                                              die->GetName(this, cu),
1831                                                              decl_ctx_die->GetOffset());
1832
1833                Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
1834                if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
1835                {
1836                    if (log)
1837                        GetObjectFile()->GetModule()->LogMessage (log.get(),
1838                                                                  "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function",
1839                                                                  die->GetOffset(),
1840                                                                  DW_TAG_value_to_name(die->Tag()),
1841                                                                  die->GetName(this, cu),
1842                                                                  decl_ctx_die->GetOffset());
1843                    // Ask the type to complete itself if it already hasn't since if we
1844                    // want a function (method or static) from a class, the class must
1845                    // create itself and add it's own methods and class functions.
1846                    if (parent_type)
1847                        parent_type->GetClangFullType();
1848                }
1849            }
1850            break;
1851
1852            default:
1853                break;
1854        }
1855        return ResolveType (cu, die);
1856    }
1857    return NULL;
1858}
1859
1860// This function is used when SymbolFileDWARFDebugMap owns a bunch of
1861// SymbolFileDWARF objects to detect if this DWARF file is the one that
1862// can resolve a clang_type.
1863bool
1864SymbolFileDWARF::HasForwardDeclForClangType (lldb::clang_type_t clang_type)
1865{
1866    clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1867    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1868    return die != NULL;
1869}
1870
1871
1872lldb::clang_type_t
1873SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1874{
1875    // We have a struct/union/class/enum that needs to be fully resolved.
1876    clang_type_t clang_type_no_qualifiers = ClangASTType::RemoveFastQualifiers(clang_type);
1877    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers);
1878    if (die == NULL)
1879    {
1880        // We have already resolved this type...
1881        return clang_type;
1882    }
1883    // Once we start resolving this type, remove it from the forward declaration
1884    // map in case anyone child members or other types require this type to get resolved.
1885    // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1886    // are done.
1887    m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers);
1888
1889
1890    // Disable external storage for this type so we don't get anymore
1891    // clang::ExternalASTSource queries for this type.
1892    ClangASTContext::SetHasExternalStorage (clang_type, false);
1893
1894    DWARFDebugInfo* debug_info = DebugInfo();
1895
1896    DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
1897    Type *type = m_die_to_type.lookup (die);
1898
1899    const dw_tag_t tag = die->Tag();
1900
1901    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
1902    if (log)
1903        GetObjectFile()->GetModule()->LogMessage (log.get(),
1904                                                  "0x%8.8llx: %s '%s' resolving forward declaration...\n",
1905                                                  MakeUserID(die->GetOffset()),
1906                                                  DW_TAG_value_to_name(tag),
1907                                                  type->GetName().AsCString());
1908    assert (clang_type);
1909    DWARFDebugInfoEntry::Attributes attributes;
1910
1911    ClangASTContext &ast = GetClangASTContext();
1912
1913    switch (tag)
1914    {
1915    case DW_TAG_structure_type:
1916    case DW_TAG_union_type:
1917    case DW_TAG_class_type:
1918        ast.StartTagDeclarationDefinition (clang_type);
1919        {
1920            LayoutInfo layout_info;
1921            if (die->HasChildren())
1922            {
1923
1924                LanguageType class_language = eLanguageTypeUnknown;
1925                bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1926                if (is_objc_class)
1927                    class_language = eLanguageTypeObjC;
1928
1929                int tag_decl_kind = -1;
1930                AccessType default_accessibility = eAccessNone;
1931                if (tag == DW_TAG_structure_type)
1932                {
1933                    tag_decl_kind = clang::TTK_Struct;
1934                    default_accessibility = eAccessPublic;
1935                }
1936                else if (tag == DW_TAG_union_type)
1937                {
1938                    tag_decl_kind = clang::TTK_Union;
1939                    default_accessibility = eAccessPublic;
1940                }
1941                else if (tag == DW_TAG_class_type)
1942                {
1943                    tag_decl_kind = clang::TTK_Class;
1944                    default_accessibility = eAccessPrivate;
1945                }
1946
1947                SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1948                std::vector<clang::CXXBaseSpecifier *> base_classes;
1949                std::vector<int> member_accessibilities;
1950                bool is_a_class = false;
1951                // Parse members and base classes first
1952                DWARFDIECollection member_function_dies;
1953
1954                ParseChildMembers (sc,
1955                                   curr_cu,
1956                                   die,
1957                                   clang_type,
1958                                   class_language,
1959                                   base_classes,
1960                                   member_accessibilities,
1961                                   member_function_dies,
1962                                   default_accessibility,
1963                                   is_a_class,
1964                                   layout_info);
1965
1966                // Now parse any methods if there were any...
1967                size_t num_functions = member_function_dies.Size();
1968                if (num_functions > 0)
1969                {
1970                    for (size_t i=0; i<num_functions; ++i)
1971                    {
1972                        ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
1973                    }
1974                }
1975
1976                if (class_language == eLanguageTypeObjC)
1977                {
1978                    std::string class_str (ClangASTType::GetTypeNameForOpaqueQualType(clang_type));
1979                    if (!class_str.empty())
1980                    {
1981
1982                        DIEArray method_die_offsets;
1983                        if (m_using_apple_tables)
1984                        {
1985                            if (m_apple_objc_ap.get())
1986                                m_apple_objc_ap->FindByName(class_str.c_str(), method_die_offsets);
1987                        }
1988                        else
1989                        {
1990                            if (!m_indexed)
1991                                Index ();
1992
1993                            ConstString class_name (class_str.c_str());
1994                            m_objc_class_selectors_index.Find (class_name, method_die_offsets);
1995                        }
1996
1997                        if (!method_die_offsets.empty())
1998                        {
1999                            DWARFDebugInfo* debug_info = DebugInfo();
2000
2001                            DWARFCompileUnit* method_cu = NULL;
2002                            const size_t num_matches = method_die_offsets.size();
2003                            for (size_t i=0; i<num_matches; ++i)
2004                            {
2005                                const dw_offset_t die_offset = method_die_offsets[i];
2006                                DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);
2007
2008                                if (method_die)
2009                                    ResolveType (method_cu, method_die);
2010                                else
2011                                {
2012                                    if (m_using_apple_tables)
2013                                    {
2014                                        GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n",
2015                                                                                                   die_offset, class_str.c_str());
2016                                    }
2017                                }
2018                            }
2019                        }
2020                    }
2021                }
2022
2023                // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2024                // need to tell the clang type it is actually a class.
2025                if (class_language != eLanguageTypeObjC)
2026                {
2027                    if (is_a_class && tag_decl_kind != clang::TTK_Class)
2028                        ast.SetTagTypeKind (clang_type, clang::TTK_Class);
2029                }
2030
2031                // Since DW_TAG_structure_type gets used for both classes
2032                // and structures, we may need to set any DW_TAG_member
2033                // fields to have a "private" access if none was specified.
2034                // When we parsed the child members we tracked that actual
2035                // accessibility value for each DW_TAG_member in the
2036                // "member_accessibilities" array. If the value for the
2037                // member is zero, then it was set to the "default_accessibility"
2038                // which for structs was "public". Below we correct this
2039                // by setting any fields to "private" that weren't correctly
2040                // set.
2041                if (is_a_class && !member_accessibilities.empty())
2042                {
2043                    // This is a class and all members that didn't have
2044                    // their access specified are private.
2045                    ast.SetDefaultAccessForRecordFields (clang_type,
2046                                                         eAccessPrivate,
2047                                                         &member_accessibilities.front(),
2048                                                         member_accessibilities.size());
2049                }
2050
2051                if (!base_classes.empty())
2052                {
2053                    ast.SetBaseClassesForClassType (clang_type,
2054                                                    &base_classes.front(),
2055                                                    base_classes.size());
2056
2057                    // Clang will copy each CXXBaseSpecifier in "base_classes"
2058                    // so we have to free them all.
2059                    ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
2060                                                                base_classes.size());
2061                }
2062
2063            }
2064
2065            if (!layout_info.field_offsets.empty())
2066            {
2067                if (type)
2068                    layout_info.bit_size = type->GetByteSize() * 8;
2069                if (layout_info.bit_size == 0)
2070                    layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_byte_size, 0) * 8;
2071                clang::QualType qual_type(clang::QualType::getFromOpaquePtr(clang_type));
2072                const clang::RecordType *record_type = clang::dyn_cast<clang::RecordType>(qual_type.getTypePtr());
2073                if (record_type)
2074                {
2075                    const clang::RecordDecl *record_decl = record_type->getDecl();
2076
2077                    if (log)
2078                    {
2079                        GetObjectFile()->GetModule()->LogMessage (log.get(),
2080                                                                  "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u], base_offsets[0], vbase_offsets[0])",
2081                                                                  clang_type,
2082                                                                  record_decl,
2083                                                                  layout_info.bit_size,
2084                                                                  layout_info.alignment,
2085                                                                  (uint32_t)layout_info.field_offsets.size());
2086
2087                        llvm::DenseMap <const clang::FieldDecl *, uint64_t>::const_iterator pos, end = layout_info.field_offsets.end();
2088                        for (pos = layout_info.field_offsets.begin(); pos != end; ++pos)
2089                        {
2090                            GetObjectFile()->GetModule()->LogMessage (log.get(),
2091                                                                      "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field = { bit_offset=%u, name='%s' }",
2092                                                                      clang_type,
2093                                                                      (uint32_t)pos->second,
2094                                                                      pos->first->getNameAsString().c_str());
2095                        }
2096                    }
2097                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
2098                }
2099            }
2100        }
2101        ast.CompleteTagDeclarationDefinition (clang_type);
2102        return clang_type;
2103
2104    case DW_TAG_enumeration_type:
2105        ast.StartTagDeclarationDefinition (clang_type);
2106        if (die->HasChildren())
2107        {
2108            SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
2109            ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
2110        }
2111        ast.CompleteTagDeclarationDefinition (clang_type);
2112        return clang_type;
2113
2114    default:
2115        assert(false && "not a forward clang type decl!");
2116        break;
2117    }
2118    return NULL;
2119}
2120
2121Type*
2122SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
2123{
2124    if (type_die != NULL)
2125    {
2126        Type *type = m_die_to_type.lookup (type_die);
2127
2128        if (type == NULL)
2129            type = GetTypeForDIE (curr_cu, type_die).get();
2130
2131        if (assert_not_being_parsed)
2132        {
2133            if (type != DIE_IS_BEING_PARSED)
2134                return type;
2135
2136            GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
2137                                                                       type_die->GetOffset(),
2138                                                                       DW_TAG_value_to_name(type_die->Tag()),
2139                                                                       type_die->GetName(this, curr_cu));
2140
2141        }
2142        else
2143            return type;
2144    }
2145    return NULL;
2146}
2147
2148CompileUnit*
2149SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
2150{
2151    // Check if the symbol vendor already knows about this compile unit?
2152    if (curr_cu->GetUserData() == NULL)
2153    {
2154        // The symbol vendor doesn't know about this compile unit, we
2155        // need to parse and add it to the symbol vendor object.
2156        CompUnitSP dc_cu;
2157        ParseCompileUnit(curr_cu, dc_cu);
2158        if (dc_cu.get())
2159        {
2160            // Figure out the compile unit index if we weren't given one
2161            if (cu_idx == UINT32_MAX)
2162                DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
2163
2164            m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
2165
2166            if (m_debug_map_symfile)
2167                m_debug_map_symfile->SetCompileUnit(this, dc_cu);
2168        }
2169    }
2170    return (CompileUnit*)curr_cu->GetUserData();
2171}
2172
2173bool
2174SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
2175{
2176    sc.Clear();
2177    // Check if the symbol vendor already knows about this compile unit?
2178    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
2179
2180    sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get();
2181    if (sc.function == NULL)
2182        sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
2183
2184    if (sc.function)
2185    {
2186        sc.module_sp = sc.function->CalculateSymbolContextModule()->shared_from_this();
2187        return true;
2188    }
2189
2190    return false;
2191}
2192
2193uint32_t
2194SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
2195{
2196    Timer scoped_timer(__PRETTY_FUNCTION__,
2197                       "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
2198                       so_addr.GetSection(),
2199                       so_addr.GetOffset(),
2200                       resolve_scope);
2201    uint32_t resolved = 0;
2202    if (resolve_scope & (   eSymbolContextCompUnit |
2203                            eSymbolContextFunction |
2204                            eSymbolContextBlock |
2205                            eSymbolContextLineEntry))
2206    {
2207        lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
2208
2209        DWARFDebugInfo* debug_info = DebugInfo();
2210        if (debug_info)
2211        {
2212            dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
2213            if (cu_offset != DW_INVALID_OFFSET)
2214            {
2215                uint32_t cu_idx;
2216                DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
2217                if (curr_cu)
2218                {
2219                    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
2220                    assert(sc.comp_unit != NULL);
2221                    resolved |= eSymbolContextCompUnit;
2222
2223                    if (resolve_scope & eSymbolContextLineEntry)
2224                    {
2225                        LineTable *line_table = sc.comp_unit->GetLineTable();
2226                        if (line_table != NULL)
2227                        {
2228                            if (so_addr.IsLinkedAddress())
2229                            {
2230                                Address linked_addr (so_addr);
2231                                linked_addr.ResolveLinkedAddress();
2232                                if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
2233                                {
2234                                    resolved |= eSymbolContextLineEntry;
2235                                }
2236                            }
2237                            else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
2238                            {
2239                                resolved |= eSymbolContextLineEntry;
2240                            }
2241                        }
2242                    }
2243
2244                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
2245                    {
2246                        DWARFDebugInfoEntry *function_die = NULL;
2247                        DWARFDebugInfoEntry *block_die = NULL;
2248                        if (resolve_scope & eSymbolContextBlock)
2249                        {
2250                            curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
2251                        }
2252                        else
2253                        {
2254                            curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
2255                        }
2256
2257                        if (function_die != NULL)
2258                        {
2259                            sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
2260                            if (sc.function == NULL)
2261                                sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
2262                        }
2263
2264                        if (sc.function != NULL)
2265                        {
2266                            resolved |= eSymbolContextFunction;
2267
2268                            if (resolve_scope & eSymbolContextBlock)
2269                            {
2270                                Block& block = sc.function->GetBlock (true);
2271
2272                                if (block_die != NULL)
2273                                    sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
2274                                else
2275                                    sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
2276                                if (sc.block)
2277                                    resolved |= eSymbolContextBlock;
2278                            }
2279                        }
2280                    }
2281                }
2282            }
2283        }
2284    }
2285    return resolved;
2286}
2287
2288
2289
2290uint32_t
2291SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
2292{
2293    const uint32_t prev_size = sc_list.GetSize();
2294    if (resolve_scope & eSymbolContextCompUnit)
2295    {
2296        DWARFDebugInfo* debug_info = DebugInfo();
2297        if (debug_info)
2298        {
2299            uint32_t cu_idx;
2300            DWARFCompileUnit* curr_cu = NULL;
2301
2302            for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
2303            {
2304                CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
2305                bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
2306                if (check_inlines || file_spec_matches_cu_file_spec)
2307                {
2308                    SymbolContext sc (m_obj_file->GetModule());
2309                    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
2310                    assert(sc.comp_unit != NULL);
2311
2312                    uint32_t file_idx = UINT32_MAX;
2313
2314                    // If we are looking for inline functions only and we don't
2315                    // find it in the support files, we are done.
2316                    if (check_inlines)
2317                    {
2318                        file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
2319                        if (file_idx == UINT32_MAX)
2320                            continue;
2321                    }
2322
2323                    if (line != 0)
2324                    {
2325                        LineTable *line_table = sc.comp_unit->GetLineTable();
2326
2327                        if (line_table != NULL && line != 0)
2328                        {
2329                            // We will have already looked up the file index if
2330                            // we are searching for inline entries.
2331                            if (!check_inlines)
2332                                file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
2333
2334                            if (file_idx != UINT32_MAX)
2335                            {
2336                                uint32_t found_line;
2337                                uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
2338                                found_line = sc.line_entry.line;
2339
2340                                while (line_idx != UINT32_MAX)
2341                                {
2342                                    sc.function = NULL;
2343                                    sc.block = NULL;
2344                                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
2345                                    {
2346                                        const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
2347                                        if (file_vm_addr != LLDB_INVALID_ADDRESS)
2348                                        {
2349                                            DWARFDebugInfoEntry *function_die = NULL;
2350                                            DWARFDebugInfoEntry *block_die = NULL;
2351                                            curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
2352
2353                                            if (function_die != NULL)
2354                                            {
2355                                                sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
2356                                                if (sc.function == NULL)
2357                                                    sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
2358                                            }
2359
2360                                            if (sc.function != NULL)
2361                                            {
2362                                                Block& block = sc.function->GetBlock (true);
2363
2364                                                if (block_die != NULL)
2365                                                    sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
2366                                                else
2367                                                    sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
2368                                            }
2369                                        }
2370                                    }
2371
2372                                    sc_list.Append(sc);
2373                                    line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
2374                                }
2375                            }
2376                        }
2377                        else if (file_spec_matches_cu_file_spec && !check_inlines)
2378                        {
2379                            // only append the context if we aren't looking for inline call sites
2380                            // by file and line and if the file spec matches that of the compile unit
2381                            sc_list.Append(sc);
2382                        }
2383                    }
2384                    else if (file_spec_matches_cu_file_spec && !check_inlines)
2385                    {
2386                        // only append the context if we aren't looking for inline call sites
2387                        // by file and line and if the file spec matches that of the compile unit
2388                        sc_list.Append(sc);
2389                    }
2390
2391                    if (!check_inlines)
2392                        break;
2393                }
2394            }
2395        }
2396    }
2397    return sc_list.GetSize() - prev_size;
2398}
2399
2400void
2401SymbolFileDWARF::Index ()
2402{
2403    if (m_indexed)
2404        return;
2405    m_indexed = true;
2406    Timer scoped_timer (__PRETTY_FUNCTION__,
2407                        "SymbolFileDWARF::Index (%s)",
2408                        GetObjectFile()->GetFileSpec().GetFilename().AsCString());
2409
2410    DWARFDebugInfo* debug_info = DebugInfo();
2411    if (debug_info)
2412    {
2413        uint32_t cu_idx = 0;
2414        const uint32_t num_compile_units = GetNumCompileUnits();
2415        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
2416        {
2417            DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
2418
2419            bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
2420
2421            curr_cu->Index (cu_idx,
2422                            m_function_basename_index,
2423                            m_function_fullname_index,
2424                            m_function_method_index,
2425                            m_function_selector_index,
2426                            m_objc_class_selectors_index,
2427                            m_global_index,
2428                            m_type_index,
2429                            m_namespace_index);
2430
2431            // Keep memory down by clearing DIEs if this generate function
2432            // caused them to be parsed
2433            if (clear_dies)
2434                curr_cu->ClearDIEs (true);
2435        }
2436
2437        m_function_basename_index.Finalize();
2438        m_function_fullname_index.Finalize();
2439        m_function_method_index.Finalize();
2440        m_function_selector_index.Finalize();
2441        m_objc_class_selectors_index.Finalize();
2442        m_global_index.Finalize();
2443        m_type_index.Finalize();
2444        m_namespace_index.Finalize();
2445
2446#if defined (ENABLE_DEBUG_PRINTF)
2447        StreamFile s(stdout, false);
2448        s.Printf ("DWARF index for '%s/%s':",
2449                  GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
2450                  GetObjectFile()->GetFileSpec().GetFilename().AsCString());
2451        s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
2452        s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
2453        s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
2454        s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
2455        s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
2456        s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
2457        s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
2458        s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
2459#endif
2460    }
2461}
2462
2463bool
2464SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl)
2465{
2466    if (namespace_decl == NULL)
2467    {
2468        // Invalid namespace decl which means we aren't matching only things
2469        // in this symbol file, so return true to indicate it matches this
2470        // symbol file.
2471        return true;
2472    }
2473
2474    clang::ASTContext *namespace_ast = namespace_decl->GetASTContext();
2475
2476    if (namespace_ast == NULL)
2477        return true;    // No AST in the "namespace_decl", return true since it
2478                        // could then match any symbol file, including this one
2479
2480    if (namespace_ast == GetClangASTContext().getASTContext())
2481        return true;    // The ASTs match, return true
2482
2483    // The namespace AST was valid, and it does not match...
2484    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2485
2486    if (log)
2487        GetObjectFile()->GetModule()->LogMessage(log.get(), "Valid namespace does not match symbol file");
2488
2489    return false;
2490}
2491
2492bool
2493SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl,
2494                                   DWARFCompileUnit* cu,
2495                                   const DWARFDebugInfoEntry* die)
2496{
2497    // No namespace specified, so the answesr i
2498    if (namespace_decl == NULL)
2499        return true;
2500
2501    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2502
2503    const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
2504    if (decl_ctx_die)
2505    {
2506
2507        clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl();
2508        if (clang_namespace_decl)
2509        {
2510            if (decl_ctx_die->Tag() != DW_TAG_namespace)
2511            {
2512                if (log)
2513                    GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match, but its parent is not a namespace");
2514                return false;
2515            }
2516
2517            DeclContextToDIEMap::iterator pos = m_decl_ctx_to_die.find(clang_namespace_decl);
2518
2519            if (pos == m_decl_ctx_to_die.end())
2520            {
2521                if (log)
2522                    GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match in a namespace, but its parent is not the requested namespace");
2523
2524                return false;
2525            }
2526
2527            return pos->second.count (decl_ctx_die);
2528        }
2529        else
2530        {
2531            // We have a namespace_decl that was not NULL but it contained
2532            // a NULL "clang::NamespaceDecl", so this means the global namespace
2533            // So as long the the contained decl context DIE isn't a namespace
2534            // we should be ok.
2535            if (decl_ctx_die->Tag() != DW_TAG_namespace)
2536                return true;
2537        }
2538    }
2539
2540    if (log)
2541        GetObjectFile()->GetModule()->LogMessage(log.get(), "Found a match, but its parent doesn't exist");
2542
2543    return false;
2544}
2545uint32_t
2546SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
2547{
2548    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2549
2550    if (log)
2551    {
2552        GetObjectFile()->GetModule()->LogMessage (log.get(),
2553                                                  "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables)",
2554                                                  name.GetCString(),
2555                                                  namespace_decl,
2556                                                  append,
2557                                                  max_matches);
2558    }
2559
2560    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
2561		return 0;
2562
2563    DWARFDebugInfo* info = DebugInfo();
2564    if (info == NULL)
2565        return 0;
2566
2567    // If we aren't appending the results to this list, then clear the list
2568    if (!append)
2569        variables.Clear();
2570
2571    // Remember how many variables are in the list before we search in case
2572    // we are appending the results to a variable list.
2573    const uint32_t original_size = variables.GetSize();
2574
2575    DIEArray die_offsets;
2576
2577    if (m_using_apple_tables)
2578    {
2579        if (m_apple_names_ap.get())
2580        {
2581            const char *name_cstr = name.GetCString();
2582            const char *base_name_start;
2583            const char *base_name_end = NULL;
2584
2585            if (!CPPLanguageRuntime::StripNamespacesFromVariableName(name_cstr, base_name_start, base_name_end))
2586                base_name_start = name_cstr;
2587
2588            m_apple_names_ap->FindByName (base_name_start, die_offsets);
2589        }
2590    }
2591    else
2592    {
2593        // Index the DWARF if we haven't already
2594        if (!m_indexed)
2595            Index ();
2596
2597        m_global_index.Find (name, die_offsets);
2598    }
2599
2600    const size_t num_matches = die_offsets.size();
2601    if (num_matches)
2602    {
2603        SymbolContext sc;
2604        sc.module_sp = m_obj_file->GetModule()->shared_from_this();
2605        assert (sc.module_sp);
2606
2607        DWARFDebugInfo* debug_info = DebugInfo();
2608        DWARFCompileUnit* dwarf_cu = NULL;
2609        const DWARFDebugInfoEntry* die = NULL;
2610        for (size_t i=0; i<num_matches; ++i)
2611        {
2612            const dw_offset_t die_offset = die_offsets[i];
2613            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2614
2615            if (die)
2616            {
2617                sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2618                assert(sc.comp_unit != NULL);
2619
2620                if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
2621                    continue;
2622
2623                ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
2624
2625                if (variables.GetSize() - original_size >= max_matches)
2626                    break;
2627            }
2628            else
2629            {
2630                if (m_using_apple_tables)
2631                {
2632                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
2633                                                                               die_offset, name.GetCString());
2634                }
2635            }
2636        }
2637    }
2638
2639    // Return the number of variable that were appended to the list
2640    return variables.GetSize() - original_size;
2641}
2642
2643uint32_t
2644SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
2645{
2646    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2647
2648    if (log)
2649    {
2650        GetObjectFile()->GetModule()->LogMessage (log.get(),
2651                                                  "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)",
2652                                                  regex.GetText(),
2653                                                  append,
2654                                                  max_matches);
2655    }
2656
2657    DWARFDebugInfo* info = DebugInfo();
2658    if (info == NULL)
2659        return 0;
2660
2661    // If we aren't appending the results to this list, then clear the list
2662    if (!append)
2663        variables.Clear();
2664
2665    // Remember how many variables are in the list before we search in case
2666    // we are appending the results to a variable list.
2667    const uint32_t original_size = variables.GetSize();
2668
2669    DIEArray die_offsets;
2670
2671    if (m_using_apple_tables)
2672    {
2673        if (m_apple_names_ap.get())
2674        {
2675            DWARFMappedHash::DIEInfoArray hash_data_array;
2676            if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2677                DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2678        }
2679    }
2680    else
2681    {
2682        // Index the DWARF if we haven't already
2683        if (!m_indexed)
2684            Index ();
2685
2686        m_global_index.Find (regex, die_offsets);
2687    }
2688
2689    SymbolContext sc;
2690    sc.module_sp = m_obj_file->GetModule()->shared_from_this();
2691    assert (sc.module_sp);
2692
2693    DWARFCompileUnit* dwarf_cu = NULL;
2694    const DWARFDebugInfoEntry* die = NULL;
2695    const size_t num_matches = die_offsets.size();
2696    if (num_matches)
2697    {
2698        DWARFDebugInfo* debug_info = DebugInfo();
2699        for (size_t i=0; i<num_matches; ++i)
2700        {
2701            const dw_offset_t die_offset = die_offsets[i];
2702            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2703
2704            if (die)
2705            {
2706                sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2707
2708                ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
2709
2710                if (variables.GetSize() - original_size >= max_matches)
2711                    break;
2712            }
2713            else
2714            {
2715                if (m_using_apple_tables)
2716                {
2717                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
2718                                                                               die_offset, regex.GetText());
2719                }
2720            }
2721        }
2722    }
2723
2724    // Return the number of variable that were appended to the list
2725    return variables.GetSize() - original_size;
2726}
2727
2728
2729bool
2730SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
2731                                  DWARFCompileUnit *&dwarf_cu,
2732                                  SymbolContextList& sc_list)
2733{
2734    const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
2735    return ResolveFunction (dwarf_cu, die, sc_list);
2736}
2737
2738
2739bool
2740SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
2741                                  const DWARFDebugInfoEntry *die,
2742                                  SymbolContextList& sc_list)
2743{
2744    SymbolContext sc;
2745
2746    if (die == NULL)
2747        return false;
2748
2749    // If we were passed a die that is not a function, just return false...
2750    if (die->Tag() != DW_TAG_subprogram && die->Tag() != DW_TAG_inlined_subroutine)
2751        return false;
2752
2753    const DWARFDebugInfoEntry* inlined_die = NULL;
2754    if (die->Tag() == DW_TAG_inlined_subroutine)
2755    {
2756        inlined_die = die;
2757
2758        while ((die = die->GetParent()) != NULL)
2759        {
2760            if (die->Tag() == DW_TAG_subprogram)
2761                break;
2762        }
2763    }
2764    assert (die->Tag() == DW_TAG_subprogram);
2765    if (GetFunction (cu, die, sc))
2766    {
2767        Address addr;
2768        // Parse all blocks if needed
2769        if (inlined_die)
2770        {
2771            sc.block = sc.function->GetBlock (true).FindBlockByID (MakeUserID(inlined_die->GetOffset()));
2772            assert (sc.block != NULL);
2773            if (sc.block->GetStartAddress (addr) == false)
2774                addr.Clear();
2775        }
2776        else
2777        {
2778            sc.block = NULL;
2779            addr = sc.function->GetAddressRange().GetBaseAddress();
2780        }
2781
2782        if (addr.IsValid())
2783        {
2784            sc_list.Append(sc);
2785            return true;
2786        }
2787    }
2788
2789    return false;
2790}
2791
2792void
2793SymbolFileDWARF::FindFunctions (const ConstString &name,
2794                                const NameToDIE &name_to_die,
2795                                SymbolContextList& sc_list)
2796{
2797    DIEArray die_offsets;
2798    if (name_to_die.Find (name, die_offsets))
2799    {
2800        ParseFunctions (die_offsets, sc_list);
2801    }
2802}
2803
2804
2805void
2806SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2807                                const NameToDIE &name_to_die,
2808                                SymbolContextList& sc_list)
2809{
2810    DIEArray die_offsets;
2811    if (name_to_die.Find (regex, die_offsets))
2812    {
2813        ParseFunctions (die_offsets, sc_list);
2814    }
2815}
2816
2817
2818void
2819SymbolFileDWARF::FindFunctions (const RegularExpression &regex,
2820                                const DWARFMappedHash::MemoryTable &memory_table,
2821                                SymbolContextList& sc_list)
2822{
2823    DIEArray die_offsets;
2824    DWARFMappedHash::DIEInfoArray hash_data_array;
2825    if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
2826    {
2827        DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
2828        ParseFunctions (die_offsets, sc_list);
2829    }
2830}
2831
2832void
2833SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
2834                                 SymbolContextList& sc_list)
2835{
2836    const size_t num_matches = die_offsets.size();
2837    if (num_matches)
2838    {
2839        SymbolContext sc;
2840
2841        DWARFCompileUnit* dwarf_cu = NULL;
2842        for (size_t i=0; i<num_matches; ++i)
2843        {
2844            const dw_offset_t die_offset = die_offsets[i];
2845            ResolveFunction (die_offset, dwarf_cu, sc_list);
2846        }
2847    }
2848}
2849
2850bool
2851SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
2852                                                const DWARFCompileUnit *dwarf_cu,
2853                                                uint32_t name_type_mask,
2854                                                const char *partial_name,
2855                                                const char *base_name_start,
2856                                                const char *base_name_end)
2857{
2858    // If we are looking only for methods, throw away all the ones that aren't in C++ classes:
2859    if (name_type_mask == eFunctionNameTypeMethod
2860        || name_type_mask == eFunctionNameTypeBase)
2861    {
2862        clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
2863        if (!containing_decl_ctx)
2864            return false;
2865
2866        bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
2867
2868        if (!is_cxx_method && name_type_mask == eFunctionNameTypeMethod)
2869            return false;
2870        if (is_cxx_method && name_type_mask == eFunctionNameTypeBase)
2871            return false;
2872    }
2873
2874    // Now we need to check whether the name we got back for this type matches the extra specifications
2875    // that were in the name we're looking up:
2876    if (base_name_start != partial_name || *base_name_end != '\0')
2877    {
2878        // First see if the stuff to the left matches the full name.  To do that let's see if
2879        // we can pull out the mips linkage name attribute:
2880
2881        Mangled best_name;
2882
2883        DWARFDebugInfoEntry::Attributes attributes;
2884        die->GetAttributes(this, dwarf_cu, NULL, attributes);
2885        uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
2886        if (idx != UINT32_MAX)
2887        {
2888            DWARFFormValue form_value;
2889            if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
2890            {
2891                const char *name = form_value.AsCString(&get_debug_str_data());
2892                best_name.SetValue (name, true);
2893            }
2894        }
2895        if (best_name)
2896        {
2897            const char *demangled = best_name.GetDemangledName().GetCString();
2898            if (demangled)
2899            {
2900                std::string name_no_parens(partial_name, base_name_end - partial_name);
2901                if (strstr (demangled, name_no_parens.c_str()) == NULL)
2902                    return false;
2903            }
2904        }
2905    }
2906
2907    return true;
2908}
2909
2910uint32_t
2911SymbolFileDWARF::FindFunctions (const ConstString &name,
2912                                const lldb_private::ClangNamespaceDecl *namespace_decl,
2913                                uint32_t name_type_mask,
2914                                bool append,
2915                                SymbolContextList& sc_list)
2916{
2917    Timer scoped_timer (__PRETTY_FUNCTION__,
2918                        "SymbolFileDWARF::FindFunctions (name = '%s')",
2919                        name.AsCString());
2920
2921    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
2922
2923    if (log)
2924    {
2925        GetObjectFile()->GetModule()->LogMessage (log.get(),
2926                                                  "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)",
2927                                                  name.GetCString(),
2928                                                  name_type_mask,
2929                                                  append);
2930    }
2931
2932    // If we aren't appending the results to this list, then clear the list
2933    if (!append)
2934        sc_list.Clear();
2935
2936    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
2937		return 0;
2938
2939    // If name is empty then we won't find anything.
2940    if (name.IsEmpty())
2941        return 0;
2942
2943    // Remember how many sc_list are in the list before we search in case
2944    // we are appending the results to a variable list.
2945
2946    const uint32_t original_size = sc_list.GetSize();
2947
2948    const char *name_cstr = name.GetCString();
2949    uint32_t effective_name_type_mask = eFunctionNameTypeNone;
2950    const char *base_name_start = name_cstr;
2951    const char *base_name_end = name_cstr + strlen(name_cstr);
2952
2953    if (name_type_mask & eFunctionNameTypeAuto)
2954    {
2955        if (CPPLanguageRuntime::IsCPPMangledName (name_cstr))
2956            effective_name_type_mask = eFunctionNameTypeFull;
2957        else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
2958            effective_name_type_mask = eFunctionNameTypeFull;
2959        else
2960        {
2961            if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
2962                effective_name_type_mask |= eFunctionNameTypeSelector;
2963
2964            if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
2965                effective_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
2966        }
2967    }
2968    else
2969    {
2970        effective_name_type_mask = name_type_mask;
2971        if (effective_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
2972        {
2973            // If they've asked for a CPP method or function name and it can't be that, we don't
2974            // even need to search for CPP methods or names.
2975            if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
2976            {
2977                effective_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase);
2978                if (effective_name_type_mask == eFunctionNameTypeNone)
2979                    return 0;
2980            }
2981        }
2982
2983        if (effective_name_type_mask & eFunctionNameTypeSelector)
2984        {
2985            if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
2986            {
2987                effective_name_type_mask &= ~(eFunctionNameTypeSelector);
2988                if (effective_name_type_mask == eFunctionNameTypeNone)
2989                    return 0;
2990            }
2991        }
2992    }
2993
2994    DWARFDebugInfo* info = DebugInfo();
2995    if (info == NULL)
2996        return 0;
2997
2998    DWARFCompileUnit *dwarf_cu = NULL;
2999    if (m_using_apple_tables)
3000    {
3001        if (m_apple_names_ap.get())
3002        {
3003
3004            DIEArray die_offsets;
3005
3006            uint32_t num_matches = 0;
3007
3008            if (effective_name_type_mask & eFunctionNameTypeFull)
3009            {
3010                // If they asked for the full name, match what they typed.  At some point we may
3011                // want to canonicalize this (strip double spaces, etc.  For now, we just add all the
3012                // dies that we find by exact match.
3013                num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
3014                for (uint32_t i = 0; i < num_matches; i++)
3015                {
3016                    const dw_offset_t die_offset = die_offsets[i];
3017                    const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
3018                    if (die)
3019                    {
3020                        if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3021                            continue;
3022
3023                        ResolveFunction (dwarf_cu, die, sc_list);
3024                    }
3025                    else
3026                    {
3027                        GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
3028                                                                                   die_offset, name_cstr);
3029                    }
3030                }
3031            }
3032            else
3033            {
3034                if (effective_name_type_mask & eFunctionNameTypeSelector)
3035                {
3036                    if (namespace_decl && *namespace_decl)
3037                        return 0; // no selectors in namespaces
3038
3039                    num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
3040                    // Now make sure these are actually ObjC methods.  In this case we can simply look up the name,
3041                    // and if it is an ObjC method name, we're good.
3042
3043                    for (uint32_t i = 0; i < num_matches; i++)
3044                    {
3045                        const dw_offset_t die_offset = die_offsets[i];
3046                        const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
3047                        if (die)
3048                        {
3049                            const char *die_name = die->GetName(this, dwarf_cu);
3050                            if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
3051                                ResolveFunction (dwarf_cu, die, sc_list);
3052                        }
3053                        else
3054                        {
3055                            GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
3056                                                                       die_offset, name_cstr);
3057                        }
3058                    }
3059                    die_offsets.clear();
3060                }
3061
3062                if (effective_name_type_mask & eFunctionNameTypeMethod
3063                    || effective_name_type_mask & eFunctionNameTypeBase)
3064                {
3065                    if ((effective_name_type_mask & eFunctionNameTypeMethod) &&
3066                        (namespace_decl && *namespace_decl))
3067                        return 0; // no methods in namespaces
3068
3069                    // The apple_names table stores just the "base name" of C++ methods in the table.  So we have to
3070                    // extract the base name, look that up, and if there is any other information in the name we were
3071                    // passed in we have to post-filter based on that.
3072
3073                    // FIXME: Arrange the logic above so that we don't calculate the base name twice:
3074                    std::string base_name(base_name_start, base_name_end - base_name_start);
3075                    num_matches = m_apple_names_ap->FindByName (base_name.c_str(), die_offsets);
3076
3077                    for (uint32_t i = 0; i < num_matches; i++)
3078                    {
3079                        const dw_offset_t die_offset = die_offsets[i];
3080                        const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
3081                        if (die)
3082                        {
3083                            if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3084                                continue;
3085
3086                            if (!FunctionDieMatchesPartialName(die,
3087                                                               dwarf_cu,
3088                                                               effective_name_type_mask,
3089                                                               name_cstr,
3090                                                               base_name_start,
3091                                                               base_name_end))
3092                                continue;
3093
3094                            // If we get to here, the die is good, and we should add it:
3095                            ResolveFunction (dwarf_cu, die, sc_list);
3096                        }
3097                        else
3098                        {
3099                            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
3100                                                                                       die_offset, name_cstr);
3101                        }
3102                    }
3103                    die_offsets.clear();
3104                }
3105            }
3106        }
3107    }
3108    else
3109    {
3110
3111        // Index the DWARF if we haven't already
3112        if (!m_indexed)
3113            Index ();
3114
3115        if (name_type_mask & eFunctionNameTypeFull)
3116            FindFunctions (name, m_function_fullname_index, sc_list);
3117
3118        std::string base_name(base_name_start, base_name_end - base_name_start);
3119        ConstString base_name_const(base_name.c_str());
3120        DIEArray die_offsets;
3121        DWARFCompileUnit *dwarf_cu = NULL;
3122
3123        if (effective_name_type_mask & eFunctionNameTypeBase)
3124        {
3125            uint32_t num_base = m_function_basename_index.Find(base_name_const, die_offsets);
3126            for (uint32_t i = 0; i < num_base; i++)
3127            {
3128                const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
3129                if (die)
3130                {
3131                    if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3132                        continue;
3133
3134                    if (!FunctionDieMatchesPartialName(die,
3135                                                       dwarf_cu,
3136                                                       effective_name_type_mask,
3137                                                       name_cstr,
3138                                                       base_name_start,
3139                                                       base_name_end))
3140                        continue;
3141
3142                    // If we get to here, the die is good, and we should add it:
3143                    ResolveFunction (dwarf_cu, die, sc_list);
3144                }
3145            }
3146            die_offsets.clear();
3147        }
3148
3149        if (effective_name_type_mask & eFunctionNameTypeMethod)
3150        {
3151            if (namespace_decl && *namespace_decl)
3152                return 0; // no methods in namespaces
3153
3154            uint32_t num_base = m_function_method_index.Find(base_name_const, die_offsets);
3155            {
3156                for (uint32_t i = 0; i < num_base; i++)
3157                {
3158                    const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
3159                    if (die)
3160                    {
3161                        if (!FunctionDieMatchesPartialName(die,
3162                                                           dwarf_cu,
3163                                                           effective_name_type_mask,
3164                                                           name_cstr,
3165                                                           base_name_start,
3166                                                           base_name_end))
3167                            continue;
3168
3169                        // If we get to here, the die is good, and we should add it:
3170                        ResolveFunction (dwarf_cu, die, sc_list);
3171                    }
3172                }
3173            }
3174            die_offsets.clear();
3175        }
3176
3177        if ((effective_name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
3178        {
3179            FindFunctions (name, m_function_selector_index, sc_list);
3180        }
3181
3182    }
3183
3184    // Return the number of variable that were appended to the list
3185    return sc_list.GetSize() - original_size;
3186}
3187
3188uint32_t
3189SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
3190{
3191    Timer scoped_timer (__PRETTY_FUNCTION__,
3192                        "SymbolFileDWARF::FindFunctions (regex = '%s')",
3193                        regex.GetText());
3194
3195    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
3196
3197    if (log)
3198    {
3199        GetObjectFile()->GetModule()->LogMessage (log.get(),
3200                                                  "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)",
3201                                                  regex.GetText(),
3202                                                  append);
3203    }
3204
3205
3206    // If we aren't appending the results to this list, then clear the list
3207    if (!append)
3208        sc_list.Clear();
3209
3210    // Remember how many sc_list are in the list before we search in case
3211    // we are appending the results to a variable list.
3212    uint32_t original_size = sc_list.GetSize();
3213
3214    if (m_using_apple_tables)
3215    {
3216        if (m_apple_names_ap.get())
3217            FindFunctions (regex, *m_apple_names_ap, sc_list);
3218    }
3219    else
3220    {
3221        // Index the DWARF if we haven't already
3222        if (!m_indexed)
3223            Index ();
3224
3225        FindFunctions (regex, m_function_basename_index, sc_list);
3226
3227        FindFunctions (regex, m_function_fullname_index, sc_list);
3228    }
3229
3230    // Return the number of variable that were appended to the list
3231    return sc_list.GetSize() - original_size;
3232}
3233
3234uint32_t
3235SymbolFileDWARF::FindTypes (const SymbolContext& sc,
3236                            const ConstString &name,
3237                            const lldb_private::ClangNamespaceDecl *namespace_decl,
3238                            bool append,
3239                            uint32_t max_matches,
3240                            TypeList& types)
3241{
3242    DWARFDebugInfo* info = DebugInfo();
3243    if (info == NULL)
3244        return 0;
3245
3246    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
3247
3248    if (log)
3249    {
3250        GetObjectFile()->GetModule()->LogMessage (log.get(),
3251                                                  "SymbolFileDWARF::FindTypes (sc, name=\"%s\", append=%u, max_matches=%u, type_list)",
3252                                                  name.GetCString(),
3253                                                  append,
3254                                                  max_matches);
3255    }
3256
3257    // If we aren't appending the results to this list, then clear the list
3258    if (!append)
3259        types.Clear();
3260
3261    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
3262		return 0;
3263
3264    DIEArray die_offsets;
3265
3266    if (m_using_apple_tables)
3267    {
3268        if (m_apple_types_ap.get())
3269        {
3270            const char *name_cstr = name.GetCString();
3271            m_apple_types_ap->FindByName (name_cstr, die_offsets);
3272        }
3273    }
3274    else
3275    {
3276        if (!m_indexed)
3277            Index ();
3278
3279        m_type_index.Find (name, die_offsets);
3280    }
3281
3282    const size_t num_matches = die_offsets.size();
3283
3284    if (num_matches)
3285    {
3286        const uint32_t initial_types_size = types.GetSize();
3287        DWARFCompileUnit* dwarf_cu = NULL;
3288        const DWARFDebugInfoEntry* die = NULL;
3289        DWARFDebugInfo* debug_info = DebugInfo();
3290        for (size_t i=0; i<num_matches; ++i)
3291        {
3292            const dw_offset_t die_offset = die_offsets[i];
3293            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
3294
3295            if (die)
3296            {
3297                if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
3298                    continue;
3299
3300                Type *matching_type = ResolveType (dwarf_cu, die);
3301                if (matching_type)
3302                {
3303                    // We found a type pointer, now find the shared pointer form our type list
3304                    types.InsertUnique (matching_type->shared_from_this());
3305                    if (types.GetSize() >= max_matches)
3306                        break;
3307                }
3308            }
3309            else
3310            {
3311                if (m_using_apple_tables)
3312                {
3313                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
3314                                                                               die_offset, name.GetCString());
3315                }
3316            }
3317
3318        }
3319        return types.GetSize() - initial_types_size;
3320    }
3321    return 0;
3322}
3323
3324
3325ClangNamespaceDecl
3326SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
3327                                const ConstString &name,
3328                                const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
3329{
3330    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
3331
3332    if (log)
3333    {
3334        GetObjectFile()->GetModule()->LogMessage (log.get(),
3335                                                  "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")",
3336                                                  name.GetCString());
3337    }
3338
3339    if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl))
3340		return ClangNamespaceDecl();
3341
3342    ClangNamespaceDecl namespace_decl;
3343    DWARFDebugInfo* info = DebugInfo();
3344    if (info)
3345    {
3346        DIEArray die_offsets;
3347
3348        // Index if we already haven't to make sure the compile units
3349        // get indexed and make their global DIE index list
3350        if (m_using_apple_tables)
3351        {
3352            if (m_apple_namespaces_ap.get())
3353            {
3354                const char *name_cstr = name.GetCString();
3355                m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
3356            }
3357        }
3358        else
3359        {
3360            if (!m_indexed)
3361                Index ();
3362
3363            m_namespace_index.Find (name, die_offsets);
3364        }
3365
3366        DWARFCompileUnit* dwarf_cu = NULL;
3367        const DWARFDebugInfoEntry* die = NULL;
3368        const size_t num_matches = die_offsets.size();
3369        if (num_matches)
3370        {
3371            DWARFDebugInfo* debug_info = DebugInfo();
3372            for (size_t i=0; i<num_matches; ++i)
3373            {
3374                const dw_offset_t die_offset = die_offsets[i];
3375                die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
3376
3377                if (die)
3378                {
3379                    if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die))
3380                        continue;
3381
3382                    clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
3383                    if (clang_namespace_decl)
3384                    {
3385                        namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
3386                        namespace_decl.SetNamespaceDecl (clang_namespace_decl);
3387                        break;
3388                    }
3389                }
3390                else
3391                {
3392                    if (m_using_apple_tables)
3393                    {
3394                        GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
3395                                                                   die_offset, name.GetCString());
3396                    }
3397                }
3398
3399            }
3400        }
3401    }
3402    return namespace_decl;
3403}
3404
3405uint32_t
3406SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
3407{
3408    // Remember how many sc_list are in the list before we search in case
3409    // we are appending the results to a variable list.
3410    uint32_t original_size = types.GetSize();
3411
3412    const uint32_t num_die_offsets = die_offsets.size();
3413    // Parse all of the types we found from the pubtypes matches
3414    uint32_t i;
3415    uint32_t num_matches = 0;
3416    for (i = 0; i < num_die_offsets; ++i)
3417    {
3418        Type *matching_type = ResolveTypeUID (die_offsets[i]);
3419        if (matching_type)
3420        {
3421            // We found a type pointer, now find the shared pointer form our type list
3422            types.InsertUnique (matching_type->shared_from_this());
3423            ++num_matches;
3424            if (num_matches >= max_matches)
3425                break;
3426        }
3427    }
3428
3429    // Return the number of variable that were appended to the list
3430    return types.GetSize() - original_size;
3431}
3432
3433
3434size_t
3435SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
3436                                       clang::DeclContext *containing_decl_ctx,
3437                                       DWARFCompileUnit* dwarf_cu,
3438                                       const DWARFDebugInfoEntry *parent_die,
3439                                       bool skip_artificial,
3440                                       bool &is_static,
3441                                       TypeList* type_list,
3442                                       std::vector<clang_type_t>& function_param_types,
3443                                       std::vector<clang::ParmVarDecl*>& function_param_decls,
3444                                       unsigned &type_quals,
3445                                       ClangASTContext::TemplateParameterInfos &template_param_infos)
3446{
3447    if (parent_die == NULL)
3448        return 0;
3449
3450    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
3451
3452    size_t arg_idx = 0;
3453    const DWARFDebugInfoEntry *die;
3454    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3455    {
3456        dw_tag_t tag = die->Tag();
3457        switch (tag)
3458        {
3459        case DW_TAG_formal_parameter:
3460            {
3461                DWARFDebugInfoEntry::Attributes attributes;
3462                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
3463                if (num_attributes > 0)
3464                {
3465                    const char *name = NULL;
3466                    Declaration decl;
3467                    dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
3468                    bool is_artificial = false;
3469                    // one of None, Auto, Register, Extern, Static, PrivateExtern
3470
3471                    clang::StorageClass storage = clang::SC_None;
3472                    uint32_t i;
3473                    for (i=0; i<num_attributes; ++i)
3474                    {
3475                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
3476                        DWARFFormValue form_value;
3477                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3478                        {
3479                            switch (attr)
3480                            {
3481                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3482                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3483                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3484                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
3485                            case DW_AT_type:        param_type_die_offset = form_value.Reference(dwarf_cu); break;
3486                            case DW_AT_artificial:  is_artificial = form_value.Unsigned() != 0; break;
3487                            case DW_AT_location:
3488    //                          if (form_value.BlockData())
3489    //                          {
3490    //                              const DataExtractor& debug_info_data = debug_info();
3491    //                              uint32_t block_length = form_value.Unsigned();
3492    //                              DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
3493    //                          }
3494    //                          else
3495    //                          {
3496    //                          }
3497    //                          break;
3498                            case DW_AT_const_value:
3499                            case DW_AT_default_value:
3500                            case DW_AT_description:
3501                            case DW_AT_endianity:
3502                            case DW_AT_is_optional:
3503                            case DW_AT_segment:
3504                            case DW_AT_variable_parameter:
3505                            default:
3506                            case DW_AT_abstract_origin:
3507                            case DW_AT_sibling:
3508                                break;
3509                            }
3510                        }
3511                    }
3512
3513                    bool skip = false;
3514                    if (skip_artificial)
3515                    {
3516                        if (is_artificial)
3517                        {
3518                            // In order to determine if a C++ member function is
3519                            // "const" we have to look at the const-ness of "this"...
3520                            // Ugly, but that
3521                            if (arg_idx == 0)
3522                            {
3523                                if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
3524                                {
3525                                    // Often times compilers omit the "this" name for the
3526                                    // specification DIEs, so we can't rely upon the name
3527                                    // being in the formal parameter DIE...
3528                                    if (name == NULL || ::strcmp(name, "this")==0)
3529                                    {
3530                                        Type *this_type = ResolveTypeUID (param_type_die_offset);
3531                                        if (this_type)
3532                                        {
3533                                            uint32_t encoding_mask = this_type->GetEncodingMask();
3534                                            if (encoding_mask & Type::eEncodingIsPointerUID)
3535                                            {
3536                                                is_static = false;
3537
3538                                                if (encoding_mask & (1u << Type::eEncodingIsConstUID))
3539                                                    type_quals |= clang::Qualifiers::Const;
3540                                                if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
3541                                                    type_quals |= clang::Qualifiers::Volatile;
3542                                            }
3543                                        }
3544                                    }
3545                                }
3546                            }
3547                            skip = true;
3548                        }
3549                        else
3550                        {
3551
3552                            // HACK: Objective C formal parameters "self" and "_cmd"
3553                            // are not marked as artificial in the DWARF...
3554                            CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
3555                            if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
3556                            {
3557                                if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
3558                                    skip = true;
3559                            }
3560                        }
3561                    }
3562
3563                    if (!skip)
3564                    {
3565                        Type *type = ResolveTypeUID(param_type_die_offset);
3566                        if (type)
3567                        {
3568                            function_param_types.push_back (type->GetClangForwardType());
3569
3570                            clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name,
3571                                                                                                                  type->GetClangForwardType(),
3572                                                                                                                  storage);
3573                            assert(param_var_decl);
3574                            function_param_decls.push_back(param_var_decl);
3575                        }
3576                    }
3577                }
3578                arg_idx++;
3579            }
3580            break;
3581
3582        case DW_TAG_template_type_parameter:
3583        case DW_TAG_template_value_parameter:
3584            ParseTemplateDIE (dwarf_cu, die,template_param_infos);
3585            break;
3586
3587        default:
3588            break;
3589        }
3590    }
3591    return arg_idx;
3592}
3593
3594size_t
3595SymbolFileDWARF::ParseChildEnumerators
3596(
3597    const SymbolContext& sc,
3598    clang_type_t  enumerator_clang_type,
3599    uint32_t enumerator_byte_size,
3600    DWARFCompileUnit* dwarf_cu,
3601    const DWARFDebugInfoEntry *parent_die
3602)
3603{
3604    if (parent_die == NULL)
3605        return 0;
3606
3607    size_t enumerators_added = 0;
3608    const DWARFDebugInfoEntry *die;
3609    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
3610
3611    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3612    {
3613        const dw_tag_t tag = die->Tag();
3614        if (tag == DW_TAG_enumerator)
3615        {
3616            DWARFDebugInfoEntry::Attributes attributes;
3617            const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
3618            if (num_child_attributes > 0)
3619            {
3620                const char *name = NULL;
3621                bool got_value = false;
3622                int64_t enum_value = 0;
3623                Declaration decl;
3624
3625                uint32_t i;
3626                for (i=0; i<num_child_attributes; ++i)
3627                {
3628                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
3629                    DWARFFormValue form_value;
3630                    if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3631                    {
3632                        switch (attr)
3633                        {
3634                        case DW_AT_const_value:
3635                            got_value = true;
3636                            enum_value = form_value.Unsigned();
3637                            break;
3638
3639                        case DW_AT_name:
3640                            name = form_value.AsCString(&get_debug_str_data());
3641                            break;
3642
3643                        case DW_AT_description:
3644                        default:
3645                        case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3646                        case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3647                        case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3648                        case DW_AT_sibling:
3649                            break;
3650                        }
3651                    }
3652                }
3653
3654                if (name && name[0] && got_value)
3655                {
3656                    GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
3657                                                                               enumerator_clang_type,
3658                                                                               decl,
3659                                                                               name,
3660                                                                               enum_value,
3661                                                                               enumerator_byte_size * 8);
3662                    ++enumerators_added;
3663                }
3664            }
3665        }
3666    }
3667    return enumerators_added;
3668}
3669
3670void
3671SymbolFileDWARF::ParseChildArrayInfo
3672(
3673    const SymbolContext& sc,
3674    DWARFCompileUnit* dwarf_cu,
3675    const DWARFDebugInfoEntry *parent_die,
3676    int64_t& first_index,
3677    std::vector<uint64_t>& element_orders,
3678    uint32_t& byte_stride,
3679    uint32_t& bit_stride
3680)
3681{
3682    if (parent_die == NULL)
3683        return;
3684
3685    const DWARFDebugInfoEntry *die;
3686    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
3687    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
3688    {
3689        const dw_tag_t tag = die->Tag();
3690        switch (tag)
3691        {
3692        case DW_TAG_enumerator:
3693            {
3694                DWARFDebugInfoEntry::Attributes attributes;
3695                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
3696                if (num_child_attributes > 0)
3697                {
3698                    const char *name = NULL;
3699                    bool got_value = false;
3700                    int64_t enum_value = 0;
3701
3702                    uint32_t i;
3703                    for (i=0; i<num_child_attributes; ++i)
3704                    {
3705                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
3706                        DWARFFormValue form_value;
3707                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3708                        {
3709                            switch (attr)
3710                            {
3711                            case DW_AT_const_value:
3712                                got_value = true;
3713                                enum_value = form_value.Unsigned();
3714                                break;
3715
3716                            case DW_AT_name:
3717                                name = form_value.AsCString(&get_debug_str_data());
3718                                break;
3719
3720                            case DW_AT_description:
3721                            default:
3722                            case DW_AT_decl_file:
3723                            case DW_AT_decl_line:
3724                            case DW_AT_decl_column:
3725                            case DW_AT_sibling:
3726                                break;
3727                            }
3728                        }
3729                    }
3730                }
3731            }
3732            break;
3733
3734        case DW_TAG_subrange_type:
3735            {
3736                DWARFDebugInfoEntry::Attributes attributes;
3737                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
3738                if (num_child_attributes > 0)
3739                {
3740                    const char *name = NULL;
3741                    bool got_value = false;
3742                    uint64_t byte_size = 0;
3743                    int64_t enum_value = 0;
3744                    uint64_t num_elements = 0;
3745                    uint64_t lower_bound = 0;
3746                    uint64_t upper_bound = 0;
3747                    uint32_t i;
3748                    for (i=0; i<num_child_attributes; ++i)
3749                    {
3750                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
3751                        DWARFFormValue form_value;
3752                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3753                        {
3754                            switch (attr)
3755                            {
3756                            case DW_AT_const_value:
3757                                got_value = true;
3758                                enum_value = form_value.Unsigned();
3759                                break;
3760
3761                            case DW_AT_name:
3762                                name = form_value.AsCString(&get_debug_str_data());
3763                                break;
3764
3765                            case DW_AT_count:
3766                                num_elements = form_value.Unsigned();
3767                                break;
3768
3769                            case DW_AT_bit_stride:
3770                                bit_stride = form_value.Unsigned();
3771                                break;
3772
3773                            case DW_AT_byte_stride:
3774                                byte_stride = form_value.Unsigned();
3775                                break;
3776
3777                            case DW_AT_byte_size:
3778                                byte_size = form_value.Unsigned();
3779                                break;
3780
3781                            case DW_AT_lower_bound:
3782                                lower_bound = form_value.Unsigned();
3783                                break;
3784
3785                            case DW_AT_upper_bound:
3786                                upper_bound = form_value.Unsigned();
3787                                break;
3788
3789                            default:
3790                            case DW_AT_abstract_origin:
3791                            case DW_AT_accessibility:
3792                            case DW_AT_allocated:
3793                            case DW_AT_associated:
3794                            case DW_AT_data_location:
3795                            case DW_AT_declaration:
3796                            case DW_AT_description:
3797                            case DW_AT_sibling:
3798                            case DW_AT_threads_scaled:
3799                            case DW_AT_type:
3800                            case DW_AT_visibility:
3801                                break;
3802                            }
3803                        }
3804                    }
3805
3806                    if (upper_bound > lower_bound)
3807                        num_elements = upper_bound - lower_bound + 1;
3808
3809                    if (num_elements > 0)
3810                        element_orders.push_back (num_elements);
3811                }
3812            }
3813            break;
3814        }
3815    }
3816}
3817
3818TypeSP
3819SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
3820{
3821    TypeSP type_sp;
3822    if (die != NULL)
3823    {
3824        assert(curr_cu != NULL);
3825        Type *type_ptr = m_die_to_type.lookup (die);
3826        if (type_ptr == NULL)
3827        {
3828            CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(curr_cu);
3829            assert (lldb_cu);
3830            SymbolContext sc(lldb_cu);
3831            type_sp = ParseType(sc, curr_cu, die, NULL);
3832        }
3833        else if (type_ptr != DIE_IS_BEING_PARSED)
3834        {
3835            // Grab the existing type from the master types lists
3836            type_sp = type_ptr->shared_from_this();
3837        }
3838
3839    }
3840    return type_sp;
3841}
3842
3843clang::DeclContext *
3844SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
3845{
3846    if (die_offset != DW_INVALID_OFFSET)
3847    {
3848        DWARFCompileUnitSP cu_sp;
3849        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
3850        return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
3851    }
3852    return NULL;
3853}
3854
3855clang::DeclContext *
3856SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
3857{
3858    if (die_offset != DW_INVALID_OFFSET)
3859    {
3860        DWARFDebugInfo* debug_info = DebugInfo();
3861        if (debug_info)
3862        {
3863            DWARFCompileUnitSP cu_sp;
3864            const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
3865            if (die)
3866                return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
3867        }
3868    }
3869    return NULL;
3870}
3871
3872clang::NamespaceDecl *
3873SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
3874{
3875    if (die && die->Tag() == DW_TAG_namespace)
3876    {
3877        // See if we already parsed this namespace DIE and associated it with a
3878        // uniqued namespace declaration
3879        clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
3880        if (namespace_decl)
3881            return namespace_decl;
3882        else
3883        {
3884            const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
3885            clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (curr_cu, die, NULL);
3886            namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
3887            LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
3888            if (log)
3889            {
3890                if (namespace_name)
3891                {
3892                    GetObjectFile()->GetModule()->LogMessage (log.get(),
3893                                                              "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
3894                                                              GetClangASTContext().getASTContext(),
3895                                                              MakeUserID(die->GetOffset()),
3896                                                              namespace_name,
3897                                                              namespace_decl,
3898                                                              namespace_decl->getOriginalNamespace());
3899                }
3900                else
3901                {
3902                    GetObjectFile()->GetModule()->LogMessage (log.get(),
3903                                                              "ASTContext => %p: 0x%8.8llx: DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
3904                                                              GetClangASTContext().getASTContext(),
3905                                                              MakeUserID(die->GetOffset()),
3906                                                              namespace_decl,
3907                                                              namespace_decl->getOriginalNamespace());
3908                }
3909            }
3910
3911            if (namespace_decl)
3912                LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
3913            return namespace_decl;
3914        }
3915    }
3916    return NULL;
3917}
3918
3919clang::DeclContext *
3920SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
3921{
3922    clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3923    if (clang_decl_ctx)
3924        return clang_decl_ctx;
3925    // If this DIE has a specification, or an abstract origin, then trace to those.
3926
3927    dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
3928    if (die_offset != DW_INVALID_OFFSET)
3929        return GetClangDeclContextForDIEOffset (sc, die_offset);
3930
3931    die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
3932    if (die_offset != DW_INVALID_OFFSET)
3933        return GetClangDeclContextForDIEOffset (sc, die_offset);
3934
3935    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
3936    if (log)
3937        GetObjectFile()->GetModule()->LogMessage(log.get(), "SymbolFileDWARF::GetClangDeclContextForDIE (die = 0x%8.8x) %s '%s'", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, cu));
3938    // This is the DIE we want.  Parse it, then query our map.
3939    bool assert_not_being_parsed = true;
3940    ResolveTypeUID (cu, die, assert_not_being_parsed);
3941
3942    clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
3943
3944    return clang_decl_ctx;
3945}
3946
3947clang::DeclContext *
3948SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy)
3949{
3950    if (m_clang_tu_decl == NULL)
3951        m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
3952
3953    const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
3954
3955    if (decl_ctx_die_copy)
3956        *decl_ctx_die_copy = decl_ctx_die;
3957
3958    if (decl_ctx_die)
3959    {
3960
3961        DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
3962        if (pos != m_die_to_decl_ctx.end())
3963            return pos->second;
3964
3965        switch (decl_ctx_die->Tag())
3966        {
3967        case DW_TAG_compile_unit:
3968            return m_clang_tu_decl;
3969
3970        case DW_TAG_namespace:
3971            return ResolveNamespaceDIE (cu, decl_ctx_die);
3972            break;
3973
3974        case DW_TAG_structure_type:
3975        case DW_TAG_union_type:
3976        case DW_TAG_class_type:
3977            {
3978                Type* type = ResolveType (cu, decl_ctx_die);
3979                if (type)
3980                {
3981                    clang::DeclContext *decl_ctx = ClangASTContext::GetDeclContextForType (type->GetClangForwardType ());
3982                    if (decl_ctx)
3983                    {
3984                        LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
3985                        if (decl_ctx)
3986                            return decl_ctx;
3987                    }
3988                }
3989            }
3990            break;
3991
3992        default:
3993            break;
3994        }
3995    }
3996    return m_clang_tu_decl;
3997}
3998
3999
4000const DWARFDebugInfoEntry *
4001SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
4002{
4003    if (cu && die)
4004    {
4005        const DWARFDebugInfoEntry * const decl_die = die;
4006
4007        while (die != NULL)
4008        {
4009            // If this is the original DIE that we are searching for a declaration
4010            // for, then don't look in the cache as we don't want our own decl
4011            // context to be our decl context...
4012            if (decl_die != die)
4013            {
4014                switch (die->Tag())
4015                {
4016                    case DW_TAG_compile_unit:
4017                    case DW_TAG_namespace:
4018                    case DW_TAG_structure_type:
4019                    case DW_TAG_union_type:
4020                    case DW_TAG_class_type:
4021                        return die;
4022
4023                    default:
4024                        break;
4025                }
4026            }
4027
4028            dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
4029            if (die_offset != DW_INVALID_OFFSET)
4030            {
4031                DWARFCompileUnit *spec_cu = cu;
4032                const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
4033                const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
4034                if (spec_die_decl_ctx_die)
4035                    return spec_die_decl_ctx_die;
4036            }
4037
4038            die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
4039            if (die_offset != DW_INVALID_OFFSET)
4040            {
4041                DWARFCompileUnit *abs_cu = cu;
4042                const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
4043                const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
4044                if (abs_die_decl_ctx_die)
4045                    return abs_die_decl_ctx_die;
4046            }
4047
4048            die = die->GetParent();
4049        }
4050    }
4051    return NULL;
4052}
4053
4054
4055Symbol *
4056SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
4057{
4058    Symbol *objc_class_symbol = NULL;
4059    if (m_obj_file)
4060    {
4061        Symtab *symtab = m_obj_file->GetSymtab();
4062        if (symtab)
4063        {
4064            objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name,
4065                                                                        eSymbolTypeObjCClass,
4066                                                                        Symtab::eDebugNo,
4067                                                                        Symtab::eVisibilityAny);
4068        }
4069    }
4070    return objc_class_symbol;
4071}
4072
4073// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
4074// then we can end up looking through all class types for a complete type and never find
4075// the full definition. We need to know if this attribute is supported, so we determine
4076// this here and cache th result. We also need to worry about the debug map DWARF file
4077// if we are doing darwin DWARF in .o file debugging.
4078bool
4079SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
4080{
4081    if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
4082    {
4083        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
4084        if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
4085            m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
4086        else
4087        {
4088            DWARFDebugInfo* debug_info = DebugInfo();
4089            const uint32_t num_compile_units = GetNumCompileUnits();
4090            for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
4091            {
4092                DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
4093                if (curr_cu != cu && curr_cu->Supports_DW_AT_APPLE_objc_complete_type())
4094                {
4095                    m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
4096                    break;
4097                }
4098            }
4099        }
4100        if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && m_debug_map_symfile)
4101            return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
4102    }
4103    return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
4104}
4105
4106// This function can be used when a DIE is found that is a forward declaration
4107// DIE and we want to try and find a type that has the complete definition.
4108TypeSP
4109SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die,
4110                                                       const ConstString &type_name,
4111                                                       bool must_be_implementation)
4112{
4113
4114    TypeSP type_sp;
4115
4116    if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
4117        return type_sp;
4118
4119    DIEArray die_offsets;
4120
4121    if (m_using_apple_tables)
4122    {
4123        if (m_apple_types_ap.get())
4124        {
4125            const char *name_cstr = type_name.GetCString();
4126            m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
4127        }
4128    }
4129    else
4130    {
4131        if (!m_indexed)
4132            Index ();
4133
4134        m_type_index.Find (type_name, die_offsets);
4135    }
4136
4137    const size_t num_matches = die_offsets.size();
4138
4139    DWARFCompileUnit* type_cu = NULL;
4140    const DWARFDebugInfoEntry* type_die = NULL;
4141    if (num_matches)
4142    {
4143        DWARFDebugInfo* debug_info = DebugInfo();
4144        for (size_t i=0; i<num_matches; ++i)
4145        {
4146            const dw_offset_t die_offset = die_offsets[i];
4147            type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
4148
4149            if (type_die)
4150            {
4151                bool try_resolving_type = false;
4152
4153                // Don't try and resolve the DIE we are looking for with the DIE itself!
4154                if (type_die != die)
4155                {
4156                    switch (type_die->Tag())
4157                    {
4158                        case DW_TAG_class_type:
4159                        case DW_TAG_structure_type:
4160                            try_resolving_type = true;
4161                            break;
4162                        default:
4163                            break;
4164                    }
4165                }
4166
4167                if (try_resolving_type)
4168                {
4169					if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type())
4170	                    try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0);
4171
4172                    if (try_resolving_type)
4173                    {
4174                        Type *resolved_type = ResolveType (type_cu, type_die, false);
4175                        if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
4176                        {
4177                            DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
4178                                          MakeUserID(die->GetOffset()),
4179                                          MakeUserID(curr_cu->GetOffset()),
4180                                          m_obj_file->GetFileSpec().GetFilename().AsCString(),
4181                                          MakeUserID(type_die->GetOffset()),
4182                                          MakeUserID(type_cu->GetOffset()));
4183
4184                            if (die)
4185                                m_die_to_type[die] = resolved_type;
4186                            type_sp = resolved_type->shared_from_this();
4187                            break;
4188                        }
4189                    }
4190                }
4191            }
4192            else
4193            {
4194                if (m_using_apple_tables)
4195                {
4196                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
4197                                                               die_offset, type_name.GetCString());
4198                }
4199            }
4200
4201        }
4202    }
4203    return type_sp;
4204}
4205
4206//----------------------------------------------------------------------
4207// This function helps to ensure that the declaration contexts match for
4208// two different DIEs. Often times debug information will refer to a
4209// forward declaration of a type (the equivalent of "struct my_struct;".
4210// There will often be a declaration of that type elsewhere that has the
4211// full definition. When we go looking for the full type "my_struct", we
4212// will find one or more matches in the accelerator tables and we will
4213// then need to make sure the type was in the same declaration context
4214// as the original DIE. This function can efficiently compare two DIEs
4215// and will return true when the declaration context matches, and false
4216// when they don't.
4217//----------------------------------------------------------------------
4218bool
4219SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1,
4220                                       DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2)
4221{
4222    assert (die1 != die2);
4223    DWARFDIECollection decl_ctx_1;
4224    DWARFDIECollection decl_ctx_2;
4225    //The declaration DIE stack is a stack of the declaration context
4226    // DIEs all the way back to the compile unit. If a type "T" is
4227    // declared inside a class "B", and class "B" is declared inside
4228    // a class "A" and class "A" is in a namespace "lldb", and the
4229    // namespace is in a compile unit, there will be a stack of DIEs:
4230    //
4231    //   [0] DW_TAG_class_type for "B"
4232    //   [1] DW_TAG_class_type for "A"
4233    //   [2] DW_TAG_namespace  for "lldb"
4234    //   [3] DW_TAG_compile_unit for the source file.
4235    //
4236    // We grab both contexts and make sure that everything matches
4237    // all the way back to the compiler unit.
4238
4239    // First lets grab the decl contexts for both DIEs
4240    die1->GetDeclContextDIEs (this, cu1, decl_ctx_1);
4241    die2->GetDeclContextDIEs (this, cu2, decl_ctx_2);
4242    // Make sure the context arrays have the same size, otherwise
4243    // we are done
4244    const size_t count1 = decl_ctx_1.Size();
4245    const size_t count2 = decl_ctx_2.Size();
4246    if (count1 != count2)
4247        return false;
4248
4249    // Make sure the DW_TAG values match all the way back up the the
4250    // compile unit. If they don't, then we are done.
4251    const DWARFDebugInfoEntry *decl_ctx_die1;
4252    const DWARFDebugInfoEntry *decl_ctx_die2;
4253    size_t i;
4254    for (i=0; i<count1; i++)
4255    {
4256        decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
4257        decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
4258        if (decl_ctx_die1->Tag() != decl_ctx_die2->Tag())
4259            return false;
4260    }
4261#if defined LLDB_CONFIGURATION_DEBUG
4262
4263    // Make sure the top item in the decl context die array is always
4264    // DW_TAG_compile_unit. If it isn't then something went wrong in
4265    // the DWARFDebugInfoEntry::GetDeclContextDIEs() function...
4266    assert (decl_ctx_1.GetDIEPtrAtIndex (count1 - 1)->Tag() == DW_TAG_compile_unit);
4267
4268#endif
4269    // Always skip the compile unit when comparing by only iterating up to
4270    // "count - 1". Here we compare the names as we go.
4271    for (i=0; i<count1 - 1; i++)
4272    {
4273        decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
4274        decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
4275        const char *name1 = decl_ctx_die1->GetName(this, cu1);
4276        const char *name2 = decl_ctx_die2->GetName(this, cu2);
4277        // If the string was from a DW_FORM_strp, then the pointer will often
4278        // be the same!
4279        if (name1 == name2)
4280            continue;
4281
4282        // Name pointers are not equal, so only compare the strings
4283        // if both are not NULL.
4284        if (name1 && name2)
4285        {
4286            // If the strings don't compare, we are done...
4287            if (strcmp(name1, name2) != 0)
4288                return false;
4289        }
4290        else
4291        {
4292            // One name was NULL while the other wasn't
4293            return false;
4294        }
4295    }
4296    // We made it through all of the checks and the declaration contexts
4297    // are equal.
4298    return true;
4299}
4300
4301// This function can be used when a DIE is found that is a forward declaration
4302// DIE and we want to try and find a type that has the complete definition.
4303TypeSP
4304SymbolFileDWARF::FindDefinitionTypeForDIE (DWARFCompileUnit* cu,
4305                                           const DWARFDebugInfoEntry *die,
4306                                           const ConstString &type_name)
4307{
4308    TypeSP type_sp;
4309
4310    if (cu == NULL || die == NULL || !type_name)
4311        return type_sp;
4312
4313    DIEArray die_offsets;
4314
4315    if (m_using_apple_tables)
4316    {
4317        if (m_apple_types_ap.get())
4318        {
4319            if (m_apple_types_ap->GetHeader().header_data.atoms.size() > 1)
4320            {
4321                m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), die->Tag(), die_offsets);
4322            }
4323            else
4324            {
4325                m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
4326            }
4327        }
4328    }
4329    else
4330    {
4331        if (!m_indexed)
4332            Index ();
4333
4334        m_type_index.Find (type_name, die_offsets);
4335    }
4336
4337    const size_t num_matches = die_offsets.size();
4338
4339    const dw_tag_t die_tag = die->Tag();
4340
4341    DWARFCompileUnit* type_cu = NULL;
4342    const DWARFDebugInfoEntry* type_die = NULL;
4343    if (num_matches)
4344    {
4345        DWARFDebugInfo* debug_info = DebugInfo();
4346        for (size_t i=0; i<num_matches; ++i)
4347        {
4348            const dw_offset_t die_offset = die_offsets[i];
4349            type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
4350
4351            if (type_die)
4352            {
4353                bool try_resolving_type = false;
4354
4355                // Don't try and resolve the DIE we are looking for with the DIE itself!
4356                if (type_die != die)
4357                {
4358                    const dw_tag_t type_die_tag = type_die->Tag();
4359                    // Make sure the tags match
4360                    if (type_die_tag == die_tag)
4361                    {
4362                        // The tags match, lets try resolving this type
4363                        try_resolving_type = true;
4364                    }
4365                    else
4366                    {
4367                        // The tags don't match, but we need to watch our for a
4368                        // forward declaration for a struct and ("struct foo")
4369                        // ends up being a class ("class foo { ... };") or
4370                        // vice versa.
4371                        switch (type_die_tag)
4372                        {
4373                        case DW_TAG_class_type:
4374                            // We had a "class foo", see if we ended up with a "struct foo { ... };"
4375                            try_resolving_type = (die_tag == DW_TAG_structure_type);
4376                            break;
4377                        case DW_TAG_structure_type:
4378                            // We had a "struct foo", see if we ended up with a "class foo { ... };"
4379                            try_resolving_type = (die_tag == DW_TAG_class_type);
4380                            break;
4381                        default:
4382                            // Tags don't match, don't event try to resolve
4383                            // using this type whose name matches....
4384                            break;
4385                        }
4386                    }
4387                }
4388
4389                if (try_resolving_type)
4390                {
4391                    // Make sure the decl contexts match all the way up
4392                    if (DIEDeclContextsMatch(cu, die, type_cu, type_die))
4393                    {
4394                        Type *resolved_type = ResolveType (type_cu, type_die, false);
4395                        if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
4396                        {
4397                            DEBUG_PRINTF ("resolved 0x%8.8llx (cu 0x%8.8llx) from %s to 0x%8.8llx (cu 0x%8.8llx)\n",
4398                                          MakeUserID(die->GetOffset()),
4399                                          MakeUserID(curr_cu->GetOffset()),
4400                                          m_obj_file->GetFileSpec().GetFilename().AsCString(),
4401                                          MakeUserID(type_die->GetOffset()),
4402                                          MakeUserID(type_cu->GetOffset()));
4403
4404                            m_die_to_type[die] = resolved_type;
4405                            type_sp = resolved_type->shared_from_this();
4406                            break;
4407                        }
4408                    }
4409                }
4410            }
4411            else
4412            {
4413                if (m_using_apple_tables)
4414                {
4415                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
4416                                                                               die_offset, type_name.GetCString());
4417                }
4418            }
4419
4420        }
4421    }
4422    return type_sp;
4423}
4424
4425TypeSP
4426SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
4427{
4428    TypeSP type_sp;
4429
4430    if (type_is_new_ptr)
4431        *type_is_new_ptr = false;
4432
4433#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE)
4434    static DIEStack g_die_stack;
4435    DIEStack::ScopedPopper scoped_die_logger(g_die_stack);
4436#endif
4437
4438    AccessType accessibility = eAccessNone;
4439    if (die != NULL)
4440    {
4441        LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
4442        if (log)
4443        {
4444            const DWARFDebugInfoEntry *context_die;
4445            clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die);
4446
4447            GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
4448                        die->GetOffset(),
4449                        context,
4450                        context_die->GetOffset(),
4451                        DW_TAG_value_to_name(die->Tag()),
4452                        die->GetName(this, dwarf_cu));
4453
4454#if defined(LLDB_CONFIGURATION_DEBUG) or defined(LLDB_CONFIGURATION_RELEASE)
4455            scoped_die_logger.Push (dwarf_cu, die);
4456            g_die_stack.LogDIEs(log.get(), this);
4457#endif
4458        }
4459//
4460//        LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
4461//        if (log && dwarf_cu)
4462//        {
4463//            StreamString s;
4464//            die->DumpLocation (this, dwarf_cu, s);
4465//            GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
4466//
4467//        }
4468
4469        Type *type_ptr = m_die_to_type.lookup (die);
4470        TypeList* type_list = GetTypeList();
4471        if (type_ptr == NULL)
4472        {
4473            ClangASTContext &ast = GetClangASTContext();
4474            if (type_is_new_ptr)
4475                *type_is_new_ptr = true;
4476
4477            const dw_tag_t tag = die->Tag();
4478
4479            bool is_forward_declaration = false;
4480            DWARFDebugInfoEntry::Attributes attributes;
4481            const char *type_name_cstr = NULL;
4482            ConstString type_name_const_str;
4483            Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
4484            size_t byte_size = 0;
4485            bool byte_size_valid = false;
4486            Declaration decl;
4487
4488            Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
4489            clang_type_t clang_type = NULL;
4490
4491            dw_attr_t attr;
4492
4493            switch (tag)
4494            {
4495            case DW_TAG_base_type:
4496            case DW_TAG_pointer_type:
4497            case DW_TAG_reference_type:
4498            case DW_TAG_typedef:
4499            case DW_TAG_const_type:
4500            case DW_TAG_restrict_type:
4501            case DW_TAG_volatile_type:
4502            case DW_TAG_unspecified_type:
4503                {
4504                    // Set a bit that lets us know that we are currently parsing this
4505                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
4506
4507                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
4508                    uint32_t encoding = 0;
4509                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
4510
4511                    if (num_attributes > 0)
4512                    {
4513                        uint32_t i;
4514                        for (i=0; i<num_attributes; ++i)
4515                        {
4516                            attr = attributes.AttributeAtIndex(i);
4517                            DWARFFormValue form_value;
4518                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4519                            {
4520                                switch (attr)
4521                                {
4522                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
4523                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
4524                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
4525                                case DW_AT_name:
4526
4527                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
4528                                    // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
4529                                    // include the "&"...
4530                                    if (tag == DW_TAG_reference_type)
4531                                    {
4532                                        if (strchr (type_name_cstr, '&') == NULL)
4533                                            type_name_cstr = NULL;
4534                                    }
4535                                    if (type_name_cstr)
4536                                        type_name_const_str.SetCString(type_name_cstr);
4537                                    break;
4538                                case DW_AT_byte_size:   byte_size = form_value.Unsigned();  byte_size_valid = true; break;
4539                                case DW_AT_encoding:    encoding = form_value.Unsigned(); break;
4540                                case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
4541                                default:
4542                                case DW_AT_sibling:
4543                                    break;
4544                                }
4545                            }
4546                        }
4547                    }
4548
4549                    DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\") type => 0x%8.8x\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
4550
4551                    switch (tag)
4552                    {
4553                    default:
4554                        break;
4555
4556                    case DW_TAG_unspecified_type:
4557                        if (strcmp(type_name_cstr, "nullptr_t") == 0)
4558                        {
4559                            resolve_state = Type::eResolveStateFull;
4560                            clang_type = ast.getASTContext()->NullPtrTy.getAsOpaquePtr();
4561                            break;
4562                        }
4563                        // Fall through to base type below in case we can handle the type there...
4564
4565                    case DW_TAG_base_type:
4566                        resolve_state = Type::eResolveStateFull;
4567                        clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
4568                                                                                   encoding,
4569                                                                                   byte_size * 8);
4570                        break;
4571
4572                    case DW_TAG_pointer_type:   encoding_data_type = Type::eEncodingIsPointerUID;           break;
4573                    case DW_TAG_reference_type: encoding_data_type = Type::eEncodingIsLValueReferenceUID;   break;
4574                    case DW_TAG_typedef:        encoding_data_type = Type::eEncodingIsTypedefUID;           break;
4575                    case DW_TAG_const_type:     encoding_data_type = Type::eEncodingIsConstUID;             break;
4576                    case DW_TAG_restrict_type:  encoding_data_type = Type::eEncodingIsRestrictUID;          break;
4577                    case DW_TAG_volatile_type:  encoding_data_type = Type::eEncodingIsVolatileUID;          break;
4578                    }
4579
4580                    if (clang_type == NULL && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID))
4581                    {
4582                        if (type_name_cstr != NULL && sc.comp_unit != NULL &&
4583                            (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
4584                        {
4585                            static ConstString g_objc_type_name_id("id");
4586                            static ConstString g_objc_type_name_Class("Class");
4587                            static ConstString g_objc_type_name_selector("SEL");
4588
4589                            if (type_name_const_str == g_objc_type_name_id)
4590                            {
4591                                if (log)
4592                                    GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
4593                                                                              die->GetOffset(),
4594                                                                              DW_TAG_value_to_name(die->Tag()),
4595                                                                              die->GetName(this, dwarf_cu));
4596                                clang_type = ast.GetBuiltInType_objc_id();
4597                                encoding_data_type = Type::eEncodingIsUID;
4598                                encoding_uid = LLDB_INVALID_UID;
4599                                resolve_state = Type::eResolveStateFull;
4600
4601                            }
4602                            else if (type_name_const_str == g_objc_type_name_Class)
4603                            {
4604                                if (log)
4605                                    GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
4606                                                                              die->GetOffset(),
4607                                                                              DW_TAG_value_to_name(die->Tag()),
4608                                                                              die->GetName(this, dwarf_cu));
4609                                clang_type = ast.GetBuiltInType_objc_Class();
4610                                encoding_data_type = Type::eEncodingIsUID;
4611                                encoding_uid = LLDB_INVALID_UID;
4612                                resolve_state = Type::eResolveStateFull;
4613                            }
4614                            else if (type_name_const_str == g_objc_type_name_selector)
4615                            {
4616                                if (log)
4617                                    GetObjectFile()->GetModule()->LogMessage (log.get(), "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
4618                                                                              die->GetOffset(),
4619                                                                              DW_TAG_value_to_name(die->Tag()),
4620                                                                              die->GetName(this, dwarf_cu));
4621                                clang_type = ast.GetBuiltInType_objc_selector();
4622                                encoding_data_type = Type::eEncodingIsUID;
4623                                encoding_uid = LLDB_INVALID_UID;
4624                                resolve_state = Type::eResolveStateFull;
4625                            }
4626                        }
4627                    }
4628
4629                    type_sp.reset( new Type (MakeUserID(die->GetOffset()),
4630                                             this,
4631                                             type_name_const_str,
4632                                             byte_size,
4633                                             NULL,
4634                                             encoding_uid,
4635                                             encoding_data_type,
4636                                             &decl,
4637                                             clang_type,
4638                                             resolve_state));
4639
4640                    m_die_to_type[die] = type_sp.get();
4641
4642//                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
4643//                  if (encoding_type != NULL)
4644//                  {
4645//                      if (encoding_type != DIE_IS_BEING_PARSED)
4646//                          type_sp->SetEncodingType(encoding_type);
4647//                      else
4648//                          m_indirect_fixups.push_back(type_sp.get());
4649//                  }
4650                }
4651                break;
4652
4653            case DW_TAG_structure_type:
4654            case DW_TAG_union_type:
4655            case DW_TAG_class_type:
4656                {
4657                    // Set a bit that lets us know that we are currently parsing this
4658                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
4659
4660                    LanguageType class_language = eLanguageTypeUnknown;
4661                    bool is_complete_objc_class = false;
4662                    //bool struct_is_class = false;
4663                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
4664                    if (num_attributes > 0)
4665                    {
4666                        uint32_t i;
4667                        for (i=0; i<num_attributes; ++i)
4668                        {
4669                            attr = attributes.AttributeAtIndex(i);
4670                            DWARFFormValue form_value;
4671                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
4672                            {
4673                                switch (attr)
4674                                {
4675                                case DW_AT_decl_file:
4676                                    if (dwarf_cu->DW_AT_decl_file_attributes_are_invalid())
4677									{
4678										// llvm-gcc outputs invalid DW_AT_decl_file attributes that always
4679										// point to the compile unit file, so we clear this invalid value
4680										// so that we can still unique types efficiently.
4681                                        decl.SetFile(FileSpec ("<invalid>", false));
4682									}
4683                                    else
4684                                        decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
4685                                    break;
4686
4687                                case DW_AT_decl_line:
4688                                    decl.SetLine(form_value.Unsigned());
4689                                    break;
4690
4691                                case DW_AT_decl_column:
4692                                    decl.SetColumn(form_value.Unsigned());
4693                                    break;
4694
4695                                case DW_AT_name:
4696                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
4697                                    type_name_const_str.SetCString(type_name_cstr);
4698                                    break;
4699
4700                                case DW_AT_byte_size:
4701                                    byte_size = form_value.Unsigned();
4702                                    byte_size_valid = true;
4703                                    break;
4704
4705                                case DW_AT_accessibility:
4706                                    accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
4707                                    break;
4708
4709                                case DW_AT_declaration:
4710                                    is_forward_declaration = form_value.Unsigned() != 0;
4711                                    break;
4712
4713                                case DW_AT_APPLE_runtime_class:
4714                                    class_language = (LanguageType)form_value.Signed();
4715                                    break;
4716
4717                                case DW_AT_APPLE_objc_complete_type:
4718                                    is_complete_objc_class = form_value.Signed();
4719                                    break;
4720
4721                                case DW_AT_allocated:
4722                                case DW_AT_associated:
4723                                case DW_AT_data_location:
4724                                case DW_AT_description:
4725                                case DW_AT_start_scope:
4726                                case DW_AT_visibility:
4727                                default:
4728                                case DW_AT_sibling:
4729                                    break;
4730                                }
4731                            }
4732                        }
4733                    }
4734
4735                    UniqueDWARFASTType unique_ast_entry;
4736
4737                    if (GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
4738                                                         this,
4739                                                         dwarf_cu,
4740                                                         die,
4741                                                         decl,
4742                                                         byte_size_valid ? byte_size : -1,
4743                                                         unique_ast_entry))
4744                    {
4745                        // We have already parsed this type or from another
4746                        // compile unit. GCC loves to use the "one definition
4747                        // rule" which can result in multiple definitions
4748                        // of the same class over and over in each compile
4749                        // unit.
4750                        type_sp = unique_ast_entry.m_type_sp;
4751                        if (type_sp)
4752                        {
4753                            m_die_to_type[die] = type_sp.get();
4754                            return type_sp;
4755                        }
4756                    }
4757
4758                    DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
4759
4760                    int tag_decl_kind = -1;
4761                    AccessType default_accessibility = eAccessNone;
4762                    if (tag == DW_TAG_structure_type)
4763                    {
4764                        tag_decl_kind = clang::TTK_Struct;
4765                        default_accessibility = eAccessPublic;
4766                    }
4767                    else if (tag == DW_TAG_union_type)
4768                    {
4769                        tag_decl_kind = clang::TTK_Union;
4770                        default_accessibility = eAccessPublic;
4771                    }
4772                    else if (tag == DW_TAG_class_type)
4773                    {
4774                        tag_decl_kind = clang::TTK_Class;
4775                        default_accessibility = eAccessPrivate;
4776                    }
4777
4778                    if (byte_size_valid && byte_size == 0 && type_name_cstr &&
4779                        die->HasChildren() == false &&
4780                        sc.comp_unit->GetLanguage() == eLanguageTypeObjC)
4781                    {
4782                        // Work around an issue with clang at the moment where
4783                        // forward declarations for objective C classes are emitted
4784                        // as:
4785                        //  DW_TAG_structure_type [2]
4786                        //  DW_AT_name( "ForwardObjcClass" )
4787                        //  DW_AT_byte_size( 0x00 )
4788                        //  DW_AT_decl_file( "..." )
4789                        //  DW_AT_decl_line( 1 )
4790                        //
4791                        // Note that there is no DW_AT_declaration and there are
4792                        // no children, and the byte size is zero.
4793                        is_forward_declaration = true;
4794                    }
4795
4796                    if (class_language == eLanguageTypeObjC)
4797                    {
4798                        if (!is_complete_objc_class && Supports_DW_AT_APPLE_objc_complete_type(dwarf_cu))
4799                        {
4800                            // We have a valid eSymbolTypeObjCClass class symbol whose
4801                            // name matches the current objective C class that we
4802                            // are trying to find and this DIE isn't the complete
4803                            // definition (we checked is_complete_objc_class above and
4804                            // know it is false), so the real definition is in here somewhere
4805                            type_sp = FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
4806
4807                            if (!type_sp && m_debug_map_symfile)
4808                            {
4809                                // We weren't able to find a full declaration in
4810                                // this DWARF, see if we have a declaration anywhere
4811                                // else...
4812                                type_sp = m_debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
4813                            }
4814
4815                            if (type_sp)
4816                            {
4817                                if (log)
4818                                {
4819                                    GetObjectFile()->GetModule()->LogMessage (log.get(),
4820                                                                              "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8llx",
4821                                                                              this,
4822                                                                              die->GetOffset(),
4823                                                                              DW_TAG_value_to_name(tag),
4824                                                                              type_name_cstr,
4825                                                                              type_sp->GetID());
4826                                }
4827
4828                                // We found a real definition for this type elsewhere
4829                                // so lets use it and cache the fact that we found
4830                                // a complete type for this die
4831                                m_die_to_type[die] = type_sp.get();
4832                                return type_sp;
4833                            }
4834                        }
4835                    }
4836
4837
4838                    if (is_forward_declaration)
4839                    {
4840                        // We have a forward declaration to a type and we need
4841                        // to try and find a full declaration. We look in the
4842                        // current type index just in case we have a forward
4843                        // declaration followed by an actual declarations in the
4844                        // DWARF. If this fails, we need to look elsewhere...
4845                        if (log)
4846                        {
4847                            GetObjectFile()->GetModule()->LogMessage (log.get(),
4848                                                                      "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type",
4849                                                                      this,
4850                                                                      die->GetOffset(),
4851                                                                      DW_TAG_value_to_name(tag),
4852                                                                      type_name_cstr);
4853                        }
4854
4855                        type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
4856
4857                        if (!type_sp && m_debug_map_symfile)
4858                        {
4859                            // We weren't able to find a full declaration in
4860                            // this DWARF, see if we have a declaration anywhere
4861                            // else...
4862                            type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
4863                        }
4864
4865                        if (type_sp)
4866                        {
4867                            if (log)
4868                            {
4869                                GetObjectFile()->GetModule()->LogMessage (log.get(),
4870                                                                          "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8llx",
4871                                                                          this,
4872                                                                          die->GetOffset(),
4873                                                                          DW_TAG_value_to_name(tag),
4874                                                                          type_name_cstr,
4875                                                                          type_sp->GetID());
4876                            }
4877
4878                            // We found a real definition for this type elsewhere
4879                            // so lets use it and cache the fact that we found
4880                            // a complete type for this die
4881                            m_die_to_type[die] = type_sp.get();
4882                            return type_sp;
4883                        }
4884                    }
4885                    assert (tag_decl_kind != -1);
4886                    bool clang_type_was_created = false;
4887                    clang_type = m_forward_decl_die_to_clang_type.lookup (die);
4888                    if (clang_type == NULL)
4889                    {
4890                        const DWARFDebugInfoEntry *decl_ctx_die;
4891
4892                        clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
4893                        if (accessibility == eAccessNone && decl_ctx)
4894                        {
4895                            // Check the decl context that contains this class/struct/union.
4896                            // If it is a class we must give it an accessability.
4897                            const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
4898                            if (DeclKindIsCXXClass (containing_decl_kind))
4899                                accessibility = default_accessibility;
4900                        }
4901
4902                        if (type_name_cstr && strchr (type_name_cstr, '<'))
4903                        {
4904                            ClangASTContext::TemplateParameterInfos template_param_infos;
4905                            if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos))
4906                            {
4907                                clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx,
4908                                                                                                        accessibility,
4909                                                                                                        type_name_cstr,
4910                                                                                                        tag_decl_kind,
4911                                                                                                        template_param_infos);
4912
4913                                clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx,
4914                                                                                                                                               class_template_decl,
4915                                                                                                                                               tag_decl_kind,
4916                                                                                                                                               template_param_infos);
4917                                clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
4918                                clang_type_was_created = true;
4919                            }
4920                        }
4921
4922                        if (!clang_type_was_created)
4923                        {
4924                            clang_type_was_created = true;
4925                            clang_type = ast.CreateRecordType (decl_ctx,
4926                                                               accessibility,
4927                                                               type_name_cstr,
4928                                                               tag_decl_kind,
4929                                                               class_language);
4930                        }
4931                    }
4932
4933                    // Store a forward declaration to this class type in case any
4934                    // parameters in any class methods need it for the clang
4935                    // types for function prototypes.
4936                    LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
4937                    type_sp.reset (new Type (MakeUserID(die->GetOffset()),
4938                                             this,
4939                                             type_name_const_str,
4940                                             byte_size,
4941                                             NULL,
4942                                             LLDB_INVALID_UID,
4943                                             Type::eEncodingIsUID,
4944                                             &decl,
4945                                             clang_type,
4946                                             Type::eResolveStateForward));
4947
4948
4949                    // Add our type to the unique type map so we don't
4950                    // end up creating many copies of the same type over
4951                    // and over in the ASTContext for our module
4952                    unique_ast_entry.m_type_sp = type_sp;
4953                    unique_ast_entry.m_symfile = this;
4954                    unique_ast_entry.m_cu = dwarf_cu;
4955                    unique_ast_entry.m_die = die;
4956                    unique_ast_entry.m_declaration = decl;
4957                    GetUniqueDWARFASTTypeMap().Insert (type_name_const_str,
4958                                                       unique_ast_entry);
4959
4960                    if (!is_forward_declaration)
4961                    {
4962                        if (die->HasChildren() == false)
4963                        {
4964                            // No children for this struct/union/class, lets finish it
4965                            ast.StartTagDeclarationDefinition (clang_type);
4966                            ast.CompleteTagDeclarationDefinition (clang_type);
4967                        }
4968                        else if (clang_type_was_created)
4969                        {
4970                            // Leave this as a forward declaration until we need
4971                            // to know the details of the type. lldb_private::Type
4972                            // will automatically call the SymbolFile virtual function
4973                            // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
4974                            // When the definition needs to be defined.
4975                            m_forward_decl_die_to_clang_type[die] = clang_type;
4976                            m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
4977                            ClangASTContext::SetHasExternalStorage (clang_type, true);
4978                        }
4979                    }
4980
4981                }
4982                break;
4983
4984            case DW_TAG_enumeration_type:
4985                {
4986                    // Set a bit that lets us know that we are currently parsing this
4987                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
4988
4989                    lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
4990
4991                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
4992                    if (num_attributes > 0)
4993                    {
4994                        uint32_t i;
4995
4996                        for (i=0; i<num_attributes; ++i)
4997                        {
4998                            attr = attributes.AttributeAtIndex(i);
4999                            DWARFFormValue form_value;
5000                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
5001                            {
5002                                switch (attr)
5003                                {
5004                                case DW_AT_decl_file:       decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
5005                                case DW_AT_decl_line:       decl.SetLine(form_value.Unsigned()); break;
5006                                case DW_AT_decl_column:     decl.SetColumn(form_value.Unsigned()); break;
5007                                case DW_AT_name:
5008                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
5009                                    type_name_const_str.SetCString(type_name_cstr);
5010                                    break;
5011                                case DW_AT_type:            encoding_uid = form_value.Reference(dwarf_cu); break;
5012                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); byte_size_valid = true; break;
5013                                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
5014                                case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
5015                                case DW_AT_allocated:
5016                                case DW_AT_associated:
5017                                case DW_AT_bit_stride:
5018                                case DW_AT_byte_stride:
5019                                case DW_AT_data_location:
5020                                case DW_AT_description:
5021                                case DW_AT_start_scope:
5022                                case DW_AT_visibility:
5023                                case DW_AT_specification:
5024                                case DW_AT_abstract_origin:
5025                                case DW_AT_sibling:
5026                                    break;
5027                                }
5028                            }
5029                        }
5030
5031                        DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
5032
5033                        clang_type_t enumerator_clang_type = NULL;
5034                        clang_type = m_forward_decl_die_to_clang_type.lookup (die);
5035                        if (clang_type == NULL)
5036                        {
5037                            enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
5038                                                                                                  DW_ATE_signed,
5039                                                                                                  byte_size * 8);
5040                            clang_type = ast.CreateEnumerationType (type_name_cstr,
5041                                                                    GetClangDeclContextContainingDIE (dwarf_cu, die, NULL),
5042                                                                    decl,
5043                                                                    enumerator_clang_type);
5044                        }
5045                        else
5046                        {
5047                            enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
5048                            assert (enumerator_clang_type != NULL);
5049                        }
5050
5051                        LinkDeclContextToDIE(ClangASTContext::GetDeclContextForType(clang_type), die);
5052
5053                        type_sp.reset( new Type (MakeUserID(die->GetOffset()),
5054                                                 this,
5055                                                 type_name_const_str,
5056                                                 byte_size,
5057                                                 NULL,
5058                                                 encoding_uid,
5059                                                 Type::eEncodingIsUID,
5060                                                 &decl,
5061                                                 clang_type,
5062                                                 Type::eResolveStateForward));
5063
5064                        ast.StartTagDeclarationDefinition (clang_type);
5065                        if (die->HasChildren())
5066                        {
5067                            SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
5068                            ParseChildEnumerators(cu_sc, clang_type, type_sp->GetByteSize(), dwarf_cu, die);
5069                        }
5070                        ast.CompleteTagDeclarationDefinition (clang_type);
5071                    }
5072                }
5073                break;
5074
5075            case DW_TAG_inlined_subroutine:
5076            case DW_TAG_subprogram:
5077            case DW_TAG_subroutine_type:
5078                {
5079                    // Set a bit that lets us know that we are currently parsing this
5080                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
5081
5082                    const char *mangled = NULL;
5083                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
5084                    bool is_variadic = false;
5085                    bool is_inline = false;
5086                    bool is_static = false;
5087                    bool is_virtual = false;
5088                    bool is_explicit = false;
5089                    bool is_artificial = false;
5090                    dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
5091                    dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
5092
5093                    unsigned type_quals = 0;
5094                    clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
5095
5096
5097                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
5098                    if (num_attributes > 0)
5099                    {
5100                        uint32_t i;
5101                        for (i=0; i<num_attributes; ++i)
5102                        {
5103                            attr = attributes.AttributeAtIndex(i);
5104                            DWARFFormValue form_value;
5105                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
5106                            {
5107                                switch (attr)
5108                                {
5109                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
5110                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
5111                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
5112                                case DW_AT_name:
5113                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
5114                                    type_name_const_str.SetCString(type_name_cstr);
5115                                    break;
5116
5117                                case DW_AT_MIPS_linkage_name:   mangled = form_value.AsCString(&get_debug_str_data()); break;
5118                                case DW_AT_type:                type_die_offset = form_value.Reference(dwarf_cu); break;
5119                                case DW_AT_accessibility:       accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
5120                                case DW_AT_declaration:         is_forward_declaration = form_value.Unsigned() != 0; break;
5121                                case DW_AT_inline:              is_inline = form_value.Unsigned() != 0; break;
5122                                case DW_AT_virtuality:          is_virtual = form_value.Unsigned() != 0;  break;
5123                                case DW_AT_explicit:            is_explicit = form_value.Unsigned() != 0;  break;
5124                                case DW_AT_artificial:          is_artificial = form_value.Unsigned() != 0;  break;
5125
5126
5127                                case DW_AT_external:
5128                                    if (form_value.Unsigned())
5129                                    {
5130                                        if (storage == clang::SC_None)
5131                                            storage = clang::SC_Extern;
5132                                        else
5133                                            storage = clang::SC_PrivateExtern;
5134                                    }
5135                                    break;
5136
5137                                case DW_AT_specification:
5138                                    specification_die_offset = form_value.Reference(dwarf_cu);
5139                                    break;
5140
5141                                case DW_AT_abstract_origin:
5142                                    abstract_origin_die_offset = form_value.Reference(dwarf_cu);
5143                                    break;
5144
5145                                case DW_AT_allocated:
5146                                case DW_AT_associated:
5147                                case DW_AT_address_class:
5148                                case DW_AT_calling_convention:
5149                                case DW_AT_data_location:
5150                                case DW_AT_elemental:
5151                                case DW_AT_entry_pc:
5152                                case DW_AT_frame_base:
5153                                case DW_AT_high_pc:
5154                                case DW_AT_low_pc:
5155                                case DW_AT_object_pointer:
5156                                case DW_AT_prototyped:
5157                                case DW_AT_pure:
5158                                case DW_AT_ranges:
5159                                case DW_AT_recursive:
5160                                case DW_AT_return_addr:
5161                                case DW_AT_segment:
5162                                case DW_AT_start_scope:
5163                                case DW_AT_static_link:
5164                                case DW_AT_trampoline:
5165                                case DW_AT_visibility:
5166                                case DW_AT_vtable_elem_location:
5167                                case DW_AT_description:
5168                                case DW_AT_sibling:
5169                                    break;
5170                                }
5171                            }
5172                        }
5173                    }
5174
5175                    DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
5176
5177                    clang_type_t return_clang_type = NULL;
5178                    Type *func_type = NULL;
5179
5180                    if (type_die_offset != DW_INVALID_OFFSET)
5181                        func_type = ResolveTypeUID(type_die_offset);
5182
5183                    if (func_type)
5184                        return_clang_type = func_type->GetClangForwardType();
5185                    else
5186                        return_clang_type = ast.GetBuiltInType_void();
5187
5188
5189                    std::vector<clang_type_t> function_param_types;
5190                    std::vector<clang::ParmVarDecl*> function_param_decls;
5191
5192                    // Parse the function children for the parameters
5193
5194                    const DWARFDebugInfoEntry *decl_ctx_die = NULL;
5195                    clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
5196                    const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();
5197
5198                    const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
5199                    // Start off static. This will be set to false in ParseChildParameters(...)
5200                    // if we find a "this" paramters as the first parameter
5201                    if (is_cxx_method)
5202                        is_static = true;
5203                    ClangASTContext::TemplateParameterInfos template_param_infos;
5204
5205                    if (die->HasChildren())
5206                    {
5207                        bool skip_artificial = true;
5208                        ParseChildParameters (sc,
5209                                              containing_decl_ctx,
5210                                              dwarf_cu,
5211                                              die,
5212                                              skip_artificial,
5213                                              is_static,
5214                                              type_list,
5215                                              function_param_types,
5216                                              function_param_decls,
5217                                              type_quals,
5218                                              template_param_infos);
5219                    }
5220
5221                    // clang_type will get the function prototype clang type after this call
5222                    clang_type = ast.CreateFunctionType (return_clang_type,
5223                                                         &function_param_types[0],
5224                                                         function_param_types.size(),
5225                                                         is_variadic,
5226                                                         type_quals);
5227
5228                    if (type_name_cstr)
5229                    {
5230                        bool type_handled = false;
5231                        if (tag == DW_TAG_subprogram)
5232                        {
5233                            ConstString class_name;
5234                            ConstString class_name_no_category;
5235                            if (ObjCLanguageRuntime::ParseMethodName (type_name_cstr, &class_name, NULL, NULL, &class_name_no_category))
5236                            {
5237                                // Use the class name with no category if there is one
5238                                if (class_name_no_category)
5239                                    class_name = class_name_no_category;
5240
5241                                SymbolContext empty_sc;
5242                                clang_type_t class_opaque_type = NULL;
5243                                if (class_name)
5244                                {
5245                                    TypeList types;
5246                                    TypeSP complete_objc_class_type_sp (FindCompleteObjCDefinitionTypeForDIE (NULL, class_name, false));
5247
5248                                    if (complete_objc_class_type_sp)
5249                                    {
5250                                        clang_type_t type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
5251                                        if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
5252                                            class_opaque_type = type_clang_forward_type;
5253                                    }
5254                                }
5255
5256                                if (class_opaque_type)
5257                                {
5258                                    // If accessibility isn't set to anything valid, assume public for
5259                                    // now...
5260                                    if (accessibility == eAccessNone)
5261                                        accessibility = eAccessPublic;
5262
5263                                    clang::ObjCMethodDecl *objc_method_decl;
5264                                    objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
5265                                                                                      type_name_cstr,
5266                                                                                      clang_type,
5267                                                                                      accessibility);
5268                                    LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
5269                                    type_handled = objc_method_decl != NULL;
5270                                }
5271                            }
5272                            else if (is_cxx_method)
5273                            {
5274                                // Look at the parent of this DIE and see if is is
5275                                // a class or struct and see if this is actually a
5276                                // C++ method
5277                                Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
5278                                if (class_type)
5279                                {
5280                                    if (specification_die_offset != DW_INVALID_OFFSET)
5281                                    {
5282                                        // We have a specification which we are going to base our function
5283                                        // prototype off of, so we need this type to be completed so that the
5284                                        // m_die_to_decl_ctx for the method in the specification has a valid
5285                                        // clang decl context.
5286                                        class_type->GetClangForwardType();
5287                                        // If we have a specification, then the function type should have been
5288                                        // made with the specification and not with this die.
5289                                        DWARFCompileUnitSP spec_cu_sp;
5290                                        const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
5291                                        clang::DeclContext *spec_clang_decl_ctx = GetCachedClangDeclContextForDIE (spec_die);
5292                                        if (spec_clang_decl_ctx)
5293                                        {
5294                                            LinkDeclContextToDIE(spec_clang_decl_ctx, die);
5295                                        }
5296                                        else
5297                                        {
5298                                            GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_specification(0x%8.8x) has no decl\n",
5299                                                                                         MakeUserID(die->GetOffset()),
5300                                                                                         specification_die_offset);
5301                                        }
5302                                        type_handled = true;
5303                                    }
5304                                    else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
5305                                    {
5306                                        // We have a specification which we are going to base our function
5307                                        // prototype off of, so we need this type to be completed so that the
5308                                        // m_die_to_decl_ctx for the method in the abstract origin has a valid
5309                                        // clang decl context.
5310                                        class_type->GetClangForwardType();
5311
5312                                        DWARFCompileUnitSP abs_cu_sp;
5313                                        const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
5314                                        clang::DeclContext *abs_clang_decl_ctx = GetCachedClangDeclContextForDIE (abs_die);
5315                                        if (abs_clang_decl_ctx)
5316                                        {
5317                                            LinkDeclContextToDIE (abs_clang_decl_ctx, die);
5318                                        }
5319                                        else
5320                                        {
5321                                            GetObjectFile()->GetModule()->ReportWarning ("0x%8.8llx: DW_AT_abstract_origin(0x%8.8x) has no decl\n",
5322                                                                                         MakeUserID(die->GetOffset()),
5323                                                                                         abstract_origin_die_offset);
5324                                        }
5325                                        type_handled = true;
5326                                    }
5327                                    else
5328                                    {
5329                                        clang_type_t class_opaque_type = class_type->GetClangForwardType();
5330                                        if (ClangASTContext::IsCXXClassType (class_opaque_type))
5331                                        {
5332                                            if (ClangASTContext::IsBeingDefined (class_opaque_type))
5333                                            {
5334                                                // Neither GCC 4.2 nor clang++ currently set a valid accessibility
5335                                                // in the DWARF for C++ methods... Default to public for now...
5336                                                if (accessibility == eAccessNone)
5337                                                    accessibility = eAccessPublic;
5338
5339                                                if (!is_static && !die->HasChildren())
5340                                                {
5341                                                    // We have a C++ member function with no children (this pointer!)
5342                                                    // and clang will get mad if we try and make a function that isn't
5343                                                    // well formed in the DWARF, so we will just skip it...
5344                                                    type_handled = true;
5345                                                }
5346                                                else
5347                                                {
5348                                                    clang::CXXMethodDecl *cxx_method_decl;
5349                                                    // REMOVE THE CRASH DESCRIPTION BELOW
5350                                                    Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8llx from %s/%s",
5351                                                                                         type_name_cstr,
5352                                                                                         class_type->GetName().GetCString(),
5353                                                                                         MakeUserID(die->GetOffset()),
5354                                                                                         m_obj_file->GetFileSpec().GetDirectory().GetCString(),
5355                                                                                         m_obj_file->GetFileSpec().GetFilename().GetCString());
5356
5357                                                    const bool is_attr_used = false;
5358
5359                                                    cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
5360                                                                                                    type_name_cstr,
5361                                                                                                    clang_type,
5362                                                                                                    accessibility,
5363                                                                                                    is_virtual,
5364                                                                                                    is_static,
5365                                                                                                    is_inline,
5366                                                                                                    is_explicit,
5367                                                                                                    is_attr_used,
5368                                                                                                    is_artificial);
5369                                                    LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);
5370
5371                                                    Host::SetCrashDescription (NULL);
5372
5373                                                    type_handled = cxx_method_decl != NULL;
5374                                                }
5375                                            }
5376                                            else
5377                                            {
5378                                                // We were asked to parse the type for a method in a class, yet the
5379                                                // class hasn't been asked to complete itself through the
5380                                                // clang::ExternalASTSource protocol, so we need to just have the
5381                                                // class complete itself and do things the right way, then our
5382                                                // DIE should then have an entry in the m_die_to_type map. First
5383                                                // we need to modify the m_die_to_type so it doesn't think we are
5384                                                // trying to parse this DIE anymore...
5385                                                m_die_to_type[die] = NULL;
5386
5387                                                // Now we get the full type to force our class type to complete itself
5388                                                // using the clang::ExternalASTSource protocol which will parse all
5389                                                // base classes and all methods (including the method for this DIE).
5390                                                class_type->GetClangFullType();
5391
5392                                                // The type for this DIE should have been filled in the function call above
5393                                                type_ptr = m_die_to_type[die];
5394                                                if (type_ptr)
5395                                                {
5396                                                    type_sp = type_ptr->shared_from_this();
5397                                                    break;
5398                                                }
5399                                            }
5400                                        }
5401                                    }
5402                                }
5403                            }
5404                        }
5405
5406                        if (!type_handled)
5407                        {
5408                            // We just have a function that isn't part of a class
5409                            clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (containing_decl_ctx,
5410                                                                                                type_name_cstr,
5411                                                                                                clang_type,
5412                                                                                                storage,
5413                                                                                                is_inline);
5414
5415//                            if (template_param_infos.GetSize() > 0)
5416//                            {
5417//                                clang::FunctionTemplateDecl *func_template_decl = ast.CreateFunctionTemplateDecl (containing_decl_ctx,
5418//                                                                                                                  function_decl,
5419//                                                                                                                  type_name_cstr,
5420//                                                                                                                  template_param_infos);
5421//
5422//                                ast.CreateFunctionTemplateSpecializationInfo (function_decl,
5423//                                                                              func_template_decl,
5424//                                                                              template_param_infos);
5425//                            }
5426                            // Add the decl to our DIE to decl context map
5427                            assert (function_decl);
5428                            LinkDeclContextToDIE(function_decl, die);
5429                            if (!function_param_decls.empty())
5430                                ast.SetFunctionParameters (function_decl,
5431                                                           &function_param_decls.front(),
5432                                                           function_param_decls.size());
5433                        }
5434                    }
5435                    type_sp.reset( new Type (MakeUserID(die->GetOffset()),
5436                                             this,
5437                                             type_name_const_str,
5438                                             0,
5439                                             NULL,
5440                                             LLDB_INVALID_UID,
5441                                             Type::eEncodingIsUID,
5442                                             &decl,
5443                                             clang_type,
5444                                             Type::eResolveStateFull));
5445                    assert(type_sp.get());
5446                }
5447                break;
5448
5449            case DW_TAG_array_type:
5450                {
5451                    // Set a bit that lets us know that we are currently parsing this
5452                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
5453
5454                    lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
5455                    int64_t first_index = 0;
5456                    uint32_t byte_stride = 0;
5457                    uint32_t bit_stride = 0;
5458                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
5459
5460                    if (num_attributes > 0)
5461                    {
5462                        uint32_t i;
5463                        for (i=0; i<num_attributes; ++i)
5464                        {
5465                            attr = attributes.AttributeAtIndex(i);
5466                            DWARFFormValue form_value;
5467                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
5468                            {
5469                                switch (attr)
5470                                {
5471                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
5472                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
5473                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
5474                                case DW_AT_name:
5475                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
5476                                    type_name_const_str.SetCString(type_name_cstr);
5477                                    break;
5478
5479                                case DW_AT_type:            type_die_offset = form_value.Reference(dwarf_cu); break;
5480                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); byte_size_valid = true; break;
5481                                case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break;
5482                                case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break;
5483                                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
5484                                case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
5485                                case DW_AT_allocated:
5486                                case DW_AT_associated:
5487                                case DW_AT_data_location:
5488                                case DW_AT_description:
5489                                case DW_AT_ordering:
5490                                case DW_AT_start_scope:
5491                                case DW_AT_visibility:
5492                                case DW_AT_specification:
5493                                case DW_AT_abstract_origin:
5494                                case DW_AT_sibling:
5495                                    break;
5496                                }
5497                            }
5498                        }
5499
5500                        DEBUG_PRINTF ("0x%8.8llx: %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);
5501
5502                        Type *element_type = ResolveTypeUID(type_die_offset);
5503
5504                        if (element_type)
5505                        {
5506                            std::vector<uint64_t> element_orders;
5507                            ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
5508                            // We have an array that claims to have no members, lets give it at least one member...
5509                            if (element_orders.empty())
5510                                element_orders.push_back (1);
5511                            if (byte_stride == 0 && bit_stride == 0)
5512                                byte_stride = element_type->GetByteSize();
5513                            clang_type_t array_element_type = element_type->GetClangForwardType();
5514                            uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
5515                            uint64_t num_elements = 0;
5516                            std::vector<uint64_t>::const_reverse_iterator pos;
5517                            std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
5518                            for (pos = element_orders.rbegin(); pos != end; ++pos)
5519                            {
5520                                num_elements = *pos;
5521                                clang_type = ast.CreateArrayType (array_element_type,
5522                                                                  num_elements,
5523                                                                  num_elements * array_element_bit_stride);
5524                                array_element_type = clang_type;
5525                                array_element_bit_stride = array_element_bit_stride * num_elements;
5526                            }
5527                            ConstString empty_name;
5528                            type_sp.reset( new Type (MakeUserID(die->GetOffset()),
5529                                                     this,
5530                                                     empty_name,
5531                                                     array_element_bit_stride / 8,
5532                                                     NULL,
5533                                                     type_die_offset,
5534                                                     Type::eEncodingIsUID,
5535                                                     &decl,
5536                                                     clang_type,
5537                                                     Type::eResolveStateFull));
5538                            type_sp->SetEncodingType (element_type);
5539                        }
5540                    }
5541                }
5542                break;
5543
5544            case DW_TAG_ptr_to_member_type:
5545                {
5546                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
5547                    dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
5548
5549                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
5550
5551                    if (num_attributes > 0) {
5552                        uint32_t i;
5553                        for (i=0; i<num_attributes; ++i)
5554                        {
5555                            attr = attributes.AttributeAtIndex(i);
5556                            DWARFFormValue form_value;
5557                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
5558                            {
5559                                switch (attr)
5560                                {
5561                                    case DW_AT_type:
5562                                        type_die_offset = form_value.Reference(dwarf_cu); break;
5563                                    case DW_AT_containing_type:
5564                                        containing_type_die_offset = form_value.Reference(dwarf_cu); break;
5565                                }
5566                            }
5567                        }
5568
5569                        Type *pointee_type = ResolveTypeUID(type_die_offset);
5570                        Type *class_type = ResolveTypeUID(containing_type_die_offset);
5571
5572                        clang_type_t pointee_clang_type = pointee_type->GetClangForwardType();
5573                        clang_type_t class_clang_type = class_type->GetClangLayoutType();
5574
5575                        clang_type = ast.CreateMemberPointerType(pointee_clang_type,
5576                                                                 class_clang_type);
5577
5578                        byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
5579                                                                       clang_type) / 8;
5580
5581                        type_sp.reset( new Type (MakeUserID(die->GetOffset()),
5582                                                 this,
5583                                                 type_name_const_str,
5584                                                 byte_size,
5585                                                 NULL,
5586                                                 LLDB_INVALID_UID,
5587                                                 Type::eEncodingIsUID,
5588                                                 NULL,
5589                                                 clang_type,
5590                                                 Type::eResolveStateForward));
5591                    }
5592
5593                    break;
5594                }
5595            default:
5596                assert(false && "Unhandled type tag!");
5597                break;
5598            }
5599
5600            if (type_sp.get())
5601            {
5602                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
5603                dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
5604
5605                SymbolContextScope * symbol_context_scope = NULL;
5606                if (sc_parent_tag == DW_TAG_compile_unit)
5607                {
5608                    symbol_context_scope = sc.comp_unit;
5609                }
5610                else if (sc.function != NULL)
5611                {
5612                    symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
5613                    if (symbol_context_scope == NULL)
5614                        symbol_context_scope = sc.function;
5615                }
5616
5617                if (symbol_context_scope != NULL)
5618                {
5619                    type_sp->SetSymbolContextScope(symbol_context_scope);
5620                }
5621
5622                // We are ready to put this type into the uniqued list up at the module level
5623                type_list->Insert (type_sp);
5624
5625                m_die_to_type[die] = type_sp.get();
5626            }
5627        }
5628        else if (type_ptr != DIE_IS_BEING_PARSED)
5629        {
5630            type_sp = type_ptr->shared_from_this();
5631        }
5632    }
5633    return type_sp;
5634}
5635
5636size_t
5637SymbolFileDWARF::ParseTypes
5638(
5639    const SymbolContext& sc,
5640    DWARFCompileUnit* dwarf_cu,
5641    const DWARFDebugInfoEntry *die,
5642    bool parse_siblings,
5643    bool parse_children
5644)
5645{
5646    size_t types_added = 0;
5647    while (die != NULL)
5648    {
5649        bool type_is_new = false;
5650        if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
5651        {
5652            if (type_is_new)
5653                ++types_added;
5654        }
5655
5656        if (parse_children && die->HasChildren())
5657        {
5658            if (die->Tag() == DW_TAG_subprogram)
5659            {
5660                SymbolContext child_sc(sc);
5661                child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get();
5662                types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
5663            }
5664            else
5665                types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
5666        }
5667
5668        if (parse_siblings)
5669            die = die->GetSibling();
5670        else
5671            die = NULL;
5672    }
5673    return types_added;
5674}
5675
5676
5677size_t
5678SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
5679{
5680    assert(sc.comp_unit && sc.function);
5681    size_t functions_added = 0;
5682    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
5683    if (dwarf_cu)
5684    {
5685        dw_offset_t function_die_offset = sc.function->GetID();
5686        const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
5687        if (function_die)
5688        {
5689            ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
5690        }
5691    }
5692
5693    return functions_added;
5694}
5695
5696
5697size_t
5698SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
5699{
5700    // At least a compile unit must be valid
5701    assert(sc.comp_unit);
5702    size_t types_added = 0;
5703    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
5704    if (dwarf_cu)
5705    {
5706        if (sc.function)
5707        {
5708            dw_offset_t function_die_offset = sc.function->GetID();
5709            const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
5710            if (func_die && func_die->HasChildren())
5711            {
5712                types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
5713            }
5714        }
5715        else
5716        {
5717            const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
5718            if (dwarf_cu_die && dwarf_cu_die->HasChildren())
5719            {
5720                types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
5721            }
5722        }
5723    }
5724
5725    return types_added;
5726}
5727
5728size_t
5729SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
5730{
5731    if (sc.comp_unit != NULL)
5732    {
5733        DWARFDebugInfo* info = DebugInfo();
5734        if (info == NULL)
5735            return 0;
5736
5737        uint32_t cu_idx = UINT32_MAX;
5738        DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
5739
5740        if (dwarf_cu == NULL)
5741            return 0;
5742
5743        if (sc.function)
5744        {
5745            const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
5746
5747            dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
5748            if (func_lo_pc != DW_INVALID_ADDRESS)
5749            {
5750                const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
5751
5752                // Let all blocks know they have parse all their variables
5753                sc.function->GetBlock (false).SetDidParseVariables (true, true);
5754                return num_variables;
5755            }
5756        }
5757        else if (sc.comp_unit)
5758        {
5759            uint32_t vars_added = 0;
5760            VariableListSP variables (sc.comp_unit->GetVariableList(false));
5761
5762            if (variables.get() == NULL)
5763            {
5764                variables.reset(new VariableList());
5765                sc.comp_unit->SetVariableList(variables);
5766
5767                DWARFCompileUnit* match_dwarf_cu = NULL;
5768                const DWARFDebugInfoEntry* die = NULL;
5769                DIEArray die_offsets;
5770                if (m_using_apple_tables)
5771                {
5772                    if (m_apple_names_ap.get())
5773                    {
5774                        DWARFMappedHash::DIEInfoArray hash_data_array;
5775                        if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(),
5776                                                                    dwarf_cu->GetNextCompileUnitOffset(),
5777                                                                    hash_data_array))
5778                        {
5779                            DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
5780                        }
5781                    }
5782                }
5783                else
5784                {
5785                    // Index if we already haven't to make sure the compile units
5786                    // get indexed and make their global DIE index list
5787                    if (!m_indexed)
5788                        Index ();
5789
5790                    m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(),
5791                                                                 dwarf_cu->GetNextCompileUnitOffset(),
5792                                                                 die_offsets);
5793                }
5794
5795                const size_t num_matches = die_offsets.size();
5796                if (num_matches)
5797                {
5798                    DWARFDebugInfo* debug_info = DebugInfo();
5799                    for (size_t i=0; i<num_matches; ++i)
5800                    {
5801                        const dw_offset_t die_offset = die_offsets[i];
5802                        die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
5803                        if (die)
5804                        {
5805                            VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
5806                            if (var_sp)
5807                            {
5808                                variables->AddVariableIfUnique (var_sp);
5809                                ++vars_added;
5810                            }
5811                        }
5812                        else
5813                        {
5814                            if (m_using_apple_tables)
5815                            {
5816                                GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_offset);
5817                            }
5818                        }
5819
5820                    }
5821                }
5822            }
5823            return vars_added;
5824        }
5825    }
5826    return 0;
5827}
5828
5829
5830VariableSP
5831SymbolFileDWARF::ParseVariableDIE
5832(
5833    const SymbolContext& sc,
5834    DWARFCompileUnit* dwarf_cu,
5835    const DWARFDebugInfoEntry *die,
5836    const lldb::addr_t func_low_pc
5837)
5838{
5839
5840    VariableSP var_sp (m_die_to_variable_sp[die]);
5841    if (var_sp)
5842        return var_sp;  // Already been parsed!
5843
5844    const dw_tag_t tag = die->Tag();
5845
5846    if ((tag == DW_TAG_variable) ||
5847        (tag == DW_TAG_constant) ||
5848        (tag == DW_TAG_formal_parameter && sc.function))
5849    {
5850        DWARFDebugInfoEntry::Attributes attributes;
5851        const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
5852        if (num_attributes > 0)
5853        {
5854            const char *name = NULL;
5855            const char *mangled = NULL;
5856            Declaration decl;
5857            uint32_t i;
5858            lldb::user_id_t type_uid = LLDB_INVALID_UID;
5859            DWARFExpression location;
5860            bool is_external = false;
5861            bool is_artificial = false;
5862            bool location_is_const_value_data = false;
5863            AccessType accessibility = eAccessNone;
5864
5865            for (i=0; i<num_attributes; ++i)
5866            {
5867                dw_attr_t attr = attributes.AttributeAtIndex(i);
5868                DWARFFormValue form_value;
5869                if (attributes.ExtractFormValueAtIndex(this, i, form_value))
5870                {
5871                    switch (attr)
5872                    {
5873                    case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
5874                    case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
5875                    case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
5876                    case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
5877                    case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
5878                    case DW_AT_type:        type_uid = form_value.Reference(dwarf_cu); break;
5879                    case DW_AT_external:    is_external = form_value.Unsigned() != 0; break;
5880                    case DW_AT_const_value:
5881                        location_is_const_value_data = true;
5882                        // Fall through...
5883                    case DW_AT_location:
5884                        {
5885                            if (form_value.BlockData())
5886                            {
5887                                const DataExtractor& debug_info_data = get_debug_info_data();
5888
5889                                uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
5890                                uint32_t block_length = form_value.Unsigned();
5891                                location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
5892                            }
5893                            else
5894                            {
5895                                const DataExtractor&    debug_loc_data = get_debug_loc_data();
5896                                const dw_offset_t debug_loc_offset = form_value.Unsigned();
5897
5898                                size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
5899                                if (loc_list_length > 0)
5900                                {
5901                                    location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
5902                                    assert (func_low_pc != LLDB_INVALID_ADDRESS);
5903                                    location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
5904                                }
5905                            }
5906                        }
5907                        break;
5908
5909                    case DW_AT_artificial:      is_artificial = form_value.Unsigned() != 0; break;
5910                    case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
5911                    case DW_AT_declaration:
5912                    case DW_AT_description:
5913                    case DW_AT_endianity:
5914                    case DW_AT_segment:
5915                    case DW_AT_start_scope:
5916                    case DW_AT_visibility:
5917                    default:
5918                    case DW_AT_abstract_origin:
5919                    case DW_AT_sibling:
5920                    case DW_AT_specification:
5921                        break;
5922                    }
5923                }
5924            }
5925
5926            if (location.IsValid())
5927            {
5928                ValueType scope = eValueTypeInvalid;
5929
5930                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
5931                dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
5932                SymbolContextScope * symbol_context_scope = NULL;
5933
5934                // DWARF doesn't specify if a DW_TAG_variable is a local, global
5935                // or static variable, so we have to do a little digging by
5936                // looking at the location of a varaible to see if it contains
5937                // a DW_OP_addr opcode _somewhere_ in the definition. I say
5938                // somewhere because clang likes to combine small global variables
5939                // into the same symbol and have locations like:
5940                // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
5941                // So if we don't have a DW_TAG_formal_parameter, we can look at
5942                // the location to see if it contains a DW_OP_addr opcode, and
5943                // then we can correctly classify  our variables.
5944                if (tag == DW_TAG_formal_parameter)
5945                    scope = eValueTypeVariableArgument;
5946                else
5947                {
5948                    bool op_error = false;
5949                    // Check if the location has a DW_OP_addr with any address value...
5950                    addr_t location_has_op_addr = false;
5951                    if (!location_is_const_value_data)
5952                    {
5953                        location_has_op_addr = location.LocationContains_DW_OP_addr (LLDB_INVALID_ADDRESS, op_error);
5954                        if (op_error)
5955                        {
5956                            StreamString strm;
5957                            location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
5958                            GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str());
5959                        }
5960                    }
5961
5962                    if (location_has_op_addr)
5963                    {
5964                        if (is_external)
5965                        {
5966                            scope = eValueTypeVariableGlobal;
5967
5968                            if (m_debug_map_symfile)
5969                            {
5970                                // When leaving the DWARF in the .o files on darwin,
5971                                // when we have a global variable that wasn't initialized,
5972                                // the .o file might not have allocated a virtual
5973                                // address for the global variable. In this case it will
5974                                // have created a symbol for the global variable
5975                                // that is undefined and external and the value will
5976                                // be the byte size of the variable. When we do the
5977                                // address map in SymbolFileDWARFDebugMap we rely on
5978                                // having an address, we need to do some magic here
5979                                // so we can get the correct address for our global
5980                                // variable. The address for all of these entries
5981                                // will be zero, and there will be an undefined symbol
5982                                // in this object file, and the executable will have
5983                                // a matching symbol with a good address. So here we
5984                                // dig up the correct address and replace it in the
5985                                // location for the variable, and set the variable's
5986                                // symbol context scope to be that of the main executable
5987                                // so the file address will resolve correctly.
5988                                if (location.LocationContains_DW_OP_addr (0, op_error))
5989                                {
5990
5991                                    // we have a possible uninitialized extern global
5992                                    Symtab *symtab = m_obj_file->GetSymtab();
5993                                    if (symtab)
5994                                    {
5995                                        ConstString const_name(name);
5996                                        Symbol *undefined_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
5997                                                                                                           eSymbolTypeUndefined,
5998                                                                                                           Symtab::eDebugNo,
5999                                                                                                           Symtab::eVisibilityExtern);
6000
6001                                        if (undefined_symbol)
6002                                        {
6003                                            ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
6004                                            if (debug_map_objfile)
6005                                            {
6006                                                Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
6007                                                Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
6008                                                                                                                           eSymbolTypeData,
6009                                                                                                                           Symtab::eDebugYes,
6010                                                                                                                           Symtab::eVisibilityExtern);
6011                                                if (defined_symbol)
6012                                                {
6013                                                    const AddressRange *defined_range = defined_symbol->GetAddressRangePtr();
6014                                                    if (defined_range)
6015                                                    {
6016                                                        const addr_t defined_addr = defined_range->GetBaseAddress().GetFileAddress();
6017                                                        if (defined_addr != LLDB_INVALID_ADDRESS)
6018                                                        {
6019                                                            if (location.Update_DW_OP_addr (defined_addr))
6020                                                            {
6021                                                                symbol_context_scope = defined_symbol;
6022                                                            }
6023                                                        }
6024                                                    }
6025                                                }
6026                                            }
6027                                        }
6028                                    }
6029                                }
6030                            }
6031                        }
6032                        else
6033                        {
6034                            scope = eValueTypeVariableStatic;
6035                        }
6036                    }
6037                    else
6038                    {
6039                        scope = eValueTypeVariableLocal;
6040                    }
6041                }
6042
6043                if (symbol_context_scope == NULL)
6044                {
6045                    switch (parent_tag)
6046                    {
6047                    case DW_TAG_subprogram:
6048                    case DW_TAG_inlined_subroutine:
6049                    case DW_TAG_lexical_block:
6050                        if (sc.function)
6051                        {
6052                            symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
6053                            if (symbol_context_scope == NULL)
6054                                symbol_context_scope = sc.function;
6055                        }
6056                        break;
6057
6058                    default:
6059                        symbol_context_scope = sc.comp_unit;
6060                        break;
6061                    }
6062                }
6063
6064                if (symbol_context_scope)
6065                {
6066                    var_sp.reset (new Variable (MakeUserID(die->GetOffset()),
6067                                                name,
6068                                                mangled,
6069                                                SymbolFileTypeSP (new SymbolFileType(*this, type_uid)),
6070                                                scope,
6071                                                symbol_context_scope,
6072                                                &decl,
6073                                                location,
6074                                                is_external,
6075                                                is_artificial));
6076
6077                    var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
6078                }
6079                else
6080                {
6081                    // Not ready to parse this variable yet. It might be a global
6082                    // or static variable that is in a function scope and the function
6083                    // in the symbol context wasn't filled in yet
6084                    return var_sp;
6085                }
6086            }
6087        }
6088        // Cache var_sp even if NULL (the variable was just a specification or
6089        // was missing vital information to be able to be displayed in the debugger
6090        // (missing location due to optimization, etc)) so we don't re-parse
6091        // this DIE over and over later...
6092        m_die_to_variable_sp[die] = var_sp;
6093    }
6094    return var_sp;
6095}
6096
6097
6098const DWARFDebugInfoEntry *
6099SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset,
6100                                                   dw_offset_t spec_block_die_offset,
6101                                                   DWARFCompileUnit **result_die_cu_handle)
6102{
6103    // Give the concrete function die specified by "func_die_offset", find the
6104    // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
6105    // to "spec_block_die_offset"
6106    DWARFDebugInfo* info = DebugInfo();
6107
6108    const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
6109    if (die)
6110    {
6111        assert (*result_die_cu_handle);
6112        return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
6113    }
6114    return NULL;
6115}
6116
6117
6118const DWARFDebugInfoEntry *
6119SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
6120                                                  const DWARFDebugInfoEntry *die,
6121                                                  dw_offset_t spec_block_die_offset,
6122                                                  DWARFCompileUnit **result_die_cu_handle)
6123{
6124    if (die)
6125    {
6126        switch (die->Tag())
6127        {
6128        case DW_TAG_subprogram:
6129        case DW_TAG_inlined_subroutine:
6130        case DW_TAG_lexical_block:
6131            {
6132                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
6133                {
6134                    *result_die_cu_handle = dwarf_cu;
6135                    return die;
6136                }
6137
6138                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
6139                {
6140                    *result_die_cu_handle = dwarf_cu;
6141                    return die;
6142                }
6143            }
6144            break;
6145        }
6146
6147        // Give the concrete function die specified by "func_die_offset", find the
6148        // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
6149        // to "spec_block_die_offset"
6150        for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
6151        {
6152            const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
6153                                                                                      child_die,
6154                                                                                      spec_block_die_offset,
6155                                                                                      result_die_cu_handle);
6156            if (result_die)
6157                return result_die;
6158        }
6159    }
6160
6161    *result_die_cu_handle = NULL;
6162    return NULL;
6163}
6164
6165size_t
6166SymbolFileDWARF::ParseVariables
6167(
6168    const SymbolContext& sc,
6169    DWARFCompileUnit* dwarf_cu,
6170    const lldb::addr_t func_low_pc,
6171    const DWARFDebugInfoEntry *orig_die,
6172    bool parse_siblings,
6173    bool parse_children,
6174    VariableList* cc_variable_list
6175)
6176{
6177    if (orig_die == NULL)
6178        return 0;
6179
6180    VariableListSP variable_list_sp;
6181
6182    size_t vars_added = 0;
6183    const DWARFDebugInfoEntry *die = orig_die;
6184    while (die != NULL)
6185    {
6186        dw_tag_t tag = die->Tag();
6187
6188        // Check to see if we have already parsed this variable or constant?
6189        if (m_die_to_variable_sp[die])
6190        {
6191            if (cc_variable_list)
6192                cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
6193        }
6194        else
6195        {
6196            // We haven't already parsed it, lets do that now.
6197            if ((tag == DW_TAG_variable) ||
6198                (tag == DW_TAG_constant) ||
6199                (tag == DW_TAG_formal_parameter && sc.function))
6200            {
6201                if (variable_list_sp.get() == NULL)
6202                {
6203                    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
6204                    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
6205                    switch (parent_tag)
6206                    {
6207                        case DW_TAG_compile_unit:
6208                            if (sc.comp_unit != NULL)
6209                            {
6210                                variable_list_sp = sc.comp_unit->GetVariableList(false);
6211                                if (variable_list_sp.get() == NULL)
6212                                {
6213                                    variable_list_sp.reset(new VariableList());
6214                                    sc.comp_unit->SetVariableList(variable_list_sp);
6215                                }
6216                            }
6217                            else
6218                            {
6219                                GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8llx %s with no valid compile unit in symbol context for 0x%8.8llx %s.\n",
6220                                                                           MakeUserID(sc_parent_die->GetOffset()),
6221                                                                           DW_TAG_value_to_name (parent_tag),
6222                                                                           MakeUserID(orig_die->GetOffset()),
6223                                                                           DW_TAG_value_to_name (orig_die->Tag()));
6224                            }
6225                            break;
6226
6227                        case DW_TAG_subprogram:
6228                        case DW_TAG_inlined_subroutine:
6229                        case DW_TAG_lexical_block:
6230                            if (sc.function != NULL)
6231                            {
6232                                // Check to see if we already have parsed the variables for the given scope
6233
6234                                Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
6235                                if (block == NULL)
6236                                {
6237                                    // This must be a specification or abstract origin with
6238                                    // a concrete block couterpart in the current function. We need
6239                                    // to find the concrete block so we can correctly add the
6240                                    // variable to it
6241                                    DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
6242                                    const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
6243                                                                                                                      sc_parent_die->GetOffset(),
6244                                                                                                                      &concrete_block_die_cu);
6245                                    if (concrete_block_die)
6246                                        block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset()));
6247                                }
6248
6249                                if (block != NULL)
6250                                {
6251                                    const bool can_create = false;
6252                                    variable_list_sp = block->GetBlockVariableList (can_create);
6253                                    if (variable_list_sp.get() == NULL)
6254                                    {
6255                                        variable_list_sp.reset(new VariableList());
6256                                        block->SetVariableList(variable_list_sp);
6257                                    }
6258                                }
6259                            }
6260                            break;
6261
6262                        default:
6263                             GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8llx %s.\n",
6264                                                                        MakeUserID(orig_die->GetOffset()),
6265                                                                        DW_TAG_value_to_name (orig_die->Tag()));
6266                            break;
6267                    }
6268                }
6269
6270                if (variable_list_sp)
6271                {
6272                    VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
6273                    if (var_sp)
6274                    {
6275                        variable_list_sp->AddVariableIfUnique (var_sp);
6276                        if (cc_variable_list)
6277                            cc_variable_list->AddVariableIfUnique (var_sp);
6278                        ++vars_added;
6279                    }
6280                }
6281            }
6282        }
6283
6284        bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
6285
6286        if (!skip_children && parse_children && die->HasChildren())
6287        {
6288            vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
6289        }
6290
6291        if (parse_siblings)
6292            die = die->GetSibling();
6293        else
6294            die = NULL;
6295    }
6296    return vars_added;
6297}
6298
6299//------------------------------------------------------------------
6300// PluginInterface protocol
6301//------------------------------------------------------------------
6302const char *
6303SymbolFileDWARF::GetPluginName()
6304{
6305    return "SymbolFileDWARF";
6306}
6307
6308const char *
6309SymbolFileDWARF::GetShortPluginName()
6310{
6311    return GetPluginNameStatic();
6312}
6313
6314uint32_t
6315SymbolFileDWARF::GetPluginVersion()
6316{
6317    return 1;
6318}
6319
6320void
6321SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
6322{
6323    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
6324    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
6325    if (clang_type)
6326        symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
6327}
6328
6329void
6330SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
6331{
6332    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
6333    clang_type_t clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
6334    if (clang_type)
6335        symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
6336}
6337
6338void
6339SymbolFileDWARF::DumpIndexes ()
6340{
6341    StreamFile s(stdout, false);
6342
6343    s.Printf ("DWARF index for (%s) '%s/%s':",
6344              GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
6345              GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
6346              GetObjectFile()->GetFileSpec().GetFilename().AsCString());
6347    s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
6348    s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
6349    s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
6350    s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
6351    s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
6352    s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
6353    s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
6354    s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
6355}
6356
6357void
6358SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context,
6359                                    const char *name,
6360                                    llvm::SmallVectorImpl <clang::NamedDecl *> *results)
6361{
6362    DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
6363
6364    if (iter == m_decl_ctx_to_die.end())
6365        return;
6366
6367    for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos)
6368    {
6369        const DWARFDebugInfoEntry *context_die = *pos;
6370
6371        if (!results)
6372            return;
6373
6374        DWARFDebugInfo* info = DebugInfo();
6375
6376        DIEArray die_offsets;
6377
6378        DWARFCompileUnit* dwarf_cu = NULL;
6379        const DWARFDebugInfoEntry* die = NULL;
6380
6381        if (m_using_apple_tables)
6382        {
6383            if (m_apple_types_ap.get())
6384                m_apple_types_ap->FindByName (name, die_offsets);
6385        }
6386        else
6387        {
6388            if (!m_indexed)
6389                Index ();
6390
6391            m_type_index.Find (ConstString(name), die_offsets);
6392        }
6393
6394        const size_t num_matches = die_offsets.size();
6395
6396        if (num_matches)
6397        {
6398            for (size_t i = 0; i < num_matches; ++i)
6399            {
6400                const dw_offset_t die_offset = die_offsets[i];
6401                die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
6402
6403                if (die->GetParent() != context_die)
6404                    continue;
6405
6406                Type *matching_type = ResolveType (dwarf_cu, die);
6407
6408                lldb::clang_type_t type = matching_type->GetClangForwardType();
6409                clang::QualType qual_type = clang::QualType::getFromOpaquePtr(type);
6410
6411                if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
6412                {
6413                    clang::TagDecl *tag_decl = tag_type->getDecl();
6414                    results->push_back(tag_decl);
6415                }
6416                else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
6417                {
6418                    clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
6419                    results->push_back(typedef_decl);
6420                }
6421            }
6422        }
6423    }
6424}
6425
6426void
6427SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
6428                                                 const clang::DeclContext *decl_context,
6429                                                 clang::DeclarationName decl_name,
6430                                                 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
6431{
6432
6433    switch (decl_context->getDeclKind())
6434    {
6435    case clang::Decl::Namespace:
6436    case clang::Decl::TranslationUnit:
6437        {
6438            SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
6439            symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results);
6440        }
6441        break;
6442    default:
6443        break;
6444    }
6445}
6446
6447bool
6448SymbolFileDWARF::LayoutRecordType (void *baton,
6449                                   const clang::RecordDecl *record_decl,
6450                                   uint64_t &size,
6451                                   uint64_t &alignment,
6452                                   llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
6453                                   llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
6454                                   llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
6455{
6456    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
6457    return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets);
6458}
6459
6460
6461bool
6462SymbolFileDWARF::LayoutRecordType (const clang::RecordDecl *record_decl,
6463                                   uint64_t &bit_size,
6464                                   uint64_t &alignment,
6465                                   llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets,
6466                                   llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
6467                                   llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
6468{
6469    LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
6470    RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
6471    bool success = false;
6472    base_offsets.clear();
6473    vbase_offsets.clear();
6474    if (pos != m_record_decl_to_layout_map.end())
6475    {
6476        bit_size = pos->second.bit_size;
6477        alignment = pos->second.alignment;
6478        field_offsets.swap(pos->second.field_offsets);
6479        m_record_decl_to_layout_map.erase(pos);
6480        success = true;
6481    }
6482    else
6483    {
6484        bit_size = 0;
6485        alignment = 0;
6486        field_offsets.clear();
6487    }
6488
6489    if (log)
6490        GetObjectFile()->GetModule()->LogMessage (log.get(),
6491                                                  "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %llu, alignment = %llu, field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
6492                                                  record_decl,
6493                                                  bit_size,
6494                                                  alignment,
6495                                                  (uint32_t)field_offsets.size(),
6496                                                  (uint32_t)base_offsets.size(),
6497                                                  (uint32_t)vbase_offsets.size(),
6498                                                  success);
6499    return success;
6500}
6501
6502
6503
6504