summaryrefslogtreecommitdiffstats
path: root/lldb/source/Core/Module.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Core/Module.cpp')
-rw-r--r--lldb/source/Core/Module.cpp164
1 files changed, 141 insertions, 23 deletions
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 671d6e4c125..151e611b71b 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -29,6 +29,8 @@
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
@@ -589,42 +591,83 @@ Module::FindFunctions (const ConstString &name,
if (!append)
sc_list.Clear();
- const size_t start_size = sc_list.GetSize();
+ const size_t old_size = sc_list.GetSize();
// Find all the functions (not symbols, but debug information functions...
SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- symbols->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, append, sc_list);
-
- // Now check our symbol table for symbols that are code symbols if requested
- if (include_symbols)
+
+ if (name_type_mask & eFunctionNameTypeAuto)
{
- ObjectFile *objfile = GetObjectFile();
- if (objfile)
+ ConstString lookup_name;
+ uint32_t lookup_name_type_mask = 0;
+ bool match_name_after_lookup = false;
+ Module::PrepareForFunctionNameLookup (name,
+ name_type_mask,
+ lookup_name,
+ lookup_name_type_mask,
+ match_name_after_lookup);
+
+ if (symbols)
+ symbols->FindFunctions(lookup_name,
+ namespace_decl,
+ lookup_name_type_mask,
+ include_inlines,
+ append,
+ sc_list);
+
+ // Now check our symbol table for symbols that are code symbols if requested
+ if (include_symbols)
{
- Symtab *symtab = objfile->GetSymtab();
- if (symtab)
+ ObjectFile *objfile = GetObjectFile();
+ if (objfile)
{
- std::vector<uint32_t> symbol_indexes;
- symtab->FindAllSymbolsWithNameAndType (name, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
- const size_t num_matches = symbol_indexes.size();
- if (num_matches)
+ Symtab *symtab = objfile->GetSymtab();
+ if (symtab)
+ symtab->FindFunctionSymbols(lookup_name, lookup_name_type_mask, sc_list);
+ }
+ }
+
+ if (match_name_after_lookup)
+ {
+ SymbolContext sc;
+ size_t i = old_size;
+ while (i<sc_list.GetSize())
+ {
+ if (sc_list.GetContextAtIndex(i, sc))
{
- const bool merge_symbol_into_function = true;
- SymbolContext sc(this);
- for (size_t i=0; i<num_matches; i++)
+ const char *func_name = sc.GetFunctionName().GetCString();
+ if (func_name && strstr (func_name, name.GetCString()) == NULL)
{
- sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
- SymbolType sym_type = sc.symbol->GetType();
- if (sc.symbol && (sym_type == eSymbolTypeCode ||
- sym_type == eSymbolTypeResolver))
- sc_list.AppendIfUnique (sc, merge_symbol_into_function);
+ // Remove the current context
+ sc_list.RemoveContextAtIndex(i);
+ // Don't increment i and continue in the loop
+ continue;
}
}
+ ++i;
}
}
+
}
- return sc_list.GetSize() - start_size;
+ else
+ {
+ if (symbols)
+ symbols->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, append, sc_list);
+
+ // Now check our symbol table for symbols that are code symbols if requested
+ if (include_symbols)
+ {
+ ObjectFile *objfile = GetObjectFile();
+ if (objfile)
+ {
+ Symtab *symtab = objfile->GetSymtab();
+ if (symtab)
+ symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
+ }
+ }
+ }
+
+ return sc_list.GetSize() - old_size;
}
size_t
@@ -1347,3 +1390,78 @@ Module::GetVersion (uint32_t *versions, uint32_t num_versions)
}
return 0;
}
+
+void
+Module::PrepareForFunctionNameLookup (const ConstString &name,
+ uint32_t name_type_mask,
+ ConstString &lookup_name,
+ uint32_t &lookup_name_type_mask,
+ bool &match_name_after_lookup)
+{
+ const char *name_cstr = name.GetCString();
+ lookup_name_type_mask = eFunctionNameTypeNone;
+ match_name_after_lookup = false;
+ const char *base_name_start = NULL;
+ const char *base_name_end = NULL;
+
+ if (name_type_mask & eFunctionNameTypeAuto)
+ {
+ if (CPPLanguageRuntime::IsCPPMangledName (name_cstr))
+ lookup_name_type_mask = eFunctionNameTypeFull;
+ else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr))
+ lookup_name_type_mask = eFunctionNameTypeFull;
+ else
+ {
+ if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
+ lookup_name_type_mask |= eFunctionNameTypeSelector;
+
+ if (CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
+ lookup_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
+ }
+ }
+ else
+ {
+ lookup_name_type_mask = name_type_mask;
+ if (lookup_name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
+ {
+ // If they've asked for a CPP method or function name and it can't be that, we don't
+ // even need to search for CPP methods or names.
+ if (!CPPLanguageRuntime::IsPossibleCPPCall(name_cstr, base_name_start, base_name_end))
+ {
+ lookup_name_type_mask &= ~(eFunctionNameTypeMethod | eFunctionNameTypeBase);
+ if (lookup_name_type_mask == eFunctionNameTypeNone)
+ return;
+ }
+ }
+
+ if (lookup_name_type_mask & eFunctionNameTypeSelector)
+ {
+ if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr))
+ {
+ lookup_name_type_mask &= ~(eFunctionNameTypeSelector);
+ if (lookup_name_type_mask == eFunctionNameTypeNone)
+ return;
+ }
+ }
+ }
+
+ if (base_name_start &&
+ base_name_end &&
+ base_name_start != name_cstr &&
+ base_name_start < base_name_end)
+ {
+ // The name supplied was a partial C++ path like "a::count". In this case we want to do a
+ // lookup on the basename "count" and then make sure any matching results contain "a::count"
+ // so that it would match "b::a::count" and "a::count". This is why we set "match_name_after_lookup"
+ // to true
+ lookup_name.SetCStringWithLength(base_name_start, base_name_end - base_name_start);
+ match_name_after_lookup = true;
+ }
+ else
+ {
+ // The name is already correct, just use the exact name as supplied, and we won't need
+ // to check if any matches contain "name"
+ lookup_name = name;
+ match_name_after_lookup = false;
+ }
+} \ No newline at end of file
OpenPOWER on IntegriCloud