diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -206,7 +206,7 @@ TypePayloadClang(GetOwningClangModule(die)))); dwarf->GetTypeList().Insert(type_sp); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp; clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type); if (tag_decl) { LinkDeclContextToDIE(tag_decl, die); @@ -434,20 +434,21 @@ die.GetTagAsCString(), die.GetName()); } - Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE()); - if (type_ptr == DIE_IS_BEING_PARSED) - return nullptr; - if (type_ptr) - return type_ptr->shared_from_this(); + if (auto type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE())) { + if (type_ptr.get() == SymbolFileDWARF::GetSentinelDieBeingParsed().get()) + return nullptr; + return type_ptr; + } // Set a bit that lets us know that we are currently parsing this - dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED; + dwarf->GetDIEToType()[die.GetDIE()] = + SymbolFileDWARF::GetSentinelDieBeingParsed(); ParsedDWARFTypeAttributes attrs(die); if (DWARFDIE signature_die = attrs.signature.Reference()) { if (TypeSP type_sp = ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp; if (clang::DeclContext *decl_ctx = GetCachedClangDeclContextForDIE(signature_die)) LinkDeclContextToDIE(decl_ctx, die); @@ -737,7 +738,7 @@ dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl, clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die))); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp; return type_sp; } @@ -810,7 +811,7 @@ // We found a real definition for this type elsewhere so lets use // it and cache the fact that we found a complete type for this // die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp; clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID())); if (defn_decl_ctx) @@ -1063,10 +1064,10 @@ // Unfortunately classes don't like having stuff added // to them after their definitions are complete... - Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; - if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { - return type_ptr->shared_from_this(); - } + if (auto type_sp = dwarf->GetDIEToType()[die.GetDIE()]) + if (type_sp.get() != + SymbolFileDWARF::GetSentinelDieBeingParsed().get()) + return type_sp; } } @@ -1179,7 +1180,7 @@ // we need to modify the dwarf->GetDIEToType() so it // doesn't think we are trying to parse this DIE // anymore... - dwarf->GetDIEToType()[die.GetDIE()] = NULL; + dwarf->GetDIEToType().erase(die.GetDIE()); // Now we get the full type to force our class type to // complete itself using the clang::ExternalASTSource @@ -1189,10 +1190,10 @@ // The type for this DIE should have been filled in the // function call above - Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()]; - if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) { - return type_ptr->shared_from_this(); - } + if (auto type_sp = dwarf->GetDIEToType()[die.GetDIE()]) + if (type_sp.get() != + SymbolFileDWARF::GetSentinelDieBeingParsed().get()) + return type_sp; // FIXME This is fixing some even uglier behavior but we // really need to @@ -1528,7 +1529,7 @@ if (symbol_context_scope != nullptr) type_sp->SetSymbolContextScope(symbol_context_scope); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp; return type_sp; } @@ -1623,7 +1624,7 @@ *unique_ast_entry_up)) { type_sp = unique_ast_entry_up->m_type_sp; if (type_sp) { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp; LinkDeclContextToDIE( GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die); return type_sp; @@ -1699,7 +1700,7 @@ // We found a real definition for this type elsewhere so lets use // it and cache the fact that we found a complete type for this // die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp; return type_sp; } } @@ -1752,7 +1753,7 @@ // We found a real definition for this type elsewhere so lets use // it and cache the fact that we found a complete type for this die - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + dwarf->GetDIEToType()[die.GetDIE()] = type_sp; clang::DeclContext *defn_decl_ctx = GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID())); if (defn_decl_ctx) @@ -2447,15 +2448,17 @@ SymbolFileDWARF *dwarf = die.GetDWARF(); // Supply the type _only_ if it has already been parsed - Type *func_type = dwarf->GetDIEToType().lookup(die.GetDIE()); + auto func_type_sp = dwarf->GetDIEToType().lookup(die.GetDIE()); - assert(func_type == nullptr || func_type != DIE_IS_BEING_PARSED); + assert(func_type_sp == nullptr || + func_type_sp.get() != + SymbolFileDWARF::GetSentinelDieBeingParsed().get()); const user_id_t func_user_id = die.GetID(); func_sp = std::make_shared(&comp_unit, func_user_id, // UserID is the DIE offset - func_user_id, func_name, func_type, + func_user_id, func_name, func_type_sp.get(), func_range); // first address range if (func_sp.get() != nullptr) { @@ -3603,7 +3606,7 @@ if (dst_decl_ctx) src_dwarf_ast_parser->LinkDeclContextToDIE(dst_decl_ctx, src); - if (Type *src_child_type = die_to_type[src.GetDIE()]) + if (auto src_child_type = die_to_type[src.GetDIE()]) die_to_type[dst.GetDIE()] = src_child_type; }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -56,7 +56,6 @@ class SymbolFileDWARFDwo; class SymbolFileDWARFDwp; -#define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) class SymbolFileDWARF : public lldb_private::SymbolFileCommon, public lldb_private::UserID { @@ -233,6 +232,10 @@ static bool SupportedVersion(uint16_t version); + /// Returns a sentinel pointer that indicates that a DIE is being + /// parsed into a type. + static std::shared_ptr GetSentinelDieBeingParsed(); + DWARFDIE GetDeclContextDIEContainingDIE(const DWARFDIE &die); @@ -348,7 +351,8 @@ lldb_private::ConstString ConstructFunctionDemangledName(const DWARFDIE &die); protected: - typedef llvm::DenseMap + typedef llvm::DenseMap> DIEToTypePtr; typedef llvm::DenseMap DIEToVariableSP; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -517,6 +517,13 @@ return version >= 2 && version <= 5; } +std::shared_ptr +SymbolFileDWARF::GetSentinelDieBeingParsed() { + static std::shared_ptr sentinel = + std::make_shared(); + return sentinel; +} + uint32_t SymbolFileDWARF::CalculateAbilities() { uint32_t abilities = 0; if (m_objfile_sp != nullptr) { @@ -1602,17 +1609,18 @@ // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done. GetForwardDeclClangTypeToDie().erase(die_it); - Type *type = GetDIEToType().lookup(dwarf_die.GetDIE()); + auto type_sp = GetDIEToType().lookup(dwarf_die.GetDIE()); Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion); if (log) GetObjectFile()->GetModule()->LogMessageVerboseBacktrace( log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", dwarf_die.GetID(), dwarf_die.GetTagAsCString(), - type->GetName().AsCString()); + type_sp->GetName().AsCString()); assert(compiler_type); if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU())) - return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type); + return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type_sp.get(), + compiler_type); } return false; } @@ -1624,7 +1632,7 @@ Type *type = GetTypeForDIE(die, resolve_function_context).get(); if (assert_not_being_parsed) { - if (type != DIE_IS_BEING_PARSED) + if (type != SymbolFileDWARF::GetSentinelDieBeingParsed().get()) return type; GetObjectFile()->GetModule()->ReportError( @@ -2686,10 +2694,13 @@ TypeSP SymbolFileDWARF::GetTypeForDIE(const DWARFDIE &die, bool resolve_function_context) { - TypeSP type_sp; if (die) { - Type *type_ptr = GetDIEToType().lookup(die.GetDIE()); - if (type_ptr == nullptr) { + if (auto type_sp = GetDIEToType().lookup(die.GetDIE())) { + if (type_sp.get() != + SymbolFileDWARF::GetSentinelDieBeingParsed().get()) { + return type_sp; + } + } else { SymbolContextScope *scope; if (auto *dwarf_cu = llvm::dyn_cast(die.GetCU())) scope = GetCompUnitForDWARFCompUnit(*dwarf_cu); @@ -2708,13 +2719,10 @@ !GetFunction(DWARFDIE(die.GetCU(), parent_die), sc)) sc = sc_backup; - type_sp = ParseType(sc, die, nullptr); - } else if (type_ptr != DIE_IS_BEING_PARSED) { - // Get the original shared pointer for this type - type_sp = type_ptr->shared_from_this(); + return ParseType(sc, die, nullptr); } } - return type_sp; + return nullptr; } DWARFDIE @@ -2850,7 +2858,9 @@ return true; Type *resolved_type = ResolveType(type_die, false, true); - if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) + if (!resolved_type || + resolved_type == + SymbolFileDWARF::GetSentinelDieBeingParsed().get()) return true; DEBUG_PRINTF( @@ -2861,7 +2871,8 @@ type_die.GetID(), type_cu->GetID()); if (die) - GetDIEToType()[die.GetDIE()] = resolved_type; + GetDIEToType()[die.GetDIE()] = + std::make_shared(*resolved_type); type_sp = resolved_type->shared_from_this(); return false; }); @@ -3066,8 +3077,10 @@ return true; Type *resolved_type = ResolveType(type_die, false); - if (!resolved_type || resolved_type == DIE_IS_BEING_PARSED) - return true; + if (!resolved_type || + resolved_type == + SymbolFileDWARF::GetSentinelDieBeingParsed().get()) + return true; // With -gsimple-template-names, the DIE name may not contain the template // parameters. If the declaration has template parameters but doesn't