diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:55:28 +0000 |
commit | e81d9d49145e432d917eea3a70d2ae74dcad1d89 (patch) | |
tree | 9ed5e1a91f242e2cb5911577356e487a55c01b78 /source/Core | |
parent | 85d8ef8f1f0e0e063a8571944302be2d2026f823 (diff) |
Notes
Diffstat (limited to 'source/Core')
46 files changed, 4355 insertions, 2779 deletions
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp index 1cd7a7447b7f0..83100dea93bc3 100644 --- a/source/Core/Address.cpp +++ b/source/Core/Address.cpp @@ -179,7 +179,7 @@ ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, buf[k_buf_len] = '\0'; // NULL terminate // Byte order and address size don't matter for C string dumping.. - DataExtractor data (buf, sizeof(buf), lldb::endian::InlHostByteOrder(), 4); + DataExtractor data (buf, sizeof(buf), endian::InlHostByteOrder(), 4); size_t total_len = 0; size_t bytes_read; Address curr_address(address); @@ -367,21 +367,29 @@ Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target) } addr_t -Address::GetOpcodeLoadAddress (Target *target) const +Address::GetOpcodeLoadAddress (Target *target, AddressClass addr_class) const { addr_t code_addr = GetLoadAddress (target); if (code_addr != LLDB_INVALID_ADDRESS) - code_addr = target->GetOpcodeLoadAddress (code_addr, GetAddressClass()); + { + if (addr_class == eAddressClassInvalid) + addr_class = GetAddressClass(); + code_addr = target->GetOpcodeLoadAddress (code_addr, addr_class); + } return code_addr; } bool -Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target) +Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target, AddressClass addr_class) { if (SetLoadAddress (load_addr, target)) { if (target) - m_offset = target->GetOpcodeLoadAddress (m_offset, GetAddressClass()); + { + if (addr_class == eAddressClassInvalid) + addr_class = GetAddressClass(); + m_offset = target->GetOpcodeLoadAddress (m_offset, addr_class); + } return true; } return false; @@ -455,6 +463,20 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum case DumpStyleLoadAddress: { addr_t load_addr = GetLoadAddress (target); + + /* + * MIPS: + * Display address in compressed form for MIPS16 or microMIPS + * if the address belongs to eAddressClassCodeAlternateISA. + */ + if (target) + { + const llvm::Triple::ArchType llvm_arch = target->GetArchitecture().GetMachine(); + if (llvm_arch == llvm::Triple::mips || llvm_arch == llvm::Triple::mipsel + || llvm_arch == llvm::Triple::mips64 || llvm_arch == llvm::Triple::mips64el) + load_addr = GetCallableLoadAddress (target); + } + if (load_addr == LLDB_INVALID_ADDRESS) { if (fallback_style != DumpStyleInvalid) diff --git a/source/Core/AddressResolverName.cpp b/source/Core/AddressResolverName.cpp index 1c6205fa6bdfd..293002ad517fd 100644 --- a/source/Core/AddressResolverName.cpp +++ b/source/Core/AddressResolverName.cpp @@ -13,7 +13,6 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Core/StreamString.h" -#include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Symbol.h" diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp index 2dc001a9047f2..ffe717f29c43f 100644 --- a/source/Core/ArchSpec.cpp +++ b/source/Core/ArchSpec.cpp @@ -419,8 +419,8 @@ ArchSpec::ArchSpec() : m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { } @@ -428,8 +428,8 @@ ArchSpec::ArchSpec (const char *triple_cstr, Platform *platform) : m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { if (triple_cstr) SetTriple(triple_cstr, platform); @@ -440,8 +440,8 @@ ArchSpec::ArchSpec (const char *triple_cstr) : m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { if (triple_cstr) SetTriple(triple_cstr); @@ -451,8 +451,8 @@ ArchSpec::ArchSpec(const llvm::Triple &triple) : m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { SetTriple(triple); } @@ -461,8 +461,8 @@ ArchSpec::ArchSpec (ArchitectureType arch_type, uint32_t cpu, uint32_t subtype) m_triple (), m_core (kCore_invalid), m_byte_order (eByteOrderInvalid), - m_distribution_id (), - m_flags (0) + m_flags (0), + m_distribution_id () { SetArchitecture (arch_type, cpu, subtype); } @@ -602,7 +602,15 @@ ArchSpec::GetAddressByteSize() const { const CoreDefinition *core_def = FindCoreDefinition (m_core); if (core_def) - return core_def->addr_byte_size; + { + if (core_def->machine == llvm::Triple::mips64 || core_def->machine == llvm::Triple::mips64el) + { + // For N32/O32 applications Address size is 4 bytes. + if (m_flags & (eMIPSABI_N32 | eMIPSABI_O32)) + return 4; + } + return core_def->addr_byte_size; + } return 0; } @@ -836,14 +844,17 @@ ArchSpec::SetTriple (const char *triple_cstr, Platform *platform) void ArchSpec::MergeFrom(const ArchSpec &other) { - if (GetTriple().getVendor() == llvm::Triple::UnknownVendor && !TripleVendorWasSpecified()) + if (TripleVendorIsUnspecifiedUnknown() && !other.TripleVendorIsUnspecifiedUnknown()) GetTriple().setVendor(other.GetTriple().getVendor()); - if (GetTriple().getOS() == llvm::Triple::UnknownOS && !TripleOSWasSpecified()) + if (TripleOSIsUnspecifiedUnknown() && !other.TripleOSIsUnspecifiedUnknown()) GetTriple().setOS(other.GetTriple().getOS()); if (GetTriple().getArch() == llvm::Triple::UnknownArch) GetTriple().setArch(other.GetTriple().getArch()); - if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment) - GetTriple().setEnvironment(other.GetTriple().getEnvironment()); + if (GetTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && !TripleVendorWasSpecified()) + { + if (other.TripleVendorWasSpecified()) + GetTriple().setEnvironment(other.GetTriple().getEnvironment()); + } } bool @@ -868,29 +879,14 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su if (arch_type == eArchTypeMachO) { m_triple.setVendor (llvm::Triple::Apple); - switch (core_def->machine) - { - case llvm::Triple::aarch64: - case llvm::Triple::arm: - case llvm::Triple::thumb: - m_triple.setOS (llvm::Triple::IOS); - break; - - case llvm::Triple::x86: - case llvm::Triple::x86_64: - // Don't set the OS for x86_64 or for x86 as we want to leave it as an "unspecified unknown" - // which means if we ask for the OS from the llvm::Triple we get back llvm::Triple::UnknownOS, but - // if we ask for the string value for the OS it will come back empty (unspecified). - // We do this because we now have iOS and MacOSX as the OS values for x86 and x86_64 for - // normal desktop and simulator binaries. And if we compare a "x86_64-apple-ios" to a "x86_64-apple-" - // triple, it will say it is compatible (because the OS is unspecified in the second one and will match - // anything in the first - break; - - default: - m_triple.setOS (llvm::Triple::MacOSX); - break; - } + + // Don't set the OS. It could be simulator, macosx, ios, watchos, tvos. We could + // get close with the cpu type - but we can't get it right all of the time. Better + // to leave this unset so other sections of code will set it when they have more + // information. + // NB: don't call m_triple.setOS (llvm::Triple::UnknownOS). That sets the OSName to + // "unknown" and the ArchSpec::TripleVendorWasSpecified() method says that any + // OSName setting means it was specified. } else if (arch_type == eArchTypeELF) { @@ -904,6 +900,11 @@ ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t su case llvm::ELF::ELFOSABI_SOLARIS: m_triple.setOS (llvm::Triple::OSType::Solaris); break; } } + else + { + m_triple.setVendor (llvm::Triple::UnknownVendor); + m_triple.setOS (llvm::Triple::UnknownOS); + } // Fall back onto setting the machine type if the arch by name failed... if (m_triple.getArch () == llvm::Triple::UnknownArch) m_triple.setArch (core_def->machine); @@ -966,15 +967,12 @@ ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor(); if (lhs_triple_vendor != rhs_triple_vendor) { - if (exact_match) - { - const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified(); - const bool lhs_vendor_specified = TripleVendorWasSpecified(); - // Both architectures had the vendor specified, so if they aren't - // equal then we return false - if (rhs_vendor_specified && lhs_vendor_specified) - return false; - } + const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified(); + const bool lhs_vendor_specified = TripleVendorWasSpecified(); + // Both architectures had the vendor specified, so if they aren't + // equal then we return false + if (rhs_vendor_specified && lhs_vendor_specified) + return false; // Only fail if both vendor types are not unknown if (lhs_triple_vendor != llvm::Triple::UnknownVendor && @@ -986,15 +984,12 @@ ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS(); if (lhs_triple_os != rhs_triple_os) { - if (exact_match) - { - const bool rhs_os_specified = rhs.TripleOSWasSpecified(); - const bool lhs_os_specified = TripleOSWasSpecified(); - // Both architectures had the OS specified, so if they aren't - // equal then we return false - if (rhs_os_specified && lhs_os_specified) - return false; - } + const bool rhs_os_specified = rhs.TripleOSWasSpecified(); + const bool lhs_os_specified = TripleOSWasSpecified(); + // Both architectures had the OS specified, so if they aren't + // equal then we return false + if (rhs_os_specified && lhs_os_specified) + return false; // Only fail if both os types are not unknown if (lhs_triple_os != llvm::Triple::UnknownOS && @@ -1103,6 +1098,10 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in return true; break; + // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization + // Cortex-M0 - ARMv6-M - armv6m + // Cortex-M3 - ARMv7-M - armv7m + // Cortex-M4 - ARMv7E-M - armv7em case ArchSpec::eCore_arm_armv7em: if (!enforce_exact_match) { @@ -1118,6 +1117,10 @@ cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_in } break; + // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization + // Cortex-M0 - ARMv6-M - armv6m + // Cortex-M3 - ARMv7-M - armv7m + // Cortex-M4 - ARMv7E-M - armv7em case ArchSpec::eCore_arm_armv7m: if (!enforce_exact_match) { @@ -1428,3 +1431,62 @@ ArchSpec::GetStopInfoOverrideCallback () const return StopInfoOverrideCallbackTypeARM; return NULL; } + +bool +ArchSpec::IsFullySpecifiedTriple () const +{ + const auto& user_specified_triple = GetTriple(); + + bool user_triple_fully_specified = false; + + if ((user_specified_triple.getOS() != llvm::Triple::UnknownOS) || TripleOSWasSpecified()) + { + if ((user_specified_triple.getVendor() != llvm::Triple::UnknownVendor) || TripleVendorWasSpecified()) + { + const unsigned unspecified = 0; + if (user_specified_triple.getOSMajorVersion() != unspecified) + { + user_triple_fully_specified = true; + } + } + } + + return user_triple_fully_specified; +} + +void +ArchSpec::PiecewiseTripleCompare (const ArchSpec &other, + bool &arch_different, + bool &vendor_different, + bool &os_different, + bool &os_version_different, + bool &env_different) +{ + const llvm::Triple &me(GetTriple()); + const llvm::Triple &them(other.GetTriple()); + + arch_different = (me.getArch() != them.getArch()); + + vendor_different = (me.getVendor() != them.getVendor()); + + os_different = (me.getOS() != them.getOS()); + + os_version_different = (me.getOSMajorVersion() != them.getOSMajorVersion()); + + env_different = (me.getEnvironment() != them.getEnvironment()); +} + +void +ArchSpec::DumpTriple(Stream &s) const +{ + const llvm::Triple &triple = GetTriple(); + llvm::StringRef arch_str = triple.getArchName(); + llvm::StringRef vendor_str = triple.getVendorName(); + llvm::StringRef os_str = triple.getOSName(); + + s.Printf("%s-%s-%s", + arch_str.empty() ? "*" : arch_str.str().c_str(), + vendor_str.empty() ? "*" : vendor_str.str().c_str(), + os_str.empty() ? "*" : os_str.str().c_str() + ); +} diff --git a/source/Core/ConnectionSharedMemory.cpp b/source/Core/ConnectionSharedMemory.cpp index 77daeb14840d0..e417347579ebf 100644 --- a/source/Core/ConnectionSharedMemory.cpp +++ b/source/Core/ConnectionSharedMemory.cpp @@ -16,10 +16,10 @@ #ifdef _WIN32 #include "lldb/Host/windows/windows.h" #else -#include <sys/file.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> +#include <fcntl.h> #endif // C++ Includes diff --git a/source/Core/ConstString.cpp b/source/Core/ConstString.cpp index 85f8d3c65cd95..c2e95d801723c 100644 --- a/source/Core/ConstString.cpp +++ b/source/Core/ConstString.cpp @@ -8,39 +8,21 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ConstString.h" #include "lldb/Core/Stream.h" -#include "lldb/Host/Mutex.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/RWMutex.h" -#include <mutex> // std::once +#include <array> +#include <mutex> using namespace lldb_private; - class Pool { public: typedef const char * StringPoolValueType; typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator> StringPool; typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType; - - //------------------------------------------------------------------ - // Default constructor - // - // Initialize the member variables and create the empty string. - //------------------------------------------------------------------ - Pool () : - m_mutex (Mutex::eMutexTypeRecursive), - m_string_map () - { - } - - //------------------------------------------------------------------ - // Destructor - //------------------------------------------------------------------ - ~Pool () - { - } - static StringPoolEntryType & GetStringMapEntryFromKeyData (const char *keyData) @@ -54,7 +36,9 @@ public: { if (ccstr) { - const StringPoolEntryType&entry = GetStringMapEntryFromKeyData (ccstr); + const uint8_t h = hash (llvm::StringRef(ccstr)); + llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex); + const StringPoolEntryType& entry = GetStringMapEntryFromKeyData (ccstr); return entry.getKey().size(); } return 0; @@ -64,7 +48,11 @@ public: GetMangledCounterpart (const char *ccstr) const { if (ccstr) + { + const uint8_t h = hash (llvm::StringRef(ccstr)); + llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex); return GetStringMapEntryFromKeyData (ccstr).getValue(); + } return 0; } @@ -73,8 +61,16 @@ public: { if (key_ccstr && value_ccstr) { - GetStringMapEntryFromKeyData (key_ccstr).setValue(value_ccstr); - GetStringMapEntryFromKeyData (value_ccstr).setValue(key_ccstr); + { + const uint8_t h = hash (llvm::StringRef(key_ccstr)); + llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); + GetStringMapEntryFromKeyData (key_ccstr).setValue(value_ccstr); + } + { + const uint8_t h = hash (llvm::StringRef(value_ccstr)); + llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); + GetStringMapEntryFromKeyData (value_ccstr).setValue(key_ccstr); + } return true; } return false; @@ -85,20 +81,15 @@ public: { if (cstr) return GetConstCStringWithLength (cstr, strlen (cstr)); - return NULL; + return nullptr; } const char * GetConstCStringWithLength (const char *cstr, size_t cstr_len) { if (cstr) - { - Mutex::Locker locker (m_mutex); - llvm::StringRef string_ref (cstr, cstr_len); - StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (string_ref, (StringPoolValueType)NULL)).first; - return entry.getKeyData(); - } - return NULL; + return GetConstCStringWithStringRef(llvm::StringRef(cstr, cstr_len)); + return nullptr; } const char * @@ -106,11 +97,20 @@ public: { if (string_ref.data()) { - Mutex::Locker locker (m_mutex); - StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (string_ref, (StringPoolValueType)NULL)).first; + const uint8_t h = hash (string_ref); + + { + llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex); + auto it = m_string_pools[h].m_string_map.find (string_ref); + if (it != m_string_pools[h].m_string_map.end()) + return it->getKeyData(); + } + + llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); + StringPoolEntryType& entry = *m_string_pools[h].m_string_map.insert (std::make_pair (string_ref, nullptr)).first; return entry.getKeyData(); } - return NULL; + return nullptr; } const char * @@ -118,19 +118,33 @@ public: { if (demangled_cstr) { - Mutex::Locker locker (m_mutex); - // Make string pool entry with the mangled counterpart already set - StringPoolEntryType& entry = *m_string_map.insert (std::make_pair (llvm::StringRef (demangled_cstr), mangled_ccstr)).first; - - // Extract the const version of the demangled_cstr - const char *demangled_ccstr = entry.getKeyData(); - // Now assign the demangled const string as the counterpart of the - // mangled const string... - GetStringMapEntryFromKeyData (mangled_ccstr).setValue(demangled_ccstr); + const char *demangled_ccstr = nullptr; + + { + llvm::StringRef string_ref (demangled_cstr); + const uint8_t h = hash (string_ref); + llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); + + // Make string pool entry with the mangled counterpart already set + StringPoolEntryType& entry = *m_string_pools[h].m_string_map.insert ( + std::make_pair (string_ref, mangled_ccstr)).first; + + // Extract the const version of the demangled_cstr + demangled_ccstr = entry.getKeyData(); + } + + { + // Now assign the demangled const string as the counterpart of the + // mangled const string... + const uint8_t h = hash (llvm::StringRef(mangled_ccstr)); + llvm::sys::SmartScopedWriter<false> wlock(m_string_pools[h].m_mutex); + GetStringMapEntryFromKeyData (mangled_ccstr).setValue(demangled_ccstr); + } + // Return the constant demangled C string return demangled_ccstr; } - return NULL; + return nullptr; } const char * @@ -141,7 +155,7 @@ public: const size_t trimmed_len = std::min<size_t> (strlen (cstr), cstr_len); return GetConstCStringWithLength (cstr, trimmed_len); } - return NULL; + return nullptr; } //------------------------------------------------------------------ @@ -152,28 +166,31 @@ public: size_t MemorySize() const { - Mutex::Locker locker (m_mutex); size_t mem_size = sizeof(Pool); - const_iterator end = m_string_map.end(); - for (const_iterator pos = m_string_map.begin(); pos != end; ++pos) + for (const auto& pool : m_string_pools) { - mem_size += sizeof(StringPoolEntryType) + pos->getKey().size(); + llvm::sys::SmartScopedReader<false> rlock(pool.m_mutex); + for (const auto& entry : pool.m_string_map) + mem_size += sizeof(StringPoolEntryType) + entry.getKey().size(); } return mem_size; } protected: - //------------------------------------------------------------------ - // Typedefs - //------------------------------------------------------------------ - typedef StringPool::iterator iterator; - typedef StringPool::const_iterator const_iterator; + uint8_t + hash(const llvm::StringRef &s) const + { + uint32_t h = llvm::HashString(s); + return ((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff; + } - //------------------------------------------------------------------ - // Member variables - //------------------------------------------------------------------ - mutable Mutex m_mutex; - StringPool m_string_map; + struct PoolEntry + { + mutable llvm::sys::SmartRWMutex<false> m_mutex; + StringPool m_string_map; + }; + + std::array<PoolEntry, 256> m_string_pools; }; //---------------------------------------------------------------------- @@ -191,7 +208,7 @@ static Pool & StringPool() { static std::once_flag g_pool_initialization_flag; - static Pool *g_string_pool = NULL; + static Pool *g_string_pool = nullptr; std::call_once(g_pool_initialization_flag, [] () { g_string_pool = new Pool(); @@ -228,8 +245,8 @@ ConstString::operator < (const ConstString& rhs) const if (lhs_string_ref.data() && rhs_string_ref.data()) return lhs_string_ref < rhs_string_ref; - // Else one of them was NULL, so if LHS is NULL then it is less than - return lhs_string_ref.data() == NULL; + // Else one of them was nullptr, so if LHS is nullptr then it is less than + return lhs_string_ref.data() == nullptr; } Stream& diff --git a/source/Core/CxaDemangle.cpp b/source/Core/CxaDemangle.cpp index bcc52ff39fe4e..7d21138c28992 100644 --- a/source/Core/CxaDemangle.cpp +++ b/source/Core/CxaDemangle.cpp @@ -13,6 +13,7 @@ // - Included win32.h for snprintf implementation for MSVC // - Removed constexpr member initialization for MSVC // - Changed argument to alignas() to a literal for MSVC +// - Include <cstdio> for fprintf, stderr like entities. //---------------------------------------------------------------------- #if defined(_MSC_VER) @@ -40,6 +41,7 @@ #include <cstdlib> #include <cstring> #include <cctype> +#include <cstdio> namespace lldb_private { diff --git a/source/Core/DataEncoder.cpp b/source/Core/DataEncoder.cpp index d21ca423892f7..040d09647562e 100644 --- a/source/Core/DataEncoder.cpp +++ b/source/Core/DataEncoder.cpp @@ -61,7 +61,7 @@ WriteSwappedInt64(unsigned char* ptr, unsigned offset, uint64_t value) DataEncoder::DataEncoder () : m_start (NULL), m_end (NULL), - m_byte_order(lldb::endian::InlHostByteOrder()), + m_byte_order(endian::InlHostByteOrder()), m_addr_size (sizeof(void*)), m_data_sp () { @@ -114,7 +114,7 @@ DataEncoder::Clear () { m_start = NULL; m_end = NULL; - m_byte_order = lldb::endian::InlHostByteOrder(); + m_byte_order = endian::InlHostByteOrder(); m_addr_size = sizeof(void*); m_data_sp.reset(); } @@ -240,7 +240,7 @@ DataEncoder::PutU16 (uint32_t offset, uint16_t value) { if (ValidOffsetForDataOfSize(offset, sizeof(value))) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) WriteSwappedInt16 (m_start, offset, value); else WriteInt16 (m_start, offset, value); @@ -255,7 +255,7 @@ DataEncoder::PutU32 (uint32_t offset, uint32_t value) { if (ValidOffsetForDataOfSize(offset, sizeof(value))) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) WriteSwappedInt32 (m_start, offset, value); else WriteInt32 (m_start, offset, value); @@ -270,7 +270,7 @@ DataEncoder::PutU64 (uint32_t offset, uint64_t value) { if (ValidOffsetForDataOfSize(offset, sizeof(value))) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) WriteSwappedInt64 (m_start, offset, value); else WriteInt64 (m_start, offset, value); diff --git a/source/Core/DataExtractor.cpp b/source/Core/DataExtractor.cpp index 861bece98da96..dc7857fe9cb77 100644 --- a/source/Core/DataExtractor.cpp +++ b/source/Core/DataExtractor.cpp @@ -14,6 +14,7 @@ #include <limits> #include <sstream> #include <string> +#include <math.h> #include "clang/AST/ASTContext.h" @@ -130,8 +131,8 @@ ReadSwapInt64(const void* ptr) DataExtractor::DataExtractor () : m_start (NULL), m_end (NULL), - m_byte_order(lldb::endian::InlHostByteOrder()), - m_addr_size (4), + m_byte_order(endian::InlHostByteOrder()), + m_addr_size (sizeof(void *)), m_data_sp (), m_target_byte_size(1) { @@ -142,13 +143,16 @@ DataExtractor::DataExtractor () : // The data must stay around as long as this object is valid. //---------------------------------------------------------------------- DataExtractor::DataExtractor (const void* data, offset_t length, ByteOrder endian, uint32_t addr_size, uint32_t target_byte_size/*=1*/) : - m_start ((uint8_t*)data), - m_end ((uint8_t*)data + length), + m_start (const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data))), + m_end (const_cast<uint8_t *>(reinterpret_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) { +#ifdef LLDB_CONFIGURATION_DEBUG + assert (addr_size == 4 || addr_size == 8); +#endif } //---------------------------------------------------------------------- @@ -166,6 +170,9 @@ DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uin m_data_sp (), m_target_byte_size(target_byte_size) { +#ifdef LLDB_CONFIGURATION_DEBUG + assert (addr_size == 4 || addr_size == 8); +#endif SetData (data_sp); } @@ -184,6 +191,9 @@ DataExtractor::DataExtractor (const DataExtractor& data, offset_t offset, offset m_data_sp(), m_target_byte_size(target_byte_size) { +#ifdef LLDB_CONFIGURATION_DEBUG + assert (m_addr_size == 4 || m_addr_size == 8); +#endif if (data.ValidOffset(offset)) { offset_t bytes_available = data.GetByteSize() - offset; @@ -201,6 +211,9 @@ DataExtractor::DataExtractor (const DataExtractor& rhs) : m_data_sp (rhs.m_data_sp), m_target_byte_size(rhs.m_target_byte_size) { +#ifdef LLDB_CONFIGURATION_DEBUG + assert (m_addr_size == 4 || m_addr_size == 8); +#endif } //---------------------------------------------------------------------- @@ -237,8 +250,8 @@ DataExtractor::Clear () { m_start = NULL; m_end = NULL; - m_byte_order = lldb::endian::InlHostByteOrder(); - m_addr_size = 4; + m_byte_order = endian::InlHostByteOrder(); + m_addr_size = sizeof(void *); m_data_sp.reset(); } @@ -287,7 +300,7 @@ DataExtractor::SetData (const void *bytes, offset_t length, ByteOrder endian) } else { - m_start = (uint8_t *)bytes; + m_start = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(bytes)); m_end = m_start + length; } return GetByteSize(); @@ -311,6 +324,9 @@ lldb::offset_t DataExtractor::SetData (const DataExtractor& data, offset_t data_offset, offset_t data_length) { m_addr_size = data.m_addr_size; +#ifdef LLDB_CONFIGURATION_DEBUG + assert (m_addr_size == 4 || m_addr_size == 8); +#endif // If "data" contains shared pointer to data, then we can use that if (data.m_data_sp.get()) { @@ -427,7 +443,7 @@ DataExtractor::GetU16 (offset_t *offset_ptr) const const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val)); if (data) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) val = ReadSwapInt16(data); else val = ReadInt16 (data); @@ -439,7 +455,7 @@ uint16_t DataExtractor::GetU16_unchecked (offset_t *offset_ptr) const { uint16_t val; - if (m_byte_order == lldb::endian::InlHostByteOrder()) + if (m_byte_order == endian::InlHostByteOrder()) val = ReadInt16 (m_start, *offset_ptr); else val = ReadSwapInt16(m_start, *offset_ptr); @@ -451,7 +467,7 @@ uint32_t DataExtractor::GetU32_unchecked (offset_t *offset_ptr) const { uint32_t val; - if (m_byte_order == lldb::endian::InlHostByteOrder()) + if (m_byte_order == endian::InlHostByteOrder()) val = ReadInt32 (m_start, *offset_ptr); else val = ReadSwapInt32 (m_start, *offset_ptr); @@ -463,7 +479,7 @@ uint64_t DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const { uint64_t val; - if (m_byte_order == lldb::endian::InlHostByteOrder()) + if (m_byte_order == endian::InlHostByteOrder()) val = ReadInt64 (m_start, *offset_ptr); else val = ReadSwapInt64 (m_start, *offset_ptr); @@ -488,7 +504,7 @@ DataExtractor::GetU16 (offset_t *offset_ptr, void *void_dst, uint32_t count) con const uint16_t *src = (const uint16_t *)GetData (offset_ptr, src_size); if (src) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) { uint16_t *dst_pos = (uint16_t *)void_dst; uint16_t *dst_end = dst_pos + count; @@ -523,7 +539,7 @@ DataExtractor::GetU32 (offset_t *offset_ptr) const const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val)); if (data) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) { val = ReadSwapInt32 (data); } @@ -551,7 +567,7 @@ DataExtractor::GetU32 (offset_t *offset_ptr, void *void_dst, uint32_t count) con const uint32_t *src = (const uint32_t *)GetData (offset_ptr, src_size); if (src) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) { uint32_t *dst_pos = (uint32_t *)void_dst; uint32_t *dst_end = dst_pos + count; @@ -586,7 +602,7 @@ DataExtractor::GetU64 (offset_t *offset_ptr) const const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val)); if (data) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) { val = ReadSwapInt64 (data); } @@ -612,7 +628,7 @@ DataExtractor::GetU64 (offset_t *offset_ptr, void *void_dst, uint32_t count) con const uint64_t *src = (const uint64_t *)GetData (offset_ptr, src_size); if (src) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) { uint64_t *dst_pos = (uint64_t *)void_dst; uint64_t *dst_end = dst_pos + count; @@ -653,7 +669,7 @@ DataExtractor::GetMaxU32 (offset_t *offset_ptr, size_t byte_size) const case 2: return GetU16(offset_ptr); break; case 4: return GetU32(offset_ptr); break; default: - assert("GetMaxU32 unhandled case!" == NULL); + assert(false && "GetMaxU32 unhandled case!"); break; } return 0; @@ -679,7 +695,7 @@ DataExtractor::GetMaxU64 (offset_t *offset_ptr, size_t size) const case 4: return GetU32(offset_ptr); break; case 8: return GetU64(offset_ptr); break; default: - assert("GetMax64 unhandled case!" == NULL); + assert(false && "GetMax64 unhandled case!"); break; } return 0; @@ -695,7 +711,7 @@ DataExtractor::GetMaxU64_unchecked (offset_t *offset_ptr, size_t size) const case 4: return GetU32_unchecked (offset_ptr); break; case 8: return GetU64_unchecked (offset_ptr); break; default: - assert("GetMax64 unhandled case!" == NULL); + assert(false && "GetMax64 unhandled case!"); break; } return 0; @@ -711,7 +727,7 @@ DataExtractor::GetMaxS64 (offset_t *offset_ptr, size_t size) const case 4: return (int32_t)GetU32(offset_ptr); break; case 8: return (int64_t)GetU64(offset_ptr); break; default: - assert("GetMax64 unhandled case!" == NULL); + assert(false && "GetMax64 unhandled case!"); break; } return 0; @@ -760,7 +776,7 @@ DataExtractor::GetFloat (offset_t *offset_ptr) const const float_type *src = (const float_type *)GetData (offset_ptr, src_size); if (src) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) { const uint8_t *src_data = (const uint8_t *)src; uint8_t *dst_data = (uint8_t *)&val; @@ -784,7 +800,7 @@ DataExtractor::GetDouble (offset_t *offset_ptr) const const float_type *src = (const float_type *)GetData (offset_ptr, src_size); if (src) { - if (m_byte_order != lldb::endian::InlHostByteOrder()) + if (m_byte_order != endian::InlHostByteOrder()) { const uint8_t *src_data = (const uint8_t *)src; uint8_t *dst_data = (uint8_t *)&val; @@ -805,9 +821,9 @@ DataExtractor::GetLongDouble (offset_t *offset_ptr) const { long double val = 0.0; #if defined (__i386__) || defined (__amd64__) || defined (__x86_64__) || defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64) - *offset_ptr += CopyByteOrderedData (*offset_ptr, 10, &val, sizeof(val), lldb::endian::InlHostByteOrder()); + *offset_ptr += CopyByteOrderedData (*offset_ptr, 10, &val, sizeof(val), endian::InlHostByteOrder()); #else - *offset_ptr += CopyByteOrderedData (*offset_ptr, sizeof(val), &val, sizeof(val), lldb::endian::InlHostByteOrder()); + *offset_ptr += CopyByteOrderedData (*offset_ptr, sizeof(val), &val, sizeof(val), endian::InlHostByteOrder()); #endif return val; } @@ -824,12 +840,18 @@ DataExtractor::GetLongDouble (offset_t *offset_ptr) const uint64_t DataExtractor::GetAddress (offset_t *offset_ptr) const { +#ifdef LLDB_CONFIGURATION_DEBUG + assert (m_addr_size == 4 || m_addr_size == 8); +#endif return GetMaxU64 (offset_ptr, m_addr_size); } uint64_t DataExtractor::GetAddress_unchecked (offset_t *offset_ptr) const { +#ifdef LLDB_CONFIGURATION_DEBUG + assert (m_addr_size == 4 || m_addr_size == 8); +#endif return GetMaxU64_unchecked (offset_ptr, m_addr_size); } @@ -844,6 +866,9 @@ DataExtractor::GetAddress_unchecked (offset_t *offset_ptr) const uint64_t DataExtractor::GetPointer (offset_t *offset_ptr) const { +#ifdef LLDB_CONFIGURATION_DEBUG + assert (m_addr_size == 4 || m_addr_size == 8); +#endif return GetMaxU64 (offset_ptr, m_addr_size); } @@ -863,6 +888,9 @@ DataExtractor::GetGNUEHPointer (offset_t *offset_ptr, uint32_t eh_ptr_enc, lldb: uint64_t baseAddress = 0; uint64_t addressValue = 0; const uint32_t addr_size = GetAddressByteSize(); +#ifdef LLDB_CONFIGURATION_DEBUG + assert (addr_size == 4 || addr_size == 8); +#endif bool signExtendValue = false; // Decode the base part or adjust our offset @@ -1378,24 +1406,21 @@ DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::of return offset; } -static float half2float (uint16_t half) +static float +half2float (uint16_t half) { -#ifdef _MSC_VER - llvm_unreachable("half2float not implemented for MSVC"); -#else - union{ float f; uint32_t u;}u; + union { float f; uint32_t u; } u; int32_t v = (int16_t) half; - - if( 0 == (v & 0x7c00)) + + if (0 == (v & 0x7c00)) { u.u = v & 0x80007FFFU; return u.f * ldexpf(1, 125); } - + v <<= 13; u.u = v | 0x70000000U; return u.f * ldexpf(1, -112); -#endif } lldb::offset_t @@ -2012,6 +2037,12 @@ DataExtractor::Dump (Stream *s, s->PutChar('}'); break; + case eFormatVectorOfFloat16: + s->PutChar('{'); + offset = Dump (s, offset, eFormatFloat, 2, item_byte_size / 2, item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0); + s->PutChar('}'); + break; + case eFormatVectorOfFloat32: s->PutChar('{'); offset = Dump (s, offset, eFormatFloat, 4, item_byte_size / 4, item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0); diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp index cd41e5d651036..d36800e20bc0f 100644 --- a/source/Core/Debugger.cpp +++ b/source/Core/Debugger.cpp @@ -11,13 +11,12 @@ #include <map> -#include "clang/AST/DeclCXX.h" -#include "clang/AST/Type.h" #include "llvm/ADT/StringRef.h" #include "lldb/lldb-private.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Module.h" +#include "lldb/Core/PluginInterface.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegisterValue.h" #include "lldb/Core/State.h" @@ -32,6 +31,7 @@ #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/DataFormatters/TypeSummary.h" +#include "lldb/Expression/REPL.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/Terminal.h" @@ -40,14 +40,12 @@ #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/OptionValueSInt64.h" #include "lldb/Interpreter/OptionValueString.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/VariableList.h" -#include "lldb/Target/CPPLanguageRuntime.h" -#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/TargetList.h" +#include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/SectionLoadList.h" @@ -88,9 +86,10 @@ GetDebuggerList() OptionEnumValueElement g_show_disassembly_enum_values[] = { - { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, - { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, - { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, + { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, + { Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", "Show disassembly when there is no debug information."}, + { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."}, + { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."}, { 0, NULL, NULL } }; @@ -105,6 +104,7 @@ g_language_enumerators[] = #define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}" #define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" +#define IS_OPTIMIZED "{${function.is-optimized} [opt]}" #define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\ "{, ${frame.pc}}"\ @@ -122,6 +122,7 @@ g_language_enumerators[] = #define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\ MODULE_WITH_FUNC\ FILE_AND_LINE\ + IS_OPTIMIZED\ "\\n" // Three parts to this disassembly format specification: @@ -150,7 +151,7 @@ g_properties[] = { "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", NULL, "The debugger command line prompt displayed for the user." }, { "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, NULL, g_language_enumerators, "The script language to be used for evaluating user-written scripts." }, { "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , NULL, NULL, "The number of disassembly lines to show when displaying a stopped context." }, -{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoSource, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." }, +{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoDebugInfo, NULL, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." }, { "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come after the current source line when displaying a stopped context." }, { "stop-line-count-before", OptionValue::eTypeSInt64 , true, 3 , NULL, NULL, "The number of sources lines to display that come before the current source line when displaying a stopped context." }, { "term-width", OptionValue::eTypeSInt64 , true, 80 , NULL, NULL, "The maximum number of columns to use for displaying text." }, @@ -158,6 +159,9 @@ g_properties[] = { "use-external-editor", OptionValue::eTypeBoolean , true, false, NULL, NULL, "Whether to use an external editor or not." }, { "use-color", OptionValue::eTypeBoolean , true, true , NULL, NULL, "Whether to use Ansi color codes or not." }, { "auto-one-line-summaries", OptionValue::eTypeBoolean , true, true, NULL, NULL, "If true, LLDB will automatically display small structs in one-liner format (default: true)." }, +{ "auto-indent", OptionValue::eTypeBoolean , true, true , NULL, NULL, "If true, LLDB will auto indent/outdent code. Currently only supported in the REPL (default: true)." }, +{ "print-decls", OptionValue::eTypeBoolean , true, true , NULL, NULL, "If true, LLDB will print the values of variables declared in an expression. Currently only supported in the REPL (default: true)." }, +{ "tab-size", OptionValue::eTypeUInt64 , true, 4 , NULL, NULL, "The tab size to use when indenting code in multi-line input mode (default: 4)." }, { "escape-non-printables", OptionValue::eTypeBoolean , true, true, NULL, NULL, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." }, { NULL, OptionValue::eTypeInvalid , true, 0 , NULL, NULL, NULL } }; @@ -179,6 +183,9 @@ enum ePropertyUseExternalEditor, ePropertyUseColor, ePropertyAutoOneLineSummaries, + ePropertyAutoIndent, + ePropertyPrintDecls, + ePropertyTabSize, ePropertyEscapeNonPrintables }; @@ -394,6 +401,49 @@ Debugger::GetEscapeNonPrintables () const return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); } +bool +Debugger::GetAutoIndent () const +{ + const uint32_t idx = ePropertyAutoIndent; + return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); +} + +bool +Debugger::SetAutoIndent (bool b) +{ + const uint32_t idx = ePropertyAutoIndent; + return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); +} + +bool +Debugger::GetPrintDecls () const +{ + const uint32_t idx = ePropertyPrintDecls; + return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, true); +} + +bool +Debugger::SetPrintDecls (bool b) +{ + const uint32_t idx = ePropertyPrintDecls; + return m_collection_sp->SetPropertyAtIndexAsBoolean (NULL, idx, b); +} + +uint32_t +Debugger::GetTabSize () const +{ + const uint32_t idx = ePropertyTabSize; + return m_collection_sp->GetPropertyAtIndexAsUInt64 (NULL, idx, g_properties[idx].default_uint_value); +} + +bool +Debugger::SetTabSize (uint32_t tab_size) +{ + const uint32_t idx = ePropertyTabSize; + return m_collection_sp->SetPropertyAtIndexAsUInt64 (NULL, idx, tab_size); +} + + #pragma mark Debugger //const DebuggerPropertiesSP & @@ -420,7 +470,11 @@ Debugger::Terminate () // Clear our master list of debugger objects Mutex::Locker locker (GetDebuggerListMutex ()); - GetDebuggerList().clear(); + auto& debuggers = GetDebuggerList(); + for (const auto& debugger: debuggers) + debugger->Clear(); + + debuggers.clear(); } void @@ -917,6 +971,12 @@ Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp) return m_input_reader_stack.IsTop (reader_sp); } +bool +Debugger::CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type) +{ + return m_input_reader_stack.CheckTopIOHandlerTypes (top_type, second_top_type); +} + void Debugger::PrintAsync (const char *s, size_t len, bool is_stdout) { @@ -1682,6 +1742,12 @@ Debugger::IOHandlerThread (lldb::thread_arg_t arg) } bool +Debugger::HasIOHandlerThread() +{ + return m_io_handler_thread.IsJoinable(); +} + +bool Debugger::StartIOHandlerThread() { if (!m_io_handler_thread.IsJoinable()) @@ -1704,6 +1770,17 @@ Debugger::StopIOHandlerThread() } } +void +Debugger::JoinIOHandlerThread() +{ + if (HasIOHandlerThread()) + { + thread_result_t result; + m_io_handler_thread.Join(&result); + m_io_handler_thread = LLDB_INVALID_HOST_THREAD; + } +} + Target * Debugger::GetDummyTarget() { @@ -1724,3 +1801,52 @@ Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) return GetDummyTarget(); } +Error +Debugger::RunREPL (LanguageType language, const char *repl_options) +{ + Error err; + FileSpec repl_executable; + + if (language == eLanguageTypeUnknown) + { + std::set<LanguageType> repl_languages; + + Language::GetLanguagesSupportingREPLs(repl_languages); + + if (repl_languages.size() == 1) + { + language = *repl_languages.begin(); + } + else if (repl_languages.size() == 0) + { + err.SetErrorStringWithFormat("LLDB isn't configured with support support for any REPLs."); + return err; + } + else + { + err.SetErrorStringWithFormat("Multiple possible REPL languages. Please specify a language."); + return err; + } + } + + Target *const target = nullptr; // passing in an empty target means the REPL must create one + + REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options)); + + if (!err.Success()) + { + return err; + } + + if (!repl_sp) + { + err.SetErrorStringWithFormat("couldn't find a REPL for %s", Language::GetNameForLanguageType(language)); + return err; + } + + repl_sp->SetCompilerOptions(repl_options); + repl_sp->RunLoop(); + + return err; +} + diff --git a/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp index f96232fcceebd..bb5f106ca611c 100644 --- a/source/Core/Disassembler.cpp +++ b/source/Core/Disassembler.cpp @@ -28,7 +28,6 @@ #include "lldb/Interpreter/OptionValueDictionary.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/OptionValueUInt64.h" -#include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/ExecutionContext.h" @@ -675,6 +674,13 @@ Instruction::DumpEmulation (const ArchSpec &arch) return false; } +bool +Instruction::HasDelaySlot () +{ + // Default is false. + return false; +} + OptionValueSP Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type) { @@ -1264,7 +1270,7 @@ Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) : // If this is an arm variant that can only include thumb (T16, T32) // instructions, force the arch triple to be "thumbv.." instead of // "armv..." - if (arch.GetTriple().getArch() == llvm::Triple::arm + if ((arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb) && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m)) @@ -1319,6 +1325,13 @@ PseudoInstruction::DoesBranch () return false; } +bool +PseudoInstruction::HasDelaySlot () +{ + // This is NOT a valid question for a pseudo instruction. + return false; +} + size_t PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler, const lldb_private::DataExtractor &data, diff --git a/source/Core/DynamicLoader.cpp b/source/Core/DynamicLoader.cpp index ffd7425f5231d..4d2824c5f3342 100644 --- a/source/Core/DynamicLoader.cpp +++ b/source/Core/DynamicLoader.cpp @@ -119,16 +119,20 @@ DynamicLoader::GetTargetExecutable() } void -DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr, addr_t base_addr) +DynamicLoader::UpdateLoadedSections(ModuleSP module, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { - UpdateLoadedSectionsCommon(module, base_addr); + UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset); } void -DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, addr_t base_addr) +DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module, + addr_t base_addr, + bool base_addr_is_offset) { bool changed; - const bool base_addr_is_offset = true; module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed); } @@ -171,7 +175,10 @@ DynamicLoader::GetSectionListFromModule(const ModuleSP module) const } ModuleSP -DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, addr_t base_addr) +DynamicLoader::LoadModuleAtAddress(const FileSpec &file, + addr_t link_map_addr, + addr_t base_addr, + bool base_addr_is_offset) { Target &target = m_process->GetTarget(); ModuleList &modules = target.GetImages(); @@ -180,27 +187,28 @@ DynamicLoader::LoadModuleAtAddress(const FileSpec &file, addr_t link_map_addr, a ModuleSpec module_spec (file, target.GetArchitecture()); if ((module_sp = modules.FindFirstModule (module_spec))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); } else if ((module_sp = target.GetSharedModule(module_spec))) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr); + UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset); } else { - // Try to fetch the load address of the file from the process. It can be different from the - // address reported by the linker in case of a file with fixed load address because the - // linker reports the bias between the load address specified in the file and the actual - // load address it loaded the file. - bool is_loaded; - lldb::addr_t load_addr; - Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); - if (error.Fail() || !is_loaded) - load_addr = base_addr; - - if ((module_sp = m_process->ReadModuleFromMemory(file, load_addr))) + if (base_addr_is_offset) { - UpdateLoadedSections(module_sp, link_map_addr, base_addr); + // Try to fetch the load address of the file from the process as we need absolute load + // address to read the file out of the memory instead of a load bias. + bool is_loaded; + lldb::addr_t load_addr; + Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr); + if (error.Success() && is_loaded) + base_addr = load_addr; + } + + if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) + { + UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); target.GetImages().AppendIfNeeded(module_sp); } } diff --git a/source/Core/EmulateInstruction.cpp b/source/Core/EmulateInstruction.cpp index 8349f54de4c7c..9b6beeb8299a0 100644 --- a/source/Core/EmulateInstruction.cpp +++ b/source/Core/EmulateInstruction.cpp @@ -635,17 +635,17 @@ EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info, return true; } - reg_num = reg_info->kinds[eRegisterKindGCC]; + reg_num = reg_info->kinds[eRegisterKindEHFrame]; if (reg_num != LLDB_INVALID_REGNUM) { - reg_kind = eRegisterKindGCC; + reg_kind = eRegisterKindEHFrame; return true; } - reg_num = reg_info->kinds[eRegisterKindGDB]; + reg_num = reg_info->kinds[eRegisterKindProcessPlugin]; if (reg_num != LLDB_INVALID_REGNUM) { - reg_kind = eRegisterKindGDB; + reg_kind = eRegisterKindProcessPlugin; return true; } return false; diff --git a/source/Core/Event.cpp b/source/Core/Event.cpp index bf5ff222a122f..293a322257ef9 100644 --- a/source/Core/Event.cpp +++ b/source/Core/Event.cpp @@ -147,7 +147,7 @@ EventDataBytes::Dump (Stream *s) const else if (m_bytes.size() > 0) { DataExtractor data; - data.SetData(&m_bytes[0], m_bytes.size(), lldb::endian::InlHostByteOrder()); + data.SetData(&m_bytes[0], m_bytes.size(), endian::InlHostByteOrder()); data.Dump(s, 0, eFormatBytes, 1, m_bytes.size(), 32, LLDB_INVALID_ADDRESS, 0, 0); } } diff --git a/source/Core/FastDemangle.cpp b/source/Core/FastDemangle.cpp index 0f12af2783db6..a27a2f1dbff13 100644 --- a/source/Core/FastDemangle.cpp +++ b/source/Core/FastDemangle.cpp @@ -161,7 +161,7 @@ public: /// the Itanium C++ ABI mangling specification as implemented by Clang /// /// @result Newly allocated null-terminated demangled name when demangling - /// is succesful, and nullptr when demangling fails. The caller is + /// is successful, and nullptr when demangling fails. The caller is /// responsible for freeing the allocated memory. char * diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp index e89d6c9cb4a9d..804682f64bd31 100644 --- a/source/Core/FormatEntity.cpp +++ b/source/Core/FormatEntity.cpp @@ -7,13 +7,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/StringRef.h" - #include "lldb/Core/FormatEntity.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" + #include "lldb/Core/Address.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Language.h" #include "lldb/Core/Module.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamString.h" @@ -21,7 +21,8 @@ #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/DataFormatters/FormatManager.h" -#include "lldb/Expression/ClangExpressionVariable.h" +#include "lldb/DataFormatters/ValueObjectPrinter.h" +#include "lldb/Expression/ExpressionVariable.h" #include "lldb/Host/FileSpec.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/Block.h" @@ -31,6 +32,7 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/SectionLoadList.h" @@ -98,7 +100,8 @@ static FormatEntity::Entry::Definition g_function_child_entries[] = ENTRY ("line-offset" , FunctionLineOffset , UInt64), ENTRY ("pc-offset" , FunctionPCOffset , UInt64), ENTRY ("initial-function" , FunctionInitial , None), - ENTRY ("changed" , FunctionChanged , None) + ENTRY ("changed" , FunctionChanged , None), + ENTRY ("is-optimized" , FunctionIsOptimized , None) }; static FormatEntity::Entry::Definition g_line_child_entries[] = @@ -343,6 +346,7 @@ FormatEntity::Entry::TypeToCString (Type t) ENUM_TO_CSTR(FunctionPCOffset); ENUM_TO_CSTR(FunctionInitial); ENUM_TO_CSTR(FunctionChanged); + ENUM_TO_CSTR(FunctionIsOptimized); ENUM_TO_CSTR(LineEntryFile); ENUM_TO_CSTR(LineEntryLineNumber); ENUM_TO_CSTR(LineEntryStartAddress); @@ -530,7 +534,7 @@ ScanBracketedRange (llvm::StringRef subpath, int64_t& index_lower, int64_t& index_higher) { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS)); close_bracket_index = llvm::StringRef::npos; const size_t open_bracket_index = subpath.find('['); if (open_bracket_index == llvm::StringRef::npos) @@ -667,7 +671,7 @@ ExpandIndexedExpression (ValueObject* valobj, StackFrame* frame, bool deref_pointer) { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS)); const char* ptr_deref_format = "[%d]"; std::string ptr_deref_buffer(10,0); ::sprintf(&ptr_deref_buffer[0], ptr_deref_format, index); @@ -728,7 +732,7 @@ DumpValue (Stream &s, if (valobj == NULL) return false; - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS)); Format custom_format = eFormatInvalid; ValueObject::ValueObjectRepresentationStyle val_obj_display = entry.string.empty() ? ValueObject::eValueObjectRepresentationStyleValue : ValueObject::eValueObjectRepresentationStyleSummary; @@ -883,10 +887,10 @@ DumpValue (Stream &s, } // TODO use flags for these - const uint32_t type_info_flags = target->GetClangType().GetTypeInfo(NULL); + const uint32_t type_info_flags = target->GetCompilerType().GetTypeInfo(NULL); bool is_array = (type_info_flags & eTypeIsArray) != 0; bool is_pointer = (type_info_flags & eTypeIsPointer) != 0; - bool is_aggregate = target->GetClangType().IsAggregateType(); + bool is_aggregate = target->GetCompilerType().IsAggregateType(); if ((is_array || is_pointer) && (!is_array_range) && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) // this should be wrong, but there are some exceptions { @@ -1302,6 +1306,8 @@ FormatEntity::Format (const Entry &entry, // Watch for the special "tid" format... if (entry.printf_format == "tid") { + // TODO(zturner): Rather than hardcoding this to be platform specific, it should be controlled by a + // setting and the default value of the setting can be different depending on the platform. Target &target = thread->GetProcess()->GetTarget(); ArchSpec arch (target.GetArchitecture ()); llvm::Triple::OSType ostype = arch.IsValid() ? arch.GetTriple().getOS() : llvm::Triple::UnknownOS; @@ -1432,7 +1438,7 @@ FormatEntity::Format (const Entry &entry, StopInfoSP stop_info_sp = thread->GetStopInfo (); if (stop_info_sp && stop_info_sp->IsValid()) { - ClangExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp); + ExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp); if (expression_var_sp && expression_var_sp->GetValueObject()) { expression_var_sp->GetValueObject()->Dump(s); @@ -1524,8 +1530,7 @@ FormatEntity::Format (const Entry &entry, CompileUnit *cu = sc->comp_unit; if (cu) { - Language lang(cu->GetLanguage()); - const char *lang_name = lang.AsCString(); + const char *lang_name = Language::GetNameForLanguageType(cu->GetLanguage()); if (lang_name) { s.PutCString(lang_name); @@ -1648,187 +1653,267 @@ FormatEntity::Format (const Entry &entry, case Entry::Type::FunctionName: { - const char *name = NULL; + Language *language_plugin = nullptr; + bool language_plugin_handled = false; + StreamString ss; if (sc->function) - name = sc->function->GetName().AsCString (NULL); + language_plugin = Language::FindPlugin(sc->function->GetLanguage()); else if (sc->symbol) - name = sc->symbol->GetName().AsCString (NULL); - if (name) + language_plugin = Language::FindPlugin(sc->symbol->GetLanguage()); + if (language_plugin) { - s.PutCString(name); - - if (sc->block) + language_plugin_handled = language_plugin->GetFunctionDisplayName(sc, + exe_ctx, + Language::FunctionNameRepresentation::eName, + ss); + } + if (language_plugin_handled) + { + s.PutCString(ss.GetData()); + return true; + } + else + { + const char *name = NULL; + if (sc->function) + name = sc->function->GetName().AsCString (NULL); + else if (sc->symbol) + name = sc->symbol->GetName().AsCString (NULL); + if (name) { - Block *inline_block = sc->block->GetContainingInlinedBlock (); - if (inline_block) + s.PutCString(name); + + if (sc->block) { - const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); - if (inline_info) + Block *inline_block = sc->block->GetContainingInlinedBlock (); + if (inline_block) { - s.PutCString(" [inlined] "); - inline_info->GetName(sc->function->GetLanguage()).Dump(&s); + const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); + if (inline_info) + { + s.PutCString(" [inlined] "); + inline_info->GetName(sc->function->GetLanguage()).Dump(&s); + } } } + return true; } - return true; } } return false; case Entry::Type::FunctionNameNoArgs: { - ConstString name; + Language *language_plugin = nullptr; + bool language_plugin_handled = false; + StreamString ss; if (sc->function) - name = sc->function->GetNameNoArguments(); + language_plugin = Language::FindPlugin(sc->function->GetLanguage()); else if (sc->symbol) - name = sc->symbol->GetNameNoArguments(); - if (name) + language_plugin = Language::FindPlugin(sc->symbol->GetLanguage()); + if (language_plugin) + { + language_plugin_handled = language_plugin->GetFunctionDisplayName(sc, + exe_ctx, + Language::FunctionNameRepresentation::eNameWithNoArgs, + ss); + } + if (language_plugin_handled) { - s.PutCString(name.GetCString()); + s.PutCString(ss.GetData()); return true; } + else + { + ConstString name; + if (sc->function) + name = sc->function->GetNameNoArguments(); + else if (sc->symbol) + name = sc->symbol->GetNameNoArguments(); + if (name) + { + s.PutCString(name.GetCString()); + return true; + } + } } return false; case Entry::Type::FunctionNameWithArgs: { - // Print the function name with arguments in it + Language *language_plugin = nullptr; + bool language_plugin_handled = false; + StreamString ss; if (sc->function) + language_plugin = Language::FindPlugin(sc->function->GetLanguage()); + else if (sc->symbol) + language_plugin = Language::FindPlugin(sc->symbol->GetLanguage()); + if (language_plugin) { - ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; - const char *cstr = sc->function->GetName().AsCString (NULL); - if (cstr) + language_plugin_handled = language_plugin->GetFunctionDisplayName(sc, + exe_ctx, + Language::FunctionNameRepresentation::eNameWithArgs, + ss); + } + if (language_plugin_handled) + { + s.PutCString(ss.GetData()); + return true; + } + else + { + // Print the function name with arguments in it + if (sc->function) { - const InlineFunctionInfo *inline_info = NULL; - VariableListSP variable_list_sp; - bool get_function_vars = true; - if (sc->block) - { - Block *inline_block = sc->block->GetContainingInlinedBlock (); - - if (inline_block) - { - get_function_vars = false; - inline_info = sc->block->GetInlinedFunctionInfo(); - if (inline_info) - variable_list_sp = inline_block->GetBlockVariableList (true); - } - } - - if (get_function_vars) - { - variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); - } - - if (inline_info) - { - s.PutCString (cstr); - s.PutCString (" [inlined] "); - cstr = inline_info->GetName(sc->function->GetLanguage()).GetCString(); - } - - VariableList args; - if (variable_list_sp) - variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); - if (args.GetSize() > 0) + ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; + const char *cstr = sc->function->GetName().AsCString (NULL); + if (cstr) { - const char *open_paren = strchr (cstr, '('); - const char *close_paren = nullptr; - const char *generic = strchr(cstr, '<'); - // if before the arguments list begins there is a template sign - // then scan to the end of the generic args before you try to find - // the arguments list - if (generic && open_paren && generic < open_paren) + const InlineFunctionInfo *inline_info = NULL; + VariableListSP variable_list_sp; + bool get_function_vars = true; + if (sc->block) { - int generic_depth = 1; - ++generic; - for (; - *generic && generic_depth > 0; - generic++) + Block *inline_block = sc->block->GetContainingInlinedBlock (); + + if (inline_block) { - if (*generic == '<') - generic_depth++; - if (*generic == '>') - generic_depth--; + get_function_vars = false; + inline_info = sc->block->GetInlinedFunctionInfo(); + if (inline_info) + variable_list_sp = inline_block->GetBlockVariableList (true); } - if (*generic) - open_paren = strchr(generic, '('); - else - open_paren = nullptr; } - if (open_paren) + + if (get_function_vars) { - if (IsToken (open_paren, "(anonymous namespace)")) - { - open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); - if (open_paren) - close_paren = strchr (open_paren, ')'); - } - else - close_paren = strchr (open_paren, ')'); + variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true); } - - if (open_paren) - s.Write(cstr, open_paren - cstr + 1); - else + + if (inline_info) { s.PutCString (cstr); - s.PutChar ('('); + s.PutCString (" [inlined] "); + cstr = inline_info->GetName(sc->function->GetLanguage()).GetCString(); } - const size_t num_args = args.GetSize(); - for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) + + VariableList args; + if (variable_list_sp) + variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args); + if (args.GetSize() > 0) { - std::string buffer; - - VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); - ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); - const char *var_representation = nullptr; - const char *var_name = var_value_sp->GetName().GetCString(); - if (var_value_sp->GetClangType().IsAggregateType() && - DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get())) + const char *open_paren = strchr (cstr, '('); + const char *close_paren = nullptr; + const char *generic = strchr(cstr, '<'); + // if before the arguments list begins there is a template sign + // then scan to the end of the generic args before you try to find + // the arguments list + if (generic && open_paren && generic < open_paren) + { + int generic_depth = 1; + ++generic; + for (; + *generic && generic_depth > 0; + generic++) + { + if (*generic == '<') + generic_depth++; + if (*generic == '>') + generic_depth--; + } + if (*generic) + open_paren = strchr(generic, '('); + else + open_paren = nullptr; + } + if (open_paren) { - static StringSummaryFormat format(TypeSummaryImpl::Flags() - .SetHideItemNames(false) - .SetShowMembersOneLiner(true), - ""); - format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions()); - var_representation = buffer.c_str(); + if (IsToken (open_paren, "(anonymous namespace)")) + { + open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '('); + if (open_paren) + close_paren = strchr (open_paren, ')'); + } + else + close_paren = strchr (open_paren, ')'); } + + if (open_paren) + s.Write(cstr, open_paren - cstr + 1); else - var_representation = var_value_sp->GetValueAsCString(); - if (arg_idx > 0) - s.PutCString (", "); - if (var_value_sp->GetError().Success()) { - if (var_representation) - s.Printf ("%s=%s", var_name, var_representation); + s.PutCString (cstr); + s.PutChar ('('); + } + const size_t num_args = args.GetSize(); + for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) + { + std::string buffer; + + VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); + ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); + StreamString ss; + const char *var_representation = nullptr; + const char *var_name = var_value_sp->GetName().GetCString(); + if (var_value_sp->GetCompilerType().IsValid()) + { + if (var_value_sp && exe_scope->CalculateTarget()) + var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(exe_scope->CalculateTarget()->TargetProperties::GetPreferDynamicValue(), + exe_scope->CalculateTarget()->TargetProperties::GetEnableSyntheticValue()); + if (var_value_sp->GetCompilerType().IsAggregateType() && + DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get())) + { + static StringSummaryFormat format(TypeSummaryImpl::Flags() + .SetHideItemNames(false) + .SetShowMembersOneLiner(true), + ""); + format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions()); + var_representation = buffer.c_str(); + } + else + var_value_sp->DumpPrintableRepresentation(ss, + ValueObject::ValueObjectRepresentationStyle::eValueObjectRepresentationStyleSummary, + eFormatDefault, + ValueObject::PrintableRepresentationSpecialCases::ePrintableRepresentationSpecialCasesAllow, + false); + } + + if (ss.GetData() && ss.GetSize()) + var_representation = ss.GetData(); + if (arg_idx > 0) + s.PutCString (", "); + if (var_value_sp->GetError().Success()) + { + if (var_representation) + s.Printf ("%s=%s", var_name, var_representation); + else + s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); + } else - s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString()); + s.Printf ("%s=<unavailable>", var_name); } + + if (close_paren) + s.PutCString (close_paren); else - s.Printf ("%s=<unavailable>", var_name); + s.PutChar(')'); + } - - if (close_paren) - s.PutCString (close_paren); else - s.PutChar(')'); - + { + s.PutCString(cstr); + } + return true; } - else + } + else if (sc->symbol) + { + const char *cstr = sc->symbol->GetName().AsCString (NULL); + if (cstr) { s.PutCString(cstr); + return true; } - return true; - } - } - else if (sc->symbol) - { - const char *cstr = sc->symbol->GetName().AsCString (NULL); - if (cstr) - { - s.PutCString(cstr); - return true; } } } @@ -1870,6 +1955,16 @@ FormatEntity::Format (const Entry &entry, case Entry::Type::FunctionChanged: return function_changed == true; + case Entry::Type::FunctionIsOptimized: + { + bool is_optimized = false; + if (sc->function && sc->function->GetIsOptimized()) + { + is_optimized = true; + } + return is_optimized; + } + case Entry::Type::FunctionInitial: return initial_function == true; @@ -1976,7 +2071,7 @@ ParseEntry (const llvm::StringRef &format_str, switch (entry_def->type) { case FormatEntity::Entry::Type::ParentString: - entry.string = std::move(format_str.str()); + entry.string = format_str.str(); return error; // Success case FormatEntity::Entry::Type::ParentNumber: @@ -2026,7 +2121,7 @@ ParseEntry (const llvm::StringRef &format_str, { // Any value whose separator is a with a ':' means this value has a string argument // that needs to be stored in the entry (like "${script.var:modulename.function}") - entry.string = std::move(value.str()); + entry.string = value.str(); } else { @@ -2247,7 +2342,7 @@ FormatEntity::ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint3 Entry entry; if (!variable_format.empty()) { - entry.printf_format = std::move(variable_format.str()); + entry.printf_format = variable_format.str(); // If the format contains a '%' we are going to assume this is // a printf style format. So if you want to format your thread ID @@ -2396,10 +2491,10 @@ FormatEntity::ExtractVariableInfo (llvm::StringRef &format_str, llvm::StringRef variable_name = llvm::StringRef(); variable_format = llvm::StringRef(); - const size_t paren_pos = format_str.find_first_of('}'); + const size_t paren_pos = format_str.find('}'); if (paren_pos != llvm::StringRef::npos) { - const size_t percent_pos = format_str.find_first_of('%'); + const size_t percent_pos = format_str.find('%'); if (percent_pos < paren_pos) { if (percent_pos > 0) @@ -2449,7 +2544,7 @@ MakeMatch (const llvm::StringRef &prefix, const char *suffix) { std::string match(prefix.str()); match.append(suffix); - return std::move(match); + return match; } static void @@ -2463,7 +2558,7 @@ AddMatches (const FormatEntity::Entry::Definition *def, { for (size_t i=0; i<n; ++i) { - std::string match = std::move(prefix.str()); + std::string match = prefix.str(); if (match_prefix.empty()) matches.AppendString(MakeMatch (prefix, def->children[i].name)); else if (strncmp(def->children[i].name, match_prefix.data(), match_prefix.size()) == 0) @@ -2488,7 +2583,7 @@ FormatEntity::AutoComplete (const char *s, // Hitting TAB after $ at the end of the string add a "{" if (dollar_pos == str.size() - 1) { - std::string match = std::move(str.str()); + std::string match = str.str(); match.append("{"); matches.AppendString(std::move(match)); } @@ -2521,12 +2616,12 @@ FormatEntity::AutoComplete (const char *s, if (n > 0) { // "${thread.info" <TAB> - matches.AppendString(std::move(MakeMatch (str, "."))); + matches.AppendString(MakeMatch(str, ".")); } else { // "${thread.id" <TAB> - matches.AppendString(std::move(MakeMatch (str, "}"))); + matches.AppendString(MakeMatch (str, "}")); word_complete = true; } } diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp index 0246778b06545..47d00e9184cfb 100644 --- a/source/Core/IOHandler.cpp +++ b/source/Core/IOHandler.cpp @@ -7,9 +7,20 @@ // //===----------------------------------------------------------------------===// +// C Includes +#ifndef LLDB_DISABLE_CURSES +#include <curses.h> +#include <panel.h> +#endif +// C++ Includes +#if defined(__APPLE__) +#include <deque> +#endif #include <string> +// Other libraries and framework includes +// Project includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/Debugger.h" @@ -28,10 +39,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/ThreadPlan.h" -#ifndef LLDB_DISABLE_CURSES -#include <ncurses.h> -#include <panel.h> -#endif + using namespace lldb; using namespace lldb_private; @@ -46,7 +54,6 @@ IOHandler::IOHandler (Debugger &debugger, IOHandler::Type type) : { } - IOHandler::IOHandler (Debugger &debugger, IOHandler::Type type, const lldb::StreamFileSP &input_sp, @@ -71,10 +78,7 @@ IOHandler::IOHandler (Debugger &debugger, m_error_sp); } -IOHandler::~IOHandler() -{ -} - +IOHandler::~IOHandler() = default; int IOHandler::GetInputFD() @@ -136,7 +140,6 @@ IOHandler::GetOutputStreamFile() return m_output_sp; } - StreamFileSP & IOHandler::GetErrorStreamFile() { @@ -204,10 +207,7 @@ IOHandlerConfirm::IOHandlerConfirm (Debugger &debugger, } - -IOHandlerConfirm::~IOHandlerConfirm () -{ -} +IOHandlerConfirm::~IOHandlerConfirm() = default; int IOHandlerConfirm::IOHandlerComplete (IOHandler &io_handler, @@ -334,11 +334,9 @@ IOHandlerDelegate::IOHandlerComplete (IOHandler &io_handler, break; } - return 0; } - IOHandlerEditline::IOHandlerEditline (Debugger &debugger, IOHandler::Type type, const char *editline_name, // Used for saving history files @@ -444,7 +442,6 @@ IOHandlerEditline::Deactivate () m_delegate.IOHandlerDeactivated(*this); } - bool IOHandlerEditline::GetLine (std::string &line, bool &interrupted) { @@ -619,7 +616,6 @@ IOHandlerEditline::GetContinuationPrompt () return m_continuation_prompt.c_str(); } - void IOHandlerEditline::SetContinuationPrompt (const char *p) { @@ -634,7 +630,6 @@ IOHandlerEditline::SetContinuationPrompt (const char *p) #endif } - void IOHandlerEditline::SetBaseLineNumber (uint32_t line) { @@ -824,6 +819,7 @@ type summary add -s "x=${var.x}, y=${var.y}" curses::Point type summary add -s "w=${var.width}, h=${var.height}" curses::Size type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect #endif + struct Point { int x; @@ -855,13 +851,13 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect { printf ("(x=%i, y=%i)\n", x, y); } - }; bool operator == (const Point &lhs, const Point &rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; } + bool operator != (const Point &lhs, const Point &rhs) { return lhs.x != rhs.x || lhs.y != rhs.y; @@ -889,13 +885,13 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect { printf ("(w=%i, h=%i)\n", width, height); } - }; bool operator == (const Size &lhs, const Size &rhs) { return lhs.width == rhs.width && lhs.height == rhs.height; } + bool operator != (const Size &lhs, const Size &rhs) { return lhs.width != rhs.width || lhs.height != rhs.height; @@ -942,6 +938,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect size.height -= h*2; origin.y += h; } + // Return a status bar rectangle which is the last line of // this rectangle. This rectangle will be modified to not // include the status bar area. @@ -1011,7 +1008,6 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect VerticalSplit (left_width, left, right); } - void VerticalSplit (int left_width, Rect &left, Rect &right) const { @@ -1035,6 +1031,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect { return lhs.origin == rhs.origin && lhs.size == rhs.size; } + bool operator != (const Rect &lhs, const Rect &rhs) { return lhs.origin != rhs.origin || lhs.size != rhs.size; @@ -1064,9 +1061,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect { public: virtual - ~WindowDelegate() - { - } + ~WindowDelegate() = default; virtual bool WindowDelegateDraw (Window &window, bool force) @@ -1098,9 +1093,9 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect { public: HelpDialogDelegate (const char *text, KeyHelp *key_help_array); - + ~HelpDialogDelegate() override; - + bool WindowDelegateDraw (Window &window, bool force) override; @@ -1124,11 +1119,9 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect int m_first_visible_line; }; - class Window { public: - Window (const char *name) : m_name (name), m_window (NULL), @@ -1726,6 +1719,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect { return m_name.c_str(); } + protected: std::string m_name; WINDOW *m_window; @@ -1747,8 +1741,8 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect class MenuDelegate { public: - virtual ~MenuDelegate() {} - + virtual ~MenuDelegate() = default; + virtual MenuActionResult MenuDelegateAction (Menu &menu) = 0; }; @@ -1772,10 +1766,8 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect const char *key_name, int key_value, uint64_t identifier); - - ~Menu () override - { - } + + ~Menu() override = default; const MenuDelegateSP & GetDelegate () const @@ -1912,7 +1904,6 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect return m_max_submenu_name_length + m_max_submenu_key_name_length + 8; } - uint64_t GetIdentifier() const { @@ -2223,7 +2214,7 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect { // Run the action on this menu in case we need to populate the // menu with dynamic content and also in case check marks, and - // any other menu decorations need to be caclulated + // any other menu decorations need to be calculated if (run_menu_sp->Action() == MenuActionResult::Quit) return eQuitApplication; @@ -2314,12 +2305,10 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect } else if (menu_type == Menu::Type::Separator) { - } return result; } - class Application { public: @@ -2496,7 +2485,6 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect } debugger.CancelForwardEvents (listener_sp); - } WindowSP & @@ -2520,11 +2508,9 @@ type summary add -s "${var.origin%S} ${var.size%S}" curses::Rect FILE *m_in; FILE *m_out; }; - } // namespace curses - using namespace curses; struct Row @@ -2661,11 +2647,13 @@ class TreeDelegate { public: TreeDelegate() {} - virtual ~TreeDelegate() {} + virtual ~TreeDelegate() = default; + virtual void TreeDelegateDrawTreeItem (TreeItem &item, Window &window) = 0; virtual void TreeDelegateGenerateChildren (TreeItem &item) = 0; virtual bool TreeDelegateItemSelected (TreeItem &item) = 0; // Return true if we need to update views }; + typedef std::shared_ptr<TreeDelegate> TreeDelegateSP; class TreeItem @@ -2751,6 +2739,7 @@ public: { m_delegate.TreeDelegateItemSelected(*this); } + void CalculateRowIndexes (int &row_idx) { @@ -2944,7 +2933,6 @@ public: { m_identifier = identifier; } - void SetMightHaveChildren (bool b) @@ -2961,7 +2949,6 @@ protected: std::vector<TreeItem> m_children; bool m_might_have_children; bool m_is_expanded; - }; class TreeWindowDelegate : public WindowDelegate @@ -3052,8 +3039,7 @@ public: return true; // Drawing handled } - - + const char * WindowDelegateGetHelpText () override { @@ -3125,6 +3111,7 @@ public: m_selected_item->ItemWasSelected (); } return eKeyHandled; + case KEY_DOWN: if (m_selected_row_idx + 1 < m_num_rows) { @@ -3191,7 +3178,6 @@ protected: int m_min_y; int m_max_x; int m_max_y; - }; class FrameTreeDelegate : public TreeDelegate @@ -3203,11 +3189,9 @@ public: FormatEntity::Parse ("frame #${frame.index}: {${function.name}${function.pc-offset}}}", m_format); } - - ~FrameTreeDelegate() override - { - } - + + ~FrameTreeDelegate() override = default; + void TreeDelegateDrawTreeItem (TreeItem &item, Window &window) override { @@ -3229,6 +3213,7 @@ public: } } } + void TreeDelegateGenerateChildren (TreeItem &item) override { @@ -3248,6 +3233,7 @@ public: } return false; } + protected: FormatEntity::Entry m_format; }; @@ -3264,11 +3250,9 @@ public: FormatEntity::Parse ("thread #${thread.index}: tid = ${thread.id}{, stop reason = ${thread.stop-reason}}", m_format); } - - ~ThreadTreeDelegate() override - { - } - + + ~ThreadTreeDelegate() override = default; + ProcessSP GetProcess () { @@ -3299,6 +3283,7 @@ public: } } } + void TreeDelegateGenerateChildren (TreeItem &item) override { @@ -3369,7 +3354,6 @@ protected: lldb::user_id_t m_tid; uint32_t m_stop_id; FormatEntity::Entry m_format; - }; class ThreadsTreeDelegate : public TreeDelegate @@ -3384,11 +3368,9 @@ public: FormatEntity::Parse("process ${process.id}{, name = ${process.name}}", m_format); } - - ~ThreadsTreeDelegate() override - { - } - + + ~ThreadsTreeDelegate() override = default; + ProcessSP GetProcess () { @@ -3460,7 +3442,6 @@ protected: Debugger &m_debugger; uint32_t m_stop_id; FormatEntity::Entry m_format; - }; class ValueObjectListDelegate : public WindowDelegate @@ -3490,10 +3471,8 @@ public: { SetValues (valobj_list); } - - ~ValueObjectListDelegate() override - { - } + + ~ValueObjectListDelegate() override = default; void SetValues (ValueObjectList &valobj_list) @@ -3586,7 +3565,6 @@ public: return g_source_view_key_help; } - HandleCharResult WindowDelegateHandleChar (Window &window, int c) override { @@ -3646,6 +3624,7 @@ public: if (m_selected_row_idx > 0) --m_selected_row_idx; return eKeyHandled; + case KEY_DOWN: if (m_selected_row_idx + 1 < m_num_rows) ++m_selected_row_idx; @@ -3784,6 +3763,7 @@ protected: return true; } + void DisplayRows (Window &window, std::vector<Row> &rows, @@ -3845,6 +3825,7 @@ protected: } return row_count; } + static Row * GetRowForRowIndexImpl (std::vector<Row> &rows, size_t &row_index) { @@ -3890,11 +3871,9 @@ public: m_frame_block (NULL) { } - - ~FrameVariablesWindowDelegate() override - { - } - + + ~FrameVariablesWindowDelegate() override = default; + const char * WindowDelegateGetHelpText () override { @@ -3924,7 +3903,6 @@ public: } } - ValueObjectList local_values; if (frame_block) { @@ -3964,7 +3942,6 @@ public: } return ValueObjectListDelegate::WindowDelegateDraw (window, force); - } protected: @@ -3972,7 +3949,6 @@ protected: Block *m_frame_block; }; - class RegistersWindowDelegate : public ValueObjectListDelegate { public: @@ -3982,10 +3958,8 @@ public: { } - ~RegistersWindowDelegate() - { - } - + ~RegistersWindowDelegate() override = default; + const char * WindowDelegateGetHelpText () override { @@ -4133,7 +4107,9 @@ CursesKeyToCString (int ch) case KEY_UNDO: return "undo key"; case KEY_MOUSE: return "Mouse event has occurred"; case KEY_RESIZE: return "Terminal resize event"; +#ifdef KEY_EVENT case KEY_EVENT: return "We were interrupted by an event"; +#endif case KEY_RETURN: return "return"; case ' ': return "space"; case '\t': return "tab"; @@ -4168,9 +4144,7 @@ HelpDialogDelegate::HelpDialogDelegate (const char *text, KeyHelp *key_help_arra } } -HelpDialogDelegate::~HelpDialogDelegate() -{ -} +HelpDialogDelegate::~HelpDialogDelegate() = default; bool HelpDialogDelegate::WindowDelegateDraw (Window &window, bool force) @@ -4235,6 +4209,7 @@ HelpDialogDelegate::WindowDelegateHandleChar (Window &window, int key) m_first_visible_line = 0; } break; + case KEY_NPAGE: case '.': if (m_first_visible_line + num_visible_lines < num_lines) @@ -4244,6 +4219,7 @@ HelpDialogDelegate::WindowDelegateHandleChar (Window &window, int key) m_first_visible_line = num_lines - num_visible_lines; } break; + default: done = true; break; @@ -4298,10 +4274,8 @@ public: m_debugger (debugger) { } - - ~ApplicationDelegate () - { - } + + ~ApplicationDelegate() override = default; bool WindowDelegateDraw (Window &window, bool force) override @@ -4330,8 +4304,7 @@ public: } return eKeyNotHandled; } - - + const char * WindowDelegateGetHelpText () override { @@ -4626,7 +4599,6 @@ protected: Debugger &m_debugger; }; - class StatusBarWindowDelegate : public WindowDelegate { public: @@ -4636,10 +4608,8 @@ public: FormatEntity::Parse("Thread: ${thread.id%tid}", m_format); } - - ~StatusBarWindowDelegate () - { - } + + ~StatusBarWindowDelegate() override = default; bool WindowDelegateDraw (Window &window, bool force) override @@ -4713,9 +4683,7 @@ public: { } - ~SourceFileWindowDelegate() override - { - } + ~SourceFileWindowDelegate() override = default; void Update (const SymbolContext &sc) @@ -5063,7 +5031,6 @@ public: } if (highlight_attr) window.AttributeOff(highlight_attr); - } else { @@ -5240,6 +5207,7 @@ public: return m_file_sp->GetNumLines(); return 0; } + size_t GetNumDisassemblyLines () const { @@ -5404,6 +5372,7 @@ public: } } return eKeyHandled; + case 'n': // 'n' == step over case 'N': // 'N' == step over instruction { @@ -5415,6 +5384,7 @@ public: } } return eKeyHandled; + case 's': // 's' == step into case 'S': // 'S' == step into instruction { @@ -5460,7 +5430,6 @@ protected: int m_min_y; int m_max_x; int m_max_y; - }; DisplayOptions ValueObjectListDelegate::g_options = { true }; @@ -5477,8 +5446,7 @@ IOHandlerCursesGUI::Activate () if (!m_app_ap) { m_app_ap.reset (new Application (GetInputFILE(), GetOutputFILE())); - - + // This is both a window and a menu delegate std::shared_ptr<ApplicationDelegate> app_delegate_sp(new ApplicationDelegate(*m_app_ap, m_debugger)); @@ -5578,7 +5546,6 @@ IOHandlerCursesGUI::Activate () init_pair (3, COLOR_MAGENTA , COLOR_WHITE ); init_pair (4, COLOR_MAGENTA , COLOR_BLACK ); init_pair (5, COLOR_RED , COLOR_BLACK ); - } } @@ -5595,11 +5562,7 @@ IOHandlerCursesGUI::Run () SetIsDone(true); } - -IOHandlerCursesGUI::~IOHandlerCursesGUI () -{ - -} +IOHandlerCursesGUI::~IOHandlerCursesGUI() = default; void IOHandlerCursesGUI::Cancel () @@ -5612,10 +5575,9 @@ IOHandlerCursesGUI::Interrupt () return false; } - void IOHandlerCursesGUI::GotEOF() { } -#endif // #ifndef LLDB_DISABLE_CURSES +#endif // LLDB_DISABLE_CURSES diff --git a/source/Core/Language.cpp b/source/Core/Language.cpp deleted file mode 100644 index 1cc4b8a0dc9cf..0000000000000 --- a/source/Core/Language.cpp +++ /dev/null @@ -1,169 +0,0 @@ -//===-- Language.cpp --------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/lldb-private.h" -#include "lldb/Core/Language.h" -#include "lldb/Core/Stream.h" -#include "llvm/ADT/STLExtras.h" -#include <string.h> - -using namespace lldb; -using namespace lldb_private; - -#define ENUM_TO_DCSTREAM(x) case x: s->PutCString(#x); return - -struct LanguageStrings -{ - const char * names[3]; -}; - -static LanguageStrings -g_languages[] = -{ - { { "unknown" , NULL , NULL } }, - { { "c89" , NULL , "ISO C:1989" } }, - { { NULL , NULL , "K&R C" } }, - { { "ada83" , "Ada83" , "ISO Ada:1983" } }, - { { "c++" , "cxx" , "ISO C++:1998" } }, - { { "cobol74" , "Cobol74" , "ISO Cobol:1974" } }, - { { "cobol" , "Cobol85" , "ISO Cobol:1985." } }, - { { "f77" , "Fortran77" , "ISO Fortran 77." } }, - { { "f90" , "Fortran90" , "ISO Fortran 90" } }, - { { "pascal" , "Pascal83" , "ISO Pascal:1983" } }, - { { "modula2" , "Modula2" , "ISO Modula-2:1996" } }, - { { "java" , NULL , "Java" } }, - { { "c" , "C99" , "ISO C:1999" } }, - { { "ada" , "Ada95" , "ISO Ada:1995" } }, - { { "f95" , "Fortran95" , "ISO Fortran 95" } }, - { { "PLI" , NULL , "ANSI PL/I:1976" } }, - { { "objc" , NULL , "Objective-C" } }, - { { "objc++" , NULL , "Objective-C++" } }, - { { "upc" , NULL , "Unified Parallel C" } }, - { { "d" , NULL , "D" } }, - { { "python" , NULL , "Python" } }, - { { "opencl" , "OpenCL" , "OpenCL" } }, - { { "go" , "Go" , "Go" } }, - { { "modula3" , "Modula3" , "Modula 3" } }, - { { "haskell" , "Haskell" , "Haskell" } }, - { { "c++03" , "C_plus_plus_03" , "ISO C++:2003" } }, - { { "c++11" , "C_plus_plus_11" , "ISO C++:2011" } }, - { { "ocaml" , "OCaml" , "OCaml" } }, - { { "rust" , "Rust" , "Rust" } }, - { { "c11" , "C11" , "ISO C:2011" } }, - { { "swift" , "Swift" , "Swift" } }, - { { "julia" , "Julia" , "Julia" } }, - { { "dylan" , "Dylan" , "Dylan" } }, - { { "c++14" , "C_plus_plus_14" , "ISO C++:2014" } }, - { { "f03" , "Fortran03" , "ISO Fortran 2003" } }, - { { "f08" , "Fortran08" , "ISO Fortran 2008" } }, - // Vendor Extensions - { { "mipsassem" , "Mips_Assembler" , "Mips Assembler" } }, - { { "renderscript" , "RenderScript" , "RenderScript" } } -}; - -static const size_t g_num_languages = llvm::array_lengthof(g_languages); - -Language::Language(LanguageType language) : - m_language (language) -{ -} - -Language::~Language() -{ -} - -LanguageType -Language::GetLanguage() const -{ - return m_language; -} - -void -Language::Clear () -{ - m_language = eLanguageTypeUnknown; -} - -void -Language::SetLanguage(LanguageType language) -{ - m_language = language; -} - -bool -Language::SetLanguageFromCString(const char *language_cstr) -{ - size_t i, desc_idx; - const char *name; - - // First check the most common name for the languages - for (desc_idx=lldb::eDescriptionLevelBrief; desc_idx<kNumDescriptionLevels; ++desc_idx) - { - for (i=0; i<g_num_languages; ++i) - { - name = g_languages[i].names[desc_idx]; - if (name == NULL) - continue; - - if (::strcasecmp (language_cstr, name) == 0) - { - m_language = (LanguageType)i; - return true; - } - } - } - - m_language = eLanguageTypeUnknown; - return false; -} - - -const char * -Language::AsCString (lldb::DescriptionLevel level) const -{ - if (m_language < g_num_languages && level < kNumDescriptionLevels) - { - const char *name = g_languages[m_language].names[level]; - if (name) - return name; - else if (level + 1 < kNumDescriptionLevels) - return AsCString ((lldb::DescriptionLevel)(level + 1)); - else - return NULL; - } - return NULL; -} - -void -Language::Dump(Stream *s) const -{ - GetDescription(s, lldb::eDescriptionLevelVerbose); -} - -void -Language::GetDescription (Stream *s, lldb::DescriptionLevel level) const -{ - const char *lang_cstr = AsCString(level); - - if (lang_cstr) - s->PutCString(lang_cstr); - else - s->Printf("Language(language = 0x%4.4x)", m_language); -} - - - - -Stream& -lldb_private::operator << (Stream& s, const Language& language) -{ - language.Dump(&s); - return s; -} - diff --git a/source/Core/Log.cpp b/source/Core/Log.cpp index 6acd50eec76a2..8d415bdc0e777 100644 --- a/source/Core/Log.cpp +++ b/source/Core/Log.cpp @@ -143,6 +143,7 @@ Log::VAPrintf(const char *format, va_list args) std::string back_trace; llvm::raw_string_ostream stream(back_trace); llvm::sys::PrintStackTrace(stream); + stream.flush(); header.PutCString(back_trace.c_str()); } @@ -449,7 +450,7 @@ Log::DisableAllLogChannels (Stream *feedback_strm) { CallbackMap &callback_map = GetCallbackMap (); CallbackMapIter pos, end = callback_map.end(); - const char *categories[1] = {NULL}; + const char *categories[] = {"all", nullptr}; for (pos = callback_map.begin(); pos != end; ++pos) pos->second.disable (categories, feedback_strm); diff --git a/source/Core/Logging.cpp b/source/Core/Logging.cpp index 412536adbb34e..d08d833ee4694 100644 --- a/source/Core/Logging.cpp +++ b/source/Core/Logging.cpp @@ -148,6 +148,7 @@ lldb_private::DisableLog (const char **categories, Stream *feedback_strm) else if (0 == ::strcasecmp(arg, "os")) flag_bits &= ~LIBLLDB_LOG_OS; else if (0 == ::strcasecmp(arg, "jit")) flag_bits &= ~LIBLLDB_LOG_JIT_LOADER; else if (0 == ::strcasecmp(arg, "language")) flag_bits &= ~LIBLLDB_LOG_LANGUAGE; + else if (0 == ::strncasecmp(arg, "formatters", 10)) flag_bits &= ~LIBLLDB_LOG_DATAFORMATTERS; else { feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg); @@ -224,6 +225,7 @@ lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const ch else if (0 == ::strncasecmp(arg, "watch", 5)) flag_bits |= LIBLLDB_LOG_WATCHPOINTS; else if (0 == ::strcasecmp(arg, "jit")) flag_bits |= LIBLLDB_LOG_JIT_LOADER; else if (0 == ::strcasecmp(arg, "language")) flag_bits |= LIBLLDB_LOG_LANGUAGE; + else if (0 == ::strncasecmp(arg, "formatters", 10)) flag_bits |= LIBLLDB_LOG_DATAFORMATTERS; else { feedback_strm->Printf("error: unrecognized log category '%s'\n", arg); @@ -254,6 +256,7 @@ lldb_private::ListLogCategories (Stream *strm) " dyld - log shared library related activities\n" " events - log broadcaster, listener and event queue activities\n" " expr - log expressions\n" + " formatters - log data formatters related activities\n" " host - log host activities\n" " jit - log JIT events in the target\n" " language - log language runtime events\n" diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp index a1916fe913c4c..bdc710c8f8e19 100644 --- a/source/Core/Mangled.cpp +++ b/source/Core/Mangled.cpp @@ -38,7 +38,8 @@ #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Stream.h" #include "lldb/Core/Timer.h" -#include "lldb/Target/CPPLanguageRuntime.h" +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" #include <ctype.h> #include <string.h> #include <stdlib.h> @@ -94,11 +95,12 @@ get_demangled_name_without_arguments (ConstString mangled, ConstString demangled mangled_name_cstr[2] != 'G' && // avoid guard variables mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually handle eSymbolTypeData, we will want this back) { - CPPLanguageRuntime::MethodName cxx_method (demangled); - if (!cxx_method.GetBasename().empty() && !cxx_method.GetContext().empty()) + CPlusPlusLanguage::MethodName cxx_method (demangled); + if (!cxx_method.GetBasename().empty()) { - std::string shortname = cxx_method.GetContext().str(); - shortname += "::"; + std::string shortname; + if (!cxx_method.GetContext().empty()) + shortname = cxx_method.GetContext().str() + "::"; shortname += cxx_method.GetBasename().str(); ConstString result(shortname.c_str()); g_most_recent_mangled_to_name_sans_args.first = mangled; @@ -360,6 +362,9 @@ Mangled::NameMatches (const RegularExpression& regex, lldb::LanguageType languag ConstString Mangled::GetName (lldb::LanguageType language, Mangled::NamePreference preference) const { + if (preference == ePreferMangled && m_mangled) + return m_mangled; + ConstString demangled = GetDemangledName(language); if (preference == ePreferDemangledWithoutArguments) @@ -374,12 +379,7 @@ Mangled::GetName (lldb::LanguageType language, Mangled::NamePreference preferenc return demangled; return m_mangled; } - else - { - if (m_mangled) - return m_mangled; - return demangled; - } + return demangled; } //---------------------------------------------------------------------- @@ -425,6 +425,14 @@ Mangled::MemorySize () const return m_mangled.MemorySize() + m_demangled.MemorySize(); } +//---------------------------------------------------------------------- +// We "guess" the language because we can't determine a symbol's language +// from it's name. For example, a Pascal symbol can be mangled using the +// C++ Itanium scheme, and defined in a compilation unit within the same +// module as other C++ units. In addition, different targets could have +// different ways of mangling names from a given language, likewise the +// compilation units within those targets. +//---------------------------------------------------------------------- lldb::LanguageType Mangled::GuessLanguage () const { @@ -433,11 +441,14 @@ Mangled::GuessLanguage () const { if (GetDemangledName(lldb::eLanguageTypeUnknown)) { - if (cstring_is_mangled(mangled.GetCString())) + const char *mangled_name = mangled.GetCString(); + if (CPlusPlusLanguage::IsCPPMangledName(mangled_name)) return lldb::eLanguageTypeC_plus_plus; + else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name)) + return lldb::eLanguageTypeObjC; } } - return lldb::eLanguageTypeUnknown; + return lldb::eLanguageTypeUnknown; } //---------------------------------------------------------------------- diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp index eb0359d02d5be..833540e1a3099 100644 --- a/source/Core/Module.cpp +++ b/source/Core/Module.cpp @@ -15,6 +15,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamString.h" @@ -23,17 +24,19 @@ #include "lldb/Host/Symbols.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" -#include "lldb/Target/CPPLanguageRuntime.h" -#include "lldb/Target/ObjCLanguageRuntime.h" +#include "lldb/Symbol/TypeSystem.h" +#include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" -#include "lldb/Symbol/SymbolFile.h" +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" +#include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "lldb/Symbol/TypeMap.h" #include "Plugins/ObjectFile/JIT/ObjectFileJIT.h" @@ -146,13 +149,12 @@ Module::Module (const ModuleSpec &module_spec) : m_object_mod_time (), m_objfile_sp (), m_symfile_ap (), - m_ast (new ClangASTContext), + m_type_system_map(), m_source_mappings (), m_sections_ap(), m_did_load_objfile (false), m_did_load_symbol_vendor (false), m_did_parse_uuid (false), - m_did_init_ast (false), m_file_has_changed (false), m_first_file_changed_log (false) { @@ -250,13 +252,12 @@ Module::Module(const FileSpec& file_spec, m_object_mod_time (), m_objfile_sp (), m_symfile_ap (), - m_ast (new ClangASTContext), + m_type_system_map(), m_source_mappings (), m_sections_ap(), m_did_load_objfile (false), m_did_load_symbol_vendor (false), m_did_parse_uuid (false), - m_did_init_ast (false), m_file_has_changed (false), m_first_file_changed_log (false) { @@ -296,13 +297,12 @@ Module::Module () : m_object_mod_time (), m_objfile_sp (), m_symfile_ap (), - m_ast (new ClangASTContext), + m_type_system_map(), m_source_mappings (), m_sections_ap(), m_did_load_objfile (false), m_did_load_symbol_vendor (false), m_did_parse_uuid (false), - m_did_init_ast (false), m_file_has_changed (false), m_first_file_changed_log (false) { @@ -399,52 +399,27 @@ Module::GetMemoryObjectFile (const lldb::ProcessSP &process_sp, lldb::addr_t hea const lldb_private::UUID& Module::GetUUID() { - Mutex::Locker locker (m_mutex); - if (m_did_parse_uuid == false) + if (m_did_parse_uuid.load() == false) { - ObjectFile * obj_file = GetObjectFile (); - - if (obj_file != NULL) + Mutex::Locker locker (m_mutex); + if (m_did_parse_uuid.load() == false) { - obj_file->GetUUID(&m_uuid); - m_did_parse_uuid = true; + ObjectFile * obj_file = GetObjectFile (); + + if (obj_file != NULL) + { + obj_file->GetUUID(&m_uuid); + m_did_parse_uuid = true; + } } } return m_uuid; } -ClangASTContext & -Module::GetClangASTContext () +TypeSystem * +Module::GetTypeSystemForLanguage (LanguageType language) { - Mutex::Locker locker (m_mutex); - if (m_did_init_ast == false) - { - ObjectFile * objfile = GetObjectFile(); - ArchSpec object_arch; - if (objfile && objfile->GetArchitecture(object_arch)) - { - m_did_init_ast = true; - - // LLVM wants this to be set to iOS or MacOSX; if we're working on - // a bare-boards type image, change the triple for llvm's benefit. - if (object_arch.GetTriple().getVendor() == llvm::Triple::Apple - && object_arch.GetTriple().getOS() == llvm::Triple::UnknownOS) - { - if (object_arch.GetTriple().getArch() == llvm::Triple::arm || - object_arch.GetTriple().getArch() == llvm::Triple::aarch64 || - object_arch.GetTriple().getArch() == llvm::Triple::thumb) - { - object_arch.GetTriple().setOS(llvm::Triple::IOS); - } - else - { - object_arch.GetTriple().setOS(llvm::Triple::MacOSX); - } - } - m_ast->SetArchitecture (object_arch); - } - } - return *m_ast; + return m_type_system_map.GetTypeSystemForLanguage(language, this, true); } void @@ -706,14 +681,14 @@ Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t li size_t Module::FindGlobalVariables (const ConstString &name, - const ClangNamespaceDecl *namespace_decl, + const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, VariableList& variables) { SymbolVendor *symbols = GetSymbolVendor (); if (symbols) - return symbols->FindGlobalVariables(name, namespace_decl, append, max_matches, variables); + return symbols->FindGlobalVariables(name, parent_decl_ctx, append, max_matches, variables); return 0; } @@ -756,7 +731,7 @@ Module::FindCompileUnits (const FileSpec &path, size_t Module::FindFunctions (const ConstString &name, - const ClangNamespaceDecl *namespace_decl, + const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_symbols, bool include_inlines, @@ -778,6 +753,7 @@ Module::FindFunctions (const ConstString &name, bool match_name_after_lookup = false; Module::PrepareForFunctionNameLookup (name, name_type_mask, + eLanguageTypeUnknown, // TODO: add support lookup_name, lookup_name_type_mask, match_name_after_lookup); @@ -785,7 +761,7 @@ Module::FindFunctions (const ConstString &name, if (symbols) { symbols->FindFunctions(lookup_name, - namespace_decl, + parent_decl_ctx, lookup_name_type_mask, include_inlines, append, @@ -825,7 +801,7 @@ Module::FindFunctions (const ConstString &name, { if (symbols) { - symbols->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, append, sc_list); + symbols->FindFunctions(name, parent_decl_ctx, name_type_mask, include_inlines, append, sc_list); // Now check our symbol table for symbols that are code symbols if requested if (include_symbols) @@ -943,17 +919,17 @@ Module::FindAddressesForLine (const lldb::TargetSP target_sp, size_t Module::FindTypes_Impl (const SymbolContext& sc, const ConstString &name, - const ClangNamespaceDecl *namespace_decl, + const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, - TypeList& types) + TypeMap& types) { Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); if (sc.module_sp.get() == NULL || sc.module_sp.get() == this) { SymbolVendor *symbols = GetSymbolVendor (); if (symbols) - return symbols->FindTypes(sc, name, namespace_decl, append, max_matches, types); + return symbols->FindTypes(sc, name, parent_decl_ctx, append, max_matches, types); } return 0; } @@ -961,12 +937,16 @@ Module::FindTypes_Impl (const SymbolContext& sc, size_t Module::FindTypesInNamespace (const SymbolContext& sc, const ConstString &type_name, - const ClangNamespaceDecl *namespace_decl, + const CompilerDeclContext *parent_decl_ctx, size_t max_matches, TypeList& type_list) { const bool append = true; - return FindTypes_Impl(sc, type_name, namespace_decl, append, max_matches, type_list); + TypeMap types_map; + size_t num_types = FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches, types_map); + if (num_types > 0) + sc.SortTypeList(types_map, type_list); + return num_types; } lldb::TypeSP @@ -995,6 +975,7 @@ Module::FindTypes (const SymbolContext& sc, std::string type_basename; const bool append = true; TypeClass type_class = eTypeClassAny; + TypeMap typesmap; if (Type::GetTypeScopeAndBasename (type_name_cstr, type_scope, type_basename, type_class)) { // Check if "name" starts with "::" which means the qualified type starts @@ -1008,10 +989,10 @@ Module::FindTypes (const SymbolContext& sc, exact_match = true; } ConstString type_basename_const_str (type_basename.c_str()); - if (FindTypes_Impl(sc, type_basename_const_str, NULL, append, max_matches, types)) + if (FindTypes_Impl(sc, type_basename_const_str, NULL, append, max_matches, typesmap)) { - types.RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match); - num_matches = types.GetSize(); + typesmap.RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match); + num_matches = typesmap.GetSize(); } } else @@ -1021,32 +1002,35 @@ Module::FindTypes (const SymbolContext& sc, { // The "type_name_cstr" will have been modified if we have a valid type class // prefix (like "struct", "class", "union", "typedef" etc). - FindTypes_Impl(sc, ConstString(type_name_cstr), NULL, append, max_matches, types); - types.RemoveMismatchedTypes (type_class); - num_matches = types.GetSize(); + FindTypes_Impl(sc, ConstString(type_name_cstr), NULL, append, max_matches, typesmap); + typesmap.RemoveMismatchedTypes (type_class); + num_matches = typesmap.GetSize(); } else { - num_matches = FindTypes_Impl(sc, name, NULL, append, max_matches, types); + num_matches = FindTypes_Impl(sc, name, NULL, append, max_matches, typesmap); } } - + if (num_matches > 0) + sc.SortTypeList(typesmap, types); return num_matches; - } SymbolVendor* Module::GetSymbolVendor (bool can_create, lldb_private::Stream *feedback_strm) { - Mutex::Locker locker (m_mutex); - if (m_did_load_symbol_vendor == false && can_create) + if (m_did_load_symbol_vendor.load() == false) { - ObjectFile *obj_file = GetObjectFile (); - if (obj_file != NULL) + Mutex::Locker locker (m_mutex); + if (m_did_load_symbol_vendor.load() == false && can_create) { - Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); - m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this(), feedback_strm)); - m_did_load_symbol_vendor = true; + ObjectFile *obj_file = GetObjectFile (); + if (obj_file != NULL) + { + Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); + m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this(), feedback_strm)); + m_did_load_symbol_vendor = true; + } } } return m_symfile_ap.get(); @@ -1287,37 +1271,40 @@ Module::GetObjectName() const ObjectFile * Module::GetObjectFile() { - Mutex::Locker locker (m_mutex); - if (m_did_load_objfile == false) + if (m_did_load_objfile.load() == false) { - Timer scoped_timer(__PRETTY_FUNCTION__, - "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); - DataBufferSP data_sp; - lldb::offset_t data_offset = 0; - const lldb::offset_t file_size = m_file.GetByteSize(); - if (file_size > m_object_offset) + Mutex::Locker locker (m_mutex); + if (m_did_load_objfile.load() == false) { - m_did_load_objfile = true; - m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(), - &m_file, - m_object_offset, - file_size - m_object_offset, - data_sp, - data_offset); - if (m_objfile_sp) + Timer scoped_timer(__PRETTY_FUNCTION__, + "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); + DataBufferSP data_sp; + lldb::offset_t data_offset = 0; + const lldb::offset_t file_size = m_file.GetByteSize(); + if (file_size > m_object_offset) { - // Once we get the object file, update our module with the object file's - // architecture since it might differ in vendor/os if some parts were - // unknown. But since the matching arch might already be more specific - // than the generic COFF architecture, only merge in those values that - // overwrite unspecified unknown values. - ArchSpec new_arch; - m_objfile_sp->GetArchitecture(new_arch); - m_arch.MergeFrom(new_arch); - } - else - { - ReportError ("failed to load objfile for %s", GetFileSpec().GetPath().c_str()); + m_did_load_objfile = true; + m_objfile_sp = ObjectFile::FindPlugin (shared_from_this(), + &m_file, + m_object_offset, + file_size - m_object_offset, + data_sp, + data_offset); + if (m_objfile_sp) + { + // Once we get the object file, update our module with the object file's + // architecture since it might differ in vendor/os if some parts were + // unknown. But since the matching arch might already be more specific + // than the generic COFF architecture, only merge in those values that + // overwrite unspecified unknown values. + ArchSpec new_arch; + m_objfile_sp->GetArchitecture(new_arch); + m_arch.MergeFrom(new_arch); + } + else + { + ReportError ("failed to load objfile for %s", GetFileSpec().GetPath().c_str()); + } } } } @@ -1487,6 +1474,9 @@ Module::SetSymbolFileFileSpec (const FileSpec &file) // we don't have to do anything. return; } + + // Cleare the current symtab as we are going to replace it with a new one + obj_file->ClearSymtab(); // The symbol file might be a directory bundle ("/tmp/a.out.dSYM") instead // of a full path to the symbol file within the bundle @@ -1680,7 +1670,8 @@ Module::MatchesModuleSpec (const ModuleSpec &module_ref) const FileSpec &file_spec = module_ref.GetFileSpec(); if (file_spec) { - if (!FileSpec::Equal (file_spec, m_file, (bool)file_spec.GetDirectory())) + if (!FileSpec::Equal (file_spec, m_file, (bool)file_spec.GetDirectory()) && + !FileSpec::Equal (file_spec, m_platform_file, (bool)file_spec.GetDirectory())) return false; } @@ -1739,6 +1730,7 @@ Module::GetVersion (uint32_t *versions, uint32_t num_versions) void Module::PrepareForFunctionNameLookup (const ConstString &name, uint32_t name_type_mask, + LanguageType language, ConstString &lookup_name, uint32_t &lookup_name_type_mask, bool &match_name_after_lookup) @@ -1752,20 +1744,28 @@ Module::PrepareForFunctionNameLookup (const ConstString &name, if (name_type_mask & eFunctionNameTypeAuto) { - if (CPPLanguageRuntime::IsCPPMangledName (name_cstr)) + if (CPlusPlusLanguage::IsCPPMangledName (name_cstr)) lookup_name_type_mask = eFunctionNameTypeFull; - else if (ObjCLanguageRuntime::IsPossibleObjCMethodName (name_cstr)) + else if ((language == eLanguageTypeUnknown || + Language::LanguageIsObjC(language)) && + ObjCLanguage::IsPossibleObjCMethodName (name_cstr)) lookup_name_type_mask = eFunctionNameTypeFull; + else if (Language::LanguageIsC(language)) + { + lookup_name_type_mask = eFunctionNameTypeFull; + } else { - if (ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr)) + if ((language == eLanguageTypeUnknown || + Language::LanguageIsObjC(language)) && + ObjCLanguage::IsPossibleObjCSelector(name_cstr)) lookup_name_type_mask |= eFunctionNameTypeSelector; - CPPLanguageRuntime::MethodName cpp_method (name); + CPlusPlusLanguage::MethodName cpp_method (name); basename = cpp_method.GetBasename(); if (basename.empty()) { - if (CPPLanguageRuntime::ExtractContextAndIdentifier (name_cstr, context, basename)) + if (CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename)) lookup_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase); else lookup_name_type_mask |= eFunctionNameTypeFull; @@ -1783,7 +1783,7 @@ Module::PrepareForFunctionNameLookup (const ConstString &name, { // If they've asked for a CPP method or function name and it can't be that, we don't // even need to search for CPP methods or names. - CPPLanguageRuntime::MethodName cpp_method (name); + CPlusPlusLanguage::MethodName cpp_method (name); if (cpp_method.IsValid()) { basename = cpp_method.GetBasename(); @@ -1801,13 +1801,13 @@ Module::PrepareForFunctionNameLookup (const ConstString &name, { // If the CPP method parser didn't manage to chop this up, try to fill in the base name if we can. // If a::b::c is passed in, we need to just look up "c", and then we'll filter the result later. - CPPLanguageRuntime::ExtractContextAndIdentifier (name_cstr, context, basename); + CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename); } } if (lookup_name_type_mask & eFunctionNameTypeSelector) { - if (!ObjCLanguageRuntime::IsPossibleObjCSelector(name_cstr)) + if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) { lookup_name_type_mask &= ~(eFunctionNameTypeSelector); if (lookup_name_type_mask == eFunctionNameTypeNone) diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp index 669b3d9274cc7..75b2ca11103a0 100644 --- a/source/Core/ModuleList.cpp +++ b/source/Core/ModuleList.cpp @@ -22,7 +22,6 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Host.h" #include "lldb/Host/Symbols.h" -#include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/VariableList.h" @@ -70,7 +69,7 @@ ModuleList::operator= (const ModuleList& rhs) // That's probably me nit-picking, but in theoretical situation: // // * that two threads A B and - // * two ModuleList's x y do opposite assignemnts ie.: + // * two ModuleList's x y do opposite assignments ie.: // // in thread A: | in thread B: // x = y; | y = x; @@ -372,6 +371,7 @@ ModuleList::FindFunctions (const ConstString &name, uint32_t lookup_name_type_mask = 0; bool match_name_after_lookup = false; Module::PrepareForFunctionNameLookup (name, name_type_mask, + eLanguageTypeUnknown, // TODO: add support lookup_name, lookup_name_type_mask, match_name_after_lookup); @@ -436,6 +436,7 @@ ModuleList::FindFunctionSymbols (const ConstString &name, uint32_t lookup_name_type_mask = 0; bool match_name_after_lookup = false; Module::PrepareForFunctionNameLookup (name, name_type_mask, + eLanguageTypeUnknown, // TODO: add support lookup_name, lookup_name_type_mask, match_name_after_lookup); @@ -682,7 +683,7 @@ ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool na { // Search the module if the module is not equal to the one in the symbol // context "sc". If "sc" contains a empty module shared pointer, then - // the comparisong will always be true (valid_module_ptr != NULL). + // the comparison will always be true (valid_module_ptr != NULL). if (sc.module_sp.get() != (*pos).get()) total_matches += (*pos)->FindTypes (world_sc, name, name_is_fully_qualified, max_matches, types); @@ -988,18 +989,31 @@ ModuleList::GetSharedModule // If we get in here we got the correct arch, now we just need // to verify the UUID if one was given if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) + { module_sp.reset(); + } else { - if (did_create_ptr) - *did_create_ptr = true; + if (module_sp->GetObjectFile() && module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary) + { + module_sp.reset(); + } + else + { + if (did_create_ptr) + { + *did_create_ptr = true; + } - shared_module_list.ReplaceEquivalent(module_sp); - return error; + shared_module_list.ReplaceEquivalent(module_sp); + return error; + } } } else + { module_sp.reset(); + } if (module_search_paths_ptr) { @@ -1023,18 +1037,29 @@ ModuleList::GetSharedModule // If we get in here we got the correct arch, now we just need // to verify the UUID if one was given if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) + { module_sp.reset(); + } else { - if (did_create_ptr) - *did_create_ptr = true; - - shared_module_list.ReplaceEquivalent(module_sp); - return Error(); + if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary) + { + module_sp.reset(); + } + else + { + if (did_create_ptr) + *did_create_ptr = true; + + shared_module_list.ReplaceEquivalent(module_sp); + return Error(); + } } } else + { module_sp.reset(); + } } } @@ -1044,19 +1069,19 @@ ModuleList::GetSharedModule // Fixup the incoming path in case the path points to a valid file, yet // the arch or UUID (if one was passed in) don't match. - FileSpec file_spec = Symbols::LocateExecutableObjectFile (module_spec); + ModuleSpec located_binary_modulespec = Symbols::LocateExecutableObjectFile (module_spec); // Don't look for the file if it appears to be the same one we already // checked for above... - if (file_spec != module_file_spec) + if (located_binary_modulespec.GetFileSpec() != module_file_spec) { - if (!file_spec.Exists()) + if (!located_binary_modulespec.GetFileSpec().Exists()) { - file_spec.GetPath(path, sizeof(path)); + located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path)); if (path[0] == '\0') module_file_spec.GetPath(path, sizeof(path)); // How can this check ever be true? This branch it is false, and we haven't modified file_spec. - if (file_spec.Exists()) + if (located_binary_modulespec.GetFileSpec().Exists()) { std::string uuid_str; if (uuid_ptr && uuid_ptr->IsValid()) @@ -1084,8 +1109,9 @@ ModuleList::GetSharedModule // function is actively working on it by doing an extra lock on the // global mutex list. ModuleSpec platform_module_spec(module_spec); - platform_module_spec.GetFileSpec() = file_spec; - platform_module_spec.GetPlatformFileSpec() = file_spec; + platform_module_spec.GetFileSpec() = located_binary_modulespec.GetFileSpec(); + platform_module_spec.GetPlatformFileSpec() = located_binary_modulespec.GetFileSpec(); + platform_module_spec.GetSymbolFileSpec() = located_binary_modulespec.GetSymbolFileSpec(); ModuleList matching_module_list; if (shared_module_list.FindModules (platform_module_spec, matching_module_list) > 0) { @@ -1095,7 +1121,7 @@ ModuleList::GetSharedModule // then we should make sure the modification time hasn't changed! if (platform_module_spec.GetUUIDPtr() == NULL) { - TimeValue file_spec_mod_time(file_spec.GetModificationTime()); + TimeValue file_spec_mod_time(located_binary_modulespec.GetFileSpec().GetModificationTime()); if (file_spec_mod_time.IsValid()) { if (file_spec_mod_time != module_sp->GetModificationTime()) @@ -1117,16 +1143,23 @@ ModuleList::GetSharedModule // By getting the object file we can guarantee that the architecture matches if (module_sp && module_sp->GetObjectFile()) { - if (did_create_ptr) - *did_create_ptr = true; + if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeStubLibrary) + { + module_sp.reset(); + } + else + { + if (did_create_ptr) + *did_create_ptr = true; - shared_module_list.ReplaceEquivalent(module_sp); + shared_module_list.ReplaceEquivalent(module_sp); + } } else { - file_spec.GetPath(path, sizeof(path)); + located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path)); - if (file_spec) + if (located_binary_modulespec.GetFileSpec()) { if (arch.IsValid()) error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path); diff --git a/source/Core/Opcode.cpp b/source/Core/Opcode.cpp index 73f5f85923c6d..89eea2624cecc 100644 --- a/source/Core/Opcode.cpp +++ b/source/Core/Opcode.cpp @@ -82,7 +82,7 @@ Opcode::GetDataByteOrder () const case Opcode::eType16: case Opcode::eType16_2: case Opcode::eType32: - case Opcode::eType64: return lldb::endian::InlHostByteOrder(); + case Opcode::eType64: return endian::InlHostByteOrder(); case Opcode::eTypeBytes: break; } diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp index e34b7fc3b17dd..a90b57678b7a4 100644 --- a/source/Core/PluginManager.cpp +++ b/source/Core/PluginManager.cpp @@ -771,16 +771,18 @@ PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstStri struct OperatingSystemInstance { - OperatingSystemInstance() : - name(), - description(), - create_callback(NULL) + OperatingSystemInstance () : + name (), + description (), + create_callback (nullptr), + debugger_init_callback (nullptr) { } ConstString name; std::string description; OperatingSystemCreateInstance create_callback; + DebuggerInitializeCallback debugger_init_callback; }; typedef std::vector<OperatingSystemInstance> OperatingSystemInstances; @@ -800,9 +802,9 @@ GetOperatingSystemInstances () } bool -PluginManager::RegisterPlugin (const ConstString &name, - const char *description, - OperatingSystemCreateInstance create_callback) +PluginManager::RegisterPlugin(const ConstString &name, const char *description, + OperatingSystemCreateInstance create_callback, + DebuggerInitializeCallback debugger_init_callback) { if (create_callback) { @@ -812,6 +814,7 @@ PluginManager::RegisterPlugin (const ConstString &name, if (description && description[0]) instance.description = description; instance.create_callback = create_callback; + instance.debugger_init_callback = debugger_init_callback; Mutex::Locker locker (GetOperatingSystemMutex ()); GetOperatingSystemInstances ().push_back (instance); } @@ -868,6 +871,111 @@ PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString } +#pragma mark Language + + +struct LanguageInstance +{ + LanguageInstance() : + name(), + description(), + create_callback(NULL) + { + } + + ConstString name; + std::string description; + LanguageCreateInstance create_callback; +}; + +typedef std::vector<LanguageInstance> LanguageInstances; + +static Mutex & +GetLanguageMutex () +{ + static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); + return g_instances_mutex; +} + +static LanguageInstances & +GetLanguageInstances () +{ + static LanguageInstances g_instances; + return g_instances; +} + +bool +PluginManager::RegisterPlugin +( + const ConstString &name, + const char *description, + LanguageCreateInstance create_callback + ) +{ + if (create_callback) + { + LanguageInstance instance; + assert ((bool)name); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + Mutex::Locker locker (GetLanguageMutex ()); + GetLanguageInstances ().push_back (instance); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback) +{ + if (create_callback) + { + Mutex::Locker locker (GetLanguageMutex ()); + LanguageInstances &instances = GetLanguageInstances (); + + LanguageInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == create_callback) + { + instances.erase(pos); + return true; + } + } + } + return false; +} + +LanguageCreateInstance +PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx) +{ + Mutex::Locker locker (GetLanguageMutex ()); + LanguageInstances &instances = GetLanguageInstances (); + if (idx < instances.size()) + return instances[idx].create_callback; + return NULL; +} + +LanguageCreateInstance +PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name) +{ + if (name) + { + Mutex::Locker locker (GetLanguageMutex ()); + LanguageInstances &instances = GetLanguageInstances (); + + LanguageInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (name == pos->name) + return pos->create_callback; + } + } + return NULL; +} + + #pragma mark LanguageRuntime @@ -1764,6 +1872,110 @@ PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name) return NULL; } +#pragma mark ScriptInterpreter + +struct ScriptInterpreterInstance +{ + ScriptInterpreterInstance() + : name() + , language(lldb::eScriptLanguageNone) + , description() + , create_callback(NULL) + { + } + + ConstString name; + lldb::ScriptLanguage language; + std::string description; + ScriptInterpreterCreateInstance create_callback; +}; + +typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances; + +static Mutex & +GetScriptInterpreterMutex() +{ + static Mutex g_instances_mutex(Mutex::eMutexTypeRecursive); + return g_instances_mutex; +} + +static ScriptInterpreterInstances & +GetScriptInterpreterInstances() +{ + static ScriptInterpreterInstances g_instances; + return g_instances; +} + +bool +PluginManager::RegisterPlugin(const ConstString &name, const char *description, lldb::ScriptLanguage script_language, + ScriptInterpreterCreateInstance create_callback) +{ + if (!create_callback) + return false; + ScriptInterpreterInstance instance; + assert((bool)name); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + instance.language = script_language; + Mutex::Locker locker(GetScriptInterpreterMutex()); + GetScriptInterpreterInstances().push_back(instance); + return false; +} + +bool +PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback) +{ + if (!create_callback) + return false; + Mutex::Locker locker(GetScriptInterpreterMutex()); + ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); + + ScriptInterpreterInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++pos) + { + if (pos->create_callback != create_callback) + continue; + + instances.erase(pos); + return true; + } + return false; +} + +ScriptInterpreterCreateInstance +PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) +{ + Mutex::Locker locker(GetScriptInterpreterMutex()); + ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); + if (idx < instances.size()) + return instances[idx].create_callback; + return nullptr; +} + +lldb::ScriptInterpreterSP +PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter) +{ + Mutex::Locker locker(GetScriptInterpreterMutex()); + ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); + + ScriptInterpreterInstances::iterator pos, end = instances.end(); + ScriptInterpreterCreateInstance none_instance = nullptr; + for (pos = instances.begin(); pos != end; ++pos) + { + if (pos->language == lldb::eScriptLanguageNone) + none_instance = pos->create_callback; + + if (script_lang == pos->language) + return pos->create_callback(interpreter); + } + + // If we didn't find one, return the ScriptInterpreter for the null language. + assert(none_instance != nullptr); + return none_instance(interpreter); +} + #pragma mark SymbolFile struct SymbolFileInstance @@ -1771,13 +1983,15 @@ struct SymbolFileInstance SymbolFileInstance() : name(), description(), - create_callback(NULL) + create_callback(nullptr), + debugger_init_callback(nullptr) { } ConstString name; std::string description; SymbolFileCreateInstance create_callback; + DebuggerInitializeCallback debugger_init_callback; }; typedef std::vector<SymbolFileInstance> SymbolFileInstances; @@ -1802,7 +2016,8 @@ PluginManager::RegisterPlugin ( const ConstString &name, const char *description, - SymbolFileCreateInstance create_callback + SymbolFileCreateInstance create_callback, + DebuggerInitializeCallback debugger_init_callback ) { if (create_callback) @@ -1813,6 +2028,7 @@ PluginManager::RegisterPlugin if (description && description[0]) instance.description = description; instance.create_callback = create_callback; + instance.debugger_init_callback = debugger_init_callback; Mutex::Locker locker (GetSymbolFileMutex ()); GetSymbolFileInstances ().push_back (instance); } @@ -2300,6 +2516,270 @@ PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const Const return NULL; } +#pragma mark TypeSystem + + +struct TypeSystemInstance +{ + TypeSystemInstance() : + name(), + description(), + create_callback(NULL) + { + } + + ConstString name; + std::string description; + TypeSystemCreateInstance create_callback; + TypeSystemEnumerateSupportedLanguages enumerate_callback; +}; + +typedef std::vector<TypeSystemInstance> TypeSystemInstances; + +static Mutex & +GetTypeSystemMutex () +{ + static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); + return g_instances_mutex; +} + +static TypeSystemInstances & +GetTypeSystemInstances () +{ + static TypeSystemInstances g_instances; + return g_instances; +} + +bool +PluginManager::RegisterPlugin (const ConstString &name, + const char *description, + TypeSystemCreateInstance create_callback, + TypeSystemEnumerateSupportedLanguages enumerate_supported_languages_callback) +{ + if (create_callback) + { + TypeSystemInstance instance; + assert ((bool)name); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + instance.enumerate_callback = enumerate_supported_languages_callback; + Mutex::Locker locker (GetTypeSystemMutex ()); + GetTypeSystemInstances ().push_back (instance); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback) +{ + if (create_callback) + { + Mutex::Locker locker (GetTypeSystemMutex ()); + TypeSystemInstances &instances = GetTypeSystemInstances (); + + TypeSystemInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == create_callback) + { + instances.erase(pos); + return true; + } + } + } + return false; +} + +TypeSystemCreateInstance +PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx) +{ + Mutex::Locker locker (GetTypeSystemMutex ()); + TypeSystemInstances &instances = GetTypeSystemInstances (); + if (idx < instances.size()) + return instances[idx].create_callback; + return NULL; +} + +TypeSystemCreateInstance +PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name) +{ + if (name) + { + Mutex::Locker locker (GetTypeSystemMutex ()); + TypeSystemInstances &instances = GetTypeSystemInstances (); + + TypeSystemInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (name == pos->name) + return pos->create_callback; + } + } + return NULL; +} + +TypeSystemEnumerateSupportedLanguages +PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx) +{ + Mutex::Locker locker (GetTypeSystemMutex ()); + TypeSystemInstances &instances = GetTypeSystemInstances (); + if (idx < instances.size()) + return instances[idx].enumerate_callback; + return NULL; +} + +TypeSystemEnumerateSupportedLanguages +PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name) +{ + if (name) + { + Mutex::Locker locker (GetTypeSystemMutex ()); + TypeSystemInstances &instances = GetTypeSystemInstances (); + + TypeSystemInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (name == pos->name) + return pos->enumerate_callback; + } + } + return NULL; +} + +#pragma mark REPL + +struct REPLInstance +{ + REPLInstance() : + name(), + description(), + create_callback(NULL) + { + } + + ConstString name; + std::string description; + REPLCreateInstance create_callback; + REPLEnumerateSupportedLanguages enumerate_languages_callback; +}; + +typedef std::vector<REPLInstance> REPLInstances; + +static Mutex & +GetREPLMutex () +{ + static Mutex g_instances_mutex (Mutex::eMutexTypeRecursive); + return g_instances_mutex; +} + +static REPLInstances & +GetREPLInstances () +{ + static REPLInstances g_instances; + return g_instances; +} + +bool +PluginManager::RegisterPlugin (const ConstString &name, + const char *description, + REPLCreateInstance create_callback, + REPLEnumerateSupportedLanguages enumerate_languages_callback) +{ + if (create_callback) + { + REPLInstance instance; + assert ((bool)name); + instance.name = name; + if (description && description[0]) + instance.description = description; + instance.create_callback = create_callback; + instance.enumerate_languages_callback = enumerate_languages_callback; + Mutex::Locker locker (GetREPLMutex ()); + GetREPLInstances ().push_back (instance); + } + return false; +} + +bool +PluginManager::UnregisterPlugin (REPLCreateInstance create_callback) +{ + if (create_callback) + { + Mutex::Locker locker (GetREPLMutex ()); + REPLInstances &instances = GetREPLInstances (); + + REPLInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (pos->create_callback == create_callback) + { + instances.erase(pos); + return true; + } + } + } + return false; +} + +REPLCreateInstance +PluginManager::GetREPLCreateCallbackAtIndex (uint32_t idx) +{ + Mutex::Locker locker (GetREPLMutex ()); + REPLInstances &instances = GetREPLInstances (); + if (idx < instances.size()) + return instances[idx].create_callback; + return NULL; +} + +REPLCreateInstance +PluginManager::GetREPLCreateCallbackForPluginName (const ConstString &name) +{ + if (name) + { + Mutex::Locker locker (GetREPLMutex ()); + REPLInstances &instances = GetREPLInstances (); + + REPLInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (name == pos->name) + return pos->create_callback; + } + } + return NULL; +} + +REPLEnumerateSupportedLanguages +PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx) +{ + Mutex::Locker locker (GetREPLMutex ()); + REPLInstances &instances = GetREPLInstances (); + if (idx < instances.size()) + return instances[idx].enumerate_languages_callback; + return NULL; +} + + +REPLEnumerateSupportedLanguages +PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name) +{ + if (name) + { + Mutex::Locker locker (GetREPLMutex ()); + REPLInstances &instances = GetREPLInstances (); + + REPLInstances::iterator pos, end = instances.end(); + for (pos = instances.begin(); pos != end; ++ pos) + { + if (name == pos->name) + return pos->enumerate_languages_callback; + } + } + return NULL; +} + #pragma mark PluginManager void @@ -2343,7 +2823,7 @@ PluginManager::DebuggerInitialize (Debugger &debugger) pos->debugger_init_callback (debugger); } } - + // Initialize the Process plugins { Mutex::Locker locker (GetProcessMutex()); @@ -2357,6 +2837,25 @@ PluginManager::DebuggerInitialize (Debugger &debugger) } } + // Initialize the SymbolFile plugins + { + Mutex::Locker locker (GetSymbolFileMutex()); + for (auto& sym_file: GetSymbolFileInstances()) + { + if (sym_file.debugger_init_callback) + sym_file.debugger_init_callback (debugger); + } + } + + // Initialize the OperatingSystem plugins + { + Mutex::Locker locker(GetOperatingSystemMutex()); + for (auto &os : GetOperatingSystemInstances()) + { + if (os.debugger_init_callback) + os.debugger_init_callback(debugger); + } + } } // This is the preferred new way to register plugin specific settings. e.g. @@ -2439,32 +2938,40 @@ GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger, return lldb::OptionValuePropertiesSP(); } +namespace { + +typedef lldb::OptionValuePropertiesSP +GetDebuggerPropertyForPluginsPtr (Debugger&, const ConstString&, const ConstString&, bool can_create); lldb::OptionValuePropertiesSP -PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, const ConstString &setting_name) +GetSettingForPlugin (Debugger &debugger, + const ConstString &setting_name, + const ConstString &plugin_type_name, + GetDebuggerPropertyForPluginsPtr get_debugger_property= GetDebuggerPropertyForPlugins) { lldb::OptionValuePropertiesSP properties_sp; - lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, - ConstString("dynamic-loader"), - ConstString(), // not creating to so we don't need the description - false)); + lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property (debugger, + plugin_type_name, + ConstString(), // not creating to so we don't need the description + false)); if (plugin_type_properties_sp) - properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); + properties_sp = plugin_type_properties_sp->GetSubProperty (nullptr, setting_name); return properties_sp; } bool -PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger, - const lldb::OptionValuePropertiesSP &properties_sp, - const ConstString &description, - bool is_global_property) +CreateSettingForPlugin (Debugger &debugger, + const ConstString &plugin_type_name, + const ConstString &plugin_type_desc, + const lldb::OptionValuePropertiesSP &properties_sp, + const ConstString &description, + bool is_global_property, + GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins) { if (properties_sp) { - lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, - ConstString("dynamic-loader"), - ConstString("Settings for dynamic loader plug-ins"), - true)); + lldb::OptionValuePropertiesSP plugin_type_properties_sp (get_debugger_property ( + debugger, plugin_type_name, plugin_type_desc, true)); if (plugin_type_properties_sp) { plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), @@ -2477,56 +2984,65 @@ PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger, return false; } +const char* kDynamicLoaderPluginName("dynamic-loader"); +const char* kPlatformPluginName("platform"); +const char* kProcessPluginName("process"); +const char* kSymbolFilePluginName("symbol-file"); +const char* kJITLoaderPluginName("jit-loader"); + +} lldb::OptionValuePropertiesSP -PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name) +PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger, + const ConstString &setting_name) { - lldb::OptionValuePropertiesSP properties_sp; - lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger, - ConstString("platform"), - ConstString(), // not creating to so we don't need the description - false)); - if (plugin_type_properties_sp) - properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); - return properties_sp; + return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName)); } bool -PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger, +PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, const ConstString &description, bool is_global_property) { - if (properties_sp) - { - lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPluginsOldStyle (debugger, - ConstString("platform"), - ConstString("Settings for platform plug-ins"), - true)); - if (plugin_type_properties_sp) - { - plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), - description, - is_global_property, - properties_sp); - return true; - } - } - return false; + return CreateSettingForPlugin(debugger, + ConstString(kDynamicLoaderPluginName), + ConstString("Settings for dynamic loader plug-ins"), + properties_sp, + description, + is_global_property); +} + + +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForPlatformPlugin (Debugger &debugger, const ConstString &setting_name) +{ + return GetSettingForPlugin(debugger, + setting_name, + ConstString(kPlatformPluginName), + GetDebuggerPropertyForPluginsOldStyle); +} + +bool +PluginManager::CreateSettingForPlatformPlugin (Debugger &debugger, + const lldb::OptionValuePropertiesSP &properties_sp, + const ConstString &description, + bool is_global_property) +{ + return CreateSettingForPlugin(debugger, + ConstString(kPlatformPluginName), + ConstString("Settings for platform plug-ins"), + properties_sp, + description, + is_global_property, + GetDebuggerPropertyForPluginsOldStyle); } lldb::OptionValuePropertiesSP PluginManager::GetSettingForProcessPlugin (Debugger &debugger, const ConstString &setting_name) { - lldb::OptionValuePropertiesSP properties_sp; - lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, - ConstString("process"), - ConstString(), // not creating to so we don't need the description - false)); - if (plugin_type_properties_sp) - properties_sp = plugin_type_properties_sp->GetSubProperty (NULL, setting_name); - return properties_sp; + return GetSettingForPlugin(debugger, setting_name, ConstString(kProcessPluginName)); } bool @@ -2535,21 +3051,87 @@ PluginManager::CreateSettingForProcessPlugin (Debugger &debugger, const ConstString &description, bool is_global_property) { + return CreateSettingForPlugin(debugger, + ConstString(kProcessPluginName), + ConstString("Settings for process plug-ins"), + properties_sp, + description, + is_global_property); +} + +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForSymbolFilePlugin (Debugger &debugger, + const ConstString &setting_name) +{ + return GetSettingForPlugin(debugger, setting_name, ConstString(kSymbolFilePluginName)); +} + +bool +PluginManager::CreateSettingForSymbolFilePlugin (Debugger &debugger, + const lldb::OptionValuePropertiesSP &properties_sp, + const ConstString &description, + bool is_global_property) +{ + return CreateSettingForPlugin(debugger, + ConstString(kSymbolFilePluginName), + ConstString("Settings for symbol file plug-ins"), + properties_sp, + description, + is_global_property); +} + +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForJITLoaderPlugin (Debugger &debugger, + const ConstString &setting_name) +{ + return GetSettingForPlugin(debugger, setting_name, ConstString(kJITLoaderPluginName)); +} + +bool +PluginManager::CreateSettingForJITLoaderPlugin (Debugger &debugger, + const lldb::OptionValuePropertiesSP &properties_sp, + const ConstString &description, + bool is_global_property) +{ + return CreateSettingForPlugin(debugger, + ConstString(kJITLoaderPluginName), + ConstString("Settings for JIT loader plug-ins"), + properties_sp, + description, + is_global_property); +} + +static const char *kOperatingSystemPluginName("os"); + +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, const ConstString &setting_name) +{ + lldb::OptionValuePropertiesSP properties_sp; + lldb::OptionValuePropertiesSP plugin_type_properties_sp( + GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName), + ConstString(), // not creating to so we don't need the description + false)); + if (plugin_type_properties_sp) + properties_sp = plugin_type_properties_sp->GetSubProperty(nullptr, setting_name); + return properties_sp; +} + +bool +PluginManager::CreateSettingForOperatingSystemPlugin(Debugger &debugger, + const lldb::OptionValuePropertiesSP &properties_sp, + const ConstString &description, bool is_global_property) +{ if (properties_sp) { - lldb::OptionValuePropertiesSP plugin_type_properties_sp (GetDebuggerPropertyForPlugins (debugger, - ConstString("process"), - ConstString("Settings for process plug-ins"), - true)); + lldb::OptionValuePropertiesSP plugin_type_properties_sp( + GetDebuggerPropertyForPlugins(debugger, ConstString(kOperatingSystemPluginName), + ConstString("Settings for operating system plug-ins"), true)); if (plugin_type_properties_sp) { - plugin_type_properties_sp->AppendProperty (properties_sp->GetName(), - description, - is_global_property, - properties_sp); + plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), description, is_global_property, + properties_sp); return true; } } return false; } - diff --git a/source/Core/RegisterValue.cpp b/source/Core/RegisterValue.cpp index 272c1eecf9207..d4ba9989c6a9d 100644 --- a/source/Core/RegisterValue.cpp +++ b/source/Core/RegisterValue.cpp @@ -119,7 +119,7 @@ RegisterValue::GetAsMemoryData (const RegisterInfo *reg_info, return 0; } - // ReadRegister should have already been called on tgus object prior to + // ReadRegister should have already been called on this object prior to // calling this. if (GetType() == eTypeInvalid) { @@ -215,10 +215,10 @@ RegisterValue::SetFromMemoryData (const RegisterInfo *reg_info, } else if (value_type == eTypeBytes) { - m_data.buffer.byte_order = src_byte_order; + buffer.byte_order = src_byte_order; // Make sure to set the buffer length of the destination buffer to avoid - // problems due to uninitalized variables. - m_data.buffer.length = src_len; + // problems due to uninitialized variables. + buffer.length = src_len; } const uint32_t bytes_copied = src_data.CopyByteOrderedData (0, // src offset @@ -240,25 +240,23 @@ RegisterValue::GetScalarValue (Scalar &scalar) const case eTypeInvalid: break; case eTypeBytes: { - switch (m_data.buffer.length) + switch (buffer.length) { default: break; - case 1: scalar = m_data.uint8; return true; - case 2: scalar = m_data.uint16; return true; - case 4: scalar = m_data.uint32; return true; - case 8: scalar = m_data.uint64; return true; + case 1: scalar = *(const uint8_t *)buffer.bytes; return true; + case 2: scalar = *(const uint16_t *)buffer.bytes; return true; + case 4: scalar = *(const uint32_t *)buffer.bytes; return true; + case 8: scalar = *(const uint64_t *)buffer.bytes; return true; } } - case eTypeUInt8: scalar = m_data.uint8; return true; - case eTypeUInt16: scalar = m_data.uint16; return true; - case eTypeUInt32: scalar = m_data.uint32; return true; - case eTypeUInt64: scalar = m_data.uint64; return true; -#if defined (ENABLE_128_BIT_SUPPORT) - case eTypeUInt128: break; -#endif - case eTypeFloat: scalar = m_data.ieee_float; return true; - case eTypeDouble: scalar = m_data.ieee_double; return true; - case eTypeLongDouble: scalar = m_data.ieee_long_double; return true; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: + case eTypeUInt64: + case eTypeUInt128: + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: scalar = m_scalar; return true; } return false; } @@ -289,10 +287,8 @@ RegisterValue::SetType (const RegisterInfo *reg_info) m_type = eTypeUInt32; else if (byte_size <= 8) m_type = eTypeUInt64; -#if defined (ENABLE_128_BIT_SUPPORT) else if (byte_size <= 16) m_type = eTypeUInt128; -#endif break; case eEncodingIEEE754: @@ -308,6 +304,7 @@ RegisterValue::SetType (const RegisterInfo *reg_info) m_type = eTypeBytes; break; } + m_scalar.SetType(reg_info); return m_type; } @@ -342,8 +339,9 @@ RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &sr src_len = reg_info->byte_size; // Zero out the value in case we get partial data... - memset (m_data.buffer.bytes, 0, sizeof (m_data.buffer.bytes)); - + memset (buffer.bytes, 0, sizeof (buffer.bytes)); + + type128 int128; switch (SetType (reg_info)) { case eTypeInvalid: @@ -353,33 +351,38 @@ RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &sr case eTypeUInt16: SetUInt16 (src.GetMaxU32 (&src_offset, src_len)); break; case eTypeUInt32: SetUInt32 (src.GetMaxU32 (&src_offset, src_len)); break; case eTypeUInt64: SetUInt64 (src.GetMaxU64 (&src_offset, src_len)); break; -#if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: { - __uint128_t data1 = src.GetU64 (&src_offset); - __uint128_t data2 = src.GetU64 (&src_offset); + uint64_t data1 = src.GetU64 (&src_offset); + uint64_t data2 = src.GetU64 (&src_offset); if (src.GetByteSize() == eByteOrderBig) - SetUInt128 (data1 << 64 + data2); + { + int128.x[0] = data1; + int128.x[1] = data2; + } else - SetUInt128 (data2 << 64 + data1); + { + int128.x[0] = data2; + int128.x[1] = data1; + } + SetUInt128 (llvm::APInt(128, 2, int128.x)); } break; -#endif case eTypeFloat: SetFloat (src.GetFloat (&src_offset)); break; case eTypeDouble: SetDouble(src.GetDouble (&src_offset)); break; case eTypeLongDouble: SetFloat (src.GetLongDouble (&src_offset)); break; case eTypeBytes: { - m_data.buffer.length = reg_info->byte_size; - m_data.buffer.byte_order = src.GetByteOrder(); - assert (m_data.buffer.length <= kMaxRegisterByteSize); - if (m_data.buffer.length > kMaxRegisterByteSize) - m_data.buffer.length = kMaxRegisterByteSize; + buffer.length = reg_info->byte_size; + buffer.byte_order = src.GetByteOrder(); + assert (buffer.length <= kMaxRegisterByteSize); + if (buffer.length > kMaxRegisterByteSize) + buffer.length = kMaxRegisterByteSize; if (src.CopyByteOrderedData (src_offset, // offset within "src" to start extracting data src_len, // src length - m_data.buffer.bytes, // dst buffer - m_data.buffer.length, // dst length - m_data.buffer.byte_order) == 0)// dst byte order + buffer.bytes, // dst buffer + buffer.length, // dst length + buffer.byte_order) == 0)// dst byte order { error.SetErrorString ("data copy failed data."); return error; @@ -459,6 +462,9 @@ RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *va } bool success = false; const uint32_t byte_size = reg_info->byte_size; + static float flt_val; + static double dbl_val; + static long double ldbl_val; switch (reg_info->encoding) { case eEncodingInvalid: @@ -510,22 +516,31 @@ RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *va case eEncodingIEEE754: if (byte_size == sizeof (float)) { - if (::sscanf (value_str, "%f", &m_data.ieee_float) == 1) + if (::sscanf (value_str, "%f", &flt_val) == 1) + { + m_scalar = flt_val; m_type = eTypeFloat; + } else error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str); } else if (byte_size == sizeof (double)) { - if (::sscanf (value_str, "%lf", &m_data.ieee_double) == 1) + if (::sscanf (value_str, "%lf", &dbl_val) == 1) + { + m_scalar = dbl_val; m_type = eTypeDouble; + } 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", &m_data.ieee_long_double) == 1) + if (::sscanf (value_str, "%Lf", &ldbl_val) == 1) + { + m_scalar = ldbl_val; m_type = eTypeLongDouble; + } else error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str); } @@ -557,81 +572,11 @@ RegisterValue::SignExtend (uint32_t sign_bitpos) break; case eTypeUInt8: - if (sign_bitpos == (8-1)) - return true; - else if (sign_bitpos < (8-1)) - { - uint8_t sign_bit = 1u << sign_bitpos; - if (m_data.uint8 & sign_bit) - { - const uint8_t mask = ~(sign_bit) + 1u; - m_data.uint8 |= mask; - } - return true; - } - break; - case eTypeUInt16: - if (sign_bitpos == (16-1)) - return true; - else if (sign_bitpos < (16-1)) - { - uint16_t sign_bit = 1u << sign_bitpos; - if (m_data.uint16 & sign_bit) - { - const uint16_t mask = ~(sign_bit) + 1u; - m_data.uint16 |= mask; - } - return true; - } - break; - case eTypeUInt32: - if (sign_bitpos == (32-1)) - return true; - else if (sign_bitpos < (32-1)) - { - uint32_t sign_bit = 1u << sign_bitpos; - if (m_data.uint32 & sign_bit) - { - const uint32_t mask = ~(sign_bit) + 1u; - m_data.uint32 |= mask; - } - return true; - } - break; - case eTypeUInt64: - if (sign_bitpos == (64-1)) - return true; - else if (sign_bitpos < (64-1)) - { - uint64_t sign_bit = 1ull << sign_bitpos; - if (m_data.uint64 & sign_bit) - { - const uint64_t mask = ~(sign_bit) + 1ull; - m_data.uint64 |= mask; - } - return true; - } - break; - -#if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: - if (sign_bitpos == (128-1)) - return true; - else if (sign_bitpos < (128-1)) - { - __uint128_t sign_bit = (__uint128_t)1u << sign_bitpos; - if (m_data.uint128 & sign_bit) - { - const uint128_t mask = ~(sign_bit) + 1u; - m_data.uint128 |= mask; - } - return true; - } - break; -#endif + return m_scalar.SignExtend(sign_bitpos); case eTypeFloat: case eTypeDouble: case eTypeLongDouble: @@ -649,21 +594,19 @@ RegisterValue::CopyValue (const RegisterValue &rhs) { case eTypeInvalid: return false; - case eTypeUInt8: m_data.uint8 = rhs.m_data.uint8; break; - case eTypeUInt16: m_data.uint16 = rhs.m_data.uint16; break; - case eTypeUInt32: m_data.uint32 = rhs.m_data.uint32; break; - case eTypeUInt64: m_data.uint64 = rhs.m_data.uint64; break; -#if defined (ENABLE_128_BIT_SUPPORT) - case eTypeUInt128: m_data.uint128 = rhs.m_data.uint128; break; -#endif - case eTypeFloat: m_data.ieee_float = rhs.m_data.ieee_float; break; - case eTypeDouble: m_data.ieee_double = rhs.m_data.ieee_double; break; - case eTypeLongDouble: m_data.ieee_long_double = rhs.m_data.ieee_long_double; break; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: + case eTypeUInt64: + case eTypeUInt128: + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: m_scalar = rhs.m_scalar; break; case eTypeBytes: - assert (rhs.m_data.buffer.length <= kMaxRegisterByteSize); - ::memcpy (m_data.buffer.bytes, rhs.m_data.buffer.bytes, kMaxRegisterByteSize); - m_data.buffer.length = rhs.m_data.buffer.length; - m_data.buffer.byte_order = rhs.m_data.buffer.byte_order; + assert (rhs.buffer.length <= kMaxRegisterByteSize); + ::memcpy (buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize); + buffer.length = rhs.buffer.length; + buffer.byte_order = rhs.buffer.byte_order; break; } return true; @@ -678,15 +621,15 @@ RegisterValue::GetAsUInt16 (uint16_t fail_value, bool *success_ptr) const switch (m_type) { default: break; - case eTypeUInt8: return m_data.uint8; - case eTypeUInt16: return m_data.uint16; + case eTypeUInt8: + case eTypeUInt16: return m_scalar.UShort(fail_value); case eTypeBytes: { - switch (m_data.buffer.length) + switch (buffer.length) { default: break; - case 1: return m_data.uint8; - case 2: return m_data.uint16; + case 1: + case 2: return *(const uint16_t *)buffer.bytes; } } break; @@ -704,29 +647,20 @@ RegisterValue::GetAsUInt32 (uint32_t fail_value, bool *success_ptr) const switch (m_type) { default: break; - case eTypeUInt8: return m_data.uint8; - case eTypeUInt16: return m_data.uint16; - case eTypeUInt32: return m_data.uint32; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: case eTypeFloat: - if (sizeof(float) == sizeof(uint32_t)) - return m_data.uint32; - break; case eTypeDouble: - if (sizeof(double) == sizeof(uint32_t)) - return m_data.uint32; - break; - case eTypeLongDouble: - if (sizeof(long double) == sizeof(uint32_t)) - return m_data.uint32; - break; + case eTypeLongDouble: return m_scalar.UInt(fail_value); case eTypeBytes: { - switch (m_data.buffer.length) + switch (buffer.length) { default: break; - case 1: return m_data.uint8; - case 2: return m_data.uint16; - case 4: return m_data.uint32; + case 1: + case 2: + case 4: return *(const uint32_t *)buffer.bytes; } } break; @@ -744,31 +678,22 @@ RegisterValue::GetAsUInt64 (uint64_t fail_value, bool *success_ptr) const switch (m_type) { default: break; - case eTypeUInt8: return m_data.uint8; - case eTypeUInt16: return m_data.uint16; - case eTypeUInt32: return m_data.uint32; - case eTypeUInt64: return m_data.uint64; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: + case eTypeUInt64: case eTypeFloat: - if (sizeof(float) == sizeof(uint64_t)) - return m_data.uint64; - break; case eTypeDouble: - if (sizeof(double) == sizeof(uint64_t)) - return m_data.uint64; - break; - case eTypeLongDouble: - if (sizeof(long double) == sizeof(uint64_t)) - return m_data.uint64; - break; + case eTypeLongDouble: return m_scalar.ULongLong(fail_value); case eTypeBytes: { - switch (m_data.buffer.length) + switch (buffer.length) { default: break; - case 1: return m_data.uint8; - case 2: return m_data.uint16; - case 4: return m_data.uint32; - case 8: return m_data.uint64; + case 1: + case 2: + case 4: + case 8: return *(const uint64_t *)buffer.bytes; } } break; @@ -778,43 +703,36 @@ RegisterValue::GetAsUInt64 (uint64_t fail_value, bool *success_ptr) const return fail_value; } -#if defined (ENABLE_128_BIT_SUPPORT) -__uint128_t -RegisterValue::GetAsUInt128 (__uint128_t fail_value, bool *success_ptr) const +llvm::APInt +RegisterValue::GetAsUInt128 (const llvm::APInt& fail_value, bool *success_ptr) const { if (success_ptr) *success_ptr = true; switch (m_type) { default: break; - case eTypeUInt8: return m_data.uint8; - case eTypeUInt16: return m_data.uint16; - case eTypeUInt32: return m_data.uint32; - case eTypeUInt64: return m_data.uint64; - case eTypeUInt128: return m_data.uint128; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: + case eTypeUInt64: + case eTypeUInt128: case eTypeFloat: - if (sizeof(float) == sizeof(__uint128_t)) - return m_data.uint128; - break; case eTypeDouble: - if (sizeof(double) == sizeof(__uint128_t)) - return m_data.uint128; - break; - case eTypeLongDouble: - if (sizeof(long double) == sizeof(__uint128_t)) - return m_data.uint128; - break; + case eTypeLongDouble: return m_scalar.UInt128(fail_value); case eTypeBytes: { - switch (m_data.buffer.length) + switch (buffer.length) { - default: - break; - case 1: return m_data.uint8; - case 2: return m_data.uint16; - case 4: return m_data.uint32; - case 8: return m_data.uint64; - case 16: return m_data.uint128; + default: + break; + case 1: + case 2: + case 4: + case 8: + case 16: + { + return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)buffer.bytes)->x); + } } } break; @@ -823,7 +741,7 @@ RegisterValue::GetAsUInt128 (__uint128_t fail_value, bool *success_ptr) const *success_ptr = false; return fail_value; } -#endif + float RegisterValue::GetAsFloat (float fail_value, bool *success_ptr) const { @@ -833,28 +751,12 @@ RegisterValue::GetAsFloat (float fail_value, bool *success_ptr) const { default: break; case eTypeUInt32: - if (sizeof(float) == sizeof(m_data.uint32)) - return m_data.ieee_float; - break; case eTypeUInt64: - if (sizeof(float) == sizeof(m_data.uint64)) - return m_data.ieee_float; - break; -#if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: - if (sizeof(float) == sizeof(m_data.uint128)) - return m_data.ieee_float; - break; -#endif - case eTypeFloat: return m_data.ieee_float; + case eTypeFloat: case eTypeDouble: - if (sizeof(float) == sizeof(double)) - return m_data.ieee_float; - break; case eTypeLongDouble: - if (sizeof(float) == sizeof(long double)) - return m_data.ieee_float; - break; + return m_scalar.Float(fail_value); } if (success_ptr) *success_ptr = false; @@ -872,27 +774,12 @@ RegisterValue::GetAsDouble (double fail_value, bool *success_ptr) const break; case eTypeUInt32: - if (sizeof(double) == sizeof(m_data.uint32)) - return m_data.ieee_double; - break; - case eTypeUInt64: - if (sizeof(double) == sizeof(m_data.uint64)) - return m_data.ieee_double; - break; - -#if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: - if (sizeof(double) == sizeof(m_data.uint128)) - return m_data.ieee_double; -#endif - case eTypeFloat: return m_data.ieee_float; - case eTypeDouble: return m_data.ieee_double; - + case eTypeFloat: + case eTypeDouble: case eTypeLongDouble: - if (sizeof(double) == sizeof(long double)) - return m_data.ieee_double; - break; + return m_scalar.Double(fail_value); } if (success_ptr) *success_ptr = false; @@ -910,24 +797,12 @@ RegisterValue::GetAsLongDouble (long double fail_value, bool *success_ptr) const break; case eTypeUInt32: - if (sizeof(long double) == sizeof(m_data.uint32)) - return m_data.ieee_long_double; - break; - case eTypeUInt64: - if (sizeof(long double) == sizeof(m_data.uint64)) - return m_data.ieee_long_double; - break; - -#if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: - if (sizeof(long double) == sizeof(m_data.uint128)) - return m_data.ieee_long_double; -#endif - case eTypeFloat: return m_data.ieee_float; - case eTypeDouble: return m_data.ieee_double; - case eTypeLongDouble: return m_data.ieee_long_double; - break; + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: + return m_scalar.LongDouble(); } if (success_ptr) *success_ptr = false; @@ -940,17 +815,15 @@ RegisterValue::GetBytes () const switch (m_type) { case eTypeInvalid: break; - case eTypeUInt8: return &m_data.uint8; - case eTypeUInt16: return &m_data.uint16; - case eTypeUInt32: return &m_data.uint32; - case eTypeUInt64: return &m_data.uint64; -#if defined (ENABLE_128_BIT_SUPPORT) - case eTypeUInt128: return &m_data.uint128; -#endif - case eTypeFloat: return &m_data.ieee_float; - case eTypeDouble: return &m_data.ieee_double; - case eTypeLongDouble: return &m_data.ieee_long_double; - case eTypeBytes: return m_data.buffer.bytes; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: + case eTypeUInt64: + case eTypeUInt128: + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: return m_scalar.GetBytes(); + case eTypeBytes: return buffer.bytes; } return NULL; } @@ -961,17 +834,15 @@ RegisterValue::GetBytes () switch (m_type) { case eTypeInvalid: break; - case eTypeUInt8: return &m_data.uint8; - case eTypeUInt16: return &m_data.uint16; - case eTypeUInt32: return &m_data.uint32; - case eTypeUInt64: return &m_data.uint64; -#if defined (ENABLE_128_BIT_SUPPORT) - case eTypeUInt128: return &m_data.uint128; -#endif - case eTypeFloat: return &m_data.ieee_float; - case eTypeDouble: return &m_data.ieee_double; - case eTypeLongDouble: return &m_data.ieee_long_double; - case eTypeBytes: return m_data.buffer.bytes; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: + case eTypeUInt64: + case eTypeUInt128: + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: return m_scalar.GetBytes(); + case eTypeBytes: return buffer.bytes; } return NULL; } @@ -982,17 +853,15 @@ RegisterValue::GetByteSize () const switch (m_type) { case eTypeInvalid: break; - case eTypeUInt8: return sizeof(m_data.uint8); - case eTypeUInt16: return sizeof(m_data.uint16); - case eTypeUInt32: return sizeof(m_data.uint32); - case eTypeUInt64: return sizeof(m_data.uint64); -#if defined (ENABLE_128_BIT_SUPPORT) - case eTypeUInt128: return sizeof(m_data.uint128); -#endif - case eTypeFloat: return sizeof(m_data.ieee_float); - case eTypeDouble: return sizeof(m_data.ieee_double); - case eTypeLongDouble: return sizeof(m_data.ieee_long_double); - case eTypeBytes: return m_data.buffer.length; + case eTypeUInt8: return 1; + case eTypeUInt16: return 2; + case eTypeUInt32: + case eTypeUInt64: + case eTypeUInt128: + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: return m_scalar.GetByteSize(); + case eTypeBytes: return buffer.length; } return 0; } @@ -1021,12 +890,10 @@ RegisterValue::SetUInt (uint64_t uint, uint32_t byte_size) { SetUInt64 (uint); } -#if defined (ENABLE_128_BIT_SUPPORT) else if (byte_size <= 16) { - SetUInt128 (uint); + SetUInt128 (llvm::APInt(128, uint)); } -#endif else return false; return true; @@ -1036,21 +903,21 @@ void RegisterValue::SetBytes (const void *bytes, size_t length, lldb::ByteOrder byte_order) { // If this assertion fires off we need to increase the size of - // m_data.buffer.bytes, or make it something that is allocated on + // buffer.bytes, or make it something that is allocated on // the heap. Since the data buffer is in a union, we can't make it // a collection class like SmallVector... if (bytes && length > 0) { - assert (length <= sizeof (m_data.buffer.bytes) && "Storing too many bytes in a RegisterValue."); + assert (length <= sizeof (buffer.bytes) && "Storing too many bytes in a RegisterValue."); m_type = eTypeBytes; - m_data.buffer.length = length; - memcpy (m_data.buffer.bytes, bytes, length); - m_data.buffer.byte_order = byte_order; + buffer.length = length; + memcpy (buffer.bytes, bytes, length); + buffer.byte_order = byte_order; } else { m_type = eTypeInvalid; - m_data.buffer.length = 0; + buffer.length = 0; } } @@ -1063,25 +930,23 @@ RegisterValue::operator == (const RegisterValue &rhs) const switch (m_type) { case eTypeInvalid: return true; - case eTypeUInt8: return m_data.uint8 == rhs.m_data.uint8; - case eTypeUInt16: return m_data.uint16 == rhs.m_data.uint16; - case eTypeUInt32: return m_data.uint32 == rhs.m_data.uint32; - case eTypeUInt64: return m_data.uint64 == rhs.m_data.uint64; -#if defined (ENABLE_128_BIT_SUPPORT) - case eTypeUInt128: return m_data.uint128 == rhs.m_data.uint128; -#endif - case eTypeFloat: return m_data.ieee_float == rhs.m_data.ieee_float; - case eTypeDouble: return m_data.ieee_double == rhs.m_data.ieee_double; - case eTypeLongDouble: return m_data.ieee_long_double == rhs.m_data.ieee_long_double; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: + case eTypeUInt64: + case eTypeUInt128: + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: return m_scalar == rhs.m_scalar; case eTypeBytes: - if (m_data.buffer.length != rhs.m_data.buffer.length) + if (buffer.length != rhs.buffer.length) return false; else { - uint8_t length = m_data.buffer.length; + uint8_t length = buffer.length; if (length > kMaxRegisterByteSize) length = kMaxRegisterByteSize; - return memcmp (m_data.buffer.bytes, rhs.m_data.buffer.bytes, length) == 0; + return memcmp (buffer.bytes, rhs.buffer.bytes, length) == 0; } break; } @@ -1097,27 +962,25 @@ RegisterValue::operator != (const RegisterValue &rhs) const switch (m_type) { case eTypeInvalid: return false; - case eTypeUInt8: return m_data.uint8 != rhs.m_data.uint8; - case eTypeUInt16: return m_data.uint16 != rhs.m_data.uint16; - case eTypeUInt32: return m_data.uint32 != rhs.m_data.uint32; - case eTypeUInt64: return m_data.uint64 != rhs.m_data.uint64; -#if defined (ENABLE_128_BIT_SUPPORT) - case eTypeUInt128: return m_data.uint128 != rhs.m_data.uint128; -#endif - case eTypeFloat: return m_data.ieee_float != rhs.m_data.ieee_float; - case eTypeDouble: return m_data.ieee_double != rhs.m_data.ieee_double; - case eTypeLongDouble: return m_data.ieee_long_double != rhs.m_data.ieee_long_double; + case eTypeUInt8: + case eTypeUInt16: + case eTypeUInt32: + case eTypeUInt64: + case eTypeUInt128: + case eTypeFloat: + case eTypeDouble: + case eTypeLongDouble: return m_scalar != rhs.m_scalar; case eTypeBytes: - if (m_data.buffer.length != rhs.m_data.buffer.length) + if (buffer.length != rhs.buffer.length) { return true; } else { - uint8_t length = m_data.buffer.length; + uint8_t length = buffer.length; if (length > kMaxRegisterByteSize) length = kMaxRegisterByteSize; - return memcmp (m_data.buffer.bytes, rhs.m_data.buffer.bytes, length) != 0; + return memcmp (buffer.bytes, rhs.buffer.bytes, length) != 0; } break; } @@ -1132,63 +995,35 @@ RegisterValue::ClearBit (uint32_t bit) case eTypeInvalid: break; - case eTypeUInt8: - if (bit < 8) - { - m_data.uint8 &= ~(1u << bit); - return true; - } - break; - + case eTypeUInt8: case eTypeUInt16: - if (bit < 16) - { - m_data.uint16 &= ~(1u << bit); - return true; - } - break; - case eTypeUInt32: - if (bit < 32) - { - m_data.uint32 &= ~(1u << bit); - return true; - } - break; - case eTypeUInt64: - if (bit < 64) - { - m_data.uint64 &= ~(1ull << (uint64_t)bit); - return true; - } - break; -#if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: - if (bit < 64) + if (bit < (GetByteSize() * 8)) { - m_data.uint128 &= ~((__uint128_t)1ull << (__uint128_t)bit); - return true; + return m_scalar.ClearBit(bit); } -#endif + break; + case eTypeFloat: case eTypeDouble: case eTypeLongDouble: break; case eTypeBytes: - if (m_data.buffer.byte_order == eByteOrderBig || m_data.buffer.byte_order == eByteOrderLittle) + if (buffer.byte_order == eByteOrderBig || buffer.byte_order == eByteOrderLittle) { uint32_t byte_idx; - if (m_data.buffer.byte_order == eByteOrderBig) - byte_idx = m_data.buffer.length - (bit / 8) - 1; + if (buffer.byte_order == eByteOrderBig) + byte_idx = buffer.length - (bit / 8) - 1; else byte_idx = bit / 8; const uint32_t byte_bit = bit % 8; - if (byte_idx < m_data.buffer.length) + if (byte_idx < buffer.length) { - m_data.buffer.bytes[byte_idx] &= ~(1u << byte_bit); + buffer.bytes[byte_idx] &= ~(1u << byte_bit); return true; } } @@ -1207,62 +1042,34 @@ RegisterValue::SetBit (uint32_t bit) break; case eTypeUInt8: - if (bit < 8) - { - m_data.uint8 |= (1u << bit); - return true; - } - break; - case eTypeUInt16: - if (bit < 16) - { - m_data.uint16 |= (1u << bit); - return true; - } - break; - case eTypeUInt32: - if (bit < 32) - { - m_data.uint32 |= (1u << bit); - return true; - } - break; - case eTypeUInt64: - if (bit < 64) - { - m_data.uint64 |= (1ull << (uint64_t)bit); - return true; - } - break; -#if defined (ENABLE_128_BIT_SUPPORT) case eTypeUInt128: - if (bit < 64) + if (bit < (GetByteSize() * 8)) { - m_data.uint128 |= ((__uint128_t)1ull << (__uint128_t)bit); - return true; + return m_scalar.SetBit(bit); } -#endif + break; + case eTypeFloat: case eTypeDouble: case eTypeLongDouble: break; case eTypeBytes: - if (m_data.buffer.byte_order == eByteOrderBig || m_data.buffer.byte_order == eByteOrderLittle) + if (buffer.byte_order == eByteOrderBig || buffer.byte_order == eByteOrderLittle) { uint32_t byte_idx; - if (m_data.buffer.byte_order == eByteOrderBig) - byte_idx = m_data.buffer.length - (bit / 8) - 1; + if (buffer.byte_order == eByteOrderBig) + byte_idx = buffer.length - (bit / 8) - 1; else byte_idx = bit / 8; const uint32_t byte_bit = bit % 8; - if (byte_idx < m_data.buffer.length) + if (byte_idx < buffer.length) { - m_data.buffer.bytes[byte_idx] |= (1u << byte_bit); + buffer.bytes[byte_idx] |= (1u << byte_bit); return true; } } diff --git a/source/Core/RegularExpression.cpp b/source/Core/RegularExpression.cpp index 3f712e1b2daa7..767521500af8a 100644 --- a/source/Core/RegularExpression.cpp +++ b/source/Core/RegularExpression.cpp @@ -153,7 +153,7 @@ RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, std::str llvm::StringRef match_str_ref; if (GetMatchAtIndex(s, idx, match_str_ref)) { - match_str = std::move(match_str_ref.str()); + match_str = match_str_ref.str(); return true; } return false; @@ -258,4 +258,3 @@ RegularExpression::operator < (const RegularExpression& rhs) const { return (m_re < rhs.m_re); } - diff --git a/source/Core/Scalar.cpp b/source/Core/Scalar.cpp index 0022c348bfeec..586969b2d50a3 100644 --- a/source/Core/Scalar.cpp +++ b/source/Core/Scalar.cpp @@ -11,6 +11,7 @@ #include <math.h> #include <inttypes.h> +#include <stdio.h> #include "lldb/Interpreter/Args.h" #include "lldb/Core/Error.h" @@ -77,7 +78,7 @@ PromoteToMaxType //---------------------------------------------------------------------- Scalar::Scalar() : m_type(e_void), - m_data() + m_float((float)0) { } @@ -86,7 +87,8 @@ Scalar::Scalar() : //---------------------------------------------------------------------- Scalar::Scalar(const Scalar& rhs) : m_type(rhs.m_type), - m_data(rhs.m_data) // TODO: verify that for C++ this will correctly copy the union?? + m_integer(rhs.m_integer), + m_float(rhs.m_float) { } @@ -135,29 +137,109 @@ bool Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const { size_t byte_size = GetByteSize(); + static float f_val; + static double d_val; if (byte_size > 0) { if (limit_byte_size < byte_size) { - if (lldb::endian::InlHostByteOrder() == eByteOrderLittle) + 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... - data.SetData((uint8_t*)&m_data, limit_byte_size, lldb::endian::InlHostByteOrder()); + 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: + data.SetData((const uint8_t *)m_integer.getRawData(), limit_byte_size, endian::InlHostByteOrder()); + return true; + case e_float: + f_val = m_float.convertToFloat(); + data.SetData((uint8_t *)&f_val, limit_byte_size, endian::InlHostByteOrder()); + return true; + case e_double: + d_val = m_float.convertToDouble(); + data.SetData((uint8_t *)&d_val, limit_byte_size, endian::InlHostByteOrder()); + return true; + case e_long_double: + static llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + data.SetData((const uint8_t *)ldbl_val.getRawData(), limit_byte_size, endian::InlHostByteOrder()); + return true; + } } - else if (lldb::endian::InlHostByteOrder() == eByteOrderBig) + 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 - data.SetData(((uint8_t*)&m_data) + byte_size - limit_byte_size, limit_byte_size, lldb::endian::InlHostByteOrder()); + 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: + data.SetData((const uint8_t *)m_integer.getRawData() + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder()); + return true; + case e_float: + f_val = m_float.convertToFloat(); + data.SetData((uint8_t *)&f_val + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder()); + return true; + case e_double: + d_val = m_float.convertToDouble(); + data.SetData((uint8_t *)&d_val + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder()); + return true; + case e_long_double: + static llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + data.SetData((const uint8_t *)ldbl_val.getRawData() + byte_size - limit_byte_size, limit_byte_size, endian::InlHostByteOrder()); + return true; + } } } else { // We want all of the data - data.SetData((uint8_t*)&m_data, byte_size, lldb::endian::InlHostByteOrder()); + 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: + data.SetData((const uint8_t *)m_integer.getRawData(), byte_size, endian::InlHostByteOrder()); + return true; + case e_float: + f_val = m_float.convertToFloat(); + data.SetData((uint8_t *)&f_val, byte_size, endian::InlHostByteOrder()); + return true; + case e_double: + d_val = m_float.convertToDouble(); + data.SetData((uint8_t *)&d_val, byte_size, endian::InlHostByteOrder()); + return true; + case e_long_double: + static llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + data.SetData((const uint8_t *)ldbl_val.getRawData(), byte_size, endian::InlHostByteOrder()); + return true; + } } return true; } @@ -165,6 +247,37 @@ Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const return false; } +void * +Scalar::GetBytes() const +{ + static float_t flt_val; + static double_t dbl_val; + 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: + return const_cast<void *>(reinterpret_cast<const void *>(m_integer.getRawData())); + case e_float: + flt_val = m_float.convertToFloat(); + return (void *)&flt_val; + case e_double: + dbl_val = m_float.convertToDouble(); + return (void *)&dbl_val; + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return const_cast<void *>(reinterpret_cast<const void *>(ldbl_val.getRawData())); + } + return NULL; +} + size_t Scalar::GetByteSize() const { @@ -172,15 +285,17 @@ Scalar::GetByteSize() const { case e_void: break; - case e_sint: return sizeof(m_data.sint); - case e_uint: return sizeof(m_data.uint); - case e_slong: return sizeof(m_data.slong); - case e_ulong: return sizeof(m_data.ulong); - case e_slonglong: return sizeof(m_data.slonglong); - case e_ulonglong: return sizeof(m_data.ulonglong); - case e_float: return sizeof(m_data.flt); - case e_double: return sizeof(m_data.dbl); - case e_long_double: return sizeof(m_data.ldbl); + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: return (m_integer.getBitWidth() / 8); + case e_float: return sizeof(float_t); + case e_double: return sizeof(double_t); + case e_long_double: return sizeof(long_double_t); } return 0; } @@ -188,19 +303,24 @@ Scalar::GetByteSize() const bool Scalar::IsZero() const { + llvm::APInt zero_int = llvm::APInt::getNullValue(m_integer.getBitWidth() / 8); switch (m_type) { case e_void: break; - case e_sint: return m_data.sint == 0; - case e_uint: return m_data.uint == 0; - case e_slong: return m_data.slong == 0; - case e_ulong: return m_data.ulong == 0; - case e_slonglong: return m_data.slonglong == 0; - case e_ulonglong: return m_data.ulonglong == 0; - case e_float: return m_data.flt == 0.0f; - case e_double: return m_data.dbl == 0.0; - case e_long_double: return m_data.ldbl == 0.0; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return llvm::APInt::isSameValue(zero_int, m_integer); + case e_float: + case e_double: + case e_long_double: + return m_float.isZero(); } return false; } @@ -208,6 +328,7 @@ Scalar::IsZero() const void Scalar::GetValue (Stream *s, bool show_type) const { + const uint64_t *src; if (show_type) s->Printf("(%s) ", GetTypeAsCString()); @@ -215,15 +336,26 @@ Scalar::GetValue (Stream *s, bool show_type) const { case e_void: break; - case e_sint: s->Printf("%i", m_data.sint); break; - case e_uint: s->Printf("0x%8.8x", m_data.uint); break; - case e_slong: s->Printf("%li", m_data.slong); break; - case e_ulong: s->Printf("0x%8.8lx", m_data.ulong); break; - case e_slonglong: s->Printf("%lli", m_data.slonglong); break; - case e_ulonglong: s->Printf("0x%16.16llx", m_data.ulonglong); break; - case e_float: s->Printf("%f", m_data.flt); break; - case e_double: s->Printf("%g", m_data.dbl); break; - case e_long_double: s->Printf("%Lg", m_data.ldbl); break; + case e_sint: s->Printf("%i", *(const sint_t *) m_integer.getRawData()); break; + case e_uint: s->Printf("0x%8.8x", *(const uint_t *) m_integer.getRawData()); break; + case e_slong: s->Printf("%li", *(const slong_t *) m_integer.getRawData()); break; + case e_ulong: s->Printf("0x%8.8lx", *(const ulong_t *) m_integer.getRawData()); break; + case e_slonglong: s->Printf("%lli", *(const slonglong_t *) m_integer.getRawData()); break; + case e_ulonglong: s->Printf("0x%16.16llx", *(const ulonglong_t *) m_integer.getRawData()); break; + case e_sint128: + src = m_integer.getRawData(); + s->Printf("%lli%lli", *(const slonglong_t *)src, *(const slonglong_t *)(src + 1)); + break; + case e_uint128: + src = m_integer.getRawData(); + s->Printf("0x%16.16llx%16.16llx", *(const ulonglong_t *)src, *(const ulonglong_t *)(src + 1)); + break; + case e_float: s->Printf("%f", m_float.convertToFloat()); break; + case e_double: s->Printf("%g", m_float.convertToDouble()); break; + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + s->Printf("%Lg", *(const long_double_t *)ldbl_val.getRawData()); + break; } } @@ -239,6 +371,8 @@ Scalar::GetTypeAsCString() const 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_float: return "float"; case e_double: return "double"; case e_long_double: return "long double"; @@ -257,7 +391,8 @@ Scalar::operator=(const Scalar& rhs) if (this != &rhs) { m_type = rhs.m_type; - ::memcpy (&m_data, &rhs.m_data, sizeof(m_data)); + m_integer = llvm::APInt(rhs.m_integer); + m_float = rhs.m_float; } return *this; } @@ -266,7 +401,7 @@ Scalar& Scalar::operator= (const int v) { m_type = e_sint; - m_data.sint = v; + m_integer = llvm::APInt(sizeof(int) * 8, v, true); return *this; } @@ -275,7 +410,7 @@ Scalar& Scalar::operator= (unsigned int v) { m_type = e_uint; - m_data.uint = v; + m_integer = llvm::APInt(sizeof(int) * 8, v); return *this; } @@ -283,7 +418,7 @@ Scalar& Scalar::operator= (long v) { m_type = e_slong; - m_data.slong = v; + m_integer = llvm::APInt(sizeof(long) * 8, v, true); return *this; } @@ -291,7 +426,7 @@ Scalar& Scalar::operator= (unsigned long v) { m_type = e_ulong; - m_data.ulong = v; + m_integer = llvm::APInt(sizeof(long) * 8, v); return *this; } @@ -299,7 +434,7 @@ Scalar& Scalar::operator= (long long v) { m_type = e_slonglong; - m_data.slonglong = v; + m_integer = llvm::APInt(sizeof(long) * 8, v, true); return *this; } @@ -307,7 +442,7 @@ Scalar& Scalar::operator= (unsigned long long v) { m_type = e_ulonglong; - m_data.ulonglong = v; + m_integer = llvm::APInt(sizeof(long long) * 8, v); return *this; } @@ -315,7 +450,7 @@ Scalar& Scalar::operator= (float v) { m_type = e_float; - m_data.flt = v; + m_float = llvm::APFloat(v); return *this; } @@ -323,7 +458,7 @@ Scalar& Scalar::operator= (double v) { m_type = e_double; - m_data.dbl = v; + m_float = llvm::APFloat(v); return *this; } @@ -331,7 +466,40 @@ Scalar& Scalar::operator= (long double v) { m_type = e_long_double; - m_data.ldbl = v; + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&v)->x)); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((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; + } return *this; } @@ -354,128 +522,455 @@ Scalar::Promote(Scalar::Type type) case e_sint: switch (type) { - case e_void: break; - case e_sint: success = true; break; - case e_uint: m_data.uint = m_data.sint; success = true; break; - case e_slong: m_data.slong = m_data.sint; success = true; break; - case e_ulong: m_data.ulong = m_data.sint; success = true; break; - case e_slonglong: m_data.slonglong = m_data.sint; success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.sint; success = true; break; - case e_float: m_data.flt = m_data.sint; success = true; break; - case e_double: m_data.dbl = m_data.sint; success = true; break; - case e_long_double: m_data.ldbl = m_data.sint; success = true; break; + case e_void: break; + case e_sint: success = true; break; + case e_uint: + { + m_integer = llvm::APInt(sizeof(uint_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_slong: + { + m_integer = llvm::APInt(sizeof(slong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + success = true; + break; + } + case e_ulong: + { + m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_slonglong: + { + m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + success = true; + break; + } + case e_ulonglong: + { + m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_sint128: + case e_uint128: + { + m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + success = true; + break; + } + case e_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + 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_data.slong = m_data.uint; success = true; break; - case e_ulong: m_data.ulong = m_data.uint; success = true; break; - case e_slonglong: m_data.slonglong = m_data.uint; success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.uint; success = true; break; - case e_float: m_data.flt = m_data.uint; success = true; break; - case e_double: m_data.dbl = m_data.uint; success = true; break; - case e_long_double: m_data.ldbl = m_data.uint; success = true; break; + case e_void: + case e_sint: break; + case e_uint: success = true; break; + case e_slong: + { + m_integer = llvm::APInt(sizeof(slong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + success = true; + break; + } + case e_ulong: + { + m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_slonglong: + { + m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + success = true; + break; + } + case e_ulonglong: + { + m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_sint128: + case e_uint128: + { + m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + success = true; + break; + } + case e_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + 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_data.ulong = m_data.slong; success = true; break; - case e_slonglong: m_data.slonglong = m_data.slong; success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.slong; success = true; break; - case e_float: m_data.flt = m_data.slong; success = true; break; - case e_double: m_data.dbl = m_data.slong; success = true; break; - case e_long_double: m_data.ldbl = m_data.slong; success = true; break; + case e_void: + case e_sint: + case e_uint: break; + case e_slong: success = true; break; + case e_ulong: + { + m_integer = llvm::APInt(sizeof(ulong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_slonglong: + { + m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + success = true; + break; + } + case e_ulonglong: + { + m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_sint128: + case e_uint128: + { + m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + success = true; + break; + } + case e_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + 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_data.slonglong = m_data.ulong; success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.ulong; success = true; break; - case e_float: m_data.flt = m_data.ulong; success = true; break; - case e_double: m_data.dbl = m_data.ulong; success = true; break; - case e_long_double: m_data.ldbl = m_data.ulong; success = true; break; + case e_void: + case e_sint: + case e_uint: + case e_slong: break; + case e_ulong: success = true; break; + case e_slonglong: + { + m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + success = true; + break; + } + case e_ulonglong: + { + m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_sint128: + case e_uint128: + { + m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + success = true; + break; + } + case e_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + 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_data.ulonglong = m_data.slonglong; success = true; break; - case e_float: m_data.flt = m_data.slonglong; success = true; break; - case e_double: m_data.dbl = m_data.slonglong; success = true; break; - case e_long_double: m_data.ldbl = m_data.slonglong; success = true; break; + 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 = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + success = true; + break; + } + case e_sint128: + case e_uint128: + { + m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + success = true; + break; + } + case e_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + 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_float: m_data.flt = m_data.ulonglong; success = true; break; - case e_double: m_data.dbl = m_data.ulonglong; success = true; break; - case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break; + 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 = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + success = true; + break; + } + case e_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + success = true; + break; + } + } + 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 = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())); + success = true; + break; + } + case e_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + 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_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + success = true; + break; + } } 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: break; - case e_float: success = true; break; - case e_double: m_data.dbl = m_data.flt; success = true; break; - case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break; + 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: break; + case e_float: success = true; break; + case e_double: + { + m_float = llvm::APFloat((float_t)m_float.convertToFloat()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt()); + 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_float: break; - case e_double: success = true; break; - case e_long_double: m_data.ldbl = m_data.dbl; success = true; break; + 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_float: break; + case e_double: success = true; break; + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt()); + success = true; + break; + } } break; @@ -489,6 +984,8 @@ Scalar::Promote(Scalar::Type type) case e_ulong: case e_slonglong: case e_ulonglong: + case e_sint128: + case e_uint128: case e_float: case e_double: break; case e_long_double: success = true; break; @@ -516,6 +1013,8 @@ Scalar::GetValueTypeAsCString (Scalar::Type type) case e_float: return "float"; case e_double: return "double"; case e_long_double: return "long double"; + case e_sint128: return "int128_t"; + case e_uint128: return "uint128_t"; } return "???"; } @@ -567,145 +1066,198 @@ Scalar::Cast(Scalar::Type type) 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: switch (type) { - case e_void: break; - case e_sint: success = true; break; - case e_uint: m_data.uint = m_data.sint; success = true; break; - case e_slong: m_data.slong = m_data.sint; success = true; break; - case e_ulong: m_data.ulong = m_data.sint; success = true; break; - case e_slonglong: m_data.slonglong = m_data.sint; success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.sint; success = true; break; - case e_float: m_data.flt = m_data.sint; success = true; break; - case e_double: m_data.dbl = m_data.sint; success = true; break; - case e_long_double: m_data.ldbl = m_data.sint; success = true; break; + case e_void: break; + case e_sint: + { + m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8); + success = true; + break; + } + case e_uint: + { + m_integer = m_integer.zextOrTrunc(sizeof(sint_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.zextOrTrunc(sizeof(slong_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.zextOrTrunc(sizeof(slonglong_t) * 8); + success = true; + break; + } + case e_sint128: + { + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + } + case e_uint128: + { + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); + success = true; + break; + } + case e_float: + { + m_float = llvm::APFloat(m_integer.bitsToFloat()); + success = true; + break; + } + case e_double: + { + m_float = llvm::APFloat(m_integer.bitsToDouble()); + success = true; + break; + } + case e_long_double: + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer); + success = true; + break; + } } break; - case e_uint: + case e_float: switch (type) { - case e_void: - case e_sint: m_data.sint = m_data.uint; success = true; break; - case e_uint: success = true; break; - case e_slong: m_data.slong = m_data.uint; success = true; break; - case e_ulong: m_data.ulong = m_data.uint; success = true; break; - case e_slonglong: m_data.slonglong = m_data.uint; success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.uint; success = true; break; - case e_float: m_data.flt = m_data.uint; success = true; break; - case e_double: m_data.dbl = m_data.uint; success = true; break; - case e_long_double: m_data.ldbl = m_data.uint; success = true; break; + 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: m_integer = m_float.bitcastToAPInt(); success = true; break; + case e_float: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break; + case e_double: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break; + case e_long_double: + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt()); + success = true; + break; } break; - case e_slong: + case e_double: switch (type) { - case e_void: - case e_sint: m_data.sint = (sint_t)m_data.slong; success = true; break; - case e_uint: m_data.uint = (uint_t)m_data.slong; success = true; break; - case e_slong: success = true; break; - case e_ulong: m_data.ulong = m_data.slong; success = true; break; - case e_slonglong: m_data.slonglong = m_data.slong; success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.slong; success = true; break; - case e_float: m_data.flt = m_data.slong; success = true; break; - case e_double: m_data.dbl = m_data.slong; success = true; break; - case e_long_double: m_data.ldbl = m_data.slong; success = true; break; + 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: m_integer = m_float.bitcastToAPInt(); success = true; break; + case e_float: m_float = llvm::APFloat(m_float.convertToDouble()); success = true; break; + case e_double: m_float = llvm::APFloat(m_float.convertToDouble()); success = true; break; + case e_long_double: + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt()); + success = true; + break; } break; - case e_ulong: + case e_long_double: switch (type) { - case e_void: - case e_sint: m_data.sint = (sint_t)m_data.ulong; success = true; break; - case e_uint: m_data.uint = (uint_t)m_data.ulong; success = true; break; - case e_slong: m_data.slong = m_data.ulong; success = true; break; - case e_ulong: success = true; break; - case e_slonglong: m_data.slonglong = m_data.ulong; success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.ulong; success = true; break; - case e_float: m_data.flt = m_data.ulong; success = true; break; - case e_double: m_data.dbl = m_data.ulong; success = true; break; - case e_long_double: m_data.ldbl = m_data.ulong; success = true; break; + case e_void: break; + case e_sint: + { + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8); + success = true; + break; } - break; - - case e_slonglong: - switch (type) + case e_uint: { - case e_void: - case e_sint: m_data.sint = (sint_t)m_data.slonglong; success = true; break; - case e_uint: m_data.uint = (uint_t)m_data.slonglong; success = true; break; - case e_slong: m_data.slong = m_data.slonglong; success = true; break; - case e_ulong: m_data.ulong = m_data.slonglong; success = true; break; - case e_slonglong: success = true; break; - case e_ulonglong: m_data.ulonglong = m_data.slonglong; success = true; break; - case e_float: m_data.flt = m_data.slonglong; success = true; break; - case e_double: m_data.dbl = m_data.slonglong; success = true; break; - case e_long_double: m_data.ldbl = m_data.slonglong; success = true; break; + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8); + success = true; + break; } - break; - - case e_ulonglong: - switch (type) + case e_slong: { - case e_void: - case e_sint: m_data.sint = (sint_t)m_data.ulonglong; success = true; break; - case e_uint: m_data.uint = (uint_t)m_data.ulonglong; success = true; break; - case e_slong: m_data.slong = m_data.ulonglong; success = true; break; - case e_ulong: m_data.ulong = m_data.ulonglong; success = true; break; - case e_slonglong: m_data.slonglong = m_data.ulonglong; success = true; break; - case e_ulonglong: success = true; break; - case e_float: m_data.flt = m_data.ulonglong; success = true; break; - case e_double: m_data.dbl = m_data.ulonglong; success = true; break; - case e_long_double: m_data.ldbl = m_data.ulonglong; success = true; break; + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8); + success = true; + break; } - break; - - case e_float: - switch (type) + case e_ulong: { - case e_void: - case e_sint: m_data.sint = (sint_t)m_data.flt; success = true; break; - case e_uint: m_data.uint = (uint_t)m_data.flt; success = true; break; - case e_slong: m_data.slong = (slong_t)m_data.flt; success = true; break; - case e_ulong: m_data.ulong = (ulong_t)m_data.flt; success = true; break; - case e_slonglong: m_data.slonglong = (slonglong_t)m_data.flt; success = true; break; - case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.flt; success = true; break; - case e_float: success = true; break; - case e_double: m_data.dbl = m_data.flt; success = true; break; - case e_long_double: m_data.ldbl = m_data.flt; success = true; break; + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8); + success = true; + break; } - break; - - case e_double: - switch (type) + case e_slonglong: { - case e_void: - case e_sint: m_data.sint = (sint_t)m_data.dbl; success = true; break; - case e_uint: m_data.uint = (uint_t)m_data.dbl; success = true; break; - case e_slong: m_data.slong = (slong_t)m_data.dbl; success = true; break; - case e_ulong: m_data.ulong = (ulong_t)m_data.dbl; success = true; break; - case e_slonglong: m_data.slonglong = (slonglong_t)m_data.dbl; success = true; break; - case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.dbl; success = true; break; - case e_float: m_data.flt = (float_t)m_data.dbl; success = true; break; - case e_double: success = true; break; - case e_long_double: m_data.ldbl = m_data.dbl; success = true; break; + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8); + success = true; + break; } - break; - - case e_long_double: - switch (type) + case e_ulonglong: { - case e_void: - case e_sint: m_data.sint = (sint_t)m_data.ldbl; success = true; break; - case e_uint: m_data.uint = (uint_t)m_data.ldbl; success = true; break; - case e_slong: m_data.slong = (slong_t)m_data.ldbl; success = true; break; - case e_ulong: m_data.ulong = (ulong_t)m_data.ldbl; success = true; break; - case e_slonglong: m_data.slonglong = (slonglong_t)m_data.ldbl; success = true; break; - case e_ulonglong: m_data.ulonglong = (ulonglong_t)m_data.ldbl; success = true; break; - case e_float: m_data.flt = (float_t)m_data.ldbl; success = true; break; - case e_double: m_data.dbl = (double_t)m_data.ldbl; success = true; break; + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8); + success = true; + break; + } + case e_sint128: + { + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128); + success = true; + break; + } + case e_uint128: + { + m_integer = m_float.bitcastToAPInt(); + m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128); + success = true; + break; + } + case e_float: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break; + case e_double: m_float = llvm::APFloat(m_float.convertToFloat()); success = true; break; case e_long_double: success = true; break; } break; @@ -730,6 +1282,8 @@ Scalar::MakeSigned () case e_ulong: m_type = e_slong; success = true; break; case e_slonglong: success = true; break; case e_ulonglong: m_type = e_slonglong; success = true; break; + case e_sint128: success = true; break; + case e_uint128: m_type = e_sint; success = true; break; case e_float: success = true; break; case e_double: success = true; break; case e_long_double: success = true; break; @@ -738,21 +1292,132 @@ Scalar::MakeSigned () return success; } +char +Scalar::SChar(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: + return *(const schar_t *)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getRawData(); + case e_float: + return (schar_t)m_float.convertToFloat(); + case e_double: + return (schar_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return (schar_t)*ldbl_val.getRawData(); + } + return 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: + return *(const uchar_t *)m_integer.getRawData(); + case e_float: + return (uchar_t)m_float.convertToFloat(); + case e_double: + return (uchar_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return (uchar_t)*ldbl_val.getRawData(); + } + return 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: + return *(const sshort_t *)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getRawData(); + case e_float: + return (sshort_t)m_float.convertToFloat(); + case e_double: + return (sshort_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *(const sshort_t *)ldbl_val.getRawData(); + } + return 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: + return *(const ushort_t *)m_integer.getRawData(); + case e_float: + return (ushort_t)m_float.convertToFloat(); + case e_double: + return (ushort_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *(const ushort_t *)ldbl_val.getRawData();; + } + return fail_value; +} + int Scalar::SInt(int fail_value) const { switch (m_type) { case e_void: break; - case e_sint: return m_data.sint; - case e_uint: return (int)m_data.uint; - case e_slong: return (int)m_data.slong; - case e_ulong: return (int)m_data.ulong; - case e_slonglong: return (int)m_data.slonglong; - case e_ulonglong: return (int)m_data.ulonglong; - case e_float: return (int)m_data.flt; - case e_double: return (int)m_data.dbl; - case e_long_double: return (int)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return *(const sint_t *)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getRawData(); + case e_float: + return (sint_t)m_float.convertToFloat(); + case e_double: + return (sint_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *(const sint_t *)ldbl_val.getRawData(); } return fail_value; } @@ -763,15 +1428,22 @@ Scalar::UInt(unsigned int fail_value) const switch (m_type) { case e_void: break; - case e_sint: return (unsigned int)m_data.sint; - case e_uint: return (unsigned int)m_data.uint; - case e_slong: return (unsigned int)m_data.slong; - case e_ulong: return (unsigned int)m_data.ulong; - case e_slonglong: return (unsigned int)m_data.slonglong; - case e_ulonglong: return (unsigned int)m_data.ulonglong; - case e_float: return (unsigned int)m_data.flt; - case e_double: return (unsigned int)m_data.dbl; - case e_long_double: return (unsigned int)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return *(const uint_t *)m_integer.getRawData(); + case e_float: + return (uint_t)m_float.convertToFloat(); + case e_double: + return (uint_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *(const uint_t *)ldbl_val.getRawData(); } return fail_value; } @@ -783,15 +1455,22 @@ Scalar::SLong(long fail_value) const switch (m_type) { case e_void: break; - case e_sint: return (long)m_data.sint; - case e_uint: return (long)m_data.uint; - case e_slong: return (long)m_data.slong; - case e_ulong: return (long)m_data.ulong; - case e_slonglong: return (long)m_data.slonglong; - case e_ulonglong: return (long)m_data.ulonglong; - case e_float: return (long)m_data.flt; - case e_double: return (long)m_data.dbl; - case e_long_double: return (long)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return *(const slong_t *)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getRawData(); + case e_float: + return (slong_t)m_float.convertToFloat(); + case e_double: + return (slong_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *(const slong_t *)ldbl_val.getRawData(); } return fail_value; } @@ -804,15 +1483,22 @@ Scalar::ULong(unsigned long fail_value) const switch (m_type) { case e_void: break; - case e_sint: return (unsigned long)m_data.sint; - case e_uint: return (unsigned long)m_data.uint; - case e_slong: return (unsigned long)m_data.slong; - case e_ulong: return (unsigned long)m_data.ulong; - case e_slonglong: return (unsigned long)m_data.slonglong; - case e_ulonglong: return (unsigned long)m_data.ulonglong; - case e_float: return (unsigned long)m_data.flt; - case e_double: return (unsigned long)m_data.dbl; - case e_long_double: return (unsigned long)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return *(const ulong_t *)m_integer.getRawData(); + case e_float: + return (ulong_t)m_float.convertToFloat(); + case e_double: + return (ulong_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *(const ulong_t *)ldbl_val.getRawData(); } return fail_value; } @@ -827,42 +1513,20 @@ Scalar::GetRawBits64(uint64_t fail_value) const case e_sint: case e_uint: - return m_data.uint; - case e_slong: case e_ulong: - return m_data.ulong; - case e_slonglong: case e_ulonglong: - return m_data.ulonglong; - + case e_sint128: + case e_uint128: + return *m_integer.getRawData(); case e_float: - if (sizeof(m_data.flt) == sizeof(m_data.uint)) - return m_data.uint; - else if (sizeof(m_data.flt) == sizeof(m_data.ulong)) - return m_data.ulong; - else if (sizeof(m_data.flt) == sizeof(m_data.ulonglong)) - return m_data.ulonglong; - break; - + return (uint64_t)m_float.convertToFloat(); case e_double: - if (sizeof(m_data.dbl) == sizeof(m_data.uint)) - return m_data.uint; - else if (sizeof(m_data.dbl) == sizeof(m_data.ulong)) - return m_data.ulong; - else if (sizeof(m_data.dbl) == sizeof(m_data.ulonglong)) - return m_data.ulonglong; - break; - + return (uint64_t)m_float.convertToDouble(); case e_long_double: - if (sizeof(m_data.ldbl) == sizeof(m_data.uint)) - return m_data.uint; - else if (sizeof(m_data.ldbl) == sizeof(m_data.ulong)) - return m_data.ulong; - else if (sizeof(m_data.ldbl) == sizeof(m_data.ulonglong)) - return m_data.ulonglong; - break; + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *ldbl_val.getRawData(); } return fail_value; } @@ -875,15 +1539,22 @@ Scalar::SLongLong(long long fail_value) const switch (m_type) { case e_void: break; - case e_sint: return (long long)m_data.sint; - case e_uint: return (long long)m_data.uint; - case e_slong: return (long long)m_data.slong; - case e_ulong: return (long long)m_data.ulong; - case e_slonglong: return (long long)m_data.slonglong; - case e_ulonglong: return (long long)m_data.ulonglong; - case e_float: return (long long)m_data.flt; - case e_double: return (long long)m_data.dbl; - case e_long_double: return (long long)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return *(const slonglong_t *)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getRawData(); + case e_float: + return (slonglong_t)m_float.convertToFloat(); + case e_double: + return (slonglong_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *(const slonglong_t *)ldbl_val.getRawData(); } return fail_value; } @@ -895,19 +1566,71 @@ Scalar::ULongLong(unsigned long long fail_value) const switch (m_type) { case e_void: break; - case e_sint: return (unsigned long long)m_data.sint; - case e_uint: return (unsigned long long)m_data.uint; - case e_slong: return (unsigned long long)m_data.slong; - case e_ulong: return (unsigned long long)m_data.ulong; - case e_slonglong: return (unsigned long long)m_data.slonglong; - case e_ulonglong: return (unsigned long long)m_data.ulonglong; - case e_float: return (unsigned long long)m_data.flt; - case e_double: return (unsigned long long)m_data.dbl; - case e_long_double: return (unsigned long long)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return *(const ulonglong_t *)m_integer.getRawData(); + case e_float: + return (ulonglong_t)m_float.convertToFloat(); + case e_double: + return (ulonglong_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return *(const ulonglong_t *)ldbl_val.getRawData(); } return fail_value; } +llvm::APInt +Scalar::UInt128(const llvm::APInt& 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: + return m_integer; + case e_float: + case e_double: + case e_long_double: + return m_float.bitcastToAPInt(); + } + return fail_value; +} + +llvm::APInt +Scalar::SInt128(llvm::APInt& 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: + return m_integer; + case e_float: + case e_double: + case e_long_double: + return m_float.bitcastToAPInt(); + } + return fail_value; +} float Scalar::Float(float fail_value) const @@ -915,15 +1638,22 @@ Scalar::Float(float fail_value) const switch (m_type) { case e_void: break; - case e_sint: return (float)m_data.sint; - case e_uint: return (float)m_data.uint; - case e_slong: return (float)m_data.slong; - case e_ulong: return (float)m_data.ulong; - case e_slonglong: return (float)m_data.slonglong; - case e_ulonglong: return (float)m_data.ulonglong; - case e_float: return (float)m_data.flt; - case e_double: return (float)m_data.dbl; - case e_long_double: return (float)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return m_integer.bitsToFloat(); + case e_float: + return m_float.convertToFloat(); + case e_double: + return (float_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return ldbl_val.bitsToFloat(); } return fail_value; } @@ -935,15 +1665,22 @@ Scalar::Double(double fail_value) const switch (m_type) { case e_void: break; - case e_sint: return (double)m_data.sint; - case e_uint: return (double)m_data.uint; - case e_slong: return (double)m_data.slong; - case e_ulong: return (double)m_data.ulong; - case e_slonglong: return (double)m_data.slonglong; - case e_ulonglong: return (double)m_data.ulonglong; - case e_float: return (double)m_data.flt; - case e_double: return (double)m_data.dbl; - case e_long_double: return (double)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return m_integer.bitsToDouble(); + case e_float: + return (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(); } return fail_value; } @@ -955,15 +1692,22 @@ Scalar::LongDouble(long double fail_value) const switch (m_type) { case e_void: break; - case e_sint: return (long double)m_data.sint; - case e_uint: return (long double)m_data.uint; - case e_slong: return (long double)m_data.slong; - case e_ulong: return (long double)m_data.ulong; - case e_slonglong: return (long double)m_data.slonglong; - case e_ulonglong: return (long double)m_data.ulonglong; - case e_float: return (long double)m_data.flt; - case e_double: return (long double)m_data.dbl; - case e_long_double: return (long double)m_data.ldbl; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + return (long_double_t)m_integer.bitsToDouble(); + case e_float: + return (long_double_t)m_float.convertToFloat(); + case e_double: + return (long_double_t)m_float.convertToDouble(); + case e_long_double: + llvm::APInt ldbl_val = m_float.bitcastToAPInt(); + return (long_double_t)ldbl_val.bitsToDouble(); } return fail_value; } @@ -978,17 +1722,27 @@ Scalar::operator+= (const Scalar& rhs) if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) != Scalar::e_void) { switch (m_type) - { - case e_void: break; - case e_sint: m_data.sint = a->m_data.sint + b->m_data.sint; break; - case e_uint: m_data.uint = a->m_data.uint + b->m_data.uint; break; - case e_slong: m_data.slong = a->m_data.slong + b->m_data.slong; break; - case e_ulong: m_data.ulong = a->m_data.ulong + b->m_data.ulong; break; - case e_slonglong: m_data.slonglong = a->m_data.slonglong + b->m_data.slonglong; break; - case e_ulonglong: m_data.ulonglong = a->m_data.ulonglong + b->m_data.ulonglong; break; - case e_float: m_data.flt = a->m_data.flt + b->m_data.flt; break; - case e_double: m_data.dbl = a->m_data.dbl + b->m_data.dbl; break; - case e_long_double: m_data.ldbl = a->m_data.ldbl + b->m_data.ldbl; break; + { + 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: + { + m_integer = a->m_integer + b->m_integer; + break; + } + case e_float: + case e_double: + case e_long_double: + { + m_float = a->m_float + b->m_float; + break; + } } } return *this; @@ -1007,109 +1761,33 @@ Scalar::operator<<= (const Scalar& rhs) break; case e_sint: - 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: m_data.sint <<= rhs.m_data.sint; break; - case e_uint: m_data.sint <<= rhs.m_data.uint; break; - case e_slong: m_data.sint <<= rhs.m_data.slong; break; - case e_ulong: m_data.sint <<= rhs.m_data.ulong; break; - case e_slonglong: m_data.sint <<= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.sint <<= rhs.m_data.ulonglong; break; - } - break; - case e_uint: - 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: m_data.uint <<= rhs.m_data.sint; break; - case e_uint: m_data.uint <<= rhs.m_data.uint; break; - case e_slong: m_data.uint <<= rhs.m_data.slong; break; - case e_ulong: m_data.uint <<= rhs.m_data.ulong; break; - case e_slonglong: m_data.uint <<= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.uint <<= rhs.m_data.ulonglong; break; - } - break; - case e_slong: - 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: m_data.slong <<= rhs.m_data.sint; break; - case e_uint: m_data.slong <<= rhs.m_data.uint; break; - case e_slong: m_data.slong <<= rhs.m_data.slong; break; - case e_ulong: m_data.slong <<= rhs.m_data.ulong; break; - case e_slonglong: m_data.slong <<= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.slong <<= rhs.m_data.ulonglong; break; - } - break; - case e_ulong: - 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: m_data.ulong <<= rhs.m_data.sint; break; - case e_uint: m_data.ulong <<= rhs.m_data.uint; break; - case e_slong: m_data.ulong <<= rhs.m_data.slong; break; - case e_ulong: m_data.ulong <<= rhs.m_data.ulong; break; - case e_slonglong: m_data.ulong <<= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.ulong <<= rhs.m_data.ulonglong; break; - } - break; case e_slonglong: - 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: m_data.slonglong <<= rhs.m_data.sint; break; - case e_uint: m_data.slonglong <<= rhs.m_data.uint; break; - case e_slong: m_data.slonglong <<= rhs.m_data.slong; break; - case e_ulong: m_data.slonglong <<= rhs.m_data.ulong; break; - case e_slonglong: m_data.slonglong <<= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.slonglong <<= rhs.m_data.ulonglong; break; - } - break; - case e_ulonglong: + case e_sint128: + case e_uint128: 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: m_data.ulonglong <<= rhs.m_data.sint; break; - case e_uint: m_data.ulonglong <<= rhs.m_data.uint; break; - case e_slong: m_data.ulonglong <<= rhs.m_data.slong; break; - case e_ulong: m_data.ulonglong <<= rhs.m_data.ulong; break; - case e_slonglong: m_data.ulonglong <<= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.ulonglong <<= rhs.m_data.ulonglong; break; + 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: + { + m_integer <<= *rhs.m_integer.getRawData(); + break; + } } break; } @@ -1130,44 +1808,12 @@ Scalar::ShiftRightLogical(const Scalar& rhs) case e_sint: case e_uint: - 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: m_data.uint >>= rhs.m_data.sint; break; - case e_uint: m_data.uint >>= rhs.m_data.uint; break; - case e_slong: m_data.uint >>= rhs.m_data.slong; break; - case e_ulong: m_data.uint >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.uint >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.uint >>= rhs.m_data.ulonglong; break; - } - break; - case e_slong: case e_ulong: - 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: m_data.ulong >>= rhs.m_data.sint; break; - case e_uint: m_data.ulong >>= rhs.m_data.uint; break; - case e_slong: m_data.ulong >>= rhs.m_data.slong; break; - case e_ulong: m_data.ulong >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.ulong >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.ulong >>= rhs.m_data.ulonglong; break; - } - break; - case e_slonglong: case e_ulonglong: + case e_sint128: + case e_uint128: switch (rhs.m_type) { case e_void: @@ -1176,12 +1822,15 @@ Scalar::ShiftRightLogical(const Scalar& rhs) case e_long_double: m_type = e_void; break; - case e_sint: m_data.ulonglong >>= rhs.m_data.sint; break; - case e_uint: m_data.ulonglong >>= rhs.m_data.uint; break; - case e_slong: m_data.ulonglong >>= rhs.m_data.slong; break; - case e_ulong: m_data.ulonglong >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.ulonglong >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.ulonglong >>= rhs.m_data.ulonglong; 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: + m_integer = m_integer.lshr(*(const uint_t *) rhs.m_integer.getRawData()); break; } break; } @@ -1202,95 +1851,13 @@ Scalar::operator>>= (const Scalar& rhs) break; case e_sint: - 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: m_data.sint >>= rhs.m_data.sint; break; - case e_uint: m_data.sint >>= rhs.m_data.uint; break; - case e_slong: m_data.sint >>= rhs.m_data.slong; break; - case e_ulong: m_data.sint >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.sint >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.sint >>= rhs.m_data.ulonglong; break; - } - break; - case e_uint: - 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: m_data.uint >>= rhs.m_data.sint; break; - case e_uint: m_data.uint >>= rhs.m_data.uint; break; - case e_slong: m_data.uint >>= rhs.m_data.slong; break; - case e_ulong: m_data.uint >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.uint >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.uint >>= rhs.m_data.ulonglong; break; - } - break; - case e_slong: - 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: m_data.slong >>= rhs.m_data.sint; break; - case e_uint: m_data.slong >>= rhs.m_data.uint; break; - case e_slong: m_data.slong >>= rhs.m_data.slong; break; - case e_ulong: m_data.slong >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.slong >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.slong >>= rhs.m_data.ulonglong; break; - } - break; - case e_ulong: - 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: m_data.ulong >>= rhs.m_data.sint; break; - case e_uint: m_data.ulong >>= rhs.m_data.uint; break; - case e_slong: m_data.ulong >>= rhs.m_data.slong; break; - case e_ulong: m_data.ulong >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.ulong >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.ulong >>= rhs.m_data.ulonglong; break; - } - break; case e_slonglong: - 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: m_data.slonglong >>= rhs.m_data.sint; break; - case e_uint: m_data.slonglong >>= rhs.m_data.uint; break; - case e_slong: m_data.slonglong >>= rhs.m_data.slong; break; - case e_ulong: m_data.slonglong >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.slonglong >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.slonglong >>= rhs.m_data.ulonglong; break; - } - break; - case e_ulonglong: + case e_sint128: + case e_uint128: switch (rhs.m_type) { case e_void: @@ -1299,12 +1866,18 @@ Scalar::operator>>= (const Scalar& rhs) case e_long_double: m_type = e_void; break; - case e_sint: m_data.ulonglong >>= rhs.m_data.sint; break; - case e_uint: m_data.ulonglong >>= rhs.m_data.uint; break; - case e_slong: m_data.ulonglong >>= rhs.m_data.slong; break; - case e_ulong: m_data.ulonglong >>= rhs.m_data.ulong; break; - case e_slonglong: m_data.ulonglong >>= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.ulonglong >>= rhs.m_data.ulonglong; 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: + { + m_integer >> *rhs.m_integer.getRawData(); + break; + } } break; } @@ -1325,95 +1898,13 @@ Scalar::operator&= (const Scalar& rhs) break; case e_sint: - 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: m_data.sint &= rhs.m_data.sint; break; - case e_uint: m_data.sint &= rhs.m_data.uint; break; - case e_slong: m_data.sint &= rhs.m_data.slong; break; - case e_ulong: m_data.sint &= rhs.m_data.ulong; break; - case e_slonglong: m_data.sint &= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.sint &= rhs.m_data.ulonglong; break; - } - break; - case e_uint: - 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: m_data.uint &= rhs.m_data.sint; break; - case e_uint: m_data.uint &= rhs.m_data.uint; break; - case e_slong: m_data.uint &= rhs.m_data.slong; break; - case e_ulong: m_data.uint &= rhs.m_data.ulong; break; - case e_slonglong: m_data.uint &= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.uint &= rhs.m_data.ulonglong; break; - } - break; - case e_slong: - 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: m_data.slong &= rhs.m_data.sint; break; - case e_uint: m_data.slong &= rhs.m_data.uint; break; - case e_slong: m_data.slong &= rhs.m_data.slong; break; - case e_ulong: m_data.slong &= rhs.m_data.ulong; break; - case e_slonglong: m_data.slong &= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.slong &= rhs.m_data.ulonglong; break; - } - break; - case e_ulong: - 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: m_data.ulong &= rhs.m_data.sint; break; - case e_uint: m_data.ulong &= rhs.m_data.uint; break; - case e_slong: m_data.ulong &= rhs.m_data.slong; break; - case e_ulong: m_data.ulong &= rhs.m_data.ulong; break; - case e_slonglong: m_data.ulong &= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.ulong &= rhs.m_data.ulonglong; break; - } - break; case e_slonglong: - 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: m_data.slonglong &= rhs.m_data.sint; break; - case e_uint: m_data.slonglong &= rhs.m_data.uint; break; - case e_slong: m_data.slonglong &= rhs.m_data.slong; break; - case e_ulong: m_data.slonglong &= rhs.m_data.ulong; break; - case e_slonglong: m_data.slonglong &= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.slonglong &= rhs.m_data.ulonglong; break; - } - break; - case e_ulonglong: + case e_sint128: + case e_uint128: switch (rhs.m_type) { case e_void: @@ -1422,12 +1913,18 @@ Scalar::operator&= (const Scalar& rhs) case e_long_double: m_type = e_void; break; - case e_sint: m_data.ulonglong &= rhs.m_data.sint; break; - case e_uint: m_data.ulonglong &= rhs.m_data.uint; break; - case e_slong: m_data.ulonglong &= rhs.m_data.slong; break; - case e_ulong: m_data.ulonglong &= rhs.m_data.ulong; break; - case e_slonglong: m_data.ulonglong &= rhs.m_data.slonglong; break; - case e_ulonglong: m_data.ulonglong &= rhs.m_data.ulonglong; 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: + { + m_integer &= rhs.m_integer; + break; + } } break; } @@ -1445,26 +1942,22 @@ Scalar::AbsoluteValue() break; case e_sint: - if (m_data.sint < 0) - m_data.sint = -m_data.sint; - return true; - case e_slong: - if (m_data.slong < 0) - m_data.slong = -m_data.slong; - return true; - case e_slonglong: - if (m_data.slonglong < 0) - m_data.slonglong = -m_data.slonglong; + case e_sint128: + if (m_integer.isNegative()) + m_integer = -m_integer; return true; case e_uint: case e_ulong: case e_ulonglong: return true; - case e_float: m_data.flt = fabsf(m_data.flt); return true; - case e_double: m_data.dbl = fabs(m_data.dbl); return true; - case e_long_double: m_data.ldbl = fabsl(m_data.ldbl); return true; + case e_uint128: + case e_float: + case e_double: + case e_long_double: + m_float.clearSign(); + return true; } return false; } @@ -1476,15 +1969,19 @@ Scalar::UnaryNegate() switch (m_type) { case e_void: break; - case e_sint: m_data.sint = -m_data.sint; return true; - case e_uint: m_data.uint = -m_data.uint; return true; - case e_slong: m_data.slong = -m_data.slong; return true; - case e_ulong: m_data.ulong = -m_data.ulong; return true; - case e_slonglong: m_data.slonglong = -m_data.slonglong; return true; - case e_ulonglong: m_data.ulonglong = -m_data.ulonglong; return true; - case e_float: m_data.flt = -m_data.flt; return true; - case e_double: m_data.dbl = -m_data.dbl; return true; - case e_long_double: m_data.ldbl = -m_data.ldbl; return true; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + m_integer = -m_integer; return true; + case e_float: + case e_double: + case e_long_double: + m_float.changeSign(); return true; } return false; } @@ -1494,12 +1991,15 @@ Scalar::OnesComplement() { switch (m_type) { - case e_sint: m_data.sint = ~m_data.sint; return true; - case e_uint: m_data.uint = ~m_data.uint; return true; - case e_slong: m_data.slong = ~m_data.slong; return true; - case e_ulong: m_data.ulong = ~m_data.ulong; return true; - case e_slonglong: m_data.slonglong = ~m_data.slonglong; return true; - case e_ulonglong: m_data.ulonglong = ~m_data.ulonglong; return true; + case e_sint: + case e_uint: + case e_slong: + case e_ulong: + case e_slonglong: + case e_ulonglong: + case e_sint128: + case e_uint128: + m_integer = ~m_integer; return true; case e_void: case e_float: @@ -1523,15 +2023,19 @@ lldb_private::operator+ (const Scalar& lhs, const Scalar& rhs) switch (result.m_type) { case Scalar::e_void: break; - case Scalar::e_sint: result.m_data.sint = a->m_data.sint + b->m_data.sint; break; - case Scalar::e_uint: result.m_data.uint = a->m_data.uint + b->m_data.uint; break; - case Scalar::e_slong: result.m_data.slong = a->m_data.slong + b->m_data.slong; break; - case Scalar::e_ulong: result.m_data.ulong = a->m_data.ulong + b->m_data.ulong; break; - case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong + b->m_data.slonglong; break; - case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong + b->m_data.ulonglong; break; - case Scalar::e_float: result.m_data.flt = a->m_data.flt + b->m_data.flt; break; - case Scalar::e_double: result.m_data.dbl = a->m_data.dbl + b->m_data.dbl; break; - case Scalar::e_long_double: result.m_data.ldbl = a->m_data.ldbl + b->m_data.ldbl; 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: + 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; } } return result; @@ -1550,15 +2054,19 @@ lldb_private::operator- (const Scalar& lhs, const Scalar& rhs) switch (result.m_type) { case Scalar::e_void: break; - case Scalar::e_sint: result.m_data.sint = a->m_data.sint - b->m_data.sint; break; - case Scalar::e_uint: result.m_data.uint = a->m_data.uint - b->m_data.uint; break; - case Scalar::e_slong: result.m_data.slong = a->m_data.slong - b->m_data.slong; break; - case Scalar::e_ulong: result.m_data.ulong = a->m_data.ulong - b->m_data.ulong; break; - case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong - b->m_data.slonglong; break; - case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong - b->m_data.ulonglong; break; - case Scalar::e_float: result.m_data.flt = a->m_data.flt - b->m_data.flt; break; - case Scalar::e_double: result.m_data.dbl = a->m_data.dbl - b->m_data.dbl; break; - case Scalar::e_long_double: result.m_data.ldbl = a->m_data.ldbl - b->m_data.ldbl; 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: + 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; } } return result; @@ -1576,16 +2084,31 @@ lldb_private::operator/ (const Scalar& lhs, const Scalar& rhs) switch (result.m_type) { case Scalar::e_void: break; - - case Scalar::e_sint: if (b->m_data.sint != 0) { result.m_data.sint = a->m_data.sint/ b->m_data.sint; return result; } break; - case Scalar::e_uint: if (b->m_data.uint != 0) { result.m_data.uint = a->m_data.uint / b->m_data.uint; return result; } break; - case Scalar::e_slong: if (b->m_data.slong != 0) { result.m_data.slong = a->m_data.slong / b->m_data.slong; return result; } break; - case Scalar::e_ulong: if (b->m_data.ulong != 0) { result.m_data.ulong = a->m_data.ulong / b->m_data.ulong; return result; } break; - case Scalar::e_slonglong: if (b->m_data.slonglong != 0) { result.m_data.slonglong = a->m_data.slonglong / b->m_data.slonglong; return result; } break; - case Scalar::e_ulonglong: if (b->m_data.ulonglong != 0) { result.m_data.ulonglong = a->m_data.ulonglong / b->m_data.ulonglong; return result; } break; - case Scalar::e_float: if (b->m_data.flt != 0.0f) { result.m_data.flt = a->m_data.flt / b->m_data.flt; return result; } break; - case Scalar::e_double: if (b->m_data.dbl != 0.0) { result.m_data.dbl = a->m_data.dbl / b->m_data.dbl; return result; } break; - case Scalar::e_long_double: if (b->m_data.ldbl != 0.0) { result.m_data.ldbl = a->m_data.ldbl / b->m_data.ldbl; return result; } 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: + { + if (b->m_integer != 0) + { + result.m_integer = *a->m_integer.getRawData() / *b->m_integer.getRawData(); + 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; } } // For division only, the only way it should make it here is if a promotion failed, @@ -1606,15 +2129,19 @@ lldb_private::operator* (const Scalar& lhs, const Scalar& rhs) switch (result.m_type) { case Scalar::e_void: break; - case Scalar::e_sint: result.m_data.sint = a->m_data.sint * b->m_data.sint; break; - case Scalar::e_uint: result.m_data.uint = a->m_data.uint * b->m_data.uint; break; - case Scalar::e_slong: result.m_data.slong = a->m_data.slong * b->m_data.slong; break; - case Scalar::e_ulong: result.m_data.ulong = a->m_data.ulong * b->m_data.ulong; break; - case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong * b->m_data.slonglong; break; - case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong * b->m_data.ulonglong; break; - case Scalar::e_float: result.m_data.flt = a->m_data.flt * b->m_data.flt; break; - case Scalar::e_double: result.m_data.dbl = a->m_data.dbl * b->m_data.dbl; break; - case Scalar::e_long_double: result.m_data.ldbl = a->m_data.ldbl * b->m_data.ldbl; 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: + 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; } } return result; @@ -1631,13 +2158,15 @@ lldb_private::operator& (const Scalar& lhs, const Scalar& rhs) { switch (result.m_type) { - case Scalar::e_sint: result.m_data.sint = a->m_data.sint & b->m_data.sint; break; - case Scalar::e_uint: result.m_data.uint = a->m_data.uint & b->m_data.uint; break; - case Scalar::e_slong: result.m_data.slong = a->m_data.slong & b->m_data.slong; break; - case Scalar::e_ulong: result.m_data.ulong = a->m_data.ulong & b->m_data.ulong; break; - case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong & b->m_data.slonglong; break; - case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong & b->m_data.ulonglong; 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: + result.m_integer = a->m_integer & b->m_integer; break; case Scalar::e_void: case Scalar::e_float: case Scalar::e_double: @@ -1661,12 +2190,15 @@ lldb_private::operator| (const Scalar& lhs, const Scalar& rhs) { switch (result.m_type) { - case Scalar::e_sint: result.m_data.sint = a->m_data.sint | b->m_data.sint; break; - case Scalar::e_uint: result.m_data.uint = a->m_data.uint | b->m_data.uint; break; - case Scalar::e_slong: result.m_data.slong = a->m_data.slong | b->m_data.slong; break; - case Scalar::e_ulong: result.m_data.ulong = a->m_data.ulong | b->m_data.ulong; break; - case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong | b->m_data.slonglong; break; - case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong | b->m_data.ulonglong; 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: + result.m_integer = a->m_integer | b->m_integer; break; case Scalar::e_void: case Scalar::e_float: @@ -1692,12 +2224,23 @@ lldb_private::operator% (const Scalar& lhs, const Scalar& rhs) switch (result.m_type) { default: break; - case Scalar::e_sint: if (b->m_data.sint != 0) { result.m_data.sint = a->m_data.sint % b->m_data.sint; return result; } break; - case Scalar::e_uint: if (b->m_data.uint != 0) { result.m_data.uint = a->m_data.uint % b->m_data.uint; return result; } break; - case Scalar::e_slong: if (b->m_data.slong != 0) { result.m_data.slong = a->m_data.slong % b->m_data.slong; return result; } break; - case Scalar::e_ulong: if (b->m_data.ulong != 0) { result.m_data.ulong = a->m_data.ulong % b->m_data.ulong; return result; } break; - case Scalar::e_slonglong: if (b->m_data.slonglong != 0) { result.m_data.slonglong = a->m_data.slonglong % b->m_data.slonglong; return result; } break; - case Scalar::e_ulonglong: if (b->m_data.ulonglong != 0) { result.m_data.ulonglong = a->m_data.ulonglong % b->m_data.ulonglong; return result; } break; + 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: + { + if (b->m_integer != 0) + { + result.m_integer = *a->m_integer.getRawData() % *b->m_integer.getRawData(); + return result; + } + break; + } } } result.m_type = Scalar::e_void; @@ -1715,12 +2258,15 @@ lldb_private::operator^ (const Scalar& lhs, const Scalar& rhs) { switch (result.m_type) { - case Scalar::e_sint: result.m_data.sint = a->m_data.sint ^ b->m_data.sint; break; - case Scalar::e_uint: result.m_data.uint = a->m_data.uint ^ b->m_data.uint; break; - case Scalar::e_slong: result.m_data.slong = a->m_data.slong ^ b->m_data.slong; break; - case Scalar::e_ulong: result.m_data.ulong = a->m_data.ulong ^ b->m_data.ulong; break; - case Scalar::e_slonglong: result.m_data.slonglong = a->m_data.slonglong ^ b->m_data.slonglong; break; - case Scalar::e_ulonglong: result.m_data.ulonglong = a->m_data.ulonglong ^ b->m_data.ulonglong; 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: + result.m_integer = a->m_integer ^ b->m_integer; break; case Scalar::e_void: case Scalar::e_float: @@ -1754,21 +2300,21 @@ lldb_private::operator>> (const Scalar& lhs, const Scalar &rhs) unsigned int Scalar::RawUInt () const { - return m_data.uint; + return *(const uint_t *) m_integer.getRawData(); } // Return the raw unsigned long without any casting or conversion unsigned long Scalar::RawULong () const { - return m_data.ulong; + return *(const ulong_t *) m_integer.getRawData(); } // Return the raw unsigned long long without any casting or conversion unsigned long long Scalar::RawULongLong () const { - return m_data.ulonglong; + return *(const ulonglong_t *) m_integer.getRawData(); } @@ -1801,9 +2347,9 @@ Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t by m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize (byte_size); switch (m_type) { - case e_uint: m_data.uint = (uint_t)uval64; break; - case e_ulong: m_data.ulong = (ulong_t)uval64; break; - case e_ulonglong: m_data.ulonglong = (ulonglong_t)uval64; break; + 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 "", (uint64_t)byte_size); break; @@ -1830,9 +2376,9 @@ Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t by m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize (byte_size); switch (m_type) { - case e_sint: m_data.sint = (sint_t)sval64; break; - case e_slong: m_data.slong = (slong_t)sval64; break; - case e_slonglong: m_data.slonglong = (slonglong_t)sval64; break; + 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 "", (uint64_t)byte_size); break; @@ -1847,24 +2393,36 @@ Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t by 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", &m_data.flt) == 1) + 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", &m_data.dbl) == 1) + 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", &m_data.ldbl) == 1) + if (::sscanf (value_str, "%Lf", &l_val) == 1) + { + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&l_val)->x)); m_type = e_long_double; + } else error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str); } @@ -1890,6 +2448,7 @@ Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t b { Error error; + type128 int128; switch (encoding) { case lldb::eEncodingInvalid: @@ -1904,10 +2463,25 @@ Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t b switch (byte_size) { - case 1: operator=((uint8_t)data.GetU8(&offset)); break; - case 2: operator=((uint16_t)data.GetU16(&offset)); break; - case 4: operator=((uint32_t)data.GetU32(&offset)); break; - case 8: operator=((uint64_t)data.GetU64(&offset)); break; + case 1: operator=((uint8_t)data.GetU8(&offset)); break; + case 2: operator=((uint16_t)data.GetU16(&offset)); break; + case 4: operator=((uint32_t)data.GetU32(&offset)); break; + case 8: operator=((uint64_t)data.GetU64(&offset)); break; + case 16: + { + if (data.GetByteOrder() == eByteOrderBig) + { + int128.x[1] = (uint64_t)data.GetU64 (&offset); + int128.x[0] = (uint64_t)data.GetU64 (&offset + 1); + } + else + { + int128.x[0] = (uint64_t)data.GetU64 (&offset); + int128.x[1] = (uint64_t)data.GetU64 (&offset + 1); + } + operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x)); + break; + } default: error.SetErrorStringWithFormat("unsupported unsigned integer byte size: %" PRIu64 "", (uint64_t)byte_size); break; @@ -1924,6 +2498,21 @@ Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t b case 2: operator=((int16_t)data.GetU16(&offset)); break; case 4: operator=((int32_t)data.GetU32(&offset)); break; case 8: operator=((int64_t)data.GetU64(&offset)); break; + case 16: + { + if (data.GetByteOrder() == eByteOrderBig) + { + int128.x[1] = (uint64_t)data.GetU64 (&offset); + int128.x[0] = (uint64_t)data.GetU64 (&offset + 1); + } + else + { + int128.x[0] = (uint64_t)data.GetU64 (&offset); + int128.x[1] = (uint64_t)data.GetU64 (&offset + 1); + } + operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x)); + break; + } default: error.SetErrorStringWithFormat("unsupported signed integer byte size: %" PRIu64 "", (uint64_t)byte_size); break; @@ -1966,47 +2555,22 @@ Scalar::SignExtend (uint32_t sign_bit_pos) case Scalar::e_sint: case Scalar::e_uint: - if (max_bit_pos == sign_bit_pos) - return true; - else if (sign_bit_pos < (max_bit_pos-1)) - { - unsigned int sign_bit = 1u << sign_bit_pos; - if (m_data.uint & sign_bit) - { - const unsigned int mask = ~(sign_bit) + 1u; - m_data.uint |= mask; - } - return true; - } - break; - case Scalar::e_slong: case Scalar::e_ulong: - if (max_bit_pos == sign_bit_pos) - return true; - else if (sign_bit_pos < (max_bit_pos-1)) - { - unsigned long sign_bit = 1ul << sign_bit_pos; - if (m_data.ulong & sign_bit) - { - const unsigned long mask = ~(sign_bit) + 1ul; - m_data.ulong |= mask; - } - return true; - } - break; - case Scalar::e_slonglong: case Scalar::e_ulonglong: + case Scalar::e_sint128: + case Scalar::e_uint128: if (max_bit_pos == sign_bit_pos) return true; else if (sign_bit_pos < (max_bit_pos-1)) { - unsigned long long sign_bit = 1ull << sign_bit_pos; - if (m_data.ulonglong & sign_bit) + llvm::APInt sign_bit = llvm::APInt::getSignBit(sign_bit_pos + 1); + llvm::APInt bitwize_and = m_integer & sign_bit; + if (bitwize_and.getBoolValue()) { - const unsigned long long mask = ~(sign_bit) + 1ull; - m_data.ulonglong |= mask; + const llvm::APInt mask = ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1); + m_integer |= mask; } return true; } @@ -2053,66 +2617,40 @@ Scalar::ExtractBitfield (uint32_t bit_size, uint32_t msbit = bit_offset + bit_size - 1; uint32_t lsbit = bit_offset; + uint64_t result; switch (m_type) { case Scalar::e_void: break; case e_float: - if (sizeof(m_data.flt) == sizeof(sint_t)) - m_data.sint = (sint_t)SignedBits (m_data.sint, msbit, lsbit); - else if (sizeof(m_data.flt) == sizeof(ulong_t)) - m_data.slong = (slong_t)SignedBits (m_data.slong, msbit, lsbit); - else if (sizeof(m_data.flt) == sizeof(ulonglong_t)) - m_data.slonglong = (slonglong_t)SignedBits (m_data.slonglong, msbit, lsbit); - else - return false; + result = SignedBits ((uint64_t )m_float.convertToFloat(), msbit, lsbit); + m_float = llvm::APFloat((float_t)result); return true; - case e_double: - if (sizeof(m_data.dbl) == sizeof(sint_t)) - m_data.sint = SignedBits (m_data.sint, msbit, lsbit); - else if (sizeof(m_data.dbl) == sizeof(ulong_t)) - m_data.slong = SignedBits (m_data.slong, msbit, lsbit); - else if (sizeof(m_data.dbl) == sizeof(ulonglong_t)) - m_data.slonglong = SignedBits (m_data.slonglong, msbit, lsbit); - else - return false; - return true; - + result = SignedBits ((uint64_t )m_float.convertToDouble(), msbit, lsbit); + m_float = llvm::APFloat((double_t)result); case e_long_double: - if (sizeof(m_data.ldbl) == sizeof(sint_t)) - m_data.sint = SignedBits (m_data.sint, msbit, lsbit); - else if (sizeof(m_data.ldbl) == sizeof(ulong_t)) - m_data.slong = SignedBits (m_data.slong, msbit, lsbit); - else if (sizeof(m_data.ldbl) == sizeof(ulonglong_t)) - m_data.slonglong = SignedBits (m_data.slonglong, msbit, lsbit); + m_integer = m_float.bitcastToAPInt(); + result = SignedBits (*m_integer.getRawData(), msbit, lsbit); + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&result)->x)); else - return false; + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&result)->x)); return true; case Scalar::e_sint: - m_data.sint = (sint_t)SignedBits (m_data.sint, msbit, lsbit); - return true; - - case Scalar::e_uint: - m_data.uint = (uint_t)UnsignedBits (m_data.uint, msbit, lsbit); - return true; - case Scalar::e_slong: - m_data.slong = (slong_t)SignedBits (m_data.slong, msbit, lsbit); - return true; - - case Scalar::e_ulong: - m_data.ulong = (ulong_t)UnsignedBits (m_data.ulong, msbit, lsbit); - return true; - case Scalar::e_slonglong: - m_data.slonglong = (slonglong_t)SignedBits (m_data.slonglong, msbit, lsbit); + case Scalar::e_sint128: + m_integer = SignedBits (*m_integer.getRawData(), msbit, lsbit); return true; + case Scalar::e_uint: + case Scalar::e_ulong: case Scalar::e_ulonglong: - m_data.ulonglong = (ulonglong_t)UnsignedBits (m_data.ulonglong, msbit, lsbit); + case Scalar::e_uint128: + m_integer = UnsignedBits (*m_integer.getRawData(), msbit, lsbit); return true; } return false; @@ -2132,18 +2670,25 @@ lldb_private::operator== (const Scalar& lhs, const Scalar& rhs) Scalar temp_value; const Scalar* a; const Scalar* b; + llvm::APFloat::cmpResult result; switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) { case Scalar::e_void: break; - case Scalar::e_sint: return a->m_data.sint == b->m_data.sint; - case Scalar::e_uint: return a->m_data.uint == b->m_data.uint; - case Scalar::e_slong: return a->m_data.slong == b->m_data.slong; - case Scalar::e_ulong: return a->m_data.ulong == b->m_data.ulong; - case Scalar::e_slonglong: return a->m_data.slonglong == b->m_data.slonglong; - case Scalar::e_ulonglong: return a->m_data.ulonglong == b->m_data.ulonglong; - case Scalar::e_float: return a->m_data.flt == b->m_data.flt; - case Scalar::e_double: return a->m_data.dbl == b->m_data.dbl; - case Scalar::e_long_double: return a->m_data.ldbl == b->m_data.ldbl; + 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: + return a->m_integer == b->m_integer; + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: + result = a->m_float.compare(b->m_float); + if(result == llvm::APFloat::cmpEqual) + return true; } return false; } @@ -2158,18 +2703,25 @@ lldb_private::operator!= (const Scalar& lhs, const Scalar& rhs) Scalar temp_value; // A temp value that might get a copy of either promoted value const Scalar* a; const Scalar* b; + llvm::APFloat::cmpResult result; switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) { case Scalar::e_void: break; - case Scalar::e_sint: return a->m_data.sint != b->m_data.sint; - case Scalar::e_uint: return a->m_data.uint != b->m_data.uint; - case Scalar::e_slong: return a->m_data.slong != b->m_data.slong; - case Scalar::e_ulong: return a->m_data.ulong != b->m_data.ulong; - case Scalar::e_slonglong: return a->m_data.slonglong != b->m_data.slonglong; - case Scalar::e_ulonglong: return a->m_data.ulonglong != b->m_data.ulonglong; - case Scalar::e_float: return a->m_data.flt != b->m_data.flt; - case Scalar::e_double: return a->m_data.dbl != b->m_data.dbl; - case Scalar::e_long_double: return a->m_data.ldbl != b->m_data.ldbl; + 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: + return a->m_integer != b->m_integer; + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: + result = a->m_float.compare(b->m_float); + if(result != llvm::APFloat::cmpEqual) + return true; } return true; } @@ -2183,18 +2735,26 @@ lldb_private::operator< (const Scalar& lhs, const Scalar& rhs) Scalar temp_value; const Scalar* a; const Scalar* b; + llvm::APFloat::cmpResult result; switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) { case Scalar::e_void: break; - case Scalar::e_sint: return a->m_data.sint < b->m_data.sint; - case Scalar::e_uint: return a->m_data.uint < b->m_data.uint; - case Scalar::e_slong: return a->m_data.slong < b->m_data.slong; - case Scalar::e_ulong: return a->m_data.ulong < b->m_data.ulong; - case Scalar::e_slonglong: return a->m_data.slonglong < b->m_data.slonglong; - case Scalar::e_ulonglong: return a->m_data.ulonglong < b->m_data.ulonglong; - case Scalar::e_float: return a->m_data.flt < b->m_data.flt; - case Scalar::e_double: return a->m_data.dbl < b->m_data.dbl; - case Scalar::e_long_double: return a->m_data.ldbl < b->m_data.ldbl; + case Scalar::e_sint: + case Scalar::e_slong: + case Scalar::e_slonglong: + case Scalar::e_sint128: + return a->m_integer.slt(b->m_integer); + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: + return a->m_integer.ult(b->m_integer); + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: + result = a->m_float.compare(b->m_float); + if(result == llvm::APFloat::cmpLessThan) + return true; } return false; } @@ -2208,18 +2768,26 @@ lldb_private::operator<= (const Scalar& lhs, const Scalar& rhs) Scalar temp_value; const Scalar* a; const Scalar* b; + llvm::APFloat::cmpResult result; switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) { case Scalar::e_void: break; - case Scalar::e_sint: return a->m_data.sint <= b->m_data.sint; - case Scalar::e_uint: return a->m_data.uint <= b->m_data.uint; - case Scalar::e_slong: return a->m_data.slong <= b->m_data.slong; - case Scalar::e_ulong: return a->m_data.ulong <= b->m_data.ulong; - case Scalar::e_slonglong: return a->m_data.slonglong <= b->m_data.slonglong; - case Scalar::e_ulonglong: return a->m_data.ulonglong <= b->m_data.ulonglong; - case Scalar::e_float: return a->m_data.flt <= b->m_data.flt; - case Scalar::e_double: return a->m_data.dbl <= b->m_data.dbl; - case Scalar::e_long_double: return a->m_data.ldbl <= b->m_data.ldbl; + case Scalar::e_sint: + case Scalar::e_slong: + case Scalar::e_slonglong: + case Scalar::e_sint128: + return a->m_integer.sle(b->m_integer); + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: + return a->m_integer.ule(b->m_integer); + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: + result = a->m_float.compare(b->m_float); + if(result == llvm::APFloat::cmpLessThan || result == llvm::APFloat::cmpEqual) + return true; } return false; } @@ -2234,18 +2802,26 @@ lldb_private::operator> (const Scalar& lhs, const Scalar& rhs) Scalar temp_value; const Scalar* a; const Scalar* b; + llvm::APFloat::cmpResult result; switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) { - case Scalar::e_void: break; - case Scalar::e_sint: return a->m_data.sint > b->m_data.sint; - case Scalar::e_uint: return a->m_data.uint > b->m_data.uint; - case Scalar::e_slong: return a->m_data.slong > b->m_data.slong; - case Scalar::e_ulong: return a->m_data.ulong > b->m_data.ulong; - case Scalar::e_slonglong: return a->m_data.slonglong > b->m_data.slonglong; - case Scalar::e_ulonglong: return a->m_data.ulonglong > b->m_data.ulonglong; - case Scalar::e_float: return a->m_data.flt > b->m_data.flt; - case Scalar::e_double: return a->m_data.dbl > b->m_data.dbl; - case Scalar::e_long_double: return a->m_data.ldbl > b->m_data.ldbl; + case Scalar::e_void: break; + case Scalar::e_sint: + case Scalar::e_slong: + case Scalar::e_slonglong: + case Scalar::e_sint128: + return a->m_integer.sgt(b->m_integer); + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: + return a->m_integer.ugt(b->m_integer); + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: + result = a->m_float.compare(b->m_float); + if(result == llvm::APFloat::cmpGreaterThan) + return true; } return false; } @@ -2259,22 +2835,140 @@ lldb_private::operator>= (const Scalar& lhs, const Scalar& rhs) Scalar temp_value; const Scalar* a; const Scalar* b; + llvm::APFloat::cmpResult result; switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) { - case Scalar::e_void: break; - case Scalar::e_sint: return a->m_data.sint >= b->m_data.sint; - case Scalar::e_uint: return a->m_data.uint >= b->m_data.uint; - case Scalar::e_slong: return a->m_data.slong >= b->m_data.slong; - case Scalar::e_ulong: return a->m_data.ulong >= b->m_data.ulong; - case Scalar::e_slonglong: return a->m_data.slonglong >= b->m_data.slonglong; - case Scalar::e_ulonglong: return a->m_data.ulonglong >= b->m_data.ulonglong; - case Scalar::e_float: return a->m_data.flt >= b->m_data.flt; - case Scalar::e_double: return a->m_data.dbl >= b->m_data.dbl; - case Scalar::e_long_double: return a->m_data.ldbl >= b->m_data.ldbl; + case Scalar::e_void: break; + case Scalar::e_sint: + case Scalar::e_slong: + case Scalar::e_slonglong: + case Scalar::e_sint128: + return a->m_integer.sge(b->m_integer); + case Scalar::e_uint: + case Scalar::e_ulong: + case Scalar::e_ulonglong: + case Scalar::e_uint128: + return a->m_integer.uge(b->m_integer); + case Scalar::e_float: + case Scalar::e_double: + case Scalar::e_long_double: + result = a->m_float.compare(b->m_float); + if(result == llvm::APFloat::cmpGreaterThan || result == llvm::APFloat::cmpEqual) + return true; } return false; } +bool +Scalar::ClearBit (uint32_t bit) +{ + 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: m_integer.clearBit(bit); return true; + case e_float: + case e_double: + case e_long_double: break; + } + return false; +} +bool +Scalar::SetBit (uint32_t bit) +{ + 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: m_integer.setBit(bit); return true; + case e_float: + case e_double: + case e_long_double: break; + } + return false; +} - +void +Scalar::SetType (const RegisterInfo *reg_info) +{ + const uint32_t byte_size = reg_info->byte_size; + switch (reg_info->encoding) + { + case eEncodingInvalid: + break; + case eEncodingUint: + if (byte_size == 1 || byte_size == 2 || byte_size == 4) + { + m_integer = llvm::APInt(sizeof(uint_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_type = e_uint; + } + if (byte_size == 8) + { + m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), false); + m_type = e_ulonglong; + } + if (byte_size == 16) + { + m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())->x); + m_type = e_uint128; + } + break; + case eEncodingSint: + if (byte_size == 1 || byte_size == 2 || byte_size == 4) + { + m_integer = llvm::APInt(sizeof(sint_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + m_type = e_sint; + } + if (byte_size == 8) + { + m_integer = llvm::APInt(sizeof(slonglong_t) * 8, *(const uint64_t *)m_integer.getRawData(), true); + m_type = e_slonglong; + } + if (byte_size == 16) + { + m_integer = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((const type128 *)m_integer.getRawData())->x); + m_type = e_sint128; + } + break; + case eEncodingIEEE754: + if (byte_size == sizeof(float)) + { + bool losesInfo = false; + m_float.convert(llvm::APFloat::IEEEsingle, llvm::APFloat::rmTowardZero, &losesInfo); + m_type = e_float; + } + else if (byte_size == sizeof(double)) + { + bool losesInfo = false; + m_float.convert(llvm::APFloat::IEEEdouble, llvm::APFloat::rmTowardZero, &losesInfo); + m_type = e_double; + } + else if (byte_size == sizeof(long double)) + { + if(m_ieee_quad) + m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_float.bitcastToAPInt()); + else + m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_float.bitcastToAPInt()); + m_type = e_long_double; + } + break; + case eEncodingVector: + m_type = e_void; + break; + } +} diff --git a/source/Core/Section.cpp b/source/Core/Section.cpp index 9a3f220beb445..cf1cbac8fd7c0 100644 --- a/source/Core/Section.cpp +++ b/source/Core/Section.cpp @@ -319,6 +319,25 @@ Section::Slide (addr_t slide_amount, bool slide_children) return false; } +lldb::offset_t +Section::GetSectionData (void *dst, lldb::offset_t dst_len, lldb::offset_t offset) +{ + if (m_obj_file) + return m_obj_file->ReadSectionData (this, + offset, + dst, + dst_len); + return 0; +} + +lldb::offset_t +Section::GetSectionData (DataExtractor& section_data) const +{ + if (m_obj_file) + return m_obj_file->ReadSectionData (this, section_data); + return 0; +} + #pragma mark SectionList SectionList::SectionList () : diff --git a/source/Core/SourceManager.cpp b/source/Core/SourceManager.cpp index 324ed34bfaacb..a69e75fe244a2 100644 --- a/source/Core/SourceManager.cpp +++ b/source/Core/SourceManager.cpp @@ -18,7 +18,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Stream.h" -#include "lldb/Symbol/ClangNamespaceDecl.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/SymbolContext.h" @@ -83,6 +82,10 @@ SourceManager::GetFile (const FileSpec &file_spec) if (target_sp && file_sp && file_sp->GetSourceMapModificationID() != target_sp->GetSourcePathMap().GetModificationID()) file_sp.reset(); + // Update the file contents if needed if we found a file + if (file_sp) + file_sp->UpdateIfNeeded(); + // If file_sp is no good or it points to a non-existent file, reset it. if (!file_sp || !file_sp->GetFileSpec().Exists()) { @@ -492,8 +495,8 @@ SourceManager::File::LineIsValid (uint32_t line) return false; } -size_t -SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t context_before, uint32_t context_after, Stream *s) +void +SourceManager::File::UpdateIfNeeded () { // TODO: use host API to sign up for file modifications to anything in our // source cache and only update when we determine a file has been updated. @@ -506,7 +509,11 @@ SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t context_before, m_data_sp = m_file_spec.ReadFileContents (); m_offsets.clear(); } +} +size_t +SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t context_before, uint32_t context_after, Stream *s) +{ // Sanity check m_data_sp before proceeding. if (!m_data_sp) return 0; @@ -538,14 +545,6 @@ SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t context_before, void SourceManager::File::FindLinesMatchingRegex (RegularExpression& regex, uint32_t start_line, uint32_t end_line, std::vector<uint32_t> &match_lines) { - TimeValue curr_mod_time (m_file_spec.GetModificationTime()); - if (m_mod_time != curr_mod_time) - { - m_mod_time = curr_mod_time; - m_data_sp = m_file_spec.ReadFileContents (); - m_offsets.clear(); - } - match_lines.clear(); if (!LineIsValid(start_line) || (end_line != UINT32_MAX && !LineIsValid(end_line))) @@ -645,14 +644,14 @@ SourceManager::File::CalculateLineOffsets (uint32_t line) else { // Some lines have been populated, start where we last left off - assert("Not implemented yet" == NULL); + assert("Not implemented yet" && false); } } else { // Calculate all line offsets up to "line" - assert("Not implemented yet" == NULL); + assert("Not implemented yet" && false); } return false; } diff --git a/source/Core/Stream.cpp b/source/Core/Stream.cpp index 29bebb3ae3db9..15876d558ec5b 100644 --- a/source/Core/Stream.cpp +++ b/source/Core/Stream.cpp @@ -30,7 +30,7 @@ Stream::Stream (uint32_t flags, uint32_t addr_size, ByteOrder byte_order) : Stream::Stream () : m_flags (0), m_addr_size (4), - m_byte_order (lldb::endian::InlHostByteOrder()), + m_byte_order (endian::InlHostByteOrder()), m_indent_level(0) { } @@ -284,9 +284,9 @@ Stream::operator<< (const char *s) // Stream the pointer value out to this stream. //------------------------------------------------------------------ Stream& -Stream::operator<< (void *p) +Stream::operator<< (const void *p) { - Printf ("0x%.*tx", (int)sizeof(void*) * 2, (ptrdiff_t)p); + Printf ("0x%.*tx", (int)sizeof(const void*) * 2, (ptrdiff_t)p); return *this; } @@ -632,7 +632,7 @@ Stream::PutMaxHex64 size_t Stream::PutPointer (void *ptr) { - return PutRawBytes (&ptr, sizeof(ptr), lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder()); + return PutRawBytes (&ptr, sizeof(ptr), endian::InlHostByteOrder(), endian::InlHostByteOrder()); } size_t @@ -641,7 +641,7 @@ Stream::PutFloat(float f, ByteOrder byte_order) if (byte_order == eByteOrderInvalid) byte_order = m_byte_order; - return PutRawBytes (&f, sizeof(f), lldb::endian::InlHostByteOrder(), byte_order); + return PutRawBytes (&f, sizeof(f), endian::InlHostByteOrder(), byte_order); } size_t @@ -650,7 +650,7 @@ Stream::PutDouble(double d, ByteOrder byte_order) if (byte_order == eByteOrderInvalid) byte_order = m_byte_order; - return PutRawBytes (&d, sizeof(d), lldb::endian::InlHostByteOrder(), byte_order); + return PutRawBytes (&d, sizeof(d), endian::InlHostByteOrder(), byte_order); } size_t @@ -659,7 +659,7 @@ Stream::PutLongDouble(long double ld, ByteOrder byte_order) if (byte_order == eByteOrderInvalid) byte_order = m_byte_order; - return PutRawBytes (&ld, sizeof(ld), lldb::endian::InlHostByteOrder(), byte_order); + return PutRawBytes (&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order); } size_t @@ -743,21 +743,21 @@ Stream::UnitTest(Stream *s) s->PutHex8(0x12); s->PutChar(' '); - s->PutHex16(0x3456, lldb::endian::InlHostByteOrder()); + s->PutHex16(0x3456, endian::InlHostByteOrder()); s->PutChar(' '); s->PutHex16(0x3456, eByteOrderBig); s->PutChar(' '); s->PutHex16(0x3456, eByteOrderLittle); s->PutChar(' '); - s->PutHex32(0x789abcde, lldb::endian::InlHostByteOrder()); + s->PutHex32(0x789abcde, endian::InlHostByteOrder()); s->PutChar(' '); s->PutHex32(0x789abcde, eByteOrderBig); s->PutChar(' '); s->PutHex32(0x789abcde, eByteOrderLittle); s->PutChar(' '); - s->PutHex64(0x1122334455667788ull, lldb::endian::InlHostByteOrder()); + s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder()); s->PutChar(' '); s->PutHex64(0x1122334455667788ull, eByteOrderBig); s->PutChar(' '); diff --git a/source/Core/StreamAsynchronousIO.cpp b/source/Core/StreamAsynchronousIO.cpp index ccfde0c9a0119..6f8fcce932e71 100644 --- a/source/Core/StreamAsynchronousIO.cpp +++ b/source/Core/StreamAsynchronousIO.cpp @@ -36,7 +36,7 @@ StreamAsynchronousIO::Flush () if (!m_data.empty()) { m_debugger.PrintAsync (m_data.data(), m_data.size(), m_for_stdout); - m_data = std::move(std::string()); + m_data = std::string(); } } diff --git a/source/Core/StreamString.cpp b/source/Core/StreamString.cpp index ef2b70583ebd3..36e086b0b4332 100644 --- a/source/Core/StreamString.cpp +++ b/source/Core/StreamString.cpp @@ -37,7 +37,7 @@ StreamString::Flush () size_t StreamString::Write (const void *s, size_t length) { - m_packet.append ((char *)s, length); + m_packet.append (reinterpret_cast<const char *>(s), length); return length; } diff --git a/source/Core/Timer.cpp b/source/Core/Timer.cpp index bbd990056ba08..e53ce2ec453de 100644 --- a/source/Core/Timer.cpp +++ b/source/Core/Timer.cpp @@ -21,12 +21,27 @@ using namespace lldb_private; #define TIMER_INDENT_AMOUNT 2 -static bool g_quiet = true; -uint32_t Timer::g_depth = 0; -uint32_t Timer::g_display_depth = 0; -FILE * Timer::g_file = NULL; -typedef std::vector<Timer *> TimerStack; -typedef std::map<const char *, uint64_t> TimerCategoryMap; + +namespace +{ + typedef std::map<const char*, uint64_t> TimerCategoryMap; + + struct TimerStack + { + TimerStack() : + m_depth(0) + {} + + uint32_t m_depth; + std::vector<Timer*> m_stack; + }; +} // end of anonymous namespace + +std::atomic<bool> Timer::g_quiet(true); +std::atomic<unsigned> Timer::g_display_depth(0); +std::mutex Timer::g_file_mutex; +FILE* Timer::g_file = nullptr; + static lldb::thread_key_t g_key; static Mutex & @@ -82,12 +97,18 @@ Timer::Timer (const char *category, const char *format, ...) : m_total_ticks (0), m_timer_ticks (0) { - if (g_depth++ < g_display_depth) + TimerStack *stack = GetTimerStackForCurrentThread (); + if (!stack) + return; + + if (stack->m_depth++ < g_display_depth) { if (g_quiet == false) { + std::lock_guard<std::mutex> lock(g_file_mutex); + // Indent - ::fprintf (g_file, "%*s", g_depth * TIMER_INDENT_AMOUNT, ""); + ::fprintf (g_file, "%*s", stack->m_depth * TIMER_INDENT_AMOUNT, ""); // Print formatted string va_list args; va_start (args, format); @@ -100,19 +121,19 @@ Timer::Timer (const char *category, const char *format, ...) : TimeValue start_time(TimeValue::Now()); m_total_start = start_time; m_timer_start = start_time; - TimerStack *stack = GetTimerStackForCurrentThread (); - if (stack) - { - if (stack->empty() == false) - stack->back()->ChildStarted (start_time); - stack->push_back(this); - } + + if (!stack->m_stack.empty()) + stack->m_stack.back()->ChildStarted (start_time); + stack->m_stack.push_back(this); } } - Timer::~Timer() { + TimerStack *stack = GetTimerStackForCurrentThread (); + if (!stack) + return; + if (m_total_start.IsValid()) { TimeValue stop_time = TimeValue::Now(); @@ -127,14 +148,10 @@ Timer::~Timer() m_timer_start.Clear(); } - TimerStack *stack = GetTimerStackForCurrentThread (); - if (stack) - { - assert (stack->back() == this); - stack->pop_back(); - if (stack->empty() == false) - stack->back()->ChildStopped(stop_time); - } + assert (stack->m_stack.back() == this); + stack->m_stack.pop_back(); + if (stack->m_stack.empty() == false) + stack->m_stack.back()->ChildStopped(stop_time); const uint64_t total_nsec_uint = GetTotalElapsedNanoSeconds(); const uint64_t timer_nsec_uint = GetTimerElapsedNanoSeconds(); @@ -143,10 +160,10 @@ Timer::~Timer() if (g_quiet == false) { - + std::lock_guard<std::mutex> lock(g_file_mutex); ::fprintf (g_file, "%*s%.9f sec (%.9f sec)\n", - (g_depth - 1) *TIMER_INDENT_AMOUNT, "", + (stack->m_depth - 1) *TIMER_INDENT_AMOUNT, "", total_nsec / 1000000000.0, timer_nsec / 1000000000.0); } @@ -156,8 +173,8 @@ Timer::~Timer() TimerCategoryMap &category_map = GetCategoryMap(); category_map[m_category] += timer_nsec_uint; } - if (g_depth > 0) - --g_depth; + if (stack->m_depth > 0) + --stack->m_depth; } uint64_t diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp index a416d0745a69f..a5c48e823ace7 100644 --- a/source/Core/Value.cpp +++ b/source/Core/Value.cpp @@ -18,7 +18,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/State.h" #include "lldb/Core/Stream.h" -#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" @@ -35,7 +35,7 @@ using namespace lldb_private; Value::Value() : m_value (), m_vector (), - m_clang_type (), + m_compiler_type (), m_context (NULL), m_value_type (eValueTypeScalar), m_context_type (eContextTypeInvalid), @@ -46,7 +46,7 @@ Value::Value() : Value::Value(const Scalar& scalar) : m_value (scalar), m_vector (), - m_clang_type (), + m_compiler_type (), m_context (NULL), m_value_type (eValueTypeScalar), m_context_type (eContextTypeInvalid), @@ -58,7 +58,7 @@ Value::Value(const Scalar& scalar) : Value::Value(const void *bytes, int len) : m_value (), m_vector (), - m_clang_type (), + m_compiler_type (), m_context (NULL), m_value_type (eValueTypeHostAddress), m_context_type (eContextTypeInvalid), @@ -70,7 +70,7 @@ Value::Value(const void *bytes, int len) : Value::Value(const Value &v) : m_value (v.m_value), m_vector (v.m_vector), - m_clang_type (v.m_clang_type), + m_compiler_type (v.m_compiler_type), m_context (v.m_context), m_value_type (v.m_value_type), m_context_type (v.m_context_type), @@ -93,7 +93,7 @@ Value::operator=(const Value &rhs) { m_value = rhs.m_value; m_vector = rhs.m_vector; - m_clang_type = rhs.m_clang_type; + m_compiler_type = rhs.m_compiler_type; m_context = rhs.m_context; m_value_type = rhs.m_value_type; m_context_type = rhs.m_context_type; @@ -189,7 +189,7 @@ Value::AppendDataToHostBuffer (const Value &rhs) { rhs.m_value.GetAsMemoryData (m_data_buffer.GetBytes() + curr_size, scalar_size, - lldb::endian::InlHostByteOrder(), + endian::InlHostByteOrder(), error); return scalar_size; } @@ -260,7 +260,7 @@ Value::ValueOf(ExecutionContext *exe_ctx) } uint64_t -Value::GetValueByteSize (Error *error_ptr) +Value::GetValueByteSize (Error *error_ptr, ExecutionContext *exe_ctx) { uint64_t byte_size = 0; @@ -275,9 +275,9 @@ Value::GetValueByteSize (Error *error_ptr) case eContextTypeLLDBType: // Type * case eContextTypeVariable: // Variable * { - const ClangASTType &ast_type = GetClangType(); + const CompilerType &ast_type = GetCompilerType(); if (ast_type.IsValid()) - byte_size = ast_type.GetByteSize(nullptr); + byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); } break; } @@ -297,10 +297,10 @@ Value::GetValueByteSize (Error *error_ptr) return byte_size; } -const ClangASTType & -Value::GetClangType () +const CompilerType & +Value::GetCompilerType () { - if (!m_clang_type.IsValid()) + if (!m_compiler_type.IsValid()) { switch (m_context_type) { @@ -308,13 +308,13 @@ Value::GetClangType () break; case eContextTypeRegisterInfo: - break; // TODO: Eventually convert into a clang type? + break; // TODO: Eventually convert into a compiler type? case eContextTypeLLDBType: { Type *lldb_type = GetType(); if (lldb_type) - m_clang_type = lldb_type->GetClangForwardType(); + m_compiler_type = lldb_type->GetForwardCompilerType (); } break; @@ -325,20 +325,20 @@ Value::GetClangType () { Type *variable_type = variable->GetType(); if (variable_type) - m_clang_type = variable_type->GetClangForwardType(); + m_compiler_type = variable_type->GetForwardCompilerType (); } } break; } } - return m_clang_type; + return m_compiler_type; } void -Value::SetClangType (const ClangASTType &clang_type) +Value::SetCompilerType (const CompilerType &compiler_type) { - m_clang_type = clang_type; + m_compiler_type = compiler_type; } lldb::Format @@ -355,7 +355,7 @@ Value::GetValueDefaultFormat () case eContextTypeLLDBType: case eContextTypeVariable: { - const ClangASTType &ast_type = GetClangType(); + const CompilerType &ast_type = GetCompilerType(); if (ast_type.IsValid()) return ast_type.GetFormat(); } @@ -407,7 +407,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, lldb::addr_t address = LLDB_INVALID_ADDRESS; AddressType address_type = eAddressTypeFile; Address file_so_addr; - const ClangASTType &ast_type = GetClangType(); + const CompilerType &ast_type = GetCompilerType(); switch (m_value_type) { case eValueTypeVector: @@ -420,7 +420,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, case eValueTypeScalar: { - data.SetByteOrder (lldb::endian::InlHostByteOrder()); + data.SetByteOrder (endian::InlHostByteOrder()); if (ast_type.IsValid()) data.SetAddressByteSize (ast_type.GetPointerByteSize()); else @@ -434,7 +434,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, lldb::Encoding type_encoding = ast_type.GetEncoding(type_encoding_count); if (type_encoding == eEncodingUint || type_encoding == eEncodingSint) - limit_byte_size = ast_type.GetByteSize(nullptr); + limit_byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); } if (m_value.GetData (data, limit_byte_size)) @@ -623,7 +623,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, } } // fallback to host settings - data.SetByteOrder(lldb::endian::InlHostByteOrder()); + data.SetByteOrder(endian::InlHostByteOrder()); data.SetAddressByteSize(sizeof(void *)); break; } @@ -639,7 +639,7 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, } // If we got here, we need to read the value from memory - size_t byte_size = GetValueByteSize (&error); + size_t byte_size = GetValueByteSize (&error, exe_ctx); // Bail if we encountered any errors getting the byte size if (error.Fail()) @@ -721,8 +721,8 @@ Value::GetValueAsData (ExecutionContext *exe_ctx, Scalar & Value::ResolveValue(ExecutionContext *exe_ctx) { - const ClangASTType &clang_type = GetClangType(); - if (clang_type.IsValid()) + const CompilerType &compiler_type = GetCompilerType(); + if (compiler_type.IsValid()) { switch (m_value_type) { @@ -740,7 +740,7 @@ Value::ResolveValue(ExecutionContext *exe_ctx) if (error.Success()) { Scalar scalar; - if (clang_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar)) + if (compiler_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar)) { m_value = scalar; m_value_type = eValueTypeScalar; @@ -782,7 +782,7 @@ Value::Clear() { m_value.Clear(); m_vector.Clear(); - m_clang_type.Clear(); + m_compiler_type.Clear(); m_value_type = eValueTypeScalar; m_context = NULL; m_context_type = eContextTypeInvalid; diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp index 8718b37b95e08..6b1a6c5906310 100644 --- a/source/Core/ValueObject.cpp +++ b/source/Core/ValueObject.cpp @@ -15,7 +15,6 @@ // C++ Includes // Other libraries and framework includes #include "llvm/Support/raw_ostream.h" -#include "clang/AST/Type.h" // Project includes #include "lldb/Core/DataBufferHeap.h" @@ -35,19 +34,20 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" -#include "lldb/Expression/ClangExpressionVariable.h" -#include "lldb/Expression/ClangPersistentVariables.h" +#include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h" +#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" #include "lldb/Host/Endian.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Type.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Language.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" @@ -97,6 +97,7 @@ ValueObject::ValueObject (ValueObject &parent) : m_address_type_of_ptr_or_ref_children(eAddressTypeInvalid), m_value_checksum(), m_preferred_display_language(lldb::eLanguageTypeUnknown), + m_language_flags(0), m_value_is_valid (false), m_value_did_change (false), m_children_count_valid (false), @@ -148,6 +149,7 @@ ValueObject::ValueObject (ExecutionContextScope *exe_scope, m_address_type_of_ptr_or_ref_children(child_ptr_or_ref_addr_type), m_value_checksum(), m_preferred_display_language(lldb::eLanguageTypeUnknown), + m_language_flags(0), m_value_is_valid (false), m_value_did_change (false), m_children_count_valid (false), @@ -276,7 +278,7 @@ ValueObject::UpdateValueIfNeeded (bool update_format) bool ValueObject::UpdateFormatsIfNeeded() { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES)); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS)); if (log) log->Printf("[%s %p] checking for FormatManager revisions. ValueObject rev: %d - Global rev: %d", GetName().GetCString(), static_cast<void*>(this), @@ -316,39 +318,39 @@ ValueObject::ClearDynamicTypeInformation () m_children_count_valid = false; m_did_calculate_complete_objc_class_type = false; m_last_format_mgr_revision = 0; - m_override_type = ClangASTType(); + m_override_type = CompilerType(); SetValueFormat(lldb::TypeFormatImplSP()); SetSummaryFormat(lldb::TypeSummaryImplSP()); SetSyntheticChildren(lldb::SyntheticChildrenSP()); } -ClangASTType +CompilerType ValueObject::MaybeCalculateCompleteType () { - ClangASTType clang_type(GetClangTypeImpl()); + CompilerType compiler_type(GetCompilerTypeImpl()); if (m_did_calculate_complete_objc_class_type) { if (m_override_type.IsValid()) return m_override_type; else - return clang_type; + return compiler_type; } - ClangASTType class_type; + CompilerType class_type; bool is_pointer_type = false; - if (clang_type.IsObjCObjectPointerType(&class_type)) + if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type)) { is_pointer_type = true; } - else if (clang_type.IsObjCObjectOrInterfaceType()) + else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type)) { - class_type = clang_type; + class_type = compiler_type; } else { - return clang_type; + return compiler_type; } m_did_calculate_complete_objc_class_type = true; @@ -371,7 +373,7 @@ ValueObject::MaybeCalculateCompleteType () if (complete_objc_class_type_sp) { - ClangASTType complete_class(complete_objc_class_type_sp->GetClangFullType()); + CompilerType complete_class(complete_objc_class_type_sp->GetFullCompilerType ()); if (complete_class.GetCompleteType()) { @@ -392,11 +394,11 @@ ValueObject::MaybeCalculateCompleteType () } } } - return clang_type; + return compiler_type; } -ClangASTType -ValueObject::GetClangType () +CompilerType +ValueObject::GetCompilerType () { return MaybeCalculateCompleteType(); } @@ -404,7 +406,7 @@ ValueObject::GetClangType () TypeImpl ValueObject::GetTypeImpl () { - return TypeImpl(GetClangType()); + return TypeImpl(GetCompilerType()); } DataExtractor & @@ -514,6 +516,39 @@ ValueObject::ResolveValue (Scalar &scalar) } bool +ValueObject::IsLogicalTrue (Error& error) +{ + if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) + { + LazyBool is_logical_true = language->IsLogicalTrue(*this, error); + switch (is_logical_true) + { + case eLazyBoolYes: + case eLazyBoolNo: + return (is_logical_true == true); + case eLazyBoolCalculate: + break; + } + } + + Scalar scalar_value; + + if (!ResolveValue (scalar_value)) + { + error.SetErrorString("failed to get a scalar result"); + return false; + } + + bool ret; + if (scalar_value.ULongLong(1) == 0) + ret = false; + else + ret = true; + error.Clear(); + return ret; +} + +bool ValueObject::GetValueIsValid () const { return m_value_is_valid; @@ -566,40 +601,16 @@ ValueObjectSP ValueObject::GetChildAtIndexPath (const std::initializer_list<size_t>& idxs, size_t* index_of_error) { - if (idxs.size() == 0) - return GetSP(); - ValueObjectSP root(GetSP()); - for (size_t idx : idxs) - { - root = root->GetChildAtIndex(idx, true); - if (!root) - { - if (index_of_error) - *index_of_error = idx; - return root; - } - } - return root; + return GetChildAtIndexPath( std::vector<size_t>(idxs), + index_of_error ); } ValueObjectSP ValueObject::GetChildAtIndexPath (const std::initializer_list< std::pair<size_t, bool> >& idxs, size_t* index_of_error) { - if (idxs.size() == 0) - return GetSP(); - ValueObjectSP root(GetSP()); - for (std::pair<size_t, bool> idx : idxs) - { - root = root->GetChildAtIndex(idx.first, idx.second); - if (!root) - { - if (index_of_error) - *index_of_error = idx.first; - return root; - } - } - return root; + return GetChildAtIndexPath( std::vector<std::pair<size_t,bool>>(idxs), + index_of_error ); } lldb::ValueObjectSP @@ -646,20 +657,16 @@ lldb::ValueObjectSP ValueObject::GetChildAtNamePath (const std::initializer_list<ConstString> &names, ConstString* name_of_error) { - if (names.size() == 0) - return GetSP(); - ValueObjectSP root(GetSP()); - for (ConstString name : names) - { - root = root->GetChildMemberWithName(name, true); - if (!root) - { - if (name_of_error) - *name_of_error = name; - return root; - } - } - return root; + return GetChildAtNamePath( std::vector<ConstString>(names), + name_of_error ); +} + +lldb::ValueObjectSP +ValueObject::GetChildAtNamePath (const std::initializer_list< std::pair<ConstString, bool> > &names, + ConstString* name_of_error) +{ + return GetChildAtNamePath( std::vector<std::pair<ConstString,bool>>(names), + name_of_error ); } lldb::ValueObjectSP @@ -683,7 +690,7 @@ ValueObject::GetChildAtNamePath (const std::vector<ConstString> &names, } lldb::ValueObjectSP -ValueObject::GetChildAtNamePath (const std::initializer_list< std::pair<ConstString, bool> > &names, +ValueObject::GetChildAtNamePath (const std::vector< std::pair<ConstString, bool> > &names, ConstString* name_of_error) { if (names.size() == 0) @@ -696,37 +703,17 @@ ValueObject::GetChildAtNamePath (const std::initializer_list< std::pair<ConstStr { if (name_of_error) *name_of_error = name.first; - return root; + return root; } } return root; } -lldb::ValueObjectSP -ValueObject::GetChildAtNamePath (const std::vector< std::pair<ConstString, bool> > &names, - ConstString* name_of_error) -{ - if (names.size() == 0) - return GetSP(); - ValueObjectSP root(GetSP()); - for (std::pair<ConstString, bool> name : names) - { - root = root->GetChildMemberWithName(name.first, name.second); - if (!root) - { - if (name_of_error) - *name_of_error = name.first; - return root; - } - } - return root; -} - size_t ValueObject::GetIndexOfChildWithName (const ConstString &name) { bool omit_empty_base_classes = true; - return GetClangType().GetIndexOfChildWithName (name.GetCString(), omit_empty_base_classes); + return GetCompilerType().GetIndexOfChildWithName (name.GetCString(), omit_empty_base_classes); } ValueObjectSP @@ -743,7 +730,7 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) std::vector<uint32_t> child_indexes; bool omit_empty_base_classes = true; - const size_t num_child_indexes = GetClangType().GetIndexOfChildMemberWithName (name.GetCString(), + const size_t num_child_indexes = GetCompilerType().GetIndexOfChildMemberWithName (name.GetCString(), omit_empty_base_classes, child_indexes); if (num_child_indexes > 0) @@ -771,9 +758,21 @@ ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create) size_t -ValueObject::GetNumChildren () +ValueObject::GetNumChildren (uint32_t max) { UpdateValueIfNeeded(); + + if (max < UINT32_MAX) + { + if (m_children_count_valid) + { + size_t children_count = m_children.GetChildrenCount(); + return children_count <= max ? children_count : max; + } + else + return CalculateNumChildren(max); + } + if (!m_children_count_valid) { SetNumChildren (CalculateNumChildren()); @@ -828,26 +827,28 @@ ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_ uint32_t child_bitfield_bit_offset = 0; bool child_is_base_class = false; bool child_is_deref_of_parent = false; + uint64_t language_flags = 0; const bool transparent_pointers = synthetic_array_member == false; - ClangASTType child_clang_type; + CompilerType child_compiler_type; ExecutionContext exe_ctx (GetExecutionContextRef()); - child_clang_type = GetClangType().GetChildClangTypeAtIndex (&exe_ctx, - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name_str, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent, - this); - if (child_clang_type) + child_compiler_type = GetCompilerType().GetChildCompilerTypeAtIndex (&exe_ctx, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent, + this, + language_flags); + if (child_compiler_type) { if (synthetic_index) child_byte_offset += child_byte_size * synthetic_index; @@ -857,7 +858,7 @@ ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_ child_name.SetCString (child_name_str.c_str()); valobj = new ValueObjectChild (*this, - child_clang_type, + child_compiler_type, child_name, child_byte_size, child_byte_offset, @@ -865,7 +866,8 @@ ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_ child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, - eAddressTypeInvalid); + eAddressTypeInvalid, + language_flags); //if (valobj) // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid); } @@ -875,9 +877,10 @@ ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_ bool ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr, - std::string& destination) + std::string& destination, + lldb::LanguageType lang) { - return GetSummaryAsCString(summary_ptr, destination, TypeSummaryOptions()); + return GetSummaryAsCString(summary_ptr, destination, TypeSummaryOptions().SetLanguage(lang)); } bool @@ -886,7 +889,7 @@ ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr, const TypeSummaryOptions& options) { destination.clear(); - + // ideally we would like to bail out if passing NULL, but if we do so // we end up not providing the summary for function pointers anymore if (/*summary_ptr == NULL ||*/ m_is_getting_summary) @@ -894,31 +897,38 @@ ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr, m_is_getting_summary = true; + TypeSummaryOptions actual_options(options); + + if (actual_options.GetLanguage() == lldb::eLanguageTypeUnknown) + actual_options.SetLanguage(GetPreferredDisplayLanguage()); + // this is a hot path in code and we prefer to avoid setting this string all too often also clearing out other // information that we might care to see in a crash log. might be useful in very specific situations though. /*Host::SetCrashDescriptionWithFormat("Trying to fetch a summary for %s %s. Summary provider's description is %s", - GetTypeName().GetCString(), - GetName().GetCString(), - summary_ptr->GetDescription().c_str());*/ + GetTypeName().GetCString(), + GetName().GetCString(), + summary_ptr->GetDescription().c_str());*/ if (UpdateValueIfNeeded (false) && summary_ptr) { if (HasSyntheticValue()) m_synthetic_value->UpdateValueIfNeeded(); // the summary might depend on the synthetic children being up-to-date (e.g. ${svar%#}) - summary_ptr->FormatObject(this, destination, options); + summary_ptr->FormatObject(this, destination, actual_options); } m_is_getting_summary = false; return !destination.empty(); } const char * -ValueObject::GetSummaryAsCString () +ValueObject::GetSummaryAsCString (lldb::LanguageType lang) { if (UpdateValueIfNeeded(true) && m_summary_str.empty()) { + TypeSummaryOptions summary_options; + summary_options.SetLanguage(lang); GetSummaryAsCString(GetSummaryFormat().get(), m_summary_str, - TypeSummaryOptions()); + summary_options); } if (m_summary_str.empty()) return NULL; @@ -930,17 +940,17 @@ ValueObject::GetSummaryAsCString (std::string& destination, const TypeSummaryOptions& options) { return GetSummaryAsCString(GetSummaryFormat().get(), - destination, - options); + destination, + options); } bool ValueObject::IsCStringContainer(bool check_pointer) { - ClangASTType pointee_or_element_clang_type; - const Flags type_flags (GetTypeInfo (&pointee_or_element_clang_type)); + CompilerType pointee_or_element_compiler_type; + const Flags type_flags (GetTypeInfo (&pointee_or_element_compiler_type)); bool is_char_arr_ptr (type_flags.AnySet (eTypeIsArray | eTypeIsPointer) && - pointee_or_element_clang_type.IsCharType ()); + pointee_or_element_compiler_type.IsCharType ()); if (!is_char_arr_ptr) return false; if (!check_pointer) @@ -958,8 +968,8 @@ ValueObject::GetPointeeData (DataExtractor& data, uint32_t item_idx, uint32_t item_count) { - ClangASTType pointee_or_element_clang_type; - const uint32_t type_info = GetTypeInfo (&pointee_or_element_clang_type); + CompilerType pointee_or_element_compiler_type; + const uint32_t type_info = GetTypeInfo (&pointee_or_element_compiler_type); const bool is_pointer_type = type_info & eTypeIsPointer; const bool is_array_type = type_info & eTypeIsArray; if (!(is_pointer_type || is_array_type)) @@ -970,7 +980,7 @@ ValueObject::GetPointeeData (DataExtractor& data, ExecutionContext exe_ctx (GetExecutionContextRef()); - const uint64_t item_type_size = pointee_or_element_clang_type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); + const uint64_t item_type_size = pointee_or_element_compiler_type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); const uint64_t bytes = item_count * item_type_size; const uint64_t offset = item_idx * item_type_size; @@ -1046,12 +1056,12 @@ ValueObject::GetPointeeData (DataExtractor& data, break; case eAddressTypeHost: { - const uint64_t max_bytes = GetClangType().GetByteSize(exe_ctx.GetBestExecutionContextScope()); + const uint64_t max_bytes = GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()); if (max_bytes > offset) { size_t bytes_read = std::min<uint64_t>(max_bytes - offset, bytes); addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); - if (addr == LLDB_INVALID_ADDRESS) + if (addr == 0 || addr == LLDB_INVALID_ADDRESS) break; heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes_read); data.SetData(data_sp); @@ -1077,6 +1087,7 @@ ValueObject::GetData (DataExtractor& data, Error &error) if (m_data.GetByteSize()) { data = m_data; + error.Clear(); return data.GetByteSize(); } else @@ -1102,7 +1113,7 @@ ValueObject::SetData (DataExtractor &data, Error &error) } uint64_t count = 0; - const Encoding encoding = GetClangType().GetEncoding(count); + const Encoding encoding = GetCompilerType().GetEncoding(count); const size_t byte_size = GetByteSize(); @@ -1167,31 +1178,6 @@ ValueObject::SetData (DataExtractor &data, Error &error) return true; } -// will compute strlen(str), but without consuming more than -// maxlen bytes out of str (this serves the purpose of reading -// chunks of a string without having to worry about -// missing NULL terminators in the chunk) -// of course, if strlen(str) > maxlen, the function will return -// maxlen_value (which should be != maxlen, because that allows you -// to know whether strlen(str) == maxlen or strlen(str) > maxlen) -static uint32_t -strlen_or_inf (const char* str, - uint32_t maxlen, - uint32_t maxlen_value) -{ - uint32_t len = 0; - if (str) - { - while(*str) - { - len++;str++; - if (len >= maxlen) - return maxlen_value; - } - } - return len; -} - static bool CopyStringDataToBufferSP(const StreamString& source, lldb::DataBufferSP& destination) @@ -1201,13 +1187,14 @@ CopyStringDataToBufferSP(const StreamString& source, return true; } -size_t +std::pair<size_t,bool> ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, Error& error, uint32_t max_length, bool honor_array, Format item_format) { + bool was_capped = false; StreamString s; ExecutionContext exe_ctx (GetExecutionContextRef()); Target* target = exe_ctx.GetTargetPtr(); @@ -1217,7 +1204,7 @@ ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, s << "<no target to read from>"; error.SetErrorString("no target to read from"); CopyStringDataToBufferSP(s, buffer_sp); - return 0; + return {0,was_capped}; } if (max_length == 0) @@ -1226,11 +1213,11 @@ ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, size_t bytes_read = 0; size_t total_bytes_read = 0; - ClangASTType clang_type = GetClangType(); - ClangASTType elem_or_pointee_clang_type; - const Flags type_flags (GetTypeInfo (&elem_or_pointee_clang_type)); + CompilerType compiler_type = GetCompilerType(); + CompilerType elem_or_pointee_compiler_type; + const Flags type_flags (GetTypeInfo (&elem_or_pointee_compiler_type)); if (type_flags.AnySet (eTypeIsArray | eTypeIsPointer) && - elem_or_pointee_clang_type.IsCharType ()) + elem_or_pointee_compiler_type.IsCharType ()) { addr_t cstr_address = LLDB_INVALID_ADDRESS; AddressType cstr_address_type = eAddressTypeInvalid; @@ -1241,7 +1228,7 @@ ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, { // We have an array uint64_t array_size = 0; - if (clang_type.IsArrayType(NULL, &array_size, NULL)) + if (compiler_type.IsArrayType(NULL, &array_size, NULL)) { cstr_len = array_size; if (cstr_len > max_length) @@ -1263,7 +1250,7 @@ ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, s << "<invalid address>"; error.SetErrorString("invalid address"); CopyStringDataToBufferSP(s, buffer_sp); - return 0; + return {0,was_capped}; } Address cstr_so_addr (cstr_address); @@ -1280,7 +1267,7 @@ ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, for (size_t offset = 0; offset < bytes_read; offset++) s.Printf("%c", *data.PeekData(offset, 1)); if (capped_data) - s << "..."; + was_capped = true; } } else @@ -1298,10 +1285,7 @@ ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, { total_bytes_read += bytes_read; const char *cstr = data.PeekCStr(0); - size_t len = strlen_or_inf (cstr, k_max_buf_size, k_max_buf_size+1); - if (len > k_max_buf_size) - len = k_max_buf_size; - + size_t len = strnlen (cstr, k_max_buf_size); if (cstr_len_displayed < 0) cstr_len_displayed = len; @@ -1332,7 +1316,7 @@ ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, if (cstr_len_displayed >= 0) { if (capped_cstr) - s << "..."; + was_capped = true; } } } @@ -1342,7 +1326,7 @@ ValueObject::ReadPointedString (lldb::DataBufferSP& buffer_sp, s << "<not a string object>"; } CopyStringDataToBufferSP(s, buffer_sp); - return total_bytes_read; + return {total_bytes_read,was_capped}; } std::pair<TypeValidatorResult, std::string> @@ -1385,11 +1369,11 @@ ValueObject::GetObjectDescription () if (runtime == NULL) { // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway... - ClangASTType clang_type = GetClangType(); - if (clang_type) + CompilerType compiler_type = GetCompilerType(); + if (compiler_type) { bool is_signed; - if (clang_type.IsIntegerType (is_signed) || clang_type.IsPointerType ()) + if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType ()) { runtime = process->GetLanguageRuntime(eLanguageTypeObjC); } @@ -1449,7 +1433,7 @@ ValueObject::GetValueAsCString () } else { - my_format = GetValue().GetClangType().GetFormat(); + my_format = GetValue().GetCompilerType().GetFormat(); } } } @@ -1590,18 +1574,19 @@ ValueObject::DumpPrintableRepresentation(Stream& s, { Error error; lldb::DataBufferSP buffer_sp; - ReadPointedString(buffer_sp, - error, - 0, - (custom_format == eFormatVectorOfChar) || - (custom_format == eFormatCharArray)); - lldb_private::formatters::ReadBufferAndDumpToStreamOptions options(*this); + std::pair<size_t, bool> read_string = ReadPointedString(buffer_sp, + error, + 0, + (custom_format == eFormatVectorOfChar) || + (custom_format == eFormatCharArray)); + lldb_private::formatters::StringPrinter::ReadBufferAndDumpToStreamOptions options(*this); options.SetData(DataExtractor(buffer_sp, lldb::eByteOrderInvalid, 8)); // none of this matters for a string - pass some defaults options.SetStream(&s); options.SetPrefixToken(0); options.SetQuote('"'); options.SetSourceSize(buffer_sp->GetByteSize()); - lldb_private::formatters::ReadBufferAndDumpToStream<lldb_private::formatters::StringElementType::ASCII>(options); + options.SetIsTruncated(read_string.second); + formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::ASCII>(options); return !error.Fail(); } @@ -1886,7 +1871,7 @@ ValueObject::SetValueFromCString (const char *value_str, Error& error) } uint64_t count = 0; - const Encoding encoding = GetClangType().GetEncoding (count); + const Encoding encoding = GetCompilerType().GetEncoding (count); const size_t byte_size = GetByteSize(); @@ -1897,7 +1882,7 @@ ValueObject::SetValueFromCString (const char *value_str, Error& error) // If the value is already a scalar, then let the scalar change itself: m_value.GetScalar().SetValueFromCString (value_str, encoding, byte_size); } - else if (byte_size <= Scalar::GetMaxByteSize()) + else if (byte_size <= 16) { // If the value fits in a scalar, then make a new scalar and again let the // scalar code do the conversion, then figure out where to put the new value. @@ -1984,7 +1969,7 @@ ValueObject::GetDeclaration (Declaration &decl) ConstString ValueObject::GetTypeName() { - return GetClangType().GetConstTypeName(); + return GetCompilerType().GetConstTypeName(); } ConstString @@ -1996,14 +1981,14 @@ ValueObject::GetDisplayTypeName() ConstString ValueObject::GetQualifiedTypeName() { - return GetClangType().GetConstQualifiedTypeName(); + return GetCompilerType().GetConstQualifiedTypeName(); } LanguageType ValueObject::GetObjectRuntimeLanguage () { - return GetClangType().GetMinimumLanguage (); + return GetCompilerType().GetMinimumLanguage (); } void @@ -2023,39 +2008,39 @@ ValueObject::GetSyntheticChild (const ConstString &key) const } uint32_t -ValueObject::GetTypeInfo (ClangASTType *pointee_or_element_clang_type) +ValueObject::GetTypeInfo (CompilerType *pointee_or_element_compiler_type) { - return GetClangType().GetTypeInfo (pointee_or_element_clang_type); + return GetCompilerType().GetTypeInfo (pointee_or_element_compiler_type); } bool ValueObject::IsPointerType () { - return GetClangType().IsPointerType(); + return GetCompilerType().IsPointerType(); } bool ValueObject::IsArrayType () { - return GetClangType().IsArrayType (NULL, NULL, NULL); + return GetCompilerType().IsArrayType (NULL, NULL, NULL); } bool ValueObject::IsScalarType () { - return GetClangType().IsScalarType (); + return GetCompilerType().IsScalarType (); } bool ValueObject::IsIntegerType (bool &is_signed) { - return GetClangType().IsIntegerType (is_signed); + return GetCompilerType().IsIntegerType (is_signed); } bool ValueObject::IsPointerOrReferenceType () { - return GetClangType().IsPointerOrReferenceType (); + return GetCompilerType().IsPointerOrReferenceType (); } bool @@ -2066,7 +2051,7 @@ ValueObject::IsPossibleDynamicType () if (process) return process->IsPossibleDynamicValue(*this); else - return GetClangType().IsPossibleDynamicType (NULL, true, true); + return GetCompilerType().IsPossibleDynamicType (NULL, true, true); } bool @@ -2085,15 +2070,23 @@ ValueObject::IsRuntimeSupportValue () } bool -ValueObject::IsObjCNil () +ValueObject::IsNilReference () { - const uint32_t mask = eTypeIsObjC | eTypeIsPointer; - bool isObjCpointer = (((GetClangType().GetTypeInfo(NULL)) & mask) == mask); - if (!isObjCpointer) - return false; - bool canReadValue = true; - bool isZero = GetValueAsUnsigned(0,&canReadValue) == 0; - return canReadValue && isZero; + if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) + { + return language->IsNilReference(*this); + } + return false; +} + +bool +ValueObject::IsUninitializedReference () +{ + if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) + { + return language->IsUninitializedReference(*this); + } + return false; } // This allows you to create an array member using and index @@ -2156,7 +2149,7 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre // We haven't made a synthetic array member for INDEX yet, so // lets make one and cache it for any future reference. ValueObjectChild *synthetic_child = new ValueObjectChild (*this, - GetClangType(), + GetCompilerType(), index_const_str, GetByteSize(), 0, @@ -2164,7 +2157,8 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre from, false, false, - eAddressTypeInvalid); + eAddressTypeInvalid, + 0); // Cache the value if we got one back... if (synthetic_child) @@ -2180,7 +2174,7 @@ ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_cre } ValueObjectSP -ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create) +ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create) { ValueObjectSP synthetic_child_sp; @@ -2210,7 +2204,8 @@ ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type 0, false, false, - eAddressTypeInvalid); + eAddressTypeInvalid, + 0); if (synthetic_child) { AddSyntheticChild(name_const_str, synthetic_child); @@ -2222,7 +2217,7 @@ ValueObject::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type } ValueObjectSP -ValueObject::GetSyntheticBase (uint32_t offset, const ClangASTType& type, bool can_create) +ValueObject::GetSyntheticBase (uint32_t offset, const CompilerType& type, bool can_create) { ValueObjectSP synthetic_child_sp; @@ -2253,7 +2248,8 @@ ValueObject::GetSyntheticBase (uint32_t offset, const ClangASTType& type, bool c 0, is_base_class, false, - eAddressTypeInvalid); + eAddressTypeInvalid, + 0); if (synthetic_child) { AddSyntheticChild(name_const_str, synthetic_child); @@ -2417,9 +2413,9 @@ ValueObject::GetBaseClassPath (Stream &s) if (IsBaseClass()) { bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s); - ClangASTType clang_type = GetClangType(); + CompilerType compiler_type = GetCompilerType(); std::string cxx_class_name; - bool this_had_base_class = clang_type.GetCXXClassName (cxx_class_name); + bool this_had_base_class = ClangASTContext::GetCXXClassName (compiler_type, cxx_class_name); if (this_had_base_class) { if (parent_had_base_class) @@ -2536,8 +2532,8 @@ ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExp ValueObject *non_base_class_parent = GetNonBaseClassParent(); if (non_base_class_parent) { - ClangASTType non_base_class_parent_clang_type = non_base_class_parent->GetClangType(); - if (non_base_class_parent_clang_type) + CompilerType non_base_class_parent_compiler_type = non_base_class_parent->GetCompilerType(); + if (non_base_class_parent_compiler_type) { if (parent && parent->IsDereferenceOfParent() && epformat == eGetExpressionPathFormatHonorPointers) { @@ -2545,7 +2541,7 @@ ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExp } else { - const uint32_t non_base_class_parent_type_info = non_base_class_parent_clang_type.GetTypeInfo(); + const uint32_t non_base_class_parent_type_info = non_base_class_parent_compiler_type.GetTypeInfo(); if (non_base_class_parent_type_info & eTypeIsPointer) { @@ -2757,13 +2753,13 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr - ClangASTType root_clang_type = root->GetClangType(); - ClangASTType pointee_clang_type; - Flags pointee_clang_type_info; + CompilerType root_compiler_type = root->GetCompilerType(); + CompilerType pointee_compiler_type; + Flags pointee_compiler_type_info; - Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type)); - if (pointee_clang_type) - pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo()); + Flags root_compiler_type_info(root_compiler_type.GetTypeInfo(&pointee_compiler_type)); + if (pointee_compiler_type) + pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo()); if (!expression_cstr || *expression_cstr == '\0') { @@ -2776,15 +2772,15 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, case '-': { if (options.m_check_dot_vs_arrow_syntax && - root_clang_type_info.Test(eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error + root_compiler_type_info.Test(eTypeIsPointer) ) // if you are trying to use -> on a non-pointer and I must catch the error { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot; *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; return ValueObjectSP(); } - if (root_clang_type_info.Test(eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden - root_clang_type_info.Test(eTypeIsPointer) && + if (root_compiler_type_info.Test(eTypeIsObjC) && // if yo are trying to extract an ObjC IVar when this is forbidden + root_compiler_type_info.Test(eTypeIsPointer) && options.m_no_fragile_ivar) { *first_unparsed = expression_cstr; @@ -2804,7 +2800,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, case '.': // or fallthrough from -> { if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' && - root_clang_type_info.Test(eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error + root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to use . on a pointer and I must catch the error { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow; @@ -2953,9 +2949,9 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } case '[': { - if (!root_clang_type_info.Test(eTypeIsArray) && !root_clang_type_info.Test(eTypeIsPointer) && !root_clang_type_info.Test(eTypeIsVector)) // if this is not a T[] nor a T* + if (!root_compiler_type_info.Test(eTypeIsArray) && !root_compiler_type_info.Test(eTypeIsPointer) && !root_compiler_type_info.Test(eTypeIsVector)) // if this is not a T[] nor a T* { - if (!root_clang_type_info.Test(eTypeIsScalar)) // if this is not even a scalar... + if (!root_compiler_type_info.Test(eTypeIsScalar)) // if this is not even a scalar... { if (options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None) // ...only chance left is synthetic { @@ -2975,7 +2971,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays { - if (!root_clang_type_info.Test(eTypeIsArray)) + if (!root_compiler_type_info.Test(eTypeIsArray)) { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed; @@ -3012,7 +3008,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays { - if (root_clang_type_info.Test(eTypeIsArray)) + if (root_compiler_type_info.Test(eTypeIsArray)) { *first_unparsed = expression_cstr+2; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet; @@ -3028,7 +3024,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } } // from here on we do have a valid index - if (root_clang_type_info.Test(eTypeIsArray)) + if (root_compiler_type_info.Test(eTypeIsArray)) { ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true); if (!child_valobj_sp) @@ -3051,10 +3047,10 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, return ValueObjectSP(); } } - else if (root_clang_type_info.Test(eTypeIsPointer)) + else if (root_compiler_type_info.Test(eTypeIsPointer)) { if (*what_next == ValueObject::eExpressionPathAftermathDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield - pointee_clang_type_info.Test(eTypeIsScalar)) + pointee_compiler_type_info.Test(eTypeIsScalar)) { Error error; root = root->Dereference(error); @@ -3073,8 +3069,8 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } else { - if (root->GetClangType().GetMinimumLanguage() == eLanguageTypeObjC - && pointee_clang_type_info.AllClear(eTypeIsPointer) + if (root->GetCompilerType().GetMinimumLanguage() == eLanguageTypeObjC + && pointee_compiler_type_info.AllClear(eTypeIsPointer) && root->HasSyntheticValue() && (options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::ToSynthetic || options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both)) @@ -3098,7 +3094,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, } } } - else if (root_clang_type_info.Test(eTypeIsScalar)) + else if (root_compiler_type_info.Test(eTypeIsScalar)) { root = root->GetSyntheticBitFieldChild(index, index, true); if (!root.get()) @@ -3116,7 +3112,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, return root; } } - else if (root_clang_type_info.Test(eTypeIsVector)) + else if (root_compiler_type_info.Test(eTypeIsVector)) { root = root->GetChildAtIndex(index, true); if (!root.get()) @@ -3202,7 +3198,7 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, index_lower = index_higher; index_higher = temp; } - if (root_clang_type_info.Test(eTypeIsScalar)) // expansion only works for scalars + if (root_compiler_type_info.Test(eTypeIsScalar)) // expansion only works for scalars { root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); if (!root.get()) @@ -3220,9 +3216,9 @@ ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr, return root; } } - else if (root_clang_type_info.Test(eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield + else if (root_compiler_type_info.Test(eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield *what_next == ValueObject::eExpressionPathAftermathDereference && - pointee_clang_type_info.Test(eTypeIsScalar)) + pointee_compiler_type_info.Test(eTypeIsScalar)) { Error error; root = root->Dereference(error); @@ -3281,12 +3277,12 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr - ClangASTType root_clang_type = root->GetClangType(); - ClangASTType pointee_clang_type; - Flags pointee_clang_type_info; - Flags root_clang_type_info(root_clang_type.GetTypeInfo(&pointee_clang_type)); - if (pointee_clang_type) - pointee_clang_type_info.Reset(pointee_clang_type.GetTypeInfo()); + CompilerType root_compiler_type = root->GetCompilerType(); + CompilerType pointee_compiler_type; + Flags pointee_compiler_type_info; + Flags root_compiler_type_info(root_compiler_type.GetTypeInfo(&pointee_compiler_type)); + if (pointee_compiler_type) + pointee_compiler_type_info.Reset(pointee_compiler_type.GetTypeInfo()); if (!expression_cstr || *expression_cstr == '\0') { @@ -3299,9 +3295,9 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, { case '[': { - if (!root_clang_type_info.Test(eTypeIsArray) && !root_clang_type_info.Test(eTypeIsPointer)) // if this is not a T[] nor a T* + if (!root_compiler_type_info.Test(eTypeIsArray) && !root_compiler_type_info.Test(eTypeIsPointer)) // if this is not a T[] nor a T* { - if (!root_clang_type_info.Test(eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong! + if (!root_compiler_type_info.Test(eTypeIsScalar)) // if this is not even a scalar, this syntax is just plain wrong! { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid; @@ -3318,7 +3314,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, } if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays { - if (!root_clang_type_info.Test(eTypeIsArray)) + if (!root_compiler_type_info.Test(eTypeIsArray)) { *first_unparsed = expression_cstr; *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed; @@ -3362,7 +3358,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, } if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays { - if (root_clang_type_info.Test(eTypeIsArray)) + if (root_compiler_type_info.Test(eTypeIsArray)) { const size_t max_index = root->GetNumChildren() - 1; for (size_t index = 0; index < max_index; index++) @@ -3385,7 +3381,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, } } // from here on we do have a valid index - if (root_clang_type_info.Test(eTypeIsArray)) + if (root_compiler_type_info.Test(eTypeIsArray)) { root = root->GetChildAtIndex(index, true); if (!root.get()) @@ -3404,10 +3400,10 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, return 1; } } - else if (root_clang_type_info.Test(eTypeIsPointer)) + else if (root_compiler_type_info.Test(eTypeIsPointer)) { if (*what_next == ValueObject::eExpressionPathAftermathDereference && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield - pointee_clang_type_info.Test(eTypeIsScalar)) + pointee_compiler_type_info.Test(eTypeIsScalar)) { Error error; root = root->Dereference(error); @@ -3444,7 +3440,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, } } } - else /*if (ClangASTContext::IsScalarType(root_clang_type))*/ + else /*if (ClangASTContext::IsScalarType(root_compiler_type))*/ { root = root->GetSyntheticBitFieldChild(index, index, true); if (!root.get()) @@ -3489,7 +3485,7 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, index_lower = index_higher; index_higher = temp; } - if (root_clang_type_info.Test(eTypeIsScalar)) // expansion only works for scalars + if (root_compiler_type_info.Test(eTypeIsScalar)) // expansion only works for scalars { root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true); if (!root.get()) @@ -3508,9 +3504,9 @@ ValueObject::ExpandArraySliceExpression(const char* expression_cstr, return 1; } } - else if (root_clang_type_info.Test(eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield + else if (root_compiler_type_info.Test(eTypeIsPointer) && // if this is a ptr-to-scalar, I am accessing it by index and I would have deref'ed anyway, then do it now and use this as a bitfield *what_next == ValueObject::eExpressionPathAftermathDereference && - pointee_clang_type_info.Test(eTypeIsScalar)) + pointee_compiler_type_info.Test(eTypeIsScalar)) { Error error; root = root->Dereference(error); @@ -3611,7 +3607,7 @@ ValueObject::CreateConstantValue (const ConstString &name) m_error = m_value.GetValueAsData (&exe_ctx, data, 0, GetModule().get()); valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - GetClangType(), + GetCompilerType(), name, data, GetAddressOf()); @@ -3677,8 +3673,8 @@ ValueObject::GetQualifiedRepresentationIfAvailable (lldb::DynamicValueType dynVa lldb::addr_t ValueObject::GetCPPVTableAddress (AddressType &address_type) { - ClangASTType pointee_type; - ClangASTType this_type(GetClangType()); + CompilerType pointee_type; + CompilerType this_type(GetCompilerType()); uint32_t type_info = this_type.GetTypeInfo(&pointee_type); if (type_info) { @@ -3711,9 +3707,9 @@ ValueObject::Dereference (Error &error) { if (m_deref_valobj) return m_deref_valobj->GetSP(); - - const bool is_pointer_type = IsPointerType(); - if (is_pointer_type) + + const bool is_pointer_or_reference_type = IsPointerOrReferenceType(); + if (is_pointer_or_reference_type) { bool omit_empty_base_classes = true; bool ignore_array_bounds = false; @@ -3726,32 +3722,34 @@ ValueObject::Dereference (Error &error) bool child_is_base_class = false; bool child_is_deref_of_parent = false; const bool transparent_pointers = false; - ClangASTType clang_type = GetClangType(); - ClangASTType child_clang_type; + CompilerType compiler_type = GetCompilerType(); + CompilerType child_compiler_type; + uint64_t language_flags; ExecutionContext exe_ctx (GetExecutionContextRef()); - - child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx, - 0, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name_str, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent, - this); - if (child_clang_type && child_byte_size) + + child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex (&exe_ctx, + 0, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent, + this, + language_flags); + if (child_compiler_type && child_byte_size) { ConstString child_name; if (!child_name_str.empty()) child_name.SetCString (child_name_str.c_str()); m_deref_valobj = new ValueObjectChild (*this, - child_clang_type, + child_compiler_type, child_name, child_byte_size, child_byte_offset, @@ -3759,7 +3757,8 @@ ValueObject::Dereference (Error &error) child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, - eAddressTypeInvalid); + eAddressTypeInvalid, + language_flags); } } @@ -3773,10 +3772,10 @@ ValueObject::Dereference (Error &error) StreamString strm; GetExpressionPath(strm, true); - if (is_pointer_type) + if (is_pointer_or_reference_type) error.SetErrorStringWithFormat("dereference failed: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); else - error.SetErrorStringWithFormat("not a pointer type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); + error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str()); return ValueObjectSP(); } } @@ -3806,14 +3805,14 @@ ValueObject::AddressOf (Error &error) case eAddressTypeFile: case eAddressTypeLoad: { - ClangASTType clang_type = GetClangType(); - if (clang_type) + CompilerType compiler_type = GetCompilerType(); + if (compiler_type) { std::string name (1, '&'); name.append (m_name.AsCString("")); ExecutionContext exe_ctx (GetExecutionContextRef()); m_addr_of_valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - clang_type.GetPointerType(), + compiler_type.GetPointerType(), ConstString (name.c_str()), addr, eAddressTypeInvalid, @@ -3836,13 +3835,13 @@ ValueObject::AddressOf (Error &error) } ValueObjectSP -ValueObject::Cast (const ClangASTType &clang_ast_type) +ValueObject::Cast (const CompilerType &compiler_type) { - return ValueObjectCast::Create (*this, GetName(), clang_ast_type); + return ValueObjectCast::Create (*this, GetName(), compiler_type); } ValueObjectSP -ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type) +ValueObject::CastPointerType (const char *name, CompilerType &compiler_type) { ValueObjectSP valobj_sp; AddressType address_type; @@ -3855,7 +3854,7 @@ ValueObject::CastPointerType (const char *name, ClangASTType &clang_ast_type) valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, - clang_ast_type); + compiler_type); } return valobj_sp; } @@ -4104,11 +4103,11 @@ lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress (const char* name, uint64_t address, const ExecutionContext& exe_ctx, - ClangASTType type) + CompilerType type) { if (type) { - ClangASTType pointer_type(type.GetPointerType()); + CompilerType pointer_type(type.GetPointerType()); if (pointer_type) { lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t))); @@ -4136,7 +4135,7 @@ lldb::ValueObjectSP ValueObject::CreateValueObjectFromData (const char* name, const DataExtractor& data, const ExecutionContext& exe_ctx, - ClangASTType type) + CompilerType type) { lldb::ValueObjectSP new_value_sp; new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), @@ -4252,13 +4251,20 @@ ValueObject::SetPreferredDisplayLanguage (lldb::LanguageType lt) m_preferred_display_language = lt; } +void +ValueObject::SetPreferredDisplayLanguageIfNeeded (lldb::LanguageType lt) +{ + if (m_preferred_display_language == lldb::eLanguageTypeUnknown) + SetPreferredDisplayLanguage(lt); +} + bool ValueObject::CanProvideValue () { // we need to support invalid types as providers of values because some bare-board // debugging scenarios have no notion of types, but still manage to have raw numeric // values for things like registers. sigh. - const ClangASTType &type(GetClangType()); + const CompilerType &type(GetCompilerType()); return (false == type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue)); } @@ -4278,15 +4284,18 @@ ValueObject::Persist () if (!target_sp) return nullptr; - ConstString name(target_sp->GetPersistentVariables().GetNextPersistentVariableName()); + PersistentExpressionState *persistent_state = target_sp->GetPersistentExpressionStateForLanguage(GetPreferredDisplayLanguage()); - ClangExpressionVariableSP clang_var_sp(new ClangExpressionVariable(target_sp.get(), GetValue(), name)); - if (clang_var_sp) - { - clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp; - clang_var_sp->m_flags |= ClangExpressionVariable::EVIsProgramReference; - target_sp->GetPersistentVariables().AddVariable(clang_var_sp); - } + if (!persistent_state) + return nullptr; + + ConstString name(persistent_state->GetNextPersistentVariableName()); + + ValueObjectSP const_result_sp = ValueObjectConstResult::Create (target_sp.get(), GetValue(), name); + + ExpressionVariableSP clang_var_sp = persistent_state->CreatePersistentVariable(const_result_sp); + clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp; + clang_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference; return clang_var_sp->GetValueObject(); } @@ -4302,3 +4311,15 @@ ValueObject::SetSyntheticChildrenGenerated (bool b) { m_is_synthetic_children_generated = b; } + +uint64_t +ValueObject::GetLanguageFlags () +{ + return m_language_flags; +} + +void +ValueObject::SetLanguageFlags (uint64_t flags) +{ + m_language_flags = flags; +} diff --git a/source/Core/ValueObjectCast.cpp b/source/Core/ValueObjectCast.cpp index b20371b128dfe..1c5838b820e13 100644 --- a/source/Core/ValueObjectCast.cpp +++ b/source/Core/ValueObjectCast.cpp @@ -20,14 +20,13 @@ #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" @@ -38,7 +37,7 @@ using namespace lldb_private; lldb::ValueObjectSP ValueObjectCast::Create (ValueObject &parent, const ConstString &name, - const ClangASTType &cast_type) + const CompilerType &cast_type) { ValueObjectCast *cast_valobj_ptr = new ValueObjectCast (parent, name, cast_type); return cast_valobj_ptr->GetSP(); @@ -48,36 +47,38 @@ ValueObjectCast::ValueObjectCast ( ValueObject &parent, const ConstString &name, - const ClangASTType &cast_type + const CompilerType &cast_type ) : ValueObject(parent), m_cast_type (cast_type) { SetName (name); //m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType()); - m_value.SetClangType (cast_type); + m_value.SetCompilerType (cast_type); } ValueObjectCast::~ValueObjectCast() { } -ClangASTType -ValueObjectCast::GetClangTypeImpl () +CompilerType +ValueObjectCast::GetCompilerTypeImpl () { return m_cast_type; } size_t -ValueObjectCast::CalculateNumChildren() +ValueObjectCast::CalculateNumChildren(uint32_t max) { - return GetClangType().GetNumChildren (true); + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; } uint64_t ValueObjectCast::GetByteSize() { - return m_value.GetValueByteSize(NULL); + ExecutionContext exe_ctx (GetExecutionContextRef()); + return m_value.GetValueByteSize(nullptr, &exe_ctx); } lldb::ValueType @@ -98,9 +99,9 @@ ValueObjectCast::UpdateValue () Value old_value(m_value); m_update_point.SetUpdated(); m_value = m_parent->GetValue(); - ClangASTType clang_type (GetClangType()); - //m_value.SetContext (Value::eContextTypeClangType, clang_type); - m_value.SetClangType (clang_type); + CompilerType compiler_type (GetCompilerType()); + //m_value.SetContext (Value::eContextTypeClangType, compiler_type); + m_value.SetCompilerType (compiler_type); SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren()); if (!CanProvideValue()) { diff --git a/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp index c1e45e1f48de8..6ecc749b8953c 100644 --- a/source/Core/ValueObjectChild.cpp +++ b/source/Core/ValueObjectChild.cpp @@ -12,7 +12,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ValueObjectList.h" -#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" @@ -27,7 +27,7 @@ using namespace lldb_private; ValueObjectChild::ValueObjectChild ( ValueObject &parent, - const ClangASTType &clang_type, + const CompilerType &compiler_type, const ConstString &name, uint64_t byte_size, int32_t byte_offset, @@ -35,19 +35,22 @@ ValueObjectChild::ValueObjectChild uint32_t bitfield_bit_offset, bool is_base_class, bool is_deref_of_parent, - AddressType child_ptr_or_ref_addr_type + AddressType child_ptr_or_ref_addr_type, + uint64_t language_flags ) : ValueObject (parent), - m_clang_type (clang_type), + m_compiler_type (compiler_type), m_byte_size (byte_size), m_byte_offset (byte_offset), m_bitfield_bit_size (bitfield_bit_size), m_bitfield_bit_offset (bitfield_bit_offset), m_is_base_class (is_base_class), - m_is_deref_of_parent (is_deref_of_parent) + m_is_deref_of_parent (is_deref_of_parent), + m_can_update_with_invalid_exe_ctx() { m_name = name; SetAddressTypeOfChildren(child_ptr_or_ref_addr_type); + SetLanguageFlags(language_flags); } ValueObjectChild::~ValueObjectChild() @@ -61,9 +64,10 @@ ValueObjectChild::GetValueType() const } size_t -ValueObjectChild::CalculateNumChildren() +ValueObjectChild::CalculateNumChildren(uint32_t max) { - return GetClangType().GetNumChildren (true); + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; } static void @@ -72,11 +76,11 @@ AdjustForBitfieldness(ConstString& name, { if (name && bitfield_bit_size) { - const char *clang_type_name = name.AsCString(); - if (clang_type_name) + const char *compiler_type_name = name.AsCString(); + if (compiler_type_name) { - std::vector<char> bitfield_type_name (strlen(clang_type_name) + 32, 0); - ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", clang_type_name, bitfield_bit_size); + std::vector<char> bitfield_type_name (strlen(compiler_type_name) + 32, 0); + ::snprintf (&bitfield_type_name.front(), bitfield_type_name.size(), "%s:%u", compiler_type_name, bitfield_bit_size); name.SetCString(&bitfield_type_name.front()); } } @@ -87,7 +91,7 @@ ValueObjectChild::GetTypeName() { if (m_type_name.IsEmpty()) { - m_type_name = GetClangType().GetConstTypeName (); + m_type_name = GetCompilerType().GetConstTypeName (); AdjustForBitfieldness(m_type_name, m_bitfield_bit_size); } return m_type_name; @@ -96,7 +100,7 @@ ValueObjectChild::GetTypeName() ConstString ValueObjectChild::GetQualifiedTypeName() { - ConstString qualified_name = GetClangType().GetConstTypeName(); + ConstString qualified_name = GetCompilerType().GetConstTypeName(); AdjustForBitfieldness(qualified_name, m_bitfield_bit_size); return qualified_name; } @@ -104,17 +108,25 @@ ValueObjectChild::GetQualifiedTypeName() ConstString ValueObjectChild::GetDisplayTypeName() { - ConstString display_name = GetClangType().GetDisplayTypeName(); + ConstString display_name = GetCompilerType().GetDisplayTypeName(); AdjustForBitfieldness(display_name, m_bitfield_bit_size); return display_name; } -bool +LazyBool ValueObjectChild::CanUpdateWithInvalidExecutionContext () { + if (m_can_update_with_invalid_exe_ctx.hasValue()) + return m_can_update_with_invalid_exe_ctx.getValue(); if (m_parent) - return m_parent->CanUpdateWithInvalidExecutionContext(); - return this->ValueObject::CanUpdateWithInvalidExecutionContext(); + { + ValueObject *opinionated_parent = m_parent->FollowParentChain([] (ValueObject* valobj) -> bool { + return (valobj->CanUpdateWithInvalidExecutionContext() == eLazyBoolCalculate); + }); + if (opinionated_parent) + return (m_can_update_with_invalid_exe_ctx = opinionated_parent->CanUpdateWithInvalidExecutionContext()).getValue(); + } + return (m_can_update_with_invalid_exe_ctx = this->ValueObject::CanUpdateWithInvalidExecutionContext()).getValue(); } bool @@ -127,18 +139,22 @@ ValueObjectChild::UpdateValue () { if (parent->UpdateValueIfNeeded(false)) { - m_value.SetClangType(GetClangType()); - + m_value.SetCompilerType(GetCompilerType()); + + CompilerType parent_type(parent->GetCompilerType()); // Copy the parent scalar value and the scalar value type m_value.GetScalar() = parent->GetValue().GetScalar(); Value::ValueType value_type = parent->GetValue().GetValueType(); m_value.SetValueType (value_type); + + Flags parent_type_flags(parent_type.GetTypeInfo()); + const bool is_instance_ptr_base = ((m_is_base_class == true) && (parent_type_flags.AnySet(lldb::eTypeInstanceIsPointer))); - if (parent->GetClangType().IsPointerOrReferenceType ()) + if (parent->GetCompilerType().ShouldTreatScalarValueAsAddress()) { lldb::addr_t addr = parent->GetPointerValue (); m_value.GetScalar() = addr; - + if (addr == LLDB_INVALID_ADDRESS) { m_error.SetErrorString ("parent address is invalid."); @@ -155,16 +171,16 @@ ValueObjectChild::UpdateValue () switch (addr_type) { case eAddressTypeFile: - { - lldb::ProcessSP process_sp (GetProcessSP()); - if (process_sp && process_sp->IsAlive() == true) - m_value.SetValueType (Value::eValueTypeLoadAddress); - else - m_value.SetValueType(Value::eValueTypeFileAddress); - } + { + lldb::ProcessSP process_sp (GetProcessSP()); + if (process_sp && process_sp->IsAlive() == true) + m_value.SetValueType (Value::eValueTypeLoadAddress); + else + m_value.SetValueType(Value::eValueTypeFileAddress); + } break; case eAddressTypeLoad: - m_value.SetValueType (Value::eValueTypeLoadAddress); + m_value.SetValueType (is_instance_ptr_base ? Value::eValueTypeScalar: Value::eValueTypeLoadAddress); break; case eAddressTypeHost: m_value.SetValueType(Value::eValueTypeHostAddress); @@ -180,9 +196,9 @@ ValueObjectChild::UpdateValue () { switch (value_type) { - case Value::eValueTypeLoadAddress: - case Value::eValueTypeFileAddress: - case Value::eValueTypeHostAddress: + case Value::eValueTypeLoadAddress: + case Value::eValueTypeFileAddress: + case Value::eValueTypeHostAddress: { lldb::addr_t addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); if (addr == LLDB_INVALID_ADDRESS) @@ -200,27 +216,42 @@ ValueObjectChild::UpdateValue () m_value.GetScalar() += GetByteOffset(); } } - break; - - case Value::eValueTypeScalar: - // TODO: What if this is a register value? Do we try and - // extract the child value from within the parent data? - // Probably... - default: - m_error.SetErrorString ("parent has invalid value."); - break; + break; + + case Value::eValueTypeScalar: + // try to extract the child value from the parent's scalar value + { + Scalar scalar(m_value.GetScalar()); + if (m_bitfield_bit_size) + scalar.ExtractBitfield(m_bitfield_bit_size, m_bitfield_bit_offset); + else + scalar.ExtractBitfield(8*m_byte_size, 8*m_byte_offset); + m_value.GetScalar() = scalar; + } + break; + default: + m_error.SetErrorString ("parent has invalid value."); + break; } } - + if (m_error.Success()) { const bool thread_and_frame_only_if_stopped = true; ExecutionContext exe_ctx (GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped)); - if (GetClangType().GetTypeInfo() & lldb::eTypeHasValue) - m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); + if (GetCompilerType().GetTypeInfo() & lldb::eTypeHasValue) + { + if (!is_instance_ptr_base) + m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); + else + m_error = m_parent->GetValue().GetValueAsData (&exe_ctx, m_data, 0, GetModule().get()); + } else + { m_error.Clear(); // No value so nothing to read... + } } + } else { diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp index b4e6303064691..a0f1737a861c4 100644 --- a/source/Core/ValueObjectConstResult.cpp +++ b/source/Core/ValueObjectConstResult.cpp @@ -16,7 +16,7 @@ #include "lldb/Core/ValueObjectDynamicValue.h" #include "lldb/Core/ValueObjectList.h" -#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" @@ -61,21 +61,21 @@ ValueObjectSP ValueObjectConstResult::Create ( ExecutionContextScope *exe_scope, - const ClangASTType &clang_type, + const CompilerType &compiler_type, const ConstString &name, const DataExtractor &data, lldb::addr_t address ) { return (new ValueObjectConstResult (exe_scope, - clang_type, + compiler_type, name, data, address))->GetSP(); } ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, - const ClangASTType &clang_type, + const CompilerType &compiler_type, const ConstString &name, const DataExtractor &data, lldb::addr_t address) : @@ -94,7 +94,7 @@ ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope m_value.GetScalar() = (uintptr_t)m_data.GetDataStart(); m_value.SetValueType(Value::eValueTypeHostAddress); - m_value.SetClangType(clang_type); + m_value.SetCompilerType(compiler_type); m_name = name; SetIsConstant (); SetValueIsValid(true); @@ -103,7 +103,7 @@ ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope ValueObjectSP ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, - const ClangASTType &clang_type, + const CompilerType &compiler_type, const ConstString &name, const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order, @@ -111,7 +111,7 @@ ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, lldb::addr_t address) { return (new ValueObjectConstResult (exe_scope, - clang_type, + compiler_type, name, data_sp, data_byte_order, @@ -129,7 +129,7 @@ ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, } ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, - const ClangASTType &clang_type, + const CompilerType &compiler_type, const ConstString &name, const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order, @@ -145,8 +145,8 @@ ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope m_data.SetData(data_sp); m_value.GetScalar() = (uintptr_t)data_sp->GetBytes(); m_value.SetValueType(Value::eValueTypeHostAddress); - //m_value.SetContext(Value::eContextTypeClangType, clang_type); - m_value.SetClangType (clang_type); + //m_value.SetContext(Value::eContextTypeClangType, compiler_type); + m_value.SetCompilerType (compiler_type); m_name = name; SetIsConstant (); SetValueIsValid(true); @@ -155,14 +155,14 @@ ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope ValueObjectSP ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, - const ClangASTType &clang_type, + const CompilerType &compiler_type, const ConstString &name, lldb::addr_t address, AddressType address_type, uint32_t addr_byte_size) { return (new ValueObjectConstResult (exe_scope, - clang_type, + compiler_type, name, address, address_type, @@ -170,7 +170,7 @@ ValueObjectConstResult::Create (ExecutionContextScope *exe_scope, } ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope, - const ClangASTType &clang_type, + const CompilerType &compiler_type, const ConstString &name, lldb::addr_t address, AddressType address_type, @@ -191,8 +191,8 @@ ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope case eAddressTypeLoad: m_value.SetValueType(Value::eValueTypeLoadAddress); break; case eAddressTypeHost: m_value.SetValueType(Value::eValueTypeHostAddress); break; } -// m_value.SetContext(Value::eContextTypeClangType, clang_type); - m_value.SetClangType (clang_type); +// m_value.SetContext(Value::eContextTypeClangType, compiler_type); + m_value.SetCompilerType (compiler_type); m_name = name; SetIsConstant (); SetValueIsValid(true); @@ -241,10 +241,10 @@ ValueObjectConstResult::~ValueObjectConstResult() { } -ClangASTType -ValueObjectConstResult::GetClangTypeImpl() +CompilerType +ValueObjectConstResult::GetCompilerTypeImpl() { - return m_value.GetClangType(); + return m_value.GetCompilerType(); } lldb::ValueType @@ -259,7 +259,7 @@ ValueObjectConstResult::GetByteSize() ExecutionContext exe_ctx(GetExecutionContextRef()); if (m_byte_size == 0) - SetByteSize(GetClangType().GetByteSize(exe_ctx.GetBestExecutionContextScope())); + SetByteSize(GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope())); return m_byte_size; } @@ -270,23 +270,24 @@ ValueObjectConstResult::SetByteSize (size_t size) } size_t -ValueObjectConstResult::CalculateNumChildren() +ValueObjectConstResult::CalculateNumChildren(uint32_t max) { - return GetClangType().GetNumChildren (true); + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; } ConstString ValueObjectConstResult::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = GetClangType().GetConstTypeName (); + m_type_name = GetCompilerType().GetConstTypeName (); return m_type_name; } ConstString ValueObjectConstResult::GetDisplayTypeName() { - return GetClangType().GetDisplayTypeName(); + return GetCompilerType().GetDisplayTypeName(); } bool @@ -313,7 +314,7 @@ ValueObjectConstResult::Dereference (Error &error) } lldb::ValueObjectSP -ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create) +ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create) { return m_impl.GetSyntheticChildAtOffset(offset, type, can_create); } @@ -365,8 +366,16 @@ ValueObjectConstResult::GetDynamicValue (lldb::DynamicValueType use_dynamic) return ValueObjectSP(); } +lldb::ValueObjectSP +ValueObjectConstResult::Cast (const CompilerType &compiler_type) +{ + return m_impl.Cast(compiler_type); +} + lldb::LanguageType ValueObjectConstResult::GetPreferredDisplayLanguage () { - return lldb::eLanguageTypeUnknown; + if (m_preferred_display_language != lldb::eLanguageTypeUnknown) + return m_preferred_display_language; + return GetCompilerTypeImpl().GetMinimumLanguage(); } diff --git a/source/Core/ValueObjectConstResultCast.cpp b/source/Core/ValueObjectConstResultCast.cpp new file mode 100644 index 0000000000000..8f0c0f1522f2f --- /dev/null +++ b/source/Core/ValueObjectConstResultCast.cpp @@ -0,0 +1,75 @@ +//===-- ValueObjectConstResultCast.cpp --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/ValueObjectConstResultCast.h" + +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectList.h" + +#include "lldb/Symbol/ClangASTContext.h" + +using namespace lldb_private; + +ValueObjectConstResultCast::ValueObjectConstResultCast( + ValueObject &parent, + const ConstString &name, + const CompilerType &cast_type, + lldb::addr_t live_address) : + ValueObjectCast (parent, name, cast_type), + m_impl(this, live_address) +{ + m_name = name; +} + +ValueObjectConstResultCast::~ValueObjectConstResultCast() +{ +} + +lldb::ValueObjectSP +ValueObjectConstResultCast::Dereference (Error &error) +{ + return m_impl.Dereference(error); +} + +lldb::ValueObjectSP +ValueObjectConstResultCast::GetSyntheticChildAtOffset(uint32_t offset, + const CompilerType& type, + bool can_create) +{ + return m_impl.GetSyntheticChildAtOffset(offset, type, can_create); +} + +lldb::ValueObjectSP +ValueObjectConstResultCast::AddressOf (Error &error) +{ + return m_impl.AddressOf(error); +} + +ValueObject * +ValueObjectConstResultCast::CreateChildAtIndex (size_t idx, + bool synthetic_array_member, + int32_t synthetic_index) +{ + return m_impl.CreateChildAtIndex( + idx, synthetic_array_member, synthetic_index); +} + +size_t +ValueObjectConstResultCast::GetPointeeData (DataExtractor& data, + uint32_t item_idx, + uint32_t item_count) +{ + return m_impl.GetPointeeData(data, item_idx, item_count); +} + +lldb::ValueObjectSP +ValueObjectConstResultCast::Cast (const CompilerType &compiler_type) +{ + return m_impl.Cast(compiler_type); +} diff --git a/source/Core/ValueObjectConstResultChild.cpp b/source/Core/ValueObjectConstResultChild.cpp index 64425ea50969f..c93aedc226038 100644 --- a/source/Core/ValueObjectConstResultChild.cpp +++ b/source/Core/ValueObjectConstResultChild.cpp @@ -19,17 +19,19 @@ using namespace lldb_private; ValueObjectConstResultChild::ValueObjectConstResultChild ( ValueObject &parent, - const ClangASTType &clang_type, + const CompilerType &compiler_type, const ConstString &name, uint32_t byte_size, int32_t byte_offset, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool is_base_class, - bool is_deref_of_parent + bool is_deref_of_parent, + lldb::addr_t live_address, + uint64_t language_flags ) : ValueObjectChild (parent, - clang_type, + compiler_type, name, byte_size, byte_offset, @@ -37,8 +39,9 @@ ValueObjectConstResultChild::ValueObjectConstResultChild bitfield_bit_offset, is_base_class, is_deref_of_parent, - eAddressTypeLoad), - m_impl(this) + eAddressTypeLoad, + language_flags), + m_impl(this, live_address) { m_name = name; } @@ -54,7 +57,7 @@ ValueObjectConstResultChild::Dereference (Error &error) } lldb::ValueObjectSP -ValueObjectConstResultChild::GetSyntheticChildAtOffset(uint32_t offset, const ClangASTType& type, bool can_create) +ValueObjectConstResultChild::GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create) { return m_impl.GetSyntheticChildAtOffset(offset, type, can_create); } @@ -78,3 +81,9 @@ ValueObjectConstResultChild::GetPointeeData (DataExtractor& data, { return m_impl.GetPointeeData(data, item_idx, item_count); } + +lldb::ValueObjectSP +ValueObjectConstResultChild::Cast (const CompilerType &compiler_type) +{ + return m_impl.Cast(compiler_type); +} diff --git a/source/Core/ValueObjectConstResultImpl.cpp b/source/Core/ValueObjectConstResultImpl.cpp index 733d767b7ee19..85ac3f2c5fe55 100644 --- a/source/Core/ValueObjectConstResultImpl.cpp +++ b/source/Core/ValueObjectConstResultImpl.cpp @@ -11,13 +11,14 @@ #include "lldb/Core/ValueObjectChild.h" #include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectConstResultCast.h" #include "lldb/Core/ValueObjectConstResultChild.h" #include "lldb/Core/ValueObjectMemory.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/ValueObjectList.h" -#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" @@ -68,27 +69,29 @@ ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array uint32_t child_bitfield_bit_offset = 0; bool child_is_base_class = false; bool child_is_deref_of_parent = false; + uint64_t language_flags; const bool transparent_pointers = synthetic_array_member == false; - ClangASTType clang_type = m_impl_backend->GetClangType(); - ClangASTType child_clang_type; + CompilerType compiler_type = m_impl_backend->GetCompilerType(); + CompilerType child_compiler_type; ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); - child_clang_type = clang_type.GetChildClangTypeAtIndex (&exe_ctx, - idx, - transparent_pointers, - omit_empty_base_classes, - ignore_array_bounds, - child_name_str, - child_byte_size, - child_byte_offset, - child_bitfield_bit_size, - child_bitfield_bit_offset, - child_is_base_class, - child_is_deref_of_parent, - m_impl_backend); - if (child_clang_type && child_byte_size) + child_compiler_type = compiler_type.GetChildCompilerTypeAtIndex (&exe_ctx, + idx, + transparent_pointers, + omit_empty_base_classes, + ignore_array_bounds, + child_name_str, + child_byte_size, + child_byte_offset, + child_bitfield_bit_size, + child_bitfield_bit_offset, + child_is_base_class, + child_is_deref_of_parent, + m_impl_backend, + language_flags); + if (child_compiler_type && child_byte_size) { if (synthetic_index) child_byte_offset += child_byte_size * synthetic_index; @@ -96,25 +99,25 @@ ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array ConstString child_name; if (!child_name_str.empty()) child_name.SetCString (child_name_str.c_str()); - + valobj = new ValueObjectConstResultChild (*m_impl_backend, - child_clang_type, + child_compiler_type, child_name, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent); - if (m_live_address != LLDB_INVALID_ADDRESS) - valobj->m_impl.SetLiveAddress(m_live_address+child_byte_offset); + child_is_deref_of_parent, + m_live_address == LLDB_INVALID_ADDRESS ? m_live_address : m_live_address+child_byte_offset, + language_flags); } return valobj; } lldb::ValueObjectSP -ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const ClangASTType& type, bool can_create) +ValueObjectConstResultImpl::GetSyntheticChildAtOffset (uint32_t offset, const CompilerType& type, bool can_create) { if (m_impl_backend == NULL) return lldb::ValueObjectSP(); @@ -132,7 +135,7 @@ ValueObjectConstResultImpl::AddressOf (Error &error) return lldb::ValueObjectSP(); if (m_live_address != LLDB_INVALID_ADDRESS) { - ClangASTType clang_type(m_impl_backend->GetClangType()); + CompilerType compiler_type(m_impl_backend->GetCompilerType()); lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t))); @@ -140,10 +143,10 @@ ValueObjectConstResultImpl::AddressOf (Error &error) new_name.append(m_impl_backend->GetName().AsCString("")); ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef()); m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), - clang_type.GetPointerType(), + compiler_type.GetPointerType(), ConstString(new_name.c_str()), buffer, - lldb::endian::InlHostByteOrder(), + endian::InlHostByteOrder(), exe_ctx.GetAddressByteSize()); m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar); @@ -155,6 +158,17 @@ ValueObjectConstResultImpl::AddressOf (Error &error) return m_impl_backend->ValueObject::AddressOf(error); } +lldb::ValueObjectSP +ValueObjectConstResultImpl::Cast (const CompilerType &compiler_type) +{ + if (m_impl_backend == NULL) + return lldb::ValueObjectSP(); + + ValueObjectConstResultCast *result_cast = new ValueObjectConstResultCast( + *m_impl_backend, m_impl_backend->GetName(), compiler_type, m_live_address); + return result_cast->GetSP(); +} + lldb::addr_t ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address, AddressType *address_type) diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp index 89b98a1db1bad..0ac86a68f19f6 100644 --- a/source/Core/ValueObjectDynamicValue.cpp +++ b/source/Core/ValueObjectDynamicValue.cpp @@ -20,7 +20,7 @@ #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" @@ -49,18 +49,18 @@ ValueObjectDynamicValue::~ValueObjectDynamicValue() m_owning_valobj_sp.reset(); } -ClangASTType -ValueObjectDynamicValue::GetClangTypeImpl () +CompilerType +ValueObjectDynamicValue::GetCompilerTypeImpl () { const bool success = UpdateValueIfNeeded(false); if (success) { if (m_dynamic_type_info.HasType()) - return m_value.GetClangType(); + return m_value.GetCompilerType(); else - return m_parent->GetClangType(); + return m_parent->GetCompilerType(); } - return m_parent->GetClangType(); + return m_parent->GetCompilerType(); } ConstString @@ -105,7 +105,7 @@ ValueObjectDynamicValue::GetDisplayTypeName() if (success) { if (m_dynamic_type_info.HasType()) - return GetClangType().GetDisplayTypeName(); + return GetCompilerType().GetDisplayTypeName(); if (m_dynamic_type_info.HasName()) return m_dynamic_type_info.GetName(); } @@ -113,13 +113,16 @@ ValueObjectDynamicValue::GetDisplayTypeName() } size_t -ValueObjectDynamicValue::CalculateNumChildren() +ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) { const bool success = UpdateValueIfNeeded(false); if (success && m_dynamic_type_info.HasType()) - return GetClangType().GetNumChildren (true); + { + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; + } else - return m_parent->GetNumChildren(); + return m_parent->GetNumChildren(max); } uint64_t @@ -127,7 +130,10 @@ ValueObjectDynamicValue::GetByteSize() { const bool success = UpdateValueIfNeeded(false); if (success && m_dynamic_type_info.HasType()) - return m_value.GetValueByteSize(nullptr); + { + ExecutionContext exe_ctx (GetExecutionContextRef()); + return m_value.GetValueByteSize(nullptr, &exe_ctx); + } else return m_parent->GetByteSize(); } @@ -138,40 +144,6 @@ ValueObjectDynamicValue::GetValueType() const return m_parent->GetValueType(); } - -static TypeAndOrName -FixupTypeAndOrName (const TypeAndOrName& type_andor_name, - ValueObject& parent) -{ - TypeAndOrName ret(type_andor_name); - if (type_andor_name.HasType()) - { - // The type will always be the type of the dynamic object. If our parent's type was a pointer, - // then our type should be a pointer to the type of the dynamic object. If a reference, then the original type - // should be okay... - ClangASTType orig_type = type_andor_name.GetClangASTType(); - ClangASTType corrected_type = orig_type; - if (parent.IsPointerType()) - corrected_type = orig_type.GetPointerType (); - else if (parent.IsPointerOrReferenceType()) - corrected_type = orig_type.GetLValueReferenceType (); - ret.SetClangASTType(corrected_type); - } - else /*if (m_dynamic_type_info.HasName())*/ - { - // If we are here we need to adjust our dynamic type name to include the correct & or * symbol - std::string corrected_name (type_andor_name.GetName().GetCString()); - if (parent.IsPointerType()) - corrected_name.append(" *"); - else if (parent.IsPointerOrReferenceType()) - corrected_name.append(" &"); - // the parent type should be a correctly pointer'ed or referenc'ed type - ret.SetClangASTType(parent.GetClangType()); - ret.SetName(corrected_name.c_str()); - } - return ret; -} - bool ValueObjectDynamicValue::UpdateValue () { @@ -210,25 +182,28 @@ ValueObjectDynamicValue::UpdateValue () TypeAndOrName class_type_or_name; Address dynamic_address; bool found_dynamic_type = false; + Value::ValueType value_type; + + LanguageRuntime *runtime = nullptr; lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage(); if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) { - LanguageRuntime *runtime = process->GetLanguageRuntime (known_type); + runtime = process->GetLanguageRuntime (known_type); if (runtime) - found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); + found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type); } else { - LanguageRuntime *cpp_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); - if (cpp_runtime) - found_dynamic_type = cpp_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); + runtime = process->GetLanguageRuntime (lldb::eLanguageTypeC_plus_plus); + if (runtime) + found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type); if (!found_dynamic_type) { - LanguageRuntime *objc_runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); - if (objc_runtime) - found_dynamic_type = objc_runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address); + runtime = process->GetLanguageRuntime (lldb::eLanguageTypeObjC); + if (runtime) + found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type); } } @@ -237,11 +212,12 @@ ValueObjectDynamicValue::UpdateValue () m_update_point.SetUpdated(); - if (found_dynamic_type) + if (runtime && found_dynamic_type) { if (class_type_or_name.HasType()) { - m_type_impl = TypeImpl(m_parent->GetClangType(),FixupTypeAndOrName(class_type_or_name, *m_parent).GetClangASTType()); + m_type_impl = TypeImpl(m_parent->GetCompilerType(), + runtime->FixUpDynamicType(class_type_or_name, *m_parent).GetCompilerType()); } else { @@ -300,14 +276,13 @@ ValueObjectDynamicValue::UpdateValue () m_value.GetScalar() = load_address; } - m_dynamic_type_info = FixupTypeAndOrName(m_dynamic_type_info, *m_parent); + if (runtime) + m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent); //m_value.SetContext (Value::eContextTypeClangType, corrected_type); - m_value.SetClangType (m_dynamic_type_info.GetClangASTType()); + m_value.SetCompilerType (m_dynamic_type_info.GetCompilerType()); - // Our address is the location of the dynamic type stored in memory. It isn't a load address, - // because we aren't pointing to the LOCATION that stores the pointer to us, we're pointing to us... - m_value.SetValueType(Value::eValueTypeScalar); + m_value.SetValueType(value_type); if (has_changed_type && log) log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(), @@ -421,3 +396,50 @@ ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error) SetNeedsUpdate(); return ret_val; } + +void +ValueObjectDynamicValue::SetPreferredDisplayLanguage (lldb::LanguageType lang) +{ + this->ValueObject::SetPreferredDisplayLanguage(lang); + if (m_parent) + m_parent->SetPreferredDisplayLanguage(lang); +} + +lldb::LanguageType +ValueObjectDynamicValue::GetPreferredDisplayLanguage () +{ + if (m_preferred_display_language == lldb::eLanguageTypeUnknown) + { + if (m_parent) + return m_parent->GetPreferredDisplayLanguage(); + return lldb::eLanguageTypeUnknown; + } + else + return m_preferred_display_language; +} + +bool +ValueObjectDynamicValue::GetDeclaration (Declaration &decl) +{ + if (m_parent) + return m_parent->GetDeclaration(decl); + + return ValueObject::GetDeclaration(decl); +} + +uint64_t +ValueObjectDynamicValue::GetLanguageFlags () +{ + if (m_parent) + return m_parent->GetLanguageFlags(); + return this->ValueObject::GetLanguageFlags(); +} + +void +ValueObjectDynamicValue::SetLanguageFlags (uint64_t flags) +{ + if (m_parent) + m_parent->SetLanguageFlags(flags); + else + this->ValueObject::SetLanguageFlags(flags); +} diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp index 9f1953138f629..b989710c95d57 100644 --- a/source/Core/ValueObjectMemory.cpp +++ b/source/Core/ValueObjectMemory.cpp @@ -46,7 +46,7 @@ ValueObjectSP ValueObjectMemory::Create (ExecutionContextScope *exe_scope, const char *name, const Address &address, - const ClangASTType &ast_type) + const CompilerType &ast_type) { return (new ValueObjectMemory (exe_scope, name, address, ast_type))->GetSP(); } @@ -58,7 +58,7 @@ ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, ValueObject(exe_scope), m_address (address), m_type_sp(type_sp), - m_clang_type() + m_compiler_type() { // Do not attempt to construct one of these objects with no variable! assert (m_type_sp.get() != NULL); @@ -90,21 +90,21 @@ ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope, const char *name, const Address &address, - const ClangASTType &ast_type) : + const CompilerType &ast_type) : ValueObject(exe_scope), m_address (address), m_type_sp(), - m_clang_type(ast_type) + m_compiler_type(ast_type) { // Do not attempt to construct one of these objects with no variable! - assert (m_clang_type.GetASTContext()); - assert (m_clang_type.GetOpaqueQualType()); + assert (m_compiler_type.GetTypeSystem()); + assert (m_compiler_type.GetOpaqueQualType()); TargetSP target_sp (GetTargetSP()); SetName (ConstString(name)); -// m_value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); - m_value.SetClangType(m_clang_type); +// m_value.SetContext(Value::eContextTypeClangType, m_compiler_type.GetOpaqueQualType()); + m_value.SetCompilerType(m_compiler_type); lldb::addr_t load_address = m_address.GetLoadAddress (target_sp.get()); if (load_address != LLDB_INVALID_ADDRESS) { @@ -131,12 +131,12 @@ ValueObjectMemory::~ValueObjectMemory() { } -ClangASTType -ValueObjectMemory::GetClangTypeImpl () +CompilerType +ValueObjectMemory::GetCompilerTypeImpl () { if (m_type_sp) - return m_type_sp->GetClangForwardType(); - return m_clang_type; + return m_type_sp->GetForwardCompilerType (); + return m_compiler_type; } ConstString @@ -144,24 +144,29 @@ ValueObjectMemory::GetTypeName() { if (m_type_sp) return m_type_sp->GetName(); - return m_clang_type.GetConstTypeName(); + return m_compiler_type.GetConstTypeName(); } ConstString ValueObjectMemory::GetDisplayTypeName() { if (m_type_sp) - return m_type_sp->GetClangForwardType().GetDisplayTypeName(); - return m_clang_type.GetDisplayTypeName(); + return m_type_sp->GetForwardCompilerType ().GetDisplayTypeName(); + return m_compiler_type.GetDisplayTypeName(); } size_t -ValueObjectMemory::CalculateNumChildren() +ValueObjectMemory::CalculateNumChildren(uint32_t max) { if (m_type_sp) - return m_type_sp->GetNumChildren(true); + { + auto child_count = m_type_sp->GetNumChildren(true); + return child_count <= max ? child_count : max; + } + const bool omit_empty_base_classes = true; - return m_clang_type.GetNumChildren (omit_empty_base_classes); + auto child_count = m_compiler_type.GetNumChildren (omit_empty_base_classes); + return child_count <= max ? child_count : max; } uint64_t @@ -169,7 +174,7 @@ ValueObjectMemory::GetByteSize() { if (m_type_sp) return m_type_sp->GetByteSize(); - return m_clang_type.GetByteSize (nullptr); + return m_compiler_type.GetByteSize (nullptr); } lldb::ValueType @@ -249,8 +254,8 @@ ValueObjectMemory::UpdateValue () value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); else { - //value.SetContext(Value::eContextTypeClangType, m_clang_type.GetOpaqueQualType()); - value.SetClangType(m_clang_type); + //value.SetContext(Value::eContextTypeClangType, m_compiler_type.GetOpaqueQualType()); + value.SetCompilerType(m_compiler_type); } m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); diff --git a/source/Core/ValueObjectRegister.cpp b/source/Core/ValueObjectRegister.cpp index 0db1f0cd45cf5..c7845cd032070 100644 --- a/source/Core/ValueObjectRegister.cpp +++ b/source/Core/ValueObjectRegister.cpp @@ -15,7 +15,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/Module.h" -#include "lldb/Symbol/ClangASTType.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Target/ExecutionContext.h" @@ -42,10 +42,10 @@ ValueObjectRegisterContext::~ValueObjectRegisterContext() { } -ClangASTType -ValueObjectRegisterContext::GetClangTypeImpl () +CompilerType +ValueObjectRegisterContext::GetCompilerTypeImpl () { - return ClangASTType(); + return CompilerType(); } ConstString @@ -67,9 +67,10 @@ ValueObjectRegisterContext::GetQualifiedTypeName() } size_t -ValueObjectRegisterContext::CalculateNumChildren() +ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) { - return m_reg_ctx_sp->GetRegisterSetCount(); + auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount(); + return reg_set_count <= max ? reg_set_count : max; } uint64_t @@ -144,10 +145,10 @@ ValueObjectRegisterSet::~ValueObjectRegisterSet() { } -ClangASTType -ValueObjectRegisterSet::GetClangTypeImpl () +CompilerType +ValueObjectRegisterSet::GetCompilerTypeImpl () { - return ClangASTType(); + return CompilerType(); } ConstString @@ -163,11 +164,14 @@ ValueObjectRegisterSet::GetQualifiedTypeName() } size_t -ValueObjectRegisterSet::CalculateNumChildren() +ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) { const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx); if (reg_set) - return reg_set->num_registers; + { + auto reg_count = reg_set->num_registers; + return reg_count <= max ? reg_count : max; + } return 0; } @@ -279,7 +283,7 @@ ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterCon m_reg_info (), m_reg_value (), m_type_name (), - m_clang_type () + m_compiler_type () { assert (reg_ctx_sp.get()); ConstructObject(reg_num); @@ -297,7 +301,7 @@ ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb m_reg_info (), m_reg_value (), m_type_name (), - m_clang_type () + m_compiler_type () { assert (reg_ctx); ConstructObject(reg_num); @@ -307,10 +311,10 @@ ValueObjectRegister::~ValueObjectRegister() { } -ClangASTType -ValueObjectRegister::GetClangTypeImpl () +CompilerType +ValueObjectRegister::GetCompilerTypeImpl () { - if (!m_clang_type.IsValid()) + if (!m_compiler_type.IsValid()) { ExecutionContext exe_ctx (GetExecutionContextRef()); Target *target = exe_ctx.GetTargetPtr(); @@ -319,26 +323,29 @@ ValueObjectRegister::GetClangTypeImpl () Module *exe_module = target->GetExecutableModulePointer(); if (exe_module) { - m_clang_type = exe_module->GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding, - m_reg_info.byte_size * 8); + TypeSystem *type_system = exe_module->GetTypeSystemForLanguage (eLanguageTypeC); + if (type_system) + m_compiler_type = type_system->GetBuiltinTypeForEncodingAndBitSize (m_reg_info.encoding, + m_reg_info.byte_size * 8); } } } - return m_clang_type; + return m_compiler_type; } ConstString ValueObjectRegister::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = GetClangType().GetConstTypeName (); + m_type_name = GetCompilerType().GetConstTypeName (); return m_type_name; } size_t -ValueObjectRegister::CalculateNumChildren() +ValueObjectRegister::CalculateNumChildren(uint32_t max) { - return GetClangType().GetNumChildren(true); + auto children_count = GetCompilerType().GetNumChildren (true); + return children_count <= max ? children_count : max; } uint64_t diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp index 867b520162982..0ccc4385e3cc8 100644 --- a/source/Core/ValueObjectSyntheticFilter.cpp +++ b/source/Core/ValueObjectSyntheticFilter.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectSyntheticFilter.cpp -----------------------------*- C++ -*-===// +//===-- ValueObjectSyntheticFilter.cpp --------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/ValueObjectSyntheticFilter.h" - // C Includes // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/ValueObjectSyntheticFilter.h" #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSynthetic.h" @@ -26,35 +25,34 @@ public: {} size_t - CalculateNumChildren() + CalculateNumChildren() override { return m_backend.GetNumChildren(); } lldb::ValueObjectSP - GetChildAtIndex (size_t idx) + GetChildAtIndex(size_t idx) override { return m_backend.GetChildAtIndex(idx, true); } - + size_t - GetIndexOfChildWithName (const ConstString &name) + GetIndexOfChildWithName(const ConstString &name) override { return m_backend.GetIndexOfChildWithName(name); } bool - MightHaveChildren () + MightHaveChildren() override { return true; } bool - Update() + Update() override { return false; } - }; ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) : @@ -78,14 +76,12 @@ ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::Synthetic CreateSynthFilter(); } -ValueObjectSynthetic::~ValueObjectSynthetic() -{ -} +ValueObjectSynthetic::~ValueObjectSynthetic() = default; -ClangASTType -ValueObjectSynthetic::GetClangTypeImpl () +CompilerType +ValueObjectSynthetic::GetCompilerTypeImpl () { - return m_parent->GetClangType(); + return m_parent->GetCompilerType(); } ConstString @@ -107,12 +103,16 @@ ValueObjectSynthetic::GetDisplayTypeName() } size_t -ValueObjectSynthetic::CalculateNumChildren() +ValueObjectSynthetic::CalculateNumChildren(uint32_t max) { UpdateValueIfNeeded(); if (m_synthetic_children_count < UINT32_MAX) - return m_synthetic_children_count; - return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren()); + return m_synthetic_children_count <= max ? m_synthetic_children_count : max; + + if (max < UINT32_MAX) + return m_synth_filter_ap->CalculateNumChildren(max); + else + return (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren(max)); } lldb::ValueObjectSP @@ -217,12 +217,13 @@ ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create) ValueObject *valobj; if (m_children_byindex.GetValueForKey(idx, valobj) == false) { - if (can_create && m_synth_filter_ap.get() != NULL) + if (can_create && m_synth_filter_ap.get() != nullptr) { lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx); if (!synth_guy) return synth_guy; m_children_byindex.SetValueForKey(idx, synth_guy.get()); + synth_guy->SetPreferredDisplayLanguageIfNeeded(GetPreferredDisplayLanguage()); return synth_guy; } else @@ -253,7 +254,7 @@ ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name) uint32_t found_index = UINT32_MAX; bool did_find = m_name_toindex.GetValueForKey(name.GetCString(), found_index); - if (!did_find && m_synth_filter_ap.get() != NULL) + if (!did_find && m_synth_filter_ap.get() != nullptr) { uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name); if (index == UINT32_MAX) @@ -261,7 +262,7 @@ ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name) m_name_toindex.SetValueForKey(name.GetCString(), index); return index; } - else if (!did_find && m_synth_filter_ap.get() == NULL) + else if (!did_find && m_synth_filter_ap.get() == nullptr) return UINT32_MAX; else /*if (iter != m_name_toindex.end())*/ return found_index; @@ -314,3 +315,50 @@ ValueObjectSynthetic::SetFormat (lldb::Format format) this->ValueObject::SetFormat(format); this->ClearUserVisibleData(eClearUserVisibleDataItemsAll); } + +void +ValueObjectSynthetic::SetPreferredDisplayLanguage (lldb::LanguageType lang) +{ + this->ValueObject::SetPreferredDisplayLanguage(lang); + if (m_parent) + m_parent->SetPreferredDisplayLanguage(lang); +} + +lldb::LanguageType +ValueObjectSynthetic::GetPreferredDisplayLanguage () +{ + if (m_preferred_display_language == lldb::eLanguageTypeUnknown) + { + if (m_parent) + return m_parent->GetPreferredDisplayLanguage(); + return lldb::eLanguageTypeUnknown; + } + else + return m_preferred_display_language; +} + +bool +ValueObjectSynthetic::GetDeclaration (Declaration &decl) +{ + if (m_parent) + return m_parent->GetDeclaration(decl); + + return ValueObject::GetDeclaration(decl); +} + +uint64_t +ValueObjectSynthetic::GetLanguageFlags () +{ + if (m_parent) + return m_parent->GetLanguageFlags(); + return this->ValueObject::GetLanguageFlags(); +} + +void +ValueObjectSynthetic::SetLanguageFlags (uint64_t flags) +{ + if (m_parent) + m_parent->SetLanguageFlags(flags); + else + this->ValueObject::SetLanguageFlags(flags); +} diff --git a/source/Core/ValueObjectVariable.cpp b/source/Core/ValueObjectVariable.cpp index c86bece42eb89..389b7c54243db 100644 --- a/source/Core/ValueObjectVariable.cpp +++ b/source/Core/ValueObjectVariable.cpp @@ -54,13 +54,13 @@ ValueObjectVariable::~ValueObjectVariable() { } -ClangASTType -ValueObjectVariable::GetClangTypeImpl () +CompilerType +ValueObjectVariable::GetCompilerTypeImpl () { Type *var_type = m_variable_sp->GetType(); if (var_type) - return var_type->GetClangForwardType(); - return ClangASTType(); + return var_type->GetForwardCompilerType (); + return CompilerType(); } ConstString @@ -77,7 +77,7 @@ ValueObjectVariable::GetDisplayTypeName() { Type * var_type = m_variable_sp->GetType(); if (var_type) - return var_type->GetClangForwardType().GetDisplayTypeName(); + return var_type->GetForwardCompilerType ().GetDisplayTypeName(); return ConstString(); } @@ -91,15 +91,16 @@ ValueObjectVariable::GetQualifiedTypeName() } size_t -ValueObjectVariable::CalculateNumChildren() +ValueObjectVariable::CalculateNumChildren(uint32_t max) { - ClangASTType type(GetClangType()); + CompilerType type(GetCompilerType()); if (!type.IsValid()) return 0; const bool omit_empty_base_classes = true; - return type.GetNumChildren(omit_empty_base_classes); + auto child_count = type.GetNumChildren(omit_empty_base_classes); + return child_count <= max ? child_count : max; } uint64_t @@ -107,7 +108,7 @@ ValueObjectVariable::GetByteSize() { ExecutionContext exe_ctx(GetExecutionContextRef()); - ClangASTType type(GetClangType()); + CompilerType type(GetCompilerType()); if (!type.IsValid()) return 0; @@ -168,15 +169,15 @@ ValueObjectVariable::UpdateValue () m_resolved_value = m_value; m_value.SetContext(Value::eContextTypeVariable, variable); - ClangASTType clang_type = GetClangType(); - if (clang_type.IsValid()) - m_value.SetClangType(clang_type); + CompilerType compiler_type = GetCompilerType(); + if (compiler_type.IsValid()) + m_value.SetCompilerType(compiler_type); Value::ValueType value_type = m_value.GetValueType(); Process *process = exe_ctx.GetProcessPtr(); const bool process_is_alive = process && process->IsAlive(); - const uint32_t type_info = clang_type.GetTypeInfo(); + const uint32_t type_info = compiler_type.GetTypeInfo(); const bool is_pointer_or_ref = (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0; switch (value_type) |