[ProcessWindows] Implement a RegisterContextWindows for x86.

This implements the skeleton of a RegisterContext for Windows.
In particular, this implements support only for x86 general purpose
registers.

After this patch, LLDB on Windows can perform basic debugging
operations in a single-threaded inferior process (breakpoint,
register inspection, frame select, unwinding, etc).

Differential Revision: http://reviews.llvm.org/D6322
Reviewed by: Greg Clayton

llvm-svn: 222474
diff --git a/lldb/source/Plugins/Process/Windows/TargetThreadWindows.cpp b/lldb/source/Plugins/Process/Windows/TargetThreadWindows.cpp
index 2ca55d7..1c33f21 100644
--- a/lldb/source/Plugins/Process/Windows/TargetThreadWindows.cpp
+++ b/lldb/source/Plugins/Process/Windows/TargetThreadWindows.cpp
@@ -7,11 +7,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "TargetThreadWindows.h"
-#include "ProcessWindows.h"
+#include "lldb/Host/HostInfo.h"
 #include "lldb/Host/HostNativeThreadBase.h"
 #include "lldb/Host/windows/HostThreadWindows.h"
 #include "lldb/Host/windows/windows.h"
+#include "lldb/Target/RegisterContext.h"
+
+#include "TargetThreadWindows.h"
+#include "ProcessWindows.h"
+#include "RegisterContextWindows_x86.h"
+#include "UnwindLLDB.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -30,6 +35,7 @@
 void
 TargetThreadWindows::RefreshStateAfterStop()
 {
+    GetRegisterContext()->InvalidateIfNeeded(false);
 }
 
 void
@@ -45,19 +51,51 @@
 RegisterContextSP
 TargetThreadWindows::GetRegisterContext()
 {
-    return RegisterContextSP();
+    if (!m_reg_context_sp)
+        m_reg_context_sp = CreateRegisterContextForFrameIndex(0);
+
+    return m_reg_context_sp;
 }
 
 RegisterContextSP
 TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame)
 {
-    return RegisterContextSP();
+    return CreateRegisterContextForFrameIndex(frame->GetConcreteFrameIndex());
+}
+
+RegisterContextSP
+TargetThreadWindows::CreateRegisterContextForFrameIndex(uint32_t idx)
+{
+    if (!m_reg_context_sp)
+    {
+        ArchSpec arch = HostInfo::GetArchitecture();
+        switch (arch.GetMachine())
+        {
+            case llvm::Triple::x86:
+                m_reg_context_sp.reset(new RegisterContextWindows_x86(*this, idx));
+                break;
+            default:
+                // FIXME: Support x64 by creating a RegisterContextWindows_x86_64
+                break;
+        }
+    }
+    return m_reg_context_sp;
 }
 
 bool
 TargetThreadWindows::CalculateStopInfo()
 {
-    return false;
+    SetStopInfo(m_stop_info_sp);
+    return true;
+}
+
+Unwind *
+TargetThreadWindows::GetUnwinder()
+{
+    // FIXME: Implement an unwinder based on the Windows unwinder exposed through DIA SDK.
+    if (m_unwinder_ap.get() == NULL)
+        m_unwinder_ap.reset(new UnwindLLDB(*this));
+    return m_unwinder_ap.get();
 }
 
 bool