[Lldb-commits] [lldb] 219ccdf - [lldb/Utility] Use APSInt in the Scalar class

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Thu Aug 27 06:05:56 PDT 2020


Author: Pavel Labath
Date: 2020-08-27T15:05:47+02:00
New Revision: 219ccdfddecb963971ad14b5c14220b896d2c2e7

URL: https://github.com/llvm/llvm-project/commit/219ccdfddecb963971ad14b5c14220b896d2c2e7
DIFF: https://github.com/llvm/llvm-project/commit/219ccdfddecb963971ad14b5c14220b896d2c2e7.diff

LOG: [lldb/Utility] Use APSInt in the Scalar class

This enables us to further simplify some code because it no longer needs
to switch on the signedness of the type (APSInt handles that).

Added: 
    

Modified: 
    lldb/include/lldb/Utility/Scalar.h
    lldb/source/Utility/Scalar.cpp
    lldb/unittests/Utility/ScalarTest.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Utility/Scalar.h b/lldb/include/lldb/Utility/Scalar.h
index 9d3a20c93898..332bb00489d0 100644
--- a/lldb/include/lldb/Utility/Scalar.h
+++ b/lldb/include/lldb/Utility/Scalar.h
@@ -14,7 +14,7 @@
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-private-types.h"
 #include "llvm/ADT/APFloat.h"
-#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
 #include <cstddef>
 #include <cstdint>
 #include <utility>
@@ -38,35 +38,35 @@ namespace lldb_private {
 // and values before performing these operations. Type promotion currently
 // follows the ANSI C type promotion rules.
 class Scalar {
+  template<typename T>
+  static llvm::APSInt MakeAPSInt(T v) {
+    static_assert(std::is_integral<T>::value, "");
+    static_assert(sizeof(T) <= sizeof(uint64_t), "Conversion loses precision!");
+    return llvm::APSInt(
+        llvm::APInt(sizeof(T) * 8, uint64_t(v), std::is_signed<T>::value),
+        std::is_unsigned<T>::value);
+  }
+
 public:
   // FIXME: These are host types which seems to be an odd choice.
   enum Type {
     e_void = 0,
-    e_sint,
-    e_uint,
+    e_int,
     e_float,
   };
 
   // Constructors and Destructors
   Scalar() : m_type(e_void), m_float(0.0f) {}
-  Scalar(int v)
-      : m_type(e_sint), m_integer(sizeof(v) * 8, uint64_t(v), true),
-        m_float(0.0f) {}
+  Scalar(int v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
   Scalar(unsigned int v)
-      : m_type(e_uint), m_integer(sizeof(v) * 8, uint64_t(v), false),
-        m_float(0.0f) {}
-  Scalar(long v)
-      : m_type(e_sint), m_integer(sizeof(v) * 8, uint64_t(v), true),
-        m_float(0.0f) {}
+      : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
+  Scalar(long v) : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
   Scalar(unsigned long v)
-      : m_type(e_uint), m_integer(sizeof(v) * 8, uint64_t(v), false),
-        m_float(0.0f) {}
+      : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
   Scalar(long long v)
-      : m_type(e_sint), m_integer(sizeof(v) * 8, uint64_t(v), true),
-        m_float(0.0f) {}
+      : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
   Scalar(unsigned long long v)
-      : m_type(e_uint), m_integer(sizeof(v) * 8, uint64_t(v), false),
-        m_float(0.0f) {}
+      : m_type(e_int), m_integer(MakeAPSInt(v)), m_float(0.0f) {}
   Scalar(float v) : m_type(e_float), m_float(v) {}
   Scalar(double v) : m_type(e_float), m_float(v) {}
   Scalar(long double v) : m_type(e_float), m_float(double(v)) {
@@ -75,7 +75,7 @@ class Scalar {
                     llvm::APFloat::rmNearestTiesToEven, &ignore);
   }
   Scalar(llvm::APInt v)
-      : m_type(e_sint), m_integer(std::move(v)), m_float(0.0f) {}
+      : m_type(e_int), m_integer(std::move(v), false), m_float(0.0f) {}
 
   bool SignExtend(uint32_t bit_pos);
 
@@ -108,7 +108,7 @@ class Scalar {
 
   void GetValue(Stream *s, bool show_type) const;
 
-  bool IsValid() const { return (m_type >= e_sint) && (m_type <= e_float); }
+  bool IsValid() const { return (m_type >= e_int) && (m_type <= e_float); }
 
   /// Convert to an integer with \p bits and the given signedness.
   void TruncOrExtendTo(uint16_t bits, bool sign);
@@ -116,6 +116,7 @@ class Scalar {
   bool IntegralPromote(uint16_t bits, bool sign);
   bool FloatPromote(const llvm::fltSemantics &semantics);
 
+  bool IsSigned() const;
   bool MakeSigned();
 
   bool MakeUnsigned();
@@ -234,7 +235,7 @@ class Scalar {
 
   // Classes that inherit from Scalar can see and modify these
   Scalar::Type m_type;
-  llvm::APInt m_integer;
+  llvm::APSInt m_integer;
   llvm::APFloat m_float;
 
   template <typename T> T GetAs(T fail_value) const;

diff  --git a/lldb/source/Utility/Scalar.cpp b/lldb/source/Utility/Scalar.cpp
index 3249ba5a02e3..3dd2813b5eb0 100644
--- a/lldb/source/Utility/Scalar.cpp
+++ b/lldb/source/Utility/Scalar.cpp
@@ -25,6 +25,7 @@ using namespace lldb_private;
 
 using llvm::APFloat;
 using llvm::APInt;
+using llvm::APSInt;
 
 Scalar::Category Scalar::GetCategory(Scalar::Type type) {
   switch (type) {
@@ -32,32 +33,19 @@ Scalar::Category Scalar::GetCategory(Scalar::Type type) {
     return Category::Void;
   case Scalar::e_float:
     return Category::Float;
-  case Scalar::e_sint:
-  case Scalar::e_uint:
+  case Scalar::e_int:
     return Category::Integral;
   }
   llvm_unreachable("Unhandled type!");
 }
 
-static bool IsSigned(Scalar::Type type) {
-  switch (type) {
-  case Scalar::e_void:
-  case Scalar::e_uint:
-    return false;
-  case Scalar::e_sint:
-  case Scalar::e_float:
-    return true;
-  }
-  llvm_unreachable("Unhandled type!");
-}
-
 Scalar::PromotionKey Scalar::GetPromoKey() const {
   Category cat = GetCategory(m_type);
   switch (cat) {
   case Category::Void:
     return PromotionKey{cat, 0, false};
   case Category::Integral:
-    return PromotionKey{cat, m_integer.getBitWidth(), !IsSigned(m_type)};
+    return PromotionKey{cat, m_integer.getBitWidth(), m_integer.isUnsigned()};
   case Category::Float:
     return GetFloatPromoKey(m_float.getSemantics());
   }
@@ -83,8 +71,7 @@ Scalar::Type Scalar::PromoteToMaxType(Scalar &lhs, Scalar &rhs) {
     case Category::Void:
       break;
     case Category::Integral:
-      a.IntegralPromote(b.UInt128(APInt()).getBitWidth(),
-                        IsSigned(b.GetType()));
+      a.IntegralPromote(b.m_integer.getBitWidth(), b.m_integer.isSigned());
       break;
     case Category::Float:
       a.FloatPromote(b.m_float.getSemantics());
@@ -158,8 +145,7 @@ size_t Scalar::GetByteSize() const {
   switch (m_type) {
   case e_void:
     break;
-  case e_sint:
-  case e_uint:
+  case e_int:
     return (m_integer.getBitWidth() / 8);
   case e_float:
     return m_float.bitcastToAPInt().getBitWidth() / 8;
@@ -187,7 +173,7 @@ void Scalar::GetValue(Stream *s, bool show_type) const {
   case Category::Void:
     break;
   case Category::Integral:
-    s->PutCString(m_integer.toString(10, IsSigned(m_type)));
+    s->PutCString(m_integer.toString(10));
     break;
   case Category::Float:
     llvm::SmallString<24> string;
@@ -198,8 +184,8 @@ void Scalar::GetValue(Stream *s, bool show_type) const {
 }
 
 void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) {
-  m_integer = sign ? m_integer.sextOrTrunc(bits) : m_integer.zextOrTrunc(bits);
-  m_type = sign ? e_sint : e_uint;
+  m_integer.setIsSigned(sign);
+  m_integer = m_integer.extOrTrunc(bits);
 }
 
 bool Scalar::IntegralPromote(uint16_t bits, bool sign) {
@@ -210,11 +196,8 @@ bool Scalar::IntegralPromote(uint16_t bits, bool sign) {
   case Category::Integral:
     if (GetPromoKey() > PromotionKey(Category::Integral, bits, !sign))
       break;
-    if (IsSigned(m_type))
-      m_integer = m_integer.sextOrTrunc(bits);
-    else
-      m_integer = m_integer.zextOrTrunc(bits);
-    m_type = sign ? e_sint : e_uint;
+    m_integer = m_integer.extOrTrunc(bits);
+    m_integer.setIsSigned(sign);
     return true;
   }
   return false;
@@ -227,7 +210,7 @@ bool Scalar::FloatPromote(const llvm::fltSemantics &semantics) {
     break;
   case Category::Integral:
     m_float = llvm::APFloat(semantics);
-    m_float.convertFromAPInt(m_integer, IsSigned(m_type),
+    m_float.convertFromAPInt(m_integer, m_integer.isSigned(),
                              llvm::APFloat::rmNearestTiesToEven);
     success = true;
     break;
@@ -248,27 +231,34 @@ const char *Scalar::GetValueTypeAsCString(Scalar::Type type) {
   switch (type) {
   case e_void:
     return "void";
-  case e_sint:
-    return "signed int";
-  case e_uint:
-    return "unsigned int";
+  case e_int:
+    return "int";
   case e_float:
     return "float";
   }
   return "???";
 }
 
+bool Scalar::IsSigned() const {
+  switch (m_type) {
+  case e_void:
+    return false;
+  case e_int:
+    return m_integer.isSigned();
+  case e_float:
+    return true;
+  }
+  llvm_unreachable("Unrecognized type!");
+}
+
 bool Scalar::MakeSigned() {
   bool success = false;
 
   switch (m_type) {
   case e_void:
     break;
-  case e_sint:
-    success = true;
-    break;
-  case e_uint:
-    m_type = e_sint;
+  case e_int:
+    m_integer.setIsSigned(true);
     success = true;
     break;
   case e_float:
@@ -285,11 +275,8 @@ bool Scalar::MakeUnsigned() {
   switch (m_type) {
   case e_void:
     break;
-  case e_sint:
-    m_type = e_uint;
-    success = true;
-    break;
-  case e_uint:
+  case e_int:
+    m_integer.setIsUnsigned(true);
     success = true;
     break;
   case e_float:
@@ -312,10 +299,12 @@ template <typename T> T Scalar::GetAs(T fail_value) const {
   switch (GetCategory(m_type)) {
   case Category::Void:
     break;
-  case Category::Integral:
-    if (IsSigned(m_type))
-      return m_integer.sextOrTrunc(sizeof(T) * 8).getSExtValue();
-    return m_integer.zextOrTrunc(sizeof(T) * 8).getZExtValue();
+  case Category::Integral: {
+    APSInt ext = m_integer.extOrTrunc(sizeof(T) * 8);
+    if (ext.isSigned())
+      return ext.getSExtValue();
+    return ext.getZExtValue();
+  }
   case Category::Float:
     return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value)
         .getSExtValue();
@@ -388,7 +377,7 @@ float Scalar::Float(float fail_value) const {
   case Category::Void:
     break;
   case Category::Integral:
-    if (IsSigned(m_type))
+    if (m_integer.isSigned())
       return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer);
     return llvm::APIntOps::RoundAPIntToFloat(m_integer);
 
@@ -408,7 +397,7 @@ double Scalar::Double(double fail_value) const {
   case Category::Void:
     break;
   case Category::Integral:
-    if (IsSigned(m_type))
+    if (m_integer.isSigned())
       return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer);
     return llvm::APIntOps::RoundAPIntToDouble(m_integer);
 
@@ -449,7 +438,7 @@ Scalar &Scalar::operator+=(Scalar rhs) {
 Scalar &Scalar::operator<<=(const Scalar &rhs) {
   if (GetCategory(m_type) == Category::Integral &&
       GetCategory(rhs.m_type) == Category::Integral)
-    m_integer <<= rhs.m_integer;
+    static_cast<APInt &>(m_integer) <<= rhs.m_integer;
   else
     m_type = e_void;
   return *this;
@@ -472,15 +461,13 @@ Scalar &Scalar::operator>>=(const Scalar &rhs) {
     m_type = e_void;
     break;
 
-  case e_sint:
-  case e_uint:
+  case e_int:
     switch (rhs.m_type) {
     case e_void:
     case e_float:
       m_type = e_void;
       break;
-    case e_sint:
-    case e_uint:
+    case e_int:
       m_integer = m_integer.ashr(rhs.m_integer);
       break;
     }
@@ -503,13 +490,11 @@ bool Scalar::AbsoluteValue() {
   case e_void:
     break;
 
-  case e_sint:
+  case e_int:
     if (m_integer.isNegative())
       m_integer = -m_integer;
     return true;
 
-  case e_uint:
-    return true;
   case e_float:
     m_float.clearSign();
     return true;
@@ -571,10 +556,7 @@ const Scalar lldb_private::operator/(Scalar lhs, Scalar rhs) {
     case Scalar::Category::Void:
       break;
     case Scalar::Category::Integral:
-      if (IsSigned(result.m_type))
-        result.m_integer = lhs.m_integer.sdiv(rhs.m_integer);
-      else
-        result.m_integer = lhs.m_integer.udiv(rhs.m_integer);
+      result.m_integer = lhs.m_integer / rhs.m_integer;
       return result;
     case Scalar::Category::Float:
       result.m_float = lhs.m_float / rhs.m_float;
@@ -631,10 +613,7 @@ const Scalar lldb_private::operator%(Scalar lhs, Scalar rhs) {
   if ((result.m_type = Scalar::PromoteToMaxType(lhs, rhs)) != Scalar::e_void) {
     if (!rhs.IsZero() &&
         Scalar::GetCategory(result.m_type) == Scalar::Category::Integral) {
-      if (IsSigned(result.m_type))
-        result.m_integer = lhs.m_integer.srem(rhs.m_integer);
-      else
-        result.m_integer = lhs.m_integer.urem(rhs.m_integer);
+      result.m_integer = lhs.m_integer % rhs.m_integer;
       return result;
     }
   }
@@ -702,13 +681,9 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
           value_str, byte_size);
       break;
     }
-    if (is_signed) {
-      m_type = e_sint;
-      m_integer = integer.sextOrTrunc(8 * byte_size);
-    } else {
-      m_type = e_uint;
-      m_integer = integer.zextOrTrunc(8 * byte_size);
-    }
+    m_type = e_int;
+    m_integer =
+        APSInt(std::move(integer), !is_signed).extOrTrunc(8 * byte_size);
     break;
   }
 
@@ -754,9 +729,10 @@ Status Scalar::SetValueFromData(const DataExtractor &data,
   case lldb::eEncodingSint: {
     if (data.GetByteSize() < byte_size)
       return Status("insufficient data");
-    m_type = encoding == lldb::eEncodingSint ? e_sint : e_uint;
+    m_type = e_int;
+    m_integer =
+        APSInt(APInt::getNullValue(8 * byte_size), encoding == eEncodingUint);
     if (data.GetByteOrder() == endian::InlHostByteOrder()) {
-      m_integer = APInt::getNullValue(8 * byte_size);
       llvm::LoadIntFromMemory(m_integer, data.GetDataStart(), byte_size);
     } else {
       std::vector<uint8_t> buffer(byte_size);
@@ -792,17 +768,16 @@ bool Scalar::SignExtend(uint32_t sign_bit_pos) {
     case Scalar::e_float:
       return false;
 
-    case Scalar::e_sint:
-    case Scalar::e_uint:
+    case Scalar::e_int:
       if (max_bit_pos == sign_bit_pos)
         return true;
       else if (sign_bit_pos < (max_bit_pos - 1)) {
         llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1);
         llvm::APInt bitwize_and = m_integer & sign_bit;
         if (bitwize_and.getBoolValue()) {
-          const llvm::APInt mask =
+          llvm::APInt mask =
               ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
-          m_integer |= mask;
+          m_integer |= APSInt(std::move(mask), m_integer.isUnsigned());
         }
         return true;
       }
@@ -846,16 +821,9 @@ bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {
   case Scalar::e_float:
     break;
 
-  case Scalar::e_sint:
-    m_integer = m_integer.ashr(bit_offset)
-                    .sextOrTrunc(bit_size)
-                    .sextOrSelf(8 * GetByteSize());
-    return true;
-
-  case Scalar::e_uint:
-    m_integer = m_integer.lshr(bit_offset)
-                    .zextOrTrunc(bit_size)
-                    .zextOrSelf(8 * GetByteSize());
+  case Scalar::e_int:
+    m_integer >>= bit_offset;
+    m_integer = m_integer.extOrTrunc(bit_size).extOrTrunc(8 * GetByteSize());
     return true;
   }
   return false;
@@ -870,8 +838,7 @@ bool lldb_private::operator==(Scalar lhs, Scalar rhs) {
   switch (Scalar::PromoteToMaxType(lhs, rhs)) {
   case Scalar::e_void:
     break;
-  case Scalar::e_sint:
-  case Scalar::e_uint:
+  case Scalar::e_int:
     return lhs.m_integer == rhs.m_integer;
   case Scalar::e_float:
     result = lhs.m_float.compare(rhs.m_float);
@@ -893,10 +860,8 @@ bool lldb_private::operator<(Scalar lhs, Scalar rhs) {
   switch (Scalar::PromoteToMaxType(lhs, rhs)) {
   case Scalar::e_void:
     break;
-  case Scalar::e_sint:
-    return lhs.m_integer.slt(rhs.m_integer);
-  case Scalar::e_uint:
-    return lhs.m_integer.ult(rhs.m_integer);
+  case Scalar::e_int:
+    return lhs.m_integer < rhs.m_integer;
   case Scalar::e_float:
     result = lhs.m_float.compare(rhs.m_float);
     if (result == llvm::APFloat::cmpLessThan)
@@ -921,8 +886,7 @@ bool Scalar::ClearBit(uint32_t bit) {
   switch (m_type) {
   case e_void:
     break;
-  case e_sint:
-  case e_uint:
+  case e_int:
     m_integer.clearBit(bit);
     return true;
   case e_float:
@@ -935,8 +899,7 @@ bool Scalar::SetBit(uint32_t bit) {
   switch (m_type) {
   case e_void:
     break;
-  case e_sint:
-  case e_uint:
+  case e_int:
     m_integer.setBit(bit);
     return true;
   case e_float:

diff  --git a/lldb/unittests/Utility/ScalarTest.cpp b/lldb/unittests/Utility/ScalarTest.cpp
index 48cadfce466b..1e65cd535733 100644
--- a/lldb/unittests/Utility/ScalarTest.cpp
+++ b/lldb/unittests/Utility/ScalarTest.cpp
@@ -292,15 +292,15 @@ TEST(ScalarTest, Division) {
 TEST(ScalarTest, Promotion) {
   Scalar a(47);
   EXPECT_TRUE(a.IntegralPromote(64, true));
-  EXPECT_EQ(Scalar::e_sint, a.GetType());
+  EXPECT_TRUE(a.IsSigned());
   EXPECT_EQ(APInt(64, 47), a.UInt128(APInt()));
 
   EXPECT_FALSE(a.IntegralPromote(32, true));
   EXPECT_FALSE(a.IntegralPromote(32, false));
-  EXPECT_EQ(Scalar::e_sint, a.GetType());
+  EXPECT_TRUE(a.IsSigned());
 
   EXPECT_TRUE(a.IntegralPromote(64, false));
-  EXPECT_EQ(Scalar::e_uint, a.GetType());
+  EXPECT_FALSE(a.IsSigned());
   EXPECT_EQ(APInt(64, 47), a.UInt128(APInt()));
 
   EXPECT_FALSE(a.IntegralPromote(64, true));
@@ -362,7 +362,8 @@ TEST(ScalarTest, SetValueFromCString) {
 TEST(ScalarTest, APIntConstructor) {
   for (auto &width : {8, 16, 32}) {
     Scalar A(APInt(width, 24));
-    EXPECT_EQ(A.GetType(), Scalar::e_sint);
+    EXPECT_TRUE(A.IsSigned());
+    EXPECT_EQ(A.GetType(), Scalar::e_int);
     EXPECT_EQ(APInt(width, 24), A.UInt128(APInt()));
   }
 }
@@ -374,15 +375,17 @@ TEST(ScalarTest, Scalar_512) {
   ASSERT_TRUE(Z.IsZero());
 
   Scalar S(APInt(512, 2000));
-  ASSERT_STREQ(S.GetTypeAsCString(), "signed int");
+  ASSERT_STREQ(S.GetTypeAsCString(), "int");
 
   ASSERT_TRUE(S.MakeUnsigned());
-  EXPECT_EQ(S.GetType(), Scalar::e_uint);
-  ASSERT_STREQ(S.GetTypeAsCString(), "unsigned int");
+  EXPECT_EQ(S.GetType(), Scalar::e_int);
+  EXPECT_FALSE(S.IsSigned());
+  ASSERT_STREQ(S.GetTypeAsCString(), "int");
   EXPECT_EQ(S.GetByteSize(), 64U);
 
   ASSERT_TRUE(S.MakeSigned());
-  EXPECT_EQ(S.GetType(), Scalar::e_sint);
+  EXPECT_EQ(S.GetType(), Scalar::e_int);
+  EXPECT_TRUE(S.IsSigned());
   EXPECT_EQ(S.GetByteSize(), 64U);
 }
 


        


More information about the lldb-commits mailing list