Skip to content
This repository has been archived by the owner on Apr 23, 2020. It is now read-only.

Commit

Permalink
Adding support for an "equivalents map". This can be useful when comp…
Browse files Browse the repository at this point in the history
…ilers 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.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@149661 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
egranata committed Feb 3, 2012
1 parent 3eeaf6e commit bad9753
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 0 deletions.
9 changes: 9 additions & 0 deletions include/lldb/Target/CPPLanguageRuntime.h
Expand Up @@ -12,6 +12,7 @@

// C Includes
// C++ Includes
#include <vector>
// Other libraries and framework includes
// Project includes
#include "lldb/Core/PluginInterface.h"
Expand Down Expand Up @@ -50,6 +51,14 @@ class CPPLanguageRuntime :

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:
//------------------------------------------------------------------
Expand Down
151 changes: 151 additions & 0 deletions source/Target/CPPLanguageRuntime.cpp
Expand Up @@ -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
//----------------------------------------------------------------------
Expand Down Expand Up @@ -118,3 +253,19 @@ CPPLanguageRuntime::IsPossibleCPPCall (const char *name, const char *&base_name_

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;
}

0 comments on commit bad9753

Please sign in to comment.