Changed SymbolContext so when you search for functions

it returns a list of functions as a SymbolContextList.

Rewrote the clients of SymbolContext to use this
SymbolContextList.

Rewrote some of the providers of the data to SymbolContext
to make them respect preferences as to whether the list
should be cleared first; propagated that change out.

ClangExpressionDeclMap and ClangASTSource use this new
function list to properly generate function definitions -
even for functions that don't have a prototype in the
debug information.

llvm-svn: 109476
This commit is contained in:
Sean Callanan 2010-07-27 00:55:47 +00:00
parent ce3a8293a0
commit 8ade104a0a
10 changed files with 127 additions and 66 deletions

View File

@ -160,6 +160,7 @@ public:
size_t
FindFunctions (const ConstString &name,
uint32_t name_type_mask,
bool append,
SymbolContextList &sc_list);
//------------------------------------------------------------------

View File

@ -61,6 +61,7 @@ struct NameSearchContext {
clang::ASTContext *GetASTContext();
clang::NamedDecl *AddVarDecl(void *type);
clang::NamedDecl *AddFunDecl(void *type);
clang::NamedDecl *AddGenericFunDecl();
};
}

View File

@ -157,7 +157,7 @@ private:
TypeFromParser *parser_type = NULL);
void AddOneVariable(NameSearchContext &context, Variable *var);
void AddOneFunction(NameSearchContext &context, Function *fun);
void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym);
bool DoMaterialize (bool dematerialize,
ExecutionContext *exe_ctx,

View File

@ -195,10 +195,12 @@ public:
/// symbol context.
///
/// @return
/// A shared pointer to the function found.
/// The number of symbol contexts found.
//------------------------------------------------------------------
Function *
FindFunctionByName (const char *name) const;
size_t
FindFunctionsByName (const ConstString &name,
bool append,
SymbolContextList &sc_list) const;
//------------------------------------------------------------------
/// Find a variable matching the given name, working out from this

View File

@ -169,9 +169,20 @@ CommandObjectCall::Execute
//const char *return_type = command.GetArgumentAtIndex(0);
const char *function_name = command.GetArgumentAtIndex(1);
// Look up the called function:
Function *target_fn = NULL;
SymbolContextList sc_list;
exe_ctx.frame->GetSymbolContext(eSymbolContextEverything).FindFunctionsByName(ConstString(function_name), false, sc_list);
Function *target_fn = exe_ctx.frame->GetSymbolContext(eSymbolContextEverything).FindFunctionByName (function_name);
if (sc_list.GetSize() > 0)
{
SymbolContext sc;
sc_list.GetContextAtIndex(0, sc);
target_fn = sc.function;
}
// FIXME: If target_fn is NULL, we should look up the name as a symbol and use it and the provided
// return type.

View File

@ -115,7 +115,8 @@ Disassembler::Disassemble
else
{
if (exe_ctx.target->GetImages().FindFunctions (name,
eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
false,
sc_list))
{
return Disassemble (debugger, arch, exe_ctx, sc_list, num_mixed_context_lines, show_bytes, strm);

View File

@ -126,15 +126,18 @@ ModuleList::GetModuleAtIndex(uint32_t idx)
}
size_t
ModuleList::FindFunctions (const ConstString &name, uint32_t name_type_mask, SymbolContextList &sc_list)
ModuleList::FindFunctions (const ConstString &name, uint32_t name_type_mask, bool append, SymbolContextList &sc_list)
{
sc_list.Clear();
if (!append)
sc_list.Clear();
Mutex::Locker locker(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
for (pos = m_modules.begin(); pos != end; ++pos)
{
(*pos)->FindFunctions (name, name_type_mask, true, sc_list);
}
return sc_list.GetSize();
}

View File

@ -146,3 +146,19 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(void *type) {
return Decl;
}
clang::NamedDecl *NameSearchContext::AddGenericFunDecl()
{
QualType generic_function_type(ASTSource.Context.getFunctionType(ASTSource.Context.getSizeType(), // result
NULL, // argument types
0, // number of arguments
true, // variadic?
0, // type qualifiers
false, // has exception specification?
false, // has any exception specification?
0, // number of exceptions
NULL, // exceptions
FunctionType::ExtInfo())); // defaults for noreturn, regparm, calling convention
return AddFunDecl(generic_function_type.getAsOpaquePtr());
}

View File

@ -603,12 +603,23 @@ ClangExpressionDeclMap::GetDecls(NameSearchContext &context,
}
ConstString name_cs(name);
SymbolContextList sym_ctxs;
Function *fn = m_sym_ctx->FindFunctionByName(name_cs.GetCString());
m_sym_ctx->FindFunctionsByName(name_cs, false, sym_ctxs);
for (uint32_t index = 0, num_indices = sym_ctxs.GetSize();
index < num_indices;
++index)
{
SymbolContext sym_ctx;
sym_ctxs.GetContextAtIndex(index, sym_ctx);
if (sym_ctx.function)
AddOneFunction(context, sym_ctx.function, NULL);
else if(sym_ctx.symbol)
AddOneFunction(context, NULL, sym_ctx.symbol);
}
if (fn)
AddOneFunction(context, fn);
Variable *var = FindVariableInScope(*m_sym_ctx, name);
if (var)
@ -749,41 +760,64 @@ ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
void
ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
Function* fun)
Function* fun,
Symbol* symbol)
{
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
Type *fun_type = fun->GetType();
if (!fun_type)
{
if (log)
log->PutCString("Skipped a function because it has no type");
return;
}
void *fun_opaque_type = fun_type->GetOpaqueClangQualType();
if (!fun_opaque_type)
{
if (log)
log->PutCString("Skipped a function because it has no Clang type");
return;
}
NamedDecl *fun_decl;
std::auto_ptr<Value> fun_location(new Value);
const Address *fun_address;
const Address &fun_address = fun->GetAddressRange().GetBaseAddress();
lldb::addr_t load_addr = fun_address.GetLoadAddress(m_exe_ctx->process);
// only valid for Functions, not for Symbols
void *fun_opaque_type = NULL;
clang::ASTContext *fun_ast_context = NULL;
if (fun)
{
Type *fun_type = fun->GetType();
if (!fun_type)
{
if (log)
log->PutCString("Skipped a function because it has no type");
return;
}
fun_opaque_type = fun_type->GetOpaqueClangQualType();
if (!fun_opaque_type)
{
if (log)
log->PutCString("Skipped a function because it has no Clang type");
return;
}
fun_address = &fun->GetAddressRange().GetBaseAddress();
TypeList *type_list = fun_type->GetTypeList();
fun_ast_context = type_list->GetClangASTContext().getASTContext();
void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
fun_decl = context.AddFunDecl(copied_type);
}
else if (symbol)
{
fun_address = &symbol->GetAddressRangeRef().GetBaseAddress();
fun_decl = context.AddGenericFunDecl();
}
else
{
if (log)
log->PutCString("AddOneFunction called with no function and no symbol");
return;
}
lldb::addr_t load_addr = fun_address->GetLoadAddress(m_exe_ctx->process);
fun_location->SetValueType(Value::eValueTypeLoadAddress);
fun_location->GetScalar() = load_addr;
TypeList *type_list = fun_type->GetTypeList();
clang::ASTContext *fun_ast_context = type_list->GetClangASTContext().getASTContext();
void *copied_type = ClangASTContext::CopyType(context.GetASTContext(), fun_ast_context, fun_opaque_type);
NamedDecl *fun_decl = context.AddFunDecl(copied_type);
Tuple tuple;
tuple.m_decl = fun_decl;

View File

@ -354,17 +354,18 @@ SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
}
Function *
SymbolContext::FindFunctionByName (const char *name) const
{
ConstString name_const_str (name);
size_t
SymbolContext::FindFunctionsByName (const ConstString &name, bool append, SymbolContextList &sc_list) const
{
if (!append)
sc_list.Clear();
if (function != NULL)
{
// FIXME: Look in the class of the current function, if it exists,
// for methods matching name.
}
//
if (comp_unit != NULL)
{
// Make sure we've read in all the functions. We should be able to check and see
@ -374,33 +375,24 @@ SymbolContext::FindFunctionByName (const char *name) const
lldb::FunctionSP func_sp;
for (func_idx = 0; (func_sp = comp_unit->GetFunctionAtIndex(func_idx)) != NULL; ++func_idx)
{
if (func_sp->GetMangled().GetName() == name_const_str)
return func_sp.get();
if (func_sp->GetMangled().GetName() == name)
{
SymbolContext sym_ctx(target_sp,
module_sp,
comp_unit,
func_sp.get());
sc_list.Append(sym_ctx);
}
}
}
if (module_sp != NULL)
{
SymbolContextList sc_matches;
if (module_sp->FindFunctions (name_const_str, eFunctionNameTypeBase | eFunctionNameTypeFull, false, sc_matches) > 0)
{
SymbolContext sc;
sc_matches.GetContextAtIndex (0, sc);
return sc.function;
}
}
module_sp->FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
if (target_sp)
{
SymbolContextList sc_matches;
if (target_sp->GetImages().FindFunctions (name_const_str, eFunctionNameTypeBase | eFunctionNameTypeFull, sc_matches) > 0)
{
SymbolContext sc;
sc_matches.GetContextAtIndex (0, sc);
return sc.function;
}
}
target_sp->GetImages().FindFunctions (name, eFunctionNameTypeBase | eFunctionNameTypeFull, true, sc_list);
return NULL;
return sc_list.GetSize();
}
lldb::VariableSP