[Lldb-commits] [PATCH] [IRForTarget] Strenghten handling of alternate mangling.
Siva Chandra
sivachandra at google.com
Mon Apr 6 14:08:07 PDT 2015
Hi clayborg, spyffe,
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.
http://reviews.llvm.org/D8846
Files:
source/Expression/IRForTarget.cpp
Index: source/Expression/IRForTarget.cpp
===================================================================
--- source/Expression/IRForTarget.cpp
+++ source/Expression/IRForTarget.cpp
@@ -42,6 +42,50 @@
static char ID;
+namespace {
+
+std::map<lldb_private::ConstString, lldb_private::ConstString> std_alternate_mangling_prefixes;
+
+void
+InitStdAlternateManglingPrefixes()
+{
+ if (!std_alternate_mangling_prefixes.empty())
+ return;
+
+ std_alternate_mangling_prefixes[lldb_private::ConstString("_ZNSbIcSt17char_traits<char>St15allocator<char>E")] =
+ lldb_private::ConstString("_ZNSs");
+ std_alternate_mangling_prefixes[lldb_private::ConstString("_ZNKSbIcSt17char_traits<char>St15allocator<char>E")] =
+ lldb_private::ConstString("_ZNKSs");
+}
+
+bool
+GetStdAlternateMangling(const lldb_private::ConstString &mangled, lldb_private::ConstString &alternate)
+{
+ InitStdAlternateManglingPrefixes();
+
+ if (!mangled)
+ return false;
+
+ const char *mangled_cstr = mangled.AsCString();
+ for (std::map<lldb_private::ConstString, lldb_private::ConstString>::iterator it = std_alternate_mangling_prefixes.begin();
+ it != std_alternate_mangling_prefixes.end();
+ ++it)
+ {
+ const char *prefix_cstr = it->first.AsCString();
+ if (strncmp(mangled_cstr, prefix_cstr, strlen(prefix_cstr)) == 0)
+ {
+ std::string alternate_mangling(it->second.AsCString());
+ alternate_mangling.append(mangled_cstr + strlen(prefix_cstr));
+ alternate.SetCString(alternate_mangling.c_str());
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // anonymous namespace
+
IRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) :
m_execution_unit(execution_unit),
m_stream_string(lldb_private::Stream::eBinary, execution_unit.GetAddressByteSize(), execution_unit.GetByteOrder()),
@@ -226,26 +270,21 @@
{
if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
{
- lldb_private::ConstString altnernate_name;
+ lldb_private::ConstString alternate_name;
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)
- {
- 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);
- }
+ // 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.
+ if (GetStdAlternateMangling(name, alternate_name))
+ found_it = m_decl_map->GetFunctionAddress (alternate_name, fun_addr);
}
if (!found_it)
{
lldb_private::Mangled mangled_name(name);
- lldb_private::Mangled alt_mangled_name(altnernate_name);
+ lldb_private::Mangled alt_mangled_name(alternate_name);
if (log)
{
if (alt_mangled_name)
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D8846.23291.patch
Type: text/x-patch
Size: 3697 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20150406/673b9732/attachment.bin>
More information about the lldb-commits
mailing list