Improve the x86_64 return value decoder to handle most structure returns.
Switch from GetReturnValue, which was hardly ever used, to GetReturnValueObject
which is much more convenient.
Return the "return value object" as a persistent variable if requested.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@147157 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/ABI.cpp b/source/Target/ABI.cpp
index f3a5404..7d82ab1 100644
--- a/source/Target/ABI.cpp
+++ b/source/Target/ABI.cpp
@@ -12,6 +12,7 @@
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
using namespace lldb;
@@ -104,25 +105,69 @@
ValueObjectSP
ABI::GetReturnValueObject (Thread &thread,
- ClangASTType &ast_type) const
+ ClangASTType &ast_type,
+ bool persistent) const
{
if (!ast_type.IsValid())
return ValueObjectSP();
- Value ret_value;
- ret_value.SetContext(Value::eContextTypeClangType,
- ast_type.GetOpaqueQualType());
- if (GetReturnValue (thread, ret_value))
+ ValueObjectSP return_valobj_sp;
+
+ return_valobj_sp = GetReturnValueObjectImpl(thread, ast_type);
+ if (!return_valobj_sp)
+ return return_valobj_sp;
+
+ // Now turn this into a persistent variable.
+ // FIXME: This code is duplicated from Target::EvaluateExpression, and it is used in similar form in a couple
+ // of other places. Figure out the correct Create function to do all this work.
+
+ if (persistent)
{
- return ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(),
- ast_type.GetASTContext(),
- ret_value,
- ConstString("FunctionReturn"));
+ ClangPersistentVariables& persistent_variables = thread.GetProcess().GetTarget().GetPersistentVariables();
+ ConstString persistent_variable_name (persistent_variables.GetNextPersistentVariableName());
+
+ lldb::ValueObjectSP const_valobj_sp;
+
+ // Check in case our value is already a constant value
+ if (return_valobj_sp->GetIsConstant())
+ {
+ const_valobj_sp = return_valobj_sp;
+ const_valobj_sp->SetName (persistent_variable_name);
+ }
+ else
+ const_valobj_sp = return_valobj_sp->CreateConstantValue (persistent_variable_name);
+
+ lldb::ValueObjectSP live_valobj_sp = return_valobj_sp;
+
+ return_valobj_sp = const_valobj_sp;
+
+ ClangExpressionVariableSP clang_expr_variable_sp(persistent_variables.CreatePersistentVariable(return_valobj_sp));
+
+ assert (clang_expr_variable_sp.get());
+
+ // Set flags and live data as appropriate
+
+ const Value &result_value = live_valobj_sp->GetValue();
+
+ switch (result_value.GetValueType())
+ {
+ case Value::eValueTypeHostAddress:
+ case Value::eValueTypeFileAddress:
+ // we don't do anything with these for now
+ break;
+ case Value::eValueTypeScalar:
+ clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
+ clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
+ break;
+ case Value::eValueTypeLoadAddress:
+ clang_expr_variable_sp->m_live_sp = live_valobj_sp;
+ clang_expr_variable_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference;
+ break;
+ }
+ return_valobj_sp = clang_expr_variable_sp->GetValueObject();
}
- else
- return ValueObjectSP();
+ return return_valobj_sp;
}