<rdar://problem/12953853>

Setting breakpoints using "breakpoint set --selector <SEL>" previously didn't when there was no dSYM file.

Also fixed issues in the test suite that arose after fixing the bug.

Also fixed the log channels to properly ref count the log streams using weak pointers to the streams. This fixes a test suite problem that would happen when you specified a full path to the compiler with the "--compiler" option.

llvm-svn: 171816
diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp
index 0f0e06d..60932bf 100644
--- a/lldb/source/Breakpoint/BreakpointResolverName.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp
@@ -182,8 +182,7 @@
                     
                     if (num_functions == 0 && !filter_by_cu)
                     {
-                        if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
-                            context.module_sp->FindSymbolsWithNameAndType (m_func_names[j], eSymbolTypeCode, sym_list);
+                        context.module_sp->FindFunctionSymbols (m_func_names[j], m_func_name_type_mask, sym_list);
                     }
                 }
             }
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 0159249..2a296db 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -2614,13 +2614,13 @@
     else
     {
         LogStreamMap::iterator pos = m_log_streams.find(log_file);
-        if (pos == m_log_streams.end())
+        if (pos != m_log_streams.end())
+            log_stream_sp = pos->second.lock();
+        if (!log_stream_sp)
         {
             log_stream_sp.reset (new StreamFile (log_file));
             m_log_streams[log_file] = log_stream_sp;
         }
-        else
-            log_stream_sp = pos->second;
     }
     assert (log_stream_sp.get());
     
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 62a6ab6..69fccfc 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -1064,6 +1064,25 @@
 }
 
 size_t
+Module::FindFunctionSymbols (const ConstString &name,
+                             uint32_t name_type_mask,
+                             SymbolContextList& sc_list)
+{
+    Timer scoped_timer(__PRETTY_FUNCTION__,
+                       "Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
+                       name.AsCString(),
+                       name_type_mask);
+    ObjectFile *objfile = GetObjectFile ();
+    if (objfile)
+    {
+        Symtab *symtab = objfile->GetSymtab();
+        if (symtab)
+            return symtab->FindFunctionSymbols (name, name_type_mask, sc_list);
+    }
+    return 0;
+}
+
+size_t
 Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
 {
     // No need to protect this call using m_mutex all other method calls are
diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp
index 5a2ff1b..60f2c75 100644
--- a/lldb/source/Symbol/Symtab.cpp
+++ b/lldb/source/Symbol/Symtab.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolContext.h"
 #include "lldb/Symbol/Symtab.h"
 #include "lldb/Target/ObjCLanguageRuntime.h"
 
@@ -309,20 +310,25 @@
                 
             // If the demangled name turns out to be an ObjC name, and
             // is a category name, add the version without categories to the index too.
+            ConstString objc_selector_name;
             ConstString objc_base_name;
             if (ObjCLanguageRuntime::ParseMethodName (entry.cstring,
                                                       NULL,
-                                                      NULL,
+                                                      &objc_selector_name,
                                                       &objc_base_name,
                                                       NULL))
             {
                 entry.cstring = objc_base_name.GetCString();
                 m_name_to_index.Append (entry);
+                entry.cstring = objc_selector_name.GetCString();
+                m_selector_to_index.Append (entry);
             }
                                                         
         }
         m_name_to_index.Sort();
         m_name_to_index.SizeToFit();
+        m_selector_to_index.Sort();
+        m_selector_to_index.SizeToFit();
     }
 }
 
@@ -979,3 +985,64 @@
     return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size());
 }
 
+void
+Symtab::SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
+{
+    // No need to protect this call using m_mutex all other method calls are
+    // already thread safe.
+    
+    size_t num_indices = symbol_indexes.size();
+    if (num_indices > 0)
+    {
+        SymbolContext sc;
+        sc.module_sp = m_objfile->GetModule();
+        for (size_t i = 0; i < num_indices; i++)
+        {
+            sc.symbol = SymbolAtIndex (symbol_indexes[i]);
+            if (sc.symbol)
+                sc_list.Append (sc);
+        }
+    }
+}
+
+
+size_t
+Symtab::FindFunctionSymbols (const ConstString &name,
+                             uint32_t name_type_mask,
+                             SymbolContextList& sc_list)
+{
+    size_t count = 0;
+    std::vector<uint32_t> symbol_indexes;
+    if (name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
+    {
+        FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, symbol_indexes);
+    }
+    
+    if (name_type_mask & eFunctionNameTypeSelector)
+    {
+        if (!m_name_indexes_computed)
+            InitNameIndexes();
+
+        if (!m_selector_to_index.IsEmpty())
+        {
+            const UniqueCStringMap<uint32_t>::Entry *match;
+            for (match = m_selector_to_index.FindFirstValueForName(name.AsCString());
+                 match != NULL;
+                 match = m_selector_to_index.FindNextValueForName(match))
+            {
+                symbol_indexes.push_back(match->value);
+            }
+        }
+    }
+
+    if (!symbol_indexes.empty())
+    {
+        std::sort(symbol_indexes.begin(), symbol_indexes.end());
+        symbol_indexes.erase(std::unique(symbol_indexes.begin(), symbol_indexes.end()), symbol_indexes.end());
+        count = symbol_indexes.size();
+        SymbolIndicesToSymbolContextList (symbol_indexes, sc_list);
+    }
+
+    return count;
+}
+