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