diff options
| author | Siva Chandra <sivachandra@google.com> | 2015-04-09 18:48:34 +0000 |
|---|---|---|
| committer | Siva Chandra <sivachandra@google.com> | 2015-04-09 18:48:34 +0000 |
| commit | 0f404e057501728e819a8955c893fb4b772ba97f (patch) | |
| tree | 0f3630849d40921eea8787cb51d442366e2c9c90 /lldb/source/Plugins | |
| parent | 10821e5283fd190c8ff38dcad8b5e2a2fcdc4e5a (diff) | |
| download | bcm5719-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/Plugins')
| -rw-r--r-- | lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp | 43 | ||||
| -rw-r--r-- | lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h | 8 |
2 files changed, 51 insertions, 0 deletions
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index 50537eb119f..5712b208855 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -281,9 +281,43 @@ ItaniumABILanguageRuntime::IsVTableName (const char *name) return false; } +size_t +ItaniumABILanguageRuntime::GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates) +{ + if (!mangled) + return static_cast<size_t>(0); + + alternates.clear(); + const char *mangled_cstr = mangled.AsCString(); + for (typename std::map<ConstString, std::vector<ConstString> >::iterator it = s_alternate_mangling_prefixes.begin(); + it != s_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<ConstString> &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<size_t>(0); +} + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ + +std::map<ConstString, std::vector<ConstString> > ItaniumABILanguageRuntime::s_alternate_mangling_prefixes; + LanguageRuntime * ItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language) { @@ -304,6 +338,15 @@ ItaniumABILanguageRuntime::Initialize() PluginManager::RegisterPlugin (GetPluginNameStatic(), "Itanium ABI for the C++ language", CreateInstance); + + // Alternate manglings for std::basic_string<...> + std::vector<ConstString> basic_string_alternates; + basic_string_alternates.push_back(ConstString("_ZNSs")); + basic_string_alternates.push_back(ConstString("_ZNKSs")); + s_alternate_mangling_prefixes[ConstString("_ZNSbIcSt17char_traits<char>St15allocator<char>E")] = + basic_string_alternates; + s_alternate_mangling_prefixes[ConstString("_ZNKSbIcSt17char_traits<char>St15allocator<char>E")] = + basic_string_alternates; } void diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index cd0a4b2c15e..d1dbb7ad407 100644 --- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -20,6 +20,9 @@ #include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Core/Value.h" +#include <map> +#include <vector> + namespace lldb_private { class ItaniumABILanguageRuntime : @@ -82,6 +85,9 @@ namespace lldb_private { virtual lldb::SearchFilterSP CreateExceptionSearchFilter (); + virtual size_t + GetAlternateManglings(const ConstString &mangled, std::vector<ConstString> &alternates); + protected: lldb::BreakpointResolverSP @@ -97,6 +103,8 @@ namespace lldb_private { ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead. lldb::BreakpointSP m_cxx_exception_bp_sp; + + static std::map<ConstString, std::vector<ConstString> > s_alternate_mangling_prefixes; }; } // namespace lldb_private |

