This commit completes the rearchitecting of ClangASTSource
to allow variables in the persistent variable store to know
how to complete themselves from debug information.  That
fixes a variety of bugs during dematerialization of 
expression results and also makes persistent variable and
result variables ($foo, $4, ...) more useful.

I have also added logging improvements that make it much
easier to figure out how types are moving from place to 
place, and made some checking a little more aggressive.

The commit includes patches to Clang which are currently being
integrated into Clang proper; once these fixes are in Clang
top-of-tree, these patches will be removed.  The patches don't
fix API; rather, they fix some internal bugs in Clang's 
ASTImporter that were exposed when LLDB was moving types from
place to place multiple times.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@144969 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index 382d7df..0ca8808 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -196,9 +196,9 @@
 
     ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
     
-    TypeFromUser user_type(ClangASTContext::CopyType(context, 
-                                                     type.GetASTContext(),
-                                                     type.GetOpaqueQualType()),
+    TypeFromUser user_type(m_ast_importer->CopyType(context, 
+                                                    type.GetASTContext(),
+                                                    type.GetOpaqueQualType()),
                            context);
     
     if (!m_parser_vars->m_persistent_vars->CreatePersistentVariable (exe_ctx->GetBestExecutionContextScope (),
@@ -285,9 +285,9 @@
     if (!var_sp)
         return ClangExpressionVariableSP();
     
-    TypeFromUser user_type(ClangASTContext::CopyType(context, 
-                                                     type.GetASTContext(),
-                                                     type.GetOpaqueQualType()),
+    TypeFromUser user_type(m_ast_importer->CopyType(context, 
+                                                    type.GetASTContext(),
+                                                    type.GetOpaqueQualType()),
                            context);
     
     TypeFromUser var_type = var_sp->GetTypeFromUser();
@@ -424,10 +424,17 @@
 
     ASTContext *context(target->GetScratchClangASTContext()->getASTContext());
     
-    TypeFromUser user_type(ClangASTContext::CopyType(context, 
-                                                     parser_type.GetASTContext(),
-                                                     parser_type.GetOpaqueQualType()),
+    TypeFromUser user_type(m_ast_importer->CopyType(context, 
+                                                    parser_type.GetASTContext(),
+                                                    parser_type.GetOpaqueQualType()),
                            context);
+    
+    if (!user_type.GetOpaqueQualType())
+    {
+        if (log)
+            log->Printf("Persistent variable's type wasn't copied successfully");
+        return false;
+    }
         
     if (!m_parser_vars->m_target_info.IsValid())
         return false;
@@ -499,7 +506,7 @@
         return false;
     
     if (log)
-        log->Printf("Adding value for decl %p [%s - %s] to the structure",
+        log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
                     decl,
                     name.GetCString(),
                     var_sp->GetName().GetCString());
@@ -936,8 +943,15 @@
                 return err.Success();
             }
             case Value::eValueTypeHostAddress:
-                memcpy (data, (const void *)value.GetScalar().ULongLong(), length);
+            {
+                void *host_addr = (void*)value.GetScalar().ULongLong();
+                
+                if (!host_addr)
+                    return false;
+                
+                memcpy (data, host_addr, length);
                 return true;
+            }
             case Value::eValueTypeScalar:
                 return false;
         }
@@ -1370,12 +1384,16 @@
             log->PutCString("Allocating memory for materialized argument struct");
         
         lldb::addr_t mem = process->AllocateMemory(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size, 
-                                                           lldb::ePermissionsReadable | lldb::ePermissionsWritable,
-                                                           err);
+                                                   lldb::ePermissionsReadable | lldb::ePermissionsWritable,
+                                                   err);
         
         if (mem == LLDB_INVALID_ADDRESS)
+        {
+            err.SetErrorStringWithFormat("Couldn't allocate 0x%llx bytes for materialized argument struct", 
+                                         (unsigned long long)(m_struct_vars->m_struct_alignment + m_struct_vars->m_struct_size));
             return false;
-        
+        }
+            
         m_material_vars->m_allocated_area = mem;
     }
     
@@ -1400,8 +1418,11 @@
                 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
                 
                 if (!reg_ctx)
+                {
+                    err.SetErrorString("Couldn't get register context");
                     return false;
-                
+                }
+                    
                 if (!DoMaterializeOneRegister (dematerialize, 
                                                exe_ctx, 
                                                *reg_ctx, 
@@ -1413,7 +1434,10 @@
             else
             {
                 if (!member_sp->m_jit_vars.get())
+                {
+                    err.SetErrorString("Variable being materialized doesn't have necessary state");
                     return false;
+                }
                 
                 if (!DoMaterializeOneVariable (dematerialize, 
                                                exe_ctx, 
@@ -1485,7 +1509,10 @@
     
     uint8_t *pvar_data = var_sp->GetValueBytes();
     if (pvar_data == NULL)
+    {
+        err.SetErrorString("Persistent variable being materialized contains no data");
         return false;
+    }
     
     Error error;
     Process *process = exe_ctx.GetProcessPtr();
@@ -1689,7 +1716,10 @@
     StackFrame *frame = exe_ctx.GetFramePtr();
 
     if (!frame || !process || !target || !m_parser_vars.get() || !expr_var->m_parser_vars.get())
+    {
+        err.SetErrorString("Necessary state for variable materialization isn't present");
         return false;
+    }
     
     // Vital information about the value
     
@@ -2200,7 +2230,7 @@
         ClangASTImporter::NamespaceMapSP namespace_map = m_ast_importer->GetNamespaceMap(namespace_context);
         
         if (log && log->GetVerbose())
-            log->Printf("  CEDM::FEVD[%u] Inspecting namespace map %p (%d entries)", 
+            log->Printf("  CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)", 
                         current_id, 
                         namespace_map.get(), 
                         (int)namespace_map->size());
@@ -2873,7 +2903,7 @@
             QualType var_type = var_decl->getType();
             TypeFromParser parser_type(var_type.getAsOpaquePtr(), &var_decl->getASTContext());
             
-            lldb::clang_type_t copied_type = ClangASTContext::CopyType(scratch_ast_context, &var_decl->getASTContext(), var_type.getAsOpaquePtr());
+            lldb::clang_type_t copied_type = m_ast_importer->CopyType(scratch_ast_context, &var_decl->getASTContext(), var_type.getAsOpaquePtr());
             
             TypeFromUser user_type(copied_type, scratch_ast_context);