diff options
author | Siva Chandra <sivachandra@google.com> | 2016-01-07 23:32:34 +0000 |
---|---|---|
committer | Siva Chandra <sivachandra@google.com> | 2016-01-07 23:32:34 +0000 |
commit | 9293fc4185bc737303f0114936ca9a7f467a7bcc (patch) | |
tree | 560f4169d2ce25809c88de274648421ee90282fe /lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp | |
parent | f94c149f7fc52e48a83a59282fbc63834d464ef0 (diff) | |
download | bcm5719-llvm-9293fc4185bc737303f0114936ca9a7f467a7bcc.tar.gz bcm5719-llvm-9293fc4185bc737303f0114936ca9a7f467a7bcc.zip |
Better scheme to lookup alternate mangled name when looking up function address.
Summary:
This change is relevant for inferiors compiled with GCC. GCC does not
emit complete debug info for std::basic_string<...>, and consequently, Clang
(the LLDB compiler) does not generate correct mangled names for certain
functions.
This change removes the hard-coded alternate names in
ItaniumABILanguageRuntime.cpp.
Before the hard-coded names were put in ItaniumABILanguageRuntime.cpp, one could
not evaluate std::string methods (ex. std::string::length). After putting in
the hard-coded names, one could evaluate them. However, it did not still
enable one to call methods on, say for example, std::vector<string>.
This change makes that possible.
There is some amount of incompleteness in this change. Consider the
following example:
std::string hello("hello"), world("world");
std::map<std::string, std::string> m;
m[hello] = world;
One can still not evaluate the expression "m[hello]" in LLDB. Will
address this issue in another pass.
Reviewers: jingham, vharron, evgeny777, spyffe, dawn
Subscribers: clayborg, dawn, lldb-commits
Differential Revision: http://reviews.llvm.org/D12809
llvm-svn: 257113
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp')
-rw-r--r-- | lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp | 76 |
1 files changed, 72 insertions, 4 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index c9bc4b6487c..f4d6b195c7f 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/lldb/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 @@ FindCodeSymbolInContext } } +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<ConstString> alternates; + sym_file->GetMangledNamesForFunction(scope_qualified_name, alternates); + + std::vector<ConstString> param_and_qual_matches; + std::vector<ConstString> 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 @@ ClangExpressionDeclMap::GetFunctionAddress 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(); + } } } } |