[Lldb-commits] [lldb] r149661 - in /lldb/trunk: include/lldb/Target/CPPLanguageRuntime.h source/Target/CPPLanguageRuntime.cpp

Enrico Granata granata.enrico at gmail.com
Thu Feb 2 17:41:25 PST 2012


Author: enrico
Date: Thu Feb  2 19:41:25 2012
New Revision: 149661

URL: http://llvm.org/viewvc/llvm-project?rev=149661&view=rev
Log:
Adding support for an "equivalents map". This can be useful when compilers emit multiple, different names for the same actual type. In such scenarios, one of the type names can actually be found during a type lookup, while the others are just aliases. This can cause issues when trying to work with these aliased names and being unable to resolve them to an actual type (e.g. getting an SBType for the aliased name).
Currently, no code is using this feature, since we can hopefully rely on the new template support in SBType to get the same stuff done, but the support is there just in case it turns out to be useful for some future need.

Modified:
    lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h
    lldb/trunk/source/Target/CPPLanguageRuntime.cpp

Modified: lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h?rev=149661&r1=149660&r2=149661&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/CPPLanguageRuntime.h Thu Feb  2 19:41:25 2012
@@ -12,6 +12,7 @@
 
 // C Includes
 // C++ Includes
+#include <vector>
 // Other libraries and framework includes
 // Project includes
 #include "lldb/Core/PluginInterface.h"
@@ -50,6 +51,14 @@
 
     static bool
     StripNamespacesFromVariableName (const char *name, const char *&base_name_start, const char *&base_name_end);
+    
+    // in some cases, compilers will output different names for one same type. when tht happens, it might be impossible
+    // to construct SBType objects for a valid type, because the name that is available is not the same as the name that
+    // can be used as a search key in FindTypes(). the equivalents map here is meant to return possible alternative names
+    // for a type through which a search can be conducted. Currently, this is only enabled for C++ but can be extended
+    // to ObjC or other languages if necessary
+    static uint32_t
+    FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents);
 
 protected:
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Target/CPPLanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/CPPLanguageRuntime.cpp?rev=149661&r1=149660&r2=149661&view=diff
==============================================================================
--- lldb/trunk/source/Target/CPPLanguageRuntime.cpp (original)
+++ lldb/trunk/source/Target/CPPLanguageRuntime.cpp Thu Feb  2 19:41:25 2012
@@ -8,12 +8,147 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Target/CPPLanguageRuntime.h"
+
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/Target/ExecutionContext.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
+class CPPRuntimeEquivalents
+{
+public:
+    CPPRuntimeEquivalents ()
+    {
+        
+        m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("basic_string<char>"));
+        m_impl.Append(ConstString("class std::basic_string<char, class std::char_traits<char>, class std::allocator<char> >").AsCString(), ConstString("basic_string<char>"));
+
+        // these two (with a prefixed std::) occur when c++stdlib string class occurs as a template argument in some STL container
+        m_impl.Append(ConstString("std::basic_string<char, std::char_traits<char>, std::allocator<char> >").AsCString(), ConstString("std::basic_string<char>"));
+        m_impl.Append(ConstString("class std::basic_string<char, class std::char_traits<char>, class std::allocator<char> >").AsCString(), ConstString("std::asic_string<char>"));
+        
+        m_impl.Sort();
+    }
+    
+    void
+    Add (ConstString& type_name,
+         ConstString& type_equivalent)
+    {
+        m_impl.Insert(type_name.AsCString(), type_equivalent);
+    }
+    
+    uint32_t
+    FindExactMatches (ConstString& type_name,
+                      std::vector<ConstString>& equivalents)
+    {
+        
+        uint32_t count = 0;
+
+        for (ImplData match = m_impl.FindFirstValueForName(type_name.AsCString());
+             match != NULL;
+             match = m_impl.FindNextValueForName(match))
+        {
+            equivalents.push_back(match->value);
+            count++;
+        }
+
+        return count;        
+    }
+    
+    // partial matches can occur when a name with equivalents is a template argument.
+    // e.g. we may have "class Foo" be a match for "struct Bar". if we have a typename
+    // such as "class Templatized<class Foo, Anything>" we want this to be replaced with
+    // "class Templatized<struct Bar, Anything>". Since partial matching is time consuming
+    // once we get a partial match, we add it to the exact matches list for faster retrieval
+    uint32_t
+    FindPartialMatches (ConstString& type_name,
+                        std::vector<ConstString>& equivalents)
+    {
+        
+        uint32_t count = 0;
+        
+        const char* type_name_cstr = type_name.AsCString();
+        
+        size_t items_count = m_impl.GetSize();
+        
+        for (size_t item = 0; item < items_count; item++)
+        {
+            const char* key_cstr = m_impl.GetCStringAtIndex(item);
+            if ( strstr(type_name_cstr,key_cstr) )
+            {
+                count += AppendReplacements(type_name_cstr,
+                                            key_cstr,
+                                            equivalents);
+            }
+        }
+        
+        return count;
+        
+    }
+    
+private:
+    
+    std::string& replace (std::string& target,
+                          std::string& pattern,
+                          std::string& with)
+    {
+        size_t pos;
+        size_t pattern_len = pattern.size();
+        
+        while ( (pos = target.find(pattern)) != std::string::npos )
+            target.replace(pos, pattern_len, with);
+        
+        return target;
+    }
+    
+    uint32_t
+    AppendReplacements (const char* original,
+                        const char *matching_key,
+                        std::vector<ConstString>& equivalents)
+    {
+        
+        std::string matching_key_str(matching_key);
+        ConstString original_const(original);
+        
+        uint32_t count = 0;
+        
+        for (ImplData match = m_impl.FindFirstValueForName(matching_key);
+             match != NULL;
+             match = m_impl.FindNextValueForName(match))
+        {
+            std::string target(original);
+            std::string equiv_class(match->value.AsCString());
+            
+            replace (target, matching_key_str, equiv_class);
+            
+            ConstString target_const(target.c_str());
+
+// you will most probably want to leave this off since it might make this map grow indefinitely
+#ifdef ENABLE_CPP_EQUIVALENTS_MAP_TO_GROW
+            Add(original_const, target_const);
+#endif
+            equivalents.push_back(target_const);
+            
+            count++;
+        }
+        
+        return count;
+    }
+    
+    typedef UniqueCStringMap<ConstString> Impl;
+    typedef const Impl::Entry* ImplData;
+    Impl m_impl;
+};
+
+static CPPRuntimeEquivalents&
+GetEquivalentsMap ()
+{
+    static CPPRuntimeEquivalents g_equivalents_map;
+    return g_equivalents_map;
+}
+
 //----------------------------------------------------------------------
 // Destructor
 //----------------------------------------------------------------------
@@ -118,3 +253,19 @@
 
     return StripNamespacesFromVariableName (name, base_name_start, base_name_end);
 }
+
+uint32_t
+CPPLanguageRuntime::FindEquivalentNames(ConstString type_name, std::vector<ConstString>& equivalents)
+{
+    uint32_t count = GetEquivalentsMap().FindExactMatches(type_name, equivalents);
+
+    bool might_have_partials= 
+        ( count == 0 )  // if we have a full name match just use it
+        && (strchr(type_name.AsCString(), '<') != NULL  // we should only have partial matches when templates are involved, check that we have
+            && strchr(type_name.AsCString(), '>') != NULL); // angle brackets in the type_name before trying to scan for partial matches
+    
+    if ( might_have_partials )
+        count = GetEquivalentsMap().FindPartialMatches(type_name, equivalents);
+    
+    return count;
+}





More information about the lldb-commits mailing list