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
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index c9bc4b6..f4d6b19 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 @@
     }
 }
 
+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 @@
             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();
+                    }
                 }
             }
         }