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