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