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();
+                    }
                 }
             }
         }
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
index 37b7bd1..509c594 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp
@@ -36,7 +36,6 @@
 #include "lldb/Host/Endian.h"
 #include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/CompilerType.h"
-#include "lldb/Target/CPPLanguageRuntime.h"
 
 #include <map>
 
@@ -230,36 +229,6 @@
         {
             std::vector<lldb_private::ConstString> alternates;
             bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
-            if (!found_it)
-            {
-                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();
-                if (process_sp)
-                {
-                    lldb_private::CPPLanguageRuntime *cpp_runtime = process_sp->GetCPPLanguageRuntime();
-                    if (cpp_runtime && cpp_runtime->GetAlternateManglings(name, alternates))
-                    {
-                        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)
             {