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/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index da4333c..fb10605 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -83,22 +83,25 @@
 
 // Interface for IRForTarget
 
+void
+ClangExpressionDeclMap::GetPersistentResultName (std::string &name)
+{
+    m_persistent_vars->GetNextResultName(m_result_name);
+    
+    name = m_result_name;
+}
+
 bool 
-ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl)
+ClangExpressionDeclMap::AddPersistentVariable (const char *name, TypeFromParser parser_type)
 {
     clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext());
     
-    const clang::VarDecl *var(dyn_cast<clang::VarDecl>(decl));
-    
-    if (!var)
-        return false;
-    
     TypeFromUser user_type(ClangASTContext::CopyType(context, 
-                                                     &var->getASTContext(),
-                                                     var->getType().getAsOpaquePtr()),
+                                                     parser_type.GetASTContext(),
+                                                     parser_type.GetOpaqueQualType()),
                             context);
     
-    ConstString const_name(decl->getName().str().c_str());
+    ConstString const_name(name);
     
     ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type);
     
@@ -292,10 +295,10 @@
 
 bool 
 ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx,
-                                       lldb_private::Value &result_value,
+                                       ClangPersistentVariable *&result,
                                        Error &err)
 {
-    return DoMaterialize(true, exe_ctx, &result_value, err);
+    return DoMaterialize(true, exe_ctx, &result, err);
 }
 
 bool
@@ -366,11 +369,11 @@
 bool 
 ClangExpressionDeclMap::DoMaterialize (bool dematerialize,
                                        ExecutionContext *exe_ctx,
-                                       lldb_private::Value *result_value,
+                                       ClangPersistentVariable **result,
                                        Error &err)
 {
     Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS);
-
+    
     if (!m_struct_laid_out)
     {
         err.SetErrorString("Structure hasn't been laid out yet");
@@ -426,36 +429,54 @@
         
         if (!GetIndexForDecl(tuple_index, iter->m_decl)) 
         {
+            if (iter->m_name.find("___clang_expr_result") != std::string::npos)
+            {
+                if (dematerialize)
+                {
+                    // Here we pick up the odd anomaly produced by 
+                    // IRForTarget::createResultVariable (and described in a comment
+                    // there).
+                    //
+                    // We rename the variable to the name of the result PVar and
+                    // incidentally drop the address of the PVar into *result
+                    // (if it's non-NULL, of course).  We then let this case fall 
+                    // through to the persistent variable handler.
+                    
+                    if (log)
+                        log->PutCString("Found result member in the struct");
+                    
+                    iter->m_name = m_result_name;
+                    
+                    if (result)
+                    {
+                        if (log)
+                            log->PutCString("Returning result PVar");
+                        
+                        *result = m_persistent_vars->GetVariable(ConstString(m_result_name.c_str()));
+                        
+                        if (!*result)
+                        {
+                            err.SetErrorStringWithFormat("Couldn't find persistent variable for result %s", m_result_name.c_str());
+                        }
+                    }
+                    else
+                    {
+                        if (log)
+                            log->PutCString("Didn't return result PVar; pointer was NULL");
+                    }
+                }
+                else
+                {
+                    // The result variable doesn't need to be materialized, ever.
+                    continue;
+                }
+            }
+            
             if (iter->m_name[0] == '$')
             {
                 if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err))
                     return false;
             }
-            else if (iter->m_name.find("___clang_expr_result") != std::string::npos)
-            {
-                if (log)
-                    log->Printf("Found special result variable %s", iter->m_name.c_str());
-                
-                if (dematerialize)
-                {
-                    clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext());
-                    
-                    if (!context)
-                    {
-                        err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); 
-                    }
-                    
-                    TypeFromUser copied_type(ClangASTContext::CopyType(context, 
-                                                                       iter->m_parser_type.GetASTContext(),
-                                                                       iter->m_parser_type.GetOpaqueQualType()),
-                                             context);
-                    
-                    result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType());
-                    
-                    result_value->SetValueType(Value::eValueTypeLoadAddress);
-                    result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset;
-                }
-            }
             else
             {
                 err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str());