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