This revision was automatically updated to reflect the committed changes.
Closed by commit rL371532: Implement DW_OP_convert (authored by adrian, 
committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D67369?vs=219422&id=219559#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D67369/new/

https://reviews.llvm.org/D67369

Files:
  lldb/trunk/include/lldb/Core/Section.h
  lldb/trunk/include/lldb/Utility/Scalar.h
  lldb/trunk/source/Core/Section.cpp
  lldb/trunk/source/Expression/DWARFExpression.cpp
  lldb/trunk/source/Utility/Scalar.cpp
  lldb/trunk/unittests/Expression/DWARFExpressionTest.cpp
  lldb/trunk/unittests/Utility/ScalarTest.cpp

Index: lldb/trunk/unittests/Utility/ScalarTest.cpp
===================================================================
--- lldb/trunk/unittests/Utility/ScalarTest.cpp
+++ lldb/trunk/unittests/Utility/ScalarTest.cpp
@@ -272,7 +272,7 @@
   }
 
   Scalar B(APInt(64, 42));
-  EXPECT_EQ(B.GetType(), Scalar::e_slonglong);
+  EXPECT_EQ(B.GetType(), Scalar::GetBestTypeForBitSize(64, true));
   Scalar C(APInt(128, 96));
   EXPECT_EQ(C.GetType(), Scalar::e_sint128);
   Scalar D(APInt(256, 156));
Index: lldb/trunk/unittests/Expression/DWARFExpressionTest.cpp
===================================================================
--- lldb/trunk/unittests/Expression/DWARFExpressionTest.cpp
+++ lldb/trunk/unittests/Expression/DWARFExpressionTest.cpp
@@ -7,24 +7,108 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Expression/DWARFExpression.h"
+#include "../../source/Plugins/SymbolFile/DWARF/DWARFUnit.h"
+#include "../../source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Core/Section.h"
 #include "lldb/Core/Value.h"
 #include "lldb/Core/dwarf.h"
+#include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/StreamString.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/ObjectYAML/DWARFEmitter.h"
 #include "llvm/Testing/Support/Error.h"
 #include "gtest/gtest.h"
 
 using namespace lldb_private;
 
-static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr) {
+/// A mock module holding an object file parsed from YAML.
+class YAMLModule : public lldb_private::Module {
+public:
+  YAMLModule(ArchSpec &arch) : Module(FileSpec("test"), arch) {}
+  void SetObjectFile(lldb::ObjectFileSP obj_file) { m_objfile_sp = obj_file; }
+  ObjectFile *GetObjectFile() override { return m_objfile_sp.get(); }
+};
+
+/// A mock object file that can be parsed from YAML.
+class YAMLObjectFile : public lldb_private::ObjectFile {
+  const lldb::ModuleSP m_module_sp;
+  llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> &m_section_map;
+  /// Because there is only one DataExtractor in the ObjectFile
+  /// interface, all sections are copied into a contiguous buffer.
+  std::vector<char> m_buffer;
+
+public:
+  YAMLObjectFile(const lldb::ModuleSP &module_sp,
+                 llvm::StringMap<std::unique_ptr<llvm::MemoryBuffer>> &map)
+      : ObjectFile(module_sp, &module_sp->GetFileSpec(), /*file_offset*/ 0,
+                   /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0),
+        m_module_sp(module_sp), m_section_map(map) {}
+
+  /// Callback for initializing the module's list of sections.
+  void CreateSections(SectionList &unified_section_list) override {
+    lldb::offset_t total_bytes = 0;
+    for (auto &entry : m_section_map)
+      total_bytes += entry.getValue()->getBufferSize();
+    m_buffer.reserve(total_bytes);
+    m_data =
+        DataExtractor(m_buffer.data(), total_bytes, lldb::eByteOrderLittle, 4);
+
+    lldb::user_id_t sect_id = 1;
+    for (auto &entry : m_section_map) {
+      llvm::StringRef name = entry.getKey();
+      lldb::SectionType sect_type =
+          llvm::StringSwitch<lldb::SectionType>(name)
+              .Case("debug_info", lldb::eSectionTypeDWARFDebugInfo)
+              .Case("debug_abbrev", lldb::eSectionTypeDWARFDebugAbbrev);
+      auto &membuf = entry.getValue();
+      lldb::addr_t file_vm_addr = 0;
+      lldb::addr_t vm_size = 0;
+      lldb::offset_t file_offset = m_buffer.size();
+      lldb::offset_t file_size = membuf->getBufferSize();
+      m_buffer.resize(file_offset + file_size);
+      memcpy(m_buffer.data() + file_offset, membuf->getBufferStart(),
+             file_size);
+      uint32_t log2align = 0;
+      uint32_t flags = 0;
+      auto section_sp = std::make_shared<lldb_private::Section>(
+          m_module_sp, this, sect_id++, ConstString(name), sect_type,
+          file_vm_addr, vm_size, file_offset, file_size, log2align, flags);
+      unified_section_list.AddSection(section_sp);
+    }
+  }
+
+  /// \{
+  /// Stub methods that aren't needed here.
+  ConstString GetPluginName() override { return ConstString("YAMLObjectFile"); }
+  uint32_t GetPluginVersion() override { return 0; }
+  void Dump(Stream *s) override {}
+  uint32_t GetAddressByteSize() const override { return 8; }
+  uint32_t GetDependentModules(FileSpecList &file_list) override { return 0; }
+  bool IsExecutable() const override { return 0; }
+  ArchSpec GetArchitecture() override { return {}; }
+  Symtab *GetSymtab() override { return nullptr; }
+  bool IsStripped() override { return false; }
+  UUID GetUUID() override { return {}; }
+  lldb::ByteOrder GetByteOrder() const override {
+    return lldb::eByteOrderLittle;
+  }
+  bool ParseHeader() override { return false; }
+  Type CalculateType() override { return {}; }
+  Strata CalculateStrata() override { return {}; }
+  /// \}
+};
+
+static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
+                                       lldb::ModuleSP module_sp = {},
+                                       DWARFUnit *unit = nullptr) {
   DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle,
                           /*addr_size*/ 4);
-
   Value result;
   Status status;
   if (!DWARFExpression::Evaluate(
-          /*exe_ctx*/ nullptr, /*reg_ctx*/ nullptr, /*opcode_ctx*/ nullptr,
-          extractor, /*dwarf_cu*/ nullptr, lldb::eRegisterKindLLDB,
+          /*exe_ctx*/ nullptr, /*reg_ctx*/ nullptr, module_sp, extractor, unit,
+          lldb::eRegisterKindLLDB,
           /*initial_value_ptr*/ nullptr,
           /*object_address_ptr*/ nullptr, result, &status))
     return status.ToError();
@@ -32,6 +116,40 @@
   return result.GetScalar();
 }
 
+/// Unfortunately Scalar's operator==() is really picky.
+static Scalar GetScalar(unsigned bits, uint64_t value, bool sign) {
+  Scalar scalar;
+  auto type = Scalar::GetBestTypeForBitSize(bits, sign);
+  switch (type) {
+  case Scalar::e_sint:
+    scalar = Scalar((int)value);
+    break;
+  case Scalar::e_slong:
+    scalar = Scalar((long)value);
+    break;
+  case Scalar::e_slonglong:
+    scalar = Scalar((long long)value);
+    break;
+  case Scalar::e_uint:
+    scalar = Scalar((unsigned int)value);
+    break;
+  case Scalar::e_ulong:
+    scalar = Scalar((unsigned long)value);
+    break;
+  case Scalar::e_ulonglong:
+    scalar = Scalar((unsigned long long)value);
+    break;
+  default:
+    llvm_unreachable("not implemented");
+  }
+  scalar.TruncOrExtendTo(type, bits);
+  if (sign)
+    scalar.MakeSigned();
+  else
+    scalar.MakeUnsigned();
+  return scalar;
+}
+
 TEST(DWARFExpression, DW_OP_pick) {
   EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 0}),
                        llvm::HasValue(0));
@@ -40,3 +158,171 @@
   EXPECT_THAT_EXPECTED(Evaluate({DW_OP_lit1, DW_OP_lit0, DW_OP_pick, 2}),
                        llvm::Failed());
 }
+
+TEST(DWARFExpression, DW_OP_convert) {
+  /// Auxiliary debug info.
+  const char *yamldata =
+      "debug_abbrev:\n"
+      "  - Code:            0x00000001\n"
+      "    Tag:             DW_TAG_compile_unit\n"
+      "    Children:        DW_CHILDREN_yes\n"
+      "    Attributes:\n"
+      "      - Attribute:       DW_AT_language\n"
+      "        Form:            DW_FORM_data2\n"
+      "  - Code:            0x00000002\n"
+      "    Tag:             DW_TAG_base_type\n"
+      "    Children:        DW_CHILDREN_no\n"
+      "    Attributes:\n"
+      "      - Attribute:       DW_AT_encoding\n"
+      "        Form:            DW_FORM_data1\n"
+      "      - Attribute:       DW_AT_byte_size\n"
+      "        Form:            DW_FORM_data1\n"
+      "debug_info:\n"
+      "  - Length:\n"
+      "      TotalLength:     0\n"
+      "    Version:         4\n"
+      "    AbbrOffset:      0\n"
+      "    AddrSize:        8\n"
+      "    Entries:\n"
+      "      - AbbrCode:        0x00000001\n"
+      "        Values:\n"
+      "          - Value:           0x000000000000000C\n"
+      // 0x0000000e:
+      "      - AbbrCode:        0x00000002\n"
+      "        Values:\n"
+      "          - Value:           0x0000000000000007\n" // DW_ATE_unsigned
+      "          - Value:           0x0000000000000004\n"
+      // 0x00000011:
+      "      - AbbrCode:        0x00000002\n"
+      "        Values:\n"
+      "          - Value:           0x0000000000000007\n" // DW_ATE_unsigned
+      "          - Value:           0x0000000000000008\n"
+      // 0x00000014:
+      "      - AbbrCode:        0x00000002\n"
+      "        Values:\n"
+      "          - Value:           0x0000000000000005\n" // DW_ATE_signed
+      "          - Value:           0x0000000000000008\n"
+      // 0x00000017:
+      "      - AbbrCode:        0x00000002\n"
+      "        Values:\n"
+      "          - Value:           0x0000000000000008\n" // DW_ATE_unsigned_char
+      "          - Value:           0x0000000000000001\n"
+      // 0x0000001a:
+      "      - AbbrCode:        0x00000002\n"
+      "        Values:\n"
+      "          - Value:           0x0000000000000006\n" // DW_ATE_signed_char
+      "          - Value:           0x0000000000000001\n"
+      // 0x0000001d:
+      "      - AbbrCode:        0x00000002\n"
+      "        Values:\n"
+      "          - Value:           0x000000000000000b\n" // DW_ATE_numeric_string
+      "          - Value:           0x0000000000000001\n"
+      ""
+      "      - AbbrCode:        0x00000000\n"
+      "        Values:          []\n";
+  uint8_t offs_uint32_t = 0x0000000e;
+  uint8_t offs_uint64_t = 0x00000011;
+  uint8_t offs_sint64_t = 0x00000014;
+  uint8_t offs_uchar = 0x00000017;
+  uint8_t offs_schar = 0x0000001a;
+
+  //
+  // Setup. Parse the debug info sections from the YAML description.
+  //
+  auto sections_map = llvm::DWARFYAML::EmitDebugSections(yamldata, true);
+  ASSERT_TRUE((bool)sections_map);
+  ArchSpec arch("i386-unknown-linux");
+  FileSystem::Initialize();
+  auto module_sp = std::make_shared<YAMLModule>(arch);
+  lldb::ObjectFileSP objfile_sp =
+      std::make_shared<YAMLObjectFile>(module_sp, *sections_map);
+  module_sp->SetObjectFile(objfile_sp);
+  SymbolFileDWARF symfile_dwarf(objfile_sp, nullptr);
+
+  lldb::user_id_t uid = 0;
+  llvm::StringRef raw_debug_info = (*sections_map)["debug_info"]->getBuffer();
+  lldb_private::DataExtractor debug_info(
+      raw_debug_info.data(), raw_debug_info.size(), objfile_sp->GetByteOrder(),
+      objfile_sp->GetAddressByteSize());
+  lldb::offset_t offset_ptr = 0;
+  llvm::Expected<DWARFUnitSP> dwarf_unit = DWARFUnit::extract(
+      symfile_dwarf, uid,
+      *static_cast<lldb_private::DWARFDataExtractor *>(&debug_info),
+      DIERef::DebugInfo, &offset_ptr);
+  ASSERT_TRUE((bool)dwarf_unit);
+
+  //
+  // Actual tests.
+  //
+
+  // Constant is given as little-endian.
+  bool is_signed = true;
+  bool not_signed = false;
+
+  // Truncate to default unspecified (pointer-sized) type.
+  EXPECT_THAT_EXPECTED(Evaluate({DW_OP_const8u, 0x11, 0x22, 0x33, 0x44, 0x55,
+                                 0x66, 0x77, 0x88, DW_OP_convert, 0x00},
+                                module_sp, dwarf_unit->get()),
+                       llvm::HasValue(GetScalar(32, 0x44332211, not_signed)));
+  // Truncate to 32 bits.
+  EXPECT_THAT_EXPECTED(
+      Evaluate({DW_OP_const8u, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+                DW_OP_convert, offs_uint32_t},
+               module_sp, dwarf_unit->get()),
+      llvm::HasValue(GetScalar(32, 0x44332211, not_signed)));
+
+  // Leave as is.
+  EXPECT_THAT_EXPECTED(
+      Evaluate({DW_OP_const8u, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88,
+                DW_OP_convert, offs_uint64_t},
+               module_sp, dwarf_unit->get()),
+      llvm::HasValue(GetScalar(64, 0x8877665544332211, not_signed)));
+
+  // Sign-extend to 64 bits.
+  EXPECT_THAT_EXPECTED(
+      Evaluate({DW_OP_const4s, 0xcc, 0xdd, 0xee, 0xff, //
+                DW_OP_convert, offs_sint64_t},
+               module_sp, dwarf_unit->get()),
+      llvm::HasValue(GetScalar(64, 0xffffffffffeeddcc, is_signed)));
+
+  // Truncate to 8 bits.
+  EXPECT_THAT_EXPECTED(
+      Evaluate({DW_OP_const4s, 'A', 'B', 'C', 'D', 0xee, 0xff, //
+                DW_OP_convert, offs_uchar},
+               module_sp, dwarf_unit->get()),
+      llvm::HasValue(GetScalar(8, 'A', not_signed)));
+
+  // Also truncate to 8 bits.
+  EXPECT_THAT_EXPECTED(
+      Evaluate({DW_OP_const4s, 'A', 'B', 'C', 'D', 0xee, 0xff, //
+                DW_OP_convert, offs_schar},
+               module_sp, dwarf_unit->get()),
+      llvm::HasValue(GetScalar(8, 'A', is_signed)));
+
+  //
+  // Errors.
+  //
+
+  // No Module.
+  EXPECT_THAT_ERROR(Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x00}, nullptr,
+                             dwarf_unit->get())
+                        .takeError(),
+                    llvm::Failed());
+
+  // No DIE.
+  EXPECT_THAT_ERROR(Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x01},
+                             module_sp, dwarf_unit->get())
+                        .takeError(),
+                    llvm::Failed());
+
+  // Unsupported.
+  EXPECT_THAT_ERROR(Evaluate({DW_OP_const1s, 'X', DW_OP_convert, 0x1d}, nullptr,
+                             dwarf_unit->get())
+                        .takeError(),
+                    llvm::Failed());
+
+  //
+  // Tear down.
+  //
+  FileSystem::Terminate();
+}
Index: lldb/trunk/source/Core/Section.cpp
===================================================================
--- lldb/trunk/source/Core/Section.cpp
+++ lldb/trunk/source/Core/Section.cpp
@@ -417,10 +417,6 @@
 
 #pragma mark SectionList
 
-SectionList::SectionList() : m_sections() {}
-
-SectionList::~SectionList() {}
-
 SectionList &SectionList::operator=(const SectionList &rhs) {
   if (this != &rhs)
     m_sections = rhs.m_sections;
Index: lldb/trunk/source/Utility/Scalar.cpp
===================================================================
--- lldb/trunk/source/Utility/Scalar.cpp
+++ lldb/trunk/source/Utility/Scalar.cpp
@@ -416,6 +416,51 @@
 
 Scalar::~Scalar() = default;
 
+Scalar::Type Scalar::GetBestTypeForBitSize(size_t bit_size, bool sign) {
+  // Scalar types are always host types, hence the sizeof().
+  if (sign) {
+    if (bit_size <= sizeof(int)*8) return Scalar::e_sint;
+    if (bit_size <= sizeof(long)*8) return Scalar::e_slong;
+    if (bit_size <= sizeof(long long)*8) return Scalar::e_slonglong;
+    if (bit_size <= 128) return Scalar::e_sint128;
+    if (bit_size <= 256) return Scalar::e_sint256;
+    if (bit_size <= 512) return Scalar::e_sint512;
+  } else {
+    if (bit_size <= sizeof(unsigned int)*8) return Scalar::e_uint;
+    if (bit_size <= sizeof(unsigned long)*8) return Scalar::e_ulong;
+    if (bit_size <= sizeof(unsigned long long)*8) return Scalar::e_ulonglong;
+    if (bit_size <= 128) return Scalar::e_uint128;
+    if (bit_size <= 256) return Scalar::e_uint256;
+    if (bit_size <= 512) return Scalar::e_uint512;
+  }
+  return Scalar::e_void;
+};
+
+void Scalar::TruncOrExtendTo(Scalar::Type type, uint16_t bits) {
+  switch (type) {
+  case e_sint:
+  case e_slong:
+  case e_slonglong:
+  case e_sint128:
+  case e_sint256:
+  case e_sint512:
+    m_integer = m_integer.sextOrTrunc(bits);
+    break;
+  case e_uint:
+  case e_ulong:
+  case e_ulonglong:
+  case e_uint128:
+  case e_uint256:
+  case e_uint512:
+    m_integer = m_integer.zextOrTrunc(bits);
+    break;
+  default:
+    llvm_unreachable("Promoting a Scalar to a specific number of bits is only "
+                     "supported for integer types.");
+  }
+  m_type = type;
+}
+
 bool Scalar::Promote(Scalar::Type type) {
   bool success = false;
   switch (m_type) {
Index: lldb/trunk/source/Expression/DWARFExpression.cpp
===================================================================
--- lldb/trunk/source/Expression/DWARFExpression.cpp
+++ lldb/trunk/source/Expression/DWARFExpression.cpp
@@ -2559,6 +2559,83 @@
       stack.back().SetValueType(Value::eValueTypeScalar);
       break;
 
+    // OPCODE: DW_OP_convert
+    // OPERANDS: 1
+    //      A ULEB128 that is either a DIE offset of a
+    //      DW_TAG_base_type or 0 for the generic (pointer-sized) type.
+    //
+    // DESCRIPTION: Pop the top stack element, convert it to a
+    // different type, and push the result.
+    case DW_OP_convert: {
+      if (stack.size() < 1) {
+        if (error_ptr)
+          error_ptr->SetErrorString(
+              "Expression stack needs at least 1 item for DW_OP_convert.");
+        return false;
+      }
+      const uint64_t die_offset = opcodes.GetULEB128(&offset);
+      Scalar::Type type = Scalar::e_void;
+      uint64_t bit_size;
+      if (die_offset == 0) {
+        // The generic type has the size of an address on the target
+        // machine and an unspecified signedness. Scalar has no
+        // "unspecified signedness", so we use unsigned types.
+        if (!module_sp) {
+          if (error_ptr)
+            error_ptr->SetErrorString("No module");
+          return false;
+        }
+        bit_size = module_sp->GetArchitecture().GetAddressByteSize() * 8;
+        if (!bit_size) {
+          if (error_ptr)
+            error_ptr->SetErrorString("unspecified architecture");
+          return false;
+        }
+        type = Scalar::GetBestTypeForBitSize(bit_size, false);
+      } else {
+        // Retrieve the type DIE that the value is being converted to.
+        // FIXME: the constness has annoying ripple effects.
+        DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(die_offset);
+        if (!die) {
+          if (error_ptr)
+            error_ptr->SetErrorString("Cannot resolve DW_OP_convert type DIE");
+          return false;
+        }
+        uint64_t encoding =
+            die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
+        bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
+        if (!bit_size)
+          bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
+        if (!bit_size) {
+          if (error_ptr)
+            error_ptr->SetErrorString("Unsupported type size in DW_OP_convert");
+          return false;
+        }
+        switch (encoding) {
+        case DW_ATE_signed:
+        case DW_ATE_signed_char:
+          type = Scalar::GetBestTypeForBitSize(bit_size, true);
+          break;
+        case DW_ATE_unsigned:
+        case DW_ATE_unsigned_char:
+          type = Scalar::GetBestTypeForBitSize(bit_size, false);
+          break;
+        default:
+          if (error_ptr)
+            error_ptr->SetErrorString("Unsupported encoding in DW_OP_convert");
+          return false;
+        }
+      }
+      if (type == Scalar::e_void) {
+        if (error_ptr)
+          error_ptr->SetErrorString("Unsupported pointer size");
+        return false;
+      }
+      Scalar &top = stack.back().ResolveValue(exe_ctx);
+      top.TruncOrExtendTo(type, bit_size);
+      break;
+    }
+
     // OPCODE: DW_OP_call_frame_cfa
     // OPERANDS: None
     // DESCRIPTION: Specifies a DWARF expression that pushes the value of
Index: lldb/trunk/include/lldb/Utility/Scalar.h
===================================================================
--- lldb/trunk/include/lldb/Utility/Scalar.h
+++ lldb/trunk/include/lldb/Utility/Scalar.h
@@ -38,6 +38,7 @@
 // follows the ANSI C type promotion rules.
 class Scalar {
 public:
+  // FIXME: These are host types which seems to be an odd choice.
   enum Type {
     e_void = 0,
     e_sint,
@@ -98,30 +99,14 @@
   }
   Scalar(llvm::APInt v) : m_type(), m_float(static_cast<float>(0)) {
     m_integer = llvm::APInt(v);
-    switch (m_integer.getBitWidth()) {
-    case 8:
-    case 16:
-    case 32:
-      m_type = e_sint;
-      return;
-    case 64:
-      m_type = e_slonglong;
-      return;
-    case 128:
-      m_type = e_sint128;
-      return;
-    case 256:
-      m_type = e_sint256;
-      return;
-    case 512:
-      m_type = e_sint512;
-      return;
-    }
-    lldbassert(false && "unsupported bitwidth");
+    m_type = GetBestTypeForBitSize(m_integer.getBitWidth(), true);
   }
   // Scalar(const RegisterValue& reg_value);
   virtual ~Scalar();
 
+  /// Return the most efficient Scalar::Type for the requested bit size.
+  static Type GetBestTypeForBitSize(size_t bit_size, bool sign);
+
   bool SignExtend(uint32_t bit_pos);
 
   bool ExtractBitfield(uint32_t bit_size, uint32_t bit_offset);
@@ -154,6 +139,9 @@
     return (m_type >= e_sint) && (m_type <= e_long_double);
   }
 
+  /// Convert integer to \p type, limited to \p bits size.
+  void TruncOrExtendTo(Scalar::Type type, uint16_t bits);
+
   bool Promote(Scalar::Type type);
 
   bool MakeSigned();
Index: lldb/trunk/include/lldb/Core/Section.h
===================================================================
--- lldb/trunk/include/lldb/Core/Section.h
+++ lldb/trunk/include/lldb/Core/Section.h
@@ -43,9 +43,8 @@
   const_iterator begin() { return m_sections.begin(); }
   const_iterator end() { return m_sections.end(); }
 
-  SectionList();
-
-  ~SectionList();
+  /// Create an empty list.
+  SectionList() = default;
 
   SectionList &operator=(const SectionList &rhs);
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to