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