Added a new ValueObject type that will be used to freeze dry expression
results. The clang opaque type for the expression result will be added to the
Target's ASTContext, and the bytes will be stored in a DataBuffer inside
the new object. The class is named: ValueObjectConstResult

Now after an expression is evaluated, we can get a ValueObjectSP back that
contains a ValueObjectConstResult object.

Relocated the value object dumping code into a static function within
the ValueObject class instead of being in the CommandObjectFrame.cpp file
which is what contained the code to dump variables ("frame variables").




git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@115578 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionVariable.cpp b/source/Expression/ClangExpressionVariable.cpp
index 0ae37e4..d6798f5 100644
--- a/source/Expression/ClangExpressionVariable.cpp
+++ b/source/Expression/ClangExpressionVariable.cpp
@@ -18,154 +18,74 @@
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 
 using namespace lldb_private;
 using namespace clang;
 
-ClangExpressionVariable::ClangExpressionVariable()
+ClangExpressionVariable::ClangExpressionVariable() :
+    m_name(),
+    m_user_type (TypeFromUser(NULL, NULL)),
+    m_store (NULL),
+    m_index (0),
+    m_parser_vars(),
+    m_jit_vars (),
+    m_data_sp ()
 {
-    m_name = "";
-    m_user_type = TypeFromUser(NULL, NULL);
-    m_parser_vars.reset(NULL);
-    m_jit_vars.reset(NULL);
-    m_data_vars.reset(NULL);
 }
 
-void ClangExpressionVariable::DisableDataVars()
+void 
+ClangExpressionVariable::DisableDataVars()
 {
-    if (m_data_vars.get() && m_data_vars->m_data)
-        delete m_data_vars->m_data;
-    m_data_vars.reset();
+    m_data_sp.reset();
 }
 
-Error
-ClangExpressionVariable::Print (Stream &output_stream,
-                                ExecutionContext &exe_ctx,
-                                lldb::Format format,
-                                bool show_types,
-                                bool show_summary,
-                                bool verbose)
-{
-    Error err;
-    
-    Value val;
-    if (!PointValueAtData (val, NULL))
-    {
-        err.SetErrorToGenericError();
-        err.SetErrorStringWithFormat("Variable doesn't contain a value");
-        return err;
-    }
-    
-    if (val.GetContextType () == Value::eContextTypeInvalid &&
-        val.GetValueType () == Value::eValueTypeScalar &&
-        format == lldb::eFormatDefault)
-    {
-        // The expression result is just a scalar with no special formatting
-        val.GetScalar ().GetValue (&output_stream, show_types);
-        output_stream.EOL ();
-        return err;
-    }
-    
-    clang::ASTContext *ast_context = m_user_type.GetASTContext();
 
-    // The expression result is more complex and requires special handling
-    DataExtractor data;
-    Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0);
-    
-    
-    // Set byte order and pointer size to TARGET byte order and pointer size!
-    
-    data.SetByteOrder(exe_ctx.process->GetByteOrder());
-    data.SetAddressByteSize(exe_ctx.process->GetAddressByteSize());
-    
-    if (!expr_error.Success ())
-    {
-        err.SetErrorToGenericError ();
-        err.SetErrorStringWithFormat ("Couldn't resolve variable value: %s", expr_error.AsCString ());
-        return err;
-    }
-    
-    if (format == lldb::eFormatDefault)
-        format = val.GetValueDefaultFormat ();
-    
-    void *clang_type = val.GetClangType ();
-    
-    output_stream.Printf("%s = ", m_name.c_str());
-    
-    if (clang_type)
-    {
-        if (show_types)
-            output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString());
-        
-        ClangASTType::DumpValue (ast_context,               // The ASTContext that the clang type belongs to
-                                 clang_type,                // The opaque clang type we want to dump that value of
-                                 &exe_ctx,                  // The execution context for memory and variable access
-                                 &output_stream,            // Stream to dump to
-                                 format,                    // Format to use when dumping
-                                 data,                      // A buffer containing the bytes for the clang type
-                                 0,                         // Byte offset within "data" where value is
-                                 data.GetByteSize (),       // Size in bytes of the value we are dumping
-                                 0,                         // Bitfield bit size
-                                 0,                         // Bitfield bit offset
-                                 show_types,                // Show types?
-                                 show_summary,              // Show summary?
-                                 verbose,                   // Debug logging output?
-                                 UINT32_MAX);               // Depth to dump in case this is an aggregate type
-    }
-    else
-    {
-        data.Dump (&output_stream,          // Stream to dump to
-                   0,                       // Byte offset within "data"
-                   format,                  // Format to use when dumping
-                   data.GetByteSize (),     // Size in bytes of each item we are dumping
-                   1,                       // Number of items to dump
-                   UINT32_MAX,              // Number of items per line
-                   LLDB_INVALID_ADDRESS,    // Invalid address, don't show any offset/address context
-                   0,                       // Bitfield bit size
-                   0);                      // Bitfield bit offset
-    }
-    
-    output_stream.EOL();
-    
-    return err;
-}
-
-ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &cev) :
-    m_name(cev.m_name),
-    m_user_type(cev.m_user_type),
-    m_store(cev.m_store),
-    m_index(cev.m_index)
+ClangExpressionVariable::ClangExpressionVariable(const ClangExpressionVariable &rhs) :
+    m_name(rhs.m_name),
+    m_user_type(rhs.m_user_type),
+    m_store(rhs.m_store),
+    m_index(rhs.m_index)
 {
-    if (cev.m_parser_vars.get())
+    if (rhs.m_parser_vars.get())
     {
+        // TODO: Sean, can m_parser_vars be a shared pointer??? We are copy
+        // constructing it here. That is ok if we need to, but do we really
+        // need to?
         m_parser_vars.reset(new struct ParserVars);
-        *m_parser_vars.get() = *cev.m_parser_vars.get();
+        *m_parser_vars.get() = *rhs.m_parser_vars.get();
     }
     
-    if (cev.m_jit_vars.get())
+    if (rhs.m_jit_vars.get())
     {
+        // TODO: Sean, can m_jit_vars be a shared pointer??? We are copy
+        // constructing it here. That is ok if we need to, but do we really
+        // need to?
         m_jit_vars.reset(new struct JITVars);
-        *m_jit_vars.get() = *cev.m_jit_vars.get();
+        *m_jit_vars.get() = *rhs.m_jit_vars.get();
     }
     
-    if (cev.m_data_vars.get())
+    if (rhs.m_data_sp)
     {
-        m_data_vars.reset(new struct DataVars);
-        *m_data_vars.get() = *cev.m_data_vars.get();
+        // TODO: Sean, does m_data_sp need to be copy constructed? Or can it
+        // shared the data?
+        
+        m_data_sp.reset(new DataBufferHeap (rhs.m_data_sp->GetBytes(),
+                                            rhs.m_data_sp->GetByteSize()));
     }
 }
 
 bool
 ClangExpressionVariable::PointValueAtData(Value &value, ExecutionContext *exe_ctx)
 {
-    if (!m_data_vars.get() || !m_data_vars->m_data)
+    if (m_data_sp.get() == NULL)
         return false;
     
     value.SetContext(Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType());
     value.SetValueType(Value::eValueTypeHostAddress);
-    value.GetScalar() = (uint64_t)m_data_vars->m_data->GetBytes();
+    value.GetScalar() = (uintptr_t)m_data_sp->GetBytes();
     clang::ASTContext *ast_context = m_user_type.GetASTContext();
 
     if (exe_ctx)
@@ -173,3 +93,46 @@
     
     return true;
 }
+
+void 
+ClangExpressionVariable::EnableDataVars()
+{
+    if (!m_data_sp.get())
+        m_data_sp.reset(new DataBufferHeap);
+}
+
+lldb::ValueObjectSP
+ClangExpressionVariable::GetExpressionResult (ExecutionContext *exe_ctx)
+{
+    lldb::ValueObjectSP result_sp;
+    if (m_data_sp)
+    {
+        Target * target = NULL;
+        Process *process = NULL;
+        if (exe_ctx)
+        {
+            target = exe_ctx->target;
+            process = exe_ctx->process;
+        }
+        
+        Value value;
+        if (PointValueAtData(value, exe_ctx))
+        {
+            lldb::ByteOrder byte_order = lldb::eByteOrderHost;
+            uint32_t addr_byte_size = 4;
+            if (process)
+            {
+                byte_order = process->GetByteOrder();
+                addr_byte_size = process->GetAddressByteSize();
+            }
+            result_sp.reset (new ValueObjectConstResult (m_user_type.GetASTContext(),
+                                                         m_user_type.GetOpaqueQualType(),
+                                                         ConstString (m_name.c_str()),
+                                                         m_data_sp,// TODO: sean can you get this to be valid?
+                                                         byte_order,
+                                                         addr_byte_size));
+        }
+    }
+    return result_sp;
+}
+