summaryrefslogtreecommitdiffstats
path: root/lldb/source/Expression/IRForTarget.cpp
diff options
context:
space:
mode:
authorSiva Chandra <sivachandra@google.com>2015-04-09 18:48:34 +0000
committerSiva Chandra <sivachandra@google.com>2015-04-09 18:48:34 +0000
commit0f404e057501728e819a8955c893fb4b772ba97f (patch)
tree0f3630849d40921eea8787cb51d442366e2c9c90 /lldb/source/Expression/IRForTarget.cpp
parent10821e5283fd190c8ff38dcad8b5e2a2fcdc4e5a (diff)
downloadbcm5719-llvm-0f404e057501728e819a8955c893fb4b772ba97f.tar.gz
bcm5719-llvm-0f404e057501728e819a8955c893fb4b772ba97f.zip
[IRForTarget] Strenghten handling of alternate mangling.
Summary: This fixes an issue with GCC generated binaries wherein an expression with method invocations on std::string variables was failing. Such use cases are tested in TestSTL (albeit, in a test marked with @unittest2.expectedFailure because of other reasons). The reason for this particular failure with GCC is that the generated DWARF for std::basic_string<...> is incomplete, which makes clang not to use the alternate mangling scheme. GCC correctly generates the name of basic_string<...>: DW_AT_name "basic_string<char, std::char_traits<char>, std::allocator<char> >" It also lists the template parameters of basic_string correctly: DW_TAG_template_type_parameter DW_AT_name "_CharT" DW_AT_type <0x0000009c> DW_TAG_template_type_parameter DW_AT_name "_Traits" DW_AT_type <0x00000609> DW_TAG_template_type_parameter DW_AT_name "_Alloc" DW_AT_type <0x000007fb> However, it does not list the template parameters of std::char_traits<>. This makes Clang feel (while parsing the expression) that the string variable is not actually a basic_string instance, and consequently does not use the alternate mangling scheme. Test Plan: dotest.py -C gcc -p TestSTL -- See it go past the "for" loop expression successfully. Reviewers: clayborg, spyffe Reviewed By: clayborg, spyffe Subscribers: tberghammer, zturner, lldb-commits Differential Revision: http://reviews.llvm.org/D8846 llvm-svn: 234522
Diffstat (limited to 'lldb/source/Expression/IRForTarget.cpp')
-rw-r--r--lldb/source/Expression/IRForTarget.cpp51
1 files changed, 25 insertions, 26 deletions
diff --git a/lldb/source/Expression/IRForTarget.cpp b/lldb/source/Expression/IRForTarget.cpp
index f5cfb782c48..210ba65f665 100644
--- a/lldb/source/Expression/IRForTarget.cpp
+++ b/lldb/source/Expression/IRForTarget.cpp
@@ -35,6 +35,7 @@
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
#include <map>
@@ -226,44 +227,42 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
{
if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
{
- lldb_private::ConstString altnernate_name;
+ std::vector<lldb_private::ConstString> alternates;
bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
if (!found_it)
{
- // Check for an alternate mangling for "std::basic_string<char>"
- // that is part of the itanium C++ name mangling scheme
- const char *name_cstr = name.GetCString();
- if (name_cstr && strncmp(name_cstr, "_ZNKSbIcE", strlen("_ZNKSbIcE")) == 0)
+ 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();
+ lldb_private::CPPLanguageRuntime *cpp_runtime = process_sp->GetCPPLanguageRuntime();
+ if (cpp_runtime && cpp_runtime->GetAlternateManglings(name, alternates))
{
- std::string alternate_mangling("_ZNKSs");
- alternate_mangling.append (name_cstr + strlen("_ZNKSbIcE"));
- altnernate_name.SetCString(alternate_mangling.c_str());
- found_it = m_decl_map->GetFunctionAddress (altnernate_name, fun_addr);
+ 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)
{
lldb_private::Mangled mangled_name(name);
- lldb_private::Mangled alt_mangled_name(altnernate_name);
- if (log)
- {
- if (alt_mangled_name)
- log->Printf("Function \"%s\" (alternate name \"%s\") has no address",
- mangled_name.GetName().GetCString(),
- alt_mangled_name.GetName().GetCString());
- else
- log->Printf("Function \"%s\" had no address",
- mangled_name.GetName().GetCString());
- }
-
if (m_error_stream)
{
- if (alt_mangled_name)
- m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n",
- mangled_name.GetName().GetCString(),
- alt_mangled_name.GetName().GetCString());
- else if (mangled_name.GetMangledName())
+ if (mangled_name.GetMangledName())
m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n",
mangled_name.GetName().GetCString(),
mangled_name.GetMangledName().GetCString());
OpenPOWER on IntegriCloud