Added automatically generated result variables for each
expression.  It is now possible to do things like this:

(lldb) expr int $i = 5; $i + 1
$0 = (int) 6
(lldb) expr $i + 3
$1 = (int) 8
(lldb) expr $1 + $0
$2 = (int) 14

As a bonus, this allowed us to move printing of
expression results into the ClangPersistentVariable
class.  This code needs a bit of refactoring -- in
particular, ClangExpressionDeclMap has eaten one too
many bacteria and needs to undergo mitosis -- but the
infrastructure appears to be holding up nicely.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@110896 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangPersistentVariables.cpp b/source/Expression/ClangPersistentVariables.cpp
index dbeac00..7e16648 100644
--- a/source/Expression/ClangPersistentVariables.cpp
+++ b/source/Expression/ClangPersistentVariables.cpp
@@ -8,11 +8,98 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangPersistentVariables.h"
+#include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/StreamString.h"
+#include "lldb/Core/Value.h"
 
 using namespace lldb_private;
-using namespace clang;
+
+Error
+ClangPersistentVariable::Print (Stream &output_stream,
+                                ExecutionContext &exe_ctx,
+                                lldb::Format format,
+                                bool show_types,
+                                bool show_summary,
+                                bool verbose)
+{
+    Error err;
+    
+    Value val;
+    
+    clang::ASTContext *ast_context = m_user_type.GetASTContext();
+    
+    val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ());
+    val.SetValueType (Value::eValueTypeHostAddress);
+    val.GetScalar() = (uint64_t)Data ();
+    
+    val.ResolveValue (&exe_ctx, ast_context);
+    
+    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;
+    }
+    
+    // The expression result is more complext and requires special handling
+    DataExtractor data;
+    Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0);
+    
+    if (!expr_error.Success ())
+    {
+        err.SetErrorToGenericError ();
+        err.SetErrorStringWithFormat ("Couldn't resolve result value: %s", expr_error.AsCString ());
+        return err;
+    }
+    
+    if (format == lldb::eFormatDefault)
+        format = val.GetValueDefaultFormat ();
+    
+    void *clang_type = val.GetValueOpaqueClangQualType ();
+    
+    output_stream.Printf("%s = ", m_name.AsCString("<anonymous>"));
+    
+    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;
+}
 
 ClangPersistentVariables::ClangPersistentVariables () :
     m_variables(),
@@ -24,7 +111,7 @@
 ClangPersistentVariables::CreateVariable (ConstString name, 
                                           TypeFromUser user_type)
 {    
-    ClangPersistentVariable new_var(user_type);
+    ClangPersistentVariable new_var(name, user_type);
     
     if (m_variables.find(name) != m_variables.end())
         return NULL;
@@ -35,21 +122,6 @@
 }
 
 ClangPersistentVariable *
-ClangPersistentVariables::CreateResultVariable (TypeFromUser user_type)
-{    
-    StreamString s;
-    s.Printf("$%llu", m_result_counter);
-    ConstString name(s.GetString().c_str());
-    
-    ClangPersistentVariable *ret = CreateVariable (name, user_type);
-    
-    if (ret != NULL)
-        ++m_result_counter;
-    
-    return ret;
-}
-
-ClangPersistentVariable *
 ClangPersistentVariables::GetVariable (ConstString name)
 {    
     if (m_variables.find(name) == m_variables.end())
@@ -57,3 +129,14 @@
     
     return &m_variables[name];
 }
+
+void
+ClangPersistentVariables::GetNextResultName (std::string &name)
+{
+    StreamString s;
+    s.Printf("$%llu", m_result_counter);
+    
+    m_result_counter++;
+    
+    name = s.GetString();
+}