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