forked from OSchip/llvm-project
FindFunctions now works again with mangled names.
<rdar://problem/28147057> llvm-svn: 294990
This commit is contained in:
parent
b74485dfaa
commit
5d0c114630
|
@ -0,0 +1,5 @@
|
|||
LEVEL = ../../make
|
||||
|
||||
CXX_SOURCES := main.cpp
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,65 @@
|
|||
"""
|
||||
Test SBTarget APIs.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
|
||||
import unittest2
|
||||
import os
|
||||
import time
|
||||
import re
|
||||
import lldb
|
||||
from lldbsuite.test.decorators import *
|
||||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test import lldbutil
|
||||
|
||||
|
||||
class TestNameLookup(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
@add_test_categories(['pyapi'])
|
||||
def test_target(self):
|
||||
"""Exercise SBTarget.FindFunctions() with various name masks.
|
||||
|
||||
A previous regression caused mangled names to not be able to be looked up.
|
||||
This test verifies that using a mangled name with eFunctionNameTypeFull works
|
||||
and that using a function basename with eFunctionNameTypeFull works for all
|
||||
C++ functions that are at the global namespace level."""
|
||||
self.build();
|
||||
exe = os.path.join(os.getcwd(), 'a.out')
|
||||
|
||||
# Create a target by the debugger.
|
||||
target = self.dbg.CreateTarget(exe)
|
||||
self.assertTrue(target, VALID_TARGET)
|
||||
|
||||
exe_module = target.FindModule(target.GetExecutable())
|
||||
|
||||
c_name_to_symbol = {}
|
||||
cpp_name_to_symbol = {}
|
||||
mangled_to_symbol = {}
|
||||
num_symbols = exe_module.GetNumSymbols();
|
||||
for i in range(num_symbols):
|
||||
symbol = exe_module.GetSymbolAtIndex(i);
|
||||
name = symbol.GetName()
|
||||
if 'unique_function_name' in name:
|
||||
mangled = symbol.GetMangledName()
|
||||
if mangled:
|
||||
mangled_to_symbol[mangled] = symbol
|
||||
if name:
|
||||
cpp_name_to_symbol[name] = symbol
|
||||
elif name:
|
||||
c_name_to_symbol[name] = symbol
|
||||
|
||||
# Make sure each mangled name turns up exactly one match when looking up
|
||||
# functions by full name and using the mangled name as the name in the
|
||||
# lookup
|
||||
for mangled in mangled_to_symbol.keys():
|
||||
symbol_contexts = target.FindFunctions(mangled, lldb.eFunctionNameTypeFull)
|
||||
self.assertTrue(symbol_contexts.GetSize() == 1)
|
||||
for symbol_context in symbol_contexts:
|
||||
self.assertTrue(symbol_context.GetFunction().IsValid())
|
||||
self.assertTrue(symbol_context.GetSymbol().IsValid())
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
#include <stdio.h>
|
||||
|
||||
extern "C" int unique_function_name(int i)
|
||||
{
|
||||
return puts(__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
int unique_function_name()
|
||||
{
|
||||
return puts(__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
int unique_function_name(float f)
|
||||
{
|
||||
return puts(__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
namespace e
|
||||
{
|
||||
int unique_function_name()
|
||||
{
|
||||
return puts(__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
namespace g
|
||||
{
|
||||
int unique_function_name()
|
||||
{
|
||||
return puts(__PRETTY_FUNCTION__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class g
|
||||
{
|
||||
public:
|
||||
int unique_function_name()
|
||||
{
|
||||
return puts(__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
int unique_function_name(int i)
|
||||
{
|
||||
return puts(__PRETTY_FUNCTION__);
|
||||
}
|
||||
};
|
||||
|
||||
int main (int argc, char const *argv[])
|
||||
{
|
||||
g g;
|
||||
g.unique_function_name();
|
||||
g.unique_function_name(argc);
|
||||
return 0;
|
||||
}
|
|
@ -719,10 +719,10 @@ Module::LookupInfo::LookupInfo(const ConstString &name, uint32_t name_type_mask,
|
|||
}
|
||||
|
||||
// Still try and get a basename in case someone specifies a name type mask
|
||||
// of
|
||||
// eFunctionNameTypeFull and a name like "A::func"
|
||||
// of eFunctionNameTypeFull and a name like "A::func"
|
||||
if (basename.empty()) {
|
||||
if (name_type_mask & eFunctionNameTypeFull) {
|
||||
if (name_type_mask & eFunctionNameTypeFull &&
|
||||
!CPlusPlusLanguage::IsCPPMangledName(name_cstr)) {
|
||||
CPlusPlusLanguage::MethodName cpp_method(name);
|
||||
basename = cpp_method.GetBasename();
|
||||
if (basename.empty())
|
||||
|
@ -770,30 +770,39 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list,
|
|||
}
|
||||
|
||||
// If we have only full name matches we might have tried to set breakpoint on
|
||||
// "func"
|
||||
// and specified eFunctionNameTypeFull, but we might have found "a::func()",
|
||||
// "a::b::func()", "c::func()", "func()" and "func". Only "func()" and "func"
|
||||
// should
|
||||
// end up matching.
|
||||
// "func" and specified eFunctionNameTypeFull, but we might have found
|
||||
// "a::func()", "a::b::func()", "c::func()", "func()" and "func". Only
|
||||
// "func()" and "func" should end up matching.
|
||||
if (m_name_type_mask == eFunctionNameTypeFull) {
|
||||
SymbolContext sc;
|
||||
size_t i = start_idx;
|
||||
while (i < sc_list.GetSize()) {
|
||||
if (!sc_list.GetContextAtIndex(i, sc))
|
||||
break;
|
||||
// Make sure the mangled and demangled names don't match before we try
|
||||
// to pull anything out
|
||||
ConstString mangled_name(sc.GetFunctionName(Mangled::ePreferMangled));
|
||||
ConstString full_name(sc.GetFunctionName());
|
||||
CPlusPlusLanguage::MethodName cpp_method(full_name);
|
||||
if (cpp_method.IsValid()) {
|
||||
if (cpp_method.GetContext().empty()) {
|
||||
if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) {
|
||||
sc_list.RemoveContextAtIndex(i);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
std::string qualified_name = cpp_method.GetScopeQualifiedName();
|
||||
if (qualified_name.compare(m_name.GetCString()) != 0) {
|
||||
sc_list.RemoveContextAtIndex(i);
|
||||
continue;
|
||||
if (mangled_name != m_name && full_name != m_name)
|
||||
{
|
||||
CPlusPlusLanguage::MethodName cpp_method(full_name);
|
||||
if (cpp_method.IsValid()) {
|
||||
if (cpp_method.GetContext().empty()) {
|
||||
if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) {
|
||||
sc_list.RemoveContextAtIndex(i);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
std::string qualified_name;
|
||||
llvm::StringRef anon_prefix("(anonymous namespace)");
|
||||
if (cpp_method.GetContext() == anon_prefix)
|
||||
qualified_name = cpp_method.GetBasename().str();
|
||||
else
|
||||
qualified_name = cpp_method.GetScopeQualifiedName();
|
||||
if (qualified_name.compare(m_name.GetCString()) != 0) {
|
||||
sc_list.RemoveContextAtIndex(i);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -328,6 +328,11 @@ void Symtab::InitNameIndexes() {
|
|||
} else {
|
||||
// No context for this function so this has to be a basename
|
||||
m_basename_to_index.Append(entry);
|
||||
// If there is no context (no namespaces or class scopes that
|
||||
// come before the function name) then this also could be a
|
||||
// fullname.
|
||||
if (cxx_method.GetContext().empty())
|
||||
m_name_to_index.Append(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue