rdar://problem/11597911

Fix confusing error message about "expression did not evaluate to an address" when doing 'watchpoint set expression".
Instead of using 0 as the fail_value when invoking ValueObject::GetValueAsUnsigned(), modify the API to take an addition
bool pointer (defaults to NULL) to indicate success/failure of value conversion.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@158016 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h
index c34fd49..92a5f66 100644
--- a/include/lldb/Core/ValueObject.h
+++ b/include/lldb/Core/ValueObject.h
@@ -690,7 +690,7 @@
                        std::string& destination);
     
     virtual uint64_t
-    GetValueAsUnsigned (uint64_t fail_value);
+    GetValueAsUnsigned (uint64_t fail_value, bool *success = NULL);
 
     virtual bool
     SetValueFromCString (const char *value_str, Error& error);
diff --git a/source/Commands/CommandObjectWatchpoint.cpp b/source/Commands/CommandObjectWatchpoint.cpp
index 04d8789..0ac4576 100644
--- a/source/Commands/CommandObjectWatchpoint.cpp
+++ b/source/Commands/CommandObjectWatchpoint.cpp
@@ -1196,8 +1196,9 @@
     }
 
     // Get the address to watch.
-    addr = valobj_sp->GetValueAsUnsigned(0);
-    if (!addr) {
+    bool success = false;
+    addr = valobj_sp->GetValueAsUnsigned(0, &success);
+    if (!success) {
         result.GetErrorStream().Printf("error: expression did not evaluate to an address\n");
         result.SetStatus(eReturnStatusFailed);
         return false;
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index 07af307..b3c0a0b 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -1246,15 +1246,23 @@
 // if > 8bytes, 0 is returned. this method should mostly be used
 // to read address values out of pointers
 uint64_t
-ValueObject::GetValueAsUnsigned (uint64_t fail_value)
+ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success)
 {
     // If our byte size is zero this is an aggregate type that has children
     if (ClangASTContext::IsAggregateType (GetClangType()) == false)
     {
         Scalar scalar;
         if (ResolveValue (scalar))
+        {
+            if (success)
+                *success = true;
             return scalar.GetRawBits64(fail_value);
+        }
+        // fallthrough, otherwise...
     }
+
+    if (success)
+        *success = false;
     return fail_value;
 }
 
diff --git a/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py b/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
index 44d1664..538694b 100644
--- a/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
+++ b/test/functionalities/watchpoint/watchpoint_set_command/TestWatchpointSetErrorCases.py
@@ -61,6 +61,10 @@
         self.expect("watchpoint set expression -w write --", error=True,
             startstr = 'error: required argument missing; specify an expression to evaulate into the addres to watch for')
 
+        # It's an error if the expression did not evaluate to an address.
+        self.expect("watchpoint set expression MyAggregateDataType", error=True,
+            startstr = 'error: expression did not evaluate to an address')
+
         # Check for missing option terminator '--'.
         self.expect("watchpoint set expression -w write -x 1 g_char_ptr", error=True,
             startstr = 'error: did you forget to enter the option terminator string "--"?')
diff --git a/test/functionalities/watchpoint/watchpoint_set_command/main.cpp b/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
index 83ea085..9dcefbd 100644
--- a/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
+++ b/test/functionalities/watchpoint/watchpoint_set_command/main.cpp
@@ -98,6 +98,12 @@
     err = ::pthread_create (&g_thread_2, NULL, thread_func, &thread_index_2);
     err = ::pthread_create (&g_thread_3, NULL, thread_func, &thread_index_3);
 
+    struct {
+        int a;
+        int b;
+        int c;
+    } MyAggregateDataType;
+
     printf ("Before turning all three threads loose...\n"); // Set break point at this line.
 
     // Join all of our threads