Make CompilerType::getBitSize() / getByteSize() return an optional result. NFC

The code in LLDB assumes that CompilerType and friends use the size 0
as a sentinel value to signal an error. This works for C++, where no
zero-sized type exists, but in many other programming languages
(including I believe C) types of size zero are possible and even
common. This is a particular pain point in swift-lldb, where extra
code exists to double-check that a type is *really* of size zero and
not an error at various locations.

To remedy this situation, this patch starts by converting
CompilerType::getBitSize() and getByteSize() to return an optional
result. To avoid wasting space, I hand-rolled my own optional data
type assuming that no type is larger than what fits into 63
bits. Follow-up patches would make similar changes to the ValueObject
hierarchy.

rdar://problem/47178964

Differential Revision: https://reviews.llvm.org/D56688

llvm-svn: 351214
diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
index 0cdb0b2..0d39e5a 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -79,17 +79,22 @@
   CompilerType type;
   ValueObjectSP chunk;
   // For small bitsets __first_ is not an array, but a plain size_t.
-  if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr))
-    chunk = m_first->GetChildAtIndex(
-        idx / type.GetBitSize(ctx.GetBestExecutionContextScope()), true);
-  else {
+  if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) {
+    auto bit_size = type.GetBitSize(ctx.GetBestExecutionContextScope());
+    if (!bit_size || *bit_size == 0)
+      return {};
+    chunk = m_first->GetChildAtIndex(idx / *bit_size, true);
+  } else {
     type = m_first->GetCompilerType();
     chunk = m_first;
   }
   if (!type || !chunk)
-    return ValueObjectSP();
+    return {};
 
-  size_t chunk_idx = idx % type.GetBitSize(ctx.GetBestExecutionContextScope());
+  auto bit_size = type.GetBitSize(ctx.GetBestExecutionContextScope());
+  if (!bit_size || *bit_size == 0)
+    return {};
+  size_t chunk_idx = idx % *bit_size;
   uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx));
   DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size);