SymbolFileDWARF.cpp revision d7cb26e87841731c6452a9f2e997ed0f9c92625c
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/Basic/Builtins.h"
18#include "clang/Basic/IdentifierTable.h"
19#include "clang/Basic/LangOptions.h"
20#include "clang/Basic/SourceManager.h"
21#include "clang/Basic/TargetInfo.h"
22#include "clang/Basic/Specifiers.h"
23
24#include "lldb/Core/Module.h"
25#include "lldb/Core/PluginManager.h"
26#include "lldb/Core/RegularExpression.h"
27#include "lldb/Core/Scalar.h"
28#include "lldb/Core/Section.h"
29#include "lldb/Core/StreamFile.h"
30#include "lldb/Core/Timer.h"
31#include "lldb/Core/Value.h"
32
33#include "lldb/Symbol/Block.h"
34#include "lldb/Symbol/CompileUnit.h"
35#include "lldb/Symbol/LineTable.h"
36#include "lldb/Symbol/ObjectFile.h"
37#include "lldb/Symbol/SymbolVendor.h"
38#include "lldb/Symbol/VariableList.h"
39
40#include "DWARFCompileUnit.h"
41#include "DWARFDebugAbbrev.h"
42#include "DWARFDebugAranges.h"
43#include "DWARFDebugInfo.h"
44#include "DWARFDebugInfoEntry.h"
45#include "DWARFDebugLine.h"
46#include "DWARFDebugPubnames.h"
47#include "DWARFDebugRanges.h"
48#include "DWARFDIECollection.h"
49#include "DWARFFormValue.h"
50#include "DWARFLocationList.h"
51#include "LogChannelDWARF.h"
52#include "SymbolFileDWARFDebugMap.h"
53
54#include <map>
55
56#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
57
58#ifdef ENABLE_DEBUG_PRINTF
59#include <stdio.h>
60#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)
61#else
62#define DEBUG_PRINTF(fmt, ...)
63#endif
64
65#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)
66
67using namespace lldb;
68using namespace lldb_private;
69
70
71static AccessType
72DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
73{
74    switch (dwarf_accessibility)
75    {
76        case DW_ACCESS_public:      return eAccessPublic;
77        case DW_ACCESS_private:     return eAccessPrivate;
78        case DW_ACCESS_protected:   return eAccessProtected;
79        default:                    break;
80    }
81    return eAccessNone;
82}
83
84void
85SymbolFileDWARF::Initialize()
86{
87    LogChannelDWARF::Initialize();
88    PluginManager::RegisterPlugin (GetPluginNameStatic(),
89                                   GetPluginDescriptionStatic(),
90                                   CreateInstance);
91}
92
93void
94SymbolFileDWARF::Terminate()
95{
96    PluginManager::UnregisterPlugin (CreateInstance);
97    LogChannelDWARF::Initialize();
98}
99
100
101const char *
102SymbolFileDWARF::GetPluginNameStatic()
103{
104    return "symbol-file.dwarf2";
105}
106
107const char *
108SymbolFileDWARF::GetPluginDescriptionStatic()
109{
110    return "DWARF and DWARF3 debug symbol file reader.";
111}
112
113
114SymbolFile*
115SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
116{
117    return new SymbolFileDWARF(obj_file);
118}
119
120
121ClangASTContext &
122SymbolFileDWARF::GetClangASTContext()
123{
124    return GetTypeList()->GetClangASTContext();
125}
126
127TypeList *
128SymbolFileDWARF::GetTypeList ()
129{
130    if (m_debug_map_symfile)
131        return m_debug_map_symfile->GetTypeList();
132    return m_obj_file->GetModule()->GetTypeList();
133
134}
135
136//----------------------------------------------------------------------
137// Gets the first parent that is a lexical block, function or inlined
138// subroutine, or compile unit.
139//----------------------------------------------------------------------
140static const DWARFDebugInfoEntry *
141GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
142{
143    const DWARFDebugInfoEntry *die;
144    for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
145    {
146        dw_tag_t tag = die->Tag();
147
148        switch (tag)
149        {
150        case DW_TAG_compile_unit:
151        case DW_TAG_subprogram:
152        case DW_TAG_inlined_subroutine:
153        case DW_TAG_lexical_block:
154            return die;
155        }
156    }
157    return NULL;
158}
159
160
161SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
162    SymbolFile (objfile),
163    m_debug_map_symfile (NULL),
164    m_clang_tu_decl (NULL),
165    m_flags(),
166    m_data_debug_abbrev(),
167    m_data_debug_frame(),
168    m_data_debug_info(),
169    m_data_debug_line(),
170    m_data_debug_loc(),
171    m_data_debug_ranges(),
172    m_data_debug_str(),
173    m_abbr(),
174    m_aranges(),
175    m_info(),
176    m_line(),
177    m_function_basename_index(),
178    m_function_fullname_index(),
179    m_function_method_index(),
180    m_function_selector_index(),
181    m_objc_class_selectors_index(),
182    m_global_index(),
183    m_type_index(),
184    m_namespace_index(),
185    m_indexed(false),
186    m_ranges()
187{
188}
189
190SymbolFileDWARF::~SymbolFileDWARF()
191{
192}
193
194bool
195SymbolFileDWARF::SupportedVersion(uint16_t version)
196{
197    return version == 2 || version == 3;
198}
199
200uint32_t
201SymbolFileDWARF::GetAbilities ()
202{
203    uint32_t abilities = 0;
204    if (m_obj_file != NULL)
205    {
206        const Section* section = NULL;
207        const SectionList *section_list = m_obj_file->GetSectionList();
208        if (section_list == NULL)
209            return 0;
210
211        uint64_t debug_abbrev_file_size = 0;
212        uint64_t debug_aranges_file_size = 0;
213        uint64_t debug_frame_file_size = 0;
214        uint64_t debug_info_file_size = 0;
215        uint64_t debug_line_file_size = 0;
216        uint64_t debug_loc_file_size = 0;
217        uint64_t debug_macinfo_file_size = 0;
218        uint64_t debug_pubnames_file_size = 0;
219        uint64_t debug_pubtypes_file_size = 0;
220        uint64_t debug_ranges_file_size = 0;
221        uint64_t debug_str_file_size = 0;
222
223        static ConstString g_dwarf_section_name ("__DWARF");
224
225        section = section_list->FindSectionByName(g_dwarf_section_name).get();
226
227        if (section)
228        {
229            section->MemoryMapSectionDataFromObjectFile(m_obj_file, m_dwarf_data);
230            section_list = &section->GetChildren ();
231        }
232
233        section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
234        if (section != NULL)
235        {
236            debug_info_file_size = section->GetByteSize();
237
238            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
239            if (section)
240                debug_abbrev_file_size = section->GetByteSize();
241            else
242                m_flags.Set (flagsGotDebugAbbrevData);
243
244            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
245            if (section)
246                debug_aranges_file_size = section->GetByteSize();
247            else
248                m_flags.Set (flagsGotDebugArangesData);
249
250            section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
251            if (section)
252                debug_frame_file_size = section->GetByteSize();
253            else
254                m_flags.Set (flagsGotDebugFrameData);
255
256            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
257            if (section)
258                debug_line_file_size = section->GetByteSize();
259            else
260                m_flags.Set (flagsGotDebugLineData);
261
262            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
263            if (section)
264                debug_loc_file_size = section->GetByteSize();
265            else
266                m_flags.Set (flagsGotDebugLocData);
267
268            section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
269            if (section)
270                debug_macinfo_file_size = section->GetByteSize();
271            else
272                m_flags.Set (flagsGotDebugMacInfoData);
273
274            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
275            if (section)
276                debug_pubnames_file_size = section->GetByteSize();
277            else
278                m_flags.Set (flagsGotDebugPubNamesData);
279
280            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
281            if (section)
282                debug_pubtypes_file_size = section->GetByteSize();
283            else
284                m_flags.Set (flagsGotDebugPubTypesData);
285
286            section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
287            if (section)
288                debug_ranges_file_size = section->GetByteSize();
289            else
290                m_flags.Set (flagsGotDebugRangesData);
291
292            section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
293            if (section)
294                debug_str_file_size = section->GetByteSize();
295            else
296                m_flags.Set (flagsGotDebugStrData);
297        }
298
299        if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
300            abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;
301
302        if (debug_line_file_size > 0)
303            abilities |= LineTables;
304
305        if (debug_aranges_file_size > 0)
306            abilities |= AddressAcceleratorTable;
307
308        if (debug_pubnames_file_size > 0)
309            abilities |= FunctionAcceleratorTable;
310
311        if (debug_pubtypes_file_size > 0)
312            abilities |= TypeAcceleratorTable;
313
314        if (debug_macinfo_file_size > 0)
315            abilities |= MacroInformation;
316
317        if (debug_frame_file_size > 0)
318            abilities |= CallFrameInformation;
319    }
320    return abilities;
321}
322
323const DataExtractor&
324SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DataExtractor &data)
325{
326    if (m_flags.IsClear (got_flag))
327    {
328        m_flags.Set (got_flag);
329        const SectionList *section_list = m_obj_file->GetSectionList();
330        if (section_list)
331        {
332            Section *section = section_list->FindSectionByType(sect_type, true).get();
333            if (section)
334            {
335                // See if we memory mapped the DWARF segment?
336                if (m_dwarf_data.GetByteSize())
337                {
338                    data.SetData(m_dwarf_data, section->GetOffset (), section->GetByteSize());
339                }
340                else
341                {
342                    if (section->ReadSectionDataFromObjectFile(m_obj_file, data) == 0)
343                        data.Clear();
344                }
345            }
346        }
347    }
348    return data;
349}
350
351const DataExtractor&
352SymbolFileDWARF::get_debug_abbrev_data()
353{
354    return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
355}
356
357const DataExtractor&
358SymbolFileDWARF::get_debug_frame_data()
359{
360    return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
361}
362
363const DataExtractor&
364SymbolFileDWARF::get_debug_info_data()
365{
366    return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
367}
368
369const DataExtractor&
370SymbolFileDWARF::get_debug_line_data()
371{
372    return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
373}
374
375const DataExtractor&
376SymbolFileDWARF::get_debug_loc_data()
377{
378    return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
379}
380
381const DataExtractor&
382SymbolFileDWARF::get_debug_ranges_data()
383{
384    return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
385}
386
387const DataExtractor&
388SymbolFileDWARF::get_debug_str_data()
389{
390    return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
391}
392
393
394DWARFDebugAbbrev*
395SymbolFileDWARF::DebugAbbrev()
396{
397    if (m_abbr.get() == NULL)
398    {
399        const DataExtractor &debug_abbrev_data = get_debug_abbrev_data();
400        if (debug_abbrev_data.GetByteSize() > 0)
401        {
402            m_abbr.reset(new DWARFDebugAbbrev());
403            if (m_abbr.get())
404                m_abbr->Parse(debug_abbrev_data);
405        }
406    }
407    return m_abbr.get();
408}
409
410const DWARFDebugAbbrev*
411SymbolFileDWARF::DebugAbbrev() const
412{
413    return m_abbr.get();
414}
415
416DWARFDebugAranges*
417SymbolFileDWARF::DebugAranges()
418{
419    // It turns out that llvm-gcc doesn't generate .debug_aranges in .o files
420    // and we are already parsing all of the DWARF because the .debug_pubnames
421    // is useless (it only mentions symbols that are externally visible), so
422    // don't use the .debug_aranges section, we should be using a debug aranges
423    // we got from SymbolFileDWARF::Index().
424
425    if (!m_indexed)
426        Index();
427
428
429//    if (m_aranges.get() == NULL)
430//    {
431//        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
432//        m_aranges.reset(new DWARFDebugAranges());
433//        if (m_aranges.get())
434//        {
435//            const DataExtractor &debug_aranges_data = get_debug_aranges_data();
436//            if (debug_aranges_data.GetByteSize() > 0)
437//                m_aranges->Extract(debug_aranges_data);
438//            else
439//                m_aranges->Generate(this);
440//        }
441//    }
442    return m_aranges.get();
443}
444
445const DWARFDebugAranges*
446SymbolFileDWARF::DebugAranges() const
447{
448    return m_aranges.get();
449}
450
451
452DWARFDebugInfo*
453SymbolFileDWARF::DebugInfo()
454{
455    if (m_info.get() == NULL)
456    {
457        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
458        if (get_debug_info_data().GetByteSize() > 0)
459        {
460            m_info.reset(new DWARFDebugInfo());
461            if (m_info.get())
462            {
463                m_info->SetDwarfData(this);
464            }
465        }
466    }
467    return m_info.get();
468}
469
470const DWARFDebugInfo*
471SymbolFileDWARF::DebugInfo() const
472{
473    return m_info.get();
474}
475
476DWARFCompileUnit*
477SymbolFileDWARF::GetDWARFCompileUnitForUID(lldb::user_id_t cu_uid)
478{
479    DWARFDebugInfo* info = DebugInfo();
480    if (info)
481        return info->GetCompileUnit(cu_uid).get();
482    return NULL;
483}
484
485
486DWARFDebugRanges*
487SymbolFileDWARF::DebugRanges()
488{
489    if (m_ranges.get() == NULL)
490    {
491        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p", __PRETTY_FUNCTION__, this);
492        if (get_debug_ranges_data().GetByteSize() > 0)
493        {
494            m_ranges.reset(new DWARFDebugRanges());
495            if (m_ranges.get())
496                m_ranges->Extract(this);
497        }
498    }
499    return m_ranges.get();
500}
501
502const DWARFDebugRanges*
503SymbolFileDWARF::DebugRanges() const
504{
505    return m_ranges.get();
506}
507
508bool
509SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* curr_cu, CompUnitSP& compile_unit_sp)
510{
511    if (curr_cu != NULL)
512    {
513        const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly ();
514        if (cu_die)
515        {
516            const char * cu_die_name = cu_die->GetName(this, curr_cu);
517            const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
518            LanguageType class_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_language, 0);
519            if (cu_die_name)
520            {
521                FileSpec cu_file_spec;
522
523                if (cu_die_name[0] == '/' || cu_comp_dir == NULL && cu_comp_dir[0])
524                {
525                    // If we have a full path to the compile unit, we don't need to resolve
526                    // the file.  This can be expensive e.g. when the source files are NFS mounted.
527                    cu_file_spec.SetFile (cu_die_name, false);
528                }
529                else
530                {
531                    std::string fullpath(cu_comp_dir);
532                    if (*fullpath.rbegin() != '/')
533                        fullpath += '/';
534                    fullpath += cu_die_name;
535                    cu_file_spec.SetFile (fullpath.c_str(), false);
536                }
537
538                compile_unit_sp.reset(new CompileUnit(m_obj_file->GetModule(), curr_cu, cu_file_spec, curr_cu->GetOffset(), class_language));
539                if (compile_unit_sp.get())
540                {
541                    curr_cu->SetUserData(compile_unit_sp.get());
542                    return true;
543                }
544            }
545        }
546    }
547    return false;
548}
549
550uint32_t
551SymbolFileDWARF::GetNumCompileUnits()
552{
553    DWARFDebugInfo* info = DebugInfo();
554    if (info)
555        return info->GetNumCompileUnits();
556    return 0;
557}
558
559CompUnitSP
560SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
561{
562    CompUnitSP comp_unit;
563    DWARFDebugInfo* info = DebugInfo();
564    if (info)
565    {
566        DWARFCompileUnit* curr_cu = info->GetCompileUnitAtIndex(cu_idx);
567        if (curr_cu != NULL)
568        {
569            // Our symbol vendor shouldn't be asking us to add a compile unit that
570            // has already been added to it, which this DWARF plug-in knows as it
571            // stores the lldb compile unit (CompileUnit) pointer in each
572            // DWARFCompileUnit object when it gets added.
573            assert(curr_cu->GetUserData() == NULL);
574            ParseCompileUnit(curr_cu, comp_unit);
575        }
576    }
577    return comp_unit;
578}
579
580static void
581AddRangesToBlock
582(
583    Block& block,
584    DWARFDebugRanges::RangeList& ranges,
585    addr_t block_base_addr
586)
587{
588    ranges.SubtractOffset (block_base_addr);
589    size_t range_idx = 0;
590    const DWARFDebugRanges::Range *debug_range;
591    for (range_idx = 0; (debug_range = ranges.RangeAtIndex(range_idx)) != NULL; range_idx++)
592    {
593        block.AddRange(debug_range->begin_offset, debug_range->end_offset);
594    }
595}
596
597
598Function *
599SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
600{
601    DWARFDebugRanges::RangeList func_ranges;
602    const char *name = NULL;
603    const char *mangled = NULL;
604    int decl_file = 0;
605    int decl_line = 0;
606    int decl_column = 0;
607    int call_file = 0;
608    int call_line = 0;
609    int call_column = 0;
610    DWARFExpression frame_base;
611
612    assert (die->Tag() == DW_TAG_subprogram);
613
614    if (die->Tag() != DW_TAG_subprogram)
615        return NULL;
616
617    const DWARFDebugInfoEntry *parent_die = die->GetParent();
618    switch (parent_die->Tag())
619    {
620    case DW_TAG_structure_type:
621    case DW_TAG_class_type:
622        // We have methods of a class or struct
623        {
624            Type *class_type = ResolveType (dwarf_cu, parent_die);
625            if (class_type)
626                class_type->GetClangType();
627        }
628        break;
629
630    default:
631        // Parse the function prototype as a type that can then be added to concrete function instance
632        ParseTypes (sc, dwarf_cu, die, false, false);
633        break;
634    }
635
636    //FixupTypes();
637
638    if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled, func_ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, &frame_base))
639    {
640        // Union of all ranges in the function DIE (if the function is discontiguous)
641        AddressRange func_range;
642        lldb::addr_t lowest_func_addr = func_ranges.LowestAddress(0);
643        lldb::addr_t highest_func_addr = func_ranges.HighestAddress(0);
644        if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
645        {
646            func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, m_obj_file->GetSectionList());
647            if (func_range.GetBaseAddress().IsValid())
648                func_range.SetByteSize(highest_func_addr - lowest_func_addr);
649        }
650
651        if (func_range.GetBaseAddress().IsValid())
652        {
653            Mangled func_name;
654            if (mangled)
655                func_name.SetValue(mangled, true);
656            else if (name)
657                func_name.SetValue(name, false);
658
659            FunctionSP func_sp;
660            std::auto_ptr<Declaration> decl_ap;
661            if (decl_file != 0 || decl_line != 0 || decl_column != 0)
662                decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column));
663
664            Type *func_type = m_die_to_type.lookup (die);
665
666            assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
667
668            func_range.GetBaseAddress().ResolveLinkedAddress();
669
670            func_sp.reset(new Function (sc.comp_unit,
671                                        die->GetOffset(),       // UserID is the DIE offset
672                                        die->GetOffset(),
673                                        func_name,
674                                        func_type,
675                                        func_range));           // first address range
676
677            if (func_sp.get() != NULL)
678            {
679                func_sp->GetFrameBaseExpression() = frame_base;
680                sc.comp_unit->AddFunction(func_sp);
681                return func_sp.get();
682            }
683        }
684    }
685    return NULL;
686}
687
688size_t
689SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
690{
691    assert (sc.comp_unit);
692    size_t functions_added = 0;
693    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
694    if (dwarf_cu)
695    {
696        DWARFDIECollection function_dies;
697        const size_t num_funtions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
698        size_t func_idx;
699        for (func_idx = 0; func_idx < num_funtions; ++func_idx)
700        {
701            const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
702            if (sc.comp_unit->FindFunctionByUID (die->GetOffset()).get() == NULL)
703            {
704                if (ParseCompileUnitFunction(sc, dwarf_cu, die))
705                    ++functions_added;
706            }
707        }
708        //FixupTypes();
709    }
710    return functions_added;
711}
712
713bool
714SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
715{
716    assert (sc.comp_unit);
717    DWARFCompileUnit* curr_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
718    assert (curr_cu);
719    const DWARFDebugInfoEntry * cu_die = curr_cu->GetCompileUnitDIEOnly();
720
721    if (cu_die)
722    {
723        const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, curr_cu, DW_AT_comp_dir, NULL);
724        dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
725
726        // All file indexes in DWARF are one based and a file of index zero is
727        // supposed to be the compile unit itself.
728        support_files.Append (*sc.comp_unit);
729
730        return DWARFDebugLine::ParseSupportFiles(get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
731    }
732    return false;
733}
734
735struct ParseDWARFLineTableCallbackInfo
736{
737    LineTable* line_table;
738    const SectionList *section_list;
739    lldb::addr_t prev_sect_file_base_addr;
740    lldb::addr_t curr_sect_file_base_addr;
741    bool is_oso_for_debug_map;
742    bool prev_in_final_executable;
743    DWARFDebugLine::Row prev_row;
744    SectionSP prev_section_sp;
745    SectionSP curr_section_sp;
746};
747
748//----------------------------------------------------------------------
749// ParseStatementTableCallback
750//----------------------------------------------------------------------
751static void
752ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
753{
754    LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
755    if (state.row == DWARFDebugLine::State::StartParsingLineTable)
756    {
757        // Just started parsing the line table
758    }
759    else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
760    {
761        // Done parsing line table, nothing to do for the cleanup
762    }
763    else
764    {
765        ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
766        // We have a new row, lets append it
767
768        if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
769        {
770            info->prev_section_sp = info->curr_section_sp;
771            info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
772            // If this is an end sequence entry, then we subtract one from the
773            // address to make sure we get an address that is not the end of
774            // a section.
775            if (state.end_sequence && state.address != 0)
776                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
777            else
778                info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
779
780            if (info->curr_section_sp.get())
781                info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
782            else
783                info->curr_sect_file_base_addr = 0;
784        }
785        if (info->curr_section_sp.get())
786        {
787            lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
788            // Check for the fancy section magic to determine if we
789
790            if (info->is_oso_for_debug_map)
791            {
792                // When this is a debug map object file that contains DWARF
793                // (referenced from an N_OSO debug map nlist entry) we will have
794                // a file address in the file range for our section from the
795                // original .o file, and a load address in the executable that
796                // contains the debug map.
797                //
798                // If the sections for the file range and load range are
799                // different, we have a remapped section for the function and
800                // this address is resolved. If they are the same, then the
801                // function for this address didn't make it into the final
802                // executable.
803                bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection () != NULL;
804
805                // If we are doing DWARF with debug map, then we need to carefully
806                // add each line table entry as there may be gaps as functions
807                // get moved around or removed.
808                if (!info->prev_row.end_sequence && info->prev_section_sp.get())
809                {
810                    if (info->prev_in_final_executable)
811                    {
812                        bool terminate_previous_entry = false;
813                        if (!curr_in_final_executable)
814                        {
815                            // Check for the case where the previous line entry
816                            // in a function made it into the final executable,
817                            // yet the current line entry falls in a function
818                            // that didn't. The line table used to be contiguous
819                            // through this address range but now it isn't. We
820                            // need to terminate the previous line entry so
821                            // that we can reconstruct the line range correctly
822                            // for it and to keep the line table correct.
823                            terminate_previous_entry = true;
824                        }
825                        else if (info->curr_section_sp.get() != info->prev_section_sp.get())
826                        {
827                            // Check for cases where the line entries used to be
828                            // contiguous address ranges, but now they aren't.
829                            // This can happen when order files specify the
830                            // ordering of the functions.
831                            lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
832                            Section *curr_sect = info->curr_section_sp.get();
833                            Section *prev_sect = info->prev_section_sp.get();
834                            assert (curr_sect->GetLinkedSection());
835                            assert (prev_sect->GetLinkedSection());
836                            lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
837                            lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
838                            lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
839                            lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
840                            if (object_file_addr_delta != linked_file_addr_delta)
841                                terminate_previous_entry = true;
842                        }
843
844                        if (terminate_previous_entry)
845                        {
846                            line_table->InsertLineEntry (info->prev_section_sp,
847                                                         state.address - info->prev_sect_file_base_addr,
848                                                         info->prev_row.line,
849                                                         info->prev_row.column,
850                                                         info->prev_row.file,
851                                                         false,                 // is_stmt
852                                                         false,                 // basic_block
853                                                         false,                 // state.prologue_end
854                                                         false,                 // state.epilogue_begin
855                                                         true);                 // end_sequence);
856                        }
857                    }
858                }
859
860                if (curr_in_final_executable)
861                {
862                    line_table->InsertLineEntry (info->curr_section_sp,
863                                                 curr_line_section_offset,
864                                                 state.line,
865                                                 state.column,
866                                                 state.file,
867                                                 state.is_stmt,
868                                                 state.basic_block,
869                                                 state.prologue_end,
870                                                 state.epilogue_begin,
871                                                 state.end_sequence);
872                    info->prev_section_sp = info->curr_section_sp;
873                }
874                else
875                {
876                    // If the current address didn't make it into the final
877                    // executable, the current section will be the __text
878                    // segment in the .o file, so we need to clear this so
879                    // we can catch the next function that did make it into
880                    // the final executable.
881                    info->prev_section_sp.reset();
882                    info->curr_section_sp.reset();
883                }
884
885                info->prev_in_final_executable = curr_in_final_executable;
886            }
887            else
888            {
889                // We are not in an object file that contains DWARF for an
890                // N_OSO, this is just a normal DWARF file. The DWARF spec
891                // guarantees that the addresses will be in increasing order
892                // so, since we store line tables in file address order, we
893                // can always just append the line entry without needing to
894                // search for the correct insertion point (we don't need to
895                // use LineEntry::InsertLineEntry()).
896                line_table->AppendLineEntry (info->curr_section_sp,
897                                             curr_line_section_offset,
898                                             state.line,
899                                             state.column,
900                                             state.file,
901                                             state.is_stmt,
902                                             state.basic_block,
903                                             state.prologue_end,
904                                             state.epilogue_begin,
905                                             state.end_sequence);
906            }
907        }
908
909        info->prev_row = state;
910    }
911}
912
913bool
914SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
915{
916    assert (sc.comp_unit);
917    if (sc.comp_unit->GetLineTable() != NULL)
918        return true;
919
920    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
921    if (dwarf_cu)
922    {
923        const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
924        const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
925        if (cu_line_offset != DW_INVALID_OFFSET)
926        {
927            std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
928            if (line_table_ap.get())
929            {
930                ParseDWARFLineTableCallbackInfo info = { line_table_ap.get(), m_obj_file->GetSectionList(), 0, 0, m_debug_map_symfile != NULL, false};
931                uint32_t offset = cu_line_offset;
932                DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
933                sc.comp_unit->SetLineTable(line_table_ap.release());
934                return true;
935            }
936        }
937    }
938    return false;
939}
940
941size_t
942SymbolFileDWARF::ParseFunctionBlocks
943(
944    const SymbolContext& sc,
945    Block *parent_block,
946    DWARFCompileUnit* dwarf_cu,
947    const DWARFDebugInfoEntry *die,
948    addr_t subprogram_low_pc,
949    bool parse_siblings,
950    bool parse_children
951)
952{
953    size_t blocks_added = 0;
954    while (die != NULL)
955    {
956        dw_tag_t tag = die->Tag();
957
958        switch (tag)
959        {
960        case DW_TAG_inlined_subroutine:
961        case DW_TAG_subprogram:
962        case DW_TAG_lexical_block:
963            {
964                DWARFDebugRanges::RangeList ranges;
965                const char *name = NULL;
966                const char *mangled_name = NULL;
967                Block *block = NULL;
968                if (tag != DW_TAG_subprogram)
969                {
970                    BlockSP block_sp(new Block (die->GetOffset()));
971                    parent_block->AddChild(block_sp);
972                    block = block_sp.get();
973                }
974                else
975                {
976                    block = parent_block;
977                }
978
979                int decl_file = 0;
980                int decl_line = 0;
981                int decl_column = 0;
982                int call_file = 0;
983                int call_line = 0;
984                int call_column = 0;
985                if (die->GetDIENamesAndRanges (this,
986                                               dwarf_cu,
987                                               name,
988                                               mangled_name,
989                                               ranges,
990                                               decl_file, decl_line, decl_column,
991                                               call_file, call_line, call_column))
992                {
993                    if (tag == DW_TAG_subprogram)
994                    {
995                        assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
996                        subprogram_low_pc = ranges.LowestAddress(0);
997                    }
998                    else if (tag == DW_TAG_inlined_subroutine)
999                    {
1000                        // We get called here for inlined subroutines in two ways.
1001                        // The first time is when we are making the Function object
1002                        // for this inlined concrete instance.  Since we're creating a top level block at
1003                        // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS.  So we need to
1004                        // adjust the containing address.
1005                        // The second time is when we are parsing the blocks inside the function that contains
1006                        // the inlined concrete instance.  Since these will be blocks inside the containing "real"
1007                        // function the offset will be for that function.
1008                        if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
1009                        {
1010                            subprogram_low_pc = ranges.LowestAddress(0);
1011                        }
1012                    }
1013
1014                    AddRangesToBlock (*block, ranges, subprogram_low_pc);
1015
1016                    if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
1017                    {
1018                        std::auto_ptr<Declaration> decl_ap;
1019                        if (decl_file != 0 || decl_line != 0 || decl_column != 0)
1020                            decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
1021                                                          decl_line, decl_column));
1022
1023                        std::auto_ptr<Declaration> call_ap;
1024                        if (call_file != 0 || call_line != 0 || call_column != 0)
1025                            call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file),
1026                                                          call_line, call_column));
1027
1028                        block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
1029                    }
1030
1031                    ++blocks_added;
1032
1033                    if (parse_children && die->HasChildren())
1034                    {
1035                        blocks_added += ParseFunctionBlocks (sc,
1036                                                             block,
1037                                                             dwarf_cu,
1038                                                             die->GetFirstChild(),
1039                                                             subprogram_low_pc,
1040                                                             true,
1041                                                             true);
1042                    }
1043                }
1044            }
1045            break;
1046        default:
1047            break;
1048        }
1049
1050        if (parse_siblings)
1051            die = die->GetSibling();
1052        else
1053            die = NULL;
1054    }
1055    return blocks_added;
1056}
1057
1058size_t
1059SymbolFileDWARF::ParseChildMembers
1060(
1061    const SymbolContext& sc,
1062    DWARFCompileUnit* dwarf_cu,
1063    const DWARFDebugInfoEntry *parent_die,
1064    clang_type_t class_clang_type,
1065    const LanguageType class_language,
1066    std::vector<clang::CXXBaseSpecifier *>& base_classes,
1067    std::vector<int>& member_accessibilities,
1068    DWARFDIECollection& member_function_dies,
1069    AccessType& default_accessibility,
1070    bool &is_a_class
1071)
1072{
1073    if (parent_die == NULL)
1074        return 0;
1075
1076    size_t count = 0;
1077    const DWARFDebugInfoEntry *die;
1078    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
1079
1080    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
1081    {
1082        dw_tag_t tag = die->Tag();
1083
1084        switch (tag)
1085        {
1086        case DW_TAG_member:
1087            {
1088                DWARFDebugInfoEntry::Attributes attributes;
1089                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
1090                if (num_attributes > 0)
1091                {
1092                    Declaration decl;
1093                    //DWARFExpression location;
1094                    const char *name = NULL;
1095                    bool is_artificial = false;
1096                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1097                    AccessType accessibility = eAccessNone;
1098                    //off_t member_offset = 0;
1099                    size_t byte_size = 0;
1100                    size_t bit_offset = 0;
1101                    size_t bit_size = 0;
1102                    uint32_t i;
1103                    for (i=0; i<num_attributes && !is_artificial; ++i)
1104                    {
1105                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1106                        DWARFFormValue form_value;
1107                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1108                        {
1109                            switch (attr)
1110                            {
1111                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1112                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1113                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1114                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
1115                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1116                            case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break;
1117                            case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break;
1118                            case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
1119                            case DW_AT_data_member_location:
1120//                                if (form_value.BlockData())
1121//                                {
1122//                                    Value initialValue(0);
1123//                                    Value memberOffset(0);
1124//                                    const DataExtractor& debug_info_data = get_debug_info_data();
1125//                                    uint32_t block_length = form_value.Unsigned();
1126//                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1127//                                    if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1128//                                    {
1129//                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1130//                                    }
1131//                                }
1132                                break;
1133
1134                            case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
1135                            case DW_AT_artificial: is_artificial = form_value.Unsigned() != 0; break;
1136                            case DW_AT_declaration:
1137                            case DW_AT_description:
1138                            case DW_AT_mutable:
1139                            case DW_AT_visibility:
1140                            default:
1141                            case DW_AT_sibling:
1142                                break;
1143                            }
1144                        }
1145                    }
1146
1147                    // FIXME: Make Clang ignore Objective-C accessibility for expressions
1148
1149                    if (class_language == eLanguageTypeObjC ||
1150                        class_language == eLanguageTypeObjC_plus_plus)
1151                        accessibility = eAccessNone;
1152
1153                    if (is_artificial == false)
1154                    {
1155                        Type *member_type = ResolveTypeUID(encoding_uid);
1156                        assert(member_type);
1157                        if (accessibility == eAccessNone)
1158                            accessibility = default_accessibility;
1159                        member_accessibilities.push_back(accessibility);
1160
1161                        GetClangASTContext().AddFieldToRecordType (class_clang_type, name, member_type->GetClangType(), accessibility, bit_size);
1162                    }
1163                }
1164            }
1165            break;
1166
1167        case DW_TAG_subprogram:
1168            // Let the type parsing code handle this one for us.
1169            member_function_dies.Append (die);
1170            break;
1171
1172        case DW_TAG_inheritance:
1173            {
1174                is_a_class = true;
1175                if (default_accessibility == eAccessNone)
1176                    default_accessibility = eAccessPrivate;
1177                // TODO: implement DW_TAG_inheritance type parsing
1178                DWARFDebugInfoEntry::Attributes attributes;
1179                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
1180                if (num_attributes > 0)
1181                {
1182                    Declaration decl;
1183                    DWARFExpression location;
1184                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
1185                    AccessType accessibility = default_accessibility;
1186                    bool is_virtual = false;
1187                    bool is_base_of_class = true;
1188                    off_t member_offset = 0;
1189                    uint32_t i;
1190                    for (i=0; i<num_attributes; ++i)
1191                    {
1192                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1193                        DWARFFormValue form_value;
1194                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
1195                        {
1196                            switch (attr)
1197                            {
1198                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
1199                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
1200                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
1201                            case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
1202                            case DW_AT_data_member_location:
1203                                if (form_value.BlockData())
1204                                {
1205                                    Value initialValue(0);
1206                                    Value memberOffset(0);
1207                                    const DataExtractor& debug_info_data = get_debug_info_data();
1208                                    uint32_t block_length = form_value.Unsigned();
1209                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
1210                                    if (DWARFExpression::Evaluate(NULL, NULL, debug_info_data, NULL, NULL, block_offset, block_length, eRegisterKindDWARF, &initialValue, memberOffset, NULL))
1211                                    {
1212                                        member_offset = memberOffset.ResolveValue(NULL, NULL).UInt();
1213                                    }
1214                                }
1215                                break;
1216
1217                            case DW_AT_accessibility:
1218                                accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
1219                                break;
1220
1221                            case DW_AT_virtuality: is_virtual = form_value.Unsigned() != 0; break;
1222                            default:
1223                            case DW_AT_sibling:
1224                                break;
1225                            }
1226                        }
1227                    }
1228
1229                    Type *base_class_dctype = ResolveTypeUID(encoding_uid);
1230                    assert(base_class_dctype);
1231
1232                    if (class_language == eLanguageTypeObjC)
1233                    {
1234                        GetClangASTContext().SetObjCSuperClass(class_clang_type, base_class_dctype->GetClangType());
1235                    }
1236                    else
1237                    {
1238                        base_classes.push_back (GetClangASTContext().CreateBaseClassSpecifier (base_class_dctype->GetClangType(), accessibility, is_virtual, is_base_of_class));
1239                        assert(base_classes.back());
1240                    }
1241                }
1242            }
1243            break;
1244
1245        default:
1246            break;
1247        }
1248    }
1249    return count;
1250}
1251
1252
1253clang::DeclContext*
1254SymbolFileDWARF::GetClangDeclContextForTypeUID (lldb::user_id_t type_uid)
1255{
1256    DWARFDebugInfo* debug_info = DebugInfo();
1257    if (debug_info)
1258    {
1259        DWARFCompileUnitSP cu_sp;
1260        const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1261        if (die)
1262            return GetClangDeclContextForDIE (cu_sp.get(), die);
1263    }
1264    return NULL;
1265}
1266
1267Type*
1268SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
1269{
1270    DWARFDebugInfo* debug_info = DebugInfo();
1271    if (debug_info)
1272    {
1273        DWARFCompileUnitSP cu_sp;
1274        const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
1275        if (type_die != NULL)
1276            return ResolveType (cu_sp.get(), type_die);
1277    }
1278    return NULL;
1279}
1280
1281lldb::clang_type_t
1282SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (lldb::clang_type_t clang_type)
1283{
1284    // We have a struct/union/class/enum that needs to be fully resolved.
1285    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (ClangASTType::RemoveFastQualifiers(clang_type));
1286    if (die == NULL)
1287    {
1288        // We have already resolved this type...
1289        return clang_type;
1290    }
1291    // Once we start resolving this type, remove it from the forward declaration
1292    // map in case anyone child members or other types require this type to get resolved.
1293    // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
1294    // are done.
1295    m_forward_decl_clang_type_to_die.erase (ClangASTType::RemoveFastQualifiers(clang_type));
1296
1297
1298    DWARFDebugInfo* debug_info = DebugInfo();
1299
1300    DWARFCompileUnit *curr_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
1301    Type *type = m_die_to_type.lookup (die);
1302
1303    const dw_tag_t tag = die->Tag();
1304
1305    DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") - resolve forward declaration...\n",
1306                  die->GetOffset(),
1307                  DW_TAG_value_to_name(tag),
1308                  type->GetName().AsCString());
1309    assert (clang_type);
1310    DWARFDebugInfoEntry::Attributes attributes;
1311
1312    ClangASTContext &ast = GetClangASTContext();
1313
1314    switch (tag)
1315    {
1316    case DW_TAG_structure_type:
1317    case DW_TAG_union_type:
1318    case DW_TAG_class_type:
1319        ast.StartTagDeclarationDefinition (clang_type);
1320        if (die->HasChildren())
1321        {
1322            LanguageType class_language = eLanguageTypeUnknown;
1323            bool is_objc_class = ClangASTContext::IsObjCClassType (clang_type);
1324            if (is_objc_class)
1325                class_language = eLanguageTypeObjC;
1326
1327            int tag_decl_kind = -1;
1328            AccessType default_accessibility = eAccessNone;
1329            if (tag == DW_TAG_structure_type)
1330            {
1331                tag_decl_kind = clang::TTK_Struct;
1332                default_accessibility = eAccessPublic;
1333            }
1334            else if (tag == DW_TAG_union_type)
1335            {
1336                tag_decl_kind = clang::TTK_Union;
1337                default_accessibility = eAccessPublic;
1338            }
1339            else if (tag == DW_TAG_class_type)
1340            {
1341                tag_decl_kind = clang::TTK_Class;
1342                default_accessibility = eAccessPrivate;
1343            }
1344
1345            SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1346            std::vector<clang::CXXBaseSpecifier *> base_classes;
1347            std::vector<int> member_accessibilities;
1348            bool is_a_class = false;
1349            // Parse members and base classes first
1350            DWARFDIECollection member_function_dies;
1351
1352            ParseChildMembers (sc,
1353                               curr_cu,
1354                               die,
1355                               clang_type,
1356                               class_language,
1357                               base_classes,
1358                               member_accessibilities,
1359                               member_function_dies,
1360                               default_accessibility,
1361                               is_a_class);
1362
1363            // Now parse any methods if there were any...
1364            size_t num_functions = member_function_dies.Size();
1365            if (num_functions > 0)
1366            {
1367                for (size_t i=0; i<num_functions; ++i)
1368                {
1369                    ResolveType(curr_cu, member_function_dies.GetDIEPtrAtIndex(i));
1370                }
1371            }
1372
1373            if (class_language == eLanguageTypeObjC)
1374            {
1375                std::string class_str (ClangASTContext::GetTypeName (clang_type));
1376                if (!class_str.empty())
1377                {
1378
1379                    ConstString class_name (class_str.c_str());
1380                    std::vector<NameToDIE::Info> method_die_infos;
1381                    if (m_objc_class_selectors_index.Find (class_name, method_die_infos))
1382                    {
1383                        DWARFCompileUnit* method_cu = NULL;
1384                        DWARFCompileUnit* prev_method_cu = NULL;
1385                        const size_t num_objc_methods = method_die_infos.size();
1386                        for (size_t i=0;i<num_objc_methods; ++i, prev_method_cu = method_cu)
1387                        {
1388                            method_cu = debug_info->GetCompileUnitAtIndex(method_die_infos[i].cu_idx);
1389
1390                            if (method_cu != prev_method_cu)
1391                                method_cu->ExtractDIEsIfNeeded (false);
1392
1393                            DWARFDebugInfoEntry *method_die = method_cu->GetDIEAtIndexUnchecked(method_die_infos[i].die_idx);
1394
1395                            ResolveType (method_cu, method_die);
1396                        }
1397                    }
1398                }
1399            }
1400
1401            // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
1402            // need to tell the clang type it is actually a class.
1403            if (class_language != eLanguageTypeObjC)
1404            {
1405                if (is_a_class && tag_decl_kind != clang::TTK_Class)
1406                    ast.SetTagTypeKind (clang_type, clang::TTK_Class);
1407            }
1408
1409            // Since DW_TAG_structure_type gets used for both classes
1410            // and structures, we may need to set any DW_TAG_member
1411            // fields to have a "private" access if none was specified.
1412            // When we parsed the child members we tracked that actual
1413            // accessibility value for each DW_TAG_member in the
1414            // "member_accessibilities" array. If the value for the
1415            // member is zero, then it was set to the "default_accessibility"
1416            // which for structs was "public". Below we correct this
1417            // by setting any fields to "private" that weren't correctly
1418            // set.
1419            if (is_a_class && !member_accessibilities.empty())
1420            {
1421                // This is a class and all members that didn't have
1422                // their access specified are private.
1423                ast.SetDefaultAccessForRecordFields (clang_type,
1424                                                     eAccessPrivate,
1425                                                     &member_accessibilities.front(),
1426                                                     member_accessibilities.size());
1427            }
1428
1429            if (!base_classes.empty())
1430            {
1431                ast.SetBaseClassesForClassType (clang_type,
1432                                                &base_classes.front(),
1433                                                base_classes.size());
1434
1435                // Clang will copy each CXXBaseSpecifier in "base_classes"
1436                // so we have to free them all.
1437                ClangASTContext::DeleteBaseClassSpecifiers (&base_classes.front(),
1438                                                            base_classes.size());
1439            }
1440
1441        }
1442        ast.CompleteTagDeclarationDefinition (clang_type);
1443        return clang_type;
1444
1445    case DW_TAG_enumeration_type:
1446        ast.StartTagDeclarationDefinition (clang_type);
1447        if (die->HasChildren())
1448        {
1449            SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
1450            ParseChildEnumerators(sc, clang_type, type->GetByteSize(), curr_cu, die);
1451        }
1452        ast.CompleteTagDeclarationDefinition (clang_type);
1453        return clang_type;
1454
1455    default:
1456        assert(false && "not a forward clang type decl!");
1457        break;
1458    }
1459    return NULL;
1460}
1461
1462Type*
1463SymbolFileDWARF::ResolveType (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
1464{
1465    if (type_die != NULL)
1466    {
1467        Type *type = m_die_to_type.lookup (type_die);
1468        if (type == NULL)
1469            type = GetTypeForDIE (curr_cu, type_die).get();
1470        if (assert_not_being_parsed)
1471            assert (type != DIE_IS_BEING_PARSED);
1472        return type;
1473    }
1474    return NULL;
1475}
1476
1477CompileUnit*
1478SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* curr_cu, uint32_t cu_idx)
1479{
1480    // Check if the symbol vendor already knows about this compile unit?
1481    if (curr_cu->GetUserData() == NULL)
1482    {
1483        // The symbol vendor doesn't know about this compile unit, we
1484        // need to parse and add it to the symbol vendor object.
1485        CompUnitSP dc_cu;
1486        ParseCompileUnit(curr_cu, dc_cu);
1487        if (dc_cu.get())
1488        {
1489            // Figure out the compile unit index if we weren't given one
1490            if (cu_idx == UINT32_MAX)
1491                DebugInfo()->GetCompileUnit(curr_cu->GetOffset(), &cu_idx);
1492
1493            m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(dc_cu, cu_idx);
1494
1495            if (m_debug_map_symfile)
1496                m_debug_map_symfile->SetCompileUnit(this, dc_cu);
1497        }
1498    }
1499    return (CompileUnit*)curr_cu->GetUserData();
1500}
1501
1502bool
1503SymbolFileDWARF::GetFunction (DWARFCompileUnit* curr_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
1504{
1505    sc.Clear();
1506    // Check if the symbol vendor already knows about this compile unit?
1507    sc.module_sp = m_obj_file->GetModule()->GetSP();
1508    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
1509
1510    sc.function = sc.comp_unit->FindFunctionByUID (func_die->GetOffset()).get();
1511    if (sc.function == NULL)
1512        sc.function = ParseCompileUnitFunction(sc, curr_cu, func_die);
1513
1514    return sc.function != NULL;
1515}
1516
1517uint32_t
1518SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
1519{
1520    Timer scoped_timer(__PRETTY_FUNCTION__,
1521                       "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%llx }, resolve_scope = 0x%8.8x)",
1522                       so_addr.GetSection(),
1523                       so_addr.GetOffset(),
1524                       resolve_scope);
1525    uint32_t resolved = 0;
1526    if (resolve_scope & (   eSymbolContextCompUnit |
1527                            eSymbolContextFunction |
1528                            eSymbolContextBlock |
1529                            eSymbolContextLineEntry))
1530    {
1531        lldb::addr_t file_vm_addr = so_addr.GetFileAddress();
1532
1533        DWARFDebugAranges* debug_aranges = DebugAranges();
1534        DWARFDebugInfo* debug_info = DebugInfo();
1535        if (debug_aranges)
1536        {
1537            dw_offset_t cu_offset = debug_aranges->FindAddress(file_vm_addr);
1538            if (cu_offset != DW_INVALID_OFFSET)
1539            {
1540                uint32_t cu_idx;
1541                DWARFCompileUnit* curr_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
1542                if (curr_cu)
1543                {
1544                    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
1545                    assert(sc.comp_unit != NULL);
1546                    resolved |= eSymbolContextCompUnit;
1547
1548                    if (resolve_scope & eSymbolContextLineEntry)
1549                    {
1550                        LineTable *line_table = sc.comp_unit->GetLineTable();
1551                        if (line_table == NULL)
1552                        {
1553                            if (ParseCompileUnitLineTable(sc))
1554                                line_table = sc.comp_unit->GetLineTable();
1555                        }
1556                        if (line_table != NULL)
1557                        {
1558                            if (so_addr.IsLinkedAddress())
1559                            {
1560                                Address linked_addr (so_addr);
1561                                linked_addr.ResolveLinkedAddress();
1562                                if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
1563                                {
1564                                    resolved |= eSymbolContextLineEntry;
1565                                }
1566                            }
1567                            else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
1568                            {
1569                                resolved |= eSymbolContextLineEntry;
1570                            }
1571                        }
1572                    }
1573
1574                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1575                    {
1576                        DWARFDebugInfoEntry *function_die = NULL;
1577                        DWARFDebugInfoEntry *block_die = NULL;
1578                        if (resolve_scope & eSymbolContextBlock)
1579                        {
1580                            curr_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
1581                        }
1582                        else
1583                        {
1584                            curr_cu->LookupAddress(file_vm_addr, &function_die, NULL);
1585                        }
1586
1587                        if (function_die != NULL)
1588                        {
1589                            sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1590                            if (sc.function == NULL)
1591                                sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
1592                        }
1593
1594                        if (sc.function != NULL)
1595                        {
1596                            resolved |= eSymbolContextFunction;
1597
1598                            if (resolve_scope & eSymbolContextBlock)
1599                            {
1600                                Block& block = sc.function->GetBlock (true);
1601
1602                                if (block_die != NULL)
1603                                    sc.block = block.FindBlockByID (block_die->GetOffset());
1604                                else
1605                                    sc.block = block.FindBlockByID (function_die->GetOffset());
1606                                if (sc.block)
1607                                    resolved |= eSymbolContextBlock;
1608                            }
1609                        }
1610                    }
1611                }
1612            }
1613        }
1614    }
1615    return resolved;
1616}
1617
1618
1619
1620uint32_t
1621SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
1622{
1623    const uint32_t prev_size = sc_list.GetSize();
1624    if (resolve_scope & eSymbolContextCompUnit)
1625    {
1626        DWARFDebugInfo* debug_info = DebugInfo();
1627        if (debug_info)
1628        {
1629            uint32_t cu_idx;
1630            DWARFCompileUnit* curr_cu = NULL;
1631
1632            for (cu_idx = 0; (curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
1633            {
1634                CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
1635                bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Compare(file_spec, *dc_cu, false) == 0;
1636                if (check_inlines || file_spec_matches_cu_file_spec)
1637                {
1638                    SymbolContext sc (m_obj_file->GetModule());
1639                    sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, cu_idx);
1640                    assert(sc.comp_unit != NULL);
1641
1642                    uint32_t file_idx = UINT32_MAX;
1643
1644                    // If we are looking for inline functions only and we don't
1645                    // find it in the support files, we are done.
1646                    if (check_inlines)
1647                    {
1648                        file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1649                        if (file_idx == UINT32_MAX)
1650                            continue;
1651                    }
1652
1653                    if (line != 0)
1654                    {
1655                        LineTable *line_table = sc.comp_unit->GetLineTable();
1656
1657                        if (line_table != NULL && line != 0)
1658                        {
1659                            // We will have already looked up the file index if
1660                            // we are searching for inline entries.
1661                            if (!check_inlines)
1662                                file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
1663
1664                            if (file_idx != UINT32_MAX)
1665                            {
1666                                uint32_t found_line;
1667                                uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
1668                                found_line = sc.line_entry.line;
1669
1670                                while (line_idx != UINT32_MAX)
1671                                {
1672                                    sc.function = NULL;
1673                                    sc.block = NULL;
1674                                    if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
1675                                    {
1676                                        const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
1677                                        if (file_vm_addr != LLDB_INVALID_ADDRESS)
1678                                        {
1679                                            DWARFDebugInfoEntry *function_die = NULL;
1680                                            DWARFDebugInfoEntry *block_die = NULL;
1681                                            curr_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);
1682
1683                                            if (function_die != NULL)
1684                                            {
1685                                                sc.function = sc.comp_unit->FindFunctionByUID (function_die->GetOffset()).get();
1686                                                if (sc.function == NULL)
1687                                                    sc.function = ParseCompileUnitFunction(sc, curr_cu, function_die);
1688                                            }
1689
1690                                            if (sc.function != NULL)
1691                                            {
1692                                                Block& block = sc.function->GetBlock (true);
1693
1694                                                if (block_die != NULL)
1695                                                    sc.block = block.FindBlockByID (block_die->GetOffset());
1696                                                else
1697                                                    sc.block = block.FindBlockByID (function_die->GetOffset());
1698                                            }
1699                                        }
1700                                    }
1701
1702                                    sc_list.Append(sc);
1703                                    line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
1704                                }
1705                            }
1706                        }
1707                        else if (file_spec_matches_cu_file_spec && !check_inlines)
1708                        {
1709                            // only append the context if we aren't looking for inline call sites
1710                            // by file and line and if the file spec matches that of the compile unit
1711                            sc_list.Append(sc);
1712                        }
1713                    }
1714                    else if (file_spec_matches_cu_file_spec && !check_inlines)
1715                    {
1716                        // only append the context if we aren't looking for inline call sites
1717                        // by file and line and if the file spec matches that of the compile unit
1718                        sc_list.Append(sc);
1719                    }
1720
1721                    if (!check_inlines)
1722                        break;
1723                }
1724            }
1725        }
1726    }
1727    return sc_list.GetSize() - prev_size;
1728}
1729
1730void
1731SymbolFileDWARF::Index ()
1732{
1733    if (m_indexed)
1734        return;
1735    m_indexed = true;
1736    Timer scoped_timer (__PRETTY_FUNCTION__,
1737                        "SymbolFileDWARF::Index (%s)",
1738                        GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1739
1740    DWARFDebugInfo* debug_info = DebugInfo();
1741    if (debug_info)
1742    {
1743        m_aranges.reset(new DWARFDebugAranges());
1744
1745        uint32_t cu_idx = 0;
1746        const uint32_t num_compile_units = GetNumCompileUnits();
1747        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
1748        {
1749            DWARFCompileUnit* curr_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
1750
1751            bool clear_dies = curr_cu->ExtractDIEsIfNeeded (false) > 1;
1752
1753            curr_cu->Index (cu_idx,
1754                       m_function_basename_index,
1755                       m_function_fullname_index,
1756                       m_function_method_index,
1757                       m_function_selector_index,
1758                       m_objc_class_selectors_index,
1759                       m_global_index,
1760                       m_type_index,
1761                       m_namespace_index,
1762                       DebugRanges(),
1763                       m_aranges.get());
1764
1765            // Keep memory down by clearing DIEs if this generate function
1766            // caused them to be parsed
1767            if (clear_dies)
1768                curr_cu->ClearDIEs (true);
1769        }
1770
1771        m_aranges->Sort();
1772
1773#if defined (ENABLE_DEBUG_PRINTF)
1774        StreamFile s(stdout);
1775        s.Printf ("DWARF index for (%s) '%s/%s':",
1776                  GetObjectFile()->GetModule()->GetArchitecture().AsCString(),
1777                  GetObjectFile()->GetFileSpec().GetDirectory().AsCString(),
1778                  GetObjectFile()->GetFileSpec().GetFilename().AsCString());
1779//        s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
1780//        s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
1781//        s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
1782//        s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
1783//        s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
1784//        s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s);
1785        s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
1786//        s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
1787
1788#endif
1789    }
1790}
1791
1792uint32_t
1793SymbolFileDWARF::FindGlobalVariables (const ConstString &name, bool append, uint32_t max_matches, VariableList& variables)
1794{
1795    DWARFDebugInfo* info = DebugInfo();
1796    if (info == NULL)
1797        return 0;
1798
1799    // If we aren't appending the results to this list, then clear the list
1800    if (!append)
1801        variables.Clear();
1802
1803    // Remember how many variables are in the list before we search in case
1804    // we are appending the results to a variable list.
1805    const uint32_t original_size = variables.GetSize();
1806
1807    // Index the DWARF if we haven't already
1808    if (!m_indexed)
1809        Index ();
1810
1811    SymbolContext sc;
1812    sc.module_sp = m_obj_file->GetModule()->GetSP();
1813    assert (sc.module_sp);
1814
1815    DWARFCompileUnit* curr_cu = NULL;
1816    DWARFCompileUnit* prev_cu = NULL;
1817    const DWARFDebugInfoEntry* die = NULL;
1818    std::vector<NameToDIE::Info> die_info_array;
1819    const size_t num_matches = m_global_index.Find(name, die_info_array);
1820    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
1821    {
1822        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1823
1824        if (curr_cu != prev_cu)
1825            curr_cu->ExtractDIEsIfNeeded (false);
1826
1827        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1828
1829        sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
1830        assert(sc.comp_unit != NULL);
1831
1832        ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
1833
1834        if (variables.GetSize() - original_size >= max_matches)
1835            break;
1836    }
1837
1838    // Return the number of variable that were appended to the list
1839    return variables.GetSize() - original_size;
1840}
1841
1842uint32_t
1843SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
1844{
1845    DWARFDebugInfo* info = DebugInfo();
1846    if (info == NULL)
1847        return 0;
1848
1849    // If we aren't appending the results to this list, then clear the list
1850    if (!append)
1851        variables.Clear();
1852
1853    // Remember how many variables are in the list before we search in case
1854    // we are appending the results to a variable list.
1855    const uint32_t original_size = variables.GetSize();
1856
1857    // Index the DWARF if we haven't already
1858    if (!m_indexed)
1859        Index ();
1860
1861    SymbolContext sc;
1862    sc.module_sp = m_obj_file->GetModule()->GetSP();
1863    assert (sc.module_sp);
1864
1865    DWARFCompileUnit* curr_cu = NULL;
1866    DWARFCompileUnit* prev_cu = NULL;
1867    const DWARFDebugInfoEntry* die = NULL;
1868    std::vector<NameToDIE::Info> die_info_array;
1869    const size_t num_matches = m_global_index.Find(regex, die_info_array);
1870    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
1871    {
1872        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1873
1874        if (curr_cu != prev_cu)
1875            curr_cu->ExtractDIEsIfNeeded (false);
1876
1877        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1878
1879        sc.comp_unit = GetCompUnitForDWARFCompUnit(curr_cu, UINT32_MAX);
1880        assert(sc.comp_unit != NULL);
1881
1882        ParseVariables(sc, curr_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);
1883
1884        if (variables.GetSize() - original_size >= max_matches)
1885            break;
1886    }
1887
1888    // Return the number of variable that were appended to the list
1889    return variables.GetSize() - original_size;
1890}
1891
1892
1893void
1894SymbolFileDWARF::FindFunctions
1895(
1896    const ConstString &name,
1897    const NameToDIE &name_to_die,
1898    SymbolContextList& sc_list
1899)
1900{
1901    DWARFDebugInfo* info = DebugInfo();
1902    if (info == NULL)
1903        return;
1904
1905    SymbolContext sc;
1906    sc.module_sp = m_obj_file->GetModule()->GetSP();
1907    assert (sc.module_sp);
1908
1909    DWARFCompileUnit* curr_cu = NULL;
1910    DWARFCompileUnit* prev_cu = NULL;
1911    const DWARFDebugInfoEntry* die = NULL;
1912    std::vector<NameToDIE::Info> die_info_array;
1913    const size_t num_matches = name_to_die.Find(name, die_info_array);
1914    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
1915    {
1916        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1917
1918        if (curr_cu != prev_cu)
1919            curr_cu->ExtractDIEsIfNeeded (false);
1920
1921        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1922        if (GetFunction (curr_cu, die, sc))
1923        {
1924            // We found the function, so we should find the line table
1925            // and line table entry as well
1926            LineTable *line_table = sc.comp_unit->GetLineTable();
1927            if (line_table == NULL)
1928            {
1929                if (ParseCompileUnitLineTable(sc))
1930                    line_table = sc.comp_unit->GetLineTable();
1931            }
1932            if (line_table != NULL)
1933                line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1934
1935            sc_list.Append(sc);
1936        }
1937    }
1938}
1939
1940
1941void
1942SymbolFileDWARF::FindFunctions
1943(
1944    const RegularExpression &regex,
1945    const NameToDIE &name_to_die,
1946    SymbolContextList& sc_list
1947)
1948{
1949    DWARFDebugInfo* info = DebugInfo();
1950    if (info == NULL)
1951        return;
1952
1953    SymbolContext sc;
1954    sc.module_sp = m_obj_file->GetModule()->GetSP();
1955    assert (sc.module_sp);
1956
1957    DWARFCompileUnit* curr_cu = NULL;
1958    DWARFCompileUnit* prev_cu = NULL;
1959    const DWARFDebugInfoEntry* die = NULL;
1960    std::vector<NameToDIE::Info> die_info_array;
1961    const size_t num_matches = name_to_die.Find(regex, die_info_array);
1962    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
1963    {
1964        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
1965
1966        if (curr_cu != prev_cu)
1967            curr_cu->ExtractDIEsIfNeeded (false);
1968
1969        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
1970        if (GetFunction (curr_cu, die, sc))
1971        {
1972            // We found the function, so we should find the line table
1973            // and line table entry as well
1974            LineTable *line_table = sc.comp_unit->GetLineTable();
1975            if (line_table == NULL)
1976            {
1977                if (ParseCompileUnitLineTable(sc))
1978                    line_table = sc.comp_unit->GetLineTable();
1979            }
1980            if (line_table != NULL)
1981                line_table->FindLineEntryByAddress (sc.function->GetAddressRange().GetBaseAddress(), sc.line_entry);
1982
1983            sc_list.Append(sc);
1984        }
1985    }
1986}
1987
1988uint32_t
1989SymbolFileDWARF::FindFunctions
1990(
1991    const ConstString &name,
1992    uint32_t name_type_mask,
1993    bool append,
1994    SymbolContextList& sc_list
1995)
1996{
1997    Timer scoped_timer (__PRETTY_FUNCTION__,
1998                        "SymbolFileDWARF::FindFunctions (name = '%s')",
1999                        name.AsCString());
2000
2001    // If we aren't appending the results to this list, then clear the list
2002    if (!append)
2003        sc_list.Clear();
2004
2005    // Remember how many sc_list are in the list before we search in case
2006    // we are appending the results to a variable list.
2007    uint32_t original_size = sc_list.GetSize();
2008
2009    // Index the DWARF if we haven't already
2010    if (!m_indexed)
2011        Index ();
2012
2013    if (name_type_mask & eFunctionNameTypeBase)
2014        FindFunctions (name, m_function_basename_index, sc_list);
2015
2016    if (name_type_mask & eFunctionNameTypeFull)
2017        FindFunctions (name, m_function_fullname_index, sc_list);
2018
2019    if (name_type_mask & eFunctionNameTypeMethod)
2020        FindFunctions (name, m_function_method_index, sc_list);
2021
2022    if (name_type_mask & eFunctionNameTypeSelector)
2023        FindFunctions (name, m_function_selector_index, sc_list);
2024
2025    // Return the number of variable that were appended to the list
2026    return sc_list.GetSize() - original_size;
2027}
2028
2029
2030uint32_t
2031SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool append, SymbolContextList& sc_list)
2032{
2033    Timer scoped_timer (__PRETTY_FUNCTION__,
2034                        "SymbolFileDWARF::FindFunctions (regex = '%s')",
2035                        regex.GetText());
2036
2037    // If we aren't appending the results to this list, then clear the list
2038    if (!append)
2039        sc_list.Clear();
2040
2041    // Remember how many sc_list are in the list before we search in case
2042    // we are appending the results to a variable list.
2043    uint32_t original_size = sc_list.GetSize();
2044
2045    // Index the DWARF if we haven't already
2046    if (!m_indexed)
2047        Index ();
2048
2049    FindFunctions (regex, m_function_basename_index, sc_list);
2050
2051    FindFunctions (regex, m_function_fullname_index, sc_list);
2052
2053    // Return the number of variable that were appended to the list
2054    return sc_list.GetSize() - original_size;
2055}
2056
2057uint32_t
2058SymbolFileDWARF::FindTypes(const SymbolContext& sc, const ConstString &name, bool append, uint32_t max_matches, TypeList& types)
2059{
2060    DWARFDebugInfo* info = DebugInfo();
2061    if (info == NULL)
2062        return 0;
2063
2064    // If we aren't appending the results to this list, then clear the list
2065    if (!append)
2066        types.Clear();
2067
2068    // Index if we already haven't to make sure the compile units
2069    // get indexed and make their global DIE index list
2070    if (!m_indexed)
2071        Index ();
2072
2073    const uint32_t initial_types_size = types.GetSize();
2074    DWARFCompileUnit* curr_cu = NULL;
2075    DWARFCompileUnit* prev_cu = NULL;
2076    const DWARFDebugInfoEntry* die = NULL;
2077    std::vector<NameToDIE::Info> die_info_array;
2078    const size_t num_matches = m_type_index.Find (name, die_info_array);
2079    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2080    {
2081        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2082
2083        if (curr_cu != prev_cu)
2084            curr_cu->ExtractDIEsIfNeeded (false);
2085
2086        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2087
2088        Type *matching_type = ResolveType (curr_cu, die);
2089        if (matching_type)
2090        {
2091            // We found a type pointer, now find the shared pointer form our type list
2092            TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
2093            assert (type_sp.get() != NULL);
2094            types.InsertUnique (type_sp);
2095            if (types.GetSize() >= max_matches)
2096                break;
2097        }
2098    }
2099    return types.GetSize() - initial_types_size;
2100}
2101
2102
2103clang::NamespaceDecl *
2104SymbolFileDWARF::FindNamespace (const SymbolContext& sc,
2105                                const ConstString &name)
2106{
2107    DWARFDebugInfo* info = DebugInfo();
2108    if (info == NULL)
2109        return 0;
2110
2111    // Index if we already haven't to make sure the compile units
2112    // get indexed and make their global DIE index list
2113    if (!m_indexed)
2114        Index ();
2115
2116    DWARFCompileUnit* curr_cu = NULL;
2117    DWARFCompileUnit* prev_cu = NULL;
2118    const DWARFDebugInfoEntry* die = NULL;
2119    std::vector<NameToDIE::Info> die_info_array;
2120    const size_t num_matches = m_namespace_index.Find (name, die_info_array);
2121    for (size_t i=0; i<num_matches; ++i, prev_cu = curr_cu)
2122    {
2123        curr_cu = info->GetCompileUnitAtIndex(die_info_array[i].cu_idx);
2124
2125        if (curr_cu != prev_cu)
2126            curr_cu->ExtractDIEsIfNeeded (false);
2127
2128        die = curr_cu->GetDIEAtIndexUnchecked(die_info_array[i].die_idx);
2129
2130        return ResolveNamespaceDIE (curr_cu, die);
2131    }
2132    return NULL;
2133}
2134
2135uint32_t
2136SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
2137{
2138    // Remember how many sc_list are in the list before we search in case
2139    // we are appending the results to a variable list.
2140    uint32_t original_size = types.GetSize();
2141
2142    const uint32_t num_die_offsets = die_offsets.size();
2143    // Parse all of the types we found from the pubtypes matches
2144    uint32_t i;
2145    uint32_t num_matches = 0;
2146    for (i = 0; i < num_die_offsets; ++i)
2147    {
2148        Type *matching_type = ResolveTypeUID (die_offsets[i]);
2149        if (matching_type)
2150        {
2151            // We found a type pointer, now find the shared pointer form our type list
2152            TypeSP type_sp (GetTypeList()->FindType(matching_type->GetID()));
2153            assert (type_sp.get() != NULL);
2154            types.InsertUnique (type_sp);
2155            ++num_matches;
2156            if (num_matches >= max_matches)
2157                break;
2158        }
2159    }
2160
2161    // Return the number of variable that were appended to the list
2162    return types.GetSize() - original_size;
2163}
2164
2165
2166size_t
2167SymbolFileDWARF::ParseChildParameters
2168(
2169    const SymbolContext& sc,
2170    TypeSP& type_sp,
2171    DWARFCompileUnit* dwarf_cu,
2172    const DWARFDebugInfoEntry *parent_die,
2173    bool skip_artificial,
2174    TypeList* type_list,
2175    std::vector<clang_type_t>& function_param_types,
2176    std::vector<clang::ParmVarDecl*>& function_param_decls
2177)
2178{
2179    if (parent_die == NULL)
2180        return 0;
2181
2182    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2183
2184    size_t count = 0;
2185    const DWARFDebugInfoEntry *die;
2186    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2187    {
2188        dw_tag_t tag = die->Tag();
2189        switch (tag)
2190        {
2191        case DW_TAG_formal_parameter:
2192            {
2193                DWARFDebugInfoEntry::Attributes attributes;
2194                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
2195                if (num_attributes > 0)
2196                {
2197                    const char *name = NULL;
2198                    Declaration decl;
2199                    dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
2200                    bool is_artificial = false;
2201                    // one of None, Auto, Register, Extern, Static, PrivateExtern
2202
2203                    clang::StorageClass storage = clang::SC_None;
2204                    uint32_t i;
2205                    for (i=0; i<num_attributes; ++i)
2206                    {
2207                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2208                        DWARFFormValue form_value;
2209                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2210                        {
2211                            switch (attr)
2212                            {
2213                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2214                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2215                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2216                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
2217                            case DW_AT_type:        param_type_die_offset = form_value.Reference(dwarf_cu); break;
2218                            case DW_AT_artificial:  is_artificial = form_value.Unsigned() != 0; break;
2219                            case DW_AT_location:
2220    //                          if (form_value.BlockData())
2221    //                          {
2222    //                              const DataExtractor& debug_info_data = debug_info();
2223    //                              uint32_t block_length = form_value.Unsigned();
2224    //                              DataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
2225    //                          }
2226    //                          else
2227    //                          {
2228    //                          }
2229    //                          break;
2230                            case DW_AT_const_value:
2231                            case DW_AT_default_value:
2232                            case DW_AT_description:
2233                            case DW_AT_endianity:
2234                            case DW_AT_is_optional:
2235                            case DW_AT_segment:
2236                            case DW_AT_variable_parameter:
2237                            default:
2238                            case DW_AT_abstract_origin:
2239                            case DW_AT_sibling:
2240                                break;
2241                            }
2242                        }
2243                    }
2244
2245                    bool skip = false;
2246                    if (skip_artificial)
2247                    {
2248                        if (is_artificial)
2249                            skip = true;
2250                        else
2251                        {
2252
2253                            // HACK: Objective C formal parameters "self" and "_cmd"
2254                            // are not marked as artificial in the DWARF...
2255                            CompileUnit *curr_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
2256                            if (curr_cu && (curr_cu->GetLanguage() == eLanguageTypeObjC || curr_cu->GetLanguage() == eLanguageTypeObjC_plus_plus))
2257                            {
2258                                if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
2259                                    skip = true;
2260                            }
2261                        }
2262                    }
2263
2264                    if (!skip)
2265                    {
2266                        Type *type = ResolveTypeUID(param_type_die_offset);
2267                        if (type)
2268                        {
2269                            function_param_types.push_back (type->GetClangForwardType());
2270
2271                            clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, type->GetClangForwardType(), storage);
2272                            assert(param_var_decl);
2273                            function_param_decls.push_back(param_var_decl);
2274                        }
2275                    }
2276                }
2277            }
2278            break;
2279
2280        default:
2281            break;
2282        }
2283    }
2284    return count;
2285}
2286
2287size_t
2288SymbolFileDWARF::ParseChildEnumerators
2289(
2290    const SymbolContext& sc,
2291    clang_type_t  enumerator_clang_type,
2292    uint32_t enumerator_byte_size,
2293    DWARFCompileUnit* dwarf_cu,
2294    const DWARFDebugInfoEntry *parent_die
2295)
2296{
2297    if (parent_die == NULL)
2298        return 0;
2299
2300    size_t enumerators_added = 0;
2301    const DWARFDebugInfoEntry *die;
2302    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2303
2304    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2305    {
2306        const dw_tag_t tag = die->Tag();
2307        if (tag == DW_TAG_enumerator)
2308        {
2309            DWARFDebugInfoEntry::Attributes attributes;
2310            const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
2311            if (num_child_attributes > 0)
2312            {
2313                const char *name = NULL;
2314                bool got_value = false;
2315                int64_t enum_value = 0;
2316                Declaration decl;
2317
2318                uint32_t i;
2319                for (i=0; i<num_child_attributes; ++i)
2320                {
2321                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
2322                    DWARFFormValue form_value;
2323                    if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2324                    {
2325                        switch (attr)
2326                        {
2327                        case DW_AT_const_value:
2328                            got_value = true;
2329                            enum_value = form_value.Unsigned();
2330                            break;
2331
2332                        case DW_AT_name:
2333                            name = form_value.AsCString(&get_debug_str_data());
2334                            break;
2335
2336                        case DW_AT_description:
2337                        default:
2338                        case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2339                        case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2340                        case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2341                        case DW_AT_sibling:
2342                            break;
2343                        }
2344                    }
2345                }
2346
2347                if (name && name[0] && got_value)
2348                {
2349                    GetClangASTContext().AddEnumerationValueToEnumerationType (enumerator_clang_type,
2350                                                                               enumerator_clang_type,
2351                                                                               decl,
2352                                                                               name,
2353                                                                               enum_value,
2354                                                                               enumerator_byte_size * 8);
2355                    ++enumerators_added;
2356                }
2357            }
2358        }
2359    }
2360    return enumerators_added;
2361}
2362
2363void
2364SymbolFileDWARF::ParseChildArrayInfo
2365(
2366    const SymbolContext& sc,
2367    DWARFCompileUnit* dwarf_cu,
2368    const DWARFDebugInfoEntry *parent_die,
2369    int64_t& first_index,
2370    std::vector<uint64_t>& element_orders,
2371    uint32_t& byte_stride,
2372    uint32_t& bit_stride
2373)
2374{
2375    if (parent_die == NULL)
2376        return;
2377
2378    const DWARFDebugInfoEntry *die;
2379    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize());
2380    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
2381    {
2382        const dw_tag_t tag = die->Tag();
2383        switch (tag)
2384        {
2385        case DW_TAG_enumerator:
2386            {
2387                DWARFDebugInfoEntry::Attributes attributes;
2388                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
2389                if (num_child_attributes > 0)
2390                {
2391                    const char *name = NULL;
2392                    bool got_value = false;
2393                    int64_t enum_value = 0;
2394
2395                    uint32_t i;
2396                    for (i=0; i<num_child_attributes; ++i)
2397                    {
2398                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2399                        DWARFFormValue form_value;
2400                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2401                        {
2402                            switch (attr)
2403                            {
2404                            case DW_AT_const_value:
2405                                got_value = true;
2406                                enum_value = form_value.Unsigned();
2407                                break;
2408
2409                            case DW_AT_name:
2410                                name = form_value.AsCString(&get_debug_str_data());
2411                                break;
2412
2413                            case DW_AT_description:
2414                            default:
2415                            case DW_AT_decl_file:
2416                            case DW_AT_decl_line:
2417                            case DW_AT_decl_column:
2418                            case DW_AT_sibling:
2419                                break;
2420                            }
2421                        }
2422                    }
2423                }
2424            }
2425            break;
2426
2427        case DW_TAG_subrange_type:
2428            {
2429                DWARFDebugInfoEntry::Attributes attributes;
2430                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
2431                if (num_child_attributes > 0)
2432                {
2433                    const char *name = NULL;
2434                    bool got_value = false;
2435                    uint64_t byte_size = 0;
2436                    int64_t enum_value = 0;
2437                    uint64_t num_elements = 0;
2438                    uint64_t lower_bound = 0;
2439                    uint64_t upper_bound = 0;
2440                    uint32_t i;
2441                    for (i=0; i<num_child_attributes; ++i)
2442                    {
2443                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
2444                        DWARFFormValue form_value;
2445                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2446                        {
2447                            switch (attr)
2448                            {
2449                            case DW_AT_const_value:
2450                                got_value = true;
2451                                enum_value = form_value.Unsigned();
2452                                break;
2453
2454                            case DW_AT_name:
2455                                name = form_value.AsCString(&get_debug_str_data());
2456                                break;
2457
2458                            case DW_AT_count:
2459                                num_elements = form_value.Unsigned();
2460                                break;
2461
2462                            case DW_AT_bit_stride:
2463                                bit_stride = form_value.Unsigned();
2464                                break;
2465
2466                            case DW_AT_byte_stride:
2467                                byte_stride = form_value.Unsigned();
2468                                break;
2469
2470                            case DW_AT_byte_size:
2471                                byte_size = form_value.Unsigned();
2472                                break;
2473
2474                            case DW_AT_lower_bound:
2475                                lower_bound = form_value.Unsigned();
2476                                break;
2477
2478                            case DW_AT_upper_bound:
2479                                upper_bound = form_value.Unsigned();
2480                                break;
2481
2482                            default:
2483                            case DW_AT_abstract_origin:
2484                            case DW_AT_accessibility:
2485                            case DW_AT_allocated:
2486                            case DW_AT_associated:
2487                            case DW_AT_data_location:
2488                            case DW_AT_declaration:
2489                            case DW_AT_description:
2490                            case DW_AT_sibling:
2491                            case DW_AT_threads_scaled:
2492                            case DW_AT_type:
2493                            case DW_AT_visibility:
2494                                break;
2495                            }
2496                        }
2497                    }
2498
2499                    if (upper_bound > lower_bound)
2500                        num_elements = upper_bound - lower_bound + 1;
2501
2502                    if (num_elements > 0)
2503                        element_orders.push_back (num_elements);
2504                }
2505            }
2506            break;
2507        }
2508    }
2509}
2510
2511TypeSP
2512SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry* die)
2513{
2514    TypeSP type_sp;
2515    if (die != NULL)
2516    {
2517        assert(curr_cu != NULL);
2518        Type *type_ptr = m_die_to_type.lookup (die);
2519        if (type_ptr == NULL)
2520        {
2521            SymbolContext sc(GetCompUnitForDWARFCompUnit(curr_cu));
2522            type_sp = ParseType(sc, curr_cu, die, NULL);
2523        }
2524        else if (type_ptr != DIE_IS_BEING_PARSED)
2525        {
2526            // Grab the existing type from the master types lists
2527            type_sp = GetTypeList()->FindType(type_ptr->GetID());
2528        }
2529
2530    }
2531    return type_sp;
2532}
2533
2534clang::DeclContext *
2535SymbolFileDWARF::GetClangDeclContextForDIEOffset (dw_offset_t die_offset)
2536{
2537    if (die_offset != DW_INVALID_OFFSET)
2538    {
2539        DWARFCompileUnitSP cu_sp;
2540        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
2541        return GetClangDeclContextForDIE (cu_sp.get(), die);
2542    }
2543    return NULL;
2544}
2545
2546
2547clang::NamespaceDecl *
2548SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2549{
2550    if (die->Tag() == DW_TAG_namespace)
2551    {
2552        const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2553        if (namespace_name)
2554        {
2555            Declaration decl;   // TODO: fill in the decl object
2556            clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2557            if (namespace_decl)
2558                m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2559            return namespace_decl;
2560        }
2561    }
2562    return NULL;
2563}
2564
2565clang::DeclContext *
2566SymbolFileDWARF::GetClangDeclContextForDIE (DWARFCompileUnit *curr_cu, const DWARFDebugInfoEntry *die)
2567{
2568    DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die);
2569    if (pos != m_die_to_decl_ctx.end())
2570        return pos->second;
2571
2572    while (die != NULL)
2573    {
2574        switch (die->Tag())
2575        {
2576        case DW_TAG_namespace:
2577            {
2578                const char *namespace_name = die->GetAttributeValueAsString(this, curr_cu, DW_AT_name, NULL);
2579                if (namespace_name)
2580                {
2581                    Declaration decl;   // TODO: fill in the decl object
2582                    clang::NamespaceDecl *namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, decl, GetClangDeclContextForDIE (curr_cu, die->GetParent()));
2583                    if (namespace_decl)
2584                        m_die_to_decl_ctx[die] = (clang::DeclContext*)namespace_decl;
2585                    return namespace_decl;
2586                }
2587            }
2588            break;
2589
2590        default:
2591            break;
2592        }
2593        clang::DeclContext *decl_ctx;
2594        decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_specification, DW_INVALID_OFFSET));
2595        if (decl_ctx)
2596            return decl_ctx;
2597
2598        decl_ctx = GetClangDeclContextForDIEOffset (die->GetAttributeValueAsUnsigned(this, curr_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET));
2599        if (decl_ctx)
2600            return decl_ctx;
2601
2602        die = die->GetParent();
2603    }
2604    // Right now we have only one translation unit per module...
2605    if (m_clang_tu_decl == NULL)
2606        m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();
2607    return m_clang_tu_decl;
2608}
2609
2610// This function can be used when a DIE is found that is a forward declaration
2611// DIE and we want to try and find a type that has the complete definition.
2612TypeSP
2613SymbolFileDWARF::FindDefinitionTypeForDIE (
2614    DWARFCompileUnit* curr_cu,
2615    const DWARFDebugInfoEntry *die,
2616    const ConstString &type_name
2617)
2618{
2619    TypeSP type_sp;
2620
2621    if (curr_cu == NULL || die == NULL || !type_name)
2622        return type_sp;
2623
2624    const dw_tag_t type_tag = die->Tag();
2625    std::vector<NameToDIE::Info> die_info_array;
2626    const size_t num_matches = m_type_index.Find (type_name, die_info_array);
2627    if (num_matches > 0)
2628    {
2629        DWARFCompileUnit* type_cu = NULL;
2630        DWARFCompileUnit* curr_cu = curr_cu;
2631        DWARFDebugInfo *info = DebugInfo();
2632        for (size_t i=0; i<num_matches; ++i)
2633        {
2634            type_cu = info->GetCompileUnitAtIndex (die_info_array[i].cu_idx);
2635
2636            if (type_cu != curr_cu)
2637            {
2638                type_cu->ExtractDIEsIfNeeded (false);
2639                curr_cu = type_cu;
2640            }
2641
2642            DWARFDebugInfoEntry *type_die = type_cu->GetDIEAtIndexUnchecked (die_info_array[i].die_idx);
2643
2644            if (type_die != die && type_die->Tag() == type_tag)
2645            {
2646                // Hold off on comparing parent DIE tags until
2647                // we know what happens with stuff in namespaces
2648                // for gcc and clang...
2649                //DWARFDebugInfoEntry *parent_die = die->GetParent();
2650                //DWARFDebugInfoEntry *parent_type_die = type_die->GetParent();
2651                //if (parent_die->Tag() == parent_type_die->Tag())
2652                {
2653                    Type *resolved_type = ResolveType (type_cu, type_die, false);
2654                    if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
2655                    {
2656                        DEBUG_PRINTF ("resolved 0x%8.8x (cu 0x%8.8x) from %s to 0x%8.8x (cu 0x%8.8x)\n",
2657                                      die->GetOffset(),
2658                                      curr_cu->GetOffset(),
2659                                      m_obj_file->GetFileSpec().GetFilename().AsCString(),
2660                                      type_die->GetOffset(),
2661                                      type_cu->GetOffset());
2662
2663                        m_die_to_type[die] = resolved_type;
2664                        type_sp = GetTypeList()->FindType(resolved_type->GetID());
2665                        if (!type_sp)
2666                        {
2667                            DEBUG_PRINTF("unable to resolve type '%s' from DIE 0x%8.8x\n", type_name.GetCString(), die->GetOffset());
2668                        }
2669                        break;
2670                    }
2671                }
2672            }
2673        }
2674    }
2675    return type_sp;
2676}
2677
2678TypeSP
2679SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
2680{
2681    TypeSP type_sp;
2682
2683    if (type_is_new_ptr)
2684        *type_is_new_ptr = false;
2685
2686    AccessType accessibility = eAccessNone;
2687    if (die != NULL)
2688    {
2689        Type *type_ptr = m_die_to_type.lookup (die);
2690        TypeList* type_list = GetTypeList();
2691        if (type_ptr == NULL)
2692        {
2693            ClangASTContext &ast = GetClangASTContext();
2694            if (type_is_new_ptr)
2695                *type_is_new_ptr = true;
2696
2697            const dw_tag_t tag = die->Tag();
2698
2699            bool is_forward_declaration = false;
2700            DWARFDebugInfoEntry::Attributes attributes;
2701            const char *type_name_cstr = NULL;
2702            ConstString type_name_const_str;
2703            Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
2704            clang_type_t clang_type = NULL;
2705
2706            dw_attr_t attr;
2707
2708            switch (tag)
2709            {
2710            case DW_TAG_base_type:
2711            case DW_TAG_pointer_type:
2712            case DW_TAG_reference_type:
2713            case DW_TAG_typedef:
2714            case DW_TAG_const_type:
2715            case DW_TAG_restrict_type:
2716            case DW_TAG_volatile_type:
2717                {
2718                    // Set a bit that lets us know that we are currently parsing this
2719                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
2720
2721                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
2722                    Declaration decl;
2723                    uint32_t encoding = 0;
2724                    size_t byte_size = 0;
2725                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
2726
2727                    if (num_attributes > 0)
2728                    {
2729                        uint32_t i;
2730                        for (i=0; i<num_attributes; ++i)
2731                        {
2732                            attr = attributes.AttributeAtIndex(i);
2733                            DWARFFormValue form_value;
2734                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2735                            {
2736                                switch (attr)
2737                                {
2738                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
2739                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
2740                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
2741                                case DW_AT_name:
2742                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
2743                                    type_name_const_str.SetCString(type_name_cstr);
2744                                    break;
2745                                case DW_AT_byte_size:   byte_size = form_value.Unsigned();  break;
2746                                case DW_AT_encoding:    encoding = form_value.Unsigned(); break;
2747                                case DW_AT_type:        encoding_uid = form_value.Reference(dwarf_cu); break;
2748                                default:
2749                                case DW_AT_sibling:
2750                                    break;
2751                                }
2752                            }
2753                        }
2754                    }
2755
2756                    DEBUG_PRINTF ("0x%8.8x: %s (\"%s\") type => 0x%8.8x\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);
2757
2758                    switch (tag)
2759                    {
2760                    default:
2761                    case DW_TAG_base_type:
2762                        clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr,
2763                                                                                   encoding,
2764                                                                                   byte_size * 8);
2765                        break;
2766
2767                    case DW_TAG_pointer_type:
2768                        // The encoding_uid will be embedded into the
2769                        // Type object and will be looked up when the Type::GetClangType()
2770                        encoding_data_type = Type::eEncodingIsPointerUID;
2771                        break;
2772
2773                    case DW_TAG_reference_type:
2774                        // The encoding_uid will be embedded into the
2775                        // Type object and will be looked up when the Type::GetClangType()
2776                        encoding_data_type = Type::eEncodingIsLValueReferenceUID;
2777                        break;
2778
2779                    case DW_TAG_typedef:
2780                        // The encoding_uid will be embedded into the
2781                        // Type object and will be looked up when the Type::GetClangType()
2782                        encoding_data_type = Type::eEncodingIsTypedefUID;
2783                        break;
2784
2785                    case DW_TAG_const_type:
2786                        // The encoding_uid will be embedded into the
2787                        // Type object and will be looked up when the Type::GetClangType()
2788                        encoding_data_type = Type::eEncodingIsConstUID; //ClangASTContext::AddConstModifier (clang_type);
2789                        break;
2790
2791                    case DW_TAG_restrict_type:
2792                        // The encoding_uid will be embedded into the
2793                        // Type object and will be looked up when the Type::GetClangType()
2794                        encoding_data_type = Type::eEncodingIsRestrictUID; //ClangASTContext::AddRestrictModifier (clang_type);
2795                        break;
2796
2797                    case DW_TAG_volatile_type:
2798                        // The encoding_uid will be embedded into the
2799                        // Type object and will be looked up when the Type::GetClangType()
2800                        encoding_data_type = Type::eEncodingIsVolatileUID; //ClangASTContext::AddVolatileModifier (clang_type);
2801                        break;
2802                    }
2803
2804                    if (type_name_cstr != NULL && sc.comp_unit != NULL &&
2805                        (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus))
2806                    {
2807                        static ConstString g_objc_type_name_id("id");
2808                        static ConstString g_objc_type_name_Class("Class");
2809                        static ConstString g_objc_type_name_selector("SEL");
2810
2811                        if (type_name_const_str == g_objc_type_name_id)
2812                        {
2813                            clang_type = ast.GetBuiltInType_objc_id();
2814                        }
2815                        else if (type_name_const_str == g_objc_type_name_Class)
2816                        {
2817                            clang_type = ast.GetBuiltInType_objc_Class();
2818                        }
2819                        else if (type_name_const_str == g_objc_type_name_selector)
2820                        {
2821                            clang_type = ast.GetBuiltInType_objc_selector();
2822                        }
2823                    }
2824
2825                    type_sp.reset( new Type (die->GetOffset(),
2826                                             this,
2827                                             type_name_const_str,
2828                                             byte_size,
2829                                             NULL,
2830                                             encoding_uid,
2831                                             encoding_data_type,
2832                                             &decl,
2833                                             clang_type,
2834                                             clang_type == NULL));
2835
2836                    m_die_to_type[die] = type_sp.get();
2837
2838//                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
2839//                  if (encoding_type != NULL)
2840//                  {
2841//                      if (encoding_type != DIE_IS_BEING_PARSED)
2842//                          type_sp->SetEncodingType(encoding_type);
2843//                      else
2844//                          m_indirect_fixups.push_back(type_sp.get());
2845//                  }
2846                }
2847                break;
2848
2849            case DW_TAG_structure_type:
2850            case DW_TAG_union_type:
2851            case DW_TAG_class_type:
2852                {
2853                    // Set a bit that lets us know that we are currently parsing this
2854                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
2855
2856                    size_t byte_size = 0;
2857                    LanguageType class_language = eLanguageTypeUnknown;
2858                    //bool struct_is_class = false;
2859                    Declaration decl;
2860                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
2861                    if (num_attributes > 0)
2862                    {
2863                        uint32_t i;
2864                        for (i=0; i<num_attributes; ++i)
2865                        {
2866                            attr = attributes.AttributeAtIndex(i);
2867                            DWARFFormValue form_value;
2868                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
2869                            {
2870                                switch (attr)
2871                                {
2872                                case DW_AT_decl_file:
2873                                    decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned()));
2874                                    break;
2875
2876                                case DW_AT_decl_line:
2877                                    decl.SetLine(form_value.Unsigned());
2878                                    break;
2879
2880                                case DW_AT_decl_column:
2881                                    decl.SetColumn(form_value.Unsigned());
2882                                    break;
2883
2884                                case DW_AT_name:
2885                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
2886                                    type_name_const_str.SetCString(type_name_cstr);
2887                                    break;
2888
2889                                case DW_AT_byte_size:
2890                                    byte_size = form_value.Unsigned();
2891                                    break;
2892
2893                                case DW_AT_accessibility:
2894                                    accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2895                                    break;
2896
2897                                case DW_AT_declaration:
2898                                    is_forward_declaration = form_value.Unsigned() != 0;
2899                                    break;
2900
2901                                case DW_AT_APPLE_runtime_class:
2902                                    class_language = (LanguageType)form_value.Signed();
2903                                    break;
2904
2905                                case DW_AT_allocated:
2906                                case DW_AT_associated:
2907                                case DW_AT_data_location:
2908                                case DW_AT_description:
2909                                case DW_AT_start_scope:
2910                                case DW_AT_visibility:
2911                                default:
2912                                case DW_AT_sibling:
2913                                    break;
2914                                }
2915                            }
2916                        }
2917                    }
2918
2919                    DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
2920
2921                    int tag_decl_kind = -1;
2922                    AccessType default_accessibility = eAccessNone;
2923                    if (tag == DW_TAG_structure_type)
2924                    {
2925                        tag_decl_kind = clang::TTK_Struct;
2926                        default_accessibility = eAccessPublic;
2927                    }
2928                    else if (tag == DW_TAG_union_type)
2929                    {
2930                        tag_decl_kind = clang::TTK_Union;
2931                        default_accessibility = eAccessPublic;
2932                    }
2933                    else if (tag == DW_TAG_class_type)
2934                    {
2935                        tag_decl_kind = clang::TTK_Class;
2936                        default_accessibility = eAccessPrivate;
2937                    }
2938
2939
2940                    if (is_forward_declaration)
2941                    {
2942                        // We have a forward declaration to a type and we need
2943                        // to try and find a full declaration. We look in the
2944                        // current type index just in case we have a forward
2945                        // declaration followed by an actual declarations in the
2946                        // DWARF. If this fails, we need to look elsewhere...
2947
2948                        type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
2949
2950                        if (!type_sp)
2951                        {
2952                            // We weren't able to find a full declaration in
2953                            // this DWARF, see if we have a declaration anywhere
2954                            // else...
2955                            if (m_debug_map_symfile)
2956                                type_sp = m_debug_map_symfile->FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
2957                        }
2958                        if (type_sp)
2959                            return type_sp;
2960                    }
2961                    assert (tag_decl_kind != -1);
2962                    bool clang_type_was_created = false;
2963                    clang_type = m_forward_decl_die_to_clang_type.lookup (die);
2964                    if (clang_type == NULL)
2965                    {
2966                        clang_type_was_created = true;
2967                        clang_type = ast.CreateRecordType (type_name_cstr,
2968                                                           tag_decl_kind,
2969                                                           GetClangDeclContextForDIE (dwarf_cu, die),
2970                                                           class_language);
2971                    }
2972
2973                    // Store a forward declaration to this class type in case any
2974                    // parameters in any class methods need it for the clang
2975                    // types for function prototypes.
2976                    m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
2977                    const bool is_forward_decl = die->HasChildren();
2978                    type_sp.reset (new Type (die->GetOffset(),
2979                                             this,
2980                                             type_name_const_str,
2981                                             byte_size,
2982                                             NULL,
2983                                             LLDB_INVALID_UID,
2984                                             Type::eEncodingIsUID,
2985                                             &decl,
2986                                             clang_type,
2987                                             is_forward_decl));
2988
2989                    m_die_to_type[die] = type_sp.get();
2990
2991                    if (die->HasChildren() == false && is_forward_declaration == false)
2992                    {
2993                        // No children for this struct/union/class, lets finish it
2994                        ast.StartTagDeclarationDefinition (clang_type);
2995                        ast.CompleteTagDeclarationDefinition (clang_type);
2996                    }
2997                    else if (clang_type_was_created)
2998                    {
2999                        // Leave this as a forward declaration until we need
3000                        // to know the details of the type. lldb_private::Type
3001                        // will automatically call the SymbolFile virtual function
3002                        // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3003                        // When the definition needs to be defined.
3004                        m_forward_decl_die_to_clang_type[die] = clang_type;
3005                        m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3006                    }
3007
3008                }
3009                break;
3010
3011            case DW_TAG_enumeration_type:
3012                {
3013                    // Set a bit that lets us know that we are currently parsing this
3014                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
3015
3016                    size_t byte_size = 0;
3017                    lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;
3018                    Declaration decl;
3019
3020                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3021                    if (num_attributes > 0)
3022                    {
3023                        uint32_t i;
3024
3025                        for (i=0; i<num_attributes; ++i)
3026                        {
3027                            attr = attributes.AttributeAtIndex(i);
3028                            DWARFFormValue form_value;
3029                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3030                            {
3031                                switch (attr)
3032                                {
3033                                case DW_AT_decl_file:       decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3034                                case DW_AT_decl_line:       decl.SetLine(form_value.Unsigned()); break;
3035                                case DW_AT_decl_column:     decl.SetColumn(form_value.Unsigned()); break;
3036                                case DW_AT_name:
3037                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3038                                    type_name_const_str.SetCString(type_name_cstr);
3039                                    break;
3040                                case DW_AT_type:            encoding_uid = form_value.Reference(dwarf_cu); break;
3041                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;
3042                                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3043                                case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
3044                                case DW_AT_allocated:
3045                                case DW_AT_associated:
3046                                case DW_AT_bit_stride:
3047                                case DW_AT_byte_stride:
3048                                case DW_AT_data_location:
3049                                case DW_AT_description:
3050                                case DW_AT_start_scope:
3051                                case DW_AT_visibility:
3052                                case DW_AT_specification:
3053                                case DW_AT_abstract_origin:
3054                                case DW_AT_sibling:
3055                                    break;
3056                                }
3057                            }
3058                        }
3059
3060                        DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3061
3062                        clang_type_t enumerator_clang_type = NULL;
3063                        clang_type = m_forward_decl_die_to_clang_type.lookup (die);
3064                        if (clang_type == NULL)
3065                        {
3066                            enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
3067                                                                                                  DW_ATE_signed,
3068                                                                                                  byte_size * 8);
3069                            clang_type = ast.CreateEnumerationType (decl,
3070                                                                    type_name_cstr,
3071                                                                    enumerator_clang_type);
3072                        }
3073                        else
3074                        {
3075                            enumerator_clang_type = ClangASTContext::GetEnumerationIntegerType (clang_type);
3076                            assert (enumerator_clang_type != NULL);
3077                        }
3078
3079                        m_die_to_decl_ctx[die] = ClangASTContext::GetDeclContextForType (clang_type);
3080                        type_sp.reset( new Type (die->GetOffset(),
3081                                                 this,
3082                                                 type_name_const_str,
3083                                                 byte_size,
3084                                                 NULL,
3085                                                 encoding_uid,
3086                                                 Type::eEncodingIsUID,
3087                                                 &decl,
3088                                                 clang_type,
3089                                                 true));
3090
3091                        m_die_to_type[die] = type_sp.get();
3092
3093                        // Leave this as a forward declaration until we need
3094                        // to know the details of the type. lldb_private::Type
3095                        // will automatically call the SymbolFile virtual function
3096                        // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
3097                        // When the definition needs to be defined.
3098                        m_forward_decl_die_to_clang_type[die] = clang_type;
3099                        m_forward_decl_clang_type_to_die[ClangASTType::RemoveFastQualifiers (clang_type)] = die;
3100
3101                    }
3102                }
3103                break;
3104
3105            case DW_TAG_inlined_subroutine:
3106            case DW_TAG_subprogram:
3107            case DW_TAG_subroutine_type:
3108                {
3109                    // Set a bit that lets us know that we are currently parsing this
3110                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
3111
3112                    const char *mangled = NULL;
3113                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3114                    Declaration decl;
3115                    bool is_variadic = false;
3116                    bool is_inline = false;
3117                    bool is_static = false;
3118                    bool is_virtual = false;
3119                    bool is_explicit = false;
3120
3121                    unsigned type_quals = 0;
3122                    clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern
3123
3124
3125                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3126                    if (num_attributes > 0)
3127                    {
3128                        uint32_t i;
3129                        for (i=0; i<num_attributes; ++i)
3130                        {
3131                            const dw_attr_t attr = attributes.AttributeAtIndex(i);
3132                            DWARFFormValue form_value;
3133                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3134                            {
3135                                switch (attr)
3136                                {
3137                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3138                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3139                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3140                                case DW_AT_name:
3141                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3142                                    type_name_const_str.SetCString(type_name_cstr);
3143                                    break;
3144
3145                                case DW_AT_MIPS_linkage_name:   mangled = form_value.AsCString(&get_debug_str_data()); break;
3146                                case DW_AT_type:                type_die_offset = form_value.Reference(dwarf_cu); break;
3147                                case DW_AT_accessibility:       accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3148                                case DW_AT_declaration:         is_forward_declaration = form_value.Unsigned() != 0; break;
3149                                case DW_AT_inline:              is_inline = form_value.Unsigned() != 0; break;
3150                                case DW_AT_virtuality:          is_virtual = form_value.Unsigned() != 0;  break;
3151                                case DW_AT_explicit:            is_explicit = form_value.Unsigned() != 0;  break;
3152
3153                                case DW_AT_external:
3154                                    if (form_value.Unsigned())
3155                                    {
3156                                        if (storage == clang::SC_None)
3157                                            storage = clang::SC_Extern;
3158                                        else
3159                                            storage = clang::SC_PrivateExtern;
3160                                    }
3161                                    break;
3162
3163                                case DW_AT_allocated:
3164                                case DW_AT_associated:
3165                                case DW_AT_address_class:
3166                                case DW_AT_artificial:
3167                                case DW_AT_calling_convention:
3168                                case DW_AT_data_location:
3169                                case DW_AT_elemental:
3170                                case DW_AT_entry_pc:
3171                                case DW_AT_frame_base:
3172                                case DW_AT_high_pc:
3173                                case DW_AT_low_pc:
3174                                case DW_AT_object_pointer:
3175                                case DW_AT_prototyped:
3176                                case DW_AT_pure:
3177                                case DW_AT_ranges:
3178                                case DW_AT_recursive:
3179                                case DW_AT_return_addr:
3180                                case DW_AT_segment:
3181                                case DW_AT_specification:
3182                                case DW_AT_start_scope:
3183                                case DW_AT_static_link:
3184                                case DW_AT_trampoline:
3185                                case DW_AT_visibility:
3186                                case DW_AT_vtable_elem_location:
3187                                case DW_AT_abstract_origin:
3188                                case DW_AT_description:
3189                                case DW_AT_sibling:
3190                                    break;
3191                                }
3192                            }
3193                        }
3194                    }
3195
3196                    DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3197
3198                    clang_type_t return_clang_type = NULL;
3199                    Type *func_type = NULL;
3200
3201                    if (type_die_offset != DW_INVALID_OFFSET)
3202                        func_type = ResolveTypeUID(type_die_offset);
3203
3204                    if (func_type)
3205                        return_clang_type = func_type->GetClangForwardType();
3206                    else
3207                        return_clang_type = ast.GetBuiltInType_void();
3208
3209
3210                    std::vector<clang_type_t> function_param_types;
3211                    std::vector<clang::ParmVarDecl*> function_param_decls;
3212
3213                    // Parse the function children for the parameters
3214                    if (die->HasChildren())
3215                    {
3216                        bool skip_artificial = true;
3217                        ParseChildParameters (sc,
3218                                              type_sp,
3219                                              dwarf_cu,
3220                                              die,
3221                                              skip_artificial,
3222                                              type_list,
3223                                              function_param_types,
3224                                              function_param_decls);
3225                    }
3226
3227                    // clang_type will get the function prototype clang type after this call
3228                    clang_type = ast.CreateFunctionType (return_clang_type,
3229                                                         &function_param_types[0],
3230                                                         function_param_types.size(),
3231                                                         is_variadic,
3232                                                         type_quals);
3233
3234                    if (type_name_cstr)
3235                    {
3236                        bool type_handled = false;
3237                        const DWARFDebugInfoEntry *parent_die = die->GetParent();
3238                        if (tag == DW_TAG_subprogram)
3239                        {
3240                            if (type_name_cstr[1] == '[' && (type_name_cstr[0] == '-' || type_name_cstr[0] == '+'))
3241                            {
3242                                // We need to find the DW_TAG_class_type or
3243                                // DW_TAG_struct_type by name so we can add this
3244                                // as a member function of the class.
3245                                const char *class_name_start = type_name_cstr + 2;
3246                                const char *class_name_end = ::strchr (class_name_start, ' ');
3247                                SymbolContext empty_sc;
3248                                clang_type_t class_opaque_type = NULL;
3249                                if (class_name_start < class_name_end)
3250                                {
3251                                    ConstString class_name (class_name_start, class_name_end - class_name_start);
3252                                    TypeList types;
3253                                    const uint32_t match_count = FindTypes (empty_sc, class_name, true, UINT32_MAX, types);
3254                                    if (match_count > 0)
3255                                    {
3256                                        for (uint32_t i=0; i<match_count; ++i)
3257                                        {
3258                                            Type *type = types.GetTypeAtIndex (i).get();
3259                                            clang_type_t type_clang_forward_type = type->GetClangForwardType();
3260                                            if (ClangASTContext::IsObjCClassType (type_clang_forward_type))
3261                                            {
3262                                                class_opaque_type = type_clang_forward_type;
3263                                                break;
3264                                            }
3265                                        }
3266                                    }
3267                                }
3268
3269                                if (class_opaque_type)
3270                                {
3271                                    // If accessibility isn't set to anything valid, assume public for
3272                                    // now...
3273                                    if (accessibility == eAccessNone)
3274                                        accessibility = eAccessPublic;
3275
3276                                    clang::ObjCMethodDecl *objc_method_decl;
3277                                    objc_method_decl = ast.AddMethodToObjCObjectType (class_opaque_type,
3278                                                                                      type_name_cstr,
3279                                                                                      clang_type,
3280                                                                                      accessibility);
3281                                    type_handled = objc_method_decl != NULL;
3282                                }
3283                            }
3284                            else if (parent_die->Tag() == DW_TAG_class_type ||
3285                                     parent_die->Tag() == DW_TAG_structure_type)
3286                            {
3287                                // Look at the parent of this DIE and see if is is
3288                                // a class or struct and see if this is actually a
3289                                // C++ method
3290                                Type *class_type = ResolveType (dwarf_cu, parent_die);
3291                                if (class_type)
3292                                {
3293                                    clang_type_t class_opaque_type = class_type->GetClangForwardType();
3294                                    if (ClangASTContext::IsCXXClassType (class_opaque_type))
3295                                    {
3296                                        // Neither GCC 4.2 nor clang++ currently set a valid accessibility
3297                                        // in the DWARF for C++ methods... Default to public for now...
3298                                        if (accessibility == eAccessNone)
3299                                            accessibility = eAccessPublic;
3300
3301                                        clang::CXXMethodDecl *cxx_method_decl;
3302                                        cxx_method_decl = ast.AddMethodToCXXRecordType (class_opaque_type,
3303                                                                                        type_name_cstr,
3304                                                                                        clang_type,
3305                                                                                        accessibility,
3306                                                                                        is_virtual,
3307                                                                                        is_static,
3308                                                                                        is_inline,
3309                                                                                        is_explicit);
3310                                        type_handled = cxx_method_decl != NULL;
3311                                    }
3312                                }
3313                            }
3314                        }
3315
3316                        if (!type_handled)
3317                        {
3318                            // We just have a function that isn't part of a class
3319                            clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (type_name_cstr,
3320                                                                                                clang_type,
3321                                                                                                storage,
3322                                                                                                is_inline);
3323
3324                            // Add the decl to our DIE to decl context map
3325                            assert (function_decl);
3326                            m_die_to_decl_ctx[die] = function_decl;
3327                            if (!function_param_decls.empty())
3328                                ast.SetFunctionParameters (function_decl,
3329                                                           &function_param_decls.front(),
3330                                                           function_param_decls.size());
3331                        }
3332                    }
3333                    type_sp.reset( new Type (die->GetOffset(),
3334                                             this,
3335                                             type_name_const_str,
3336                                             0,
3337                                             NULL,
3338                                             LLDB_INVALID_UID,
3339                                             Type::eEncodingIsUID,
3340                                             &decl,
3341                                             clang_type,
3342                                             false));
3343
3344                    m_die_to_type[die] = type_sp.get();
3345                    assert(type_sp.get());
3346                }
3347                break;
3348
3349            case DW_TAG_array_type:
3350                {
3351                    // Set a bit that lets us know that we are currently parsing this
3352                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
3353
3354                    size_t byte_size = 0;
3355                    lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
3356                    Declaration decl;
3357                    int64_t first_index = 0;
3358                    uint32_t byte_stride = 0;
3359                    uint32_t bit_stride = 0;
3360                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3361
3362                    if (num_attributes > 0)
3363                    {
3364                        uint32_t i;
3365                        for (i=0; i<num_attributes; ++i)
3366                        {
3367                            attr = attributes.AttributeAtIndex(i);
3368                            DWARFFormValue form_value;
3369                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3370                            {
3371                                switch (attr)
3372                                {
3373                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3374                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3375                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3376                                case DW_AT_name:
3377                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
3378                                    type_name_const_str.SetCString(type_name_cstr);
3379                                    break;
3380
3381                                case DW_AT_type:            type_die_offset = form_value.Reference(dwarf_cu); break;
3382                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;
3383                                case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break;
3384                                case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break;
3385                                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3386                                case DW_AT_declaration:     is_forward_declaration = form_value.Unsigned() != 0; break;
3387                                case DW_AT_allocated:
3388                                case DW_AT_associated:
3389                                case DW_AT_data_location:
3390                                case DW_AT_description:
3391                                case DW_AT_ordering:
3392                                case DW_AT_start_scope:
3393                                case DW_AT_visibility:
3394                                case DW_AT_specification:
3395                                case DW_AT_abstract_origin:
3396                                case DW_AT_sibling:
3397                                    break;
3398                                }
3399                            }
3400                        }
3401
3402                        DEBUG_PRINTF ("0x%8.8x: %s (\"%s\")\n", die->GetOffset(), DW_TAG_value_to_name(tag), type_name_cstr);
3403
3404                        Type *element_type = ResolveTypeUID(type_die_offset);
3405
3406                        if (element_type)
3407                        {
3408                            std::vector<uint64_t> element_orders;
3409                            ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
3410                            // We have an array that claims to have no members, lets give it at least one member...
3411                            if (element_orders.empty())
3412                                element_orders.push_back (1);
3413                            if (byte_stride == 0 && bit_stride == 0)
3414                                byte_stride = element_type->GetByteSize();
3415                            clang_type_t array_element_type = element_type->GetClangType();
3416                            uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
3417                            uint64_t num_elements = 0;
3418                            std::vector<uint64_t>::const_reverse_iterator pos;
3419                            std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
3420                            for (pos = element_orders.rbegin(); pos != end; ++pos)
3421                            {
3422                                num_elements = *pos;
3423                                clang_type = ast.CreateArrayType (array_element_type,
3424                                                                  num_elements,
3425                                                                  num_elements * array_element_bit_stride);
3426                                array_element_type = clang_type;
3427                                array_element_bit_stride = array_element_bit_stride * num_elements;
3428                            }
3429                            ConstString empty_name;
3430                            type_sp.reset( new Type (die->GetOffset(),
3431                                                     this,
3432                                                     empty_name,
3433                                                     array_element_bit_stride / 8,
3434                                                     NULL,
3435                                                     LLDB_INVALID_UID,
3436                                                     Type::eEncodingIsUID,
3437                                                     &decl,
3438                                                     clang_type,
3439                                                     false));
3440                            m_die_to_type[die] = type_sp.get();
3441                        }
3442                    }
3443                }
3444                break;
3445
3446            case DW_TAG_ptr_to_member_type:
3447                {
3448                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
3449                    dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;
3450
3451                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3452
3453                    if (num_attributes > 0) {
3454                        uint32_t i;
3455                        for (i=0; i<num_attributes; ++i)
3456                        {
3457                            attr = attributes.AttributeAtIndex(i);
3458                            DWARFFormValue form_value;
3459                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3460                            {
3461                                switch (attr)
3462                                {
3463                                    case DW_AT_type:
3464                                        type_die_offset = form_value.Reference(dwarf_cu); break;
3465                                    case DW_AT_containing_type:
3466                                        containing_type_die_offset = form_value.Reference(dwarf_cu); break;
3467                                }
3468                            }
3469                        }
3470
3471                        Type *pointee_type = ResolveTypeUID(type_die_offset);
3472                        Type *class_type = ResolveTypeUID(containing_type_die_offset);
3473
3474                        clang_type_t pointee_clang_type = pointee_type->GetClangType();
3475                        clang_type_t class_clang_type = class_type->GetClangType();
3476
3477                        clang_type = ast.CreateMemberPointerType(pointee_clang_type,
3478                                                                 class_clang_type);
3479
3480                        size_t byte_size = ClangASTType::GetClangTypeBitWidth (ast.getASTContext(),
3481                                                                               clang_type) / 8;
3482
3483                        type_sp.reset( new Type (die->GetOffset(),
3484                                                 this,
3485                                                 type_name_const_str,
3486                                                 byte_size,
3487                                                 NULL,
3488                                                 LLDB_INVALID_UID,
3489                                                 Type::eEncodingIsUID,
3490                                                 NULL,
3491                                                 clang_type,
3492                                                 false));
3493                        m_die_to_type[die] = type_sp.get();
3494                    }
3495
3496                    break;
3497                }
3498            default:
3499                assert(false && "Unhandled type tag!");
3500                break;
3501            }
3502
3503            if (type_sp.get())
3504            {
3505                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3506                dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3507
3508                SymbolContextScope * symbol_context_scope = NULL;
3509                if (sc_parent_tag == DW_TAG_compile_unit)
3510                {
3511                    symbol_context_scope = sc.comp_unit;
3512                }
3513                else if (sc.function != NULL)
3514                {
3515                    symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3516                    if (symbol_context_scope == NULL)
3517                        symbol_context_scope = sc.function;
3518                }
3519
3520                if (symbol_context_scope != NULL)
3521                {
3522                    type_sp->SetSymbolContextScope(symbol_context_scope);
3523                }
3524
3525//              if (udt_sp.get())
3526//              {
3527//                  if (is_forward_declaration)
3528//                      udt_sp->GetFlags().Set(UserDefType::flagIsForwardDefinition);
3529//                  type_sp->SetUserDefinedType(udt_sp);
3530//              }
3531
3532                if (type_sp.unique())
3533                {
3534                    // We are ready to put this type into the uniqued list up at the module level
3535                    type_list->Insert (type_sp);
3536
3537                    m_die_to_type[die] = type_sp.get();
3538                }
3539            }
3540        }
3541        else if (type_ptr != DIE_IS_BEING_PARSED)
3542        {
3543            type_sp = type_list->FindType(type_ptr->GetID());
3544        }
3545    }
3546    return type_sp;
3547}
3548
3549size_t
3550SymbolFileDWARF::ParseTypes
3551(
3552    const SymbolContext& sc,
3553    DWARFCompileUnit* dwarf_cu,
3554    const DWARFDebugInfoEntry *die,
3555    bool parse_siblings,
3556    bool parse_children
3557)
3558{
3559    size_t types_added = 0;
3560    while (die != NULL)
3561    {
3562        bool type_is_new = false;
3563        if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
3564        {
3565            if (type_is_new)
3566                ++types_added;
3567        }
3568
3569        if (parse_children && die->HasChildren())
3570        {
3571            if (die->Tag() == DW_TAG_subprogram)
3572            {
3573                SymbolContext child_sc(sc);
3574                child_sc.function = sc.comp_unit->FindFunctionByUID(die->GetOffset()).get();
3575                types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
3576            }
3577            else
3578                types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
3579        }
3580
3581        if (parse_siblings)
3582            die = die->GetSibling();
3583        else
3584            die = NULL;
3585    }
3586    return types_added;
3587}
3588
3589
3590size_t
3591SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
3592{
3593    assert(sc.comp_unit && sc.function);
3594    size_t functions_added = 0;
3595    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3596    if (dwarf_cu)
3597    {
3598        dw_offset_t function_die_offset = sc.function->GetID();
3599        const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
3600        if (function_die)
3601        {
3602            ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, false, true);
3603        }
3604    }
3605
3606    return functions_added;
3607}
3608
3609
3610size_t
3611SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
3612{
3613    // At least a compile unit must be valid
3614    assert(sc.comp_unit);
3615    size_t types_added = 0;
3616    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnitForUID(sc.comp_unit->GetID());
3617    if (dwarf_cu)
3618    {
3619        if (sc.function)
3620        {
3621            dw_offset_t function_die_offset = sc.function->GetID();
3622            const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
3623            if (func_die && func_die->HasChildren())
3624            {
3625                types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
3626            }
3627        }
3628        else
3629        {
3630            const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
3631            if (dwarf_cu_die && dwarf_cu_die->HasChildren())
3632            {
3633                types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
3634            }
3635        }
3636    }
3637
3638    return types_added;
3639}
3640
3641size_t
3642SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
3643{
3644    if (sc.comp_unit != NULL)
3645    {
3646        DWARFDebugInfo* info = DebugInfo();
3647        if (info == NULL)
3648            return 0;
3649
3650        uint32_t cu_idx = UINT32_MAX;
3651        DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
3652
3653        if (dwarf_cu == NULL)
3654            return 0;
3655
3656        if (sc.function)
3657        {
3658            const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
3659
3660            dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, DW_INVALID_ADDRESS);
3661            assert (func_lo_pc != DW_INVALID_ADDRESS);
3662
3663            return ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
3664        }
3665        else if (sc.comp_unit)
3666        {
3667            uint32_t vars_added = 0;
3668            VariableListSP variables (sc.comp_unit->GetVariableList(false));
3669
3670            if (variables.get() == NULL)
3671            {
3672                variables.reset(new VariableList());
3673                sc.comp_unit->SetVariableList(variables);
3674
3675                // Index if we already haven't to make sure the compile units
3676                // get indexed and make their global DIE index list
3677                if (!m_indexed)
3678                    Index ();
3679
3680                std::vector<NameToDIE::Info> global_die_info_array;
3681                const size_t num_globals = m_global_index.FindAllEntriesForCompileUnitWithIndex (cu_idx, global_die_info_array);
3682                for (size_t idx=0; idx<num_globals; ++idx)
3683                {
3684                    VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, dwarf_cu->GetDIEAtIndexUnchecked(global_die_info_array[idx].die_idx), LLDB_INVALID_ADDRESS));
3685                    if (var_sp)
3686                    {
3687                        variables->AddVariable(var_sp);
3688                        ++vars_added;
3689                    }
3690                }
3691            }
3692            return vars_added;
3693        }
3694    }
3695    return 0;
3696}
3697
3698
3699VariableSP
3700SymbolFileDWARF::ParseVariableDIE
3701(
3702    const SymbolContext& sc,
3703    DWARFCompileUnit* dwarf_cu,
3704    const DWARFDebugInfoEntry *die,
3705    const lldb::addr_t func_low_pc
3706)
3707{
3708
3709    VariableSP var_sp;
3710
3711    const dw_tag_t tag = die->Tag();
3712    DWARFDebugInfoEntry::Attributes attributes;
3713    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
3714    if (num_attributes > 0)
3715    {
3716        const char *name = NULL;
3717        const char *mangled = NULL;
3718        Declaration decl;
3719        uint32_t i;
3720        Type *var_type = NULL;
3721        DWARFExpression location;
3722        bool is_external = false;
3723        bool is_artificial = false;
3724        AccessType accessibility = eAccessNone;
3725
3726        for (i=0; i<num_attributes; ++i)
3727        {
3728            dw_attr_t attr = attributes.AttributeAtIndex(i);
3729            DWARFFormValue form_value;
3730            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
3731            {
3732                switch (attr)
3733                {
3734                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
3735                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
3736                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
3737                case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
3738                case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
3739                case DW_AT_type:        var_type = ResolveTypeUID(form_value.Reference(dwarf_cu)); break;
3740                case DW_AT_external:    is_external = form_value.Unsigned() != 0; break;
3741                case DW_AT_location:
3742                    {
3743                        if (form_value.BlockData())
3744                        {
3745                            const DataExtractor& debug_info_data = get_debug_info_data();
3746
3747                            uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
3748                            uint32_t block_length = form_value.Unsigned();
3749                            location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
3750                        }
3751                        else
3752                        {
3753                            const DataExtractor&    debug_loc_data = get_debug_loc_data();
3754                            const dw_offset_t debug_loc_offset = form_value.Unsigned();
3755
3756                            size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
3757                            if (loc_list_length > 0)
3758                            {
3759                                location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
3760                                assert (func_low_pc != LLDB_INVALID_ADDRESS);
3761                                location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
3762                            }
3763                        }
3764                    }
3765                    break;
3766
3767                case DW_AT_artificial:      is_artificial = form_value.Unsigned() != 0; break;
3768                case DW_AT_accessibility:   accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
3769                case DW_AT_const_value:
3770                case DW_AT_declaration:
3771                case DW_AT_description:
3772                case DW_AT_endianity:
3773                case DW_AT_segment:
3774                case DW_AT_start_scope:
3775                case DW_AT_visibility:
3776                default:
3777                case DW_AT_abstract_origin:
3778                case DW_AT_sibling:
3779                case DW_AT_specification:
3780                    break;
3781                }
3782            }
3783        }
3784
3785        if (location.IsValid())
3786        {
3787            assert(var_type != DIE_IS_BEING_PARSED);
3788
3789            ConstString var_name;
3790            if (mangled)
3791            {
3792                Mangled mangled_var_name (mangled, true);
3793                var_name = mangled_var_name.GetDemangledName();
3794            }
3795
3796            if (!var_name && name)
3797            {
3798                var_name.SetCString(name);
3799            }
3800
3801            ValueType scope = eValueTypeInvalid;
3802
3803            const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
3804            dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3805
3806            if (tag == DW_TAG_formal_parameter)
3807                scope = eValueTypeVariableArgument;
3808            else if (is_external || parent_tag == DW_TAG_compile_unit)
3809                scope = eValueTypeVariableGlobal;
3810            else
3811                scope = eValueTypeVariableLocal;
3812
3813            SymbolContextScope * symbol_context_scope = NULL;
3814            if (parent_tag == DW_TAG_compile_unit)
3815            {
3816                symbol_context_scope = sc.comp_unit;
3817            }
3818            else if (sc.function != NULL)
3819            {
3820                symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3821                if (symbol_context_scope == NULL)
3822                    symbol_context_scope = sc.function;
3823            }
3824
3825            assert(symbol_context_scope != NULL);
3826            var_sp.reset (new Variable(die->GetOffset(),
3827                                       var_name,
3828                                       var_type,
3829                                       scope,
3830                                       symbol_context_scope,
3831                                       &decl,
3832                                       location,
3833                                       is_external,
3834                                       is_artificial));
3835
3836            m_die_to_variable_sp[die] = var_sp;
3837        }
3838    }
3839    return var_sp;
3840}
3841
3842size_t
3843SymbolFileDWARF::ParseVariables
3844(
3845    const SymbolContext& sc,
3846    DWARFCompileUnit* dwarf_cu,
3847    const lldb::addr_t func_low_pc,
3848    const DWARFDebugInfoEntry *orig_die,
3849    bool parse_siblings,
3850    bool parse_children,
3851    VariableList* cc_variable_list
3852)
3853{
3854    if (orig_die == NULL)
3855        return 0;
3856
3857    size_t vars_added = 0;
3858    const DWARFDebugInfoEntry *die = orig_die;
3859    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
3860    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
3861    VariableListSP variables;
3862    switch (parent_tag)
3863    {
3864    case DW_TAG_compile_unit:
3865        if (sc.comp_unit != NULL)
3866        {
3867            variables = sc.comp_unit->GetVariableList(false);
3868            if (variables.get() == NULL)
3869            {
3870                variables.reset(new VariableList());
3871                sc.comp_unit->SetVariableList(variables);
3872            }
3873        }
3874        else
3875        {
3876            assert(!"Parent DIE was a compile unit, yet we don't have a valid compile unit in the symbol context...");
3877            vars_added = 0;
3878        }
3879        break;
3880
3881    case DW_TAG_subprogram:
3882    case DW_TAG_inlined_subroutine:
3883    case DW_TAG_lexical_block:
3884        if (sc.function != NULL)
3885        {
3886            // Check to see if we already have parsed the variables for the given scope
3887
3888            Block *block = sc.function->GetBlock(true).FindBlockByID(sc_parent_die->GetOffset());
3889            assert (block != NULL);
3890            variables = block->GetVariableList(false, false);
3891            if (variables.get() == NULL)
3892            {
3893                variables.reset(new VariableList());
3894                block->SetVariableList(variables);
3895            }
3896        }
3897        else
3898        {
3899            assert(!"Parent DIE was a function or block, yet we don't have a function in the symbol context...");
3900            vars_added = 0;
3901        }
3902        break;
3903
3904    default:
3905        assert(!"Didn't find appropriate parent DIE for variable list...");
3906        break;
3907    }
3908
3909    // We need to have a variable list at this point that we can add variables to
3910    assert(variables.get());
3911
3912    while (die != NULL)
3913    {
3914        dw_tag_t tag = die->Tag();
3915
3916        // Check to see if we have already parsed this variable or constant?
3917        if (m_die_to_variable_sp[die])
3918        {
3919            if (cc_variable_list)
3920                cc_variable_list->AddVariable (m_die_to_variable_sp[die]);
3921        }
3922        else
3923        {
3924            // We haven't already parsed it, lets do that now.
3925            if ((tag == DW_TAG_variable) ||
3926                (tag == DW_TAG_constant) ||
3927                (tag == DW_TAG_formal_parameter && sc.function))
3928            {
3929                VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
3930                if (var_sp)
3931                {
3932                    variables->AddVariable(var_sp);
3933                    if (cc_variable_list)
3934                        cc_variable_list->AddVariable (var_sp);
3935                    ++vars_added;
3936                }
3937            }
3938        }
3939
3940        bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);
3941
3942        if (!skip_children && parse_children && die->HasChildren())
3943        {
3944            vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
3945        }
3946
3947        if (parse_siblings)
3948            die = die->GetSibling();
3949        else
3950            die = NULL;
3951    }
3952
3953    return vars_added;
3954}
3955
3956//------------------------------------------------------------------
3957// PluginInterface protocol
3958//------------------------------------------------------------------
3959const char *
3960SymbolFileDWARF::GetPluginName()
3961{
3962    return "SymbolFileDWARF";
3963}
3964
3965const char *
3966SymbolFileDWARF::GetShortPluginName()
3967{
3968    return GetPluginNameStatic();
3969}
3970
3971uint32_t
3972SymbolFileDWARF::GetPluginVersion()
3973{
3974    return 1;
3975}
3976
3977void
3978SymbolFileDWARF::GetPluginCommandHelp (const char *command, Stream *strm)
3979{
3980}
3981
3982Error
3983SymbolFileDWARF::ExecutePluginCommand (Args &command, Stream *strm)
3984{
3985    Error error;
3986    error.SetErrorString("No plug-in command are currently supported.");
3987    return error;
3988}
3989
3990Log *
3991SymbolFileDWARF::EnablePluginLogging (Stream *strm, Args &command)
3992{
3993    return NULL;
3994}
3995
3996