diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 53084a57cae3..8282b43c198a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -555,43 +555,32 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, // and clang isn't good and sharing the stack space for variables in different blocks. std::unique_ptr unique_ast_entry_ap(new UniqueDWARFASTType()); + ConstString unique_typename(type_name_const_str); + Declaration unique_decl(decl); + if (type_name_const_str) { LanguageType die_language = die.GetLanguage(); - bool handled = false; if (Language::LanguageIsCPlusPlus(die_language)) { + // For C++, we rely solely upon the one definition rule that says only + // one thing can exist at a given decl context. We ignore the file and + // line that things are declared on. std::string qualified_name; if (die.GetQualifiedName(qualified_name)) - { - handled = true; - ConstString const_qualified_name(qualified_name); - if (dwarf->GetUniqueDWARFASTTypeMap().Find(const_qualified_name, die, Declaration(), - byte_size_valid ? byte_size : -1, - *unique_ast_entry_ap)) - { - type_sp = unique_ast_entry_ap->m_type_sp; - if (type_sp) - { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - return type_sp; - } - } - } + unique_typename = ConstString(qualified_name); + unique_decl.Clear(); } - if (!handled) + if (dwarf->GetUniqueDWARFASTTypeMap().Find(unique_typename, die, unique_decl, + byte_size_valid ? byte_size : -1, + *unique_ast_entry_ap)) { - if (dwarf->GetUniqueDWARFASTTypeMap().Find(type_name_const_str, die, decl, - byte_size_valid ? byte_size : -1, - *unique_ast_entry_ap)) + type_sp = unique_ast_entry_ap->m_type_sp; + if (type_sp) { - type_sp = unique_ast_entry_ap->m_type_sp; - if (type_sp) - { - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - return type_sp; - } + dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); + return type_sp; } } } @@ -822,9 +811,9 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, // and over in the ASTContext for our module unique_ast_entry_ap->m_type_sp = type_sp; unique_ast_entry_ap->m_die = die; - unique_ast_entry_ap->m_declaration = decl; + unique_ast_entry_ap->m_declaration = unique_decl; unique_ast_entry_ap->m_byte_size = byte_size; - dwarf->GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, + dwarf->GetUniqueDWARFASTTypeMap().Insert (unique_typename, *unique_ast_entry_ap); if (is_forward_declaration && die.HasChildren()) @@ -1069,6 +1058,7 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, bool is_virtual = false; bool is_explicit = false; bool is_artificial = false; + bool has_template_params = false; DWARFFormValue specification_die_form; DWARFFormValue abstract_origin_die_form; dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET; @@ -1193,11 +1183,13 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (die, &decl_ctx_die); const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind(); - const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind); + bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind); // Start off static. This will be set to false in ParseChildParameters(...) // if we find a "this" parameters as the first parameter if (is_cxx_method) + { is_static = true; + } if (die.HasChildren()) { @@ -1208,11 +1200,26 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, skip_artificial, is_static, is_variadic, + has_template_params, function_param_types, function_param_decls, type_quals); } + bool ignore_containing_context = false; + // Check for templatized class member functions. If we had any DW_TAG_template_type_parameter + // or DW_TAG_template_value_parameter the DW_TAG_subprogram DIE, then we can't let this become + // a method in a class. Why? Because templatized functions are only emitted if one of the + // templatized methods is used in the current compile unit and we will end up with classes + // that may or may not include these member functions and this means one class won't match another + // class definition and it affects our ability to use a class in the clang expression parser. So + // for the greater good, we currently must not allow any template member functions in a class definition. +// if (is_cxx_method && has_template_params) +// { +// ignore_containing_context = true; +// is_cxx_method = false; +// } + // clang_type will get the function prototype clang type after this call clang_type = m_ast.CreateFunctionType (return_clang_type, function_param_types.data(), @@ -1220,7 +1227,6 @@ DWARFASTParserClang::ParseTypeFromDWARF (const SymbolContext& sc, is_variadic, type_quals); - bool ignore_containing_context = false; if (type_name_cstr) { @@ -1980,6 +1986,10 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) { + SymbolFileDWARF *dwarf = die.GetDWARF(); + + lldb_private::Mutex::Locker locker(dwarf->GetObjectFile()->GetModule()->GetMutex()); + // Disable external storage for this type so we don't get anymore // clang::ExternalASTSource queries for this type. m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), false); @@ -1989,8 +1999,6 @@ DWARFASTParserClang::CompleteTypeFromDWARF (const DWARFDIE &die, const dw_tag_t tag = die.Tag(); - SymbolFileDWARF *dwarf = die.GetDWARF(); - Log *log = nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION)); if (log) dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log, @@ -2507,6 +2515,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc, // never mangled. bool is_static = false; bool is_variadic = false; + bool has_template_params = false; unsigned type_quals = 0; std::vector param_types; std::vector param_decls; @@ -2523,6 +2532,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF (const SymbolContext& sc, true, is_static, is_variadic, + has_template_params, param_types, param_decls, type_quals); @@ -3189,6 +3199,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc, bool skip_artificial, bool &is_static, bool &is_variadic, + bool &has_template_params, std::vector& function_param_types, std::vector& function_param_decls, unsigned &type_quals) @@ -3347,6 +3358,7 @@ DWARFASTParserClang::ParseChildParameters (const SymbolContext& sc, // in SymbolFileDWARF::ParseType() so this was removed. If we ever need // the template params back, we can add them back. // ParseTemplateDIE (dwarf_cu, die, template_param_infos); + has_template_params = true; break; default: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 3814758fdd2c..bd8325028d9e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -133,6 +133,7 @@ protected: bool skip_artificial, bool &is_static, bool &is_variadic, + bool &has_template_params, std::vector& function_args, std::vector& function_param_decls, unsigned &type_quals); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 287b22886fa4..b23836433c7a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1623,6 +1623,8 @@ SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &compiler_type) bool SymbolFileDWARF::CompleteType (CompilerType &compiler_type) { + lldb_private::Mutex::Locker locker(GetObjectFile()->GetModule()->GetMutex()); + TypeSystem *type_system = compiler_type.GetTypeSystem(); if (type_system) {