[lldb/Utility] Simplify more Scalar methods

A lot of the methods handle all integral and all floating point types
the same way. They can be changed to switch on the category of the type,
instead of the actual type, saving a lot of boilerplate.

This patch does that for the methods where I could be reasonably certain
of their expected semantics.
diff --git a/lldb/source/Utility/Scalar.cpp b/lldb/source/Utility/Scalar.cpp
index 7bd42f3..c36ccab 100644
--- a/lldb/source/Utility/Scalar.cpp
+++ b/lldb/source/Utility/Scalar.cpp
@@ -23,6 +23,60 @@
 using namespace lldb;
 using namespace lldb_private;
 
+namespace {
+enum class Category { Void, Integral, Float };
+}
+
+static Category GetCategory(Scalar::Type type) {
+  switch (type) {
+  case Scalar::e_void:
+    return Category::Void;
+  case Scalar::e_float:
+  case Scalar::e_double:
+  case Scalar::e_long_double:
+    return Category::Float;
+  case Scalar::e_sint:
+  case Scalar::e_slong:
+  case Scalar::e_slonglong:
+  case Scalar::e_sint128:
+  case Scalar::e_sint256:
+  case Scalar::e_sint512:
+  case Scalar::e_uint:
+  case Scalar::e_ulong:
+  case Scalar::e_ulonglong:
+  case Scalar::e_uint128:
+  case Scalar::e_uint256:
+  case Scalar::e_uint512:
+    return Category::Integral;
+  }
+  llvm_unreachable("Unhandled type!");
+}
+
+static bool IsSigned(Scalar::Type type) {
+  switch (type) {
+  case Scalar::e_void:
+  case Scalar::e_uint:
+  case Scalar::e_ulong:
+  case Scalar::e_ulonglong:
+  case Scalar::e_uint128:
+  case Scalar::e_uint256:
+  case Scalar::e_uint512:
+    return false;
+  case Scalar::e_sint:
+  case Scalar::e_slong:
+  case Scalar::e_slonglong:
+  case Scalar::e_sint128:
+  case Scalar::e_sint256:
+  case Scalar::e_sint512:
+  case Scalar::e_float:
+  case Scalar::e_double:
+  case Scalar::e_long_double:
+    return true;
+  }
+  llvm_unreachable("Unhandled type!");
+}
+
+
 // Promote to max type currently follows the ANSI C rule for type promotion in
 // expressions.
 static Scalar::Type PromoteToMaxType(
@@ -103,40 +157,19 @@
 void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const {
   assert(storage.size() >= GetByteSize());
 
-  switch (m_type) {
-  case e_void:
+  const auto &store = [&](const llvm::APInt val) {
+    StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8);
+  };
+  switch (GetCategory(m_type)) {
+  case Category::Void:
     break;
-  case e_sint:
-  case e_uint:
-  case e_slong:
-  case e_ulong:
-  case e_slonglong:
-  case e_ulonglong:
-  case e_sint128:
-  case e_uint128:
-  case e_sint256:
-  case e_uint256:
-  case e_sint512:
-  case e_uint512:
-    StoreIntToMemory(m_integer, storage.data(),
-                     (m_integer.getBitWidth() + 7) / 8);
+  case Category::Integral:
+    store(m_integer);
     break;
-  case e_float: {
-    float val = m_float.convertToFloat();
-    memcpy(storage.data(), &val, sizeof(val));
+  case Category::Float:
+    store(m_float.bitcastToAPInt());
     break;
   }
-  case e_double: {
-    double val = m_float.convertToDouble();
-    memcpy(storage.data(), &val, sizeof(double));
-    break;
-  }
-  case e_long_double: {
-    llvm::APInt val = m_float.bitcastToAPInt();
-    StoreIntToMemory(val, storage.data(), storage.size());
-    break;
-  }
-  }
 }
 
 size_t Scalar::GetByteSize() const {
@@ -167,26 +200,12 @@
 }
 
 bool Scalar::IsZero() const {
-  llvm::APInt zero_int = llvm::APInt::getNullValue(m_integer.getBitWidth() / 8);
-  switch (m_type) {
-  case e_void:
+  switch (GetCategory(m_type)) {
+  case Category::Void:
     break;
-  case e_sint:
-  case e_uint:
-  case e_slong:
-  case e_ulong:
-  case e_slonglong:
-  case e_ulonglong:
-  case e_sint128:
-  case e_uint128:
-  case e_sint256:
-  case e_uint256:
-  case e_uint512:
-  case e_sint512:
-    return llvm::APInt::isSameValue(zero_int, m_integer);
-  case e_float:
-  case e_double:
-  case e_long_double:
+  case Category::Integral:
+    return m_integer.isNullValue();
+  case Category::Float:
     return m_float.isZero();
   }
   return false;
@@ -196,31 +215,16 @@
   if (show_type)
     s->Printf("(%s) ", GetTypeAsCString());
 
-  switch (m_type) {
-  case e_void:
+  switch (GetCategory(m_type)) {
+  case Category::Void:
     break;
-  case e_sint:
-  case e_slong:
-  case e_slonglong:
-  case e_sint128:
-  case e_sint256:
-  case e_sint512:
-    s->PutCString(m_integer.toString(10, true));
+  case Category::Integral:
+    s->PutCString(m_integer.toString(10, IsSigned(m_type)));
     break;
-  case e_uint:
-  case e_ulong:
-  case e_ulonglong:
-  case e_uint128:
-  case e_uint256:
-  case e_uint512:
-    s->PutCString(m_integer.toString(10, false));
-    break;
-  case e_float:
-  case e_double:
-  case e_long_double:
+  case Category::Float:
     llvm::SmallString<24> string;
     m_float.toString(string);
-    s->Printf("%s", string.c_str());
+    s->PutCString(string);
     break;
   }
 }
@@ -325,59 +329,6 @@
   llvm_unreachable("Unhandled type!");
 }
 
-static bool IsSigned(Scalar::Type type) {
-  switch (type) {
-  case Scalar::e_void:
-  case Scalar::e_uint:
-  case Scalar::e_ulong:
-  case Scalar::e_ulonglong:
-  case Scalar::e_uint128:
-  case Scalar::e_uint256:
-  case Scalar::e_uint512:
-    return false;
-  case Scalar::e_sint:
-  case Scalar::e_slong:
-  case Scalar::e_slonglong:
-  case Scalar::e_sint128:
-  case Scalar::e_sint256:
-  case Scalar::e_sint512:
-  case Scalar::e_float:
-  case Scalar::e_double:
-  case Scalar::e_long_double:
-    return true;
-  }
-  llvm_unreachable("Unhandled type!");
-}
-
-namespace {
-enum class Category { Void, Integral, Float };
-}
-
-static Category GetCategory(Scalar::Type type) {
-  switch (type) {
-  case Scalar::e_void:
-    return Category::Void;
-  case Scalar::e_float:
-  case Scalar::e_double:
-  case Scalar::e_long_double:
-    return Category::Float;
-  case Scalar::e_sint:
-  case Scalar::e_slong:
-  case Scalar::e_slonglong:
-  case Scalar::e_sint128:
-  case Scalar::e_sint256:
-  case Scalar::e_sint512:
-  case Scalar::e_uint:
-  case Scalar::e_ulong:
-  case Scalar::e_ulonglong:
-  case Scalar::e_uint128:
-  case Scalar::e_uint256:
-  case Scalar::e_uint512:
-    return Category::Integral;
-  }
-  llvm_unreachable("Unhandled type!");
-}
-
 static const llvm::fltSemantics &GetFltSemantics(Scalar::Type type) {
   switch (type) {
   case Scalar::e_void:
@@ -849,27 +800,14 @@
   const Scalar *b;
   if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) !=
       Scalar::e_void) {
-    switch (m_type) {
-    case e_void:
+    switch (GetCategory(m_type)) {
+    case Category::Void:
       break;
-    case e_sint:
-    case e_uint:
-    case e_slong:
-    case e_ulong:
-    case e_slonglong:
-    case e_ulonglong:
-    case e_sint128:
-    case e_uint128:
-    case e_sint256:
-    case e_uint256:
-    case e_sint512:
-    case e_uint512:
+    case Category::Integral:
       m_integer = a->m_integer + b->m_integer;
       break;
 
-    case e_float:
-    case e_double:
-    case e_long_double:
+    case Category::Float:
       m_float = a->m_float + b->m_float;
       break;
     }
@@ -878,99 +816,22 @@
 }
 
 Scalar &Scalar::operator<<=(const Scalar &rhs) {
-  switch (m_type) {
-  case e_void:
-  case e_float:
-  case e_double:
-  case e_long_double:
+  if (GetCategory(m_type) == Category::Integral &&
+      GetCategory(rhs.m_type) == Category::Integral)
+    m_integer <<= rhs.m_integer;
+  else
     m_type = e_void;
-    break;
-
-  case e_sint:
-  case e_uint:
-  case e_slong:
-  case e_ulong:
-  case e_slonglong:
-  case e_ulonglong:
-  case e_sint128:
-  case e_uint128:
-  case e_sint256:
-  case e_uint256:
-  case e_sint512:
-  case e_uint512:
-    switch (rhs.m_type) {
-    case e_void:
-    case e_float:
-    case e_double:
-    case e_long_double:
-      m_type = e_void;
-      break;
-    case e_sint:
-    case e_uint:
-    case e_slong:
-    case e_ulong:
-    case e_slonglong:
-    case e_ulonglong:
-    case e_sint128:
-    case e_uint128:
-    case e_sint256:
-    case e_uint256:
-    case e_sint512:
-    case e_uint512:
-      m_integer = m_integer << rhs.m_integer;
-      break;
-    }
-    break;
-  }
   return *this;
 }
 
 bool Scalar::ShiftRightLogical(const Scalar &rhs) {
-  switch (m_type) {
-  case e_void:
-  case e_float:
-  case e_double:
-  case e_long_double:
-    m_type = e_void;
-    break;
-
-  case e_sint:
-  case e_uint:
-  case e_slong:
-  case e_ulong:
-  case e_slonglong:
-  case e_ulonglong:
-  case e_sint128:
-  case e_uint128:
-  case e_sint256:
-  case e_uint256:
-  case e_sint512:
-  case e_uint512:
-    switch (rhs.m_type) {
-    case e_void:
-    case e_float:
-    case e_double:
-    case e_long_double:
-      m_type = e_void;
-      break;
-    case e_sint:
-    case e_uint:
-    case e_slong:
-    case e_ulong:
-    case e_slonglong:
-    case e_ulonglong:
-    case e_sint128:
-    case e_uint128:
-    case e_sint256:
-    case e_uint256:
-    case e_sint512:
-    case e_uint512:
-      m_integer = m_integer.lshr(rhs.m_integer);
-      break;
-    }
-    break;
+  if (GetCategory(m_type) == Category::Integral &&
+      GetCategory(rhs.m_type) == Category::Integral) {
+    m_integer = m_integer.lshr(rhs.m_integer);
+    return true;
   }
-  return m_type != e_void;
+  m_type = e_void;
+  return false;
 }
 
 Scalar &Scalar::operator>>=(const Scalar &rhs) {
@@ -1022,50 +883,11 @@
 }
 
 Scalar &Scalar::operator&=(const Scalar &rhs) {
-  switch (m_type) {
-  case e_void:
-  case e_float:
-  case e_double:
-  case e_long_double:
+  if (GetCategory(m_type) == Category::Integral &&
+      GetCategory(rhs.m_type) == Category::Integral)
+    m_integer &= rhs.m_integer;
+  else
     m_type = e_void;
-    break;
-
-  case e_sint:
-  case e_uint:
-  case e_slong:
-  case e_ulong:
-  case e_slonglong:
-  case e_ulonglong:
-  case e_sint128:
-  case e_uint128:
-  case e_sint256:
-  case e_uint256:
-  case e_sint512:
-  case e_uint512:
-    switch (rhs.m_type) {
-    case e_void:
-    case e_float:
-    case e_double:
-    case e_long_double:
-      m_type = e_void;
-      break;
-    case e_sint:
-    case e_uint:
-    case e_slong:
-    case e_ulong:
-    case e_slonglong:
-    case e_ulonglong:
-    case e_sint128:
-    case e_uint128:
-    case e_sint256:
-    case e_uint256:
-    case e_sint512:
-    case e_uint512:
-      m_integer &= rhs.m_integer;
-      break;
-    }
-    break;
-  }
   return *this;
 }
 
@@ -1101,26 +923,13 @@
 }
 
 bool Scalar::UnaryNegate() {
-  switch (m_type) {
-  case e_void:
+  switch (GetCategory(m_type)) {
+  case Category::Void:
     break;
-  case e_sint:
-  case e_uint:
-  case e_slong:
-  case e_ulong:
-  case e_slonglong:
-  case e_ulonglong:
-  case e_sint128:
-  case e_uint128:
-  case e_sint256:
-  case e_uint256:
-  case e_sint512:
-  case e_uint512:
+  case Category::Integral:
     m_integer = -m_integer;
     return true;
-  case e_float:
-  case e_double:
-  case e_long_double:
+  case Category::Float:
     m_float.changeSign();
     return true;
   }
@@ -1128,62 +937,17 @@
 }
 
 bool Scalar::OnesComplement() {
-  switch (m_type) {
-  case e_sint:
-  case e_uint:
-  case e_slong:
-  case e_ulong:
-  case e_slonglong:
-  case e_ulonglong:
-  case e_sint128:
-  case e_uint128:
-  case e_sint256:
-  case e_uint256:
-  case e_sint512:
-  case e_uint512:
+  if (GetCategory(m_type) == Category::Integral) {
     m_integer = ~m_integer;
     return true;
-
-  case e_void:
-  case e_float:
-  case e_double:
-  case e_long_double:
-    break;
   }
+
   return false;
 }
 
 const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
-  Scalar result;
-  Scalar temp_value;
-  const Scalar *a;
-  const Scalar *b;
-  if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
-      Scalar::e_void) {
-    switch (result.m_type) {
-    case Scalar::e_void:
-      break;
-    case Scalar::e_sint:
-    case Scalar::e_uint:
-    case Scalar::e_slong:
-    case Scalar::e_ulong:
-    case Scalar::e_slonglong:
-    case Scalar::e_ulonglong:
-    case Scalar::e_sint128:
-    case Scalar::e_uint128:
-    case Scalar::e_sint256:
-    case Scalar::e_uint256:
-    case Scalar::e_sint512:
-    case Scalar::e_uint512:
-      result.m_integer = a->m_integer + b->m_integer;
-      break;
-    case Scalar::e_float:
-    case Scalar::e_double:
-    case Scalar::e_long_double:
-      result.m_float = a->m_float + b->m_float;
-      break;
-    }
-  }
+  Scalar result = lhs;
+  result += rhs;
   return result;
 }
 
@@ -1194,26 +958,13 @@
   const Scalar *b;
   if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
       Scalar::e_void) {
-    switch (result.m_type) {
-    case Scalar::e_void:
+    switch (GetCategory(result.m_type)) {
+    case Category::Void:
       break;
-    case Scalar::e_sint:
-    case Scalar::e_uint:
-    case Scalar::e_slong:
-    case Scalar::e_ulong:
-    case Scalar::e_slonglong:
-    case Scalar::e_ulonglong:
-    case Scalar::e_sint128:
-    case Scalar::e_uint128:
-    case Scalar::e_sint256:
-    case Scalar::e_uint256:
-    case Scalar::e_sint512:
-    case Scalar::e_uint512:
+    case Category::Integral:
       result.m_integer = a->m_integer - b->m_integer;
       break;
-    case Scalar::e_float:
-    case Scalar::e_double:
-    case Scalar::e_long_double:
+    case Category::Float:
       result.m_float = a->m_float - b->m_float;
       break;
     }
@@ -1227,40 +978,20 @@
   const Scalar *a;
   const Scalar *b;
   if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
-      Scalar::e_void) {
-    switch (result.m_type) {
-    case Scalar::e_void:
+          Scalar::e_void &&
+      !b->IsZero()) {
+    switch (GetCategory(result.m_type)) {
+    case Category::Void:
       break;
-    case Scalar::e_sint:
-    case Scalar::e_slong:
-    case Scalar::e_slonglong:
-    case Scalar::e_sint128:
-    case Scalar::e_sint256:
-    case Scalar::e_sint512:
-      if (b->m_integer != 0) {
+    case Category::Integral:
+      if (IsSigned(result.m_type))
         result.m_integer = a->m_integer.sdiv(b->m_integer);
-        return result;
-      }
-      break;
-    case Scalar::e_uint:
-    case Scalar::e_ulong:
-    case Scalar::e_ulonglong:
-    case Scalar::e_uint128:
-    case Scalar::e_uint256:
-    case Scalar::e_uint512:
-      if (b->m_integer != 0) {
+      else 
         result.m_integer = a->m_integer.udiv(b->m_integer);
-        return result;
-      }
-      break;
-    case Scalar::e_float:
-    case Scalar::e_double:
-    case Scalar::e_long_double:
-      if (!b->m_float.isZero()) {
-        result.m_float = a->m_float / b->m_float;
-        return result;
-      }
-      break;
+      return result;
+    case Category::Float:
+      result.m_float = a->m_float / b->m_float;
+      return result;
     }
   }
   // For division only, the only way it should make it here is if a promotion
@@ -1276,26 +1007,13 @@
   const Scalar *b;
   if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
       Scalar::e_void) {
-    switch (result.m_type) {
-    case Scalar::e_void:
+    switch (GetCategory(result.m_type)) {
+    case Category::Void:
       break;
-    case Scalar::e_sint:
-    case Scalar::e_uint:
-    case Scalar::e_slong:
-    case Scalar::e_ulong:
-    case Scalar::e_slonglong:
-    case Scalar::e_ulonglong:
-    case Scalar::e_sint128:
-    case Scalar::e_uint128:
-    case Scalar::e_sint256:
-    case Scalar::e_uint256:
-    case Scalar::e_sint512:
-    case Scalar::e_uint512:
+    case Category::Integral:
       result.m_integer = a->m_integer * b->m_integer;
       break;
-    case Scalar::e_float:
-    case Scalar::e_double:
-    case Scalar::e_long_double:
+    case Category::Float:
       result.m_float = a->m_float * b->m_float;
       break;
     }
@@ -1310,29 +1028,10 @@
   const Scalar *b;
   if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
       Scalar::e_void) {
-    switch (result.m_type) {
-    case Scalar::e_sint:
-    case Scalar::e_uint:
-    case Scalar::e_slong:
-    case Scalar::e_ulong:
-    case Scalar::e_slonglong:
-    case Scalar::e_ulonglong:
-    case Scalar::e_sint128:
-    case Scalar::e_uint128:
-    case Scalar::e_sint256:
-    case Scalar::e_uint256:
-    case Scalar::e_sint512:
-    case Scalar::e_uint512:
+    if (GetCategory(result.m_type) == Category::Integral)
       result.m_integer = a->m_integer & b->m_integer;
-      break;
-    case Scalar::e_void:
-    case Scalar::e_float:
-    case Scalar::e_double:
-    case Scalar::e_long_double:
-      // No bitwise AND on floats, doubles of long doubles
+    else
       result.m_type = Scalar::e_void;
-      break;
-    }
   }
   return result;
 }
@@ -1344,30 +1043,10 @@
   const Scalar *b;
   if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
       Scalar::e_void) {
-    switch (result.m_type) {
-    case Scalar::e_sint:
-    case Scalar::e_uint:
-    case Scalar::e_slong:
-    case Scalar::e_ulong:
-    case Scalar::e_slonglong:
-    case Scalar::e_ulonglong:
-    case Scalar::e_sint128:
-    case Scalar::e_uint128:
-    case Scalar::e_sint256:
-    case Scalar::e_uint256:
-    case Scalar::e_sint512:
-    case Scalar::e_uint512:
+    if (GetCategory(result.m_type) == Category::Integral)
       result.m_integer = a->m_integer | b->m_integer;
-      break;
-
-    case Scalar::e_void:
-    case Scalar::e_float:
-    case Scalar::e_double:
-    case Scalar::e_long_double:
-      // No bitwise AND on floats, doubles of long doubles
+    else
       result.m_type = Scalar::e_void;
-      break;
-    }
   }
   return result;
 }
@@ -1379,33 +1058,12 @@
   const Scalar *b;
   if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
       Scalar::e_void) {
-    switch (result.m_type) {
-    default:
-      break;
-    case Scalar::e_void:
-      break;
-    case Scalar::e_sint:
-    case Scalar::e_slong:
-    case Scalar::e_slonglong:
-    case Scalar::e_sint128:
-    case Scalar::e_sint256:
-    case Scalar::e_sint512:
-      if (b->m_integer != 0) {
+    if (!b->IsZero() && GetCategory(result.m_type) == Category::Integral) {
+      if (IsSigned(result.m_type))
         result.m_integer = a->m_integer.srem(b->m_integer);
-        return result;
-      }
-      break;
-    case Scalar::e_uint:
-    case Scalar::e_ulong:
-    case Scalar::e_ulonglong:
-    case Scalar::e_uint128:
-    case Scalar::e_uint256:
-    case Scalar::e_uint512:
-      if (b->m_integer != 0) {
+      else
         result.m_integer = a->m_integer.urem(b->m_integer);
-        return result;
-      }
-      break;
+      return result;
     }
   }
   result.m_type = Scalar::e_void;
@@ -1419,30 +1077,10 @@
   const Scalar *b;
   if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
       Scalar::e_void) {
-    switch (result.m_type) {
-    case Scalar::e_sint:
-    case Scalar::e_uint:
-    case Scalar::e_slong:
-    case Scalar::e_ulong:
-    case Scalar::e_slonglong:
-    case Scalar::e_ulonglong:
-    case Scalar::e_sint128:
-    case Scalar::e_uint128:
-    case Scalar::e_sint256:
-    case Scalar::e_uint256:
-    case Scalar::e_sint512:
-    case Scalar::e_uint512:
+    if (GetCategory(result.m_type) == Category::Integral)
       result.m_integer = a->m_integer ^ b->m_integer;
-      break;
-
-    case Scalar::e_void:
-    case Scalar::e_float:
-    case Scalar::e_double:
-    case Scalar::e_long_double:
-      // No bitwise AND on floats, doubles of long doubles
+    else
       result.m_type = Scalar::e_void;
-      break;
-    }
   }
   return result;
 }