Fixed a problem with the IR interpreter that caused

it to generate result variables that were not bound
to their underlying data.  This allowed the SBValue
class to use the interpreter (if possible).

Also made sure that any result variables that point
to stack allocations in the stack frame of the
interpreted expressions do not get live data.

llvm-svn: 140285
This commit is contained in:
Sean Callanan 2011-09-22 00:41:11 +00:00
parent fbe52c0192
commit 0886e5657b
6 changed files with 31 additions and 16 deletions

View File

@ -463,6 +463,10 @@ public:
/// @param[in] type /// @param[in] type
/// The type of the data. /// The type of the data.
/// ///
/// @param[in] transient
/// True if the data should be treated as disappearing after the
/// expression completes. In that case, it gets no live data.
///
/// @return /// @return
/// True on success; false otherwise. /// True on success; false otherwise.
//------------------------------------------------------------------ //------------------------------------------------------------------
@ -470,7 +474,8 @@ public:
CompleteResultVariable (lldb::ClangExpressionVariableSP &valobj, CompleteResultVariable (lldb::ClangExpressionVariableSP &valobj,
lldb_private::Value &value, lldb_private::Value &value,
const ConstString &name, const ConstString &name,
lldb_private::TypeFromParser type); lldb_private::TypeFromParser type,
bool transient);
//------------------------------------------------------------------ //------------------------------------------------------------------
/// [Used by CommandObjectExpression] Materialize the entire struct /// [Used by CommandObjectExpression] Materialize the entire struct

View File

@ -379,7 +379,7 @@ SBValue::CreateValueFromExpression (const char *name, const char* expression)
ValueObjectSP result_valobj_sp; ValueObjectSP result_valobj_sp;
m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression, m_opaque_sp->GetUpdatePoint().GetTargetSP()->EvaluateExpression (expression,
m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(), m_opaque_sp->GetUpdatePoint().GetExecutionContextScope()->CalculateStackFrame(),
eExecutionPolicyAlways, eExecutionPolicyOnlyWhenNeeded,
true, // unwind on error true, // unwind on error
true, // keep in memory true, // keep in memory
eNoDynamicValues, eNoDynamicValues,

View File

@ -320,7 +320,8 @@ bool
ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP &valobj, ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP &valobj,
lldb_private::Value &value, lldb_private::Value &value,
const ConstString &name, const ConstString &name,
lldb_private::TypeFromParser type) lldb_private::TypeFromParser type,
bool transient)
{ {
assert (m_parser_vars.get()); assert (m_parser_vars.get());
@ -330,7 +331,8 @@ ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP
return false; return false;
if (pvar_sp->m_flags & ClangExpressionVariable::EVIsProgramReference && if (pvar_sp->m_flags & ClangExpressionVariable::EVIsProgramReference &&
!pvar_sp->m_live_sp) !pvar_sp->m_live_sp &&
!transient)
{ {
// The reference comes from the program. We need to set up a live SP for it. // The reference comes from the program. We need to set up a live SP for it.
@ -927,11 +929,20 @@ ClangExpressionDeclMap::LookupDecl (clang::NamedDecl *decl)
} }
else if (persistent_var_sp) else if (persistent_var_sp)
{ {
lldb_private::Value ret; if ((persistent_var_sp->m_flags & ClangExpressionVariable::EVIsProgramReference ||
ret.SetValueType(Value::eValueTypeHostAddress); persistent_var_sp->m_flags & ClangExpressionVariable::EVIsLLDBAllocated) &&
ret.SetContext(Value::eContextTypeInvalid, NULL); persistent_var_sp->m_live_sp)
ret.GetScalar() = (lldb::addr_t)persistent_var_sp->GetValueBytes(); {
return ret; return persistent_var_sp->m_live_sp->GetValue();
}
else
{
lldb_private::Value ret;
ret.SetValueType(Value::eValueTypeHostAddress);
ret.SetContext(Value::eContextTypeInvalid, NULL);
ret.GetScalar() = (lldb::addr_t)persistent_var_sp->GetValueBytes();
return ret;
}
} }
else else
{ {

View File

@ -717,6 +717,8 @@ public:
lldb_private::Value base; lldb_private::Value base;
bool transient = false;
if (m_decl_map.ResultIsReference(result_name)) if (m_decl_map.ResultIsReference(result_name))
{ {
PointerType *R_ptr_ty = dyn_cast<PointerType>(R_ty); PointerType *R_ptr_ty = dyn_cast<PointerType>(R_ty);
@ -737,6 +739,9 @@ public:
if (!R_final.m_allocation) if (!R_final.m_allocation)
return false; return false;
if (R_final.m_allocation->m_data)
transient = true; // this is a stack allocation
base = R_final.m_allocation->m_origin; base = R_final.m_allocation->m_origin;
base.GetScalar() += (R_final.m_base - R_final.m_allocation->m_virtual_address); base.GetScalar() += (R_final.m_base - R_final.m_allocation->m_virtual_address);
} }
@ -747,7 +752,7 @@ public:
base.GetScalar() = (unsigned long long)R.m_allocation->m_data->GetBytes() + (R.m_base - R.m_allocation->m_virtual_address); base.GetScalar() = (unsigned long long)R.m_allocation->m_data->GetBytes() + (R.m_base - R.m_allocation->m_virtual_address);
} }
return m_decl_map.CompleteResultVariable (result, base, result_name, result_type); return m_decl_map.CompleteResultVariable (result, base, result_name, result_type, transient);
} }
}; };

View File

@ -18,16 +18,12 @@ class ExprFormattersTestCase(TestBase):
self.line = line_number('main.cpp', self.line = line_number('main.cpp',
'// Stop here') '// Stop here')
# rdar://problem/10153585 lldb ToT regression of test suite with r139772 check-in
@unittest2.expectedFailure
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
def test_with_dsym(self): def test_with_dsym(self):
"""Test expr + formatters for good interoperability.""" """Test expr + formatters for good interoperability."""
self.buildDsym() self.buildDsym()
self.do_my_test() self.do_my_test()
# rdar://problem/10153585 lldb ToT regression of test suite with r139772 check-in
@unittest2.expectedFailure
def test_with_dwarf_(self): def test_with_dwarf_(self):
"""Test expr + formatters for good interoperability.""" """Test expr + formatters for good interoperability."""
self.buildDsym() self.buildDsym()

View File

@ -12,7 +12,6 @@ class ObjCDataFormatterTestCase(TestBase):
mydir = os.path.join("functionalities", "data-formatter", "data-formatter-objc") mydir = os.path.join("functionalities", "data-formatter", "data-formatter-objc")
# rdar://problem/10153585 lldb ToT regression of test suite with r139772 check-in # rdar://problem/10153585 lldb ToT regression of test suite with r139772 check-in
@unittest2.expectedFailure
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin") @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
def test_with_dsym_and_run_command(self): def test_with_dsym_and_run_command(self):
"""Test data formatter commands.""" """Test data formatter commands."""
@ -20,7 +19,6 @@ class ObjCDataFormatterTestCase(TestBase):
self.data_formatter_commands() self.data_formatter_commands()
# rdar://problem/10153585 lldb ToT regression of test suite with r139772 check-in # rdar://problem/10153585 lldb ToT regression of test suite with r139772 check-in
@unittest2.expectedFailure
def test_with_dwarf_and_run_command(self): def test_with_dwarf_and_run_command(self):
"""Test data formatter commands.""" """Test data formatter commands."""
self.buildDwarf() self.buildDwarf()