[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