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