Fixed a bug in the expression parser where the 'this'
or 'self' variable was not properly read if the compiler
optimized it into a register.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@126973 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Expression/ClangExpressionDeclMap.cpp b/source/Expression/ClangExpressionDeclMap.cpp
index b21d3eb..aa45992 100644
--- a/source/Expression/ClangExpressionDeclMap.cpp
+++ b/source/Expression/ClangExpressionDeclMap.cpp
@@ -551,41 +551,75 @@
         return false;
     }
     
-    if (location_value->GetValueType() == Value::eValueTypeLoadAddress)
+    switch (location_value->GetValueType())
     {
-        lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
-        uint32_t address_byte_size = exe_ctx.target->GetArchitecture().GetAddressByteSize();
-        lldb::ByteOrder address_byte_order = exe_ctx.process->GetByteOrder();
-        
-        if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(), 
-                                               m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
-        {
-            err.SetErrorStringWithFormat("'%s' is not of an expected pointer size", object_name.GetCString());
-            return false;
-        }
-        
-        DataBufferHeap data;
-        data.SetByteSize(address_byte_size);
-        Error read_error;
-        
-        if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
-        {
-            err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString());
-            return false;
-        }
-        
-        DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
-        
-        uint32_t offset = 0;
-        
-        object_ptr = extractor.GetPointer(&offset);
-        
-        return true;
-    }
-    else
-    {
+    default:
         err.SetErrorStringWithFormat("'%s' is not in memory; LLDB must be extended to handle registers", object_name.GetCString());
         return false;
+    case Value::eValueTypeLoadAddress:
+        {
+            lldb::addr_t value_addr = location_value->GetScalar().ULongLong();
+            uint32_t address_byte_size = exe_ctx.target->GetArchitecture().GetAddressByteSize();
+            lldb::ByteOrder address_byte_order = exe_ctx.process->GetByteOrder();
+            
+            if (ClangASTType::GetClangTypeBitWidth(m_struct_vars->m_object_pointer_type.GetASTContext(), 
+                                                   m_struct_vars->m_object_pointer_type.GetOpaqueQualType()) != address_byte_size * 8)
+            {
+                err.SetErrorStringWithFormat("'%s' is not of an expected pointer size", object_name.GetCString());
+                return false;
+            }
+            
+            DataBufferHeap data;
+            data.SetByteSize(address_byte_size);
+            Error read_error;
+            
+            if (exe_ctx.process->ReadMemory (value_addr, data.GetBytes(), address_byte_size, read_error) != address_byte_size)
+            {
+                err.SetErrorStringWithFormat("Coldn't read '%s' from the target: %s", object_name.GetCString(), read_error.AsCString());
+                return false;
+            }
+            
+            DataExtractor extractor(data.GetBytes(), data.GetByteSize(), address_byte_order, address_byte_size);
+            
+            uint32_t offset = 0;
+            
+            object_ptr = extractor.GetPointer(&offset);
+            
+            return true;
+        }
+    case Value::eValueTypeScalar:
+        {
+            if (location_value->GetContextType() != Value::eContextTypeRegisterInfo)
+            {
+                StreamString ss;
+                location_value->Dump(&ss);
+                
+                err.SetErrorStringWithFormat("%s is a scalar of unhandled type: %s", object_name.GetCString(), ss.GetString().c_str());
+                return false;
+            }
+                        
+            lldb::RegisterInfo *register_info = location_value->GetRegisterInfo();
+            
+            if (!register_info)
+            {
+                err.SetErrorStringWithFormat("Couldn't get the register information for %s", object_name.GetCString());
+                return false;
+            }
+            
+            RegisterContext *register_context = exe_ctx.GetRegisterContext();
+            
+            if (!register_context)
+            {
+                err.SetErrorStringWithFormat("Couldn't read register context to read %s from %s", object_name.GetCString(), register_info->name);
+                return false;
+            }
+            
+            uint32_t register_number = register_info->kinds[lldb::eRegisterKindLLDB];
+            
+            object_ptr = register_context->ReadRegisterAsUnsigned(register_number, 0x0);
+            
+            return true;
+        }
     }
 }