Index: include/lldb/Symbol/ClangASTContext.h =================================================================== --- include/lldb/Symbol/ClangASTContext.h +++ include/lldb/Symbol/ClangASTContext.h @@ -573,6 +573,9 @@ ConstString DeclContextGetName (void *opaque_decl_ctx) override; + ConstString + DeclContextGetScopeQualifiedName (void *opaque_decl_ctx) override; + bool DeclContextIsClassMethod (void *opaque_decl_ctx, lldb::LanguageType *language_ptr, Index: include/lldb/Symbol/CompilerDeclContext.h =================================================================== --- include/lldb/Symbol/CompilerDeclContext.h +++ include/lldb/Symbol/CompilerDeclContext.h @@ -128,6 +128,9 @@ ConstString GetName () const; + ConstString + GetScopeQualifiedName() const; + bool IsStructUnionOrClass () const; Index: include/lldb/Symbol/GoASTContext.h =================================================================== --- include/lldb/Symbol/GoASTContext.h +++ include/lldb/Symbol/GoASTContext.h @@ -112,6 +112,12 @@ return ConstString(); } + ConstString + DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override + { + return ConstString(); + } + bool DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr, bool *is_instance_method_ptr, ConstString *language_object_name_ptr) override Index: include/lldb/Symbol/SymbolFile.h =================================================================== --- include/lldb/Symbol/SymbolFile.h +++ include/lldb/Symbol/SymbolFile.h @@ -144,6 +144,7 @@ virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types); virtual size_t FindTypes (const std::vector &context, bool append, TypeMap& types); + virtual void GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector &mangled_names); // virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0; virtual TypeList * GetTypeList (); virtual size_t GetTypes (lldb_private::SymbolContextScope *sc_scope, Index: include/lldb/Symbol/TypeSystem.h =================================================================== --- include/lldb/Symbol/TypeSystem.h +++ include/lldb/Symbol/TypeSystem.h @@ -151,6 +151,9 @@ virtual ConstString DeclContextGetName (void *opaque_decl_ctx) = 0; + virtual ConstString + DeclContextGetScopeQualifiedName (void *opaque_decl_ctx) = 0; + virtual bool DeclContextIsClassMethod (void *opaque_decl_ctx, lldb::LanguageType *language_ptr, Index: include/lldb/Target/CPPLanguageRuntime.h =================================================================== --- include/lldb/Target/CPPLanguageRuntime.h +++ include/lldb/Target/CPPLanguageRuntime.h @@ -42,9 +42,6 @@ bool GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) override; - virtual size_t - GetAlternateManglings(const ConstString &mangled, std::vector &alternates) = 0; - protected: //------------------------------------------------------------------ Index: source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -36,6 +36,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeList.h" @@ -570,6 +571,63 @@ } } +ConstString +FindBestAlternateMangledName +( + const ConstString &demangled, + const LanguageType &lang_type, + SymbolContext &sym_ctx +) +{ + CPlusPlusLanguage::MethodName cpp_name(demangled); + std::string scope_qualified_name = cpp_name.GetScopeQualifiedName(); + + if (!scope_qualified_name.size()) + return ConstString(); + + if (!sym_ctx.module_sp) + return ConstString(); + + SymbolVendor *sym_vendor = sym_ctx.module_sp->GetSymbolVendor(); + if (!sym_vendor) + return ConstString(); + + lldb_private::SymbolFile *sym_file = sym_vendor->GetSymbolFile(); + if (!sym_file) + return ConstString(); + + std::vector alternates; + sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates); + + std::vector param_and_qual_matches; + std::vector param_matches; + for (size_t i = 0; i < alternates.size(); i++) + { + ConstString alternate_mangled_name = alternates[i]; + Mangled mangled(alternate_mangled_name, true); + ConstString demangled = mangled.GetDemangledName(lang_type); + + CPlusPlusLanguage::MethodName alternate_cpp_name(demangled); + if (!cpp_name.IsValid()) + continue; + + if (alternate_cpp_name.GetArguments() == cpp_name.GetArguments()) + { + if (alternate_cpp_name.GetQualifiers() == cpp_name.GetQualifiers()) + param_and_qual_matches.push_back(alternate_mangled_name); + else + param_matches.push_back(alternate_mangled_name); + } + } + + if (param_and_qual_matches.size()) + return param_and_qual_matches[0]; // It is assumed that there will be only one! + else if (param_matches.size()) + return param_matches[0]; // Return one of them as a best match + else + return ConstString(); +} + bool ClangExpressionDeclMap::GetFunctionAddress ( @@ -603,15 +661,25 @@ if (Language::LanguageIsCPlusPlus(lang_type) && CPlusPlusLanguage::IsCPPMangledName(name.AsCString())) { - // 1. Demangle the name Mangled mangled(name, true); ConstString demangled = mangled.GetDemangledName(lang_type); if (demangled) { - FindCodeSymbolInContext( - demangled, m_parser_vars->m_sym_ctx, eFunctionNameTypeFull, sc_list); - sc_list_size = sc_list.GetSize(); + ConstString best_alternate_mangled_name = FindBestAlternateMangledName(demangled, lang_type, sc); + if (best_alternate_mangled_name) + { + FindCodeSymbolInContext( + best_alternate_mangled_name, m_parser_vars->m_sym_ctx, eFunctionNameTypeAuto, sc_list); + sc_list_size = sc_list.GetSize(); + } + + if (sc_list_size == 0) + { + FindCodeSymbolInContext( + demangled, m_parser_vars->m_sym_ctx, eFunctionNameTypeFull, sc_list); + sc_list_size = sc_list.GetSize(); + } } } } Index: source/Plugins/ExpressionParser/Clang/IRForTarget.cpp =================================================================== --- source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -36,7 +36,6 @@ #include "lldb/Host/Endian.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompilerType.h" -#include "lldb/Target/CPPLanguageRuntime.h" #include @@ -230,36 +229,6 @@ { std::vector alternates; bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr); - if (!found_it) - { - if (log) - log->Printf("Address of function \"%s\" not found.\n", name.GetCString()); - // Check for an alternate mangling for names from the standard library. - // For example, "std::basic_string<...>" has an alternate mangling scheme per - // the Itanium C++ ABI. - lldb::ProcessSP process_sp = m_data_allocator.GetTarget()->GetProcessSP(); - if (process_sp) - { - lldb_private::CPPLanguageRuntime *cpp_runtime = process_sp->GetCPPLanguageRuntime(); - if (cpp_runtime && cpp_runtime->GetAlternateManglings(name, alternates)) - { - for (size_t i = 0; i < alternates.size(); ++i) - { - const lldb_private::ConstString &alternate_name = alternates[i]; - if (log) - log->Printf("Looking up address of function \"%s\" with alternate name \"%s\"", - name.GetCString(), alternate_name.GetCString()); - if ((found_it = m_decl_map->GetFunctionAddress (alternate_name, fun_addr))) - { - if (log) - log->Printf("Found address of function \"%s\" with alternate name \"%s\"", - name.GetCString(), alternate_name.GetCString()); - break; - } - } - } - } - } if (!found_it) { Index: source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h =================================================================== --- source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -89,6 +89,9 @@ { return m_full; } + + std::string + GetScopeQualifiedName (); llvm::StringRef GetBasename (); Index: source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -296,6 +296,22 @@ return m_qualifiers; } +std::string +CPlusPlusLanguage::MethodName::GetScopeQualifiedName () +{ + if (!m_parsed) + Parse(); + if (m_basename.empty() || m_context.empty()) + return std::string(); + + std::string res; + res += m_context; + res += "::"; + res += m_basename; + + return res; +} + bool CPlusPlusLanguage::IsCPPMangledName (const char *name) { Index: source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h =================================================================== --- source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -80,9 +80,6 @@ lldb::SearchFilterSP CreateExceptionSearchFilter() override; - size_t - GetAlternateManglings(const ConstString &mangled, std::vector &alternates) override; - //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ Index: source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp =================================================================== --- source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -319,46 +319,6 @@ return false; } -static std::map >& -GetAlternateManglingPrefixes() -{ - static std::map > g_alternate_mangling_prefixes; - return g_alternate_mangling_prefixes; -} - - -size_t -ItaniumABILanguageRuntime::GetAlternateManglings(const ConstString &mangled, std::vector &alternates) -{ - if (!mangled) - return static_cast(0); - - alternates.clear(); - const char *mangled_cstr = mangled.AsCString(); - std::map >& alternate_mangling_prefixes = GetAlternateManglingPrefixes(); - for (std::map >::iterator it = alternate_mangling_prefixes.begin(); - it != alternate_mangling_prefixes.end(); - ++it) - { - const char *prefix_cstr = it->first.AsCString(); - if (strncmp(mangled_cstr, prefix_cstr, strlen(prefix_cstr)) == 0) - { - const std::vector &alternate_prefixes = it->second; - for (size_t i = 0; i < alternate_prefixes.size(); ++i) - { - std::string alternate_mangling(alternate_prefixes[i].AsCString()); - alternate_mangling.append(mangled_cstr + strlen(prefix_cstr)); - - alternates.push_back(ConstString(alternate_mangling.c_str())); - } - - return alternates.size(); - } - } - - return static_cast(0); -} - //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ @@ -382,17 +342,6 @@ PluginManager::RegisterPlugin (GetPluginNameStatic(), "Itanium ABI for the C++ language", CreateInstance); - - // Alternate manglings for std::basic_string<...> - std::vector basic_string_alternates; - basic_string_alternates.push_back(ConstString("_ZNSs")); - basic_string_alternates.push_back(ConstString("_ZNKSs")); - std::map >& alternate_mangling_prefixes = GetAlternateManglingPrefixes(); - - alternate_mangling_prefixes[ConstString("_ZNSbIcSt17char_traitsSt15allocatorE")] = - basic_string_alternates; - alternate_mangling_prefixes[ConstString("_ZNKSbIcSt17char_traitsSt15allocatorE")] = - basic_string_alternates; } void Index: source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h =================================================================== --- source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h +++ source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h @@ -207,10 +207,6 @@ void Status(Stream &strm) const; - size_t GetAlternateManglings(const ConstString &mangled, std::vector &alternates) override { - return static_cast(0); - } - void ModulesDidLoad(const ModuleList &module_list) override; bool LoadAllocation(Stream &strm, const uint32_t alloc_id, const char* filename, StackFrame* frame_ptr); Index: source/Plugins/SymbolFile/DWARF/DIERef.h =================================================================== --- source/Plugins/SymbolFile/DWARF/DIERef.h +++ source/Plugins/SymbolFile/DWARF/DIERef.h @@ -33,6 +33,18 @@ lldb::user_id_t GetUID() const; + bool + operator< (const DIERef &ref) const + { + return die_offset < ref.die_offset; + } + + bool + operator< (const DIERef &ref) + { + return die_offset < ref.die_offset; + } + dw_offset_t cu_offset; dw_offset_t die_offset; }; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -208,6 +208,10 @@ bool append, lldb_private::SymbolContextList& sc_list) override; + void + GetMangledNamesForFunction (const std::string &scope_qualified_name, + std::vector &mangled_names) override; + uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, @@ -577,6 +581,9 @@ m_fetched_external_modules:1; lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type; + typedef std::shared_ptr > DIERefSetSP; + typedef std::unordered_map NameToOffsetMap; + NameToOffsetMap m_function_scope_qualified_name_map; std::unique_ptr m_ranges; UniqueDWARFASTTypeMap m_unique_ast_type_map; DIEToTypePtr m_die_to_type; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2927,6 +2927,40 @@ return sc_list.GetSize() - original_size; } +void +SymbolFileDWARF::GetMangledNamesForFunction (const std::string &scope_qualified_name, + std::vector &mangled_names) +{ + DWARFDebugInfo* info = DebugInfo(); + uint32_t num_comp_units = 0; + if (info) + num_comp_units = info->GetNumCompileUnits(); + + for (uint32_t i = 0; i < num_comp_units; i++) + { + DWARFCompileUnit *cu = info->GetCompileUnitAtIndex(i); + if (cu == nullptr) + continue; + + SymbolFileDWARFDwo *dwo = cu->GetDwoSymbolFile(); + if (dwo) + dwo->GetMangledNamesForFunction(scope_qualified_name, mangled_names); + } + + NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name); + if (iter == m_function_scope_qualified_name_map.end()) + return; + + DIERefSetSP set_sp = (*iter).second; + std::set::iterator set_iter; + for (set_iter = set_sp->begin(); set_iter != set_sp->end(); set_iter++) + { + DWARFDIE die = DebugInfo()->GetDIE (*set_iter); + mangled_names.push_back(ConstString(die.GetMangledName())); + } +} + + uint32_t SymbolFileDWARF::FindTypes (const SymbolContext& sc, const ConstString &name, @@ -3751,6 +3785,24 @@ TypeList* type_list = GetTypeList(); if (type_list) type_list->Insert(type_sp); + + if (die.Tag() == DW_TAG_subprogram) + { + DIERef die_ref = die.GetDIERef(); + std::string scope_qualified_name(GetDeclContextForUID(die.GetID()).GetScopeQualifiedName().AsCString("")); + if (scope_qualified_name.size()) + { + NameToOffsetMap::iterator iter = m_function_scope_qualified_name_map.find(scope_qualified_name); + if (iter != m_function_scope_qualified_name_map.end()) + (*iter).second->insert(die_ref); + else + { + DIERefSetSP new_set(new std::set); + new_set->insert(die_ref); + m_function_scope_qualified_name_map.emplace(std::make_pair(scope_qualified_name, new_set)); + } + } + } } } } Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -9969,6 +9969,18 @@ return ConstString(); } +ConstString +ClangASTContext::DeclContextGetScopeQualifiedName (void *opaque_decl_ctx) +{ + if (opaque_decl_ctx) + { + clang::NamedDecl *named_decl = llvm::dyn_cast((clang::DeclContext *)opaque_decl_ctx); + if (named_decl) + return ConstString(llvm::StringRef(named_decl->getQualifiedNameAsString())); + } + return ConstString(); +} + bool ClangASTContext::DeclContextIsClassMethod (void *opaque_decl_ctx, lldb::LanguageType *language_ptr, Index: source/Symbol/CompilerDeclContext.cpp =================================================================== --- source/Symbol/CompilerDeclContext.cpp +++ source/Symbol/CompilerDeclContext.cpp @@ -38,6 +38,15 @@ return ConstString(); } +ConstString +CompilerDeclContext::GetScopeQualifiedName () const +{ + if (IsValid()) + return m_type_system->DeclContextGetScopeQualifiedName(m_opaque_decl_ctx); + else + return ConstString(); +} + bool CompilerDeclContext::IsStructUnionOrClass () const { Index: source/Symbol/SymbolFile.cpp =================================================================== --- source/Symbol/SymbolFile.cpp +++ source/Symbol/SymbolFile.cpp @@ -134,6 +134,12 @@ return 0; } +void +SymbolFile::GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector &mangled_names) +{ + return; +} + uint32_t SymbolFile::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types) {