DWARFASTParserClang.cpp revision 321369
1292932Sdim//===-- DWARFASTParserClang.cpp ---------------------------------*- C++ -*-===//
2292932Sdim//
3292932Sdim//                     The LLVM Compiler Infrastructure
4292932Sdim//
5292932Sdim// This file is distributed under the University of Illinois Open Source
6292932Sdim// License. See LICENSE.TXT for details.
7292932Sdim//
8292932Sdim//===----------------------------------------------------------------------===//
9292932Sdim
10309124Sdim#include <stdlib.h>
11309124Sdim
12292932Sdim#include "DWARFASTParserClang.h"
13292932Sdim#include "DWARFCompileUnit.h"
14314564Sdim#include "DWARFDIE.h"
15314564Sdim#include "DWARFDIECollection.h"
16292932Sdim#include "DWARFDebugInfo.h"
17292932Sdim#include "DWARFDeclContext.h"
18292932Sdim#include "DWARFDefines.h"
19292932Sdim#include "SymbolFileDWARF.h"
20292932Sdim#include "SymbolFileDWARFDebugMap.h"
21292932Sdim#include "UniqueDWARFASTType.h"
22292932Sdim
23309124Sdim#include "Plugins/Language/ObjC/ObjCLanguage.h"
24292932Sdim#include "lldb/Core/Module.h"
25292932Sdim#include "lldb/Core/Value.h"
26292932Sdim#include "lldb/Host/Host.h"
27309124Sdim#include "lldb/Interpreter/Args.h"
28292932Sdim#include "lldb/Symbol/ClangASTImporter.h"
29292932Sdim#include "lldb/Symbol/ClangExternalASTSourceCommon.h"
30309124Sdim#include "lldb/Symbol/ClangUtil.h"
31292932Sdim#include "lldb/Symbol/CompileUnit.h"
32292932Sdim#include "lldb/Symbol/Function.h"
33292932Sdim#include "lldb/Symbol/ObjectFile.h"
34292932Sdim#include "lldb/Symbol/SymbolVendor.h"
35292932Sdim#include "lldb/Symbol/TypeList.h"
36292932Sdim#include "lldb/Symbol/TypeMap.h"
37292932Sdim#include "lldb/Target/Language.h"
38309124Sdim#include "lldb/Utility/LLDBAssert.h"
39321369Sdim#include "lldb/Utility/Log.h"
40321369Sdim#include "lldb/Utility/StreamString.h"
41292932Sdim
42292932Sdim#include "clang/AST/DeclCXX.h"
43292932Sdim#include "clang/AST/DeclObjC.h"
44292932Sdim
45292932Sdim#include <map>
46292932Sdim#include <vector>
47292932Sdim
48292932Sdim//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN
49292932Sdim
50292932Sdim#ifdef ENABLE_DEBUG_PRINTF
51292932Sdim#include <stdio.h>
52292932Sdim#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
53292932Sdim#else
54292932Sdim#define DEBUG_PRINTF(fmt, ...)
55292932Sdim#endif
56292932Sdim
57292932Sdimusing namespace lldb;
58292932Sdimusing namespace lldb_private;
59314564SdimDWARFASTParserClang::DWARFASTParserClang(ClangASTContext &ast)
60314564Sdim    : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {}
61292932Sdim
62314564SdimDWARFASTParserClang::~DWARFASTParserClang() {}
63292932Sdim
64314564Sdimstatic AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) {
65314564Sdim  switch (dwarf_accessibility) {
66314564Sdim  case DW_ACCESS_public:
67314564Sdim    return eAccessPublic;
68314564Sdim  case DW_ACCESS_private:
69314564Sdim    return eAccessPrivate;
70314564Sdim  case DW_ACCESS_protected:
71314564Sdim    return eAccessProtected;
72314564Sdim  default:
73314564Sdim    break;
74314564Sdim  }
75314564Sdim  return eAccessNone;
76292932Sdim}
77292932Sdim
78314564Sdimstatic bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) {
79314564Sdim  switch (decl_kind) {
80314564Sdim  case clang::Decl::CXXRecord:
81314564Sdim  case clang::Decl::ClassTemplateSpecialization:
82314564Sdim    return true;
83314564Sdim  default:
84314564Sdim    break;
85314564Sdim  }
86314564Sdim  return false;
87292932Sdim}
88292932Sdim
89314564Sdimstruct BitfieldInfo {
90314564Sdim  uint64_t bit_size;
91314564Sdim  uint64_t bit_offset;
92292932Sdim
93314564Sdim  BitfieldInfo()
94314564Sdim      : bit_size(LLDB_INVALID_ADDRESS), bit_offset(LLDB_INVALID_ADDRESS) {}
95292932Sdim
96314564Sdim  void Clear() {
97314564Sdim    bit_size = LLDB_INVALID_ADDRESS;
98314564Sdim    bit_offset = LLDB_INVALID_ADDRESS;
99314564Sdim  }
100292932Sdim
101314564Sdim  bool IsValid() const {
102314564Sdim    return (bit_size != LLDB_INVALID_ADDRESS) &&
103314564Sdim           (bit_offset != LLDB_INVALID_ADDRESS);
104314564Sdim  }
105309124Sdim
106314564Sdim  bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const {
107314564Sdim    if (IsValid()) {
108314564Sdim      // This bitfield info is valid, so any subsequent bitfields
109314564Sdim      // must not overlap and must be at a higher bit offset than
110314564Sdim      // any previous bitfield + size.
111314564Sdim      return (bit_size + bit_offset) <= next_bit_offset;
112314564Sdim    } else {
113314564Sdim      // If the this BitfieldInfo is not valid, then any offset isOK
114314564Sdim      return true;
115309124Sdim    }
116314564Sdim  }
117292932Sdim};
118292932Sdim
119314564SdimClangASTImporter &DWARFASTParserClang::GetClangASTImporter() {
120314564Sdim  if (!m_clang_ast_importer_ap) {
121314564Sdim    m_clang_ast_importer_ap.reset(new ClangASTImporter);
122314564Sdim  }
123314564Sdim  return *m_clang_ast_importer_ap;
124292932Sdim}
125292932Sdim
126314564SdimTypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) {
127314564Sdim  ModuleSP dwo_module_sp = die.GetContainingDWOModule();
128314564Sdim  if (dwo_module_sp) {
129314564Sdim    // This type comes from an external DWO module
130314564Sdim    std::vector<CompilerContext> dwo_context;
131314564Sdim    die.GetDWOContext(dwo_context);
132314564Sdim    TypeMap dwo_types;
133314564Sdim    if (dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true,
134314564Sdim                                                    dwo_types)) {
135314564Sdim      const size_t num_dwo_types = dwo_types.GetSize();
136314564Sdim      if (num_dwo_types == 1) {
137314564Sdim        // We found a real definition for this type elsewhere
138314564Sdim        // so lets use it and cache the fact that we found
139314564Sdim        // a complete type for this die
140314564Sdim        TypeSP dwo_type_sp = dwo_types.GetTypeAtIndex(0);
141314564Sdim        if (dwo_type_sp) {
142314564Sdim          lldb_private::CompilerType dwo_type =
143314564Sdim              dwo_type_sp->GetForwardCompilerType();
144292932Sdim
145314564Sdim          lldb_private::CompilerType type =
146314564Sdim              GetClangASTImporter().CopyType(m_ast, dwo_type);
147292932Sdim
148314564Sdim          // printf ("copied_qual_type: ast = %p, clang_type = %p, name =
149314564Sdim          // '%s'\n", m_ast, copied_qual_type.getAsOpaquePtr(),
150314564Sdim          // external_type->GetName().GetCString());
151314564Sdim          if (type) {
152314564Sdim            SymbolFileDWARF *dwarf = die.GetDWARF();
153314564Sdim            TypeSP type_sp(new Type(die.GetID(), dwarf, dwo_type_sp->GetName(),
154314564Sdim                                    dwo_type_sp->GetByteSize(), NULL,
155314564Sdim                                    LLDB_INVALID_UID, Type::eEncodingInvalid,
156314564Sdim                                    &dwo_type_sp->GetDeclaration(), type,
157314564Sdim                                    Type::eResolveStateForward));
158292932Sdim
159314564Sdim            dwarf->GetTypeList()->Insert(type_sp);
160314564Sdim            dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
161314564Sdim            clang::TagDecl *tag_decl = ClangASTContext::GetAsTagDecl(type);
162314564Sdim            if (tag_decl)
163314564Sdim              LinkDeclContextToDIE(tag_decl, die);
164314564Sdim            else {
165314564Sdim              clang::DeclContext *defn_decl_ctx =
166314564Sdim                  GetCachedClangDeclContextForDIE(die);
167314564Sdim              if (defn_decl_ctx)
168314564Sdim                LinkDeclContextToDIE(defn_decl_ctx, die);
169292932Sdim            }
170314564Sdim            return type_sp;
171314564Sdim          }
172292932Sdim        }
173314564Sdim      }
174292932Sdim    }
175314564Sdim  }
176314564Sdim  return TypeSP();
177292932Sdim}
178292932Sdim
179314564SdimTypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
180314564Sdim                                               const DWARFDIE &die, Log *log,
181314564Sdim                                               bool *type_is_new_ptr) {
182314564Sdim  TypeSP type_sp;
183292932Sdim
184314564Sdim  if (type_is_new_ptr)
185314564Sdim    *type_is_new_ptr = false;
186292932Sdim
187314564Sdim  AccessType accessibility = eAccessNone;
188314564Sdim  if (die) {
189314564Sdim    SymbolFileDWARF *dwarf = die.GetDWARF();
190314564Sdim    if (log) {
191314564Sdim      DWARFDIE context_die;
192314564Sdim      clang::DeclContext *context =
193314564Sdim          GetClangDeclContextContainingDIE(die, &context_die);
194292932Sdim
195314564Sdim      dwarf->GetObjectFile()->GetModule()->LogMessage(
196314564Sdim          log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die "
197314564Sdim               "0x%8.8x)) %s name = '%s')",
198314564Sdim          die.GetOffset(), static_cast<void *>(context),
199314564Sdim          context_die.GetOffset(), die.GetTagAsCString(), die.GetName());
200314564Sdim    }
201314564Sdim    //
202314564Sdim    //        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
203314564Sdim    //        if (log && dwarf_cu)
204314564Sdim    //        {
205314564Sdim    //            StreamString s;
206314564Sdim    //            die->DumpLocation (this, dwarf_cu, s);
207314564Sdim    //            dwarf->GetObjectFile()->GetModule()->LogMessage (log,
208314564Sdim    //            "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
209314564Sdim    //
210314564Sdim    //        }
211292932Sdim
212314564Sdim    Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
213314564Sdim    TypeList *type_list = dwarf->GetTypeList();
214314564Sdim    if (type_ptr == NULL) {
215314564Sdim      if (type_is_new_ptr)
216314564Sdim        *type_is_new_ptr = true;
217292932Sdim
218314564Sdim      const dw_tag_t tag = die.Tag();
219292932Sdim
220314564Sdim      bool is_forward_declaration = false;
221314564Sdim      DWARFAttributes attributes;
222314564Sdim      const char *type_name_cstr = NULL;
223314564Sdim      ConstString type_name_const_str;
224314564Sdim      Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
225314564Sdim      uint64_t byte_size = 0;
226314564Sdim      Declaration decl;
227292932Sdim
228314564Sdim      Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
229314564Sdim      CompilerType clang_type;
230314564Sdim      DWARFFormValue form_value;
231292932Sdim
232314564Sdim      dw_attr_t attr;
233292932Sdim
234314564Sdim      switch (tag) {
235314564Sdim      case DW_TAG_typedef:
236314564Sdim      case DW_TAG_base_type:
237314564Sdim      case DW_TAG_pointer_type:
238314564Sdim      case DW_TAG_reference_type:
239314564Sdim      case DW_TAG_rvalue_reference_type:
240314564Sdim      case DW_TAG_const_type:
241314564Sdim      case DW_TAG_restrict_type:
242314564Sdim      case DW_TAG_volatile_type:
243314564Sdim      case DW_TAG_unspecified_type: {
244314564Sdim        // Set a bit that lets us know that we are currently parsing this
245314564Sdim        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
246292932Sdim
247314564Sdim        const size_t num_attributes = die.GetAttributes(attributes);
248314564Sdim        uint32_t encoding = 0;
249314564Sdim        DWARFFormValue encoding_uid;
250292932Sdim
251314564Sdim        if (num_attributes > 0) {
252314564Sdim          uint32_t i;
253314564Sdim          for (i = 0; i < num_attributes; ++i) {
254314564Sdim            attr = attributes.AttributeAtIndex(i);
255314564Sdim            if (attributes.ExtractFormValueAtIndex(i, form_value)) {
256314564Sdim              switch (attr) {
257314564Sdim              case DW_AT_decl_file:
258314564Sdim                decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
259314564Sdim                    form_value.Unsigned()));
260314564Sdim                break;
261314564Sdim              case DW_AT_decl_line:
262314564Sdim                decl.SetLine(form_value.Unsigned());
263314564Sdim                break;
264314564Sdim              case DW_AT_decl_column:
265314564Sdim                decl.SetColumn(form_value.Unsigned());
266314564Sdim                break;
267314564Sdim              case DW_AT_name:
268292932Sdim
269314564Sdim                type_name_cstr = form_value.AsCString();
270314564Sdim                // Work around a bug in llvm-gcc where they give a name to a
271314564Sdim                // reference type which doesn't
272314564Sdim                // include the "&"...
273314564Sdim                if (tag == DW_TAG_reference_type) {
274314564Sdim                  if (strchr(type_name_cstr, '&') == NULL)
275314564Sdim                    type_name_cstr = NULL;
276314564Sdim                }
277314564Sdim                if (type_name_cstr)
278314564Sdim                  type_name_const_str.SetCString(type_name_cstr);
279314564Sdim                break;
280314564Sdim              case DW_AT_byte_size:
281314564Sdim                byte_size = form_value.Unsigned();
282314564Sdim                break;
283314564Sdim              case DW_AT_encoding:
284314564Sdim                encoding = form_value.Unsigned();
285314564Sdim                break;
286314564Sdim              case DW_AT_type:
287314564Sdim                encoding_uid = form_value;
288314564Sdim                break;
289314564Sdim              default:
290314564Sdim              case DW_AT_sibling:
291314564Sdim                break;
292314564Sdim              }
293314564Sdim            }
294314564Sdim          }
295314564Sdim        }
296292932Sdim
297314564Sdim        if (tag == DW_TAG_typedef && encoding_uid.IsValid()) {
298314564Sdim          // Try to parse a typedef from the DWO file first as modules
299314564Sdim          // can contain typedef'ed structures that have no names like:
300314564Sdim          //
301314564Sdim          //  typedef struct { int a; } Foo;
302314564Sdim          //
303314564Sdim          // In this case we will have a structure with no name and a
304314564Sdim          // typedef named "Foo" that points to this unnamed structure.
305314564Sdim          // The name in the typedef is the only identifier for the struct,
306314564Sdim          // so always try to get typedefs from DWO files if possible.
307314564Sdim          //
308314564Sdim          // The type_sp returned will be empty if the typedef doesn't exist
309314564Sdim          // in a DWO file, so it is cheap to call this function just to check.
310314564Sdim          //
311314564Sdim          // If we don't do this we end up creating a TypeSP that says this
312314564Sdim          // is a typedef to type 0x123 (the DW_AT_type value would be 0x123
313314564Sdim          // in the DW_TAG_typedef), and this is the unnamed structure type.
314314564Sdim          // We will have a hard time tracking down an unnammed structure
315314564Sdim          // type in the module DWO file, so we make sure we don't get into
316314564Sdim          // this situation by always resolving typedefs from the DWO file.
317314564Sdim          const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
318292932Sdim
319314564Sdim          // First make sure that the die that this is typedef'ed to _is_
320314564Sdim          // just a declaration (DW_AT_declaration == 1), not a full definition
321314564Sdim          // since template types can't be represented in modules since only
322314564Sdim          // concrete instances of templates are ever emitted and modules
323314564Sdim          // won't contain those
324314564Sdim          if (encoding_die &&
325314564Sdim              encoding_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) ==
326314564Sdim                  1) {
327314564Sdim            type_sp = ParseTypeFromDWO(die, log);
328314564Sdim            if (type_sp)
329314564Sdim              return type_sp;
330314564Sdim          }
331314564Sdim        }
332292932Sdim
333314564Sdim        DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n",
334314564Sdim                     die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr,
335314564Sdim                     encoding_uid.Reference());
336309124Sdim
337314564Sdim        switch (tag) {
338314564Sdim        default:
339314564Sdim          break;
340309124Sdim
341314564Sdim        case DW_TAG_unspecified_type:
342314564Sdim          if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
343314564Sdim              strcmp(type_name_cstr, "decltype(nullptr)") == 0) {
344314564Sdim            resolve_state = Type::eResolveStateFull;
345314564Sdim            clang_type = m_ast.GetBasicType(eBasicTypeNullPtr);
346314564Sdim            break;
347314564Sdim          }
348314564Sdim          // Fall through to base type below in case we can handle the type
349314564Sdim          // there...
350314564Sdim          LLVM_FALLTHROUGH;
351292932Sdim
352314564Sdim        case DW_TAG_base_type:
353314564Sdim          resolve_state = Type::eResolveStateFull;
354314564Sdim          clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
355314564Sdim              type_name_cstr, encoding, byte_size * 8);
356314564Sdim          break;
357292932Sdim
358314564Sdim        case DW_TAG_pointer_type:
359314564Sdim          encoding_data_type = Type::eEncodingIsPointerUID;
360314564Sdim          break;
361314564Sdim        case DW_TAG_reference_type:
362314564Sdim          encoding_data_type = Type::eEncodingIsLValueReferenceUID;
363314564Sdim          break;
364314564Sdim        case DW_TAG_rvalue_reference_type:
365314564Sdim          encoding_data_type = Type::eEncodingIsRValueReferenceUID;
366314564Sdim          break;
367314564Sdim        case DW_TAG_typedef:
368314564Sdim          encoding_data_type = Type::eEncodingIsTypedefUID;
369314564Sdim          break;
370314564Sdim        case DW_TAG_const_type:
371314564Sdim          encoding_data_type = Type::eEncodingIsConstUID;
372314564Sdim          break;
373314564Sdim        case DW_TAG_restrict_type:
374314564Sdim          encoding_data_type = Type::eEncodingIsRestrictUID;
375314564Sdim          break;
376314564Sdim        case DW_TAG_volatile_type:
377314564Sdim          encoding_data_type = Type::eEncodingIsVolatileUID;
378314564Sdim          break;
379314564Sdim        }
380292932Sdim
381314564Sdim        if (!clang_type &&
382314564Sdim            (encoding_data_type == Type::eEncodingIsPointerUID ||
383314564Sdim             encoding_data_type == Type::eEncodingIsTypedefUID) &&
384314564Sdim            sc.comp_unit != NULL) {
385314564Sdim          if (tag == DW_TAG_pointer_type) {
386314564Sdim            DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type);
387292932Sdim
388314564Sdim            if (target_die.GetAttributeValueAsUnsigned(DW_AT_APPLE_block, 0)) {
389314564Sdim              // Blocks have a __FuncPtr inside them which is a pointer to a
390314564Sdim              // function of the proper type.
391292932Sdim
392314564Sdim              for (DWARFDIE child_die = target_die.GetFirstChild();
393314564Sdim                   child_die.IsValid(); child_die = child_die.GetSibling()) {
394314564Sdim                if (!strcmp(child_die.GetAttributeValueAsString(DW_AT_name, ""),
395314564Sdim                            "__FuncPtr")) {
396314564Sdim                  DWARFDIE function_pointer_type =
397314564Sdim                      child_die.GetReferencedDIE(DW_AT_type);
398292932Sdim
399314564Sdim                  if (function_pointer_type) {
400314564Sdim                    DWARFDIE function_type =
401314564Sdim                        function_pointer_type.GetReferencedDIE(DW_AT_type);
402292932Sdim
403314564Sdim                    bool function_type_is_new_pointer;
404314564Sdim                    TypeSP lldb_function_type_sp = ParseTypeFromDWARF(
405314564Sdim                        sc, function_type, log, &function_type_is_new_pointer);
406292932Sdim
407314564Sdim                    if (lldb_function_type_sp) {
408314564Sdim                      clang_type = m_ast.CreateBlockPointerType(
409314564Sdim                          lldb_function_type_sp->GetForwardCompilerType());
410314564Sdim                      encoding_data_type = Type::eEncodingIsUID;
411314564Sdim                      encoding_uid.Clear();
412314564Sdim                      resolve_state = Type::eResolveStateFull;
413292932Sdim                    }
414314564Sdim                  }
415292932Sdim
416314564Sdim                  break;
417292932Sdim                }
418314564Sdim              }
419314564Sdim            }
420314564Sdim          }
421292932Sdim
422314564Sdim          bool translation_unit_is_objc =
423314564Sdim              (sc.comp_unit->GetLanguage() == eLanguageTypeObjC ||
424314564Sdim               sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);
425292932Sdim
426314564Sdim          if (translation_unit_is_objc) {
427314564Sdim            if (type_name_cstr != NULL) {
428314564Sdim              static ConstString g_objc_type_name_id("id");
429314564Sdim              static ConstString g_objc_type_name_Class("Class");
430314564Sdim              static ConstString g_objc_type_name_selector("SEL");
431292932Sdim
432314564Sdim              if (type_name_const_str == g_objc_type_name_id) {
433314564Sdim                if (log)
434314564Sdim                  dwarf->GetObjectFile()->GetModule()->LogMessage(
435314564Sdim                      log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
436314564Sdim                           "is Objective C 'id' built-in type.",
437314564Sdim                      die.GetOffset(), die.GetTagAsCString(), die.GetName());
438314564Sdim                clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
439314564Sdim                encoding_data_type = Type::eEncodingIsUID;
440314564Sdim                encoding_uid.Clear();
441314564Sdim                resolve_state = Type::eResolveStateFull;
442292932Sdim
443314564Sdim              } else if (type_name_const_str == g_objc_type_name_Class) {
444314564Sdim                if (log)
445314564Sdim                  dwarf->GetObjectFile()->GetModule()->LogMessage(
446314564Sdim                      log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
447314564Sdim                           "is Objective C 'Class' built-in type.",
448314564Sdim                      die.GetOffset(), die.GetTagAsCString(), die.GetName());
449314564Sdim                clang_type = m_ast.GetBasicType(eBasicTypeObjCClass);
450314564Sdim                encoding_data_type = Type::eEncodingIsUID;
451314564Sdim                encoding_uid.Clear();
452314564Sdim                resolve_state = Type::eResolveStateFull;
453314564Sdim              } else if (type_name_const_str == g_objc_type_name_selector) {
454314564Sdim                if (log)
455314564Sdim                  dwarf->GetObjectFile()->GetModule()->LogMessage(
456314564Sdim                      log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' "
457314564Sdim                           "is Objective C 'selector' built-in type.",
458314564Sdim                      die.GetOffset(), die.GetTagAsCString(), die.GetName());
459314564Sdim                clang_type = m_ast.GetBasicType(eBasicTypeObjCSel);
460314564Sdim                encoding_data_type = Type::eEncodingIsUID;
461314564Sdim                encoding_uid.Clear();
462314564Sdim                resolve_state = Type::eResolveStateFull;
463314564Sdim              }
464314564Sdim            } else if (encoding_data_type == Type::eEncodingIsPointerUID &&
465314564Sdim                       encoding_uid.IsValid()) {
466314564Sdim              // Clang sometimes erroneously emits id as objc_object*.  In that
467314564Sdim              // case we fix up the type to "id".
468292932Sdim
469314564Sdim              const DWARFDIE encoding_die = dwarf->GetDIE(DIERef(encoding_uid));
470292932Sdim
471314564Sdim              if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
472314564Sdim                if (const char *struct_name = encoding_die.GetName()) {
473314564Sdim                  if (!strcmp(struct_name, "objc_object")) {
474314564Sdim                    if (log)
475314564Sdim                      dwarf->GetObjectFile()->GetModule()->LogMessage(
476314564Sdim                          log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s "
477314564Sdim                               "'%s' is 'objc_object*', which we overrode to "
478314564Sdim                               "'id'.",
479314564Sdim                          die.GetOffset(), die.GetTagAsCString(),
480314564Sdim                          die.GetName());
481314564Sdim                    clang_type = m_ast.GetBasicType(eBasicTypeObjCID);
482314564Sdim                    encoding_data_type = Type::eEncodingIsUID;
483314564Sdim                    encoding_uid.Clear();
484314564Sdim                    resolve_state = Type::eResolveStateFull;
485314564Sdim                  }
486314564Sdim                }
487314564Sdim              }
488314564Sdim            }
489314564Sdim          }
490314564Sdim        }
491292932Sdim
492314564Sdim        type_sp.reset(
493314564Sdim            new Type(die.GetID(), dwarf, type_name_const_str, byte_size, NULL,
494314564Sdim                     DIERef(encoding_uid).GetUID(dwarf), encoding_data_type,
495314564Sdim                     &decl, clang_type, resolve_state));
496292932Sdim
497314564Sdim        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
498292932Sdim
499314564Sdim        //                  Type* encoding_type =
500314564Sdim        //                  GetUniquedTypeForDIEOffset(encoding_uid, type_sp,
501314564Sdim        //                  NULL, 0, 0, false);
502314564Sdim        //                  if (encoding_type != NULL)
503314564Sdim        //                  {
504314564Sdim        //                      if (encoding_type != DIE_IS_BEING_PARSED)
505314564Sdim        //                          type_sp->SetEncodingType(encoding_type);
506314564Sdim        //                      else
507314564Sdim        //                          m_indirect_fixups.push_back(type_sp.get());
508314564Sdim        //                  }
509314564Sdim      } break;
510292932Sdim
511314564Sdim      case DW_TAG_structure_type:
512314564Sdim      case DW_TAG_union_type:
513314564Sdim      case DW_TAG_class_type: {
514314564Sdim        // Set a bit that lets us know that we are currently parsing this
515314564Sdim        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
516314564Sdim        bool byte_size_valid = false;
517292932Sdim
518314564Sdim        LanguageType class_language = eLanguageTypeUnknown;
519314564Sdim        bool is_complete_objc_class = false;
520314564Sdim        // bool struct_is_class = false;
521314564Sdim        const size_t num_attributes = die.GetAttributes(attributes);
522314564Sdim        if (num_attributes > 0) {
523314564Sdim          uint32_t i;
524314564Sdim          for (i = 0; i < num_attributes; ++i) {
525314564Sdim            attr = attributes.AttributeAtIndex(i);
526314564Sdim            if (attributes.ExtractFormValueAtIndex(i, form_value)) {
527314564Sdim              switch (attr) {
528314564Sdim              case DW_AT_decl_file:
529314564Sdim                if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid()) {
530314564Sdim                  // llvm-gcc outputs invalid DW_AT_decl_file attributes that
531314564Sdim                  // always
532314564Sdim                  // point to the compile unit file, so we clear this invalid
533314564Sdim                  // value
534314564Sdim                  // so that we can still unique types efficiently.
535314564Sdim                  decl.SetFile(FileSpec("<invalid>", false));
536314564Sdim                } else
537314564Sdim                  decl.SetFile(
538314564Sdim                      sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
539314564Sdim                          form_value.Unsigned()));
540314564Sdim                break;
541292932Sdim
542314564Sdim              case DW_AT_decl_line:
543314564Sdim                decl.SetLine(form_value.Unsigned());
544314564Sdim                break;
545292932Sdim
546314564Sdim              case DW_AT_decl_column:
547314564Sdim                decl.SetColumn(form_value.Unsigned());
548314564Sdim                break;
549309124Sdim
550314564Sdim              case DW_AT_name:
551314564Sdim                type_name_cstr = form_value.AsCString();
552314564Sdim                type_name_const_str.SetCString(type_name_cstr);
553314564Sdim                break;
554292932Sdim
555314564Sdim              case DW_AT_byte_size:
556314564Sdim                byte_size = form_value.Unsigned();
557314564Sdim                byte_size_valid = true;
558314564Sdim                break;
559292932Sdim
560314564Sdim              case DW_AT_accessibility:
561314564Sdim                accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
562314564Sdim                break;
563292932Sdim
564314564Sdim              case DW_AT_declaration:
565314564Sdim                is_forward_declaration = form_value.Boolean();
566314564Sdim                break;
567292932Sdim
568314564Sdim              case DW_AT_APPLE_runtime_class:
569314564Sdim                class_language = (LanguageType)form_value.Signed();
570314564Sdim                break;
571292932Sdim
572314564Sdim              case DW_AT_APPLE_objc_complete_type:
573314564Sdim                is_complete_objc_class = form_value.Signed();
574314564Sdim                break;
575292932Sdim
576314564Sdim              case DW_AT_allocated:
577314564Sdim              case DW_AT_associated:
578314564Sdim              case DW_AT_data_location:
579314564Sdim              case DW_AT_description:
580314564Sdim              case DW_AT_start_scope:
581314564Sdim              case DW_AT_visibility:
582314564Sdim              default:
583314564Sdim              case DW_AT_sibling:
584314564Sdim                break;
585314564Sdim              }
586314564Sdim            }
587314564Sdim          }
588314564Sdim        }
589292932Sdim
590314564Sdim        // UniqueDWARFASTType is large, so don't create a local variables on the
591314564Sdim        // stack, put it on the heap. This function is often called recursively
592314564Sdim        // and clang isn't good and sharing the stack space for variables in
593314564Sdim        // different blocks.
594314564Sdim        std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(
595314564Sdim            new UniqueDWARFASTType());
596292932Sdim
597314564Sdim        ConstString unique_typename(type_name_const_str);
598314564Sdim        Declaration unique_decl(decl);
599292932Sdim
600314564Sdim        if (type_name_const_str) {
601314564Sdim          LanguageType die_language = die.GetLanguage();
602314564Sdim          if (Language::LanguageIsCPlusPlus(die_language)) {
603314564Sdim            // For C++, we rely solely upon the one definition rule that says
604314564Sdim            // only
605314564Sdim            // one thing can exist at a given decl context. We ignore the file
606314564Sdim            // and
607314564Sdim            // line that things are declared on.
608314564Sdim            std::string qualified_name;
609314564Sdim            if (die.GetQualifiedName(qualified_name))
610314564Sdim              unique_typename = ConstString(qualified_name);
611314564Sdim            unique_decl.Clear();
612314564Sdim          }
613292932Sdim
614314564Sdim          if (dwarf->GetUniqueDWARFASTTypeMap().Find(
615314564Sdim                  unique_typename, die, unique_decl,
616314564Sdim                  byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) {
617314564Sdim            type_sp = unique_ast_entry_ap->m_type_sp;
618314564Sdim            if (type_sp) {
619314564Sdim              dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
620314564Sdim              return type_sp;
621314564Sdim            }
622314564Sdim          }
623314564Sdim        }
624292932Sdim
625314564Sdim        DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
626314564Sdim                     DW_TAG_value_to_name(tag), type_name_cstr);
627292932Sdim
628314564Sdim        int tag_decl_kind = -1;
629314564Sdim        AccessType default_accessibility = eAccessNone;
630314564Sdim        if (tag == DW_TAG_structure_type) {
631314564Sdim          tag_decl_kind = clang::TTK_Struct;
632314564Sdim          default_accessibility = eAccessPublic;
633314564Sdim        } else if (tag == DW_TAG_union_type) {
634314564Sdim          tag_decl_kind = clang::TTK_Union;
635314564Sdim          default_accessibility = eAccessPublic;
636314564Sdim        } else if (tag == DW_TAG_class_type) {
637314564Sdim          tag_decl_kind = clang::TTK_Class;
638314564Sdim          default_accessibility = eAccessPrivate;
639314564Sdim        }
640292932Sdim
641314564Sdim        if (byte_size_valid && byte_size == 0 && type_name_cstr &&
642314564Sdim            die.HasChildren() == false &&
643314564Sdim            sc.comp_unit->GetLanguage() == eLanguageTypeObjC) {
644314564Sdim          // Work around an issue with clang at the moment where
645314564Sdim          // forward declarations for objective C classes are emitted
646314564Sdim          // as:
647314564Sdim          //  DW_TAG_structure_type [2]
648314564Sdim          //  DW_AT_name( "ForwardObjcClass" )
649314564Sdim          //  DW_AT_byte_size( 0x00 )
650314564Sdim          //  DW_AT_decl_file( "..." )
651314564Sdim          //  DW_AT_decl_line( 1 )
652314564Sdim          //
653314564Sdim          // Note that there is no DW_AT_declaration and there are
654314564Sdim          // no children, and the byte size is zero.
655314564Sdim          is_forward_declaration = true;
656314564Sdim        }
657292932Sdim
658314564Sdim        if (class_language == eLanguageTypeObjC ||
659314564Sdim            class_language == eLanguageTypeObjC_plus_plus) {
660314564Sdim          if (!is_complete_objc_class &&
661314564Sdim              die.Supports_DW_AT_APPLE_objc_complete_type()) {
662314564Sdim            // We have a valid eSymbolTypeObjCClass class symbol whose
663314564Sdim            // name matches the current objective C class that we
664314564Sdim            // are trying to find and this DIE isn't the complete
665314564Sdim            // definition (we checked is_complete_objc_class above and
666314564Sdim            // know it is false), so the real definition is in here somewhere
667314564Sdim            type_sp = dwarf->FindCompleteObjCDefinitionTypeForDIE(
668314564Sdim                die, type_name_const_str, true);
669292932Sdim
670314564Sdim            if (!type_sp) {
671314564Sdim              SymbolFileDWARFDebugMap *debug_map_symfile =
672314564Sdim                  dwarf->GetDebugMapSymfile();
673314564Sdim              if (debug_map_symfile) {
674314564Sdim                // We weren't able to find a full declaration in
675314564Sdim                // this DWARF, see if we have a declaration anywhere
676314564Sdim                // else...
677314564Sdim                type_sp =
678314564Sdim                    debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
679314564Sdim                        die, type_name_const_str, true);
680314564Sdim              }
681314564Sdim            }
682292932Sdim
683314564Sdim            if (type_sp) {
684314564Sdim              if (log) {
685314564Sdim                dwarf->GetObjectFile()->GetModule()->LogMessage(
686314564Sdim                    log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an "
687314564Sdim                         "incomplete objc type, complete type is 0x%8.8" PRIx64,
688314564Sdim                    static_cast<void *>(this), die.GetOffset(),
689314564Sdim                    DW_TAG_value_to_name(tag), type_name_cstr,
690314564Sdim                    type_sp->GetID());
691314564Sdim              }
692292932Sdim
693314564Sdim              // We found a real definition for this type elsewhere
694314564Sdim              // so lets use it and cache the fact that we found
695314564Sdim              // a complete type for this die
696314564Sdim              dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
697314564Sdim              return type_sp;
698314564Sdim            }
699314564Sdim          }
700314564Sdim        }
701292932Sdim
702314564Sdim        if (is_forward_declaration) {
703314564Sdim          // We have a forward declaration to a type and we need
704314564Sdim          // to try and find a full declaration. We look in the
705314564Sdim          // current type index just in case we have a forward
706314564Sdim          // declaration followed by an actual declarations in the
707314564Sdim          // DWARF. If this fails, we need to look elsewhere...
708314564Sdim          if (log) {
709314564Sdim            dwarf->GetObjectFile()->GetModule()->LogMessage(
710314564Sdim                log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
711314564Sdim                     "forward declaration, trying to find complete type",
712314564Sdim                static_cast<void *>(this), die.GetOffset(),
713314564Sdim                DW_TAG_value_to_name(tag), type_name_cstr);
714314564Sdim          }
715292932Sdim
716314564Sdim          // See if the type comes from a DWO module and if so, track down that
717314564Sdim          // type.
718314564Sdim          type_sp = ParseTypeFromDWO(die, log);
719314564Sdim          if (type_sp)
720314564Sdim            return type_sp;
721292932Sdim
722314564Sdim          DWARFDeclContext die_decl_ctx;
723314564Sdim          die.GetDWARFDeclContext(die_decl_ctx);
724292932Sdim
725314564Sdim          // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
726314564Sdim          // type_name_const_str);
727314564Sdim          type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
728292932Sdim
729314564Sdim          if (!type_sp) {
730314564Sdim            SymbolFileDWARFDebugMap *debug_map_symfile =
731314564Sdim                dwarf->GetDebugMapSymfile();
732314564Sdim            if (debug_map_symfile) {
733314564Sdim              // We weren't able to find a full declaration in
734314564Sdim              // this DWARF, see if we have a declaration anywhere
735314564Sdim              // else...
736314564Sdim              type_sp =
737314564Sdim                  debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
738314564Sdim                      die_decl_ctx);
739314564Sdim            }
740314564Sdim          }
741292932Sdim
742314564Sdim          if (type_sp) {
743314564Sdim            if (log) {
744314564Sdim              dwarf->GetObjectFile()->GetModule()->LogMessage(
745314564Sdim                  log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
746314564Sdim                       "forward declaration, complete type is 0x%8.8" PRIx64,
747314564Sdim                  static_cast<void *>(this), die.GetOffset(),
748314564Sdim                  DW_TAG_value_to_name(tag), type_name_cstr, type_sp->GetID());
749314564Sdim            }
750292932Sdim
751314564Sdim            // We found a real definition for this type elsewhere
752314564Sdim            // so lets use it and cache the fact that we found
753314564Sdim            // a complete type for this die
754314564Sdim            dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
755314564Sdim            clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(
756314564Sdim                dwarf->DebugInfo()->GetDIE(DIERef(type_sp->GetID(), dwarf)));
757314564Sdim            if (defn_decl_ctx)
758314564Sdim              LinkDeclContextToDIE(defn_decl_ctx, die);
759314564Sdim            return type_sp;
760314564Sdim          }
761314564Sdim        }
762314564Sdim        assert(tag_decl_kind != -1);
763314564Sdim        bool clang_type_was_created = false;
764314564Sdim        clang_type.SetCompilerType(
765314564Sdim            &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
766314564Sdim        if (!clang_type) {
767314564Sdim          clang::DeclContext *decl_ctx =
768314564Sdim              GetClangDeclContextContainingDIE(die, nullptr);
769314564Sdim          if (accessibility == eAccessNone && decl_ctx) {
770314564Sdim            // Check the decl context that contains this class/struct/union.
771314564Sdim            // If it is a class we must give it an accessibility.
772314564Sdim            const clang::Decl::Kind containing_decl_kind =
773314564Sdim                decl_ctx->getDeclKind();
774314564Sdim            if (DeclKindIsCXXClass(containing_decl_kind))
775314564Sdim              accessibility = default_accessibility;
776314564Sdim          }
777292932Sdim
778314564Sdim          ClangASTMetadata metadata;
779314564Sdim          metadata.SetUserID(die.GetID());
780314564Sdim          metadata.SetIsDynamicCXXType(dwarf->ClassOrStructIsVirtual(die));
781292932Sdim
782314564Sdim          if (type_name_cstr && strchr(type_name_cstr, '<')) {
783314564Sdim            ClangASTContext::TemplateParameterInfos template_param_infos;
784314564Sdim            if (ParseTemplateParameterInfos(die, template_param_infos)) {
785314564Sdim              clang::ClassTemplateDecl *class_template_decl =
786314564Sdim                  m_ast.ParseClassTemplateDecl(decl_ctx, accessibility,
787314564Sdim                                               type_name_cstr, tag_decl_kind,
788314564Sdim                                               template_param_infos);
789292932Sdim
790314564Sdim              clang::ClassTemplateSpecializationDecl
791314564Sdim                  *class_specialization_decl =
792314564Sdim                      m_ast.CreateClassTemplateSpecializationDecl(
793314564Sdim                          decl_ctx, class_template_decl, tag_decl_kind,
794314564Sdim                          template_param_infos);
795314564Sdim              clang_type = m_ast.CreateClassTemplateSpecializationType(
796314564Sdim                  class_specialization_decl);
797314564Sdim              clang_type_was_created = true;
798292932Sdim
799314564Sdim              m_ast.SetMetadata(class_template_decl, metadata);
800314564Sdim              m_ast.SetMetadata(class_specialization_decl, metadata);
801314564Sdim            }
802314564Sdim          }
803292932Sdim
804314564Sdim          if (!clang_type_was_created) {
805314564Sdim            clang_type_was_created = true;
806314564Sdim            clang_type = m_ast.CreateRecordType(decl_ctx, accessibility,
807314564Sdim                                                type_name_cstr, tag_decl_kind,
808314564Sdim                                                class_language, &metadata);
809314564Sdim          }
810314564Sdim        }
811292932Sdim
812314564Sdim        // Store a forward declaration to this class type in case any
813314564Sdim        // parameters in any class methods need it for the clang
814314564Sdim        // types for function prototypes.
815314564Sdim        LinkDeclContextToDIE(m_ast.GetDeclContextForType(clang_type), die);
816314564Sdim        type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
817314564Sdim                               byte_size, NULL, LLDB_INVALID_UID,
818314564Sdim                               Type::eEncodingIsUID, &decl, clang_type,
819314564Sdim                               Type::eResolveStateForward));
820292932Sdim
821314564Sdim        type_sp->SetIsCompleteObjCClass(is_complete_objc_class);
822292932Sdim
823314564Sdim        // Add our type to the unique type map so we don't
824314564Sdim        // end up creating many copies of the same type over
825314564Sdim        // and over in the ASTContext for our module
826314564Sdim        unique_ast_entry_ap->m_type_sp = type_sp;
827314564Sdim        unique_ast_entry_ap->m_die = die;
828314564Sdim        unique_ast_entry_ap->m_declaration = unique_decl;
829314564Sdim        unique_ast_entry_ap->m_byte_size = byte_size;
830314564Sdim        dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
831314564Sdim                                                 *unique_ast_entry_ap);
832292932Sdim
833314564Sdim        if (is_forward_declaration && die.HasChildren()) {
834314564Sdim          // Check to see if the DIE actually has a definition, some version of
835314564Sdim          // GCC will
836314564Sdim          // emit DIEs with DW_AT_declaration set to true, but yet still have
837314564Sdim          // subprogram,
838314564Sdim          // members, or inheritance, so we can't trust it
839314564Sdim          DWARFDIE child_die = die.GetFirstChild();
840314564Sdim          while (child_die) {
841314564Sdim            switch (child_die.Tag()) {
842314564Sdim            case DW_TAG_inheritance:
843314564Sdim            case DW_TAG_subprogram:
844314564Sdim            case DW_TAG_member:
845314564Sdim            case DW_TAG_APPLE_property:
846314564Sdim            case DW_TAG_class_type:
847314564Sdim            case DW_TAG_structure_type:
848314564Sdim            case DW_TAG_enumeration_type:
849314564Sdim            case DW_TAG_typedef:
850314564Sdim            case DW_TAG_union_type:
851314564Sdim              child_die.Clear();
852314564Sdim              is_forward_declaration = false;
853314564Sdim              break;
854314564Sdim            default:
855314564Sdim              child_die = child_die.GetSibling();
856314564Sdim              break;
857314564Sdim            }
858314564Sdim          }
859314564Sdim        }
860292932Sdim
861314564Sdim        if (!is_forward_declaration) {
862314564Sdim          // Always start the definition for a class type so that
863314564Sdim          // if the class has child classes or types that require
864314564Sdim          // the class to be created for use as their decl contexts
865314564Sdim          // the class will be ready to accept these child definitions.
866314564Sdim          if (die.HasChildren() == false) {
867314564Sdim            // No children for this struct/union/class, lets finish it
868314564Sdim            if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
869314564Sdim              ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
870314564Sdim            } else {
871314564Sdim              dwarf->GetObjectFile()->GetModule()->ReportError(
872314564Sdim                  "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
873314564Sdim                  "definition.\nPlease file a bug and attach the file at the "
874314564Sdim                  "start of this error message",
875314564Sdim                  die.GetOffset(), type_name_cstr);
876314564Sdim            }
877292932Sdim
878314564Sdim            if (tag == DW_TAG_structure_type) // this only applies in C
879314564Sdim            {
880314564Sdim              clang::RecordDecl *record_decl =
881314564Sdim                  ClangASTContext::GetAsRecordDecl(clang_type);
882292932Sdim
883314564Sdim              if (record_decl) {
884314564Sdim                GetClangASTImporter().InsertRecordDecl(
885314564Sdim                    record_decl, ClangASTImporter::LayoutInfo());
886314564Sdim              }
887314564Sdim            }
888314564Sdim          } else if (clang_type_was_created) {
889314564Sdim            // Start the definition if the class is not objective C since
890314564Sdim            // the underlying decls respond to isCompleteDefinition(). Objective
891314564Sdim            // C decls don't respond to isCompleteDefinition() so we can't
892314564Sdim            // start the declaration definition right away. For C++
893314564Sdim            // class/union/structs
894314564Sdim            // we want to start the definition in case the class is needed as
895314564Sdim            // the
896314564Sdim            // declaration context for a contained class or type without the
897314564Sdim            // need
898314564Sdim            // to complete that type..
899292932Sdim
900314564Sdim            if (class_language != eLanguageTypeObjC &&
901314564Sdim                class_language != eLanguageTypeObjC_plus_plus)
902314564Sdim              ClangASTContext::StartTagDeclarationDefinition(clang_type);
903292932Sdim
904314564Sdim            // Leave this as a forward declaration until we need
905314564Sdim            // to know the details of the type. lldb_private::Type
906314564Sdim            // will automatically call the SymbolFile virtual function
907314564Sdim            // "SymbolFileDWARF::CompleteType(Type *)"
908314564Sdim            // When the definition needs to be defined.
909314564Sdim            assert(!dwarf->GetForwardDeclClangTypeToDie().count(
910314564Sdim                       ClangUtil::RemoveFastQualifiers(clang_type)
911314564Sdim                           .GetOpaqueQualType()) &&
912314564Sdim                   "Type already in the forward declaration map!");
913314564Sdim            // Can't assume m_ast.GetSymbolFile() is actually a SymbolFileDWARF,
914314564Sdim            // it can be a
915314564Sdim            // SymbolFileDWARFDebugMap for Apple binaries.
916314564Sdim            dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] =
917314564Sdim                clang_type.GetOpaqueQualType();
918314564Sdim            dwarf->GetForwardDeclClangTypeToDie()
919314564Sdim                [ClangUtil::RemoveFastQualifiers(clang_type)
920314564Sdim                     .GetOpaqueQualType()] = die.GetDIERef();
921314564Sdim            m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
922314564Sdim          }
923314564Sdim        }
924314564Sdim      } break;
925292932Sdim
926314564Sdim      case DW_TAG_enumeration_type: {
927314564Sdim        // Set a bit that lets us know that we are currently parsing this
928314564Sdim        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
929292932Sdim
930314564Sdim        DWARFFormValue encoding_form;
931292932Sdim
932314564Sdim        const size_t num_attributes = die.GetAttributes(attributes);
933314564Sdim        if (num_attributes > 0) {
934314564Sdim          uint32_t i;
935292932Sdim
936314564Sdim          for (i = 0; i < num_attributes; ++i) {
937314564Sdim            attr = attributes.AttributeAtIndex(i);
938314564Sdim            if (attributes.ExtractFormValueAtIndex(i, form_value)) {
939314564Sdim              switch (attr) {
940314564Sdim              case DW_AT_decl_file:
941314564Sdim                decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
942314564Sdim                    form_value.Unsigned()));
943314564Sdim                break;
944314564Sdim              case DW_AT_decl_line:
945314564Sdim                decl.SetLine(form_value.Unsigned());
946314564Sdim                break;
947314564Sdim              case DW_AT_decl_column:
948314564Sdim                decl.SetColumn(form_value.Unsigned());
949314564Sdim                break;
950314564Sdim              case DW_AT_name:
951314564Sdim                type_name_cstr = form_value.AsCString();
952314564Sdim                type_name_const_str.SetCString(type_name_cstr);
953314564Sdim                break;
954314564Sdim              case DW_AT_type:
955314564Sdim                encoding_form = form_value;
956314564Sdim                break;
957314564Sdim              case DW_AT_byte_size:
958314564Sdim                byte_size = form_value.Unsigned();
959314564Sdim                break;
960314564Sdim              case DW_AT_accessibility:
961314564Sdim                break; // accessibility =
962314564Sdim                       // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
963314564Sdim              case DW_AT_declaration:
964314564Sdim                is_forward_declaration = form_value.Boolean();
965314564Sdim                break;
966314564Sdim              case DW_AT_allocated:
967314564Sdim              case DW_AT_associated:
968314564Sdim              case DW_AT_bit_stride:
969314564Sdim              case DW_AT_byte_stride:
970314564Sdim              case DW_AT_data_location:
971314564Sdim              case DW_AT_description:
972314564Sdim              case DW_AT_start_scope:
973314564Sdim              case DW_AT_visibility:
974314564Sdim              case DW_AT_specification:
975314564Sdim              case DW_AT_abstract_origin:
976314564Sdim              case DW_AT_sibling:
977314564Sdim                break;
978314564Sdim              }
979314564Sdim            }
980314564Sdim          }
981292932Sdim
982314564Sdim          if (is_forward_declaration) {
983314564Sdim            type_sp = ParseTypeFromDWO(die, log);
984314564Sdim            if (type_sp)
985314564Sdim              return type_sp;
986292932Sdim
987314564Sdim            DWARFDeclContext die_decl_ctx;
988314564Sdim            die.GetDWARFDeclContext(die_decl_ctx);
989292932Sdim
990314564Sdim            type_sp =
991314564Sdim                dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx);
992292932Sdim
993314564Sdim            if (!type_sp) {
994314564Sdim              SymbolFileDWARFDebugMap *debug_map_symfile =
995314564Sdim                  dwarf->GetDebugMapSymfile();
996314564Sdim              if (debug_map_symfile) {
997314564Sdim                // We weren't able to find a full declaration in
998314564Sdim                // this DWARF, see if we have a declaration anywhere
999314564Sdim                // else...
1000314564Sdim                type_sp =
1001314564Sdim                    debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(
1002314564Sdim                        die_decl_ctx);
1003314564Sdim              }
1004314564Sdim            }
1005292932Sdim
1006314564Sdim            if (type_sp) {
1007314564Sdim              if (log) {
1008314564Sdim                dwarf->GetObjectFile()->GetModule()->LogMessage(
1009314564Sdim                    log, "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a "
1010314564Sdim                         "forward declaration, complete type is 0x%8.8" PRIx64,
1011314564Sdim                    static_cast<void *>(this), die.GetOffset(),
1012314564Sdim                    DW_TAG_value_to_name(tag), type_name_cstr,
1013314564Sdim                    type_sp->GetID());
1014314564Sdim              }
1015292932Sdim
1016314564Sdim              // We found a real definition for this type elsewhere
1017314564Sdim              // so lets use it and cache the fact that we found
1018314564Sdim              // a complete type for this die
1019314564Sdim              dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
1020314564Sdim              clang::DeclContext *defn_decl_ctx =
1021314564Sdim                  GetCachedClangDeclContextForDIE(dwarf->DebugInfo()->GetDIE(
1022314564Sdim                      DIERef(type_sp->GetID(), dwarf)));
1023314564Sdim              if (defn_decl_ctx)
1024314564Sdim                LinkDeclContextToDIE(defn_decl_ctx, die);
1025314564Sdim              return type_sp;
1026314564Sdim            }
1027314564Sdim          }
1028314564Sdim          DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
1029314564Sdim                       DW_TAG_value_to_name(tag), type_name_cstr);
1030292932Sdim
1031314564Sdim          CompilerType enumerator_clang_type;
1032314564Sdim          clang_type.SetCompilerType(
1033314564Sdim              &m_ast,
1034314564Sdim              dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
1035314564Sdim          if (!clang_type) {
1036314564Sdim            if (encoding_form.IsValid()) {
1037314564Sdim              Type *enumerator_type =
1038314564Sdim                  dwarf->ResolveTypeUID(DIERef(encoding_form));
1039314564Sdim              if (enumerator_type)
1040314564Sdim                enumerator_clang_type = enumerator_type->GetFullCompilerType();
1041314564Sdim            }
1042292932Sdim
1043314564Sdim            if (!enumerator_clang_type) {
1044314564Sdim              if (byte_size > 0) {
1045314564Sdim                enumerator_clang_type =
1046314564Sdim                    m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize(
1047314564Sdim                        NULL, DW_ATE_signed, byte_size * 8);
1048314564Sdim              } else {
1049314564Sdim                enumerator_clang_type = m_ast.GetBasicType(eBasicTypeInt);
1050314564Sdim              }
1051314564Sdim            }
1052292932Sdim
1053314564Sdim            clang_type = m_ast.CreateEnumerationType(
1054314564Sdim                type_name_cstr, GetClangDeclContextContainingDIE(die, nullptr),
1055314564Sdim                decl, enumerator_clang_type);
1056314564Sdim          } else {
1057314564Sdim            enumerator_clang_type =
1058314564Sdim                m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType());
1059314564Sdim          }
1060292932Sdim
1061314564Sdim          LinkDeclContextToDIE(
1062314564Sdim              ClangASTContext::GetDeclContextForType(clang_type), die);
1063292932Sdim
1064314564Sdim          type_sp.reset(new Type(
1065314564Sdim              die.GetID(), dwarf, type_name_const_str, byte_size, NULL,
1066314564Sdim              DIERef(encoding_form).GetUID(dwarf), Type::eEncodingIsUID, &decl,
1067314564Sdim              clang_type, Type::eResolveStateForward));
1068292932Sdim
1069314564Sdim          if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
1070314564Sdim            if (die.HasChildren()) {
1071314564Sdim              SymbolContext cu_sc(die.GetLLDBCompileUnit());
1072314564Sdim              bool is_signed = false;
1073314564Sdim              enumerator_clang_type.IsIntegerType(is_signed);
1074314564Sdim              ParseChildEnumerators(cu_sc, clang_type, is_signed,
1075314564Sdim                                    type_sp->GetByteSize(), die);
1076314564Sdim            }
1077314564Sdim            ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
1078314564Sdim          } else {
1079314564Sdim            dwarf->GetObjectFile()->GetModule()->ReportError(
1080314564Sdim                "DWARF DIE at 0x%8.8x named \"%s\" was not able to start its "
1081314564Sdim                "definition.\nPlease file a bug and attach the file at the "
1082314564Sdim                "start of this error message",
1083314564Sdim                die.GetOffset(), type_name_cstr);
1084314564Sdim          }
1085314564Sdim        }
1086314564Sdim      } break;
1087292932Sdim
1088314564Sdim      case DW_TAG_inlined_subroutine:
1089314564Sdim      case DW_TAG_subprogram:
1090314564Sdim      case DW_TAG_subroutine_type: {
1091314564Sdim        // Set a bit that lets us know that we are currently parsing this
1092314564Sdim        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
1093292932Sdim
1094314564Sdim        DWARFFormValue type_die_form;
1095314564Sdim        bool is_variadic = false;
1096314564Sdim        bool is_inline = false;
1097314564Sdim        bool is_static = false;
1098314564Sdim        bool is_virtual = false;
1099314564Sdim        bool is_explicit = false;
1100314564Sdim        bool is_artificial = false;
1101314564Sdim        bool has_template_params = false;
1102314564Sdim        DWARFFormValue specification_die_form;
1103314564Sdim        DWARFFormValue abstract_origin_die_form;
1104314564Sdim        dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;
1105292932Sdim
1106314564Sdim        unsigned type_quals = 0;
1107314564Sdim        clang::StorageClass storage =
1108314564Sdim            clang::SC_None; //, Extern, Static, PrivateExtern
1109292932Sdim
1110314564Sdim        const size_t num_attributes = die.GetAttributes(attributes);
1111314564Sdim        if (num_attributes > 0) {
1112314564Sdim          uint32_t i;
1113314564Sdim          for (i = 0; i < num_attributes; ++i) {
1114314564Sdim            attr = attributes.AttributeAtIndex(i);
1115314564Sdim            if (attributes.ExtractFormValueAtIndex(i, form_value)) {
1116314564Sdim              switch (attr) {
1117314564Sdim              case DW_AT_decl_file:
1118314564Sdim                decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
1119314564Sdim                    form_value.Unsigned()));
1120314564Sdim                break;
1121314564Sdim              case DW_AT_decl_line:
1122314564Sdim                decl.SetLine(form_value.Unsigned());
1123314564Sdim                break;
1124314564Sdim              case DW_AT_decl_column:
1125314564Sdim                decl.SetColumn(form_value.Unsigned());
1126314564Sdim                break;
1127314564Sdim              case DW_AT_name:
1128314564Sdim                type_name_cstr = form_value.AsCString();
1129314564Sdim                type_name_const_str.SetCString(type_name_cstr);
1130314564Sdim                break;
1131292932Sdim
1132314564Sdim              case DW_AT_linkage_name:
1133314564Sdim              case DW_AT_MIPS_linkage_name:
1134314564Sdim                break; // mangled =
1135314564Sdim                       // form_value.AsCString(&dwarf->get_debug_str_data());
1136314564Sdim                       // break;
1137314564Sdim              case DW_AT_type:
1138314564Sdim                type_die_form = form_value;
1139314564Sdim                break;
1140314564Sdim              case DW_AT_accessibility:
1141314564Sdim                accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
1142314564Sdim                break;
1143314564Sdim              case DW_AT_declaration:
1144314564Sdim                break; // is_forward_declaration = form_value.Boolean(); break;
1145314564Sdim              case DW_AT_inline:
1146314564Sdim                is_inline = form_value.Boolean();
1147314564Sdim                break;
1148314564Sdim              case DW_AT_virtuality:
1149314564Sdim                is_virtual = form_value.Boolean();
1150314564Sdim                break;
1151314564Sdim              case DW_AT_explicit:
1152314564Sdim                is_explicit = form_value.Boolean();
1153314564Sdim                break;
1154314564Sdim              case DW_AT_artificial:
1155314564Sdim                is_artificial = form_value.Boolean();
1156314564Sdim                break;
1157292932Sdim
1158314564Sdim              case DW_AT_external:
1159314564Sdim                if (form_value.Unsigned()) {
1160314564Sdim                  if (storage == clang::SC_None)
1161314564Sdim                    storage = clang::SC_Extern;
1162314564Sdim                  else
1163314564Sdim                    storage = clang::SC_PrivateExtern;
1164314564Sdim                }
1165314564Sdim                break;
1166292932Sdim
1167314564Sdim              case DW_AT_specification:
1168314564Sdim                specification_die_form = form_value;
1169314564Sdim                break;
1170292932Sdim
1171314564Sdim              case DW_AT_abstract_origin:
1172314564Sdim                abstract_origin_die_form = form_value;
1173314564Sdim                break;
1174292932Sdim
1175314564Sdim              case DW_AT_object_pointer:
1176314564Sdim                object_pointer_die_offset = form_value.Reference();
1177314564Sdim                break;
1178292932Sdim
1179314564Sdim              case DW_AT_allocated:
1180314564Sdim              case DW_AT_associated:
1181314564Sdim              case DW_AT_address_class:
1182314564Sdim              case DW_AT_calling_convention:
1183314564Sdim              case DW_AT_data_location:
1184314564Sdim              case DW_AT_elemental:
1185314564Sdim              case DW_AT_entry_pc:
1186314564Sdim              case DW_AT_frame_base:
1187314564Sdim              case DW_AT_high_pc:
1188314564Sdim              case DW_AT_low_pc:
1189314564Sdim              case DW_AT_prototyped:
1190314564Sdim              case DW_AT_pure:
1191314564Sdim              case DW_AT_ranges:
1192314564Sdim              case DW_AT_recursive:
1193314564Sdim              case DW_AT_return_addr:
1194314564Sdim              case DW_AT_segment:
1195314564Sdim              case DW_AT_start_scope:
1196314564Sdim              case DW_AT_static_link:
1197314564Sdim              case DW_AT_trampoline:
1198314564Sdim              case DW_AT_visibility:
1199314564Sdim              case DW_AT_vtable_elem_location:
1200314564Sdim              case DW_AT_description:
1201314564Sdim              case DW_AT_sibling:
1202314564Sdim                break;
1203314564Sdim              }
1204314564Sdim            }
1205314564Sdim          }
1206314564Sdim        }
1207292932Sdim
1208314564Sdim        std::string object_pointer_name;
1209314564Sdim        if (object_pointer_die_offset != DW_INVALID_OFFSET) {
1210314564Sdim          DWARFDIE object_pointer_die = die.GetDIE(object_pointer_die_offset);
1211314564Sdim          if (object_pointer_die) {
1212314564Sdim            const char *object_pointer_name_cstr = object_pointer_die.GetName();
1213314564Sdim            if (object_pointer_name_cstr)
1214314564Sdim              object_pointer_name = object_pointer_name_cstr;
1215314564Sdim          }
1216314564Sdim        }
1217292932Sdim
1218314564Sdim        DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
1219314564Sdim                     DW_TAG_value_to_name(tag), type_name_cstr);
1220292932Sdim
1221314564Sdim        CompilerType return_clang_type;
1222314564Sdim        Type *func_type = NULL;
1223292932Sdim
1224314564Sdim        if (type_die_form.IsValid())
1225314564Sdim          func_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
1226292932Sdim
1227314564Sdim        if (func_type)
1228314564Sdim          return_clang_type = func_type->GetForwardCompilerType();
1229314564Sdim        else
1230314564Sdim          return_clang_type = m_ast.GetBasicType(eBasicTypeVoid);
1231292932Sdim
1232314564Sdim        std::vector<CompilerType> function_param_types;
1233314564Sdim        std::vector<clang::ParmVarDecl *> function_param_decls;
1234292932Sdim
1235314564Sdim        // Parse the function children for the parameters
1236292932Sdim
1237314564Sdim        DWARFDIE decl_ctx_die;
1238314564Sdim        clang::DeclContext *containing_decl_ctx =
1239314564Sdim            GetClangDeclContextContainingDIE(die, &decl_ctx_die);
1240314564Sdim        const clang::Decl::Kind containing_decl_kind =
1241314564Sdim            containing_decl_ctx->getDeclKind();
1242309124Sdim
1243314564Sdim        bool is_cxx_method = DeclKindIsCXXClass(containing_decl_kind);
1244314564Sdim        // Start off static. This will be set to false in
1245314564Sdim        // ParseChildParameters(...)
1246314564Sdim        // if we find a "this" parameters as the first parameter
1247314564Sdim        if (is_cxx_method) {
1248314564Sdim          is_static = true;
1249314564Sdim        }
1250292932Sdim
1251314564Sdim        if (die.HasChildren()) {
1252314564Sdim          bool skip_artificial = true;
1253314564Sdim          ParseChildParameters(sc, containing_decl_ctx, die, skip_artificial,
1254314564Sdim                               is_static, is_variadic, has_template_params,
1255314564Sdim                               function_param_types, function_param_decls,
1256314564Sdim                               type_quals);
1257314564Sdim        }
1258292932Sdim
1259314564Sdim        bool ignore_containing_context = false;
1260314564Sdim        // Check for templatized class member functions. If we had any
1261314564Sdim        // DW_TAG_template_type_parameter
1262314564Sdim        // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we
1263314564Sdim        // can't let this become
1264314564Sdim        // a method in a class. Why? Because templatized functions are only
1265314564Sdim        // emitted if one of the
1266314564Sdim        // templatized methods is used in the current compile unit and we will
1267314564Sdim        // end up with classes
1268314564Sdim        // that may or may not include these member functions and this means one
1269314564Sdim        // class won't match another
1270314564Sdim        // class definition and it affects our ability to use a class in the
1271314564Sdim        // clang expression parser. So
1272314564Sdim        // for the greater good, we currently must not allow any template member
1273314564Sdim        // functions in a class definition.
1274314564Sdim        if (is_cxx_method && has_template_params) {
1275314564Sdim          ignore_containing_context = true;
1276314564Sdim          is_cxx_method = false;
1277314564Sdim        }
1278292932Sdim
1279314564Sdim        // clang_type will get the function prototype clang type after this call
1280314564Sdim        clang_type = m_ast.CreateFunctionType(
1281314564Sdim            return_clang_type, function_param_types.data(),
1282314564Sdim            function_param_types.size(), is_variadic, type_quals);
1283292932Sdim
1284314564Sdim        if (type_name_cstr) {
1285314564Sdim          bool type_handled = false;
1286314564Sdim          if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) {
1287314564Sdim            ObjCLanguage::MethodName objc_method(type_name_cstr, true);
1288314564Sdim            if (objc_method.IsValid(true)) {
1289314564Sdim              CompilerType class_opaque_type;
1290314564Sdim              ConstString class_name(objc_method.GetClassName());
1291314564Sdim              if (class_name) {
1292314564Sdim                TypeSP complete_objc_class_type_sp(
1293314564Sdim                    dwarf->FindCompleteObjCDefinitionTypeForDIE(
1294314564Sdim                        DWARFDIE(), class_name, false));
1295292932Sdim
1296314564Sdim                if (complete_objc_class_type_sp) {
1297314564Sdim                  CompilerType type_clang_forward_type =
1298314564Sdim                      complete_objc_class_type_sp->GetForwardCompilerType();
1299314564Sdim                  if (ClangASTContext::IsObjCObjectOrInterfaceType(
1300314564Sdim                          type_clang_forward_type))
1301314564Sdim                    class_opaque_type = type_clang_forward_type;
1302314564Sdim                }
1303314564Sdim              }
1304292932Sdim
1305314564Sdim              if (class_opaque_type) {
1306314564Sdim                // If accessibility isn't set to anything valid, assume public
1307314564Sdim                // for
1308314564Sdim                // now...
1309314564Sdim                if (accessibility == eAccessNone)
1310314564Sdim                  accessibility = eAccessPublic;
1311292932Sdim
1312314564Sdim                clang::ObjCMethodDecl *objc_method_decl =
1313314564Sdim                    m_ast.AddMethodToObjCObjectType(
1314314564Sdim                        class_opaque_type, type_name_cstr, clang_type,
1315314564Sdim                        accessibility, is_artificial, is_variadic);
1316314564Sdim                type_handled = objc_method_decl != NULL;
1317314564Sdim                if (type_handled) {
1318314564Sdim                  LinkDeclContextToDIE(
1319314564Sdim                      ClangASTContext::GetAsDeclContext(objc_method_decl), die);
1320314564Sdim                  m_ast.SetMetadataAsUserID(objc_method_decl, die.GetID());
1321314564Sdim                } else {
1322314564Sdim                  dwarf->GetObjectFile()->GetModule()->ReportError(
1323314564Sdim                      "{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), "
1324314564Sdim                      "please file a bug and attach the file at the start of "
1325314564Sdim                      "this error message",
1326314564Sdim                      die.GetOffset(), tag, DW_TAG_value_to_name(tag));
1327314564Sdim                }
1328314564Sdim              }
1329314564Sdim            } else if (is_cxx_method) {
1330314564Sdim              // Look at the parent of this DIE and see if is is
1331314564Sdim              // a class or struct and see if this is actually a
1332314564Sdim              // C++ method
1333314564Sdim              Type *class_type = dwarf->ResolveType(decl_ctx_die);
1334314564Sdim              if (class_type) {
1335314564Sdim                bool alternate_defn = false;
1336314564Sdim                if (class_type->GetID() != decl_ctx_die.GetID() ||
1337314564Sdim                    decl_ctx_die.GetContainingDWOModuleDIE()) {
1338314564Sdim                  alternate_defn = true;
1339292932Sdim
1340314564Sdim                  // We uniqued the parent class of this function to another
1341314564Sdim                  // class
1342314564Sdim                  // so we now need to associate all dies under "decl_ctx_die"
1343314564Sdim                  // to
1344314564Sdim                  // DIEs in the DIE for "class_type"...
1345314564Sdim                  SymbolFileDWARF *class_symfile = NULL;
1346314564Sdim                  DWARFDIE class_type_die;
1347292932Sdim
1348314564Sdim                  SymbolFileDWARFDebugMap *debug_map_symfile =
1349314564Sdim                      dwarf->GetDebugMapSymfile();
1350314564Sdim                  if (debug_map_symfile) {
1351314564Sdim                    class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(
1352314564Sdim                        SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(
1353314564Sdim                            class_type->GetID()));
1354314564Sdim                    class_type_die = class_symfile->DebugInfo()->GetDIE(
1355314564Sdim                        DIERef(class_type->GetID(), dwarf));
1356314564Sdim                  } else {
1357314564Sdim                    class_symfile = dwarf;
1358314564Sdim                    class_type_die = dwarf->DebugInfo()->GetDIE(
1359314564Sdim                        DIERef(class_type->GetID(), dwarf));
1360314564Sdim                  }
1361314564Sdim                  if (class_type_die) {
1362314564Sdim                    DWARFDIECollection failures;
1363292932Sdim
1364314564Sdim                    CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
1365314564Sdim                                               class_type, failures);
1366292932Sdim
1367314564Sdim                    // FIXME do something with these failures that's smarter
1368314564Sdim                    // than
1369314564Sdim                    // just dropping them on the ground.  Unfortunately classes
1370314564Sdim                    // don't
1371314564Sdim                    // like having stuff added to them after their definitions
1372314564Sdim                    // are
1373314564Sdim                    // complete...
1374292932Sdim
1375314564Sdim                    type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
1376314564Sdim                    if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
1377314564Sdim                      type_sp = type_ptr->shared_from_this();
1378314564Sdim                      break;
1379314564Sdim                    }
1380314564Sdim                  }
1381314564Sdim                }
1382292932Sdim
1383314564Sdim                if (specification_die_form.IsValid()) {
1384314564Sdim                  // We have a specification which we are going to base our
1385314564Sdim                  // function
1386314564Sdim                  // prototype off of, so we need this type to be completed so
1387314564Sdim                  // that the
1388314564Sdim                  // m_die_to_decl_ctx for the method in the specification has a
1389314564Sdim                  // valid
1390314564Sdim                  // clang decl context.
1391314564Sdim                  class_type->GetForwardCompilerType();
1392314564Sdim                  // If we have a specification, then the function type should
1393314564Sdim                  // have been
1394314564Sdim                  // made with the specification and not with this die.
1395314564Sdim                  DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(
1396314564Sdim                      DIERef(specification_die_form));
1397314564Sdim                  clang::DeclContext *spec_clang_decl_ctx =
1398314564Sdim                      GetClangDeclContextForDIE(spec_die);
1399314564Sdim                  if (spec_clang_decl_ctx) {
1400314564Sdim                    LinkDeclContextToDIE(spec_clang_decl_ctx, die);
1401314564Sdim                  } else {
1402314564Sdim                    dwarf->GetObjectFile()->GetModule()->ReportWarning(
1403314564Sdim                        "0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8" PRIx64
1404314564Sdim                        ") has no decl\n",
1405314564Sdim                        die.GetID(), specification_die_form.Reference());
1406314564Sdim                  }
1407314564Sdim                  type_handled = true;
1408314564Sdim                } else if (abstract_origin_die_form.IsValid()) {
1409314564Sdim                  // We have a specification which we are going to base our
1410314564Sdim                  // function
1411314564Sdim                  // prototype off of, so we need this type to be completed so
1412314564Sdim                  // that the
1413314564Sdim                  // m_die_to_decl_ctx for the method in the abstract origin has
1414314564Sdim                  // a valid
1415314564Sdim                  // clang decl context.
1416314564Sdim                  class_type->GetForwardCompilerType();
1417292932Sdim
1418314564Sdim                  DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE(
1419314564Sdim                      DIERef(abstract_origin_die_form));
1420314564Sdim                  clang::DeclContext *abs_clang_decl_ctx =
1421314564Sdim                      GetClangDeclContextForDIE(abs_die);
1422314564Sdim                  if (abs_clang_decl_ctx) {
1423314564Sdim                    LinkDeclContextToDIE(abs_clang_decl_ctx, die);
1424314564Sdim                  } else {
1425314564Sdim                    dwarf->GetObjectFile()->GetModule()->ReportWarning(
1426314564Sdim                        "0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8" PRIx64
1427314564Sdim                        ") has no decl\n",
1428314564Sdim                        die.GetID(), abstract_origin_die_form.Reference());
1429314564Sdim                  }
1430314564Sdim                  type_handled = true;
1431314564Sdim                } else {
1432314564Sdim                  CompilerType class_opaque_type =
1433314564Sdim                      class_type->GetForwardCompilerType();
1434314564Sdim                  if (ClangASTContext::IsCXXClassType(class_opaque_type)) {
1435314564Sdim                    if (class_opaque_type.IsBeingDefined() || alternate_defn) {
1436314564Sdim                      if (!is_static && !die.HasChildren()) {
1437314564Sdim                        // We have a C++ member function with no children (this
1438314564Sdim                        // pointer!)
1439314564Sdim                        // and clang will get mad if we try and make a function
1440314564Sdim                        // that isn't
1441314564Sdim                        // well formed in the DWARF, so we will just skip it...
1442314564Sdim                        type_handled = true;
1443314564Sdim                      } else {
1444314564Sdim                        bool add_method = true;
1445314564Sdim                        if (alternate_defn) {
1446314564Sdim                          // If an alternate definition for the class exists,
1447314564Sdim                          // then add the method only if an
1448314564Sdim                          // equivalent is not already present.
1449314564Sdim                          clang::CXXRecordDecl *record_decl =
1450314564Sdim                              m_ast.GetAsCXXRecordDecl(
1451314564Sdim                                  class_opaque_type.GetOpaqueQualType());
1452314564Sdim                          if (record_decl) {
1453314564Sdim                            for (auto method_iter = record_decl->method_begin();
1454314564Sdim                                 method_iter != record_decl->method_end();
1455314564Sdim                                 method_iter++) {
1456314564Sdim                              clang::CXXMethodDecl *method_decl = *method_iter;
1457314564Sdim                              if (method_decl->getNameInfo().getAsString() ==
1458314564Sdim                                  std::string(type_name_cstr)) {
1459314564Sdim                                if (method_decl->getType() ==
1460314564Sdim                                    ClangUtil::GetQualType(clang_type)) {
1461314564Sdim                                  add_method = false;
1462314564Sdim                                  LinkDeclContextToDIE(
1463314564Sdim                                      ClangASTContext::GetAsDeclContext(
1464314564Sdim                                          method_decl),
1465314564Sdim                                      die);
1466314564Sdim                                  type_handled = true;
1467292932Sdim
1468314564Sdim                                  break;
1469314564Sdim                                }
1470314564Sdim                              }
1471314564Sdim                            }
1472314564Sdim                          }
1473314564Sdim                        }
1474292932Sdim
1475314564Sdim                        if (add_method) {
1476314564Sdim                          llvm::PrettyStackTraceFormat stack_trace(
1477314564Sdim                              "SymbolFileDWARF::ParseType() is adding a method "
1478314564Sdim                              "%s to class %s in DIE 0x%8.8" PRIx64 " from %s",
1479314564Sdim                              type_name_cstr,
1480314564Sdim                              class_type->GetName().GetCString(), die.GetID(),
1481314564Sdim                              dwarf->GetObjectFile()
1482314564Sdim                                  ->GetFileSpec()
1483314564Sdim                                  .GetPath()
1484314564Sdim                                  .c_str());
1485292932Sdim
1486314564Sdim                          const bool is_attr_used = false;
1487314564Sdim                          // Neither GCC 4.2 nor clang++ currently set a valid
1488314564Sdim                          // accessibility
1489314564Sdim                          // in the DWARF for C++ methods... Default to public
1490314564Sdim                          // for now...
1491314564Sdim                          if (accessibility == eAccessNone)
1492314564Sdim                            accessibility = eAccessPublic;
1493292932Sdim
1494314564Sdim                          clang::CXXMethodDecl *cxx_method_decl =
1495314564Sdim                              m_ast.AddMethodToCXXRecordType(
1496314564Sdim                                  class_opaque_type.GetOpaqueQualType(),
1497314564Sdim                                  type_name_cstr, clang_type, accessibility,
1498314564Sdim                                  is_virtual, is_static, is_inline, is_explicit,
1499314564Sdim                                  is_attr_used, is_artificial);
1500292932Sdim
1501314564Sdim                          type_handled = cxx_method_decl != NULL;
1502292932Sdim
1503314564Sdim                          if (type_handled) {
1504314564Sdim                            LinkDeclContextToDIE(
1505314564Sdim                                ClangASTContext::GetAsDeclContext(
1506314564Sdim                                    cxx_method_decl),
1507314564Sdim                                die);
1508292932Sdim
1509314564Sdim                            ClangASTMetadata metadata;
1510314564Sdim                            metadata.SetUserID(die.GetID());
1511292932Sdim
1512314564Sdim                            if (!object_pointer_name.empty()) {
1513314564Sdim                              metadata.SetObjectPtrName(
1514314564Sdim                                  object_pointer_name.c_str());
1515314564Sdim                              if (log)
1516314564Sdim                                log->Printf(
1517314564Sdim                                    "Setting object pointer name: %s on method "
1518314564Sdim                                    "object %p.\n",
1519314564Sdim                                    object_pointer_name.c_str(),
1520314564Sdim                                    static_cast<void *>(cxx_method_decl));
1521292932Sdim                            }
1522314564Sdim                            m_ast.SetMetadata(cxx_method_decl, metadata);
1523314564Sdim                          } else {
1524314564Sdim                            ignore_containing_context = true;
1525314564Sdim                          }
1526292932Sdim                        }
1527314564Sdim                      }
1528314564Sdim                    } else {
1529314564Sdim                      // We were asked to parse the type for a method in a
1530314564Sdim                      // class, yet the
1531314564Sdim                      // class hasn't been asked to complete itself through the
1532314564Sdim                      // clang::ExternalASTSource protocol, so we need to just
1533314564Sdim                      // have the
1534314564Sdim                      // class complete itself and do things the right way, then
1535314564Sdim                      // our
1536314564Sdim                      // DIE should then have an entry in the
1537314564Sdim                      // dwarf->GetDIEToType() map. First
1538314564Sdim                      // we need to modify the dwarf->GetDIEToType() so it
1539314564Sdim                      // doesn't think we are
1540314564Sdim                      // trying to parse this DIE anymore...
1541314564Sdim                      dwarf->GetDIEToType()[die.GetDIE()] = NULL;
1542292932Sdim
1543314564Sdim                      // Now we get the full type to force our class type to
1544314564Sdim                      // complete itself
1545314564Sdim                      // using the clang::ExternalASTSource protocol which will
1546314564Sdim                      // parse all
1547314564Sdim                      // base classes and all methods (including the method for
1548314564Sdim                      // this DIE).
1549314564Sdim                      class_type->GetFullCompilerType();
1550292932Sdim
1551314564Sdim                      // The type for this DIE should have been filled in the
1552314564Sdim                      // function call above
1553314564Sdim                      type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
1554314564Sdim                      if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
1555314564Sdim                        type_sp = type_ptr->shared_from_this();
1556314564Sdim                        break;
1557314564Sdim                      }
1558292932Sdim
1559314564Sdim                      // FIXME This is fixing some even uglier behavior but we
1560314564Sdim                      // really need to
1561314564Sdim                      // uniq the methods of each class as well as the class
1562314564Sdim                      // itself.
1563314564Sdim                      // <rdar://problem/11240464>
1564314564Sdim                      type_handled = true;
1565292932Sdim                    }
1566314564Sdim                  }
1567292932Sdim                }
1568314564Sdim              }
1569314564Sdim            }
1570314564Sdim          }
1571292932Sdim
1572314564Sdim          if (!type_handled) {
1573314564Sdim            clang::FunctionDecl *function_decl = nullptr;
1574292932Sdim
1575314564Sdim            if (abstract_origin_die_form.IsValid()) {
1576314564Sdim              DWARFDIE abs_die =
1577314564Sdim                  dwarf->DebugInfo()->GetDIE(DIERef(abstract_origin_die_form));
1578292932Sdim
1579314564Sdim              SymbolContext sc;
1580292932Sdim
1581314564Sdim              if (dwarf->ResolveType(abs_die)) {
1582314564Sdim                function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
1583314564Sdim                    GetCachedClangDeclContextForDIE(abs_die));
1584292932Sdim
1585314564Sdim                if (function_decl) {
1586314564Sdim                  LinkDeclContextToDIE(function_decl, die);
1587314564Sdim                }
1588314564Sdim              }
1589314564Sdim            }
1590292932Sdim
1591314564Sdim            if (!function_decl) {
1592314564Sdim              // We just have a function that isn't part of a class
1593314564Sdim              function_decl = m_ast.CreateFunctionDeclaration(
1594314564Sdim                  ignore_containing_context ? m_ast.GetTranslationUnitDecl()
1595314564Sdim                                            : containing_decl_ctx,
1596314564Sdim                  type_name_cstr, clang_type, storage, is_inline);
1597292932Sdim
1598321369Sdim              if (has_template_params) {
1599321369Sdim                ClangASTContext::TemplateParameterInfos template_param_infos;
1600321369Sdim                ParseTemplateParameterInfos(die, template_param_infos);
1601321369Sdim                clang::FunctionTemplateDecl *func_template_decl =
1602321369Sdim                    m_ast.CreateFunctionTemplateDecl(
1603321369Sdim                        containing_decl_ctx, function_decl, type_name_cstr,
1604321369Sdim                        template_param_infos);
1605321369Sdim                m_ast.CreateFunctionTemplateSpecializationInfo(
1606321369Sdim                    function_decl, func_template_decl, template_param_infos);
1607321369Sdim              }
1608321369Sdim
1609314564Sdim              lldbassert(function_decl);
1610309124Sdim
1611314564Sdim              if (function_decl) {
1612314564Sdim                LinkDeclContextToDIE(function_decl, die);
1613309124Sdim
1614314564Sdim                if (!function_param_decls.empty())
1615314564Sdim                  m_ast.SetFunctionParameters(function_decl,
1616314564Sdim                                              &function_param_decls.front(),
1617314564Sdim                                              function_param_decls.size());
1618314564Sdim
1619314564Sdim                ClangASTMetadata metadata;
1620314564Sdim                metadata.SetUserID(die.GetID());
1621314564Sdim
1622314564Sdim                if (!object_pointer_name.empty()) {
1623314564Sdim                  metadata.SetObjectPtrName(object_pointer_name.c_str());
1624314564Sdim                  if (log)
1625314564Sdim                    log->Printf("Setting object pointer name: %s on function "
1626314564Sdim                                "object %p.",
1627314564Sdim                                object_pointer_name.c_str(),
1628314564Sdim                                static_cast<void *>(function_decl));
1629292932Sdim                }
1630314564Sdim                m_ast.SetMetadata(function_decl, metadata);
1631314564Sdim              }
1632314564Sdim            }
1633314564Sdim          }
1634314564Sdim        }
1635314564Sdim        type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL,
1636314564Sdim                               LLDB_INVALID_UID, Type::eEncodingIsUID, &decl,
1637314564Sdim                               clang_type, Type::eResolveStateFull));
1638314564Sdim        assert(type_sp.get());
1639314564Sdim      } break;
1640292932Sdim
1641314564Sdim      case DW_TAG_array_type: {
1642314564Sdim        // Set a bit that lets us know that we are currently parsing this
1643314564Sdim        dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
1644292932Sdim
1645314564Sdim        DWARFFormValue type_die_form;
1646314564Sdim        int64_t first_index = 0;
1647314564Sdim        uint32_t byte_stride = 0;
1648314564Sdim        uint32_t bit_stride = 0;
1649314564Sdim        bool is_vector = false;
1650314564Sdim        const size_t num_attributes = die.GetAttributes(attributes);
1651292932Sdim
1652314564Sdim        if (num_attributes > 0) {
1653314564Sdim          uint32_t i;
1654314564Sdim          for (i = 0; i < num_attributes; ++i) {
1655314564Sdim            attr = attributes.AttributeAtIndex(i);
1656314564Sdim            if (attributes.ExtractFormValueAtIndex(i, form_value)) {
1657314564Sdim              switch (attr) {
1658314564Sdim              case DW_AT_decl_file:
1659314564Sdim                decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
1660314564Sdim                    form_value.Unsigned()));
1661314564Sdim                break;
1662314564Sdim              case DW_AT_decl_line:
1663314564Sdim                decl.SetLine(form_value.Unsigned());
1664314564Sdim                break;
1665314564Sdim              case DW_AT_decl_column:
1666314564Sdim                decl.SetColumn(form_value.Unsigned());
1667314564Sdim                break;
1668314564Sdim              case DW_AT_name:
1669314564Sdim                type_name_cstr = form_value.AsCString();
1670314564Sdim                type_name_const_str.SetCString(type_name_cstr);
1671314564Sdim                break;
1672292932Sdim
1673314564Sdim              case DW_AT_type:
1674314564Sdim                type_die_form = form_value;
1675314564Sdim                break;
1676314564Sdim              case DW_AT_byte_size:
1677314564Sdim                break; // byte_size = form_value.Unsigned(); break;
1678314564Sdim              case DW_AT_byte_stride:
1679314564Sdim                byte_stride = form_value.Unsigned();
1680314564Sdim                break;
1681314564Sdim              case DW_AT_bit_stride:
1682314564Sdim                bit_stride = form_value.Unsigned();
1683314564Sdim                break;
1684314564Sdim              case DW_AT_GNU_vector:
1685314564Sdim                is_vector = form_value.Boolean();
1686314564Sdim                break;
1687314564Sdim              case DW_AT_accessibility:
1688314564Sdim                break; // accessibility =
1689314564Sdim                       // DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
1690314564Sdim              case DW_AT_declaration:
1691314564Sdim                break; // is_forward_declaration = form_value.Boolean(); break;
1692314564Sdim              case DW_AT_allocated:
1693314564Sdim              case DW_AT_associated:
1694314564Sdim              case DW_AT_data_location:
1695314564Sdim              case DW_AT_description:
1696314564Sdim              case DW_AT_ordering:
1697314564Sdim              case DW_AT_start_scope:
1698314564Sdim              case DW_AT_visibility:
1699314564Sdim              case DW_AT_specification:
1700314564Sdim              case DW_AT_abstract_origin:
1701314564Sdim              case DW_AT_sibling:
1702314564Sdim                break;
1703314564Sdim              }
1704314564Sdim            }
1705314564Sdim          }
1706292932Sdim
1707314564Sdim          DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
1708314564Sdim                       DW_TAG_value_to_name(tag), type_name_cstr);
1709292932Sdim
1710314564Sdim          DIERef type_die_ref(type_die_form);
1711314564Sdim          Type *element_type = dwarf->ResolveTypeUID(type_die_ref);
1712292932Sdim
1713314564Sdim          if (element_type) {
1714314564Sdim            std::vector<uint64_t> element_orders;
1715314564Sdim            ParseChildArrayInfo(sc, die, first_index, element_orders,
1716314564Sdim                                byte_stride, bit_stride);
1717314564Sdim            if (byte_stride == 0 && bit_stride == 0)
1718314564Sdim              byte_stride = element_type->GetByteSize();
1719314564Sdim            CompilerType array_element_type =
1720314564Sdim                element_type->GetForwardCompilerType();
1721292932Sdim
1722314564Sdim            if (ClangASTContext::IsCXXClassType(array_element_type) &&
1723314564Sdim                array_element_type.GetCompleteType() == false) {
1724314564Sdim              ModuleSP module_sp = die.GetModule();
1725314564Sdim              if (module_sp) {
1726314564Sdim                if (die.GetCU()->GetProducer() ==
1727314564Sdim                    DWARFCompileUnit::eProducerClang)
1728314564Sdim                  module_sp->ReportError(
1729314564Sdim                      "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
1730314564Sdim                      "class/union/struct element type DIE 0x%8.8x that is a "
1731314564Sdim                      "forward declaration, not a complete definition.\nTry "
1732314564Sdim                      "compiling the source file with -fno-limit-debug-info or "
1733314564Sdim                      "disable -gmodule",
1734314564Sdim                      die.GetOffset(), type_die_ref.die_offset);
1735314564Sdim                else
1736314564Sdim                  module_sp->ReportError(
1737314564Sdim                      "DWARF DW_TAG_array_type DIE at 0x%8.8x has a "
1738314564Sdim                      "class/union/struct element type DIE 0x%8.8x that is a "
1739314564Sdim                      "forward declaration, not a complete definition.\nPlease "
1740314564Sdim                      "file a bug against the compiler and include the "
1741314564Sdim                      "preprocessed output for %s",
1742314564Sdim                      die.GetOffset(), type_die_ref.die_offset,
1743314564Sdim                      die.GetLLDBCompileUnit()
1744314564Sdim                          ? die.GetLLDBCompileUnit()->GetPath().c_str()
1745314564Sdim                          : "the source file");
1746314564Sdim              }
1747314564Sdim
1748314564Sdim              // We have no choice other than to pretend that the element class
1749314564Sdim              // type
1750314564Sdim              // is complete. If we don't do this, clang will crash when trying
1751314564Sdim              // to layout the class. Since we provide layout assistance, all
1752314564Sdim              // ivars in this class and other classes will be fine, this is
1753314564Sdim              // the best we can do short of crashing.
1754314564Sdim              if (ClangASTContext::StartTagDeclarationDefinition(
1755314564Sdim                      array_element_type)) {
1756314564Sdim                ClangASTContext::CompleteTagDeclarationDefinition(
1757314564Sdim                    array_element_type);
1758314564Sdim              } else {
1759314564Sdim                module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
1760314564Sdim                                       "start its definition.\nPlease file a "
1761314564Sdim                                       "bug and attach the file at the start "
1762314564Sdim                                       "of this error message",
1763314564Sdim                                       type_die_ref.die_offset);
1764314564Sdim              }
1765292932Sdim            }
1766292932Sdim
1767314564Sdim            uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
1768314564Sdim            if (element_orders.size() > 0) {
1769314564Sdim              uint64_t num_elements = 0;
1770314564Sdim              std::vector<uint64_t>::const_reverse_iterator pos;
1771314564Sdim              std::vector<uint64_t>::const_reverse_iterator end =
1772314564Sdim                  element_orders.rend();
1773314564Sdim              for (pos = element_orders.rbegin(); pos != end; ++pos) {
1774314564Sdim                num_elements = *pos;
1775314564Sdim                clang_type = m_ast.CreateArrayType(array_element_type,
1776314564Sdim                                                   num_elements, is_vector);
1777314564Sdim                array_element_type = clang_type;
1778314564Sdim                array_element_bit_stride =
1779314564Sdim                    num_elements ? array_element_bit_stride * num_elements
1780314564Sdim                                 : array_element_bit_stride;
1781314564Sdim              }
1782314564Sdim            } else {
1783314564Sdim              clang_type =
1784314564Sdim                  m_ast.CreateArrayType(array_element_type, 0, is_vector);
1785314564Sdim            }
1786314564Sdim            ConstString empty_name;
1787314564Sdim            type_sp.reset(new Type(
1788314564Sdim                die.GetID(), dwarf, empty_name, array_element_bit_stride / 8,
1789314564Sdim                NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID,
1790314564Sdim                &decl, clang_type, Type::eResolveStateFull));
1791314564Sdim            type_sp->SetEncodingType(element_type);
1792314564Sdim          }
1793314564Sdim        }
1794314564Sdim      } break;
1795292932Sdim
1796314564Sdim      case DW_TAG_ptr_to_member_type: {
1797314564Sdim        DWARFFormValue type_die_form;
1798314564Sdim        DWARFFormValue containing_type_die_form;
1799292932Sdim
1800314564Sdim        const size_t num_attributes = die.GetAttributes(attributes);
1801292932Sdim
1802314564Sdim        if (num_attributes > 0) {
1803314564Sdim          uint32_t i;
1804314564Sdim          for (i = 0; i < num_attributes; ++i) {
1805314564Sdim            attr = attributes.AttributeAtIndex(i);
1806314564Sdim            if (attributes.ExtractFormValueAtIndex(i, form_value)) {
1807314564Sdim              switch (attr) {
1808314564Sdim              case DW_AT_type:
1809314564Sdim                type_die_form = form_value;
1810314564Sdim                break;
1811314564Sdim              case DW_AT_containing_type:
1812314564Sdim                containing_type_die_form = form_value;
1813314564Sdim                break;
1814314564Sdim              }
1815314564Sdim            }
1816314564Sdim          }
1817292932Sdim
1818314564Sdim          Type *pointee_type = dwarf->ResolveTypeUID(DIERef(type_die_form));
1819314564Sdim          Type *class_type =
1820314564Sdim              dwarf->ResolveTypeUID(DIERef(containing_type_die_form));
1821314564Sdim
1822314564Sdim          CompilerType pointee_clang_type =
1823314564Sdim              pointee_type->GetForwardCompilerType();
1824314564Sdim          CompilerType class_clang_type = class_type->GetLayoutCompilerType();
1825314564Sdim
1826314564Sdim          clang_type = ClangASTContext::CreateMemberPointerType(
1827314564Sdim              class_clang_type, pointee_clang_type);
1828314564Sdim
1829314564Sdim          byte_size = clang_type.GetByteSize(nullptr);
1830314564Sdim
1831314564Sdim          type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str,
1832314564Sdim                                 byte_size, NULL, LLDB_INVALID_UID,
1833314564Sdim                                 Type::eEncodingIsUID, NULL, clang_type,
1834314564Sdim                                 Type::eResolveStateForward));
1835292932Sdim        }
1836314564Sdim
1837314564Sdim        break;
1838314564Sdim      }
1839314564Sdim      default:
1840314564Sdim        dwarf->GetObjectFile()->GetModule()->ReportError(
1841314564Sdim            "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and "
1842314564Sdim            "attach the file at the start of this error message",
1843314564Sdim            die.GetOffset(), tag, DW_TAG_value_to_name(tag));
1844314564Sdim        break;
1845314564Sdim      }
1846314564Sdim
1847314564Sdim      if (type_sp.get()) {
1848314564Sdim        DWARFDIE sc_parent_die =
1849314564Sdim            SymbolFileDWARF::GetParentSymbolContextDIE(die);
1850314564Sdim        dw_tag_t sc_parent_tag = sc_parent_die.Tag();
1851314564Sdim
1852314564Sdim        SymbolContextScope *symbol_context_scope = NULL;
1853314564Sdim        if (sc_parent_tag == DW_TAG_compile_unit) {
1854314564Sdim          symbol_context_scope = sc.comp_unit;
1855314564Sdim        } else if (sc.function != NULL && sc_parent_die) {
1856314564Sdim          symbol_context_scope =
1857314564Sdim              sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
1858314564Sdim          if (symbol_context_scope == NULL)
1859314564Sdim            symbol_context_scope = sc.function;
1860292932Sdim        }
1861314564Sdim
1862314564Sdim        if (symbol_context_scope != NULL) {
1863314564Sdim          type_sp->SetSymbolContextScope(symbol_context_scope);
1864314564Sdim        }
1865314564Sdim
1866314564Sdim        // We are ready to put this type into the uniqued list up at the module
1867314564Sdim        // level
1868314564Sdim        type_list->Insert(type_sp);
1869314564Sdim
1870314564Sdim        dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
1871314564Sdim      }
1872314564Sdim    } else if (type_ptr != DIE_IS_BEING_PARSED) {
1873314564Sdim      type_sp = type_ptr->shared_from_this();
1874292932Sdim    }
1875314564Sdim  }
1876314564Sdim  return type_sp;
1877292932Sdim}
1878292932Sdim
1879292932Sdim// DWARF parsing functions
1880292932Sdim
1881314564Sdimclass DWARFASTParserClang::DelayedAddObjCClassProperty {
1882292932Sdimpublic:
1883314564Sdim  DelayedAddObjCClassProperty(
1884314564Sdim      const CompilerType &class_opaque_type, const char *property_name,
1885314564Sdim      const CompilerType &property_opaque_type, // The property type is only
1886314564Sdim                                                // required if you don't have an
1887314564Sdim                                                // ivar decl
1888314564Sdim      clang::ObjCIvarDecl *ivar_decl, const char *property_setter_name,
1889314564Sdim      const char *property_getter_name, uint32_t property_attributes,
1890314564Sdim      const ClangASTMetadata *metadata)
1891314564Sdim      : m_class_opaque_type(class_opaque_type), m_property_name(property_name),
1892314564Sdim        m_property_opaque_type(property_opaque_type), m_ivar_decl(ivar_decl),
1893314564Sdim        m_property_setter_name(property_setter_name),
1894314564Sdim        m_property_getter_name(property_getter_name),
1895314564Sdim        m_property_attributes(property_attributes) {
1896314564Sdim    if (metadata != NULL) {
1897314564Sdim      m_metadata_ap.reset(new ClangASTMetadata());
1898314564Sdim      *m_metadata_ap = *metadata;
1899292932Sdim    }
1900314564Sdim  }
1901292932Sdim
1902314564Sdim  DelayedAddObjCClassProperty(const DelayedAddObjCClassProperty &rhs) {
1903314564Sdim    *this = rhs;
1904314564Sdim  }
1905292932Sdim
1906314564Sdim  DelayedAddObjCClassProperty &
1907314564Sdim  operator=(const DelayedAddObjCClassProperty &rhs) {
1908314564Sdim    m_class_opaque_type = rhs.m_class_opaque_type;
1909314564Sdim    m_property_name = rhs.m_property_name;
1910314564Sdim    m_property_opaque_type = rhs.m_property_opaque_type;
1911314564Sdim    m_ivar_decl = rhs.m_ivar_decl;
1912314564Sdim    m_property_setter_name = rhs.m_property_setter_name;
1913314564Sdim    m_property_getter_name = rhs.m_property_getter_name;
1914314564Sdim    m_property_attributes = rhs.m_property_attributes;
1915292932Sdim
1916314564Sdim    if (rhs.m_metadata_ap.get()) {
1917314564Sdim      m_metadata_ap.reset(new ClangASTMetadata());
1918314564Sdim      *m_metadata_ap = *rhs.m_metadata_ap;
1919292932Sdim    }
1920314564Sdim    return *this;
1921314564Sdim  }
1922292932Sdim
1923314564Sdim  bool Finalize() {
1924314564Sdim    return ClangASTContext::AddObjCClassProperty(
1925314564Sdim        m_class_opaque_type, m_property_name, m_property_opaque_type,
1926314564Sdim        m_ivar_decl, m_property_setter_name, m_property_getter_name,
1927314564Sdim        m_property_attributes, m_metadata_ap.get());
1928314564Sdim  }
1929292932Sdim
1930292932Sdimprivate:
1931314564Sdim  CompilerType m_class_opaque_type;
1932314564Sdim  const char *m_property_name;
1933314564Sdim  CompilerType m_property_opaque_type;
1934314564Sdim  clang::ObjCIvarDecl *m_ivar_decl;
1935314564Sdim  const char *m_property_setter_name;
1936314564Sdim  const char *m_property_getter_name;
1937314564Sdim  uint32_t m_property_attributes;
1938314564Sdim  std::unique_ptr<ClangASTMetadata> m_metadata_ap;
1939292932Sdim};
1940292932Sdim
1941314564Sdimbool DWARFASTParserClang::ParseTemplateDIE(
1942314564Sdim    const DWARFDIE &die,
1943314564Sdim    ClangASTContext::TemplateParameterInfos &template_param_infos) {
1944314564Sdim  const dw_tag_t tag = die.Tag();
1945292932Sdim
1946314564Sdim  switch (tag) {
1947321369Sdim  case DW_TAG_GNU_template_parameter_pack: {
1948321369Sdim    template_param_infos.packed_args.reset(
1949321369Sdim      new ClangASTContext::TemplateParameterInfos);
1950321369Sdim    for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid();
1951321369Sdim         child_die = child_die.GetSibling()) {
1952321369Sdim      if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args))
1953321369Sdim        return false;
1954321369Sdim    }
1955321369Sdim    if (const char *name = die.GetName()) {
1956321369Sdim      template_param_infos.pack_name = name;
1957321369Sdim    }
1958321369Sdim    return true;
1959321369Sdim  }
1960314564Sdim  case DW_TAG_template_type_parameter:
1961314564Sdim  case DW_TAG_template_value_parameter: {
1962314564Sdim    DWARFAttributes attributes;
1963314564Sdim    const size_t num_attributes = die.GetAttributes(attributes);
1964314564Sdim    const char *name = nullptr;
1965314564Sdim    CompilerType clang_type;
1966314564Sdim    uint64_t uval64 = 0;
1967314564Sdim    bool uval64_valid = false;
1968314564Sdim    if (num_attributes > 0) {
1969314564Sdim      DWARFFormValue form_value;
1970314564Sdim      for (size_t i = 0; i < num_attributes; ++i) {
1971314564Sdim        const dw_attr_t attr = attributes.AttributeAtIndex(i);
1972292932Sdim
1973314564Sdim        switch (attr) {
1974314564Sdim        case DW_AT_name:
1975314564Sdim          if (attributes.ExtractFormValueAtIndex(i, form_value))
1976314564Sdim            name = form_value.AsCString();
1977314564Sdim          break;
1978292932Sdim
1979314564Sdim        case DW_AT_type:
1980314564Sdim          if (attributes.ExtractFormValueAtIndex(i, form_value)) {
1981314564Sdim            Type *lldb_type = die.ResolveTypeUID(DIERef(form_value));
1982314564Sdim            if (lldb_type)
1983314564Sdim              clang_type = lldb_type->GetForwardCompilerType();
1984314564Sdim          }
1985314564Sdim          break;
1986292932Sdim
1987314564Sdim        case DW_AT_const_value:
1988314564Sdim          if (attributes.ExtractFormValueAtIndex(i, form_value)) {
1989314564Sdim            uval64_valid = true;
1990314564Sdim            uval64 = form_value.Unsigned();
1991314564Sdim          }
1992314564Sdim          break;
1993314564Sdim        default:
1994314564Sdim          break;
1995314564Sdim        }
1996314564Sdim      }
1997292932Sdim
1998314564Sdim      clang::ASTContext *ast = m_ast.getASTContext();
1999314564Sdim      if (!clang_type)
2000314564Sdim        clang_type = m_ast.GetBasicType(eBasicTypeVoid);
2001292932Sdim
2002314564Sdim      if (clang_type) {
2003314564Sdim        bool is_signed = false;
2004314564Sdim        if (name && name[0])
2005314564Sdim          template_param_infos.names.push_back(name);
2006314564Sdim        else
2007314564Sdim          template_param_infos.names.push_back(NULL);
2008292932Sdim
2009314564Sdim        // Get the signed value for any integer or enumeration if available
2010314564Sdim        clang_type.IsIntegerOrEnumerationType(is_signed);
2011309124Sdim
2012314564Sdim        if (tag == DW_TAG_template_value_parameter && uval64_valid) {
2013314564Sdim          llvm::APInt apint(clang_type.GetBitSize(nullptr), uval64, is_signed);
2014314564Sdim          template_param_infos.args.push_back(
2015314564Sdim              clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed),
2016314564Sdim                                      ClangUtil::GetQualType(clang_type)));
2017314564Sdim        } else {
2018314564Sdim          template_param_infos.args.push_back(
2019314564Sdim              clang::TemplateArgument(ClangUtil::GetQualType(clang_type)));
2020292932Sdim        }
2021314564Sdim      } else {
2022314564Sdim        return false;
2023314564Sdim      }
2024314564Sdim    }
2025314564Sdim  }
2026314564Sdim    return true;
2027292932Sdim
2028314564Sdim  default:
2029314564Sdim    break;
2030314564Sdim  }
2031314564Sdim  return false;
2032292932Sdim}
2033292932Sdim
2034314564Sdimbool DWARFASTParserClang::ParseTemplateParameterInfos(
2035314564Sdim    const DWARFDIE &parent_die,
2036314564Sdim    ClangASTContext::TemplateParameterInfos &template_param_infos) {
2037292932Sdim
2038314564Sdim  if (!parent_die)
2039314564Sdim    return false;
2040292932Sdim
2041314564Sdim  Args template_parameter_names;
2042314564Sdim  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
2043314564Sdim       die = die.GetSibling()) {
2044314564Sdim    const dw_tag_t tag = die.Tag();
2045292932Sdim
2046314564Sdim    switch (tag) {
2047314564Sdim    case DW_TAG_template_type_parameter:
2048314564Sdim    case DW_TAG_template_value_parameter:
2049321369Sdim    case DW_TAG_GNU_template_parameter_pack:
2050314564Sdim      ParseTemplateDIE(die, template_param_infos);
2051314564Sdim      break;
2052292932Sdim
2053314564Sdim    default:
2054314564Sdim      break;
2055292932Sdim    }
2056314564Sdim  }
2057314564Sdim  if (template_param_infos.args.empty())
2058314564Sdim    return false;
2059314564Sdim  return template_param_infos.args.size() == template_param_infos.names.size();
2060292932Sdim}
2061292932Sdim
2062314564Sdimbool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
2063314564Sdim                                                lldb_private::Type *type,
2064314564Sdim                                                CompilerType &clang_type) {
2065314564Sdim  SymbolFileDWARF *dwarf = die.GetDWARF();
2066292932Sdim
2067314564Sdim  std::lock_guard<std::recursive_mutex> guard(
2068314564Sdim      dwarf->GetObjectFile()->GetModule()->GetMutex());
2069292932Sdim
2070314564Sdim  // Disable external storage for this type so we don't get anymore
2071314564Sdim  // clang::ExternalASTSource queries for this type.
2072314564Sdim  m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), false);
2073292932Sdim
2074314564Sdim  if (!die)
2075314564Sdim    return false;
2076292932Sdim
2077309124Sdim#if defined LLDB_CONFIGURATION_DEBUG
2078314564Sdim  //----------------------------------------------------------------------
2079314564Sdim  // For debugging purposes, the LLDB_DWARF_DONT_COMPLETE_TYPENAMES
2080314564Sdim  // environment variable can be set with one or more typenames separated
2081314564Sdim  // by ';' characters. This will cause this function to not complete any
2082314564Sdim  // types whose names match.
2083314564Sdim  //
2084314564Sdim  // Examples of setting this environment variable:
2085314564Sdim  //
2086314564Sdim  // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo
2087314564Sdim  // LLDB_DWARF_DONT_COMPLETE_TYPENAMES=Foo;Bar;Baz
2088314564Sdim  //----------------------------------------------------------------------
2089314564Sdim  const char *dont_complete_typenames_cstr =
2090314564Sdim      getenv("LLDB_DWARF_DONT_COMPLETE_TYPENAMES");
2091314564Sdim  if (dont_complete_typenames_cstr && dont_complete_typenames_cstr[0]) {
2092314564Sdim    const char *die_name = die.GetName();
2093314564Sdim    if (die_name && die_name[0]) {
2094314564Sdim      const char *match = strstr(dont_complete_typenames_cstr, die_name);
2095314564Sdim      if (match) {
2096314564Sdim        size_t die_name_length = strlen(die_name);
2097314564Sdim        while (match) {
2098314564Sdim          const char separator_char = ';';
2099314564Sdim          const char next_char = match[die_name_length];
2100314564Sdim          if (next_char == '\0' || next_char == separator_char) {
2101314564Sdim            if (match == dont_complete_typenames_cstr ||
2102314564Sdim                match[-1] == separator_char)
2103314564Sdim              return false;
2104314564Sdim          }
2105314564Sdim          match = strstr(match + 1, die_name);
2106309124Sdim        }
2107314564Sdim      }
2108309124Sdim    }
2109314564Sdim  }
2110309124Sdim#endif
2111309124Sdim
2112314564Sdim  const dw_tag_t tag = die.Tag();
2113292932Sdim
2114314564Sdim  Log *log =
2115314564Sdim      nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
2116314564Sdim  if (log)
2117314564Sdim    dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
2118314564Sdim        log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
2119314564Sdim        die.GetID(), die.GetTagAsCString(), type->GetName().AsCString());
2120314564Sdim  assert(clang_type);
2121314564Sdim  DWARFAttributes attributes;
2122314564Sdim  switch (tag) {
2123314564Sdim  case DW_TAG_structure_type:
2124314564Sdim  case DW_TAG_union_type:
2125314564Sdim  case DW_TAG_class_type: {
2126314564Sdim    ClangASTImporter::LayoutInfo layout_info;
2127314564Sdim
2128292932Sdim    {
2129314564Sdim      if (die.HasChildren()) {
2130314564Sdim        LanguageType class_language = eLanguageTypeUnknown;
2131314564Sdim        if (ClangASTContext::IsObjCObjectOrInterfaceType(clang_type)) {
2132314564Sdim          class_language = eLanguageTypeObjC;
2133314564Sdim          // For objective C we don't start the definition when
2134314564Sdim          // the class is created.
2135314564Sdim          ClangASTContext::StartTagDeclarationDefinition(clang_type);
2136314564Sdim        }
2137292932Sdim
2138314564Sdim        int tag_decl_kind = -1;
2139314564Sdim        AccessType default_accessibility = eAccessNone;
2140314564Sdim        if (tag == DW_TAG_structure_type) {
2141314564Sdim          tag_decl_kind = clang::TTK_Struct;
2142314564Sdim          default_accessibility = eAccessPublic;
2143314564Sdim        } else if (tag == DW_TAG_union_type) {
2144314564Sdim          tag_decl_kind = clang::TTK_Union;
2145314564Sdim          default_accessibility = eAccessPublic;
2146314564Sdim        } else if (tag == DW_TAG_class_type) {
2147314564Sdim          tag_decl_kind = clang::TTK_Class;
2148314564Sdim          default_accessibility = eAccessPrivate;
2149314564Sdim        }
2150292932Sdim
2151314564Sdim        SymbolContext sc(die.GetLLDBCompileUnit());
2152314564Sdim        std::vector<clang::CXXBaseSpecifier *> base_classes;
2153314564Sdim        std::vector<int> member_accessibilities;
2154314564Sdim        bool is_a_class = false;
2155314564Sdim        // Parse members and base classes first
2156314564Sdim        DWARFDIECollection member_function_dies;
2157292932Sdim
2158314564Sdim        DelayedPropertyList delayed_properties;
2159314564Sdim        ParseChildMembers(sc, die, clang_type, class_language, base_classes,
2160314564Sdim                          member_accessibilities, member_function_dies,
2161314564Sdim                          delayed_properties, default_accessibility, is_a_class,
2162314564Sdim                          layout_info);
2163292932Sdim
2164314564Sdim        // Now parse any methods if there were any...
2165314564Sdim        size_t num_functions = member_function_dies.Size();
2166314564Sdim        if (num_functions > 0) {
2167314564Sdim          for (size_t i = 0; i < num_functions; ++i) {
2168314564Sdim            dwarf->ResolveType(member_function_dies.GetDIEAtIndex(i));
2169314564Sdim          }
2170314564Sdim        }
2171292932Sdim
2172314564Sdim        if (class_language == eLanguageTypeObjC) {
2173314564Sdim          ConstString class_name(clang_type.GetTypeName());
2174314564Sdim          if (class_name) {
2175314564Sdim            DIEArray method_die_offsets;
2176314564Sdim            dwarf->GetObjCMethodDIEOffsets(class_name, method_die_offsets);
2177292932Sdim
2178314564Sdim            if (!method_die_offsets.empty()) {
2179314564Sdim              DWARFDebugInfo *debug_info = dwarf->DebugInfo();
2180292932Sdim
2181314564Sdim              const size_t num_matches = method_die_offsets.size();
2182314564Sdim              for (size_t i = 0; i < num_matches; ++i) {
2183314564Sdim                const DIERef &die_ref = method_die_offsets[i];
2184314564Sdim                DWARFDIE method_die = debug_info->GetDIE(die_ref);
2185292932Sdim
2186314564Sdim                if (method_die)
2187314564Sdim                  method_die.ResolveType();
2188314564Sdim              }
2189314564Sdim            }
2190292932Sdim
2191314564Sdim            for (DelayedPropertyList::iterator pi = delayed_properties.begin(),
2192314564Sdim                                               pe = delayed_properties.end();
2193314564Sdim                 pi != pe; ++pi)
2194314564Sdim              pi->Finalize();
2195314564Sdim          }
2196314564Sdim        }
2197292932Sdim
2198314564Sdim        // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
2199314564Sdim        // need to tell the clang type it is actually a class.
2200314564Sdim        if (class_language != eLanguageTypeObjC) {
2201314564Sdim          if (is_a_class && tag_decl_kind != clang::TTK_Class)
2202314564Sdim            m_ast.SetTagTypeKind(ClangUtil::GetQualType(clang_type),
2203314564Sdim                                 clang::TTK_Class);
2204314564Sdim        }
2205292932Sdim
2206314564Sdim        // Since DW_TAG_structure_type gets used for both classes
2207314564Sdim        // and structures, we may need to set any DW_TAG_member
2208314564Sdim        // fields to have a "private" access if none was specified.
2209314564Sdim        // When we parsed the child members we tracked that actual
2210314564Sdim        // accessibility value for each DW_TAG_member in the
2211314564Sdim        // "member_accessibilities" array. If the value for the
2212314564Sdim        // member is zero, then it was set to the "default_accessibility"
2213314564Sdim        // which for structs was "public". Below we correct this
2214314564Sdim        // by setting any fields to "private" that weren't correctly
2215314564Sdim        // set.
2216314564Sdim        if (is_a_class && !member_accessibilities.empty()) {
2217314564Sdim          // This is a class and all members that didn't have
2218314564Sdim          // their access specified are private.
2219314564Sdim          m_ast.SetDefaultAccessForRecordFields(
2220314564Sdim              m_ast.GetAsRecordDecl(clang_type), eAccessPrivate,
2221314564Sdim              &member_accessibilities.front(), member_accessibilities.size());
2222314564Sdim        }
2223292932Sdim
2224314564Sdim        if (!base_classes.empty()) {
2225314564Sdim          // Make sure all base classes refer to complete types and not
2226314564Sdim          // forward declarations. If we don't do this, clang will crash
2227314564Sdim          // with an assertion in the call to
2228314564Sdim          // clang_type.SetBaseClassesForClassType()
2229314564Sdim          for (auto &base_class : base_classes) {
2230314564Sdim            clang::TypeSourceInfo *type_source_info =
2231314564Sdim                base_class->getTypeSourceInfo();
2232314564Sdim            if (type_source_info) {
2233314564Sdim              CompilerType base_class_type(
2234314564Sdim                  &m_ast, type_source_info->getType().getAsOpaquePtr());
2235314564Sdim              if (base_class_type.GetCompleteType() == false) {
2236314564Sdim                auto module = dwarf->GetObjectFile()->GetModule();
2237314564Sdim                module->ReportError(":: Class '%s' has a base class '%s' which "
2238314564Sdim                                    "does not have a complete definition.",
2239314564Sdim                                    die.GetName(),
2240314564Sdim                                    base_class_type.GetTypeName().GetCString());
2241314564Sdim                if (die.GetCU()->GetProducer() ==
2242314564Sdim                    DWARFCompileUnit::eProducerClang)
2243314564Sdim                  module->ReportError(":: Try compiling the source file with "
2244314564Sdim                                      "-fno-limit-debug-info.");
2245292932Sdim
2246314564Sdim                // We have no choice other than to pretend that the base class
2247314564Sdim                // is complete. If we don't do this, clang will crash when we
2248314564Sdim                // call setBases() inside of
2249314564Sdim                // "clang_type.SetBaseClassesForClassType()"
2250314564Sdim                // below. Since we provide layout assistance, all ivars in this
2251314564Sdim                // class and other classes will be fine, this is the best we can
2252314564Sdim                // do
2253314564Sdim                // short of crashing.
2254314564Sdim                if (ClangASTContext::StartTagDeclarationDefinition(
2255314564Sdim                        base_class_type)) {
2256314564Sdim                  ClangASTContext::CompleteTagDeclarationDefinition(
2257314564Sdim                      base_class_type);
2258292932Sdim                }
2259314564Sdim              }
2260292932Sdim            }
2261314564Sdim          }
2262314564Sdim          m_ast.SetBaseClassesForClassType(clang_type.GetOpaqueQualType(),
2263314564Sdim                                           &base_classes.front(),
2264314564Sdim                                           base_classes.size());
2265292932Sdim
2266314564Sdim          // Clang will copy each CXXBaseSpecifier in "base_classes"
2267314564Sdim          // so we have to free them all.
2268314564Sdim          ClangASTContext::DeleteBaseClassSpecifiers(&base_classes.front(),
2269314564Sdim                                                     base_classes.size());
2270314564Sdim        }
2271314564Sdim      }
2272314564Sdim    }
2273292932Sdim
2274314564Sdim    ClangASTContext::BuildIndirectFields(clang_type);
2275314564Sdim    ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
2276292932Sdim
2277314564Sdim    if (!layout_info.field_offsets.empty() ||
2278314564Sdim        !layout_info.base_offsets.empty() ||
2279314564Sdim        !layout_info.vbase_offsets.empty()) {
2280314564Sdim      if (type)
2281314564Sdim        layout_info.bit_size = type->GetByteSize() * 8;
2282314564Sdim      if (layout_info.bit_size == 0)
2283314564Sdim        layout_info.bit_size =
2284314564Sdim            die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
2285292932Sdim
2286314564Sdim      clang::CXXRecordDecl *record_decl =
2287314564Sdim          m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType());
2288314564Sdim      if (record_decl) {
2289314564Sdim        if (log) {
2290314564Sdim          ModuleSP module_sp = dwarf->GetObjectFile()->GetModule();
2291292932Sdim
2292314564Sdim          if (module_sp) {
2293314564Sdim            module_sp->LogMessage(
2294314564Sdim                log,
2295314564Sdim                "ClangASTContext::CompleteTypeFromDWARF (clang_type = %p) "
2296314564Sdim                "caching layout info for record_decl = %p, bit_size = %" PRIu64
2297314564Sdim                ", alignment = %" PRIu64
2298314564Sdim                ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
2299314564Sdim                static_cast<void *>(clang_type.GetOpaqueQualType()),
2300314564Sdim                static_cast<void *>(record_decl), layout_info.bit_size,
2301314564Sdim                layout_info.alignment,
2302314564Sdim                static_cast<uint32_t>(layout_info.field_offsets.size()),
2303314564Sdim                static_cast<uint32_t>(layout_info.base_offsets.size()),
2304314564Sdim                static_cast<uint32_t>(layout_info.vbase_offsets.size()));
2305292932Sdim
2306314564Sdim            uint32_t idx;
2307314564Sdim            {
2308314564Sdim              llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator
2309314564Sdim                  pos,
2310314564Sdim                  end = layout_info.field_offsets.end();
2311314564Sdim              for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end;
2312314564Sdim                   ++pos, ++idx) {
2313314564Sdim                module_sp->LogMessage(
2314314564Sdim                    log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = "
2315314564Sdim                         "%p) field[%u] = { bit_offset=%u, name='%s' }",
2316314564Sdim                    static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
2317314564Sdim                    static_cast<uint32_t>(pos->second),
2318314564Sdim                    pos->first->getNameAsString().c_str());
2319314564Sdim              }
2320314564Sdim            }
2321292932Sdim
2322314564Sdim            {
2323314564Sdim              llvm::DenseMap<const clang::CXXRecordDecl *,
2324314564Sdim                             clang::CharUnits>::const_iterator base_pos,
2325314564Sdim                  base_end = layout_info.base_offsets.end();
2326314564Sdim              for (idx = 0, base_pos = layout_info.base_offsets.begin();
2327314564Sdim                   base_pos != base_end; ++base_pos, ++idx) {
2328314564Sdim                module_sp->LogMessage(
2329314564Sdim                    log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = "
2330314564Sdim                         "%p) base[%u] = { byte_offset=%u, name='%s' }",
2331314564Sdim                    clang_type.GetOpaqueQualType(), idx,
2332314564Sdim                    (uint32_t)base_pos->second.getQuantity(),
2333314564Sdim                    base_pos->first->getNameAsString().c_str());
2334314564Sdim              }
2335292932Sdim            }
2336314564Sdim            {
2337314564Sdim              llvm::DenseMap<const clang::CXXRecordDecl *,
2338314564Sdim                             clang::CharUnits>::const_iterator vbase_pos,
2339314564Sdim                  vbase_end = layout_info.vbase_offsets.end();
2340314564Sdim              for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin();
2341314564Sdim                   vbase_pos != vbase_end; ++vbase_pos, ++idx) {
2342314564Sdim                module_sp->LogMessage(
2343314564Sdim                    log, "ClangASTContext::CompleteTypeFromDWARF (clang_type = "
2344314564Sdim                         "%p) vbase[%u] = { byte_offset=%u, name='%s' }",
2345314564Sdim                    static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
2346314564Sdim                    static_cast<uint32_t>(vbase_pos->second.getQuantity()),
2347314564Sdim                    vbase_pos->first->getNameAsString().c_str());
2348314564Sdim              }
2349314564Sdim            }
2350314564Sdim          }
2351292932Sdim        }
2352314564Sdim        GetClangASTImporter().InsertRecordDecl(record_decl, layout_info);
2353314564Sdim      }
2354314564Sdim    }
2355314564Sdim  }
2356292932Sdim
2357314564Sdim    return (bool)clang_type;
2358292932Sdim
2359314564Sdim  case DW_TAG_enumeration_type:
2360314564Sdim    if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
2361314564Sdim      if (die.HasChildren()) {
2362314564Sdim        SymbolContext sc(die.GetLLDBCompileUnit());
2363314564Sdim        bool is_signed = false;
2364314564Sdim        clang_type.IsIntegerType(is_signed);
2365314564Sdim        ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(),
2366314564Sdim                              die);
2367314564Sdim      }
2368314564Sdim      ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
2369292932Sdim    }
2370314564Sdim    return (bool)clang_type;
2371292932Sdim
2372314564Sdim  default:
2373314564Sdim    assert(false && "not a forward clang type decl!");
2374314564Sdim    break;
2375314564Sdim  }
2376314564Sdim
2377314564Sdim  return false;
2378292932Sdim}
2379292932Sdim
2380314564Sdimstd::vector<DWARFDIE> DWARFASTParserClang::GetDIEForDeclContext(
2381314564Sdim    lldb_private::CompilerDeclContext decl_context) {
2382314564Sdim  std::vector<DWARFDIE> result;
2383314564Sdim  for (auto it = m_decl_ctx_to_die.find(
2384314564Sdim           (clang::DeclContext *)decl_context.GetOpaqueDeclContext());
2385314564Sdim       it != m_decl_ctx_to_die.end(); it++)
2386314564Sdim    result.push_back(it->second);
2387314564Sdim  return result;
2388292932Sdim}
2389292932Sdim
2390314564SdimCompilerDecl DWARFASTParserClang::GetDeclForUIDFromDWARF(const DWARFDIE &die) {
2391314564Sdim  clang::Decl *clang_decl = GetClangDeclForDIE(die);
2392314564Sdim  if (clang_decl != nullptr)
2393314564Sdim    return CompilerDecl(&m_ast, clang_decl);
2394314564Sdim  return CompilerDecl();
2395292932Sdim}
2396292932Sdim
2397292932SdimCompilerDeclContext
2398314564SdimDWARFASTParserClang::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
2399314564Sdim  clang::DeclContext *clang_decl_ctx = GetClangDeclContextForDIE(die);
2400314564Sdim  if (clang_decl_ctx)
2401314564Sdim    return CompilerDeclContext(&m_ast, clang_decl_ctx);
2402314564Sdim  return CompilerDeclContext();
2403292932Sdim}
2404292932Sdim
2405292932SdimCompilerDeclContext
2406314564SdimDWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
2407314564Sdim  clang::DeclContext *clang_decl_ctx =
2408314564Sdim      GetClangDeclContextContainingDIE(die, nullptr);
2409314564Sdim  if (clang_decl_ctx)
2410314564Sdim    return CompilerDeclContext(&m_ast, clang_decl_ctx);
2411314564Sdim  return CompilerDeclContext();
2412292932Sdim}
2413292932Sdim
2414314564Sdimsize_t DWARFASTParserClang::ParseChildEnumerators(
2415314564Sdim    const SymbolContext &sc, lldb_private::CompilerType &clang_type,
2416314564Sdim    bool is_signed, uint32_t enumerator_byte_size, const DWARFDIE &parent_die) {
2417314564Sdim  if (!parent_die)
2418314564Sdim    return 0;
2419292932Sdim
2420314564Sdim  size_t enumerators_added = 0;
2421292932Sdim
2422314564Sdim  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
2423314564Sdim       die = die.GetSibling()) {
2424314564Sdim    const dw_tag_t tag = die.Tag();
2425314564Sdim    if (tag == DW_TAG_enumerator) {
2426314564Sdim      DWARFAttributes attributes;
2427314564Sdim      const size_t num_child_attributes = die.GetAttributes(attributes);
2428314564Sdim      if (num_child_attributes > 0) {
2429314564Sdim        const char *name = NULL;
2430314564Sdim        bool got_value = false;
2431314564Sdim        int64_t enum_value = 0;
2432314564Sdim        Declaration decl;
2433292932Sdim
2434314564Sdim        uint32_t i;
2435314564Sdim        for (i = 0; i < num_child_attributes; ++i) {
2436314564Sdim          const dw_attr_t attr = attributes.AttributeAtIndex(i);
2437314564Sdim          DWARFFormValue form_value;
2438314564Sdim          if (attributes.ExtractFormValueAtIndex(i, form_value)) {
2439314564Sdim            switch (attr) {
2440314564Sdim            case DW_AT_const_value:
2441314564Sdim              got_value = true;
2442314564Sdim              if (is_signed)
2443314564Sdim                enum_value = form_value.Signed();
2444314564Sdim              else
2445314564Sdim                enum_value = form_value.Unsigned();
2446314564Sdim              break;
2447292932Sdim
2448314564Sdim            case DW_AT_name:
2449314564Sdim              name = form_value.AsCString();
2450314564Sdim              break;
2451292932Sdim
2452314564Sdim            case DW_AT_description:
2453314564Sdim            default:
2454314564Sdim            case DW_AT_decl_file:
2455314564Sdim              decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
2456314564Sdim                  form_value.Unsigned()));
2457314564Sdim              break;
2458314564Sdim            case DW_AT_decl_line:
2459314564Sdim              decl.SetLine(form_value.Unsigned());
2460314564Sdim              break;
2461314564Sdim            case DW_AT_decl_column:
2462314564Sdim              decl.SetColumn(form_value.Unsigned());
2463314564Sdim              break;
2464314564Sdim            case DW_AT_sibling:
2465314564Sdim              break;
2466292932Sdim            }
2467314564Sdim          }
2468292932Sdim        }
2469314564Sdim
2470314564Sdim        if (name && name[0] && got_value) {
2471314564Sdim          m_ast.AddEnumerationValueToEnumerationType(
2472314564Sdim              clang_type.GetOpaqueQualType(),
2473314564Sdim              m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()),
2474314564Sdim              decl, name, enum_value, enumerator_byte_size * 8);
2475314564Sdim          ++enumerators_added;
2476314564Sdim        }
2477314564Sdim      }
2478292932Sdim    }
2479314564Sdim  }
2480314564Sdim  return enumerators_added;
2481292932Sdim}
2482292932Sdim
2483292932Sdim#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
2484292932Sdim
2485314564Sdimclass DIEStack {
2486292932Sdimpublic:
2487314564Sdim  void Push(const DWARFDIE &die) { m_dies.push_back(die); }
2488292932Sdim
2489314564Sdim  void LogDIEs(Log *log) {
2490314564Sdim    StreamString log_strm;
2491314564Sdim    const size_t n = m_dies.size();
2492314564Sdim    log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
2493314564Sdim    for (size_t i = 0; i < n; i++) {
2494314564Sdim      std::string qualified_name;
2495314564Sdim      const DWARFDIE &die = m_dies[i];
2496314564Sdim      die.GetQualifiedName(qualified_name);
2497314564Sdim      log_strm.Printf("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n", (uint64_t)i,
2498314564Sdim                      die.GetOffset(), die.GetTagAsCString(),
2499314564Sdim                      qualified_name.c_str());
2500292932Sdim    }
2501314564Sdim    log->PutCString(log_strm.GetData());
2502314564Sdim  }
2503314564Sdim  void Pop() { m_dies.pop_back(); }
2504292932Sdim
2505314564Sdim  class ScopedPopper {
2506314564Sdim  public:
2507314564Sdim    ScopedPopper(DIEStack &die_stack)
2508314564Sdim        : m_die_stack(die_stack), m_valid(false) {}
2509292932Sdim
2510314564Sdim    void Push(const DWARFDIE &die) {
2511314564Sdim      m_valid = true;
2512314564Sdim      m_die_stack.Push(die);
2513292932Sdim    }
2514314564Sdim
2515314564Sdim    ~ScopedPopper() {
2516314564Sdim      if (m_valid)
2517314564Sdim        m_die_stack.Pop();
2518292932Sdim    }
2519292932Sdim
2520314564Sdim  protected:
2521314564Sdim    DIEStack &m_die_stack;
2522314564Sdim    bool m_valid;
2523314564Sdim  };
2524292932Sdim
2525292932Sdimprotected:
2526314564Sdim  typedef std::vector<DWARFDIE> Stack;
2527314564Sdim  Stack m_dies;
2528292932Sdim};
2529292932Sdim#endif
2530292932Sdim
2531314564SdimFunction *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc,
2532314564Sdim                                                      const DWARFDIE &die) {
2533314564Sdim  DWARFRangeList func_ranges;
2534314564Sdim  const char *name = NULL;
2535314564Sdim  const char *mangled = NULL;
2536314564Sdim  int decl_file = 0;
2537314564Sdim  int decl_line = 0;
2538314564Sdim  int decl_column = 0;
2539314564Sdim  int call_file = 0;
2540314564Sdim  int call_line = 0;
2541314564Sdim  int call_column = 0;
2542314564Sdim  DWARFExpression frame_base(die.GetCU());
2543292932Sdim
2544314564Sdim  const dw_tag_t tag = die.Tag();
2545292932Sdim
2546314564Sdim  if (tag != DW_TAG_subprogram)
2547314564Sdim    return NULL;
2548292932Sdim
2549314564Sdim  if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
2550314564Sdim                               decl_column, call_file, call_line, call_column,
2551314564Sdim                               &frame_base)) {
2552292932Sdim
2553314564Sdim    // Union of all ranges in the function DIE (if the function is
2554314564Sdim    // discontiguous)
2555314564Sdim    AddressRange func_range;
2556314564Sdim    lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
2557314564Sdim    lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
2558314564Sdim    if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
2559314564Sdim        lowest_func_addr <= highest_func_addr) {
2560314564Sdim      ModuleSP module_sp(die.GetModule());
2561314564Sdim      func_range.GetBaseAddress().ResolveAddressUsingFileSections(
2562314564Sdim          lowest_func_addr, module_sp->GetSectionList());
2563314564Sdim      if (func_range.GetBaseAddress().IsValid())
2564314564Sdim        func_range.SetByteSize(highest_func_addr - lowest_func_addr);
2565314564Sdim    }
2566292932Sdim
2567314564Sdim    if (func_range.GetBaseAddress().IsValid()) {
2568314564Sdim      Mangled func_name;
2569314564Sdim      if (mangled)
2570314564Sdim        func_name.SetValue(ConstString(mangled), true);
2571314564Sdim      else if (die.GetParent().Tag() == DW_TAG_compile_unit &&
2572314564Sdim               Language::LanguageIsCPlusPlus(die.GetLanguage()) && name &&
2573314564Sdim               strcmp(name, "main") != 0) {
2574314564Sdim        // If the mangled name is not present in the DWARF, generate the
2575314564Sdim        // demangled name
2576314564Sdim        // using the decl context. We skip if the function is "main" as its name
2577314564Sdim        // is
2578314564Sdim        // never mangled.
2579314564Sdim        bool is_static = false;
2580314564Sdim        bool is_variadic = false;
2581314564Sdim        bool has_template_params = false;
2582314564Sdim        unsigned type_quals = 0;
2583314564Sdim        std::vector<CompilerType> param_types;
2584314564Sdim        std::vector<clang::ParmVarDecl *> param_decls;
2585314564Sdim        DWARFDeclContext decl_ctx;
2586314564Sdim        StreamString sstr;
2587292932Sdim
2588314564Sdim        die.GetDWARFDeclContext(decl_ctx);
2589314564Sdim        sstr << decl_ctx.GetQualifiedName();
2590292932Sdim
2591314564Sdim        clang::DeclContext *containing_decl_ctx =
2592314564Sdim            GetClangDeclContextContainingDIE(die, nullptr);
2593314564Sdim        ParseChildParameters(sc, containing_decl_ctx, die, true, is_static,
2594314564Sdim                             is_variadic, has_template_params, param_types,
2595314564Sdim                             param_decls, type_quals);
2596314564Sdim        sstr << "(";
2597314564Sdim        for (size_t i = 0; i < param_types.size(); i++) {
2598314564Sdim          if (i > 0)
2599314564Sdim            sstr << ", ";
2600314564Sdim          sstr << param_types[i].GetTypeName();
2601314564Sdim        }
2602314564Sdim        if (is_variadic)
2603314564Sdim          sstr << ", ...";
2604314564Sdim        sstr << ")";
2605314564Sdim        if (type_quals & clang::Qualifiers::Const)
2606314564Sdim          sstr << " const";
2607292932Sdim
2608314564Sdim        func_name.SetValue(ConstString(sstr.GetString()), false);
2609314564Sdim      } else
2610314564Sdim        func_name.SetValue(ConstString(name), false);
2611292932Sdim
2612314564Sdim      FunctionSP func_sp;
2613314564Sdim      std::unique_ptr<Declaration> decl_ap;
2614314564Sdim      if (decl_file != 0 || decl_line != 0 || decl_column != 0)
2615314564Sdim        decl_ap.reset(new Declaration(
2616314564Sdim            sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file),
2617314564Sdim            decl_line, decl_column));
2618292932Sdim
2619314564Sdim      SymbolFileDWARF *dwarf = die.GetDWARF();
2620314564Sdim      // Supply the type _only_ if it has already been parsed
2621314564Sdim      Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE());
2622292932Sdim
2623314564Sdim      assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
2624292932Sdim
2625314564Sdim      if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
2626314564Sdim        const user_id_t func_user_id = die.GetID();
2627314564Sdim        func_sp.reset(new Function(sc.comp_unit,
2628314564Sdim                                   func_user_id, // UserID is the DIE offset
2629314564Sdim                                   func_user_id, func_name, func_type,
2630314564Sdim                                   func_range)); // first address range
2631292932Sdim
2632314564Sdim        if (func_sp.get() != NULL) {
2633314564Sdim          if (frame_base.IsValid())
2634314564Sdim            func_sp->GetFrameBaseExpression() = frame_base;
2635314564Sdim          sc.comp_unit->AddFunction(func_sp);
2636314564Sdim          return func_sp.get();
2637292932Sdim        }
2638314564Sdim      }
2639292932Sdim    }
2640314564Sdim  }
2641314564Sdim  return NULL;
2642292932Sdim}
2643292932Sdim
2644314564Sdimbool DWARFASTParserClang::ParseChildMembers(
2645314564Sdim    const SymbolContext &sc, const DWARFDIE &parent_die,
2646314564Sdim    CompilerType &class_clang_type, const LanguageType class_language,
2647314564Sdim    std::vector<clang::CXXBaseSpecifier *> &base_classes,
2648314564Sdim    std::vector<int> &member_accessibilities,
2649314564Sdim    DWARFDIECollection &member_function_dies,
2650314564Sdim    DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
2651314564Sdim    bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) {
2652314564Sdim  if (!parent_die)
2653314564Sdim    return 0;
2654292932Sdim
2655314564Sdim  // Get the parent byte size so we can verify any members will fit
2656314564Sdim  const uint64_t parent_byte_size =
2657314564Sdim      parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);
2658314564Sdim  const uint64_t parent_bit_size =
2659314564Sdim      parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
2660309124Sdim
2661314564Sdim  uint32_t member_idx = 0;
2662314564Sdim  BitfieldInfo last_field_info;
2663292932Sdim
2664314564Sdim  ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
2665314564Sdim  ClangASTContext *ast =
2666314564Sdim      llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem());
2667314564Sdim  if (ast == nullptr)
2668314564Sdim    return 0;
2669292932Sdim
2670314564Sdim  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
2671314564Sdim       die = die.GetSibling()) {
2672314564Sdim    dw_tag_t tag = die.Tag();
2673292932Sdim
2674314564Sdim    switch (tag) {
2675314564Sdim    case DW_TAG_member:
2676314564Sdim    case DW_TAG_APPLE_property: {
2677314564Sdim      DWARFAttributes attributes;
2678314564Sdim      const size_t num_attributes = die.GetAttributes(attributes);
2679314564Sdim      if (num_attributes > 0) {
2680314564Sdim        Declaration decl;
2681314564Sdim        // DWARFExpression location;
2682314564Sdim        const char *name = NULL;
2683314564Sdim        const char *prop_name = NULL;
2684314564Sdim        const char *prop_getter_name = NULL;
2685314564Sdim        const char *prop_setter_name = NULL;
2686314564Sdim        uint32_t prop_attributes = 0;
2687292932Sdim
2688314564Sdim        bool is_artificial = false;
2689314564Sdim        DWARFFormValue encoding_form;
2690314564Sdim        AccessType accessibility = eAccessNone;
2691314564Sdim        uint32_t member_byte_offset =
2692314564Sdim            (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX;
2693314564Sdim        size_t byte_size = 0;
2694314564Sdim        int64_t bit_offset = 0;
2695314564Sdim        uint64_t data_bit_offset = UINT64_MAX;
2696314564Sdim        size_t bit_size = 0;
2697314564Sdim        bool is_external =
2698314564Sdim            false; // On DW_TAG_members, this means the member is static
2699314564Sdim        uint32_t i;
2700314564Sdim        for (i = 0; i < num_attributes && !is_artificial; ++i) {
2701314564Sdim          const dw_attr_t attr = attributes.AttributeAtIndex(i);
2702314564Sdim          DWARFFormValue form_value;
2703314564Sdim          if (attributes.ExtractFormValueAtIndex(i, form_value)) {
2704314564Sdim            switch (attr) {
2705314564Sdim            case DW_AT_decl_file:
2706314564Sdim              decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
2707314564Sdim                  form_value.Unsigned()));
2708314564Sdim              break;
2709314564Sdim            case DW_AT_decl_line:
2710314564Sdim              decl.SetLine(form_value.Unsigned());
2711314564Sdim              break;
2712314564Sdim            case DW_AT_decl_column:
2713314564Sdim              decl.SetColumn(form_value.Unsigned());
2714314564Sdim              break;
2715314564Sdim            case DW_AT_name:
2716314564Sdim              name = form_value.AsCString();
2717314564Sdim              break;
2718314564Sdim            case DW_AT_type:
2719314564Sdim              encoding_form = form_value;
2720314564Sdim              break;
2721314564Sdim            case DW_AT_bit_offset:
2722314564Sdim              bit_offset = form_value.Signed();
2723314564Sdim              break;
2724314564Sdim            case DW_AT_bit_size:
2725314564Sdim              bit_size = form_value.Unsigned();
2726314564Sdim              break;
2727314564Sdim            case DW_AT_byte_size:
2728314564Sdim              byte_size = form_value.Unsigned();
2729314564Sdim              break;
2730314564Sdim            case DW_AT_data_bit_offset:
2731314564Sdim              data_bit_offset = form_value.Unsigned();
2732314564Sdim              break;
2733314564Sdim            case DW_AT_data_member_location:
2734314564Sdim              if (form_value.BlockData()) {
2735314564Sdim                Value initialValue(0);
2736314564Sdim                Value memberOffset(0);
2737314564Sdim                const DWARFDataExtractor &debug_info_data =
2738314564Sdim                    die.GetDWARF()->get_debug_info_data();
2739314564Sdim                uint32_t block_length = form_value.Unsigned();
2740314564Sdim                uint32_t block_offset =
2741314564Sdim                    form_value.BlockData() - debug_info_data.GetDataStart();
2742314564Sdim                if (DWARFExpression::Evaluate(
2743314564Sdim                        nullptr, // ExecutionContext *
2744314564Sdim                        nullptr, // ClangExpressionVariableList *
2745314564Sdim                        nullptr, // ClangExpressionDeclMap *
2746314564Sdim                        nullptr, // RegisterContext *
2747314564Sdim                        module_sp, debug_info_data, die.GetCU(), block_offset,
2748314564Sdim                        block_length, eRegisterKindDWARF, &initialValue,
2749314564Sdim                        nullptr, memberOffset, nullptr)) {
2750314564Sdim                  member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
2751314564Sdim                }
2752314564Sdim              } else {
2753314564Sdim                // With DWARF 3 and later, if the value is an integer constant,
2754314564Sdim                // this form value is the offset in bytes from the beginning
2755314564Sdim                // of the containing entity.
2756314564Sdim                member_byte_offset = form_value.Unsigned();
2757314564Sdim              }
2758314564Sdim              break;
2759292932Sdim
2760314564Sdim            case DW_AT_accessibility:
2761314564Sdim              accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
2762314564Sdim              break;
2763314564Sdim            case DW_AT_artificial:
2764314564Sdim              is_artificial = form_value.Boolean();
2765314564Sdim              break;
2766314564Sdim            case DW_AT_APPLE_property_name:
2767314564Sdim              prop_name = form_value.AsCString();
2768314564Sdim              break;
2769314564Sdim            case DW_AT_APPLE_property_getter:
2770314564Sdim              prop_getter_name = form_value.AsCString();
2771314564Sdim              break;
2772314564Sdim            case DW_AT_APPLE_property_setter:
2773314564Sdim              prop_setter_name = form_value.AsCString();
2774314564Sdim              break;
2775314564Sdim            case DW_AT_APPLE_property_attribute:
2776314564Sdim              prop_attributes = form_value.Unsigned();
2777314564Sdim              break;
2778314564Sdim            case DW_AT_external:
2779314564Sdim              is_external = form_value.Boolean();
2780314564Sdim              break;
2781292932Sdim
2782314564Sdim            default:
2783314564Sdim            case DW_AT_declaration:
2784314564Sdim            case DW_AT_description:
2785314564Sdim            case DW_AT_mutable:
2786314564Sdim            case DW_AT_visibility:
2787314564Sdim            case DW_AT_sibling:
2788314564Sdim              break;
2789314564Sdim            }
2790314564Sdim          }
2791314564Sdim        }
2792292932Sdim
2793314564Sdim        if (prop_name) {
2794314564Sdim          ConstString fixed_getter;
2795314564Sdim          ConstString fixed_setter;
2796292932Sdim
2797314564Sdim          // Check if the property getter/setter were provided as full
2798314564Sdim          // names.  We want basenames, so we extract them.
2799292932Sdim
2800314564Sdim          if (prop_getter_name && prop_getter_name[0] == '-') {
2801314564Sdim            ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true);
2802314564Sdim            prop_getter_name = prop_getter_method.GetSelector().GetCString();
2803314564Sdim          }
2804292932Sdim
2805314564Sdim          if (prop_setter_name && prop_setter_name[0] == '-') {
2806314564Sdim            ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true);
2807314564Sdim            prop_setter_name = prop_setter_method.GetSelector().GetCString();
2808314564Sdim          }
2809292932Sdim
2810314564Sdim          // If the names haven't been provided, they need to be
2811314564Sdim          // filled in.
2812292932Sdim
2813314564Sdim          if (!prop_getter_name) {
2814314564Sdim            prop_getter_name = prop_name;
2815314564Sdim          }
2816314564Sdim          if (!prop_setter_name && prop_name[0] &&
2817314564Sdim              !(prop_attributes & DW_APPLE_PROPERTY_readonly)) {
2818314564Sdim            StreamString ss;
2819292932Sdim
2820314564Sdim            ss.Printf("set%c%s:", toupper(prop_name[0]), &prop_name[1]);
2821292932Sdim
2822314564Sdim            fixed_setter.SetString(ss.GetString());
2823314564Sdim            prop_setter_name = fixed_setter.GetCString();
2824314564Sdim          }
2825314564Sdim        }
2826292932Sdim
2827314564Sdim        // Clang has a DWARF generation bug where sometimes it
2828314564Sdim        // represents fields that are references with bad byte size
2829314564Sdim        // and bit size/offset information such as:
2830314564Sdim        //
2831314564Sdim        //  DW_AT_byte_size( 0x00 )
2832314564Sdim        //  DW_AT_bit_size( 0x40 )
2833314564Sdim        //  DW_AT_bit_offset( 0xffffffffffffffc0 )
2834314564Sdim        //
2835314564Sdim        // So check the bit offset to make sure it is sane, and if
2836314564Sdim        // the values are not sane, remove them. If we don't do this
2837314564Sdim        // then we will end up with a crash if we try to use this
2838314564Sdim        // type in an expression when clang becomes unhappy with its
2839314564Sdim        // recycled debug info.
2840292932Sdim
2841314564Sdim        if (byte_size == 0 && bit_offset < 0) {
2842314564Sdim          bit_size = 0;
2843314564Sdim          bit_offset = 0;
2844314564Sdim        }
2845292932Sdim
2846314564Sdim        // FIXME: Make Clang ignore Objective-C accessibility for expressions
2847314564Sdim        if (class_language == eLanguageTypeObjC ||
2848314564Sdim            class_language == eLanguageTypeObjC_plus_plus)
2849314564Sdim          accessibility = eAccessNone;
2850292932Sdim
2851314564Sdim        if (member_idx == 0 && !is_artificial && name &&
2852314564Sdim            (strstr(name, "_vptr$") == name)) {
2853314564Sdim          // Not all compilers will mark the vtable pointer
2854314564Sdim          // member as artificial (llvm-gcc). We can't have
2855314564Sdim          // the virtual members in our classes otherwise it
2856314564Sdim          // throws off all child offsets since we end up
2857314564Sdim          // having and extra pointer sized member in our
2858314564Sdim          // class layouts.
2859314564Sdim          is_artificial = true;
2860314564Sdim        }
2861292932Sdim
2862314564Sdim        // Handle static members
2863314564Sdim        if (is_external && member_byte_offset == UINT32_MAX) {
2864314564Sdim          Type *var_type = die.ResolveTypeUID(DIERef(encoding_form));
2865292932Sdim
2866314564Sdim          if (var_type) {
2867314564Sdim            if (accessibility == eAccessNone)
2868314564Sdim              accessibility = eAccessPublic;
2869314564Sdim            ClangASTContext::AddVariableToRecordType(
2870314564Sdim                class_clang_type, name, var_type->GetLayoutCompilerType(),
2871314564Sdim                accessibility);
2872314564Sdim          }
2873314564Sdim          break;
2874314564Sdim        }
2875292932Sdim
2876314564Sdim        if (is_artificial == false) {
2877314564Sdim          Type *member_type = die.ResolveTypeUID(DIERef(encoding_form));
2878292932Sdim
2879314564Sdim          clang::FieldDecl *field_decl = NULL;
2880314564Sdim          if (tag == DW_TAG_member) {
2881314564Sdim            if (member_type) {
2882314564Sdim              if (accessibility == eAccessNone)
2883314564Sdim                accessibility = default_accessibility;
2884314564Sdim              member_accessibilities.push_back(accessibility);
2885292932Sdim
2886314564Sdim              uint64_t field_bit_offset =
2887314564Sdim                  (member_byte_offset == UINT32_MAX ? 0
2888314564Sdim                                                    : (member_byte_offset * 8));
2889314564Sdim              if (bit_size > 0) {
2890292932Sdim
2891314564Sdim                BitfieldInfo this_field_info;
2892314564Sdim                this_field_info.bit_offset = field_bit_offset;
2893314564Sdim                this_field_info.bit_size = bit_size;
2894292932Sdim
2895314564Sdim                /////////////////////////////////////////////////////////////
2896314564Sdim                // How to locate a field given the DWARF debug information
2897314564Sdim                //
2898314564Sdim                // AT_byte_size indicates the size of the word in which the
2899314564Sdim                // bit offset must be interpreted.
2900314564Sdim                //
2901314564Sdim                // AT_data_member_location indicates the byte offset of the
2902314564Sdim                // word from the base address of the structure.
2903314564Sdim                //
2904314564Sdim                // AT_bit_offset indicates how many bits into the word
2905314564Sdim                // (according to the host endianness) the low-order bit of
2906314564Sdim                // the field starts.  AT_bit_offset can be negative.
2907314564Sdim                //
2908314564Sdim                // AT_bit_size indicates the size of the field in bits.
2909314564Sdim                /////////////////////////////////////////////////////////////
2910292932Sdim
2911314564Sdim                if (data_bit_offset != UINT64_MAX) {
2912314564Sdim                  this_field_info.bit_offset = data_bit_offset;
2913314564Sdim                } else {
2914314564Sdim                  if (byte_size == 0)
2915314564Sdim                    byte_size = member_type->GetByteSize();
2916292932Sdim
2917314564Sdim                  ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
2918314564Sdim                  if (objfile->GetByteOrder() == eByteOrderLittle) {
2919314564Sdim                    this_field_info.bit_offset += byte_size * 8;
2920314564Sdim                    this_field_info.bit_offset -= (bit_offset + bit_size);
2921314564Sdim                  } else {
2922314564Sdim                    this_field_info.bit_offset += bit_offset;
2923314564Sdim                  }
2924314564Sdim                }
2925309124Sdim
2926314564Sdim                if ((this_field_info.bit_offset >= parent_bit_size) ||
2927314564Sdim                    !last_field_info.NextBitfieldOffsetIsValid(
2928314564Sdim                        this_field_info.bit_offset)) {
2929314564Sdim                  ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
2930314564Sdim                  objfile->GetModule()->ReportWarning(
2931314564Sdim                      "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
2932314564Sdim                                      "bit offset (0x%8.8" PRIx64
2933314564Sdim                      ") member will be ignored. Please file a bug against the "
2934314564Sdim                      "compiler and include the preprocessed output for %s\n",
2935314564Sdim                      die.GetID(), DW_TAG_value_to_name(tag), name,
2936314564Sdim                      this_field_info.bit_offset,
2937314564Sdim                      sc.comp_unit ? sc.comp_unit->GetPath().c_str()
2938314564Sdim                                   : "the source file");
2939314564Sdim                  this_field_info.Clear();
2940314564Sdim                  continue;
2941314564Sdim                }
2942292932Sdim
2943314564Sdim                // Update the field bit offset we will report for layout
2944314564Sdim                field_bit_offset = this_field_info.bit_offset;
2945309124Sdim
2946314564Sdim                // If the member to be emitted did not start on a character
2947314564Sdim                // boundary and there is
2948314564Sdim                // empty space between the last field and this one, then we need
2949314564Sdim                // to emit an
2950314564Sdim                // anonymous member filling up the space up to its start.  There
2951314564Sdim                // are three cases
2952314564Sdim                // here:
2953314564Sdim                //
2954314564Sdim                // 1 If the previous member ended on a character boundary, then
2955314564Sdim                // we can emit an
2956314564Sdim                //   anonymous member starting at the most recent character
2957314564Sdim                //   boundary.
2958314564Sdim                //
2959314564Sdim                // 2 If the previous member did not end on a character boundary
2960314564Sdim                // and the distance
2961314564Sdim                //   from the end of the previous member to the current member
2962314564Sdim                //   is less than a
2963314564Sdim                //   word width, then we can emit an anonymous member starting
2964314564Sdim                //   right after the
2965314564Sdim                //   previous member and right before this member.
2966314564Sdim                //
2967314564Sdim                // 3 If the previous member did not end on a character boundary
2968314564Sdim                // and the distance
2969314564Sdim                //   from the end of the previous member to the current member
2970314564Sdim                //   is greater than
2971314564Sdim                //   or equal a word width, then we act as in Case 1.
2972292932Sdim
2973314564Sdim                const uint64_t character_width = 8;
2974314564Sdim                const uint64_t word_width = 32;
2975292932Sdim
2976314564Sdim                // Objective-C has invalid DW_AT_bit_offset values in older
2977314564Sdim                // versions
2978314564Sdim                // of clang, so we have to be careful and only insert unnamed
2979314564Sdim                // bitfields
2980314564Sdim                // if we have a new enough clang.
2981314564Sdim                bool detect_unnamed_bitfields = true;
2982292932Sdim
2983314564Sdim                if (class_language == eLanguageTypeObjC ||
2984314564Sdim                    class_language == eLanguageTypeObjC_plus_plus)
2985314564Sdim                  detect_unnamed_bitfields =
2986314564Sdim                      die.GetCU()->Supports_unnamed_objc_bitfields();
2987292932Sdim
2988314564Sdim                if (detect_unnamed_bitfields) {
2989314564Sdim                  BitfieldInfo anon_field_info;
2990292932Sdim
2991314564Sdim                  if ((this_field_info.bit_offset % character_width) !=
2992314564Sdim                      0) // not char aligned
2993314564Sdim                  {
2994314564Sdim                    uint64_t last_field_end = 0;
2995292932Sdim
2996314564Sdim                    if (last_field_info.IsValid())
2997314564Sdim                      last_field_end =
2998314564Sdim                          last_field_info.bit_offset + last_field_info.bit_size;
2999292932Sdim
3000314564Sdim                    if (this_field_info.bit_offset != last_field_end) {
3001314564Sdim                      if (((last_field_end % character_width) == 0) || // case 1
3002314564Sdim                          (this_field_info.bit_offset - last_field_end >=
3003314564Sdim                           word_width)) // case 3
3004314564Sdim                      {
3005314564Sdim                        anon_field_info.bit_size =
3006314564Sdim                            this_field_info.bit_offset % character_width;
3007314564Sdim                        anon_field_info.bit_offset =
3008314564Sdim                            this_field_info.bit_offset -
3009314564Sdim                            anon_field_info.bit_size;
3010314564Sdim                      } else // case 2
3011314564Sdim                      {
3012314564Sdim                        anon_field_info.bit_size =
3013314564Sdim                            this_field_info.bit_offset - last_field_end;
3014314564Sdim                        anon_field_info.bit_offset = last_field_end;
3015314564Sdim                      }
3016314564Sdim                    }
3017314564Sdim                  }
3018292932Sdim
3019314564Sdim                  if (anon_field_info.IsValid()) {
3020314564Sdim                    clang::FieldDecl *unnamed_bitfield_decl =
3021314564Sdim                        ClangASTContext::AddFieldToRecordType(
3022314564Sdim                            class_clang_type, NULL,
3023314564Sdim                            m_ast.GetBuiltinTypeForEncodingAndBitSize(
3024314564Sdim                                eEncodingSint, word_width),
3025314564Sdim                            accessibility, anon_field_info.bit_size);
3026292932Sdim
3027314564Sdim                    layout_info.field_offsets.insert(std::make_pair(
3028314564Sdim                        unnamed_bitfield_decl, anon_field_info.bit_offset));
3029314564Sdim                  }
3030314564Sdim                }
3031314564Sdim                last_field_info = this_field_info;
3032314564Sdim              } else {
3033314564Sdim                last_field_info.Clear();
3034314564Sdim              }
3035292932Sdim
3036314564Sdim              CompilerType member_clang_type =
3037314564Sdim                  member_type->GetLayoutCompilerType();
3038314564Sdim              if (!member_clang_type.IsCompleteType())
3039314564Sdim                member_clang_type.GetCompleteType();
3040292932Sdim
3041314564Sdim              {
3042314564Sdim                // Older versions of clang emit array[0] and array[1] in the
3043314564Sdim                // same way (<rdar://problem/12566646>).
3044314564Sdim                // If the current field is at the end of the structure, then
3045314564Sdim                // there is definitely no room for extra
3046314564Sdim                // elements and we override the type to array[0].
3047292932Sdim
3048314564Sdim                CompilerType member_array_element_type;
3049314564Sdim                uint64_t member_array_size;
3050314564Sdim                bool member_array_is_incomplete;
3051292932Sdim
3052314564Sdim                if (member_clang_type.IsArrayType(
3053314564Sdim                        &member_array_element_type, &member_array_size,
3054314564Sdim                        &member_array_is_incomplete) &&
3055314564Sdim                    !member_array_is_incomplete) {
3056314564Sdim                  uint64_t parent_byte_size =
3057314564Sdim                      parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size,
3058314564Sdim                                                             UINT64_MAX);
3059292932Sdim
3060314564Sdim                  if (member_byte_offset >= parent_byte_size) {
3061314564Sdim                    if (member_array_size != 1 &&
3062314564Sdim                        (member_array_size != 0 ||
3063314564Sdim                         member_byte_offset > parent_byte_size)) {
3064314564Sdim                      module_sp->ReportError(
3065314564Sdim                          "0x%8.8" PRIx64
3066314564Sdim                          ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64
3067314564Sdim                          " which extends beyond the bounds of 0x%8.8" PRIx64,
3068314564Sdim                          die.GetID(), name, encoding_form.Reference(),
3069314564Sdim                          parent_die.GetID());
3070314564Sdim                    }
3071292932Sdim
3072314564Sdim                    member_clang_type = m_ast.CreateArrayType(
3073314564Sdim                        member_array_element_type, 0, false);
3074314564Sdim                  }
3075314564Sdim                }
3076314564Sdim              }
3077292932Sdim
3078314564Sdim              if (ClangASTContext::IsCXXClassType(member_clang_type) &&
3079314564Sdim                  member_clang_type.GetCompleteType() == false) {
3080314564Sdim                if (die.GetCU()->GetProducer() ==
3081314564Sdim                    DWARFCompileUnit::eProducerClang)
3082314564Sdim                  module_sp->ReportError(
3083314564Sdim                      "DWARF DIE at 0x%8.8x (class %s) has a member variable "
3084314564Sdim                      "0x%8.8x (%s) whose type is a forward declaration, not a "
3085314564Sdim                      "complete definition.\nTry compiling the source file "
3086314564Sdim                      "with -fno-limit-debug-info",
3087314564Sdim                      parent_die.GetOffset(), parent_die.GetName(),
3088314564Sdim                      die.GetOffset(), name);
3089314564Sdim                else
3090314564Sdim                  module_sp->ReportError(
3091314564Sdim                      "DWARF DIE at 0x%8.8x (class %s) has a member variable "
3092314564Sdim                      "0x%8.8x (%s) whose type is a forward declaration, not a "
3093314564Sdim                      "complete definition.\nPlease file a bug against the "
3094314564Sdim                      "compiler and include the preprocessed output for %s",
3095314564Sdim                      parent_die.GetOffset(), parent_die.GetName(),
3096314564Sdim                      die.GetOffset(), name,
3097314564Sdim                      sc.comp_unit ? sc.comp_unit->GetPath().c_str()
3098314564Sdim                                   : "the source file");
3099314564Sdim                // We have no choice other than to pretend that the member class
3100314564Sdim                // is complete. If we don't do this, clang will crash when
3101314564Sdim                // trying
3102314564Sdim                // to layout the class. Since we provide layout assistance, all
3103314564Sdim                // ivars in this class and other classes will be fine, this is
3104314564Sdim                // the best we can do short of crashing.
3105314564Sdim                if (ClangASTContext::StartTagDeclarationDefinition(
3106314564Sdim                        member_clang_type)) {
3107314564Sdim                  ClangASTContext::CompleteTagDeclarationDefinition(
3108314564Sdim                      member_clang_type);
3109314564Sdim                } else {
3110314564Sdim                  module_sp->ReportError(
3111314564Sdim                      "DWARF DIE at 0x%8.8x (class %s) has a member variable "
3112314564Sdim                      "0x%8.8x (%s) whose type claims to be a C++ class but we "
3113314564Sdim                      "were not able to start its definition.\nPlease file a "
3114314564Sdim                      "bug and attach the file at the start of this error "
3115314564Sdim                      "message",
3116314564Sdim                      parent_die.GetOffset(), parent_die.GetName(),
3117314564Sdim                      die.GetOffset(), name);
3118314564Sdim                }
3119314564Sdim              }
3120292932Sdim
3121314564Sdim              field_decl = ClangASTContext::AddFieldToRecordType(
3122314564Sdim                  class_clang_type, name, member_clang_type, accessibility,
3123314564Sdim                  bit_size);
3124292932Sdim
3125314564Sdim              m_ast.SetMetadataAsUserID(field_decl, die.GetID());
3126292932Sdim
3127314564Sdim              layout_info.field_offsets.insert(
3128314564Sdim                  std::make_pair(field_decl, field_bit_offset));
3129314564Sdim            } else {
3130314564Sdim              if (name)
3131314564Sdim                module_sp->ReportError(
3132314564Sdim                    "0x%8.8" PRIx64
3133314564Sdim                    ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64
3134314564Sdim                    " which was unable to be parsed",
3135314564Sdim                    die.GetID(), name, encoding_form.Reference());
3136314564Sdim              else
3137314564Sdim                module_sp->ReportError(
3138314564Sdim                    "0x%8.8" PRIx64
3139314564Sdim                    ": DW_TAG_member refers to type 0x%8.8" PRIx64
3140314564Sdim                    " which was unable to be parsed",
3141314564Sdim                    die.GetID(), encoding_form.Reference());
3142314564Sdim            }
3143314564Sdim          }
3144292932Sdim
3145314564Sdim          if (prop_name != NULL && member_type) {
3146314564Sdim            clang::ObjCIvarDecl *ivar_decl = NULL;
3147292932Sdim
3148314564Sdim            if (field_decl) {
3149314564Sdim              ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
3150314564Sdim              assert(ivar_decl != NULL);
3151292932Sdim            }
3152292932Sdim
3153314564Sdim            ClangASTMetadata metadata;
3154314564Sdim            metadata.SetUserID(die.GetID());
3155314564Sdim            delayed_properties.push_back(DelayedAddObjCClassProperty(
3156314564Sdim                class_clang_type, prop_name,
3157314564Sdim                member_type->GetLayoutCompilerType(), ivar_decl,
3158314564Sdim                prop_setter_name, prop_getter_name, prop_attributes,
3159314564Sdim                &metadata));
3160292932Sdim
3161314564Sdim            if (ivar_decl)
3162314564Sdim              m_ast.SetMetadataAsUserID(ivar_decl, die.GetID());
3163314564Sdim          }
3164314564Sdim        }
3165314564Sdim      }
3166314564Sdim      ++member_idx;
3167314564Sdim    } break;
3168292932Sdim
3169314564Sdim    case DW_TAG_subprogram:
3170314564Sdim      // Let the type parsing code handle this one for us.
3171314564Sdim      member_function_dies.Append(die);
3172314564Sdim      break;
3173292932Sdim
3174314564Sdim    case DW_TAG_inheritance: {
3175314564Sdim      is_a_class = true;
3176314564Sdim      if (default_accessibility == eAccessNone)
3177314564Sdim        default_accessibility = eAccessPrivate;
3178314564Sdim      // TODO: implement DW_TAG_inheritance type parsing
3179314564Sdim      DWARFAttributes attributes;
3180314564Sdim      const size_t num_attributes = die.GetAttributes(attributes);
3181314564Sdim      if (num_attributes > 0) {
3182314564Sdim        Declaration decl;
3183314564Sdim        DWARFExpression location(die.GetCU());
3184314564Sdim        DWARFFormValue encoding_form;
3185314564Sdim        AccessType accessibility = default_accessibility;
3186314564Sdim        bool is_virtual = false;
3187314564Sdim        bool is_base_of_class = true;
3188314564Sdim        off_t member_byte_offset = 0;
3189314564Sdim        uint32_t i;
3190314564Sdim        for (i = 0; i < num_attributes; ++i) {
3191314564Sdim          const dw_attr_t attr = attributes.AttributeAtIndex(i);
3192314564Sdim          DWARFFormValue form_value;
3193314564Sdim          if (attributes.ExtractFormValueAtIndex(i, form_value)) {
3194314564Sdim            switch (attr) {
3195314564Sdim            case DW_AT_decl_file:
3196314564Sdim              decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
3197314564Sdim                  form_value.Unsigned()));
3198314564Sdim              break;
3199314564Sdim            case DW_AT_decl_line:
3200314564Sdim              decl.SetLine(form_value.Unsigned());
3201314564Sdim              break;
3202314564Sdim            case DW_AT_decl_column:
3203314564Sdim              decl.SetColumn(form_value.Unsigned());
3204314564Sdim              break;
3205314564Sdim            case DW_AT_type:
3206314564Sdim              encoding_form = form_value;
3207314564Sdim              break;
3208314564Sdim            case DW_AT_data_member_location:
3209314564Sdim              if (form_value.BlockData()) {
3210314564Sdim                Value initialValue(0);
3211314564Sdim                Value memberOffset(0);
3212314564Sdim                const DWARFDataExtractor &debug_info_data =
3213314564Sdim                    die.GetDWARF()->get_debug_info_data();
3214314564Sdim                uint32_t block_length = form_value.Unsigned();
3215314564Sdim                uint32_t block_offset =
3216314564Sdim                    form_value.BlockData() - debug_info_data.GetDataStart();
3217314564Sdim                if (DWARFExpression::Evaluate(
3218314564Sdim                        nullptr, nullptr, nullptr, nullptr, module_sp,
3219314564Sdim                        debug_info_data, die.GetCU(), block_offset,
3220314564Sdim                        block_length, eRegisterKindDWARF, &initialValue,
3221314564Sdim                        nullptr, memberOffset, nullptr)) {
3222314564Sdim                  member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
3223314564Sdim                }
3224314564Sdim              } else {
3225314564Sdim                // With DWARF 3 and later, if the value is an integer constant,
3226314564Sdim                // this form value is the offset in bytes from the beginning
3227314564Sdim                // of the containing entity.
3228314564Sdim                member_byte_offset = form_value.Unsigned();
3229314564Sdim              }
3230314564Sdim              break;
3231292932Sdim
3232314564Sdim            case DW_AT_accessibility:
3233314564Sdim              accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
3234314564Sdim              break;
3235292932Sdim
3236314564Sdim            case DW_AT_virtuality:
3237314564Sdim              is_virtual = form_value.Boolean();
3238314564Sdim              break;
3239292932Sdim
3240314564Sdim            case DW_AT_sibling:
3241314564Sdim              break;
3242292932Sdim
3243314564Sdim            default:
3244314564Sdim              break;
3245292932Sdim            }
3246314564Sdim          }
3247314564Sdim        }
3248292932Sdim
3249314564Sdim        Type *base_class_type = die.ResolveTypeUID(DIERef(encoding_form));
3250314564Sdim        if (base_class_type == NULL) {
3251314564Sdim          module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to "
3252314564Sdim                                 "resolve the base class at 0x%8.8" PRIx64
3253314564Sdim                                 " from enclosing type 0x%8.8x. \nPlease file "
3254314564Sdim                                 "a bug and attach the file at the start of "
3255314564Sdim                                 "this error message",
3256314564Sdim                                 die.GetOffset(), encoding_form.Reference(),
3257314564Sdim                                 parent_die.GetOffset());
3258314564Sdim          break;
3259292932Sdim        }
3260292932Sdim
3261314564Sdim        CompilerType base_class_clang_type =
3262314564Sdim            base_class_type->GetFullCompilerType();
3263314564Sdim        assert(base_class_clang_type);
3264314564Sdim        if (class_language == eLanguageTypeObjC) {
3265314564Sdim          ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);
3266314564Sdim        } else {
3267314564Sdim          base_classes.push_back(ast->CreateBaseClassSpecifier(
3268314564Sdim              base_class_clang_type.GetOpaqueQualType(), accessibility,
3269314564Sdim              is_virtual, is_base_of_class));
3270292932Sdim
3271314564Sdim          if (is_virtual) {
3272314564Sdim            // Do not specify any offset for virtual inheritance. The DWARF
3273314564Sdim            // produced by clang doesn't
3274314564Sdim            // give us a constant offset, but gives us a DWARF expressions that
3275314564Sdim            // requires an actual object
3276314564Sdim            // in memory. the DW_AT_data_member_location for a virtual base
3277314564Sdim            // class looks like:
3278314564Sdim            //      DW_AT_data_member_location( DW_OP_dup, DW_OP_deref,
3279314564Sdim            //      DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref,
3280314564Sdim            //      DW_OP_plus )
3281314564Sdim            // Given this, there is really no valid response we can give to
3282314564Sdim            // clang for virtual base
3283314564Sdim            // class offsets, and this should eventually be removed from
3284314564Sdim            // LayoutRecordType() in the external
3285314564Sdim            // AST source in clang.
3286314564Sdim          } else {
3287314564Sdim            layout_info.base_offsets.insert(std::make_pair(
3288314564Sdim                ast->GetAsCXXRecordDecl(
3289314564Sdim                    base_class_clang_type.GetOpaqueQualType()),
3290314564Sdim                clang::CharUnits::fromQuantity(member_byte_offset)));
3291314564Sdim          }
3292314564Sdim        }
3293314564Sdim      }
3294314564Sdim    } break;
3295292932Sdim
3296314564Sdim    default:
3297314564Sdim      break;
3298314564Sdim    }
3299314564Sdim  }
3300292932Sdim
3301314564Sdim  return true;
3302314564Sdim}
3303292932Sdim
3304314564Sdimsize_t DWARFASTParserClang::ParseChildParameters(
3305314564Sdim    const SymbolContext &sc, clang::DeclContext *containing_decl_ctx,
3306314564Sdim    const DWARFDIE &parent_die, bool skip_artificial, bool &is_static,
3307314564Sdim    bool &is_variadic, bool &has_template_params,
3308314564Sdim    std::vector<CompilerType> &function_param_types,
3309314564Sdim    std::vector<clang::ParmVarDecl *> &function_param_decls,
3310314564Sdim    unsigned &type_quals) {
3311314564Sdim  if (!parent_die)
3312314564Sdim    return 0;
3313292932Sdim
3314314564Sdim  size_t arg_idx = 0;
3315314564Sdim  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
3316314564Sdim       die = die.GetSibling()) {
3317314564Sdim    const dw_tag_t tag = die.Tag();
3318314564Sdim    switch (tag) {
3319314564Sdim    case DW_TAG_formal_parameter: {
3320314564Sdim      DWARFAttributes attributes;
3321314564Sdim      const size_t num_attributes = die.GetAttributes(attributes);
3322314564Sdim      if (num_attributes > 0) {
3323314564Sdim        const char *name = NULL;
3324314564Sdim        Declaration decl;
3325314564Sdim        DWARFFormValue param_type_die_form;
3326314564Sdim        bool is_artificial = false;
3327314564Sdim        // one of None, Auto, Register, Extern, Static, PrivateExtern
3328292932Sdim
3329314564Sdim        clang::StorageClass storage = clang::SC_None;
3330314564Sdim        uint32_t i;
3331314564Sdim        for (i = 0; i < num_attributes; ++i) {
3332314564Sdim          const dw_attr_t attr = attributes.AttributeAtIndex(i);
3333314564Sdim          DWARFFormValue form_value;
3334314564Sdim          if (attributes.ExtractFormValueAtIndex(i, form_value)) {
3335314564Sdim            switch (attr) {
3336314564Sdim            case DW_AT_decl_file:
3337314564Sdim              decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
3338314564Sdim                  form_value.Unsigned()));
3339314564Sdim              break;
3340314564Sdim            case DW_AT_decl_line:
3341314564Sdim              decl.SetLine(form_value.Unsigned());
3342314564Sdim              break;
3343314564Sdim            case DW_AT_decl_column:
3344314564Sdim              decl.SetColumn(form_value.Unsigned());
3345314564Sdim              break;
3346314564Sdim            case DW_AT_name:
3347314564Sdim              name = form_value.AsCString();
3348314564Sdim              break;
3349314564Sdim            case DW_AT_type:
3350314564Sdim              param_type_die_form = form_value;
3351314564Sdim              break;
3352314564Sdim            case DW_AT_artificial:
3353314564Sdim              is_artificial = form_value.Boolean();
3354314564Sdim              break;
3355314564Sdim            case DW_AT_location:
3356314564Sdim            //                          if (form_value.BlockData())
3357314564Sdim            //                          {
3358314564Sdim            //                              const DWARFDataExtractor&
3359314564Sdim            //                              debug_info_data = debug_info();
3360314564Sdim            //                              uint32_t block_length =
3361314564Sdim            //                              form_value.Unsigned();
3362314564Sdim            //                              DWARFDataExtractor
3363314564Sdim            //                              location(debug_info_data,
3364314564Sdim            //                              form_value.BlockData() -
3365314564Sdim            //                              debug_info_data.GetDataStart(),
3366314564Sdim            //                              block_length);
3367314564Sdim            //                          }
3368314564Sdim            //                          else
3369314564Sdim            //                          {
3370314564Sdim            //                          }
3371314564Sdim            //                          break;
3372314564Sdim            case DW_AT_const_value:
3373314564Sdim            case DW_AT_default_value:
3374314564Sdim            case DW_AT_description:
3375314564Sdim            case DW_AT_endianity:
3376314564Sdim            case DW_AT_is_optional:
3377314564Sdim            case DW_AT_segment:
3378314564Sdim            case DW_AT_variable_parameter:
3379314564Sdim            default:
3380314564Sdim            case DW_AT_abstract_origin:
3381314564Sdim            case DW_AT_sibling:
3382314564Sdim              break;
3383314564Sdim            }
3384314564Sdim          }
3385314564Sdim        }
3386292932Sdim
3387314564Sdim        bool skip = false;
3388314564Sdim        if (skip_artificial) {
3389314564Sdim          if (is_artificial) {
3390314564Sdim            // In order to determine if a C++ member function is
3391314564Sdim            // "const" we have to look at the const-ness of "this"...
3392314564Sdim            // Ugly, but that
3393314564Sdim            if (arg_idx == 0) {
3394314564Sdim              if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind())) {
3395314564Sdim                // Often times compilers omit the "this" name for the
3396314564Sdim                // specification DIEs, so we can't rely upon the name
3397314564Sdim                // being in the formal parameter DIE...
3398314564Sdim                if (name == NULL || ::strcmp(name, "this") == 0) {
3399314564Sdim                  Type *this_type =
3400314564Sdim                      die.ResolveTypeUID(DIERef(param_type_die_form));
3401314564Sdim                  if (this_type) {
3402314564Sdim                    uint32_t encoding_mask = this_type->GetEncodingMask();
3403314564Sdim                    if (encoding_mask & Type::eEncodingIsPointerUID) {
3404314564Sdim                      is_static = false;
3405292932Sdim
3406314564Sdim                      if (encoding_mask & (1u << Type::eEncodingIsConstUID))
3407314564Sdim                        type_quals |= clang::Qualifiers::Const;
3408314564Sdim                      if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
3409314564Sdim                        type_quals |= clang::Qualifiers::Volatile;
3410292932Sdim                    }
3411314564Sdim                  }
3412292932Sdim                }
3413314564Sdim              }
3414292932Sdim            }
3415314564Sdim            skip = true;
3416314564Sdim          } else {
3417292932Sdim
3418314564Sdim            // HACK: Objective C formal parameters "self" and "_cmd"
3419314564Sdim            // are not marked as artificial in the DWARF...
3420314564Sdim            CompileUnit *comp_unit = die.GetLLDBCompileUnit();
3421314564Sdim            if (comp_unit) {
3422314564Sdim              switch (comp_unit->GetLanguage()) {
3423314564Sdim              case eLanguageTypeObjC:
3424314564Sdim              case eLanguageTypeObjC_plus_plus:
3425314564Sdim                if (name && name[0] &&
3426314564Sdim                    (strcmp(name, "self") == 0 || strcmp(name, "_cmd") == 0))
3427314564Sdim                  skip = true;
3428292932Sdim                break;
3429314564Sdim              default:
3430292932Sdim                break;
3431314564Sdim              }
3432314564Sdim            }
3433314564Sdim          }
3434314564Sdim        }
3435292932Sdim
3436314564Sdim        if (!skip) {
3437314564Sdim          Type *type = die.ResolveTypeUID(DIERef(param_type_die_form));
3438314564Sdim          if (type) {
3439314564Sdim            function_param_types.push_back(type->GetForwardCompilerType());
3440314564Sdim
3441314564Sdim            clang::ParmVarDecl *param_var_decl =
3442314564Sdim                m_ast.CreateParameterDeclaration(
3443314564Sdim                    name, type->GetForwardCompilerType(), storage);
3444314564Sdim            assert(param_var_decl);
3445314564Sdim            function_param_decls.push_back(param_var_decl);
3446314564Sdim
3447314564Sdim            m_ast.SetMetadataAsUserID(param_var_decl, die.GetID());
3448314564Sdim          }
3449292932Sdim        }
3450314564Sdim      }
3451314564Sdim      arg_idx++;
3452314564Sdim    } break;
3453314564Sdim
3454314564Sdim    case DW_TAG_unspecified_parameters:
3455314564Sdim      is_variadic = true;
3456314564Sdim      break;
3457314564Sdim
3458314564Sdim    case DW_TAG_template_type_parameter:
3459314564Sdim    case DW_TAG_template_value_parameter:
3460321369Sdim    case DW_TAG_GNU_template_parameter_pack:
3461314564Sdim      // The one caller of this was never using the template_param_infos,
3462314564Sdim      // and the local variable was taking up a large amount of stack space
3463314564Sdim      // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
3464314564Sdim      // the template params back, we can add them back.
3465314564Sdim      // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
3466314564Sdim      has_template_params = true;
3467314564Sdim      break;
3468314564Sdim
3469314564Sdim    default:
3470314564Sdim      break;
3471292932Sdim    }
3472314564Sdim  }
3473314564Sdim  return arg_idx;
3474292932Sdim}
3475292932Sdim
3476314564Sdimvoid DWARFASTParserClang::ParseChildArrayInfo(
3477314564Sdim    const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index,
3478314564Sdim    std::vector<uint64_t> &element_orders, uint32_t &byte_stride,
3479314564Sdim    uint32_t &bit_stride) {
3480314564Sdim  if (!parent_die)
3481314564Sdim    return;
3482292932Sdim
3483314564Sdim  for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
3484314564Sdim       die = die.GetSibling()) {
3485314564Sdim    const dw_tag_t tag = die.Tag();
3486314564Sdim    switch (tag) {
3487314564Sdim    case DW_TAG_subrange_type: {
3488314564Sdim      DWARFAttributes attributes;
3489314564Sdim      const size_t num_child_attributes = die.GetAttributes(attributes);
3490314564Sdim      if (num_child_attributes > 0) {
3491314564Sdim        uint64_t num_elements = 0;
3492314564Sdim        uint64_t lower_bound = 0;
3493314564Sdim        uint64_t upper_bound = 0;
3494314564Sdim        bool upper_bound_valid = false;
3495314564Sdim        uint32_t i;
3496314564Sdim        for (i = 0; i < num_child_attributes; ++i) {
3497314564Sdim          const dw_attr_t attr = attributes.AttributeAtIndex(i);
3498314564Sdim          DWARFFormValue form_value;
3499314564Sdim          if (attributes.ExtractFormValueAtIndex(i, form_value)) {
3500314564Sdim            switch (attr) {
3501314564Sdim            case DW_AT_name:
3502314564Sdim              break;
3503292932Sdim
3504314564Sdim            case DW_AT_count:
3505314564Sdim              num_elements = form_value.Unsigned();
3506314564Sdim              break;
3507292932Sdim
3508314564Sdim            case DW_AT_bit_stride:
3509314564Sdim              bit_stride = form_value.Unsigned();
3510314564Sdim              break;
3511292932Sdim
3512314564Sdim            case DW_AT_byte_stride:
3513314564Sdim              byte_stride = form_value.Unsigned();
3514314564Sdim              break;
3515292932Sdim
3516314564Sdim            case DW_AT_lower_bound:
3517314564Sdim              lower_bound = form_value.Unsigned();
3518314564Sdim              break;
3519292932Sdim
3520314564Sdim            case DW_AT_upper_bound:
3521314564Sdim              upper_bound_valid = true;
3522314564Sdim              upper_bound = form_value.Unsigned();
3523314564Sdim              break;
3524292932Sdim
3525314564Sdim            default:
3526314564Sdim            case DW_AT_abstract_origin:
3527314564Sdim            case DW_AT_accessibility:
3528314564Sdim            case DW_AT_allocated:
3529314564Sdim            case DW_AT_associated:
3530314564Sdim            case DW_AT_data_location:
3531314564Sdim            case DW_AT_declaration:
3532314564Sdim            case DW_AT_description:
3533314564Sdim            case DW_AT_sibling:
3534314564Sdim            case DW_AT_threads_scaled:
3535314564Sdim            case DW_AT_type:
3536314564Sdim            case DW_AT_visibility:
3537314564Sdim              break;
3538314564Sdim            }
3539314564Sdim          }
3540314564Sdim        }
3541292932Sdim
3542314564Sdim        if (num_elements == 0) {
3543314564Sdim          if (upper_bound_valid && upper_bound >= lower_bound)
3544314564Sdim            num_elements = upper_bound - lower_bound + 1;
3545314564Sdim        }
3546292932Sdim
3547314564Sdim        element_orders.push_back(num_elements);
3548314564Sdim      }
3549314564Sdim    } break;
3550292932Sdim    }
3551314564Sdim  }
3552292932Sdim}
3553292932Sdim
3554314564SdimType *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) {
3555314564Sdim  if (die) {
3556314564Sdim    SymbolFileDWARF *dwarf = die.GetDWARF();
3557314564Sdim    DWARFAttributes attributes;
3558314564Sdim    const size_t num_attributes = die.GetAttributes(attributes);
3559314564Sdim    if (num_attributes > 0) {
3560314564Sdim      DWARFFormValue type_die_form;
3561314564Sdim      for (size_t i = 0; i < num_attributes; ++i) {
3562314564Sdim        dw_attr_t attr = attributes.AttributeAtIndex(i);
3563314564Sdim        DWARFFormValue form_value;
3564292932Sdim
3565314564Sdim        if (attr == DW_AT_type &&
3566314564Sdim            attributes.ExtractFormValueAtIndex(i, form_value))
3567314564Sdim          return dwarf->ResolveTypeUID(dwarf->GetDIE(DIERef(form_value)), true);
3568314564Sdim      }
3569292932Sdim    }
3570314564Sdim  }
3571292932Sdim
3572314564Sdim  return nullptr;
3573292932Sdim}
3574292932Sdim
3575314564Sdimclang::Decl *DWARFASTParserClang::GetClangDeclForDIE(const DWARFDIE &die) {
3576314564Sdim  if (!die)
3577314564Sdim    return nullptr;
3578292932Sdim
3579314564Sdim  switch (die.Tag()) {
3580314564Sdim  case DW_TAG_variable:
3581314564Sdim  case DW_TAG_constant:
3582314564Sdim  case DW_TAG_formal_parameter:
3583314564Sdim  case DW_TAG_imported_declaration:
3584314564Sdim  case DW_TAG_imported_module:
3585314564Sdim    break;
3586314564Sdim  default:
3587314564Sdim    return nullptr;
3588314564Sdim  }
3589292932Sdim
3590314564Sdim  DIEToDeclMap::iterator cache_pos = m_die_to_decl.find(die.GetDIE());
3591314564Sdim  if (cache_pos != m_die_to_decl.end())
3592314564Sdim    return cache_pos->second;
3593292932Sdim
3594314564Sdim  if (DWARFDIE spec_die = die.GetReferencedDIE(DW_AT_specification)) {
3595314564Sdim    clang::Decl *decl = GetClangDeclForDIE(spec_die);
3596314564Sdim    m_die_to_decl[die.GetDIE()] = decl;
3597314564Sdim    m_decl_to_die[decl].insert(die.GetDIE());
3598314564Sdim    return decl;
3599314564Sdim  }
3600314564Sdim
3601314564Sdim  if (DWARFDIE abstract_origin_die =
3602314564Sdim          die.GetReferencedDIE(DW_AT_abstract_origin)) {
3603314564Sdim    clang::Decl *decl = GetClangDeclForDIE(abstract_origin_die);
3604314564Sdim    m_die_to_decl[die.GetDIE()] = decl;
3605314564Sdim    m_decl_to_die[decl].insert(die.GetDIE());
3606314564Sdim    return decl;
3607314564Sdim  }
3608314564Sdim
3609314564Sdim  clang::Decl *decl = nullptr;
3610314564Sdim  switch (die.Tag()) {
3611314564Sdim  case DW_TAG_variable:
3612314564Sdim  case DW_TAG_constant:
3613314564Sdim  case DW_TAG_formal_parameter: {
3614314564Sdim    SymbolFileDWARF *dwarf = die.GetDWARF();
3615314564Sdim    Type *type = GetTypeForDIE(die);
3616314564Sdim    if (dwarf && type) {
3617314564Sdim      const char *name = die.GetName();
3618314564Sdim      clang::DeclContext *decl_context =
3619314564Sdim          ClangASTContext::DeclContextGetAsDeclContext(
3620314564Sdim              dwarf->GetDeclContextContainingUID(die.GetID()));
3621314564Sdim      decl = m_ast.CreateVariableDeclaration(
3622314564Sdim          decl_context, name,
3623314564Sdim          ClangUtil::GetQualType(type->GetForwardCompilerType()));
3624292932Sdim    }
3625314564Sdim    break;
3626314564Sdim  }
3627314564Sdim  case DW_TAG_imported_declaration: {
3628314564Sdim    SymbolFileDWARF *dwarf = die.GetDWARF();
3629314564Sdim    DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
3630314564Sdim    if (imported_uid) {
3631314564Sdim      CompilerDecl imported_decl = imported_uid.GetDecl();
3632314564Sdim      if (imported_decl) {
3633314564Sdim        clang::DeclContext *decl_context =
3634314564Sdim            ClangASTContext::DeclContextGetAsDeclContext(
3635314564Sdim                dwarf->GetDeclContextContainingUID(die.GetID()));
3636314564Sdim        if (clang::NamedDecl *clang_imported_decl =
3637314564Sdim                llvm::dyn_cast<clang::NamedDecl>(
3638314564Sdim                    (clang::Decl *)imported_decl.GetOpaqueDecl()))
3639314564Sdim          decl =
3640314564Sdim              m_ast.CreateUsingDeclaration(decl_context, clang_imported_decl);
3641314564Sdim      }
3642309124Sdim    }
3643314564Sdim    break;
3644314564Sdim  }
3645314564Sdim  case DW_TAG_imported_module: {
3646314564Sdim    SymbolFileDWARF *dwarf = die.GetDWARF();
3647314564Sdim    DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
3648292932Sdim
3649314564Sdim    if (imported_uid) {
3650314564Sdim      CompilerDeclContext imported_decl_ctx = imported_uid.GetDeclContext();
3651314564Sdim      if (imported_decl_ctx) {
3652314564Sdim        clang::DeclContext *decl_context =
3653314564Sdim            ClangASTContext::DeclContextGetAsDeclContext(
3654314564Sdim                dwarf->GetDeclContextContainingUID(die.GetID()));
3655314564Sdim        if (clang::NamespaceDecl *ns_decl =
3656314564Sdim                ClangASTContext::DeclContextGetAsNamespaceDecl(
3657314564Sdim                    imported_decl_ctx))
3658314564Sdim          decl = m_ast.CreateUsingDirectiveDeclaration(decl_context, ns_decl);
3659314564Sdim      }
3660292932Sdim    }
3661314564Sdim    break;
3662314564Sdim  }
3663314564Sdim  default:
3664314564Sdim    break;
3665314564Sdim  }
3666292932Sdim
3667314564Sdim  m_die_to_decl[die.GetDIE()] = decl;
3668314564Sdim  m_decl_to_die[decl].insert(die.GetDIE());
3669292932Sdim
3670314564Sdim  return decl;
3671292932Sdim}
3672292932Sdim
3673292932Sdimclang::DeclContext *
3674314564SdimDWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
3675314564Sdim  if (die) {
3676314564Sdim    clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(die);
3677314564Sdim    if (decl_ctx)
3678314564Sdim      return decl_ctx;
3679292932Sdim
3680314564Sdim    bool try_parsing_type = true;
3681314564Sdim    switch (die.Tag()) {
3682314564Sdim    case DW_TAG_compile_unit:
3683314564Sdim      decl_ctx = m_ast.GetTranslationUnitDecl();
3684314564Sdim      try_parsing_type = false;
3685314564Sdim      break;
3686292932Sdim
3687314564Sdim    case DW_TAG_namespace:
3688314564Sdim      decl_ctx = ResolveNamespaceDIE(die);
3689314564Sdim      try_parsing_type = false;
3690314564Sdim      break;
3691292932Sdim
3692314564Sdim    case DW_TAG_lexical_block:
3693321369Sdim      decl_ctx = GetDeclContextForBlock(die);
3694314564Sdim      try_parsing_type = false;
3695314564Sdim      break;
3696292932Sdim
3697314564Sdim    default:
3698314564Sdim      break;
3699314564Sdim    }
3700292932Sdim
3701314564Sdim    if (decl_ctx == nullptr && try_parsing_type) {
3702314564Sdim      Type *type = die.GetDWARF()->ResolveType(die);
3703314564Sdim      if (type)
3704314564Sdim        decl_ctx = GetCachedClangDeclContextForDIE(die);
3705314564Sdim    }
3706292932Sdim
3707314564Sdim    if (decl_ctx) {
3708314564Sdim      LinkDeclContextToDIE(decl_ctx, die);
3709314564Sdim      return decl_ctx;
3710292932Sdim    }
3711314564Sdim  }
3712314564Sdim  return nullptr;
3713292932Sdim}
3714292932Sdim
3715321369Sdimstatic bool IsSubroutine(const DWARFDIE &die) {
3716321369Sdim  switch (die.Tag()) {
3717321369Sdim  case DW_TAG_subprogram:
3718321369Sdim  case DW_TAG_inlined_subroutine:
3719321369Sdim    return true;
3720321369Sdim  default:
3721321369Sdim    return false;
3722321369Sdim  }
3723321369Sdim}
3724321369Sdim
3725321369Sdimstatic DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) {
3726321369Sdim  for (DWARFDIE candidate = die; candidate; candidate = candidate.GetParent()) {
3727321369Sdim    if (IsSubroutine(candidate)) {
3728321369Sdim      if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
3729321369Sdim        return candidate;
3730321369Sdim      } else {
3731321369Sdim        return DWARFDIE();
3732321369Sdim      }
3733321369Sdim    }
3734321369Sdim  }
3735321369Sdim  assert(0 && "Shouldn't call GetContainingFunctionWithAbstractOrigin on "
3736321369Sdim              "something not in a function");
3737321369Sdim  return DWARFDIE();
3738321369Sdim}
3739321369Sdim
3740321369Sdimstatic DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) {
3741321369Sdim  for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid();
3742321369Sdim       candidate = candidate.GetSibling()) {
3743321369Sdim    if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
3744321369Sdim      return candidate;
3745321369Sdim    }
3746321369Sdim  }
3747321369Sdim  return DWARFDIE();
3748321369Sdim}
3749321369Sdim
3750321369Sdimstatic DWARFDIE FindFirstChildWithAbstractOrigin(const DWARFDIE &block,
3751321369Sdim                                                 const DWARFDIE &function) {
3752321369Sdim  assert(IsSubroutine(function));
3753321369Sdim  for (DWARFDIE context = block; context != function.GetParent();
3754321369Sdim       context = context.GetParent()) {
3755321369Sdim    assert(!IsSubroutine(context) || context == function);
3756321369Sdim    if (DWARFDIE child = FindAnyChildWithAbstractOrigin(context)) {
3757321369Sdim      return child;
3758321369Sdim    }
3759321369Sdim  }
3760321369Sdim  return DWARFDIE();
3761321369Sdim}
3762321369Sdim
3763321369Sdimclang::DeclContext *
3764321369SdimDWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) {
3765321369Sdim  assert(die.Tag() == DW_TAG_lexical_block);
3766321369Sdim  DWARFDIE containing_function_with_abstract_origin =
3767321369Sdim      GetContainingFunctionWithAbstractOrigin(die);
3768321369Sdim  if (!containing_function_with_abstract_origin) {
3769321369Sdim    return (clang::DeclContext *)ResolveBlockDIE(die);
3770321369Sdim  }
3771321369Sdim  DWARFDIE child = FindFirstChildWithAbstractOrigin(
3772321369Sdim      die, containing_function_with_abstract_origin);
3773321369Sdim  CompilerDeclContext decl_context =
3774321369Sdim      GetDeclContextContainingUIDFromDWARF(child);
3775321369Sdim  return (clang::DeclContext *)decl_context.GetOpaqueDeclContext();
3776321369Sdim}
3777321369Sdim
3778314564Sdimclang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
3779314564Sdim  if (die && die.Tag() == DW_TAG_lexical_block) {
3780314564Sdim    clang::BlockDecl *decl =
3781314564Sdim        llvm::cast_or_null<clang::BlockDecl>(m_die_to_decl_ctx[die.GetDIE()]);
3782292932Sdim
3783314564Sdim    if (!decl) {
3784314564Sdim      DWARFDIE decl_context_die;
3785314564Sdim      clang::DeclContext *decl_context =
3786314564Sdim          GetClangDeclContextContainingDIE(die, &decl_context_die);
3787314564Sdim      decl = m_ast.CreateBlockDeclaration(decl_context);
3788292932Sdim
3789314564Sdim      if (decl)
3790314564Sdim        LinkDeclContextToDIE((clang::DeclContext *)decl, die);
3791314564Sdim    }
3792292932Sdim
3793314564Sdim    return decl;
3794314564Sdim  }
3795314564Sdim  return nullptr;
3796292932Sdim}
3797292932Sdim
3798292932Sdimclang::NamespaceDecl *
3799314564SdimDWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) {
3800314564Sdim  if (die && die.Tag() == DW_TAG_namespace) {
3801314564Sdim    // See if we already parsed this namespace DIE and associated it with a
3802314564Sdim    // uniqued namespace declaration
3803314564Sdim    clang::NamespaceDecl *namespace_decl =
3804314564Sdim        static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die.GetDIE()]);
3805314564Sdim    if (namespace_decl)
3806314564Sdim      return namespace_decl;
3807314564Sdim    else {
3808314564Sdim      const char *namespace_name = die.GetName();
3809314564Sdim      clang::DeclContext *containing_decl_ctx =
3810314564Sdim          GetClangDeclContextContainingDIE(die, nullptr);
3811314564Sdim      namespace_decl = m_ast.GetUniqueNamespaceDeclaration(namespace_name,
3812314564Sdim                                                           containing_decl_ctx);
3813314564Sdim      Log *log =
3814314564Sdim          nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
3815314564Sdim      if (log) {
3816314564Sdim        SymbolFileDWARF *dwarf = die.GetDWARF();
3817314564Sdim        if (namespace_name) {
3818314564Sdim          dwarf->GetObjectFile()->GetModule()->LogMessage(
3819314564Sdim              log, "ASTContext => %p: 0x%8.8" PRIx64
3820314564Sdim                   ": DW_TAG_namespace with DW_AT_name(\"%s\") => "
3821314564Sdim                   "clang::NamespaceDecl *%p (original = %p)",
3822314564Sdim              static_cast<void *>(m_ast.getASTContext()), die.GetID(),
3823314564Sdim              namespace_name, static_cast<void *>(namespace_decl),
3824314564Sdim              static_cast<void *>(namespace_decl->getOriginalNamespace()));
3825314564Sdim        } else {
3826314564Sdim          dwarf->GetObjectFile()->GetModule()->LogMessage(
3827314564Sdim              log, "ASTContext => %p: 0x%8.8" PRIx64
3828314564Sdim                   ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p "
3829314564Sdim                   "(original = %p)",
3830314564Sdim              static_cast<void *>(m_ast.getASTContext()), die.GetID(),
3831314564Sdim              static_cast<void *>(namespace_decl),
3832314564Sdim              static_cast<void *>(namespace_decl->getOriginalNamespace()));
3833314564Sdim        }
3834314564Sdim      }
3835292932Sdim
3836314564Sdim      if (namespace_decl)
3837314564Sdim        LinkDeclContextToDIE((clang::DeclContext *)namespace_decl, die);
3838314564Sdim      return namespace_decl;
3839292932Sdim    }
3840314564Sdim  }
3841314564Sdim  return nullptr;
3842292932Sdim}
3843292932Sdim
3844314564Sdimclang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE(
3845314564Sdim    const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) {
3846314564Sdim  SymbolFileDWARF *dwarf = die.GetDWARF();
3847292932Sdim
3848314564Sdim  DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die);
3849292932Sdim
3850314564Sdim  if (decl_ctx_die_copy)
3851314564Sdim    *decl_ctx_die_copy = decl_ctx_die;
3852292932Sdim
3853314564Sdim  if (decl_ctx_die) {
3854314564Sdim    clang::DeclContext *clang_decl_ctx =
3855314564Sdim        GetClangDeclContextForDIE(decl_ctx_die);
3856314564Sdim    if (clang_decl_ctx)
3857314564Sdim      return clang_decl_ctx;
3858314564Sdim  }
3859314564Sdim  return m_ast.GetTranslationUnitDecl();
3860292932Sdim}
3861292932Sdim
3862292932Sdimclang::DeclContext *
3863314564SdimDWARFASTParserClang::GetCachedClangDeclContextForDIE(const DWARFDIE &die) {
3864314564Sdim  if (die) {
3865314564Sdim    DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find(die.GetDIE());
3866314564Sdim    if (pos != m_die_to_decl_ctx.end())
3867314564Sdim      return pos->second;
3868314564Sdim  }
3869314564Sdim  return nullptr;
3870292932Sdim}
3871292932Sdim
3872314564Sdimvoid DWARFASTParserClang::LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
3873314564Sdim                                               const DWARFDIE &die) {
3874314564Sdim  m_die_to_decl_ctx[die.GetDIE()] = decl_ctx;
3875314564Sdim  // There can be many DIEs for a single decl context
3876314564Sdim  // m_decl_ctx_to_die[decl_ctx].insert(die.GetDIE());
3877314564Sdim  m_decl_ctx_to_die.insert(std::make_pair(decl_ctx, die));
3878292932Sdim}
3879292932Sdim
3880314564Sdimbool DWARFASTParserClang::CopyUniqueClassMethodTypes(
3881314564Sdim    const DWARFDIE &src_class_die, const DWARFDIE &dst_class_die,
3882314564Sdim    lldb_private::Type *class_type, DWARFDIECollection &failures) {
3883314564Sdim  if (!class_type || !src_class_die || !dst_class_die)
3884314564Sdim    return false;
3885314564Sdim  if (src_class_die.Tag() != dst_class_die.Tag())
3886314564Sdim    return false;
3887292932Sdim
3888314564Sdim  // We need to complete the class type so we can get all of the method types
3889314564Sdim  // parsed so we can then unique those types to their equivalent counterparts
3890314564Sdim  // in "dst_cu" and "dst_class_die"
3891314564Sdim  class_type->GetFullCompilerType();
3892292932Sdim
3893314564Sdim  DWARFDIE src_die;
3894314564Sdim  DWARFDIE dst_die;
3895314564Sdim  UniqueCStringMap<DWARFDIE> src_name_to_die;
3896314564Sdim  UniqueCStringMap<DWARFDIE> dst_name_to_die;
3897314564Sdim  UniqueCStringMap<DWARFDIE> src_name_to_die_artificial;
3898314564Sdim  UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial;
3899314564Sdim  for (src_die = src_class_die.GetFirstChild(); src_die.IsValid();
3900314564Sdim       src_die = src_die.GetSibling()) {
3901314564Sdim    if (src_die.Tag() == DW_TAG_subprogram) {
3902314564Sdim      // Make sure this is a declaration and not a concrete instance by looking
3903314564Sdim      // for DW_AT_declaration set to 1. Sometimes concrete function instances
3904314564Sdim      // are placed inside the class definitions and shouldn't be included in
3905314564Sdim      // the list of things are are tracking here.
3906314564Sdim      if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
3907314564Sdim        const char *src_name = src_die.GetMangledName();
3908314564Sdim        if (src_name) {
3909314564Sdim          ConstString src_const_name(src_name);
3910314564Sdim          if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
3911321369Sdim            src_name_to_die_artificial.Append(src_const_name, src_die);
3912314564Sdim          else
3913321369Sdim            src_name_to_die.Append(src_const_name, src_die);
3914292932Sdim        }
3915314564Sdim      }
3916292932Sdim    }
3917314564Sdim  }
3918314564Sdim  for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid();
3919314564Sdim       dst_die = dst_die.GetSibling()) {
3920314564Sdim    if (dst_die.Tag() == DW_TAG_subprogram) {
3921314564Sdim      // Make sure this is a declaration and not a concrete instance by looking
3922314564Sdim      // for DW_AT_declaration set to 1. Sometimes concrete function instances
3923314564Sdim      // are placed inside the class definitions and shouldn't be included in
3924314564Sdim      // the list of things are are tracking here.
3925314564Sdim      if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) {
3926314564Sdim        const char *dst_name = dst_die.GetMangledName();
3927314564Sdim        if (dst_name) {
3928314564Sdim          ConstString dst_const_name(dst_name);
3929314564Sdim          if (dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0))
3930321369Sdim            dst_name_to_die_artificial.Append(dst_const_name, dst_die);
3931314564Sdim          else
3932321369Sdim            dst_name_to_die.Append(dst_const_name, dst_die);
3933292932Sdim        }
3934314564Sdim      }
3935292932Sdim    }
3936314564Sdim  }
3937314564Sdim  const uint32_t src_size = src_name_to_die.GetSize();
3938314564Sdim  const uint32_t dst_size = dst_name_to_die.GetSize();
3939314564Sdim  Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO |
3940314564Sdim                      // DWARF_LOG_TYPE_COMPLETION));
3941292932Sdim
3942314564Sdim  // Is everything kosher so we can go through the members at top speed?
3943314564Sdim  bool fast_path = true;
3944292932Sdim
3945314564Sdim  if (src_size != dst_size) {
3946314564Sdim    if (src_size != 0 && dst_size != 0) {
3947314564Sdim      if (log)
3948314564Sdim        log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, "
3949314564Sdim                    "but they didn't have the same size (src=%d, dst=%d)",
3950314564Sdim                    src_class_die.GetOffset(), dst_class_die.GetOffset(),
3951314564Sdim                    src_size, dst_size);
3952292932Sdim    }
3953292932Sdim
3954314564Sdim    fast_path = false;
3955314564Sdim  }
3956292932Sdim
3957314564Sdim  uint32_t idx;
3958292932Sdim
3959314564Sdim  if (fast_path) {
3960314564Sdim    for (idx = 0; idx < src_size; ++idx) {
3961314564Sdim      src_die = src_name_to_die.GetValueAtIndexUnchecked(idx);
3962314564Sdim      dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
3963292932Sdim
3964314564Sdim      if (src_die.Tag() != dst_die.Tag()) {
3965314564Sdim        if (log)
3966314564Sdim          log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
3967314564Sdim                      "but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
3968314564Sdim                      src_class_die.GetOffset(), dst_class_die.GetOffset(),
3969314564Sdim                      src_die.GetOffset(), src_die.GetTagAsCString(),
3970314564Sdim                      dst_die.GetOffset(), dst_die.GetTagAsCString());
3971314564Sdim        fast_path = false;
3972314564Sdim      }
3973292932Sdim
3974314564Sdim      const char *src_name = src_die.GetMangledName();
3975314564Sdim      const char *dst_name = dst_die.GetMangledName();
3976292932Sdim
3977314564Sdim      // Make sure the names match
3978314564Sdim      if (src_name == dst_name || (strcmp(src_name, dst_name) == 0))
3979314564Sdim        continue;
3980292932Sdim
3981314564Sdim      if (log)
3982314564Sdim        log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, "
3983314564Sdim                    "but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
3984314564Sdim                    src_class_die.GetOffset(), dst_class_die.GetOffset(),
3985314564Sdim                    src_die.GetOffset(), src_name, dst_die.GetOffset(),
3986314564Sdim                    dst_name);
3987314564Sdim
3988314564Sdim      fast_path = false;
3989292932Sdim    }
3990314564Sdim  }
3991292932Sdim
3992314564Sdim  DWARFASTParserClang *src_dwarf_ast_parser =
3993314564Sdim      (DWARFASTParserClang *)src_die.GetDWARFParser();
3994314564Sdim  DWARFASTParserClang *dst_dwarf_ast_parser =
3995314564Sdim      (DWARFASTParserClang *)dst_die.GetDWARFParser();
3996292932Sdim
3997314564Sdim  // Now do the work of linking the DeclContexts and Types.
3998314564Sdim  if (fast_path) {
3999314564Sdim    // We can do this quickly.  Just run across the tables index-for-index since
4000314564Sdim    // we know each node has matching names and tags.
4001314564Sdim    for (idx = 0; idx < src_size; ++idx) {
4002314564Sdim      src_die = src_name_to_die.GetValueAtIndexUnchecked(idx);
4003314564Sdim      dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
4004292932Sdim
4005314564Sdim      clang::DeclContext *src_decl_ctx =
4006314564Sdim          src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
4007314564Sdim      if (src_decl_ctx) {
4008314564Sdim        if (log)
4009314564Sdim          log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
4010314564Sdim                      static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
4011314564Sdim                      dst_die.GetOffset());
4012314564Sdim        dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
4013314564Sdim      } else {
4014314564Sdim        if (log)
4015314564Sdim          log->Printf("warning: tried to unique decl context from 0x%8.8x for "
4016314564Sdim                      "0x%8.8x, but none was found",
4017314564Sdim                      src_die.GetOffset(), dst_die.GetOffset());
4018314564Sdim      }
4019292932Sdim
4020314564Sdim      Type *src_child_type =
4021314564Sdim          dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
4022314564Sdim      if (src_child_type) {
4023314564Sdim        if (log)
4024314564Sdim          log->Printf(
4025314564Sdim              "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
4026314564Sdim              static_cast<void *>(src_child_type), src_child_type->GetID(),
4027314564Sdim              src_die.GetOffset(), dst_die.GetOffset());
4028314564Sdim        dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
4029314564Sdim      } else {
4030314564Sdim        if (log)
4031314564Sdim          log->Printf("warning: tried to unique lldb_private::Type from "
4032314564Sdim                      "0x%8.8x for 0x%8.8x, but none was found",
4033314564Sdim                      src_die.GetOffset(), dst_die.GetOffset());
4034314564Sdim      }
4035292932Sdim    }
4036314564Sdim  } else {
4037314564Sdim    // We must do this slowly.  For each member of the destination, look
4038314564Sdim    // up a member in the source with the same name, check its tag, and
4039314564Sdim    // unique them if everything matches up.  Report failures.
4040292932Sdim
4041314564Sdim    if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty()) {
4042314564Sdim      src_name_to_die.Sort();
4043292932Sdim
4044314564Sdim      for (idx = 0; idx < dst_size; ++idx) {
4045321369Sdim        ConstString dst_name = dst_name_to_die.GetCStringAtIndex(idx);
4046314564Sdim        dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
4047314564Sdim        src_die = src_name_to_die.Find(dst_name, DWARFDIE());
4048292932Sdim
4049314564Sdim        if (src_die && (src_die.Tag() == dst_die.Tag())) {
4050314564Sdim          clang::DeclContext *src_decl_ctx =
4051314564Sdim              src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
4052314564Sdim          if (src_decl_ctx) {
4053314564Sdim            if (log)
4054314564Sdim              log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
4055314564Sdim                          static_cast<void *>(src_decl_ctx),
4056314564Sdim                          src_die.GetOffset(), dst_die.GetOffset());
4057314564Sdim            dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
4058314564Sdim          } else {
4059314564Sdim            if (log)
4060314564Sdim              log->Printf("warning: tried to unique decl context from 0x%8.8x "
4061314564Sdim                          "for 0x%8.8x, but none was found",
4062314564Sdim                          src_die.GetOffset(), dst_die.GetOffset());
4063314564Sdim          }
4064292932Sdim
4065314564Sdim          Type *src_child_type =
4066314564Sdim              dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
4067314564Sdim          if (src_child_type) {
4068314564Sdim            if (log)
4069314564Sdim              log->Printf("uniquing type %p (uid=0x%" PRIx64
4070314564Sdim                          ") from 0x%8.8x for 0x%8.8x",
4071314564Sdim                          static_cast<void *>(src_child_type),
4072314564Sdim                          src_child_type->GetID(), src_die.GetOffset(),
4073314564Sdim                          dst_die.GetOffset());
4074314564Sdim            dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] =
4075314564Sdim                src_child_type;
4076314564Sdim          } else {
4077314564Sdim            if (log)
4078314564Sdim              log->Printf("warning: tried to unique lldb_private::Type from "
4079314564Sdim                          "0x%8.8x for 0x%8.8x, but none was found",
4080314564Sdim                          src_die.GetOffset(), dst_die.GetOffset());
4081314564Sdim          }
4082314564Sdim        } else {
4083314564Sdim          if (log)
4084314564Sdim            log->Printf("warning: couldn't find a match for 0x%8.8x",
4085314564Sdim                        dst_die.GetOffset());
4086292932Sdim
4087314564Sdim          failures.Append(dst_die);
4088292932Sdim        }
4089314564Sdim      }
4090292932Sdim    }
4091314564Sdim  }
4092292932Sdim
4093314564Sdim  const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize();
4094314564Sdim  const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize();
4095292932Sdim
4096314564Sdim  if (src_size_artificial && dst_size_artificial) {
4097314564Sdim    dst_name_to_die_artificial.Sort();
4098292932Sdim
4099314564Sdim    for (idx = 0; idx < src_size_artificial; ++idx) {
4100321369Sdim      ConstString src_name_artificial =
4101314564Sdim          src_name_to_die_artificial.GetCStringAtIndex(idx);
4102314564Sdim      src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
4103314564Sdim      dst_die =
4104314564Sdim          dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE());
4105292932Sdim
4106314564Sdim      if (dst_die) {
4107314564Sdim        // Both classes have the artificial types, link them
4108314564Sdim        clang::DeclContext *src_decl_ctx =
4109314564Sdim            src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()];
4110314564Sdim        if (src_decl_ctx) {
4111314564Sdim          if (log)
4112314564Sdim            log->Printf("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
4113314564Sdim                        static_cast<void *>(src_decl_ctx), src_die.GetOffset(),
4114314564Sdim                        dst_die.GetOffset());
4115314564Sdim          dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die);
4116314564Sdim        } else {
4117314564Sdim          if (log)
4118314564Sdim            log->Printf("warning: tried to unique decl context from 0x%8.8x "
4119314564Sdim                        "for 0x%8.8x, but none was found",
4120314564Sdim                        src_die.GetOffset(), dst_die.GetOffset());
4121314564Sdim        }
4122292932Sdim
4123314564Sdim        Type *src_child_type =
4124314564Sdim            dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()];
4125314564Sdim        if (src_child_type) {
4126314564Sdim          if (log)
4127314564Sdim            log->Printf(
4128314564Sdim                "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
4129314564Sdim                static_cast<void *>(src_child_type), src_child_type->GetID(),
4130314564Sdim                src_die.GetOffset(), dst_die.GetOffset());
4131314564Sdim          dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type;
4132314564Sdim        } else {
4133314564Sdim          if (log)
4134314564Sdim            log->Printf("warning: tried to unique lldb_private::Type from "
4135314564Sdim                        "0x%8.8x for 0x%8.8x, but none was found",
4136314564Sdim                        src_die.GetOffset(), dst_die.GetOffset());
4137292932Sdim        }
4138314564Sdim      }
4139292932Sdim    }
4140314564Sdim  }
4141292932Sdim
4142314564Sdim  if (dst_size_artificial) {
4143314564Sdim    for (idx = 0; idx < dst_size_artificial; ++idx) {
4144321369Sdim      ConstString dst_name_artificial =
4145314564Sdim          dst_name_to_die_artificial.GetCStringAtIndex(idx);
4146314564Sdim      dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx);
4147314564Sdim      if (log)
4148314564Sdim        log->Printf("warning: need to create artificial method for 0x%8.8x for "
4149314564Sdim                    "method '%s'",
4150321369Sdim                    dst_die.GetOffset(), dst_name_artificial.GetCString());
4151292932Sdim
4152314564Sdim      failures.Append(dst_die);
4153292932Sdim    }
4154314564Sdim  }
4155292932Sdim
4156314564Sdim  return (failures.Size() != 0);
4157292932Sdim}
4158