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