summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp32
-rw-r--r--lldb/source/Expression/IRInterpreter.cpp22
2 files changed, 42 insertions, 12 deletions
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 3dab8339390..c6517e5b0e7 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -1066,6 +1066,21 @@ ClangExpressionDeclMap::LookupDecl (clang::NamedDecl *decl, ClangExpressionVaria
ClangExpressionVariableSP expr_var_sp (m_found_entities.GetVariable(decl, GetParserID()));
ClangExpressionVariableSP persistent_var_sp (m_parser_vars->m_persistent_vars->GetVariable(decl, GetParserID()));
+ if (isa<FunctionDecl>(decl))
+ {
+ ClangExpressionVariableSP entity_sp(m_found_entities.GetVariable(decl, GetParserID()));
+
+ if (!entity_sp)
+ return Value();
+
+ // We know m_parser_vars is valid since we searched for the variable by
+ // its NamedDecl
+
+ ClangExpressionVariable::ParserVars *parser_vars = entity_sp->GetParserVars(GetParserID());
+
+ return *parser_vars->m_lldb_value;
+ }
+
if (expr_var_sp)
{
flags = expr_var_sp->m_flags;
@@ -3690,8 +3705,21 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target, is_indirect_function);
- fun_location->SetValueType(Value::eValueTypeLoadAddress);
- fun_location->GetScalar() = load_addr;
+
+ if (load_addr != LLDB_INVALID_ADDRESS)
+ {
+ fun_location->SetValueType(Value::eValueTypeLoadAddress);
+ fun_location->GetScalar() = load_addr;
+ }
+ else
+ {
+ // We have to try finding a file address.
+
+ lldb::addr_t file_addr = fun_address->GetFileAddress();
+
+ fun_location->SetValueType(Value::eValueTypeFileAddress);
+ fun_location->GetScalar() = file_addr;
+ }
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
m_parser_vars->m_target_info.byte_order,
diff --git a/lldb/source/Expression/IRInterpreter.cpp b/lldb/source/Expression/IRInterpreter.cpp
index 18a92188a70..3c7c76653fb 100644
--- a/lldb/source/Expression/IRInterpreter.cpp
+++ b/lldb/source/Expression/IRInterpreter.cpp
@@ -624,6 +624,11 @@ public:
// "this", "self", and "_cmd" are direct.
bool variable_is_this = false;
+ // If the variable is a function pointer, we do not need to
+ // build an extra layer of indirection for it because it is
+ // accessed directly.
+ bool variable_is_function_address = false;
+
// Attempt to resolve the value using the program's data.
// If it is, the values to be created are:
//
@@ -647,12 +652,7 @@ public:
break;
if (isa<clang::FunctionDecl>(decl))
- {
- if (log)
- log->Printf("The interpreter does not handle function pointers at the moment");
-
- return Memory::Region();
- }
+ variable_is_function_address = true;
resolved_value = m_decl_map.LookupDecl(decl, flags);
}
@@ -786,17 +786,19 @@ public:
}
else
{
+ bool no_extra_redirect = (variable_is_this || variable_is_function_address);
+
Memory::Region data_region = m_memory.Place(value->getType(), resolved_value.GetScalar().ULongLong(), resolved_value);
Memory::Region ref_region = m_memory.Malloc(value->getType());
Memory::Region pointer_region;
- if (!variable_is_this)
+ if (!no_extra_redirect)
pointer_region = m_memory.Malloc(value->getType());
if (ref_region.IsInvalid())
return Memory::Region();
- if (pointer_region.IsInvalid() && !variable_is_this)
+ if (pointer_region.IsInvalid() && !no_extra_redirect)
return Memory::Region();
DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
@@ -804,7 +806,7 @@ public:
if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
return Memory::Region();
- if (!variable_is_this)
+ if (!no_extra_redirect)
{
DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
@@ -824,7 +826,7 @@ public:
log->Printf(" Pointer region : %llx", (unsigned long long)pointer_region.m_base);
}
- if (variable_is_this)
+ if (no_extra_redirect)
return ref_region;
else
return pointer_region;
OpenPOWER on IntegriCloud