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