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