diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Utility | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) |
Notes
Diffstat (limited to 'lldb/source/Utility')
53 files changed, 1302 insertions, 2261 deletions
diff --git a/lldb/source/Utility/ARM64_DWARF_Registers.h b/lldb/source/Utility/ARM64_DWARF_Registers.h index 64f69d643565..ed8ff722088d 100644 --- a/lldb/source/Utility/ARM64_DWARF_Registers.h +++ b/lldb/source/Utility/ARM64_DWARF_Registers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM64_DWARF_Registers_h_ -#define utility_ARM64_DWARF_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_ARM64_DWARF_REGISTERS_H +#define LLDB_SOURCE_UTILITY_ARM64_DWARF_REGISTERS_H #include "lldb/lldb-private.h" @@ -51,7 +51,31 @@ enum { sp = x31, pc = 32, cpsr = 33, - // 34-63 reserved + // 34-45 reserved + + // 64-bit SVE Vector granule pseudo register + vg = 46, + + // VG ́8-bit SVE first fault register + ffr = 47, + + // VG x ́8-bit SVE predicate registers + p0 = 48, + p1, + p2, + p3, + p4, + p5, + p6, + p7, + p8, + p9, + p10, + p11, + p12, + p13, + p14, + p15, // V0-V31 (128 bit vector registers) v0 = 64, @@ -85,11 +109,43 @@ enum { v28, v29, v30, - v31 + v31, - // 96-127 reserved + // VG ́64-bit SVE vector registers + z0 = 96, + z1, + z2, + z3, + z4, + z5, + z6, + z7, + z8, + z9, + z10, + z11, + z12, + z13, + z14, + z15, + z16, + z17, + z18, + z19, + z20, + z21, + z22, + z23, + z24, + z25, + z26, + z27, + z28, + z29, + z30, + z31 }; } // namespace arm64_dwarf -#endif // utility_ARM64_DWARF_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_ARM64_DWARF_REGISTERS_H diff --git a/lldb/source/Utility/ARM64_ehframe_Registers.h b/lldb/source/Utility/ARM64_ehframe_Registers.h index 9b5cd931bf28..c235891ec015 100644 --- a/lldb/source/Utility/ARM64_ehframe_Registers.h +++ b/lldb/source/Utility/ARM64_ehframe_Registers.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM64_ehframe_Registers_h_ -#define utility_ARM64_ehframe_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_ARM64_EHFRAME_REGISTERS_H +#define LLDB_SOURCE_UTILITY_ARM64_EHFRAME_REGISTERS_H // The register numbers used in the eh_frame unwind information. // Should be the same as DWARF register numbers. @@ -49,10 +49,34 @@ enum { lr, // aka x30 sp, // aka x31 aka wzr pc, // value is 32 - cpsr -}; + cpsr, + // 34-45 reserved -enum { + // 64-bit SVE Vector granule pseudo register + vg = 46, + + // VG ́8-bit SVE first fault register + ffr = 47, + + // VG x ́8-bit SVE predicate registers + p0 = 48, + p1, + p2, + p3, + p4, + p5, + p6, + p7, + p8, + p9, + p10, + p11, + p12, + p13, + p14, + p15, + + // V0-V31 (128 bit vector registers) v0 = 64, v1, v2, @@ -84,8 +108,42 @@ enum { v28, v29, v30, - v31 // 95 + v31, + + // VG ́64-bit SVE vector registers + z0 = 96, + z1, + z2, + z3, + z4, + z5, + z6, + z7, + z8, + z9, + z10, + z11, + z12, + z13, + z14, + z15, + z16, + z17, + z18, + z19, + z20, + z21, + z22, + z23, + z24, + z25, + z26, + z27, + z28, + z29, + z30, + z31 }; } -#endif // utility_ARM64_ehframe_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_ARM64_EHFRAME_REGISTERS_H diff --git a/lldb/source/Utility/ARM_DWARF_Registers.h b/lldb/source/Utility/ARM_DWARF_Registers.h index e33210dfbfbd..8a3018b27e7e 100644 --- a/lldb/source/Utility/ARM_DWARF_Registers.h +++ b/lldb/source/Utility/ARM_DWARF_Registers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM_DWARF_Registers_h_ -#define utility_ARM_DWARF_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_ARM_DWARF_REGISTERS_H +#define LLDB_SOURCE_UTILITY_ARM_DWARF_REGISTERS_H #include "lldb/lldb-private.h" @@ -204,4 +204,4 @@ enum { dwarf_q15 }; -#endif // utility_ARM_DWARF_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_ARM_DWARF_REGISTERS_H diff --git a/lldb/source/Utility/ARM_ehframe_Registers.h b/lldb/source/Utility/ARM_ehframe_Registers.h index 1816b1d97497..c64e1db0c3cd 100644 --- a/lldb/source/Utility/ARM_ehframe_Registers.h +++ b/lldb/source/Utility/ARM_ehframe_Registers.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_ARM_ehframe_Registers_h_ -#define utility_ARM_ehframe_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_ARM_EHFRAME_REGISTERS_H +#define LLDB_SOURCE_UTILITY_ARM_EHFRAME_REGISTERS_H // The register numbers used in the eh_frame unwind information. // Should be the same as DWARF register numbers. @@ -33,4 +33,4 @@ enum { ehframe_cpsr }; -#endif // utility_ARM_ehframe_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_ARM_EHFRAME_REGISTERS_H diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp index 3dae25ceacd6..ca1ce4b3d378 100644 --- a/lldb/source/Utility/ArchSpec.cpp +++ b/lldb/source/Utility/ArchSpec.cpp @@ -1,4 +1,4 @@ -//===-- ArchSpec.cpp --------------------------------------------*- C++ -*-===// +//===-- ArchSpec.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -100,9 +100,9 @@ static const CoreDefinition g_core_definitions[] = { {eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_armv8, "armv8"}, {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, - ArchSpec::eCore_arm_armv8l, "armv8l"}, + ArchSpec::eCore_arm_armv8l, "armv8l"}, {eByteOrderLittle, 4, 4, 4, llvm::Triple::aarch64_32, - ArchSpec::eCore_arm_arm64_32, "arm64_32"}, + ArchSpec::eCore_arm_arm64_32, "arm64_32"}, {eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_aarch64, "aarch64"}, @@ -216,7 +216,12 @@ static const CoreDefinition g_core_definitions[] = { ArchSpec::eCore_uknownMach32, "unknown-mach-32"}, {eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch, ArchSpec::eCore_uknownMach64, "unknown-mach-64"}, - {eByteOrderLittle, 4, 2, 4, llvm::Triple::arc, ArchSpec::eCore_arc, "arc"} + {eByteOrderLittle, 4, 2, 4, llvm::Triple::arc, ArchSpec::eCore_arc, "arc"}, + + {eByteOrderLittle, 2, 2, 4, llvm::Triple::avr, ArchSpec::eCore_avr, "avr"}, + + {eByteOrderLittle, 4, 1, 4, llvm::Triple::wasm32, ArchSpec::eCore_wasm32, + "wasm32"}, }; // Ensure that we have an entry in the g_core_definitions for each core. If you @@ -445,6 +450,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARC + {ArchSpec::eCore_avr, llvm::ELF::EM_AVR, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // AVR }; static const ArchDefinition g_elf_arch_def = { @@ -1460,3 +1467,15 @@ void ArchSpec::DumpTriple(llvm::raw_ostream &s) const { if (!environ_str.empty()) s << "-" << environ_str; } + +void llvm::yaml::ScalarTraits<ArchSpec>::output(const ArchSpec &Val, void *, + raw_ostream &Out) { + Val.DumpTriple(Out); +} + +llvm::StringRef +llvm::yaml::ScalarTraits<ArchSpec>::input(llvm::StringRef Scalar, void *, + ArchSpec &Val) { + Val = ArchSpec(Scalar); + return {}; +} diff --git a/lldb/source/Utility/Args.cpp b/lldb/source/Utility/Args.cpp index 9fcc833ce432..f718c6f9ff1c 100644 --- a/lldb/source/Utility/Args.cpp +++ b/lldb/source/Utility/Args.cpp @@ -1,4 +1,4 @@ -//===-- Args.cpp ------------------------------------------------*- C++ -*-===// +//===-- Args.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -44,7 +44,7 @@ static llvm::StringRef ParseDoubleQuotes(llvm::StringRef quoted, break; } - // If the character after the backslash is not a whitelisted escapable + // If the character after the backslash is not an allowed escapable // character, we leave the character sequence untouched. if (strchr(k_escapable_characters, quoted.front()) == nullptr) result += '\\'; @@ -111,7 +111,7 @@ ParseSingleArgument(llvm::StringRef command) { break; } - // If the character after the backslash is not a whitelisted escapable + // If the character after the backslash is not an allowed escapable // character, we leave the character sequence untouched. if (strchr(" \t\\'\"`", command.front()) == nullptr) arg += '\\'; @@ -546,7 +546,7 @@ void Args::ExpandEscapedCharacters(const char *src, std::string &dst) { dst.clear(); if (src) { for (const char *p = src; *p != '\0'; ++p) { - if (isprint(*p)) + if (llvm::isPrint(*p)) dst.append(1, *p); else { switch (*p) { @@ -635,7 +635,7 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) { // If the string doesn't start with a dash, we just have no options and just // a raw part. if (!arg_string.startswith("-")) { - m_suffix = original_args; + m_suffix = std::string(original_args); return; } @@ -655,7 +655,7 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) { // The remaining line is the raw suffix, and the line we parsed so far // needs to be interpreted as arguments. m_has_args = true; - m_suffix = arg_string; + m_suffix = std::string(arg_string); found_suffix = true; // The length of the prefix after parsing. @@ -681,6 +681,23 @@ void OptionsWithRaw::SetFromString(llvm::StringRef arg_string) { // If we didn't find a suffix delimiter, the whole string is the raw suffix. if (!found_suffix) { found_suffix = true; - m_suffix = original_args; + m_suffix = std::string(original_args); } } + +void llvm::yaml::MappingTraits<Args::ArgEntry>::mapping(IO &io, + Args::ArgEntry &v) { + MappingNormalization<NormalizedArgEntry, Args::ArgEntry> keys(io, v); + io.mapRequired("value", keys->value); + io.mapRequired("quote", keys->quote); +} + +void llvm::yaml::MappingTraits<Args>::mapping(IO &io, Args &v) { + io.mapRequired("entries", v.m_entries); + + // Recompute m_argv vector. + v.m_argv.clear(); + for (auto &entry : v.m_entries) + v.m_argv.push_back(entry.data()); + v.m_argv.push_back(nullptr); +} diff --git a/lldb/source/Utility/Baton.cpp b/lldb/source/Utility/Baton.cpp index 7bba10dcec96..d6bc8e308587 100644 --- a/lldb/source/Utility/Baton.cpp +++ b/lldb/source/Utility/Baton.cpp @@ -1,4 +1,4 @@ -//===-- Baton.cpp -----------------------------------------------*- C++ -*-===// +//===-- Baton.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/Broadcaster.cpp b/lldb/source/Utility/Broadcaster.cpp index ee0c39f8fd42..342548c0b0e6 100644 --- a/lldb/source/Utility/Broadcaster.cpp +++ b/lldb/source/Utility/Broadcaster.cpp @@ -1,4 +1,4 @@ -//===-- Broadcaster.cpp -----------------------------------------*- C++ -*-===// +//===-- Broadcaster.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,7 +30,7 @@ Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name) m_manager_sp(std::move(manager_sp)), m_broadcaster_name(name) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); LLDB_LOG(log, "{0} Broadcaster::Broadcaster(\"{1}\")", - static_cast<void *>(this), GetBroadcasterName().AsCString()); + static_cast<void *>(this), GetBroadcasterName()); } Broadcaster::BroadcasterImpl::BroadcasterImpl(Broadcaster &broadcaster) @@ -40,7 +40,7 @@ Broadcaster::BroadcasterImpl::BroadcasterImpl(Broadcaster &broadcaster) Broadcaster::~Broadcaster() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); LLDB_LOG(log, "{0} Broadcaster::~Broadcaster(\"{1}\")", - static_cast<void *>(this), GetBroadcasterName().AsCString()); + static_cast<void *>(this), GetBroadcasterName()); Clear(); } @@ -373,8 +373,8 @@ bool BroadcasterManager::UnregisterListenerForEvents( if (event_bits_to_remove != iter_event_bits) { uint32_t new_event_bits = iter_event_bits & ~event_bits_to_remove; - to_be_readded.push_back( - BroadcastEventSpec(event_spec.GetBroadcasterClass(), new_event_bits)); + to_be_readded.emplace_back(event_spec.GetBroadcasterClass(), + new_event_bits); } m_event_map.erase(iter); } @@ -406,7 +406,7 @@ void BroadcasterManager::RemoveListener(Listener *listener) { listener_collection::iterator iter = m_listeners.begin(), end_iter = m_listeners.end(); - std::find_if(iter, end_iter, predicate); + iter = std::find_if(iter, end_iter, predicate); if (iter != end_iter) m_listeners.erase(iter); diff --git a/lldb/source/Utility/CompletionRequest.cpp b/lldb/source/Utility/CompletionRequest.cpp index 3b5a4570e324..8f9dbb79d37b 100644 --- a/lldb/source/Utility/CompletionRequest.cpp +++ b/lldb/source/Utility/CompletionRequest.cpp @@ -1,4 +1,4 @@ -//===-- CompletionRequest.cpp -----------------------------------*- C++ -*-===// +//===-- CompletionRequest.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/Connection.cpp b/lldb/source/Utility/Connection.cpp index 483a0c941be4..d5fcd4f3462f 100644 --- a/lldb/source/Utility/Connection.cpp +++ b/lldb/source/Utility/Connection.cpp @@ -1,4 +1,4 @@ -//===-- Connection.cpp ------------------------------------------*- C++ -*-===// +//===-- Connection.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/ConstString.cpp b/lldb/source/Utility/ConstString.cpp index e90bb929bb81..62f79b3df7a5 100644 --- a/lldb/source/Utility/ConstString.cpp +++ b/lldb/source/Utility/ConstString.cpp @@ -1,4 +1,4 @@ -//===-- ConstString.cpp -----------------------------------------*- C++ -*-===// +//===-- ConstString.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,9 +29,37 @@ using namespace lldb_private; class Pool { public: + /// The default BumpPtrAllocatorImpl slab size. + static const size_t AllocatorSlabSize = 4096; + static const size_t SizeThreshold = AllocatorSlabSize; + /// Every Pool has its own allocator which receives an equal share of + /// the ConstString allocations. This means that when allocating many + /// ConstStrings, every allocator sees only its small share of allocations and + /// assumes LLDB only allocated a small amount of memory so far. In reality + /// LLDB allocated a total memory that is N times as large as what the + /// allocator sees (where N is the number of string pools). This causes that + /// the BumpPtrAllocator continues a long time to allocate memory in small + /// chunks which only makes sense when allocating a small amount of memory + /// (which is true from the perspective of a single allocator). On some + /// systems doing all these small memory allocations causes LLDB to spend + /// a lot of time in malloc, so we need to force all these allocators to + /// behave like one allocator in terms of scaling their memory allocations + /// with increased demand. To do this we set the growth delay for each single + /// allocator to a rate so that our pool of allocators scales their memory + /// allocations similar to a single BumpPtrAllocatorImpl. + /// + /// Currently we have 256 string pools and the normal growth delay of the + /// BumpPtrAllocatorImpl is 128 (i.e., the memory allocation size increases + /// every 128 full chunks), so by changing the delay to 1 we get a + /// total growth delay in our allocator collection of 256/1 = 256. This is + /// still only half as fast as a normal allocator but we can't go any faster + /// without decreasing the number of string pools. + static const size_t AllocatorGrowthDelay = 1; + typedef llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, AllocatorSlabSize, + SizeThreshold, AllocatorGrowthDelay> + Allocator; typedef const char *StringPoolValueType; - typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator> - StringPool; + typedef llvm::StringMap<StringPoolValueType, Allocator> StringPool; typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType; static StringPoolEntryType & @@ -307,5 +335,17 @@ size_t ConstString::StaticMemorySize() { void llvm::format_provider<ConstString>::format(const ConstString &CS, llvm::raw_ostream &OS, llvm::StringRef Options) { - format_provider<StringRef>::format(CS.AsCString(), OS, Options); + format_provider<StringRef>::format(CS.GetStringRef(), OS, Options); +} + +void llvm::yaml::ScalarTraits<ConstString>::output(const ConstString &Val, + void *, raw_ostream &Out) { + Out << Val.GetStringRef(); +} + +llvm::StringRef +llvm::yaml::ScalarTraits<ConstString>::input(llvm::StringRef Scalar, void *, + ConstString &Val) { + Val = ConstString(Scalar); + return {}; } diff --git a/lldb/source/Utility/DataBufferHeap.cpp b/lldb/source/Utility/DataBufferHeap.cpp index 5bff7775f138..3aa0b6b0ac40 100644 --- a/lldb/source/Utility/DataBufferHeap.cpp +++ b/lldb/source/Utility/DataBufferHeap.cpp @@ -1,4 +1,4 @@ -//===-- DataBufferHeap.cpp --------------------------------------*- C++ -*-===// +//===-- DataBufferHeap.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/DataBufferLLVM.cpp b/lldb/source/Utility/DataBufferLLVM.cpp index c20e1b06f52e..235123a31cee 100644 --- a/lldb/source/Utility/DataBufferLLVM.cpp +++ b/lldb/source/Utility/DataBufferLLVM.cpp @@ -1,4 +1,4 @@ -//===--- DataBufferLLVM.cpp -------------------------------------*- C++ -*-===// +//===-- DataBufferLLVM.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/DataEncoder.cpp b/lldb/source/Utility/DataEncoder.cpp index 8a1036e26dce..7532ac1fdcaf 100644 --- a/lldb/source/Utility/DataEncoder.cpp +++ b/lldb/source/Utility/DataEncoder.cpp @@ -1,4 +1,4 @@ -//===-- DataEncoder.cpp -----------------------------------------*- C++ -*-===// +//===-- DataEncoder.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/DataExtractor.cpp b/lldb/source/Utility/DataExtractor.cpp index fed2a1326b86..64b878d7dee7 100644 --- a/lldb/source/Utility/DataExtractor.cpp +++ b/lldb/source/Utility/DataExtractor.cpp @@ -1,4 +1,4 @@ -//===-- DataExtractor.cpp ---------------------------------------*- C++ -*-===// +//===-- DataExtractor.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,7 +15,6 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/Endian.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Stream.h" @@ -24,6 +23,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" @@ -133,7 +133,7 @@ DataExtractor::DataExtractor(const void *data, offset_t length, m_end(const_cast<uint8_t *>(static_cast<const uint8_t *>(data)) + length), m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(addr_size == 4 || addr_size == 8); + assert(addr_size >= 1 && addr_size <= 8); } // Make a shared pointer reference to the shared data in "data_sp" and set the @@ -146,7 +146,7 @@ DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian, : m_start(nullptr), m_end(nullptr), m_byte_order(endian), m_addr_size(addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(addr_size == 4 || addr_size == 8); + assert(addr_size >= 1 && addr_size <= 8); SetData(data_sp); } @@ -160,7 +160,7 @@ DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset, : m_start(nullptr), m_end(nullptr), m_byte_order(data.m_byte_order), m_addr_size(data.m_addr_size), m_data_sp(), m_target_byte_size(target_byte_size) { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); if (data.ValidOffset(offset)) { offset_t bytes_available = data.GetByteSize() - offset; if (length > bytes_available) @@ -173,7 +173,7 @@ DataExtractor::DataExtractor(const DataExtractor &rhs) : m_start(rhs.m_start), m_end(rhs.m_end), m_byte_order(rhs.m_byte_order), m_addr_size(rhs.m_addr_size), m_data_sp(rhs.m_data_sp), m_target_byte_size(rhs.m_target_byte_size) { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); } // Assignment operator @@ -251,7 +251,7 @@ lldb::offset_t DataExtractor::SetData(const DataExtractor &data, offset_t data_offset, offset_t data_length) { m_addr_size = data.m_addr_size; - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); // If "data" contains shared pointer to data, then we can use that if (data.m_data_sp) { m_byte_order = data.m_byte_order; @@ -604,59 +604,30 @@ uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size, int64_t DataExtractor::GetMaxS64Bitfield(offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const { + assert(size >= 1 && "GetMaxS64Bitfield size must be >= 1"); + assert(size <= 8 && "GetMaxS64Bitfield size must be <= 8"); int64_t sval64 = GetMaxS64(offset_ptr, size); - if (bitfield_bit_size > 0) { - int32_t lsbcount = bitfield_bit_offset; - if (m_byte_order == eByteOrderBig) - lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size; - if (lsbcount > 0) - sval64 >>= lsbcount; - uint64_t bitfield_mask = - ((static_cast<uint64_t>(1)) << bitfield_bit_size) - 1; - sval64 &= bitfield_mask; - // sign extend if needed - if (sval64 & ((static_cast<uint64_t>(1)) << (bitfield_bit_size - 1))) - sval64 |= ~bitfield_mask; - } + if (bitfield_bit_size == 0) + return sval64; + int32_t lsbcount = bitfield_bit_offset; + if (m_byte_order == eByteOrderBig) + lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size; + if (lsbcount > 0) + sval64 >>= lsbcount; + uint64_t bitfield_mask = llvm::maskTrailingOnes<uint64_t>(bitfield_bit_size); + sval64 &= bitfield_mask; + // sign extend if needed + if (sval64 & ((static_cast<uint64_t>(1)) << (bitfield_bit_size - 1))) + sval64 |= ~bitfield_mask; return sval64; } float DataExtractor::GetFloat(offset_t *offset_ptr) const { - typedef float float_type; - float_type val = 0.0; - const size_t src_size = sizeof(float_type); - const float_type *src = - static_cast<const float_type *>(GetData(offset_ptr, src_size)); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - const uint8_t *src_data = reinterpret_cast<const uint8_t *>(src); - uint8_t *dst_data = reinterpret_cast<uint8_t *>(&val); - for (size_t i = 0; i < sizeof(float_type); ++i) - dst_data[sizeof(float_type) - 1 - i] = src_data[i]; - } else { - val = *src; - } - } - return val; + return Get<float>(offset_ptr, 0.0f); } double DataExtractor::GetDouble(offset_t *offset_ptr) const { - typedef double float_type; - float_type val = 0.0; - const size_t src_size = sizeof(float_type); - const float_type *src = - static_cast<const float_type *>(GetData(offset_ptr, src_size)); - if (src) { - if (m_byte_order != endian::InlHostByteOrder()) { - const uint8_t *src_data = reinterpret_cast<const uint8_t *>(src); - uint8_t *dst_data = reinterpret_cast<uint8_t *>(&val); - for (size_t i = 0; i < sizeof(float_type); ++i) - dst_data[sizeof(float_type) - 1 - i] = src_data[i]; - } else { - val = *src; - } - } - return val; + return Get<double>(offset_ptr, 0.0); } long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const { @@ -679,26 +650,15 @@ long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const { // // RETURNS the address that was extracted, or zero on failure. uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); return GetMaxU64(offset_ptr, m_addr_size); } uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const { - assert(m_addr_size == 4 || m_addr_size == 8); + assert(m_addr_size >= 1 && m_addr_size <= 8); return GetMaxU64_unchecked(offset_ptr, m_addr_size); } -// Extract a single pointer from the data and update the offset pointed to by -// "offset_ptr". The size of the extracted pointer comes from the -// "this->m_addr_size" member variable and should be set correctly prior to -// extracting any pointer values. -// -// RETURNS the pointer that was extracted, or zero on failure. -uint64_t DataExtractor::GetPointer(offset_t *offset_ptr) const { - assert(m_addr_size == 4 || m_addr_size == 8); - return GetMaxU64(offset_ptr, m_addr_size); -} - size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length, ByteOrder dst_byte_order, void *dst) const { const uint8_t *src = PeekData(offset, length); @@ -887,26 +847,10 @@ uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const { if (src == nullptr) return 0; - const uint8_t *end = m_end; - - if (src < end) { - uint64_t result = *src++; - if (result >= 0x80) { - result &= 0x7f; - int shift = 7; - while (src < end) { - uint8_t byte = *src++; - result |= static_cast<uint64_t>(byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - } - *offset_ptr = src - m_start; - return result; - } - - return 0; + unsigned byte_count = 0; + uint64_t result = llvm::decodeULEB128(src, &byte_count, m_end); + *offset_ptr += byte_count; + return result; } // Extracts an signed LEB128 number from this object's data starting at the @@ -920,33 +864,10 @@ int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const { if (src == nullptr) return 0; - const uint8_t *end = m_end; - - if (src < end) { - int64_t result = 0; - int shift = 0; - int size = sizeof(int64_t) * 8; - - uint8_t byte = 0; - int bytecount = 0; - - while (src < end) { - bytecount++; - byte = *src++; - result |= static_cast<int64_t>(byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - - // Sign bit of byte is 2nd high order bit (0x40) - if (shift < size && (byte & 0x40)) - result |= -(1 << shift); - - *offset_ptr += bytecount; - return result; - } - return 0; + unsigned byte_count = 0; + int64_t result = llvm::decodeSLEB128(src, &byte_count, m_end); + *offset_ptr += byte_count; + return result; } // Skips a ULEB128 number (signed or unsigned) from this object's data starting @@ -1012,7 +933,7 @@ lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset, break; case TypeChar: { char ch = GetU8(&offset); - sstr.Printf(" %c", isprint(ch) ? ch : ' '); + sstr.Printf(" %c", llvm::isPrint(ch) ? ch : ' '); } break; case TypeUInt16: sstr.Printf(" %4.4x", GetU16(&offset)); diff --git a/lldb/source/Utility/Environment.cpp b/lldb/source/Utility/Environment.cpp index 8cafd3024618..5666c2c12ffd 100644 --- a/lldb/source/Utility/Environment.cpp +++ b/lldb/source/Utility/Environment.cpp @@ -1,4 +1,4 @@ -//===-- Environment.cpp -----------------------------------------*- C++ -*-===// +//===-- Environment.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/Event.cpp b/lldb/source/Utility/Event.cpp index 579d0dac86ed..50cc7f061dc6 100644 --- a/lldb/source/Utility/Event.cpp +++ b/lldb/source/Utility/Event.cpp @@ -1,4 +1,4 @@ -//===-- Event.cpp -----------------------------------------------*- C++ -*-===// +//===-- Event.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -125,7 +125,7 @@ ConstString EventDataBytes::GetFlavor() const { void EventDataBytes::Dump(Stream *s) const { size_t num_printable_chars = - std::count_if(m_bytes.begin(), m_bytes.end(), isprint); + std::count_if(m_bytes.begin(), m_bytes.end(), llvm::isPrint); if (num_printable_chars == m_bytes.size()) s->Format("\"{0}\"", m_bytes); else diff --git a/lldb/source/Utility/FileSpec.cpp b/lldb/source/Utility/FileSpec.cpp index 5c216d947f75..1ec5d60e2780 100644 --- a/lldb/source/Utility/FileSpec.cpp +++ b/lldb/source/Utility/FileSpec.cpp @@ -1,4 +1,4 @@ -//===-- FileSpec.cpp --------------------------------------------*- C++ -*-===// +//===-- FileSpec.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -537,3 +537,19 @@ void llvm::format_provider<FileSpec>::format(const FileSpec &F, if (!file.empty()) Stream << file; } + +void llvm::yaml::ScalarEnumerationTraits<FileSpecStyle>::enumeration( + IO &io, FileSpecStyle &value) { + io.enumCase(value, "windows", FileSpecStyle(FileSpec::Style::windows)); + io.enumCase(value, "posix", FileSpecStyle(FileSpec::Style::posix)); + io.enumCase(value, "native", FileSpecStyle(FileSpec::Style::native)); +} + +void llvm::yaml::MappingTraits<FileSpec>::mapping(IO &io, FileSpec &f) { + io.mapRequired("directory", f.m_directory); + io.mapRequired("file", f.m_filename); + io.mapRequired("resolved", f.m_is_resolved); + FileSpecStyle style = f.m_style; + io.mapRequired("style", style); + f.m_style = style; +} diff --git a/lldb/source/Utility/IOObject.cpp b/lldb/source/Utility/IOObject.cpp index 5e3ccddb6a30..964edce0ce10 100644 --- a/lldb/source/Utility/IOObject.cpp +++ b/lldb/source/Utility/IOObject.cpp @@ -1,4 +1,4 @@ -//===-- IOObject.cpp --------------------------------------------*- C++ -*-===// +//===-- IOObject.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/LLDBAssert.cpp b/lldb/source/Utility/LLDBAssert.cpp index 361d6d04a28f..6ae0ee50ef14 100644 --- a/lldb/source/Utility/LLDBAssert.cpp +++ b/lldb/source/Utility/LLDBAssert.cpp @@ -1,4 +1,4 @@ -//===--------------------- LLDBAssert.cpp ------------------------*- C++-*-===// +//===-- LLDBAssert.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/Listener.cpp b/lldb/source/Utility/Listener.cpp index c2e537ba7dee..d2a4f3293963 100644 --- a/lldb/source/Utility/Listener.cpp +++ b/lldb/source/Utility/Listener.cpp @@ -1,4 +1,4 @@ -//===-- Listener.cpp --------------------------------------------*- C++ -*-===// +//===-- Listener.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/Log.cpp b/lldb/source/Utility/Log.cpp index ab5e630114a6..4df82f2bf4d7 100644 --- a/lldb/source/Utility/Log.cpp +++ b/lldb/source/Utility/Log.cpp @@ -1,4 +1,4 @@ -//===-- Log.cpp -------------------------------------------------*- C++ -*-===// +//===-- Log.cpp -----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -138,7 +138,7 @@ void Log::VAPrintf(const char *format, va_list args) { Stream << Content << "\n"; - WriteMessage(FinalMessage.str()); + WriteMessage(std::string(FinalMessage.str())); } // Printing of errors that are not fatal. diff --git a/lldb/source/Utility/Logging.cpp b/lldb/source/Utility/Logging.cpp index 22f38192fa5d..435017e9d744 100644 --- a/lldb/source/Utility/Logging.cpp +++ b/lldb/source/Utility/Logging.cpp @@ -1,4 +1,4 @@ -//===-- Logging.cpp ---------------------------------------------*- C++ -*-===// +//===-- Logging.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/NameMatches.cpp b/lldb/source/Utility/NameMatches.cpp index 5c9579ea7332..1c8cd6a0ca31 100644 --- a/lldb/source/Utility/NameMatches.cpp +++ b/lldb/source/Utility/NameMatches.cpp @@ -1,4 +1,4 @@ -//===-- NameMatches.cpp -----------------------------------------*- C++ -*-===// +//===-- NameMatches.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/PPC64LE_DWARF_Registers.h b/lldb/source/Utility/PPC64LE_DWARF_Registers.h index 548c1fda8600..cd53e7a2abd0 100644 --- a/lldb/source/Utility/PPC64LE_DWARF_Registers.h +++ b/lldb/source/Utility/PPC64LE_DWARF_Registers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_PPC64LE_DWARF_Registers_h_ -#define utility_PPC64LE_DWARF_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_PPC64LE_DWARF_REGISTERS_H +#define LLDB_SOURCE_UTILITY_PPC64LE_DWARF_REGISTERS_H #include "lldb/lldb-private.h" @@ -190,4 +190,4 @@ enum { } // namespace ppc64le_dwarf -#endif // utility_PPC64LE_DWARF_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_PPC64LE_DWARF_REGISTERS_H diff --git a/lldb/source/Utility/PPC64_DWARF_Registers.h b/lldb/source/Utility/PPC64_DWARF_Registers.h index 6ba5b6ac3727..4f279be01b27 100644 --- a/lldb/source/Utility/PPC64_DWARF_Registers.h +++ b/lldb/source/Utility/PPC64_DWARF_Registers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef utility_PPC64_DWARF_Registers_h_ -#define utility_PPC64_DWARF_Registers_h_ +#ifndef LLDB_SOURCE_UTILITY_PPC64_DWARF_REGISTERS_H +#define LLDB_SOURCE_UTILITY_PPC64_DWARF_REGISTERS_H #include "lldb/lldb-private.h" @@ -123,4 +123,4 @@ enum { } // namespace ppc64_dwarf -#endif // utility_PPC64_DWARF_Registers_h_ +#endif // LLDB_SOURCE_UTILITY_PPC64_DWARF_REGISTERS_H diff --git a/lldb/source/Utility/ProcessInfo.cpp b/lldb/source/Utility/ProcessInfo.cpp index b159e2641973..aae48d6a4872 100644 --- a/lldb/source/Utility/ProcessInfo.cpp +++ b/lldb/source/Utility/ProcessInfo.cpp @@ -1,4 +1,4 @@ -//===-- ProcessInfo.cpp -----------------------------------------*- C++ -*-===// +//===-- ProcessInfo.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ using namespace lldb; using namespace lldb_private; +using namespace lldb_private::repro; ProcessInfo::ProcessInfo() : m_executable(), m_arguments(), m_environment(), m_uid(UINT32_MAX), @@ -75,7 +76,7 @@ void ProcessInfo::SetExecutableFile(const FileSpec &exe_file, llvm::StringRef ProcessInfo::GetArg0() const { return m_arg0; } -void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = arg; } +void ProcessInfo::SetArg0(llvm::StringRef arg) { m_arg0 = std::string(arg); } void ProcessInfo::SetArguments(char const **argv, bool first_arg_is_executable) { @@ -331,3 +332,100 @@ void ProcessInstanceInfoMatch::Clear() { m_name_match_type = NameMatch::Ignore; m_match_all_users = false; } + +void llvm::yaml::MappingTraits<ProcessInstanceInfo>::mapping( + IO &io, ProcessInstanceInfo &Info) { + io.mapRequired("executable", Info.m_executable); + io.mapRequired("arg0", Info.m_arg0); + io.mapRequired("args", Info.m_arguments); + io.mapRequired("arch", Info.m_arch); + io.mapRequired("uid", Info.m_uid); + io.mapRequired("gid", Info.m_gid); + io.mapRequired("pid", Info.m_pid); + io.mapRequired("effective-uid", Info.m_euid); + io.mapRequired("effective-gid", Info.m_egid); + io.mapRequired("parent-pid", Info.m_parent_pid); +} + +llvm::Expected<std::unique_ptr<ProcessInfoRecorder>> +ProcessInfoRecorder::Create(const FileSpec &filename) { + std::error_code ec; + auto recorder = + std::make_unique<ProcessInfoRecorder>(std::move(filename), ec); + if (ec) + return llvm::errorCodeToError(ec); + return std::move(recorder); +} + +void ProcessInfoProvider::Keep() { + std::vector<std::string> files; + for (auto &recorder : m_process_info_recorders) { + recorder->Stop(); + files.push_back(recorder->GetFilename().GetPath()); + } + + FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); + std::error_code ec; + llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + if (ec) + return; + llvm::yaml::Output yout(os); + yout << files; +} + +void ProcessInfoProvider::Discard() { m_process_info_recorders.clear(); } + +ProcessInfoRecorder *ProcessInfoProvider::GetNewProcessInfoRecorder() { + std::size_t i = m_process_info_recorders.size() + 1; + std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") + + llvm::Twine(i) + llvm::Twine(".yaml")) + .str(); + auto recorder_or_error = ProcessInfoRecorder::Create( + GetRoot().CopyByAppendingPathComponent(filename)); + if (!recorder_or_error) { + llvm::consumeError(recorder_or_error.takeError()); + return nullptr; + } + + m_process_info_recorders.push_back(std::move(*recorder_or_error)); + return m_process_info_recorders.back().get(); +} + +void ProcessInfoRecorder::Record(const ProcessInstanceInfoList &process_infos) { + if (!m_record) + return; + llvm::yaml::Output yout(m_os); + yout << const_cast<ProcessInstanceInfoList &>(process_infos); + m_os.flush(); +} + +llvm::Optional<ProcessInstanceInfoList> +repro::GetReplayProcessInstanceInfoList() { + static std::unique_ptr<repro::MultiLoader<repro::ProcessInfoProvider>> + loader = repro::MultiLoader<repro::ProcessInfoProvider>::Create( + repro::Reproducer::Instance().GetLoader()); + + if (!loader) + return {}; + + llvm::Optional<std::string> nextfile = loader->GetNextFile(); + if (!nextfile) + return {}; + + auto error_or_file = llvm::MemoryBuffer::getFile(*nextfile); + if (std::error_code err = error_or_file.getError()) + return {}; + + ProcessInstanceInfoList infos; + llvm::yaml::Input yin((*error_or_file)->getBuffer()); + yin >> infos; + + if (auto err = yin.error()) + return {}; + + return infos; +} + +char ProcessInfoProvider::ID = 0; +const char *ProcessInfoProvider::Info::file = "process-info.yaml"; +const char *ProcessInfoProvider::Info::name = "process-info"; diff --git a/lldb/source/Utility/RegisterValue.cpp b/lldb/source/Utility/RegisterValue.cpp index 36790f5d8efa..7f545c214a4c 100644 --- a/lldb/source/Utility/RegisterValue.cpp +++ b/lldb/source/Utility/RegisterValue.cpp @@ -1,4 +1,4 @@ -//===-- RegisterValue.cpp ---------------------------------------*- C++ -*-===// +//===-- RegisterValue.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -441,7 +441,7 @@ Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info, break; case eEncodingIEEE754: { - std::string value_string = value_str; + std::string value_string = std::string(value_str); if (byte_size == sizeof(float)) { if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) { error.SetErrorStringWithFormat("'%s' is not a valid float string value", @@ -728,7 +728,8 @@ const void *RegisterValue::GetBytes() const { case eTypeFloat: case eTypeDouble: case eTypeLongDouble: - return m_scalar.GetBytes(); + m_scalar.GetBytes(buffer.bytes); + return buffer.bytes; case eTypeBytes: return buffer.bytes; } @@ -810,7 +811,7 @@ bool RegisterValue::operator==(const RegisterValue &rhs) const { if (buffer.length != rhs.buffer.length) return false; else { - uint8_t length = buffer.length; + uint16_t length = buffer.length; if (length > kMaxRegisterByteSize) length = kMaxRegisterByteSize; return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0; diff --git a/lldb/source/Utility/RegularExpression.cpp b/lldb/source/Utility/RegularExpression.cpp index fd9d963f7294..20bebbfe15f2 100644 --- a/lldb/source/Utility/RegularExpression.cpp +++ b/lldb/source/Utility/RegularExpression.cpp @@ -1,4 +1,4 @@ -//===-- RegularExpression.cpp -----------------------------------*- C++ -*-===// +//===-- RegularExpression.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,7 @@ using namespace lldb_private; RegularExpression::RegularExpression(llvm::StringRef str) - : m_regex_text(str), + : m_regex_text(std::string(str)), // m_regex does not reference str anymore after it is constructed. m_regex(llvm::Regex(str)) {} @@ -35,7 +35,7 @@ llvm::StringRef RegularExpression::GetText() const { return m_regex_text; } llvm::Error RegularExpression::GetError() const { std::string error; if (!m_regex.isValid(error)) - return llvm::make_error<llvm::StringError>(llvm::inconvertibleErrorCode(), - error); + return llvm::make_error<llvm::StringError>(error, + llvm::inconvertibleErrorCode()); return llvm::Error::success(); } diff --git a/lldb/source/Utility/Reproducer.cpp b/lldb/source/Utility/Reproducer.cpp index b11e1a577ed2..7620ab2c389d 100644 --- a/lldb/source/Utility/Reproducer.cpp +++ b/lldb/source/Utility/Reproducer.cpp @@ -1,4 +1,4 @@ -//===-- Reproducer.cpp ------------------------------------------*- C++ -*-===// +//===-- Reproducer.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,15 @@ using namespace lldb_private::repro; using namespace llvm; using namespace llvm::yaml; +static llvm::Optional<bool> GetEnv(const char *var) { + std::string val = llvm::StringRef(getenv(var)).lower(); + if (val == "0" || val == "off") + return false; + if (val == "1" || val == "on") + return true; + return {}; +} + Reproducer &Reproducer::Instance() { return *InstanceImpl(); } llvm::Error Reproducer::Initialize(ReproducerMode mode, @@ -27,12 +36,12 @@ llvm::Error Reproducer::Initialize(ReproducerMode mode, // The environment can override the capture mode. if (mode != ReproducerMode::Replay) { - std::string env = - llvm::StringRef(getenv("LLDB_CAPTURE_REPRODUCER")).lower(); - if (env == "0" || env == "off") - mode = ReproducerMode::Off; - else if (env == "1" || env == "on") - mode = ReproducerMode::Capture; + if (llvm::Optional<bool> override = GetEnv("LLDB_CAPTURE_REPRODUCER")) { + if (*override) + mode = ReproducerMode::Capture; + else + mode = ReproducerMode::Off; + } } switch (mode) { @@ -53,7 +62,9 @@ llvm::Error Reproducer::Initialize(ReproducerMode mode, return Instance().SetCapture(root); } break; case ReproducerMode::Replay: - return Instance().SetReplay(root); + return Instance().SetReplay(root, /*passive*/ false); + case ReproducerMode::PassiveReplay: + return Instance().SetReplay(root, /*passive*/ true); case ReproducerMode::Off: break; }; @@ -118,7 +129,7 @@ llvm::Error Reproducer::SetCapture(llvm::Optional<FileSpec> root) { return Error::success(); } -llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root) { +llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root, bool passive) { std::lock_guard<std::mutex> guard(m_mutex); if (root && m_generator) @@ -131,7 +142,7 @@ llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root) { return Error::success(); } - m_loader.emplace(*root); + m_loader.emplace(*root, passive); if (auto e = m_loader->LoadIndex()) return e; @@ -158,8 +169,12 @@ Generator::Generator(FileSpec root) : m_root(MakeAbsolute(std::move(root))) { } Generator::~Generator() { - if (!m_done) - Discard(); + if (!m_done) { + if (m_auto_generate) + Keep(); + else + Discard(); + } } ProviderBase *Generator::Register(std::unique_ptr<ProviderBase> provider) { @@ -190,6 +205,10 @@ void Generator::Discard() { llvm::sys::fs::remove_directories(m_root.GetPath()); } +void Generator::SetAutoGenerate(bool b) { m_auto_generate = b; } + +bool Generator::IsAutoGenerate() const { return m_auto_generate; } + const FileSpec &Generator::GetRoot() const { return m_root; } void Generator::AddProvidersToIndex() { @@ -210,8 +229,9 @@ void Generator::AddProvidersToIndex() { yout << files; } -Loader::Loader(FileSpec root) - : m_root(MakeAbsolute(std::move(root))), m_loaded(false) {} +Loader::Loader(FileSpec root, bool passive) + : m_root(MakeAbsolute(std::move(root))), m_loaded(false), + m_passive_replay(passive) {} llvm::Error Loader::LoadIndex() { if (m_loaded) @@ -252,40 +272,15 @@ DataRecorder::Create(const FileSpec &filename) { return std::move(recorder); } -DataRecorder *CommandProvider::GetNewDataRecorder() { - std::size_t i = m_data_recorders.size() + 1; - std::string filename = (llvm::Twine(Info::name) + llvm::Twine("-") + - llvm::Twine(i) + llvm::Twine(".yaml")) - .str(); - auto recorder_or_error = - DataRecorder::Create(GetRoot().CopyByAppendingPathComponent(filename)); - if (!recorder_or_error) { - llvm::consumeError(recorder_or_error.takeError()); - return nullptr; - } - - m_data_recorders.push_back(std::move(*recorder_or_error)); - return m_data_recorders.back().get(); -} - -void CommandProvider::Keep() { - std::vector<std::string> files; - for (auto &recorder : m_data_recorders) { - recorder->Stop(); - files.push_back(recorder->GetFilename().GetPath()); - } - - FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); +llvm::Expected<std::unique_ptr<YamlRecorder>> +YamlRecorder::Create(const FileSpec &filename) { std::error_code ec; - llvm::raw_fd_ostream os(file.GetPath(), ec, llvm::sys::fs::OF_Text); + auto recorder = std::make_unique<YamlRecorder>(std::move(filename), ec); if (ec) - return; - yaml::Output yout(os); - yout << files; + return llvm::errorCodeToError(ec); + return std::move(recorder); } -void CommandProvider::Discard() { m_data_recorders.clear(); } - void VersionProvider::Keep() { FileSpec file = GetRoot().CopyByAppendingPathComponent(Info::file); std::error_code ec; @@ -304,6 +299,11 @@ void WorkingDirectoryProvider::Keep() { os << m_cwd << "\n"; } +void FileProvider::recordInterestingDirectory(const llvm::Twine &dir) { + if (m_collector) + m_collector->addDirectory(dir); +} + void ProviderBase::anchor() {} char CommandProvider::ID = 0; char FileProvider::ID = 0; diff --git a/lldb/source/Utility/ReproducerInstrumentation.cpp b/lldb/source/Utility/ReproducerInstrumentation.cpp index 473786ef4d3e..09aea69d8313 100644 --- a/lldb/source/Utility/ReproducerInstrumentation.cpp +++ b/lldb/source/Utility/ReproducerInstrumentation.cpp @@ -1,4 +1,4 @@ -//===-- ReproducerInstrumentation.cpp ---------------------------*- C++ -*-===// +//===-- ReproducerInstrumentation.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,6 +8,9 @@ #include "lldb/Utility/ReproducerInstrumentation.h" #include "lldb/Utility/Reproducer.h" +#include <stdio.h> +#include <stdlib.h> +#include <thread> using namespace lldb_private; using namespace lldb_private::repro; @@ -21,19 +24,66 @@ void IndexToObject::AddObjectForIndexImpl(unsigned idx, void *object) { m_mapping[idx] = object; } +std::vector<void *> IndexToObject::GetAllObjects() const { + std::vector<std::pair<unsigned, void *>> pairs; + for (auto &e : m_mapping) { + pairs.emplace_back(e.first, e.second); + } + + // Sort based on index. + std::sort(pairs.begin(), pairs.end(), + [](auto &lhs, auto &rhs) { return lhs.first < rhs.first; }); + + std::vector<void *> objects; + objects.reserve(pairs.size()); + for (auto &p : pairs) { + objects.push_back(p.second); + } + + return objects; +} + +template <> const uint8_t *Deserializer::Deserialize<const uint8_t *>() { + return Deserialize<uint8_t *>(); +} + +template <> void *Deserializer::Deserialize<void *>() { + return const_cast<void *>(Deserialize<const void *>()); +} + +template <> const void *Deserializer::Deserialize<const void *>() { + return nullptr; +} + template <> char *Deserializer::Deserialize<char *>() { return const_cast<char *>(Deserialize<const char *>()); } template <> const char *Deserializer::Deserialize<const char *>() { - auto pos = m_buffer.find('\0'); - if (pos == llvm::StringRef::npos) + const size_t size = Deserialize<size_t>(); + if (size == std::numeric_limits<size_t>::max()) return nullptr; + assert(HasData(size + 1)); const char *str = m_buffer.data(); - m_buffer = m_buffer.drop_front(pos + 1); + m_buffer = m_buffer.drop_front(size + 1); +#ifdef LLDB_REPRO_INSTR_TRACE + llvm::errs() << "Deserializing with " << LLVM_PRETTY_FUNCTION << " -> \"" + << str << "\"\n"; +#endif return str; } +template <> const char **Deserializer::Deserialize<const char **>() { + const size_t size = Deserialize<size_t>(); + if (size == 0) + return nullptr; + const char **r = + reinterpret_cast<const char **>(calloc(size + 1, sizeof(char *))); + for (size_t i = 0; i < size; ++i) + r[i] = Deserialize<const char *>(); + return r; +} + bool Registry::Replay(const FileSpec &file) { auto error_or_file = llvm::MemoryBuffer::getFile(file.GetPath()); if (auto err = error_or_file.getError()) @@ -43,11 +93,19 @@ bool Registry::Replay(const FileSpec &file) { } bool Registry::Replay(llvm::StringRef buffer) { + Deserializer deserializer(buffer); + return Replay(deserializer); +} + +bool Registry::Replay(Deserializer &deserializer) { #ifndef LLDB_REPRO_INSTR_TRACE Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_API); #endif - Deserializer deserializer(buffer); + // Disable buffering stdout so that we approximate the way things get flushed + // during an interactive session. + setvbuf(stdout, nullptr, _IONBF, 0); + while (deserializer.HasData(1)) { unsigned id = deserializer.Deserialize<unsigned>(); @@ -60,6 +118,10 @@ bool Registry::Replay(llvm::StringRef buffer) { GetReplayer(id)->operator()(deserializer); } + // Add a small artificial delay to ensure that all asynchronous events have + // completed before we exit. + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + return true; } @@ -83,6 +145,22 @@ std::string Registry::GetSignature(unsigned id) { return m_ids[id].second.ToString(); } +void Registry::CheckID(unsigned expected, unsigned actual) { + if (expected != actual) { + llvm::errs() << "Reproducer expected signature " << expected << ": '" + << GetSignature(expected) << "'\n"; + llvm::errs() << "Reproducer actual signature " << actual << ": '" + << GetSignature(actual) << "'\n"; + llvm::report_fatal_error( + "Detected reproducer replay divergence. Refusing to continue."); + } + +#ifdef LLDB_REPRO_INSTR_TRACE + llvm::errs() << "Replaying " << actual << ": " << GetSignature(actual) + << "\n"; +#endif +} + Replayer *Registry::GetReplayer(unsigned id) { assert(m_ids.count(id) != 0 && "ID not in registry"); return m_ids[id].first; @@ -101,6 +179,15 @@ unsigned ObjectToIndex::GetIndexForObjectImpl(const void *object) { return m_mapping[object]; } +Recorder::Recorder() + : m_serializer(nullptr), m_pretty_func(), m_pretty_args(), + m_local_boundary(false), m_result_recorded(true) { + if (!g_global_boundary) { + g_global_boundary = true; + m_local_boundary = true; + } +} + Recorder::Recorder(llvm::StringRef pretty_func, std::string &&pretty_args) : m_serializer(nullptr), m_pretty_func(pretty_func), m_pretty_args(pretty_args), m_local_boundary(false), @@ -119,4 +206,25 @@ Recorder::~Recorder() { UpdateBoundary(); } +void InstrumentationData::Initialize(Serializer &serializer, + Registry ®istry) { + InstanceImpl().emplace(serializer, registry); +} + +void InstrumentationData::Initialize(Deserializer &deserializer, + Registry ®istry) { + InstanceImpl().emplace(deserializer, registry); +} + +InstrumentationData &InstrumentationData::Instance() { + if (!InstanceImpl()) + InstanceImpl().emplace(); + return *InstanceImpl(); +} + +llvm::Optional<InstrumentationData> &InstrumentationData::InstanceImpl() { + static llvm::Optional<InstrumentationData> g_instrumentation_data; + return g_instrumentation_data; +} + bool lldb_private::repro::Recorder::g_global_boundary; diff --git a/lldb/source/Utility/Scalar.cpp b/lldb/source/Utility/Scalar.cpp index a9293e87220b..6c48bbde532f 100644 --- a/lldb/source/Utility/Scalar.cpp +++ b/lldb/source/Utility/Scalar.cpp @@ -1,4 +1,4 @@ -//===-- Scalar.cpp ----------------------------------------------*- C++ -*-===// +//===-- Scalar.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,14 +7,14 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/Scalar.h" - +#include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-types.h" - +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallString.h" #include <cinttypes> @@ -23,6 +23,63 @@ using namespace lldb; using namespace lldb_private; +using llvm::APFloat; +using llvm::APInt; + +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( @@ -73,112 +130,49 @@ Scalar::Scalar() : m_type(e_void), m_float(static_cast<float>(0)) {} bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const { size_t byte_size = GetByteSize(); - if (byte_size > 0) { - const uint8_t *bytes = static_cast<const uint8_t *>(GetBytes()); - - if (limit_byte_size < byte_size) { - if (endian::InlHostByteOrder() == eByteOrderLittle) { - // On little endian systems if we want fewer bytes from the current - // type we just specify fewer bytes since the LSByte is first... - byte_size = limit_byte_size; - } else if (endian::InlHostByteOrder() == eByteOrderBig) { - // On big endian systems if we want fewer bytes from the current type - // have to advance our initial byte pointer and trim down the number of - // bytes since the MSByte is first - bytes += byte_size - limit_byte_size; - byte_size = limit_byte_size; - } + if (byte_size == 0) { + data.Clear(); + return false; + } + auto buffer_up = std::make_unique<DataBufferHeap>(byte_size, 0); + GetBytes(buffer_up->GetData()); + lldb::offset_t offset = 0; + + if (limit_byte_size < byte_size) { + if (endian::InlHostByteOrder() == eByteOrderLittle) { + // On little endian systems if we want fewer bytes from the current + // type we just specify fewer bytes since the LSByte is first... + byte_size = limit_byte_size; + } else if (endian::InlHostByteOrder() == eByteOrderBig) { + // On big endian systems if we want fewer bytes from the current type + // have to advance our initial byte pointer and trim down the number of + // bytes since the MSByte is first + offset = byte_size - limit_byte_size; + byte_size = limit_byte_size; } - - data.SetData(bytes, byte_size, endian::InlHostByteOrder()); - return true; } - data.Clear(); - return false; + + data.SetData(std::move(buffer_up), offset, byte_size); + data.SetByteOrder(endian::InlHostByteOrder()); + return true; } -const void *Scalar::GetBytes() const { - const uint64_t *apint_words; - const uint8_t *bytes; - static float_t flt_val; - static double_t dbl_val; - static uint64_t swapped_words[8]; - switch (m_type) { - case e_void: +void Scalar::GetBytes(llvm::MutableArrayRef<uint8_t> storage) const { + assert(storage.size() >= GetByteSize()); + + const auto &store = [&](const llvm::APInt val) { + StoreIntToMemory(val, storage.data(), (val.getBitWidth() + 7) / 8); + }; + switch (GetCategory(m_type)) { + case Category::Void: + break; + case Category::Integral: + store(m_integer); + break; + case Category::Float: + store(m_float.bitcastToAPInt()); break; - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData()); - // getRawData always returns a pointer to an uint64_t. If we have a - // smaller type, we need to update the pointer on big-endian systems. - if (endian::InlHostByteOrder() == eByteOrderBig) { - size_t byte_size = m_integer.getBitWidth() / 8; - if (byte_size < 8) - bytes += 8 - byte_size; - } - return bytes; - // getRawData always returns a pointer to an array of uint64_t values, - // where the least-significant word always comes first. On big-endian - // systems we need to swap the words. - case e_sint128: - case e_uint128: - apint_words = m_integer.getRawData(); - if (endian::InlHostByteOrder() == eByteOrderBig) { - swapped_words[0] = apint_words[1]; - swapped_words[1] = apint_words[0]; - apint_words = swapped_words; - } - return static_cast<const void *>(apint_words); - case e_sint256: - case e_uint256: - apint_words = m_integer.getRawData(); - if (endian::InlHostByteOrder() == eByteOrderBig) { - swapped_words[0] = apint_words[3]; - swapped_words[1] = apint_words[2]; - swapped_words[2] = apint_words[1]; - swapped_words[3] = apint_words[0]; - apint_words = swapped_words; - } - return static_cast<const void *>(apint_words); - case e_sint512: - case e_uint512: - apint_words = m_integer.getRawData(); - if (endian::InlHostByteOrder() == eByteOrderBig) { - swapped_words[0] = apint_words[7]; - swapped_words[1] = apint_words[6]; - swapped_words[2] = apint_words[5]; - swapped_words[3] = apint_words[4]; - swapped_words[4] = apint_words[3]; - swapped_words[5] = apint_words[2]; - swapped_words[6] = apint_words[1]; - swapped_words[7] = apint_words[0]; - apint_words = swapped_words; - } - return static_cast<const void *>(apint_words); - case e_float: - flt_val = m_float.convertToFloat(); - return static_cast<const void *>(&flt_val); - case e_double: - dbl_val = m_float.convertToDouble(); - return static_cast<const void *>(&dbl_val); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - apint_words = ldbl_val.getRawData(); - // getRawData always returns a pointer to an array of two uint64_t values, - // where the least-significant word always comes first. On big-endian - // systems we need to swap the two words. - if (endian::InlHostByteOrder() == eByteOrderBig) { - swapped_words[0] = apint_words[1]; - swapped_words[1] = apint_words[0]; - apint_words = swapped_words; - } - return static_cast<const void *>(apint_words); } - return nullptr; } size_t Scalar::GetByteSize() const { @@ -209,26 +203,12 @@ size_t Scalar::GetByteSize() const { } 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; @@ -238,171 +218,18 @@ void Scalar::GetValue(Stream *s, bool show_type) const { 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()); - break; - } -} - -const char *Scalar::GetTypeAsCString() const { - switch (m_type) { - case e_void: - return "void"; - case e_sint: - return "int"; - case e_uint: - return "unsigned int"; - case e_slong: - return "long"; - case e_ulong: - return "unsigned long"; - case e_slonglong: - return "long long"; - case e_ulonglong: - return "unsigned long long"; - case e_sint128: - return "int128_t"; - case e_uint128: - return "unsigned int128_t"; - case e_sint256: - return "int256_t"; - case e_uint256: - return "unsigned int256_t"; - case e_sint512: - return "int512_t"; - case e_uint512: - return "unsigned int512_t"; - case e_float: - return "float"; - case e_double: - return "double"; - case e_long_double: - return "long double"; - } - return "<invalid Scalar type>"; -} - -Scalar &Scalar::operator=(const int v) { - m_type = e_sint; - m_integer = llvm::APInt(sizeof(int) * 8, v, true); - return *this; -} - -Scalar &Scalar::operator=(unsigned int v) { - m_type = e_uint; - m_integer = llvm::APInt(sizeof(int) * 8, v); - return *this; -} - -Scalar &Scalar::operator=(long v) { - m_type = e_slong; - m_integer = llvm::APInt(sizeof(long) * 8, v, true); - return *this; -} - -Scalar &Scalar::operator=(unsigned long v) { - m_type = e_ulong; - m_integer = llvm::APInt(sizeof(long) * 8, v); - return *this; -} - -Scalar &Scalar::operator=(long long v) { - m_type = e_slonglong; - m_integer = llvm::APInt(sizeof(long) * 8, v, true); - return *this; -} - -Scalar &Scalar::operator=(unsigned long long v) { - m_type = e_ulonglong; - m_integer = llvm::APInt(sizeof(long long) * 8, v); - return *this; -} - -Scalar &Scalar::operator=(float v) { - m_type = e_float; - m_float = llvm::APFloat(v); - return *this; -} - -Scalar &Scalar::operator=(double v) { - m_type = e_double; - m_float = llvm::APFloat(v); - return *this; -} - -Scalar &Scalar::operator=(long double v) { - m_type = e_long_double; - if (m_ieee_quad) - m_float = llvm::APFloat(llvm::APFloat::IEEEquad(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast<type128 *>(&v))->x)); - else - m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast<type128 *>(&v))->x)); - return *this; -} - -Scalar &Scalar::operator=(llvm::APInt rhs) { - m_integer = llvm::APInt(rhs); - switch (m_integer.getBitWidth()) { - case 8: - case 16: - case 32: - if (m_integer.isSignedIntN(sizeof(sint_t) * 8)) - m_type = e_sint; - else - m_type = e_uint; - break; - case 64: - if (m_integer.isSignedIntN(sizeof(slonglong_t) * 8)) - m_type = e_slonglong; - else - m_type = e_ulonglong; - break; - case 128: - if (m_integer.isSignedIntN(BITWIDTH_INT128)) - m_type = e_sint128; - else - m_type = e_uint128; - break; - case 256: - if (m_integer.isSignedIntN(BITWIDTH_INT256)) - m_type = e_sint256; - else - m_type = e_uint256; - break; - case 512: - if (m_integer.isSignedIntN(BITWIDTH_INT512)) - m_type = e_sint512; - else - m_type = e_uint512; + s->PutCString(string); break; } - return *this; } Scalar::~Scalar() = default; @@ -427,716 +254,111 @@ Scalar::Type Scalar::GetBestTypeForBitSize(size_t bit_size, bool sign) { return Scalar::e_void; } -void Scalar::TruncOrExtendTo(Scalar::Type type, uint16_t bits) { +void Scalar::TruncOrExtendTo(uint16_t bits, bool sign) { + m_integer = sign ? m_integer.sextOrTrunc(bits) : m_integer.zextOrTrunc(bits); + m_type = GetBestTypeForBitSize(bits, sign); +} + +static size_t GetBitSize(Scalar::Type type) { 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."); + case Scalar::e_void: + return 0; + case Scalar::e_sint: + return 8 * sizeof(int); + case Scalar::e_uint: + return 8 * sizeof(unsigned int); + case Scalar::e_slong: + return 8 * sizeof(long); + case Scalar::e_ulong: + return 8 * sizeof(unsigned long); + case Scalar::e_slonglong: + return 8 * sizeof(long long); + case Scalar::e_ulonglong: + return 8 * sizeof(unsigned long long); + case Scalar::e_sint128: + case Scalar::e_uint128: + return BITWIDTH_INT128; + case Scalar::e_sint256: + case Scalar::e_uint256: + return BITWIDTH_INT256; + case Scalar::e_sint512: + case Scalar::e_uint512: + return BITWIDTH_INT512; + case Scalar::e_float: + return 8 * sizeof(float); + case Scalar::e_double: + return 8 * sizeof(double); + case Scalar::e_long_double: + return 8 * sizeof(long double); } - m_type = type; + llvm_unreachable("Unhandled type!"); +} + +static const llvm::fltSemantics &GetFltSemantics(Scalar::Type type) { + switch (type) { + case Scalar::e_void: + 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: + llvm_unreachable("Only floating point types supported!"); + case Scalar::e_float: + return llvm::APFloat::IEEEsingle(); + case Scalar::e_double: + return llvm::APFloat::IEEEdouble(); + case Scalar::e_long_double: + return llvm::APFloat::x87DoubleExtended(); + } + llvm_unreachable("Unhandled type!"); } bool Scalar::Promote(Scalar::Type type) { bool success = false; - switch (m_type) { - case e_void: - break; - - case e_sint: - switch (type) { - case e_void: - break; - case e_sint: - success = true; - break; - case e_uint: - m_integer = m_integer.sextOrTrunc(sizeof(uint_t) * 8); - success = true; - break; - - case e_slong: - m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8); - success = true; - break; - - case e_ulong: - m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8); - success = true; - break; - - case e_slonglong: - m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); - success = true; - break; - - case e_ulonglong: - m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_uint: - switch (type) { - case e_void: - case e_sint: - break; - case e_uint: - success = true; - break; - case e_slong: - m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8); - success = true; - break; - - case e_ulong: - m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8); - success = true; - break; - - case e_slonglong: - m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8); - success = true; - break; - - case e_ulonglong: - m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_slong: - switch (type) { - case e_void: - case e_sint: - case e_uint: - break; - case e_slong: - success = true; - break; - case e_ulong: - m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8); - success = true; - break; - - case e_slonglong: - m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); - success = true; - break; - - case e_ulonglong: - m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_ulong: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - break; - case e_ulong: - success = true; - break; - case e_slonglong: - m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8); - success = true; - break; - - case e_ulonglong: - m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_slonglong: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - break; - case e_slonglong: - success = true; - break; - case e_ulonglong: - m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8); - success = true; - break; - - case e_sint128: - case e_uint128: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_ulonglong: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - break; - case e_ulonglong: - success = true; - break; - case e_sint128: - case e_uint128: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } + switch (GetCategory(m_type)) { + case Category::Void: break; - - case e_sint128: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - break; - case e_sint128: - success = true; - break; - case e_uint128: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); - success = true; - break; - - case e_sint256: - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT512); - success = true; + case Category::Integral: + switch (GetCategory(type)) { + case Category::Void: break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); + case Category::Integral: + if (type < m_type) + break; success = true; + if (IsSigned(m_type)) + m_integer = m_integer.sextOrTrunc(GetBitSize(type)); + else + m_integer = m_integer.zextOrTrunc(GetBitSize(type)); break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, + case Category::Float: + m_float = llvm::APFloat(GetFltSemantics(type)); + m_float.convertFromAPInt(m_integer, IsSigned(m_type), llvm::APFloat::rmNearestTiesToEven); success = true; break; } break; - - case e_uint128: - switch (type) { - case e_void: - case e_sint: - case e_uint: - case e_slong: - case e_ulong: - case e_slonglong: - case e_ulonglong: - case e_sint128: - break; - case e_uint128: - success = true; - break; - case e_sint256: - case e_uint256: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_sint256: - switch (type) { - case e_void: - 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 Category::Float: + switch (GetCategory(type)) { + case Category::Void: + case Category::Integral: break; - case e_sint256: - success = true; - break; - case e_uint256: - m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256); - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, true, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_uint256: - switch (type) { - case e_void: - 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: - break; - case e_uint256: - success = true; - break; - - case e_sint512: - case e_uint512: - m_integer = m_integer.zextOrTrunc(BITWIDTH_INT512); - success = true; - break; - - case e_float: - m_float = llvm::APFloat(llvm::APFloat::IEEEsingle()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_double: - m_float = llvm::APFloat(llvm::APFloat::IEEEdouble()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - - case e_long_double: - m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended()); - m_float.convertFromAPInt(m_integer, false, - llvm::APFloat::rmNearestTiesToEven); - success = true; - break; - } - break; - - case e_sint512: - case e_uint512: - lldbassert(false && "unimplemented"); - break; - - case e_float: - switch (type) { - case e_void: - 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: - break; - case e_float: - success = true; - break; - case e_double: - m_float = llvm::APFloat(static_cast<double_t>(m_float.convertToFloat())); - success = true; - break; - - case e_long_double: { - bool ignore; - m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended(), - llvm::APFloat::rmNearestTiesToEven, &ignore); - success = true; - break; - } - } - break; - - case e_double: - switch (type) { - case e_void: - 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 e_float: - break; - case e_double: - success = true; - break; - case e_long_double: { + case Category::Float: + if (type < m_type) + break; bool ignore; - m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad() - : llvm::APFloat::x87DoubleExtended(), - llvm::APFloat::rmNearestTiesToEven, &ignore); success = true; - break; - } + m_float.convert(GetFltSemantics(type), llvm::APFloat::rmNearestTiesToEven, + &ignore); } - break; - - case e_long_double: - switch (type) { - case e_void: - 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 e_float: - case e_double: - break; - case e_long_double: - success = true; - break; - } - break; } if (success) @@ -1338,444 +560,132 @@ bool Scalar::MakeUnsigned() { return success; } -signed char Scalar::SChar(char fail_value) const { - switch (m_type) { - case e_void: +static llvm::APInt ToAPInt(const llvm::APFloat &f, unsigned bits, + bool is_unsigned) { + llvm::APSInt result(bits, is_unsigned); + bool isExact; + f.convertToInteger(result, llvm::APFloat::rmTowardZero, &isExact); + return std::move(result); +} + +template <typename T> T Scalar::GetAs(T fail_value) const { + 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: - return static_cast<schar_t>( - (m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue()); - case e_float: - return static_cast<schar_t>(m_float.convertToFloat()); - case e_double: - return static_cast<schar_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<schar_t>( - (ldbl_val.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue()); + 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::Float: + return ToAPInt(m_float, sizeof(T) * 8, std::is_unsigned<T>::value) + .getSExtValue(); } return fail_value; } +signed char Scalar::SChar(signed char fail_value) const { + return GetAs<signed char>(fail_value); +} + unsigned char Scalar::UChar(unsigned char fail_value) const { - switch (m_type) { - case 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: - return static_cast<uchar_t>( - (m_integer.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue()); - case e_float: - return static_cast<uchar_t>(m_float.convertToFloat()); - case e_double: - return static_cast<uchar_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<uchar_t>( - (ldbl_val.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue()); - } - return fail_value; + return GetAs<unsigned char>(fail_value); } short Scalar::SShort(short fail_value) const { - switch (m_type) { - case 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: - return static_cast<sshort_t>( - (m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue()); - case e_float: - return static_cast<sshort_t>(m_float.convertToFloat()); - case e_double: - return static_cast<sshort_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<sshort_t>( - (ldbl_val.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue()); - } - return fail_value; + return GetAs<short>(fail_value); } unsigned short Scalar::UShort(unsigned short fail_value) const { - switch (m_type) { - case 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: - return static_cast<ushort_t>( - (m_integer.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue()); - case e_float: - return static_cast<ushort_t>(m_float.convertToFloat()); - case e_double: - return static_cast<ushort_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<ushort_t>( - (ldbl_val.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue()); - } - return fail_value; + return GetAs<unsigned short>(fail_value); } -int Scalar::SInt(int fail_value) const { - switch (m_type) { - case 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: - return static_cast<sint_t>( - (m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue()); - case e_float: - return static_cast<sint_t>(m_float.convertToFloat()); - case e_double: - return static_cast<sint_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<sint_t>( - (ldbl_val.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue()); - } - return fail_value; -} +int Scalar::SInt(int fail_value) const { return GetAs<int>(fail_value); } unsigned int Scalar::UInt(unsigned int fail_value) const { - switch (m_type) { - case 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: - return static_cast<uint_t>( - (m_integer.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue()); - case e_float: - return static_cast<uint_t>(m_float.convertToFloat()); - case e_double: - return static_cast<uint_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<uint_t>( - (ldbl_val.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue()); - } - return fail_value; + return GetAs<unsigned int>(fail_value); } -long Scalar::SLong(long fail_value) const { - switch (m_type) { - case 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: - return static_cast<slong_t>( - (m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue()); - case e_float: - return static_cast<slong_t>(m_float.convertToFloat()); - case e_double: - return static_cast<slong_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<slong_t>( - (ldbl_val.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue()); - } - return fail_value; -} +long Scalar::SLong(long fail_value) const { return GetAs<long>(fail_value); } unsigned long Scalar::ULong(unsigned long fail_value) const { - switch (m_type) { - case 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: - return static_cast<ulong_t>( - (m_integer.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue()); - case e_float: - return static_cast<ulong_t>(m_float.convertToFloat()); - case e_double: - return static_cast<ulong_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<ulong_t>( - (ldbl_val.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue()); - } - return fail_value; + return GetAs<unsigned long>(fail_value); } long long Scalar::SLongLong(long long fail_value) const { - switch (m_type) { - case 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: - return static_cast<slonglong_t>( - (m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue()); - case e_float: - return static_cast<slonglong_t>(m_float.convertToFloat()); - case e_double: - return static_cast<slonglong_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<slonglong_t>( - (ldbl_val.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue()); - } - return fail_value; + return GetAs<long long>(fail_value); } unsigned long long Scalar::ULongLong(unsigned long long fail_value) const { - switch (m_type) { - case 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: - return static_cast<ulonglong_t>( - (m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue()); - case e_float: - return static_cast<ulonglong_t>(m_float.convertToFloat()); - case e_double: { - double d_val = m_float.convertToDouble(); - llvm::APInt rounded_double = - llvm::APIntOps::RoundDoubleToAPInt(d_val, sizeof(ulonglong_t) * 8); - return static_cast<ulonglong_t>( - (rounded_double.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue()); - } - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<ulonglong_t>( - (ldbl_val.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue()); - } - return fail_value; + return GetAs<unsigned long long>(fail_value); } -llvm::APInt Scalar::SInt128(llvm::APInt &fail_value) const { - switch (m_type) { - case e_void: +llvm::APInt Scalar::SInt128(const llvm::APInt &fail_value) const { + 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: return m_integer; - case e_float: - case e_double: - case e_long_double: - return m_float.bitcastToAPInt(); + case Category::Float: + return ToAPInt(m_float, 128, /*is_unsigned=*/false); } return fail_value; } llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const { - 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: return m_integer; - case e_float: - case e_double: - case e_long_double: - return m_float.bitcastToAPInt(); + case Category::Float: + return ToAPInt(m_float, 128, /*is_unsigned=*/true); } return fail_value; } float Scalar::Float(float fail_value) const { - 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: + if (IsSigned(m_type)) + return llvm::APIntOps::RoundSignedAPIntToFloat(m_integer); return llvm::APIntOps::RoundAPIntToFloat(m_integer); - case e_float: - return m_float.convertToFloat(); - case e_double: - return static_cast<float_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return ldbl_val.bitsToFloat(); + + case Category::Float: { + APFloat result = m_float; + bool losesInfo; + result.convert(APFloat::IEEEsingle(), APFloat::rmNearestTiesToEven, + &losesInfo); + return result.convertToFloat(); + } } return fail_value; } double Scalar::Double(double fail_value) const { - 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: + if (IsSigned(m_type)) + return llvm::APIntOps::RoundSignedAPIntToDouble(m_integer); return llvm::APIntOps::RoundAPIntToDouble(m_integer); - case e_float: - return static_cast<double_t>(m_float.convertToFloat()); - case e_double: - return m_float.convertToDouble(); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return ldbl_val.bitsToFloat(); + + case Category::Float: { + APFloat result = m_float; + bool losesInfo; + result.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven, + &losesInfo); + return result.convertToDouble(); + } } return fail_value; } long double Scalar::LongDouble(long double fail_value) const { - switch (m_type) { - case 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: - return static_cast<long_double_t>( - llvm::APIntOps::RoundAPIntToDouble(m_integer)); - case e_float: - return static_cast<long_double_t>(m_float.convertToFloat()); - case e_double: - return static_cast<long_double_t>(m_float.convertToDouble()); - case e_long_double: - llvm::APInt ldbl_val = m_float.bitcastToAPInt(); - return static_cast<long_double_t>(ldbl_val.bitsToDouble()); - } - return fail_value; + /// No way to get more precision at the moment. + return static_cast<long double>(Double(fail_value)); } Scalar &Scalar::operator+=(const Scalar &rhs) { @@ -1784,27 +694,14 @@ Scalar &Scalar::operator+=(const Scalar &rhs) { 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; } @@ -1813,99 +710,22 @@ Scalar &Scalar::operator+=(const Scalar &rhs) { } 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) { @@ -1957,50 +777,11 @@ Scalar &Scalar::operator>>=(const Scalar &rhs) { } 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; } @@ -2036,26 +817,13 @@ bool Scalar::AbsoluteValue() { } 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; } @@ -2063,62 +831,17 @@ bool Scalar::UnaryNegate() { } 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; } @@ -2129,26 +852,13 @@ const Scalar lldb_private::operator-(const Scalar &lhs, const Scalar &rhs) { 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; } @@ -2162,40 +872,20 @@ const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) { 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 @@ -2211,26 +901,13 @@ const Scalar lldb_private::operator*(const Scalar &lhs, const Scalar &rhs) { 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; } @@ -2245,29 +922,10 @@ const Scalar lldb_private::operator&(const Scalar &lhs, const Scalar &rhs) { 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; } @@ -2279,30 +937,10 @@ const Scalar lldb_private::operator|(const Scalar &lhs, const Scalar &rhs) { 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; } @@ -2314,33 +952,12 @@ const Scalar lldb_private::operator%(const Scalar &lhs, const Scalar &rhs) { 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; @@ -2354,30 +971,10 @@ const Scalar lldb_private::operator^(const Scalar &lhs, const Scalar &rhs) { 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; } @@ -2406,116 +1003,60 @@ Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding, error.SetErrorString("Invalid encoding."); break; - case eEncodingUint: - if (byte_size <= sizeof(uint64_t)) { - uint64_t uval64; - if (!llvm::to_integer(value_str, uval64)) - error.SetErrorStringWithFormat( - "'%s' is not a valid unsigned integer string value", value_str); - else if (!UIntValueIsValidForSize(uval64, byte_size)) - error.SetErrorStringWithFormat( - "value 0x%" PRIx64 " is too large to fit in a %" PRIu64 - " byte unsigned integer value", - uval64, static_cast<uint64_t>(byte_size)); - else { - m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize(byte_size); - switch (m_type) { - case e_uint: - m_integer = llvm::APInt(sizeof(uint_t) * 8, uval64, false); - break; - case e_ulong: - m_integer = llvm::APInt(sizeof(ulong_t) * 8, uval64, false); - break; - case e_ulonglong: - m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, uval64, false); - break; - default: - error.SetErrorStringWithFormat( - "unsupported unsigned integer byte size: %" PRIu64 "", - static_cast<uint64_t>(byte_size)); - break; - } - } - } else { - error.SetErrorStringWithFormat( - "unsupported unsigned integer byte size: %" PRIu64 "", - static_cast<uint64_t>(byte_size)); - return error; - } - break; - case eEncodingSint: - if (byte_size <= sizeof(int64_t)) { - int64_t sval64; - if (!llvm::to_integer(value_str, sval64)) - error.SetErrorStringWithFormat( - "'%s' is not a valid signed integer string value", value_str); - else if (!SIntValueIsValidForSize(sval64, byte_size)) - error.SetErrorStringWithFormat( - "value 0x%" PRIx64 " is too large to fit in a %" PRIu64 - " byte signed integer value", - sval64, static_cast<uint64_t>(byte_size)); - else { - m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize(byte_size); - switch (m_type) { - case e_sint: - m_integer = llvm::APInt(sizeof(sint_t) * 8, sval64, true); - break; - case e_slong: - m_integer = llvm::APInt(sizeof(slong_t) * 8, sval64, true); - break; - case e_slonglong: - m_integer = llvm::APInt(sizeof(slonglong_t) * 8, sval64, true); - break; - default: - error.SetErrorStringWithFormat( - "unsupported signed integer byte size: %" PRIu64 "", - static_cast<uint64_t>(byte_size)); - break; - } - } - } else { - error.SetErrorStringWithFormat( - "unsupported signed integer byte size: %" PRIu64 "", - static_cast<uint64_t>(byte_size)); - return error; + case eEncodingUint: { + llvm::StringRef str = value_str; + bool is_signed = encoding == eEncodingSint; + bool is_negative = is_signed && str.consume_front("-"); + APInt integer; + if (str.getAsInteger(0, integer)) { + error.SetErrorStringWithFormatv( + "'{0}' is not a valid integer string value", value_str); + break; + } + bool fits; + if (is_signed) { + integer = integer.zext(integer.getBitWidth() + 1); + if (is_negative) + integer.negate(); + fits = integer.isSignedIntN(byte_size * 8); + } else + fits = integer.isIntN(byte_size * 8); + if (!fits) { + error.SetErrorStringWithFormatv( + "value {0} is too large to fit in a {1} byte integer value", + value_str, byte_size); + break; } + m_type = GetBestTypeForBitSize(8 * byte_size, is_signed); + if (m_type == e_void) { + error.SetErrorStringWithFormatv("unsupported integer byte size: {0}", + byte_size); + break; + } + if (is_signed) + m_integer = integer.sextOrTrunc(GetBitSize(m_type)); + else + m_integer = integer.zextOrTrunc(GetBitSize(m_type)); break; + } - case eEncodingIEEE754: - static float f_val; - static double d_val; - static long double l_val; - if (byte_size == sizeof(float)) { - if (::sscanf(value_str, "%f", &f_val) == 1) { - m_float = llvm::APFloat(f_val); - m_type = e_float; - } else - error.SetErrorStringWithFormat("'%s' is not a valid float string value", - value_str); - } else if (byte_size == sizeof(double)) { - if (::sscanf(value_str, "%lf", &d_val) == 1) { - m_float = llvm::APFloat(d_val); - m_type = e_double; - } else - error.SetErrorStringWithFormat("'%s' is not a valid float string value", - value_str); - } else if (byte_size == sizeof(long double)) { - if (::sscanf(value_str, "%Lf", &l_val) == 1) { - m_float = llvm::APFloat( - llvm::APFloat::x87DoubleExtended(), - llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast<type128 *>(&l_val))->x)); - m_type = e_long_double; - } else - error.SetErrorStringWithFormat("'%s' is not a valid float string value", - value_str); - } else { - error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "", - static_cast<uint64_t>(byte_size)); - return error; + case eEncodingIEEE754: { + Type type = GetValueTypeForFloatWithByteSize(byte_size); + if (type == e_void) { + error.SetErrorStringWithFormatv("unsupported float byte size: {0}", + byte_size); + break; } + APFloat f(GetFltSemantics(type)); + if (llvm::Expected<APFloat::opStatus> op = + f.convertFromString(value_str, APFloat::rmNearestTiesToEven)) { + m_type = type; + m_float = std::move(f); + } else + error = op.takeError(); break; + } case eEncodingVector: error.SetErrorString("vector encoding unsupported."); diff --git a/lldb/source/Utility/SelectHelper.cpp b/lldb/source/Utility/SelectHelper.cpp index 9f5ca586e1ef..40c85bee6072 100644 --- a/lldb/source/Utility/SelectHelper.cpp +++ b/lldb/source/Utility/SelectHelper.cpp @@ -1,4 +1,4 @@ -//===-- SelectHelper.cpp ----------------------------------------*- C++ -*-===// +//===-- SelectHelper.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/SharingPtr.cpp b/lldb/source/Utility/SharingPtr.cpp deleted file mode 100644 index 45f2a773758b..000000000000 --- a/lldb/source/Utility/SharingPtr.cpp +++ /dev/null @@ -1,134 +0,0 @@ -//===---------------------SharingPtr.cpp ------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "lldb/Utility/SharingPtr.h" - -#if defined(ENABLE_SP_LOGGING) - -// If ENABLE_SP_LOGGING is defined, then log all shared pointer assignments and -// allow them to be queried using a pointer by a call to: -#include <assert.h> -#include <execinfo.h> - -#include "llvm/ADT/STLExtras.h" - -#include <map> -#include <mutex> -#include <vector> - -class Backtrace { -public: - Backtrace(); - - ~Backtrace(); - - void GetFrames(); - - void Dump() const; - -private: - void *m_sp_this; - std::vector<void *> m_frames; -}; - -Backtrace::Backtrace() : m_frames() {} - -Backtrace::~Backtrace() {} - -void Backtrace::GetFrames() { - void *frames[1024]; - const int count = ::backtrace(frames, llvm::array_lengthof(frames)); - if (count > 2) - m_frames.assign(frames + 2, frames + (count - 2)); -} - -void Backtrace::Dump() const { - if (!m_frames.empty()) - ::backtrace_symbols_fd(m_frames.data(), m_frames.size(), STDOUT_FILENO); - write(STDOUT_FILENO, "\n\n", 2); -} - -extern "C" void track_sp(void *sp_this, void *ptr, long use_count) { - typedef std::pair<void *, Backtrace> PtrBacktracePair; - typedef std::map<void *, PtrBacktracePair> PtrToBacktraceMap; - static std::mutex g_mutex; - std::lock_guard<std::mutex> guard(g_mutex); - static PtrToBacktraceMap g_map; - - if (sp_this) { - printf("sp(%p) -> %p %lu\n", sp_this, ptr, use_count); - - if (ptr) { - Backtrace bt; - bt.GetFrames(); - g_map[sp_this] = std::make_pair(ptr, bt); - } else { - g_map.erase(sp_this); - } - } else { - if (ptr) - printf("Searching for shared pointers that are tracking %p: ", ptr); - else - printf("Dump all live shared pointres: "); - - uint32_t matches = 0; - PtrToBacktraceMap::iterator pos, end = g_map.end(); - for (pos = g_map.begin(); pos != end; ++pos) { - if (ptr == NULL || pos->second.first == ptr) { - ++matches; - printf("\nsp(%p): %p\n", pos->first, pos->second.first); - pos->second.second.Dump(); - } - } - if (matches == 0) { - printf("none.\n"); - } - } -} -// Put dump_sp_refs in the lldb namespace to it gets through our exports lists -// filter in the LLDB.framework or lldb.so -namespace lldb { - -void dump_sp_refs(void *ptr) { - // Use a specially crafted call to "track_sp" which will dump info on all - // live shared pointers that reference "ptr" - track_sp(NULL, ptr, 0); -} -} - -#endif - -namespace lldb_private { - -namespace imp { - -shared_count::~shared_count() {} - -void shared_count::add_shared() { -#ifdef _MSC_VER - _InterlockedIncrement(&shared_owners_); -#else - ++shared_owners_; -#endif -} - -void shared_count::release_shared() { -#ifdef _MSC_VER - if (_InterlockedDecrement(&shared_owners_) == -1) -#else - if (--shared_owners_ == -1) -#endif - { - on_zero_shared(); - delete this; - } -} - -} // imp - -} // namespace lldb diff --git a/lldb/source/Utility/State.cpp b/lldb/source/Utility/State.cpp index 51fe92bad77e..2d76b801dcaa 100644 --- a/lldb/source/Utility/State.cpp +++ b/lldb/source/Utility/State.cpp @@ -1,4 +1,4 @@ -//===-- State.cpp -----------------------------------------------*- C++ -*-===// +//===-- State.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/Status.cpp b/lldb/source/Utility/Status.cpp index b74db72773dd..e3c4284a8e8a 100644 --- a/lldb/source/Utility/Status.cpp +++ b/lldb/source/Utility/Status.cpp @@ -1,5 +1,4 @@ -//===-- Status.cpp -----------------------------------------------*- C++ -//-*-===// +//===-- Status.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -43,8 +42,13 @@ Status::Status() : m_code(0), m_type(eErrorTypeInvalid), m_string() {} Status::Status(ValueType err, ErrorType type) : m_code(err), m_type(type), m_string() {} +// This logic is confusing because c++ calls the traditional (posix) errno codes +// "generic errors", while we use the term "generic" to mean completely +// arbitrary (text-based) errors. Status::Status(std::error_code EC) - : m_code(EC.value()), m_type(ErrorType::eErrorTypeGeneric), + : m_code(EC.value()), + m_type(EC.category() == std::generic_category() ? eErrorTypePOSIX + : eErrorTypeGeneric), m_string(EC.message()) {} Status::Status(const char *format, ...) @@ -242,7 +246,7 @@ void Status::SetErrorString(llvm::StringRef err_str) { if (Success()) SetErrorToGenericError(); } - m_string = err_str; + m_string = std::string(err_str); } /// Set the current error string to a formatted error string. @@ -271,7 +275,7 @@ int Status::SetErrorStringWithVarArg(const char *format, va_list args) { llvm::SmallString<1024> buf; VASprintf(buf, format, args); - m_string = buf.str(); + m_string = std::string(buf.str()); return buf.size(); } else { m_string.clear(); diff --git a/lldb/source/Utility/Stream.cpp b/lldb/source/Utility/Stream.cpp index b336cb6b5185..a0623bfa6e54 100644 --- a/lldb/source/Utility/Stream.cpp +++ b/lldb/source/Utility/Stream.cpp @@ -1,4 +1,4 @@ -//===-- Stream.cpp ----------------------------------------------*- C++ -*-===// +//===-- Stream.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,13 +22,14 @@ using namespace lldb; using namespace lldb_private; -Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) +Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order, + bool colors) : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order), - m_indent_level(0), m_forwarder(*this) {} + m_indent_level(0), m_forwarder(*this, colors) {} -Stream::Stream() +Stream::Stream(bool colors) : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()), - m_indent_level(0), m_forwarder(*this) {} + m_indent_level(0), m_forwarder(*this, colors) {} // Destructor Stream::~Stream() {} @@ -126,15 +127,10 @@ size_t Stream::PrintfVarArg(const char *format, va_list args) { // Print and End of Line character to the stream size_t Stream::EOL() { return PutChar('\n'); } -// Indent the current line using the current indentation level and print an -// optional string following the indentation spaces. -size_t Stream::Indent(const char *s) { - return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : ""); -} - size_t Stream::Indent(llvm::StringRef str) { - return Printf("%*.*s%s", m_indent_level, m_indent_level, "", - str.str().c_str()); + const size_t ind_length = PutCString(std::string(m_indent_level, ' ')); + const size_t str_length = PutCString(str); + return ind_length + str_length; } // Stream a character "ch" out to this stream. diff --git a/lldb/source/Utility/StreamCallback.cpp b/lldb/source/Utility/StreamCallback.cpp index b3d3adea78bc..c10f678d7a28 100644 --- a/lldb/source/Utility/StreamCallback.cpp +++ b/lldb/source/Utility/StreamCallback.cpp @@ -1,4 +1,4 @@ -//===-- StreamCallback.cpp -------------------------------------*- C++ -*-===// +//===-- StreamCallback.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/StreamString.cpp b/lldb/source/Utility/StreamString.cpp index 6b5b7d337fcc..190be588e887 100644 --- a/lldb/source/Utility/StreamString.cpp +++ b/lldb/source/Utility/StreamString.cpp @@ -1,4 +1,4 @@ -//===-- StreamString.cpp ----------------------------------------*- C++ -*-===// +//===-- StreamString.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/StringExtractor.cpp b/lldb/source/Utility/StringExtractor.cpp index 87fe4f13e450..0553a63a021e 100644 --- a/lldb/source/Utility/StringExtractor.cpp +++ b/lldb/source/Utility/StringExtractor.cpp @@ -1,4 +1,4 @@ -//===-- StringExtractor.cpp -------------------------------------*- C++ -*-===// +//===-- StringExtractor.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/StringExtractor.h" +#include "llvm/ADT/StringExtras.h" #include <tuple> @@ -365,6 +366,6 @@ bool StringExtractor::GetNameColonValue(llvm::StringRef &name, void StringExtractor::SkipSpaces() { const size_t n = m_packet.size(); - while (m_index < n && isspace(m_packet[m_index])) + while (m_index < n && llvm::isSpace(m_packet[m_index])) ++m_index; } diff --git a/lldb/source/Utility/StringExtractorGDBRemote.cpp b/lldb/source/Utility/StringExtractorGDBRemote.cpp index a011e9246d15..cfe7577e4863 100644 --- a/lldb/source/Utility/StringExtractorGDBRemote.cpp +++ b/lldb/source/Utility/StringExtractorGDBRemote.cpp @@ -1,4 +1,4 @@ -//===-- StringExtractorGDBRemote.cpp ----------------------------*- C++ -*-===// +//===-- StringExtractorGDBRemote.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/StringLexer.cpp b/lldb/source/Utility/StringLexer.cpp index c357cb0fb553..947472a014eb 100644 --- a/lldb/source/Utility/StringLexer.cpp +++ b/lldb/source/Utility/StringLexer.cpp @@ -1,4 +1,4 @@ -//===--------------------- StringLexer.cpp -----------------------*- C++-*-===// +//===-- StringLexer.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/StringList.cpp b/lldb/source/Utility/StringList.cpp index 5e06b6b69fc0..809c5a02acf6 100644 --- a/lldb/source/Utility/StringList.cpp +++ b/lldb/source/Utility/StringList.cpp @@ -1,4 +1,4 @@ -//===-- StringList.cpp ------------------------------------------*- C++ -*-===// +//===-- StringList.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -199,7 +199,7 @@ std::string StringList::CopyList(const char *item_preamble, strm << item_preamble; strm << GetStringAtIndex(i); } - return strm.GetString(); + return std::string(strm.GetString()); } StringList &StringList::operator<<(const char *str) { diff --git a/lldb/source/Utility/StructuredData.cpp b/lldb/source/Utility/StructuredData.cpp index d5d7a7ec99a0..df1b35618e4a 100644 --- a/lldb/source/Utility/StructuredData.cpp +++ b/lldb/source/Utility/StructuredData.cpp @@ -1,4 +1,4 @@ -//===---------------------StructuredData.cpp ---------------------*- C++-*-===// +//===-- StructuredData.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -156,7 +156,7 @@ void StructuredData::String::Serialize(json::OStream &s) const { void StructuredData::Dictionary::Serialize(json::OStream &s) const { s.objectBegin(); for (const auto &pair : m_dict) { - s.attributeBegin(pair.first.AsCString()); + s.attributeBegin(pair.first.GetStringRef()); pair.second->Serialize(s); s.attributeEnd(); } diff --git a/lldb/source/Utility/TildeExpressionResolver.cpp b/lldb/source/Utility/TildeExpressionResolver.cpp index b58f45728ce7..c8a0800cb807 100644 --- a/lldb/source/Utility/TildeExpressionResolver.cpp +++ b/lldb/source/Utility/TildeExpressionResolver.cpp @@ -1,4 +1,4 @@ -//===--------------------- TildeExpressionResolver.cpp ----------*- C++ -*-===// +//===-- TildeExpressionResolver.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/Timer.cpp b/lldb/source/Utility/Timer.cpp index 6b46d8ba7364..d55c9863117b 100644 --- a/lldb/source/Utility/Timer.cpp +++ b/lldb/source/Utility/Timer.cpp @@ -1,4 +1,4 @@ -//===-- Timer.cpp -----------------------------------------------*- C++ -*-===// +//===-- Timer.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,6 +15,7 @@ #include <vector> #include <assert.h> +#include <inttypes.h> #include <stdarg.h> #include <stdio.h> diff --git a/lldb/source/Utility/UUID.cpp b/lldb/source/Utility/UUID.cpp index 2a73f9a482ff..4177b43de818 100644 --- a/lldb/source/Utility/UUID.cpp +++ b/lldb/source/Utility/UUID.cpp @@ -1,4 +1,4 @@ -//===-- UUID.cpp ------------------------------------------------*- C++ -*-===// +//===-- UUID.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -61,10 +61,9 @@ static inline int xdigit_to_int(char ch) { llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p, - llvm::SmallVectorImpl<uint8_t> &uuid_bytes, - uint32_t num_uuid_bytes) { + llvm::SmallVectorImpl<uint8_t> &uuid_bytes) { uuid_bytes.clear(); - while (!p.empty()) { + while (p.size() >= 2) { if (isxdigit(p[0]) && isxdigit(p[1])) { int hi_nibble = xdigit_to_int(p[0]); int lo_nibble = xdigit_to_int(p[1]); @@ -73,11 +72,6 @@ UUID::DecodeUUIDBytesFromString(llvm::StringRef p, // Skip both hex digits p = p.drop_front(2); - - // Increment the byte that we are decoding within the UUID value and - // break out if we are done - if (uuid_bytes.size() == num_uuid_bytes) - break; } else if (p.front() == '-') { // Skip dashes p = p.drop_front(); @@ -89,35 +83,30 @@ UUID::DecodeUUIDBytesFromString(llvm::StringRef p, return p; } -size_t UUID::SetFromStringRef(llvm::StringRef str, uint32_t num_uuid_bytes) { +bool UUID::SetFromStringRef(llvm::StringRef str) { llvm::StringRef p = str; // Skip leading whitespace characters p = p.ltrim(); llvm::SmallVector<uint8_t, 20> bytes; - llvm::StringRef rest = - UUID::DecodeUUIDBytesFromString(p, bytes, num_uuid_bytes); - - // If we successfully decoded a UUID, return the amount of characters that - // were consumed - if (bytes.size() == num_uuid_bytes) { - *this = fromData(bytes); - return str.size() - rest.size(); - } + llvm::StringRef rest = UUID::DecodeUUIDBytesFromString(p, bytes); + + // Return false if we could not consume the entire string or if the parsed + // UUID is empty. + if (!rest.empty() || bytes.empty()) + return false; - // Else return zero to indicate we were not able to parse a UUID value - return 0; + *this = fromData(bytes); + return true; } -size_t UUID::SetFromOptionalStringRef(llvm::StringRef str, - uint32_t num_uuid_bytes) { - size_t num_chars_consumed = SetFromStringRef(str, num_uuid_bytes); - if (num_chars_consumed) { +bool UUID::SetFromOptionalStringRef(llvm::StringRef str) { + bool result = SetFromStringRef(str); + if (result) { if (llvm::all_of(m_bytes, [](uint8_t b) { return b == 0; })) Clear(); } - - return num_chars_consumed; -} + return result; +} diff --git a/lldb/source/Utility/UriParser.cpp b/lldb/source/Utility/UriParser.cpp index b446958f2f47..8169b0eee121 100644 --- a/lldb/source/Utility/UriParser.cpp +++ b/lldb/source/Utility/UriParser.cpp @@ -1,4 +1,4 @@ -//===-- UriParser.cpp -------------------------------------------*- C++ -*-===// +//===-- UriParser.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -42,7 +42,7 @@ bool UriParser::Parse(llvm::StringRef uri, llvm::StringRef &scheme, // Extract hostname if (!host_port.empty() && host_port[0] == '[') { // hostname is enclosed with square brackets. - pos = host_port.find(']'); + pos = host_port.rfind(']'); if (pos == std::string::npos) return false; diff --git a/lldb/source/Utility/UserID.cpp b/lldb/source/Utility/UserID.cpp index b76a1cd84f82..8e0146b93498 100644 --- a/lldb/source/Utility/UserID.cpp +++ b/lldb/source/Utility/UserID.cpp @@ -1,4 +1,4 @@ -//===-- UserID.cpp ----------------------------------------------*- C++ -*-===// +//===-- UserID.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/UserIDResolver.cpp b/lldb/source/Utility/UserIDResolver.cpp index 8aac6f948cd2..73bdde77cc0f 100644 --- a/lldb/source/Utility/UserIDResolver.cpp +++ b/lldb/source/Utility/UserIDResolver.cpp @@ -1,4 +1,4 @@ -//===-- UserIDResolver.cpp --------------------------------------*- C++ -*-===// +//===-- UserIDResolver.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/VASprintf.cpp b/lldb/source/Utility/VASprintf.cpp index 2ee0f6676fa7..aea68dfff9f1 100644 --- a/lldb/source/Utility/VASprintf.cpp +++ b/lldb/source/Utility/VASprintf.cpp @@ -1,4 +1,4 @@ -//===-- VASprintf.cpp -------------------------------------------*- C++ -*-===// +//===-- VASprintf.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/VMRange.cpp b/lldb/source/Utility/VMRange.cpp index c8c3334138d3..16c50d6e81b8 100644 --- a/lldb/source/Utility/VMRange.cpp +++ b/lldb/source/Utility/VMRange.cpp @@ -1,4 +1,4 @@ -//===-- VMRange.cpp ---------------------------------------------*- C++ -*-===// +//===-- VMRange.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Utility/XcodeSDK.cpp b/lldb/source/Utility/XcodeSDK.cpp new file mode 100644 index 000000000000..066bf457966c --- /dev/null +++ b/lldb/source/Utility/XcodeSDK.cpp @@ -0,0 +1,309 @@ +//===-- XcodeSDK.cpp ------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Utility/XcodeSDK.h" +#include "lldb/Utility/FileSpec.h" + +#include "lldb/lldb-types.h" + +#include "llvm/ADT/Triple.h" + +#include <string> + +using namespace lldb; +using namespace lldb_private; + +static llvm::StringRef GetName(XcodeSDK::Type type) { + switch (type) { + case XcodeSDK::MacOSX: + return "MacOSX"; + case XcodeSDK::iPhoneSimulator: + return "iPhoneSimulator"; + case XcodeSDK::iPhoneOS: + return "iPhoneOS"; + case XcodeSDK::AppleTVSimulator: + return "AppleTVSimulator"; + case XcodeSDK::AppleTVOS: + return "AppleTVOS"; + case XcodeSDK::WatchSimulator: + return "WatchSimulator"; + case XcodeSDK::watchOS: + return "WatchOS"; + case XcodeSDK::bridgeOS: + return "bridgeOS"; + case XcodeSDK::Linux: + return "Linux"; + case XcodeSDK::unknown: + return {}; + } + llvm_unreachable("Unhandled sdk type!"); +} + +XcodeSDK::XcodeSDK(XcodeSDK::Info info) : m_name(GetName(info.type).str()) { + if (!m_name.empty()) { + if (!info.version.empty()) + m_name += info.version.getAsString(); + if (info.internal) + m_name += ".Internal"; + m_name += ".sdk"; + } +} + +XcodeSDK &XcodeSDK::operator=(XcodeSDK other) { + m_name = other.m_name; + return *this; +} + +bool XcodeSDK::operator==(XcodeSDK other) { + return m_name == other.m_name; +} + +static XcodeSDK::Type ParseSDKName(llvm::StringRef &name) { + if (name.consume_front("MacOSX")) + return XcodeSDK::MacOSX; + if (name.consume_front("iPhoneSimulator")) + return XcodeSDK::iPhoneSimulator; + if (name.consume_front("iPhoneOS")) + return XcodeSDK::iPhoneOS; + if (name.consume_front("AppleTVSimulator")) + return XcodeSDK::AppleTVSimulator; + if (name.consume_front("AppleTVOS")) + return XcodeSDK::AppleTVOS; + if (name.consume_front("WatchSimulator")) + return XcodeSDK::WatchSimulator; + if (name.consume_front("WatchOS")) + return XcodeSDK::watchOS; + if (name.consume_front("bridgeOS")) + return XcodeSDK::bridgeOS; + if (name.consume_front("Linux")) + return XcodeSDK::Linux; + static_assert(XcodeSDK::Linux == XcodeSDK::numSDKTypes - 1, + "New SDK type was added, update this list!"); + return XcodeSDK::unknown; +} + +static llvm::VersionTuple ParseSDKVersion(llvm::StringRef &name) { + unsigned i = 0; + while (i < name.size() && name[i] >= '0' && name[i] <= '9') + ++i; + if (i == name.size() || name[i++] != '.') + return {}; + while (i < name.size() && name[i] >= '0' && name[i] <= '9') + ++i; + if (i == name.size() || name[i++] != '.') + return {}; + + llvm::VersionTuple version; + version.tryParse(name.slice(0, i - 1)); + name = name.drop_front(i); + return version; +} + +static bool ParseAppleInternalSDK(llvm::StringRef &name) { + return name.consume_front("Internal.") || name.consume_front(".Internal."); +} + +XcodeSDK::Info XcodeSDK::Parse() const { + XcodeSDK::Info info; + llvm::StringRef input(m_name); + info.type = ParseSDKName(input); + info.version = ParseSDKVersion(input); + info.internal = ParseAppleInternalSDK(input); + return info; +} + +bool XcodeSDK::IsAppleInternalSDK() const { + llvm::StringRef input(m_name); + ParseSDKName(input); + ParseSDKVersion(input); + return ParseAppleInternalSDK(input); +} + +llvm::VersionTuple XcodeSDK::GetVersion() const { + llvm::StringRef input(m_name); + ParseSDKName(input); + return ParseSDKVersion(input); +} + +XcodeSDK::Type XcodeSDK::GetType() const { + llvm::StringRef input(m_name); + return ParseSDKName(input); +} + +llvm::StringRef XcodeSDK::GetString() const { return m_name; } + +bool XcodeSDK::Info::operator<(const Info &other) const { + return std::tie(type, version, internal) < + std::tie(other.type, other.version, other.internal); +} + +bool XcodeSDK::Info::operator==(const Info &other) const { + return std::tie(type, version, internal) == + std::tie(other.type, other.version, other.internal); +} + +void XcodeSDK::Merge(XcodeSDK other) { + // The "bigger" SDK always wins. + auto l = Parse(); + auto r = other.Parse(); + if (l < r) + *this = other; + else { + // The Internal flag always wins. + if (llvm::StringRef(m_name).endswith(".sdk")) + if (!l.internal && r.internal) + m_name = + m_name.substr(0, m_name.size() - 3) + std::string("Internal.sdk"); + } +} + +std::string XcodeSDK::GetCanonicalName(XcodeSDK::Info info) { + std::string name; + switch (info.type) { + case MacOSX: + name = "macosx"; + break; + case iPhoneSimulator: + name = "iphonesimulator"; + break; + case iPhoneOS: + name = "iphoneos"; + break; + case AppleTVSimulator: + name = "appletvsimulator"; + break; + case AppleTVOS: + name = "appletvos"; + break; + case WatchSimulator: + name = "watchsimulator"; + break; + case watchOS: + name = "watchos"; + break; + case bridgeOS: + name = "bridgeos"; + break; + case Linux: + name = "linux"; + break; + case unknown: + return {}; + } + if (!info.version.empty()) + name += info.version.getAsString(); + if (info.internal) + name += ".internal"; + return name; +} + +bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type sdk_type, + llvm::VersionTuple version) { + switch (sdk_type) { + case Type::MacOSX: + return version >= llvm::VersionTuple(10, 10); + case Type::iPhoneOS: + case Type::iPhoneSimulator: + case Type::AppleTVOS: + case Type::AppleTVSimulator: + return version >= llvm::VersionTuple(8); + case Type::watchOS: + case Type::WatchSimulator: + return version >= llvm::VersionTuple(6); + default: + return false; + } + + return false; +} + +bool XcodeSDK::SupportsSwift() const { + XcodeSDK::Info info = Parse(); + switch (info.type) { + case Type::MacOSX: + return info.version.empty() || info.version >= llvm::VersionTuple(10, 10); + case Type::iPhoneOS: + case Type::iPhoneSimulator: + return info.version.empty() || info.version >= llvm::VersionTuple(8); + case Type::AppleTVSimulator: + case Type::AppleTVOS: + return info.version.empty() || info.version >= llvm::VersionTuple(9); + case Type::WatchSimulator: + case Type::watchOS: + return info.version.empty() || info.version >= llvm::VersionTuple(2); + case Type::Linux: + return true; + default: + return false; + } +} + +bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type, + const FileSpec &sdk_path) { + ConstString last_path_component = sdk_path.GetLastPathComponent(); + + if (!last_path_component) + return false; + + XcodeSDK sdk(last_path_component.GetStringRef().str()); + if (sdk.GetType() != desired_type) + return false; + return SDKSupportsModules(sdk.GetType(), sdk.GetVersion()); +} + +XcodeSDK::Type XcodeSDK::GetSDKTypeForTriple(const llvm::Triple &triple) { + using namespace llvm; + switch (triple.getOS()) { + case Triple::MacOSX: + case Triple::Darwin: + return XcodeSDK::MacOSX; + case Triple::IOS: + switch (triple.getEnvironment()) { + case Triple::MacABI: + return XcodeSDK::MacOSX; + case Triple::Simulator: + return XcodeSDK::iPhoneSimulator; + default: + return XcodeSDK::iPhoneOS; + } + case Triple::TvOS: + if (triple.getEnvironment() == Triple::Simulator) + return XcodeSDK::AppleTVSimulator; + return XcodeSDK::AppleTVOS; + case Triple::WatchOS: + if (triple.getEnvironment() == Triple::Simulator) + return XcodeSDK::WatchSimulator; + return XcodeSDK::watchOS; + case Triple::Linux: + return XcodeSDK::Linux; + default: + return XcodeSDK::unknown; + } +} + +std::string XcodeSDK::FindXcodeContentsDirectoryInPath(llvm::StringRef path) { + auto begin = llvm::sys::path::begin(path); + auto end = llvm::sys::path::end(path); + + // Iterate over the path components until we find something that ends with + // .app. If the next component is Contents then we've found the Contents + // directory. + for (auto it = begin; it != end; ++it) { + if (it->endswith(".app")) { + auto next = it; + if (++next != end && *next == "Contents") { + llvm::SmallString<128> buffer; + llvm::sys::path::append(buffer, begin, ++next, + llvm::sys::path::Style::posix); + return buffer.str().str(); + } + } + } + + return {}; +} |