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