SBValue::Watch() and SBValue::WatchPointee() are now the official API for creating
a watchpoint for either the variable encapsulated by SBValue (Watch) or the pointee
encapsulated by SBValue (WatchPointee).

Removed SBFrame::WatchValue() and SBFrame::WatchLocation() API as a result of that.

Modified the watchpoint related test suite to reflect the change.

Plus replacing WatchpointLocation with Watchpoint throughout the code base.

There are still cleanups to be dome.  This patch passes the whole test suite.
Check it in so that we aggressively catch regressions.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@141925 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/API/SBFrame.cpp b/source/API/SBFrame.cpp
index 7c18687..f72f8bf 100644
--- a/source/API/SBFrame.cpp
+++ b/source/API/SBFrame.cpp
@@ -14,7 +14,6 @@
 
 #include "lldb/lldb-types.h"
 
-#include "lldb/Breakpoint/WatchpointLocation.h"
 #include "lldb/Core/Address.h"
 #include "lldb/Core/ConstString.h"
 #include "lldb/Core/Log.h"
@@ -406,119 +405,6 @@
     return value;
 }
 
-/// Find and watch a variable using the frame as the scope.
-/// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch.
-SBValue
-SBFrame::WatchValue (const char *name, ValueType value_type, uint32_t watch_type)
-{
-    SBValue sb_value_empty;
-
-    if (!IsValid())
-        return sb_value_empty;
-
-    // Acquire the API locker, to be released at the end of the method call.
-    Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
-
-    switch (value_type) {
-    case eValueTypeVariableGlobal:      // global variable
-    case eValueTypeVariableStatic:      // static variable
-    case eValueTypeVariableArgument:    // function argument variables
-    case eValueTypeVariableLocal:       // function local variables
-        break;
-    default:
-        return sb_value_empty;          // these are not eligible for watching
-    }
-
-    SBValue sb_value = FindValue(name, value_type);
-    // If the SBValue is not valid, there's no point in even trying to watch it.
-    if (!sb_value.IsValid())
-        return sb_value;
-
-    addr_t addr = sb_value.GetLoadAddress();
-    size_t size = sb_value.GetByteSize();
-
-    WatchpointLocationSP wp_loc_sp = m_opaque_sp->GetThread().GetProcess().GetTarget().
-        CreateWatchpointLocation(addr, size, watch_type);
-
-    if (wp_loc_sp) {
-        // StackFrame::GetInScopeVariableList(true) to get file globals as well.
-        VariableListSP var_list_sp(m_opaque_sp->GetInScopeVariableList(true));
-        VariableSP var_sp = var_list_sp->FindVariable(ConstString(name));
-        if (var_sp && var_sp->GetDeclaration().GetFile()) {
-            StreamString ss;
-            // True to show fullpath for declaration file.
-            var_sp->GetDeclaration().DumpStopContext(&ss, true);
-            wp_loc_sp->SetDeclInfo(ss.GetString());
-        }
-    }
-
-    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    if (log)
-        log->Printf ("SBFrame(%p)::WatchValue (name=\"%s\", value_type=%i, watch_type=%i) => SBValue(%p) & wp_loc(%p)", 
-                     m_opaque_sp.get(), name, value_type, watch_type, sb_value.get(), wp_loc_sp.get());
-
-    return wp_loc_sp ? sb_value : sb_value_empty;
-}
-
-/// Find and watch the location pointed to by a variable using the frame as
-/// the scope.
-/// It returns an SBValue, similar to FindValue() method, if find-and-watch
-/// operation succeeds.  Otherwise, an invalid SBValue is returned.
-/// You can use LLDB_WATCH_TYPE_READ | LLDB_WATCH_TYPE_WRITE for 'rw' watch.
-SBValue
-SBFrame::WatchLocation (const char *name, ValueType value_type, uint32_t watch_type, size_t size)
-{
-    SBValue sb_value_empty;
-
-    if (!IsValid())
-        return sb_value_empty;
-
-    // Acquire the API locker, to be released at the end of the method call.
-    Mutex::Locker api_locker (m_opaque_sp->GetThread().GetProcess().GetTarget().GetAPIMutex());
-
-    switch (value_type) {
-    case eValueTypeVariableGlobal:      // global variable
-    case eValueTypeVariableStatic:      // static variable
-    case eValueTypeVariableArgument:    // function argument variables
-    case eValueTypeVariableLocal:       // function local variables
-        break;
-    default:
-        return sb_value_empty;          // these are not eligible for watching
-    }
-
-    SBValue sb_pointer = FindValue(name, value_type);
-    // If the sb_pointer is not valid, there's no point in even trying to watch it.
-    if (!sb_pointer.IsValid() || !sb_pointer.GetType().IsPointerType())
-        return sb_value_empty;
-
-    addr_t addr = sb_pointer.GetValueAsUnsigned(0);
-    if (!addr)
-        return sb_value_empty;
-
-    SBValue sb_value = sb_pointer.CreateValueFromAddress("pointee", addr, sb_pointer.GetType().GetPointeeType());
-    WatchpointLocationSP wp_loc_sp = m_opaque_sp->GetThread().GetProcess().GetTarget().
-        CreateWatchpointLocation(addr, size, watch_type);
-
-    if (wp_loc_sp) {
-        // StackFrame::GetInScopeVariableList(true) to get file globals as well.
-        VariableListSP var_list_sp(m_opaque_sp->GetInScopeVariableList(true));
-        VariableSP var_sp = var_list_sp->FindVariable(ConstString(name));
-        if (var_sp && var_sp->GetDeclaration().GetFile()) {
-            StreamString ss;
-            // True to show fullpath for declaration file.
-            var_sp->GetDeclaration().DumpStopContext(&ss, true);
-            wp_loc_sp->SetDeclInfo(ss.GetString());
-        }
-    }
-
-    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
-    if (log)
-        log->Printf ("SBFrame(%p)::WatchLocation (name=\"%s\", value_type=%i, watch_type=%i, size=%lu) => SBValue(%p) & wp_loc(%p)", 
-                     m_opaque_sp.get(), name, value_type, watch_type, size, sb_value.get(), wp_loc_sp.get());
-
-    return wp_loc_sp ? sb_value : sb_value_empty;
-}
-
 SBValue
 SBFrame::FindValue (const char *name, ValueType value_type, lldb::DynamicValueType use_dynamic)
 {
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index 3cdfe1d..652d470 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -887,8 +887,8 @@
 {
     if (m_opaque_sp)
     {
-        // The watchpoint location list is thread safe, no need to lock
-        return m_opaque_sp->GetWatchpointLocationList().GetSize();
+        // The watchpoint list is thread safe, no need to lock
+        return m_opaque_sp->GetWatchpointList().GetSize();
     }
     return 0;
 }
@@ -896,13 +896,13 @@
 SBWatchpoint
 SBTarget::GetWatchpointAtIndex (uint32_t idx) const
 {
-    SBWatchpoint sb_watchpoint_location;
+    SBWatchpoint sb_watchpoint;
     if (m_opaque_sp)
     {
-        // The watchpoint location list is thread safe, no need to lock
-        *sb_watchpoint_location = m_opaque_sp->GetWatchpointLocationList().GetByIndex(idx);
+        // The watchpoint list is thread safe, no need to lock
+        *sb_watchpoint = m_opaque_sp->GetWatchpointList().GetByIndex(idx);
     }
-    return sb_watchpoint_location;
+    return sb_watchpoint;
 }
 
 bool
@@ -914,12 +914,12 @@
     if (m_opaque_sp)
     {
         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
-        result = m_opaque_sp->RemoveWatchpointLocationByID (wp_id);
+        result = m_opaque_sp->RemoveWatchpointByID (wp_id);
     }
 
     if (log)
     {
-        log->Printf ("SBTarget(%p)::WatchpointLocationDelete (wp_id=%d) => %i", m_opaque_sp.get(), (uint32_t) wp_id, result);
+        log->Printf ("SBTarget(%p)::WatchpointDelete (wp_id=%d) => %i", m_opaque_sp.get(), (uint32_t) wp_id, result);
     }
 
     return result;
@@ -934,12 +934,12 @@
     if (m_opaque_sp && wp_id != LLDB_INVALID_WATCH_ID)
     {
         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
-        *sb_watchpoint = m_opaque_sp->GetWatchpointLocationList().FindByID(wp_id);
+        *sb_watchpoint = m_opaque_sp->GetWatchpointList().FindByID(wp_id);
     }
 
     if (log)
     {
-        log->Printf ("SBTarget(%p)::FindWatchpointLocationByID (bp_id=%d) => SBWatchpoint(%p)", 
+        log->Printf ("SBTarget(%p)::FindWatchpointByID (bp_id=%d) => SBWatchpoint(%p)", 
                      m_opaque_sp.get(), (uint32_t) wp_id, sb_watchpoint.get());
     }
 
@@ -955,8 +955,9 @@
     if (m_opaque_sp)
     {
         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
-        // TODO: Johnny fill this in
-        //*sb_watchpoint = m_opaque_sp->GetWatchpointLocationList().FindByID(wp_id);
+        uint32_t watch_type = (read ? LLDB_WATCH_TYPE_READ : 0) |
+            (write ? LLDB_WATCH_TYPE_WRITE : 0);
+        WatchpointSP wp_sp = m_opaque_sp->CreateWatchpoint(addr, size, watch_type);
     }
     
     if (log)
@@ -974,7 +975,7 @@
     if (m_opaque_sp)
     {
         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
-        m_opaque_sp->EnableAllWatchpointLocations ();
+        m_opaque_sp->EnableAllWatchpoints ();
         return true;
     }
     return false;
@@ -986,7 +987,7 @@
     if (m_opaque_sp)
     {
         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
-        m_opaque_sp->DisableAllWatchpointLocations ();
+        m_opaque_sp->DisableAllWatchpoints ();
         return true;
     }
     return false;
@@ -998,7 +999,7 @@
     if (m_opaque_sp)
     {
         Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
-        m_opaque_sp->RemoveAllWatchpointLocations ();
+        m_opaque_sp->RemoveAllWatchpoints ();
         return true;
     }
     return false;
diff --git a/source/API/SBValue.cpp b/source/API/SBValue.cpp
index 8afd564..dc594cb 100644
--- a/source/API/SBValue.cpp
+++ b/source/API/SBValue.cpp
@@ -10,6 +10,7 @@
 #include "lldb/API/SBValue.h"
 #include "lldb/API/SBStream.h"
 
+#include "lldb/Breakpoint/Watchpoint.h"
 #include "lldb/Core/DataExtractor.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Module.h"
@@ -22,6 +23,7 @@
 #include "lldb/Symbol/Block.h"
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Symbol/Variable.h"
+#include "lldb/Symbol/VariableList.h"
 #include "lldb/Target/ExecutionContext.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
@@ -1102,12 +1104,19 @@
 SBValue::Watch (bool resolve_location, bool read, bool write)
 {
     lldb::SBWatchpoint sb_watchpoint;
+    if (!m_opaque_sp)
+        return sb_watchpoint;
+
     Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
     if (target)
     {
         Mutex::Locker api_locker (target->GetAPIMutex());
-        // TODO: Johnny fill this in
+        sb_watchpoint = WatchValue(read, write, false);
     }
+    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+    if (log)
+        log->Printf ("SBValue(%p)::Watch (resolve_location=%i, read=%i, write=%i) => wp(%p)", 
+                     m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get());
     return sb_watchpoint;
 }
 
@@ -1115,13 +1124,70 @@
 SBValue::WatchPointee (bool resolve_location, bool read, bool write)
 {
     lldb::SBWatchpoint sb_watchpoint;
+    if (!m_opaque_sp)
+        return sb_watchpoint;
+
     Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get();
     if (target)
     {
         Mutex::Locker api_locker (target->GetAPIMutex());
-        // TODO: Johnny fill this in
+        sb_watchpoint = WatchValue(read, write, true);
     }
+    LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+    if (log)
+        log->Printf ("SBValue(%p)::WatchPointee (resolve_location=%i, read=%i, write=%i) => wp(%p)", 
+                     m_opaque_sp.get(), resolve_location, read, write, sb_watchpoint.get());
     return sb_watchpoint;
 }
 
+// Helper function for SBValue::Watch() and SBValue::WatchPointee().
+SBWatchpoint
+SBValue::WatchValue(bool read, bool write, bool watch_pointee)
+{
+    SBWatchpoint sb_wp_empty;
+
+    // If the SBValue is not valid, there's no point in even trying to watch it.
+    if (!IsValid() || !GetFrame().IsValid())
+        return sb_wp_empty;
+
+    // Read and Write cannot both be false.
+    if (!read && !write)
+        return sb_wp_empty;
+
+    // If we are watching the pointee, check that the SBValue is a pointer type.
+    if (watch_pointee && !GetType().IsPointerType())
+        return sb_wp_empty;
+
+    addr_t addr;
+    size_t size;
+    if (watch_pointee) {
+        addr = GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+        size = GetType().GetPointeeType().GetByteSize();
+    } else {
+        addr = GetLoadAddress();
+        size = GetByteSize();
+    }
+
+    // Sanity check the address and the size before calling Target::CreateWatchpoint().
+    if (addr == LLDB_INVALID_ADDRESS || size == 0)
+        return sb_wp_empty;
+
+    uint32_t watch_type = (read ? LLDB_WATCH_TYPE_READ : 0) |
+        (write ? LLDB_WATCH_TYPE_WRITE : 0);
+    WatchpointSP wp_sp = GetFrame().m_opaque_sp->GetThread().GetProcess().GetTarget().
+        CreateWatchpoint(addr, size, watch_type);
+
+    if (wp_sp) {
+        // StackFrame::GetInScopeVariableList(true) to get file globals as well.
+        VariableListSP var_list_sp(GetFrame().m_opaque_sp->GetInScopeVariableList(true));
+        VariableSP var_sp = var_list_sp->FindVariable(ConstString(GetName()));
+        if (var_sp && var_sp->GetDeclaration().GetFile()) {
+            StreamString ss;
+            // True to show fullpath for declaration file.
+            var_sp->GetDeclaration().DumpStopContext(&ss, true);
+            wp_sp->SetDeclInfo(ss.GetString());
+        }
+    }
+    return wp_sp;
+}
 
diff --git a/source/API/SBWatchpoint.cpp b/source/API/SBWatchpoint.cpp
index a921ea1..e3f9d8c 100644
--- a/source/API/SBWatchpoint.cpp
+++ b/source/API/SBWatchpoint.cpp
@@ -15,8 +15,8 @@
 
 #include "lldb/lldb-types.h"
 #include "lldb/lldb-defines.h"
-#include "lldb/Breakpoint/WatchpointLocation.h"
-#include "lldb/Breakpoint/WatchpointLocationList.h"
+#include "lldb/Breakpoint/Watchpoint.h"
+#include "lldb/Breakpoint/WatchpointList.h"
 #include "lldb/Core/Log.h"
 #include "lldb/Core/Stream.h"
 #include "lldb/Core/StreamFile.h"
@@ -31,8 +31,8 @@
 {
 }
 
-SBWatchpoint::SBWatchpoint (const lldb::WatchpointLocationSP &watch_loc_sp) :
-    m_opaque_sp (watch_loc_sp)
+SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp) :
+    m_opaque_sp (wp_sp)
 {
     LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 
@@ -40,8 +40,8 @@
     {
         SBStream sstr;
         GetDescription (sstr, lldb::eDescriptionLevelBrief);
-        log->Printf ("SBWatchpoint::SBWatchpoint (const lldb::WatchpointLocationsSP &watch_loc_sp"
-                     "=%p)  => this.sp = %p (%s)", watch_loc_sp.get(), m_opaque_sp.get(), sstr.GetData());
+        log->Printf ("SBWatchpoint::SBWatchpoint (const lldb::WatchpointSP &wp_sp"
+                     "=%p)  => this.sp = %p (%s)", wp_sp.get(), m_opaque_sp.get(), sstr.GetData());
     }
 }
 
@@ -156,7 +156,7 @@
     if (m_opaque_sp)
     {
         Mutex::Locker api_locker (m_opaque_sp->GetTarget().GetAPIMutex());
-        m_opaque_sp->GetTarget().DisableWatchpointLocationByID(m_opaque_sp->GetID());
+        m_opaque_sp->GetTarget().DisableWatchpointByID(m_opaque_sp->GetID());
     }
 }
 
@@ -227,19 +227,19 @@
     return true;
 }
 
-lldb_private::WatchpointLocation *
+lldb_private::Watchpoint *
 SBWatchpoint::operator->()
 {
     return m_opaque_sp.get();
 }
 
-lldb_private::WatchpointLocation *
+lldb_private::Watchpoint *
 SBWatchpoint::get()
 {
     return m_opaque_sp.get();
 }
 
-lldb::WatchpointLocationSP &
+lldb::WatchpointSP &
 SBWatchpoint::operator *()
 {
     return m_opaque_sp;