aboutsummaryrefslogtreecommitdiff
path: root/source/Core
diff options
context:
space:
mode:
Diffstat (limited to 'source/Core')
-rw-r--r--source/Core/Address.cpp1843
-rw-r--r--source/Core/AddressRange.cpp259
-rw-r--r--source/Core/AddressResolver.cpp39
-rw-r--r--source/Core/AddressResolverFileLine.cpp109
-rw-r--r--source/Core/AddressResolverName.cpp321
-rw-r--r--source/Core/ArchSpec.cpp2693
-rw-r--r--source/Core/Baton.cpp6
-rw-r--r--source/Core/Broadcaster.cpp828
-rw-r--r--source/Core/CMakeLists.txt3
-rw-r--r--source/Core/Communication.cpp685
-rw-r--r--source/Core/Connection.cpp18
-rw-r--r--source/Core/ConnectionMachPort.cpp331
-rw-r--r--source/Core/ConnectionSharedMemory.cpp171
-rw-r--r--source/Core/ConstString.cpp543
-rw-r--r--source/Core/CxaDemangle.cpp5014
-rw-r--r--source/Core/DataBufferHeap.cpp75
-rw-r--r--source/Core/DataBufferMemoryMap.cpp398
-rw-r--r--source/Core/DataEncoder.cpp348
-rw-r--r--source/Core/DataExtractor.cpp3448
-rw-r--r--source/Core/Debugger.cpp2792
-rw-r--r--source/Core/Disassembler.cpp2363
-rw-r--r--source/Core/DynamicLoader.cpp341
-rw-r--r--source/Core/EmulateInstruction.cpp1072
-rw-r--r--source/Core/Error.cpp450
-rw-r--r--source/Core/Event.cpp386
-rw-r--r--source/Core/FastDemangle.cpp4173
-rw-r--r--source/Core/FileLineResolver.cpp126
-rw-r--r--source/Core/FileSpecList.cpp162
-rw-r--r--source/Core/FormatEntity.cpp4389
-rw-r--r--source/Core/History.cpp6
-rw-r--r--source/Core/IOHandler.cpp9278
-rw-r--r--source/Core/Listener.cpp799
-rw-r--r--source/Core/Log.cpp757
-rw-r--r--source/Core/Logging.cpp491
-rw-r--r--source/Core/Mangled.cpp597
-rw-r--r--source/Core/Module.cpp3105
-rw-r--r--source/Core/ModuleChild.cpp38
-rw-r--r--source/Core/ModuleList.cpp1788
-rw-r--r--source/Core/Opcode.cpp225
-rw-r--r--source/Core/PluginManager.cpp4545
-rw-r--r--source/Core/RegisterValue.cpp1711
-rw-r--r--source/Core/RegularExpression.cpp261
-rw-r--r--source/Core/Scalar.cpp5140
-rw-r--r--source/Core/SearchFilter.cpp1262
-rw-r--r--source/Core/Section.cpp929
-rw-r--r--source/Core/SourceManager.cpp1180
-rw-r--r--source/Core/State.cpp176
-rw-r--r--source/Core/Stream.cpp1022
-rw-r--r--source/Core/StreamAsynchronousIO.cpp43
-rw-r--r--source/Core/StreamCallback.cpp59
-rw-r--r--source/Core/StreamFile.cpp66
-rw-r--r--source/Core/StreamGDBRemote.cpp64
-rw-r--r--source/Core/StreamString.cpp125
-rw-r--r--source/Core/StringList.cpp482
-rw-r--r--source/Core/StructuredData.cpp472
-rw-r--r--source/Core/Timer.cpp304
-rw-r--r--source/Core/UUID.cpp402
-rw-r--r--source/Core/UserID.cpp8
-rw-r--r--source/Core/UserSettingsController.cpp153
-rw-r--r--source/Core/VMRange.cpp135
-rw-r--r--source/Core/Value.cpp1383
-rw-r--r--source/Core/ValueObject.cpp7011
-rw-r--r--source/Core/ValueObjectCast.cpp138
-rw-r--r--source/Core/ValueObjectChild.cpp401
-rw-r--r--source/Core/ValueObjectConstResult.cpp498
-rw-r--r--source/Core/ValueObjectConstResultCast.cpp66
-rw-r--r--source/Core/ValueObjectConstResultChild.cpp96
-rw-r--r--source/Core/ValueObjectConstResultImpl.cpp290
-rw-r--r--source/Core/ValueObjectDynamicValue.cpp680
-rw-r--r--source/Core/ValueObjectList.cpp184
-rw-r--r--source/Core/ValueObjectMemory.cpp390
-rw-r--r--source/Core/ValueObjectRegister.cpp599
-rw-r--r--source/Core/ValueObjectSyntheticFilter.cpp662
-rw-r--r--source/Core/ValueObjectVariable.cpp674
74 files changed, 35531 insertions, 46550 deletions
diff --git a/source/Core/Address.cpp b/source/Core/Address.cpp
index f3ea1718d6f2..e2ccf9d72216 100644
--- a/source/Core/Address.cpp
+++ b/source/Core/Address.cpp
@@ -19,1108 +19,963 @@
#include "lldb/Core/Section.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
-#include "lldb/Symbol/SymbolVendor.h"
using namespace lldb;
using namespace lldb_private;
-static size_t
-ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
-{
- if (exe_scope == nullptr)
- return 0;
-
- TargetSP target_sp (exe_scope->CalculateTarget());
- if (target_sp)
- {
- Error error;
- bool prefer_file_cache = false;
- return target_sp->ReadMemory (address, prefer_file_cache, dst, dst_len, error);
- }
+static size_t ReadBytes(ExecutionContextScope *exe_scope,
+ const Address &address, void *dst, size_t dst_len) {
+ if (exe_scope == nullptr)
return 0;
-}
-static bool
-GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &address, ByteOrder& byte_order, uint32_t& addr_size)
-{
- byte_order = eByteOrderInvalid;
- addr_size = 0;
- if (exe_scope == nullptr)
- return false;
-
- TargetSP target_sp (exe_scope->CalculateTarget());
- if (target_sp)
- {
- byte_order = target_sp->GetArchitecture().GetByteOrder();
- addr_size = target_sp->GetArchitecture().GetAddressByteSize();
- }
+ TargetSP target_sp(exe_scope->CalculateTarget());
+ if (target_sp) {
+ Error error;
+ bool prefer_file_cache = false;
+ return target_sp->ReadMemory(address, prefer_file_cache, dst, dst_len,
+ error);
+ }
+ return 0;
+}
+
+static bool GetByteOrderAndAddressSize(ExecutionContextScope *exe_scope,
+ const Address &address,
+ ByteOrder &byte_order,
+ uint32_t &addr_size) {
+ byte_order = eByteOrderInvalid;
+ addr_size = 0;
+ if (exe_scope == nullptr)
+ return false;
- if (byte_order == eByteOrderInvalid || addr_size == 0)
- {
- ModuleSP module_sp (address.GetModule());
- if (module_sp)
- {
- byte_order = module_sp->GetArchitecture().GetByteOrder();
- addr_size = module_sp->GetArchitecture().GetAddressByteSize();
- }
- }
- return byte_order != eByteOrderInvalid && addr_size != 0;
-}
+ TargetSP target_sp(exe_scope->CalculateTarget());
+ if (target_sp) {
+ byte_order = target_sp->GetArchitecture().GetByteOrder();
+ addr_size = target_sp->GetArchitecture().GetAddressByteSize();
+ }
-static uint64_t
-ReadUIntMax64 (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, bool &success)
-{
- uint64_t uval64 = 0;
- if (exe_scope == nullptr || byte_size > sizeof(uint64_t))
- {
- success = false;
- return 0;
+ if (byte_order == eByteOrderInvalid || addr_size == 0) {
+ ModuleSP module_sp(address.GetModule());
+ if (module_sp) {
+ byte_order = module_sp->GetArchitecture().GetByteOrder();
+ addr_size = module_sp->GetArchitecture().GetAddressByteSize();
}
- uint64_t buf = 0;
-
- success = ReadBytes (exe_scope, address, &buf, byte_size) == byte_size;
- if (success)
- {
- ByteOrder byte_order = eByteOrderInvalid;
- uint32_t addr_size = 0;
- if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
- {
- DataExtractor data (&buf, sizeof(buf), byte_order, addr_size);
- lldb::offset_t offset = 0;
- uval64 = data.GetU64(&offset);
- }
- else
- success = false;
- }
- return uval64;
+ }
+ return byte_order != eByteOrderInvalid && addr_size != 0;
}
-static bool
-ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr)
-{
- if (exe_scope == nullptr)
- return false;
-
- bool success = false;
- addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success);
- if (success)
- {
- ExecutionContext exe_ctx;
- exe_scope->CalculateExecutionContext(exe_ctx);
- // If we have any sections that are loaded, try and resolve using the
- // section load list
- Target *target = exe_ctx.GetTargetPtr();
- if (target && !target->GetSectionLoadList().IsEmpty())
- {
- if (target->GetSectionLoadList().ResolveLoadAddress (deref_addr, deref_so_addr))
- return true;
- }
- else
- {
- // If we were not running, yet able to read an integer, we must
- // have a module
- ModuleSP module_sp (address.GetModule());
-
- assert (module_sp);
- if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
- return true;
- }
+static uint64_t ReadUIntMax64(ExecutionContextScope *exe_scope,
+ const Address &address, uint32_t byte_size,
+ bool &success) {
+ uint64_t uval64 = 0;
+ if (exe_scope == nullptr || byte_size > sizeof(uint64_t)) {
+ success = false;
+ return 0;
+ }
+ uint64_t buf = 0;
+
+ success = ReadBytes(exe_scope, address, &buf, byte_size) == byte_size;
+ if (success) {
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t addr_size = 0;
+ if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
+ DataExtractor data(&buf, sizeof(buf), byte_order, addr_size);
+ lldb::offset_t offset = 0;
+ uval64 = data.GetU64(&offset);
+ } else
+ success = false;
+ }
+ return uval64;
+}
+
+static bool ReadAddress(ExecutionContextScope *exe_scope,
+ const Address &address, uint32_t pointer_size,
+ Address &deref_so_addr) {
+ if (exe_scope == nullptr)
+ return false;
- // We couldn't make "deref_addr" into a section offset value, but we were
- // able to read the address, so we return a section offset address with
- // no section and "deref_addr" as the offset (address).
- deref_so_addr.SetRawAddress(deref_addr);
+ bool success = false;
+ addr_t deref_addr = ReadUIntMax64(exe_scope, address, pointer_size, success);
+ if (success) {
+ ExecutionContext exe_ctx;
+ exe_scope->CalculateExecutionContext(exe_ctx);
+ // If we have any sections that are loaded, try and resolve using the
+ // section load list
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target && !target->GetSectionLoadList().IsEmpty()) {
+ if (target->GetSectionLoadList().ResolveLoadAddress(deref_addr,
+ deref_so_addr))
return true;
- }
- return false;
-}
+ } else {
+ // If we were not running, yet able to read an integer, we must
+ // have a module
+ ModuleSP module_sp(address.GetModule());
-static bool
-DumpUInt (ExecutionContextScope *exe_scope, const Address &address, uint32_t byte_size, Stream* strm)
-{
- if (exe_scope == nullptr || byte_size == 0)
- return 0;
- std::vector<uint8_t> buf(byte_size, 0);
-
- if (ReadBytes (exe_scope, address, &buf[0], buf.size()) == buf.size())
- {
- ByteOrder byte_order = eByteOrderInvalid;
- uint32_t addr_size = 0;
- if (GetByteOrderAndAddressSize (exe_scope, address, byte_order, addr_size))
- {
- DataExtractor data (&buf.front(), buf.size(), byte_order, addr_size);
-
- data.Dump (strm,
- 0, // Start offset in "data"
- eFormatHex, // Print as characters
- buf.size(), // Size of item
- 1, // Items count
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
- 0); // bitfield bit offset
-
- return true;
- }
+ assert(module_sp);
+ if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
+ return true;
}
- return false;
-}
-static size_t
-ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm)
-{
- if (exe_scope == nullptr)
- return 0;
- const size_t k_buf_len = 256;
- char buf[k_buf_len+1];
- buf[k_buf_len] = '\0'; // NULL terminate
-
- // Byte order and address size don't matter for C string dumping..
- DataExtractor data (buf, sizeof(buf), endian::InlHostByteOrder(), 4);
- size_t total_len = 0;
- size_t bytes_read;
- Address curr_address(address);
- strm->PutChar ('"');
- while ((bytes_read = ReadBytes (exe_scope, curr_address, buf, k_buf_len)) > 0)
- {
- size_t len = strlen(buf);
- if (len == 0)
- break;
- if (len > bytes_read)
- len = bytes_read;
-
- data.Dump (strm,
- 0, // Start offset in "data"
- eFormatChar, // Print as characters
- 1, // Size of item (1 byte for a char!)
- len, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
-
- 0); // bitfield bit offset
-
- total_len += bytes_read;
-
- if (len < k_buf_len)
- break;
- curr_address.SetOffset (curr_address.GetOffset() + bytes_read);
- }
- strm->PutChar ('"');
- return total_len;
+ // We couldn't make "deref_addr" into a section offset value, but we were
+ // able to read the address, so we return a section offset address with
+ // no section and "deref_addr" as the offset (address).
+ deref_so_addr.SetRawAddress(deref_addr);
+ return true;
+ }
+ return false;
}
-Address::Address (lldb::addr_t abs_addr) :
- m_section_wp (),
- m_offset (abs_addr)
-{
-}
+static bool DumpUInt(ExecutionContextScope *exe_scope, const Address &address,
+ uint32_t byte_size, Stream *strm) {
+ if (exe_scope == nullptr || byte_size == 0)
+ return 0;
+ std::vector<uint8_t> buf(byte_size, 0);
-Address::Address (addr_t address, const SectionList *section_list) :
- m_section_wp (),
- m_offset (LLDB_INVALID_ADDRESS)
-{
- ResolveAddressUsingFileSections(address, section_list);
-}
+ if (ReadBytes(exe_scope, address, &buf[0], buf.size()) == buf.size()) {
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t addr_size = 0;
+ if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
+ DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size);
-const Address&
-Address::operator= (const Address& rhs)
-{
- if (this != &rhs)
- {
- m_section_wp = rhs.m_section_wp;
- m_offset = rhs.m_offset.load();
- }
- return *this;
-}
+ data.Dump(strm,
+ 0, // Start offset in "data"
+ eFormatHex, // Print as characters
+ buf.size(), // Size of item
+ 1, // Items count
+ UINT32_MAX, // num per line
+ LLDB_INVALID_ADDRESS, // base address
+ 0, // bitfield bit size
+ 0); // bitfield bit offset
-bool
-Address::ResolveAddressUsingFileSections (addr_t file_addr, const SectionList *section_list)
-{
- if (section_list)
- {
- SectionSP section_sp (section_list->FindSectionContainingFileAddress(file_addr));
- m_section_wp = section_sp;
- if (section_sp)
- {
- assert( section_sp->ContainsFileAddress(file_addr) );
- m_offset = file_addr - section_sp->GetFileAddress();
- return true; // Successfully transformed addr into a section offset address
- }
+ return true;
}
- m_offset = file_addr;
- return false; // Failed to resolve this address to a section offset value
+ }
+ return false;
}
-ModuleSP
-Address::GetModule () const
-{
- lldb::ModuleSP module_sp;
- SectionSP section_sp (GetSection());
- if (section_sp)
- module_sp = section_sp->GetModule();
- return module_sp;
+static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope,
+ const Address &address, Stream *strm) {
+ if (exe_scope == nullptr)
+ return 0;
+ const size_t k_buf_len = 256;
+ char buf[k_buf_len + 1];
+ buf[k_buf_len] = '\0'; // NULL terminate
+
+ // Byte order and address size don't matter for C string dumping..
+ DataExtractor data(buf, sizeof(buf), endian::InlHostByteOrder(), 4);
+ size_t total_len = 0;
+ size_t bytes_read;
+ Address curr_address(address);
+ strm->PutChar('"');
+ while ((bytes_read = ReadBytes(exe_scope, curr_address, buf, k_buf_len)) >
+ 0) {
+ size_t len = strlen(buf);
+ if (len == 0)
+ break;
+ if (len > bytes_read)
+ len = bytes_read;
+
+ data.Dump(strm,
+ 0, // Start offset in "data"
+ eFormatChar, // Print as characters
+ 1, // Size of item (1 byte for a char!)
+ len, // How many bytes to print?
+ UINT32_MAX, // num per line
+ LLDB_INVALID_ADDRESS, // base address
+ 0, // bitfield bit size
+
+ 0); // bitfield bit offset
+
+ total_len += bytes_read;
+
+ if (len < k_buf_len)
+ break;
+ curr_address.SetOffset(curr_address.GetOffset() + bytes_read);
+ }
+ strm->PutChar('"');
+ return total_len;
+}
+
+Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {}
+
+Address::Address(addr_t address, const SectionList *section_list)
+ : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {
+ ResolveAddressUsingFileSections(address, section_list);
+}
+
+const Address &Address::operator=(const Address &rhs) {
+ if (this != &rhs) {
+ m_section_wp = rhs.m_section_wp;
+ m_offset = rhs.m_offset;
+ }
+ return *this;
+}
+
+bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
+ const SectionList *section_list) {
+ if (section_list) {
+ SectionSP section_sp(
+ section_list->FindSectionContainingFileAddress(file_addr));
+ m_section_wp = section_sp;
+ if (section_sp) {
+ assert(section_sp->ContainsFileAddress(file_addr));
+ m_offset = file_addr - section_sp->GetFileAddress();
+ return true; // Successfully transformed addr into a section offset
+ // address
+ }
+ }
+ m_offset = file_addr;
+ return false; // Failed to resolve this address to a section offset value
+}
+
+ModuleSP Address::GetModule() const {
+ lldb::ModuleSP module_sp;
+ SectionSP section_sp(GetSection());
+ if (section_sp)
+ module_sp = section_sp->GetModule();
+ return module_sp;
+}
+
+addr_t Address::GetFileAddress() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ addr_t sect_file_addr = section_sp->GetFileAddress();
+ if (sect_file_addr == LLDB_INVALID_ADDRESS) {
+ // Section isn't resolved, we can't return a valid file address
+ return LLDB_INVALID_ADDRESS;
+ }
+ // We have a valid file range, so we can return the file based
+ // address by adding the file base address to our offset
+ return sect_file_addr + m_offset;
+ } else if (SectionWasDeletedPrivate()) {
+ // Used to have a valid section but it got deleted so the
+ // offset doesn't mean anything without the section
+ return LLDB_INVALID_ADDRESS;
+ }
+ // No section, we just return the offset since it is the value in this case
+ return m_offset;
}
-addr_t
-Address::GetFileAddress () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- addr_t sect_file_addr = section_sp->GetFileAddress();
- if (sect_file_addr == LLDB_INVALID_ADDRESS)
- {
- // Section isn't resolved, we can't return a valid file address
- return LLDB_INVALID_ADDRESS;
- }
+addr_t Address::GetLoadAddress(Target *target) const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ if (target) {
+ addr_t sect_load_addr = section_sp->GetLoadBaseAddress(target);
+
+ if (sect_load_addr != LLDB_INVALID_ADDRESS) {
// We have a valid file range, so we can return the file based
// address by adding the file base address to our offset
- return sect_file_addr + m_offset;
- }
- else if (SectionWasDeletedPrivate())
- {
- // Used to have a valid section but it got deleted so the
- // offset doesn't mean anything without the section
- return LLDB_INVALID_ADDRESS;
+ return sect_load_addr + m_offset;
+ }
}
- // No section, we just return the offset since it is the value in this case
+ } else if (SectionWasDeletedPrivate()) {
+ // Used to have a valid section but it got deleted so the
+ // offset doesn't mean anything without the section
+ return LLDB_INVALID_ADDRESS;
+ } else {
+ // We don't have a section so the offset is the load address
return m_offset;
+ }
+ // The section isn't resolved or an invalid target was passed in
+ // so we can't return a valid load address.
+ return LLDB_INVALID_ADDRESS;
}
-addr_t
-Address::GetLoadAddress (Target *target) const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- if (target)
- {
- addr_t sect_load_addr = section_sp->GetLoadBaseAddress (target);
-
- if (sect_load_addr != LLDB_INVALID_ADDRESS)
- {
- // We have a valid file range, so we can return the file based
- // address by adding the file base address to our offset
- return sect_load_addr + m_offset;
- }
- }
- }
- else if (SectionWasDeletedPrivate())
- {
- // Used to have a valid section but it got deleted so the
- // offset doesn't mean anything without the section
- return LLDB_INVALID_ADDRESS;
- }
- else
- {
- // We don't have a section so the offset is the load address
- return m_offset;
- }
- // The section isn't resolved or an invalid target was passed in
- // so we can't return a valid load address.
- return LLDB_INVALID_ADDRESS;
-}
+addr_t Address::GetCallableLoadAddress(Target *target, bool is_indirect) const {
+ addr_t code_addr = LLDB_INVALID_ADDRESS;
-addr_t
-Address::GetCallableLoadAddress (Target *target, bool is_indirect) const
-{
- addr_t code_addr = LLDB_INVALID_ADDRESS;
-
- if (is_indirect && target)
- {
- ProcessSP processSP = target->GetProcessSP();
- Error error;
- if (processSP)
- {
- code_addr = processSP->ResolveIndirectFunction(this, error);
- if (!error.Success())
- code_addr = LLDB_INVALID_ADDRESS;
- }
- }
- else
- {
- code_addr = GetLoadAddress (target);
+ if (is_indirect && target) {
+ ProcessSP processSP = target->GetProcessSP();
+ Error error;
+ if (processSP) {
+ code_addr = processSP->ResolveIndirectFunction(this, error);
+ if (!error.Success())
+ code_addr = LLDB_INVALID_ADDRESS;
}
-
- if (code_addr == LLDB_INVALID_ADDRESS)
- return code_addr;
-
- if (target)
- return target->GetCallableLoadAddress (code_addr, GetAddressClass());
+ } else {
+ code_addr = GetLoadAddress(target);
+ }
+
+ if (code_addr == LLDB_INVALID_ADDRESS)
return code_addr;
-}
-bool
-Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target)
-{
- if (SetLoadAddress (load_addr, target))
- {
- if (target)
- m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
- return true;
- }
- return false;
+ if (target)
+ return target->GetCallableLoadAddress(code_addr, GetAddressClass());
+ return code_addr;
}
-addr_t
-Address::GetOpcodeLoadAddress (Target *target, AddressClass addr_class) const
-{
- addr_t code_addr = GetLoadAddress (target);
- if (code_addr != LLDB_INVALID_ADDRESS)
- {
- if (addr_class == eAddressClassInvalid)
- addr_class = GetAddressClass();
- code_addr = target->GetOpcodeLoadAddress (code_addr, addr_class);
- }
- return code_addr;
+bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) {
+ if (SetLoadAddress(load_addr, target)) {
+ if (target)
+ m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
+ return true;
+ }
+ return false;
}
-bool
-Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target, AddressClass addr_class)
-{
- if (SetLoadAddress (load_addr, target))
- {
- if (target)
- {
- if (addr_class == eAddressClassInvalid)
- addr_class = GetAddressClass();
- m_offset = target->GetOpcodeLoadAddress (m_offset, addr_class);
- }
- return true;
- }
- return false;
+addr_t Address::GetOpcodeLoadAddress(Target *target,
+ AddressClass addr_class) const {
+ addr_t code_addr = GetLoadAddress(target);
+ if (code_addr != LLDB_INVALID_ADDRESS) {
+ if (addr_class == eAddressClassInvalid)
+ addr_class = GetAddressClass();
+ code_addr = target->GetOpcodeLoadAddress(code_addr, addr_class);
+ }
+ return code_addr;
}
-bool
-Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
-{
- // If the section was nullptr, only load address is going to work unless we are
- // trying to deref a pointer
- SectionSP section_sp (GetSection());
- if (!section_sp && style != DumpStyleResolvedPointerDescription)
- style = DumpStyleLoadAddress;
-
- ExecutionContext exe_ctx (exe_scope);
- Target *target = exe_ctx.GetTargetPtr();
- // If addr_byte_size is UINT32_MAX, then determine the correct address
- // byte size for the process or default to the size of addr_t
- if (addr_size == UINT32_MAX)
- {
- if (target)
- addr_size = target->GetArchitecture().GetAddressByteSize ();
- else
- addr_size = sizeof(addr_t);
+bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target,
+ AddressClass addr_class) {
+ if (SetLoadAddress(load_addr, target)) {
+ if (target) {
+ if (addr_class == eAddressClassInvalid)
+ addr_class = GetAddressClass();
+ m_offset = target->GetOpcodeLoadAddress(m_offset, addr_class);
}
+ return true;
+ }
+ return false;
+}
+
+bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
+ DumpStyle fallback_style, uint32_t addr_size) const {
+ // If the section was nullptr, only load address is going to work unless we
+ // are
+ // trying to deref a pointer
+ SectionSP section_sp(GetSection());
+ if (!section_sp && style != DumpStyleResolvedPointerDescription)
+ style = DumpStyleLoadAddress;
+
+ ExecutionContext exe_ctx(exe_scope);
+ Target *target = exe_ctx.GetTargetPtr();
+ // If addr_byte_size is UINT32_MAX, then determine the correct address
+ // byte size for the process or default to the size of addr_t
+ if (addr_size == UINT32_MAX) {
+ if (target)
+ addr_size = target->GetArchitecture().GetAddressByteSize();
+ else
+ addr_size = sizeof(addr_t);
+ }
- Address so_addr;
- switch (style)
- {
- case DumpStyleInvalid:
- return false;
-
- case DumpStyleSectionNameOffset:
- if (section_sp)
- {
- section_sp->DumpName(s);
- s->Printf (" + %" PRIu64, m_offset.load());
- }
- else
- {
- s->Address(m_offset, addr_size);
- }
- break;
-
- case DumpStyleSectionPointerOffset:
- s->Printf("(Section *)%p + ", static_cast<void*>(section_sp.get()));
- s->Address(m_offset, addr_size);
- break;
-
- case DumpStyleModuleWithFileAddress:
- if (section_sp)
- {
- ModuleSP module_sp = section_sp->GetModule();
- if (module_sp)
- s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"));
- else
- s->Printf("%s[","<Unknown>");
- }
- LLVM_FALLTHROUGH;
- case DumpStyleFileAddress:
- {
- addr_t file_addr = GetFileAddress();
- if (file_addr == LLDB_INVALID_ADDRESS)
- {
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
- }
- s->Address (file_addr, addr_size);
- if (style == DumpStyleModuleWithFileAddress && section_sp)
- s->PutChar(']');
- }
- break;
-
- 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);
- }
+ Address so_addr;
+ switch (style) {
+ case DumpStyleInvalid:
+ return false;
- if (load_addr == LLDB_INVALID_ADDRESS)
- {
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
- }
- s->Address (load_addr, addr_size);
- }
- break;
-
- case DumpStyleResolvedDescription:
- case DumpStyleResolvedDescriptionNoModule:
- case DumpStyleResolvedDescriptionNoFunctionArguments:
- case DumpStyleNoFunctionName:
- if (IsSectionOffset())
- {
- uint32_t pointer_size = 4;
- ModuleSP module_sp (GetModule());
- if (target)
- pointer_size = target->GetArchitecture().GetAddressByteSize();
- else if (module_sp)
- pointer_size = module_sp->GetArchitecture().GetAddressByteSize();
-
- bool showed_info = false;
- if (section_sp)
- {
- SectionType sect_type = section_sp->GetType();
- switch (sect_type)
- {
- case eSectionTypeData:
- if (module_sp)
- {
- SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- {
- const addr_t file_Addr = GetFileAddress();
- Symbol *symbol = symtab->FindSymbolContainingFileAddress (file_Addr);
- if (symbol)
- {
- const char *symbol_name = symbol->GetName().AsCString();
- if (symbol_name)
- {
- s->PutCString(symbol_name);
- addr_t delta = file_Addr - symbol->GetAddressRef().GetFileAddress();
- if (delta)
- s->Printf(" + %" PRIu64, delta);
- showed_info = true;
- }
- }
- }
- }
- }
- break;
-
- case eSectionTypeDataCString:
- // Read the C string from memory and display it
+ case DumpStyleSectionNameOffset:
+ if (section_sp) {
+ section_sp->DumpName(s);
+ s->Printf(" + %" PRIu64, m_offset);
+ } else {
+ s->Address(m_offset, addr_size);
+ }
+ break;
+
+ case DumpStyleSectionPointerOffset:
+ s->Printf("(Section *)%p + ", static_cast<void *>(section_sp.get()));
+ s->Address(m_offset, addr_size);
+ break;
+
+ case DumpStyleModuleWithFileAddress:
+ if (section_sp) {
+ ModuleSP module_sp = section_sp->GetModule();
+ if (module_sp)
+ s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
+ "<Unknown>"));
+ else
+ s->Printf("%s[", "<Unknown>");
+ }
+ LLVM_FALLTHROUGH;
+ case DumpStyleFileAddress: {
+ addr_t file_addr = GetFileAddress();
+ if (file_addr == LLDB_INVALID_ADDRESS) {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ s->Address(file_addr, addr_size);
+ if (style == DumpStyleModuleWithFileAddress && section_sp)
+ s->PutChar(']');
+ } break;
+
+ 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)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ s->Address(load_addr, addr_size);
+ } break;
+
+ case DumpStyleResolvedDescription:
+ case DumpStyleResolvedDescriptionNoModule:
+ case DumpStyleResolvedDescriptionNoFunctionArguments:
+ case DumpStyleNoFunctionName:
+ if (IsSectionOffset()) {
+ uint32_t pointer_size = 4;
+ ModuleSP module_sp(GetModule());
+ if (target)
+ pointer_size = target->GetArchitecture().GetAddressByteSize();
+ else if (module_sp)
+ pointer_size = module_sp->GetArchitecture().GetAddressByteSize();
+
+ bool showed_info = false;
+ if (section_sp) {
+ SectionType sect_type = section_sp->GetType();
+ switch (sect_type) {
+ case eSectionTypeData:
+ if (module_sp) {
+ SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab) {
+ const addr_t file_Addr = GetFileAddress();
+ Symbol *symbol =
+ symtab->FindSymbolContainingFileAddress(file_Addr);
+ if (symbol) {
+ const char *symbol_name = symbol->GetName().AsCString();
+ if (symbol_name) {
+ s->PutCString(symbol_name);
+ addr_t delta =
+ file_Addr - symbol->GetAddressRef().GetFileAddress();
+ if (delta)
+ s->Printf(" + %" PRIu64, delta);
showed_info = true;
- ReadCStringFromMemory (exe_scope, *this, s);
- break;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case eSectionTypeDataCString:
+ // Read the C string from memory and display it
+ showed_info = true;
+ ReadCStringFromMemory(exe_scope, *this, s);
+ break;
- case eSectionTypeDataCStringPointers:
- if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
- {
+ case eSectionTypeDataCStringPointers:
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
#if VERBOSE_OUTPUT
- s->PutCString("(char *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(": ");
+ s->PutCString("(char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(": ");
#endif
- showed_info = true;
- ReadCStringFromMemory(exe_scope, so_addr, s);
- }
- break;
-
- case eSectionTypeDataObjCMessageRefs:
- if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
- {
- if (target && so_addr.IsSectionOffset())
- {
- SymbolContext func_sc;
- target->GetImages().ResolveSymbolContextForAddress(so_addr,
- eSymbolContextEverything,
- func_sc);
- if (func_sc.function != nullptr || func_sc.symbol != nullptr)
- {
- showed_info = true;
+ showed_info = true;
+ ReadCStringFromMemory(exe_scope, so_addr, s);
+ }
+ break;
+
+ case eSectionTypeDataObjCMessageRefs:
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
+ if (target && so_addr.IsSectionOffset()) {
+ SymbolContext func_sc;
+ target->GetImages().ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, func_sc);
+ if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
+ showed_info = true;
#if VERBOSE_OUTPUT
- s->PutCString ("(objc_msgref *) -> { (func*)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
+ s->PutCString("(objc_msgref *) -> { (func*)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
#else
- s->PutCString ("{ ");
+ s->PutCString("{ ");
#endif
- Address cstr_addr(*this);
- cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
- func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true, true);
- if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr))
- {
+ Address cstr_addr(*this);
+ cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
+ func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
+ false, true, true);
+ if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
#if VERBOSE_OUTPUT
- s->PutCString("), (char *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(" (");
+ s->PutCString("), (char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(" (");
#else
- s->PutCString(", ");
+ s->PutCString(", ");
#endif
- ReadCStringFromMemory (exe_scope, so_addr, s);
- }
+ ReadCStringFromMemory(exe_scope, so_addr, s);
+ }
#if VERBOSE_OUTPUT
- s->PutCString(") }");
+ s->PutCString(") }");
#else
- s->PutCString(" }");
+ s->PutCString(" }");
#endif
- }
- }
- }
- break;
-
- case eSectionTypeDataObjCCFStrings:
- {
- Address cfstring_data_addr(*this);
- cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
- if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
- {
+ }
+ }
+ }
+ break;
+
+ case eSectionTypeDataObjCCFStrings: {
+ Address cfstring_data_addr(*this);
+ cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
+ (2 * pointer_size));
+ if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
+ so_addr)) {
#if VERBOSE_OUTPUT
- s->PutCString("(CFString *) ");
- cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(" -> @");
+ s->PutCString("(CFString *) ");
+ cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(" -> @");
#else
- s->PutChar('@');
+ s->PutChar('@');
#endif
- if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
- showed_info = true;
- }
- }
- break;
-
- case eSectionTypeData4:
- // Read the 4 byte data and display it
- showed_info = true;
- s->PutCString("(uint32_t) ");
- DumpUInt (exe_scope, *this, 4, s);
- break;
-
- case eSectionTypeData8:
- // Read the 8 byte data and display it
- showed_info = true;
- s->PutCString("(uint64_t) ");
- DumpUInt (exe_scope, *this, 8, s);
- break;
-
- case eSectionTypeData16:
- // Read the 16 byte data and display it
- showed_info = true;
- s->PutCString("(uint128_t) ");
- DumpUInt (exe_scope, *this, 16, s);
- break;
-
- case eSectionTypeDataPointers:
- // Read the pointer data and display it
- if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
- {
- s->PutCString ("(void *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
-
- showed_info = true;
- if (so_addr.IsSectionOffset())
- {
- SymbolContext pointer_sc;
- if (target)
- {
- target->GetImages().ResolveSymbolContextForAddress(so_addr,
- eSymbolContextEverything,
- pointer_sc);
- if (pointer_sc.function != nullptr || pointer_sc.symbol != nullptr)
- {
- s->PutCString(": ");
- pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true, true);
- }
- }
- }
- }
- break;
-
- default:
- break;
+ if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
+ showed_info = true;
+ }
+ } break;
+
+ case eSectionTypeData4:
+ // Read the 4 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint32_t) ");
+ DumpUInt(exe_scope, *this, 4, s);
+ break;
+
+ case eSectionTypeData8:
+ // Read the 8 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint64_t) ");
+ DumpUInt(exe_scope, *this, 8, s);
+ break;
+
+ case eSectionTypeData16:
+ // Read the 16 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint128_t) ");
+ DumpUInt(exe_scope, *this, 16, s);
+ break;
+
+ case eSectionTypeDataPointers:
+ // Read the pointer data and display it
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
+ s->PutCString("(void *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+
+ showed_info = true;
+ if (so_addr.IsSectionOffset()) {
+ SymbolContext pointer_sc;
+ if (target) {
+ target->GetImages().ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, pointer_sc);
+ if (pointer_sc.function != nullptr ||
+ pointer_sc.symbol != nullptr) {
+ s->PutCString(": ");
+ pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
+ false, true, true);
}
+ }
}
+ }
+ break;
- if (!showed_info)
- {
- if (module_sp)
- {
- SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
- if (sc.function || sc.symbol)
- {
- bool show_stop_context = true;
- const bool show_module = (style == DumpStyleResolvedDescription);
- const bool show_fullpaths = false;
- const bool show_inlined_frames = true;
- const bool show_function_arguments = (style != DumpStyleResolvedDescriptionNoFunctionArguments);
- const bool show_function_name = (style != DumpStyleNoFunctionName);
- if (sc.function == nullptr && sc.symbol != nullptr)
- {
- // If we have just a symbol make sure it is in the right section
- if (sc.symbol->ValueIsAddress())
- {
- if (sc.symbol->GetAddressRef().GetSection() != GetSection())
- {
- // don't show the module if the symbol is a trampoline symbol
- show_stop_context = false;
- }
- }
- }
- if (show_stop_context)
- {
- // We have a function or a symbol from the same
- // sections as this address.
- sc.DumpStopContext (s,
- exe_scope,
- *this,
- show_fullpaths,
- show_module,
- show_inlined_frames,
- show_function_arguments,
- show_function_name);
- }
- else
- {
- // We found a symbol but it was in a different
- // section so it isn't the symbol we should be
- // showing, just show the section name + offset
- Dump (s, exe_scope, DumpStyleSectionNameOffset);
- }
- }
- }
- }
- }
- else
- {
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
+ default:
+ break;
}
- break;
-
- case DumpStyleDetailedSymbolContext:
- if (IsSectionOffset())
- {
- ModuleSP module_sp (GetModule());
- if (module_sp)
- {
- SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
- if (sc.symbol)
- {
- // If we have just a symbol make sure it is in the same section
- // as our address. If it isn't, then we might have just found
- // the last symbol that came before the address that we are
- // looking up that has nothing to do with our address lookup.
- if (sc.symbol->ValueIsAddress() && sc.symbol->GetAddressRef().GetSection() != GetSection())
- sc.symbol = nullptr;
- }
- sc.GetDescription(s, eDescriptionLevelBrief, target);
-
- if (sc.block)
- {
- bool can_create = true;
- bool get_parent_variables = true;
- bool stop_if_block_is_inlined_function = false;
- VariableList variable_list;
- sc.block->AppendVariables (can_create,
- get_parent_variables,
- stop_if_block_is_inlined_function,
- [](Variable*) { return true; },
- &variable_list);
-
- const size_t num_variables = variable_list.GetSize();
- for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
- {
- Variable *var = variable_list.GetVariableAtIndex (var_idx).get();
- if (var && var->LocationIsValidForAddress (*this))
- {
- s->Indent();
- s->Printf (" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
- var->GetID(),
- var->GetName().GetCString());
- Type *type = var->GetType();
- if (type)
- s->Printf(", type = \"%s\"", type->GetName().GetCString());
- else
- s->PutCString(", type = <unknown>");
- s->PutCString(", location = ");
- var->DumpLocationForAddress(s, *this);
- s->PutCString(", decl = ");
- var->GetDeclaration().DumpStopContext(s, false);
- s->EOL();
- }
- }
+ }
+
+ if (!showed_info) {
+ if (module_sp) {
+ SymbolContext sc;
+ module_sp->ResolveSymbolContextForAddress(
+ *this, eSymbolContextEverything, sc);
+ if (sc.function || sc.symbol) {
+ bool show_stop_context = true;
+ const bool show_module = (style == DumpStyleResolvedDescription);
+ const bool show_fullpaths = false;
+ const bool show_inlined_frames = true;
+ const bool show_function_arguments =
+ (style != DumpStyleResolvedDescriptionNoFunctionArguments);
+ const bool show_function_name = (style != DumpStyleNoFunctionName);
+ if (sc.function == nullptr && sc.symbol != nullptr) {
+ // If we have just a symbol make sure it is in the right section
+ if (sc.symbol->ValueIsAddress()) {
+ if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
+ // don't show the module if the symbol is a trampoline symbol
+ show_stop_context = false;
}
+ }
}
- }
- else
- {
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
- }
- break;
-
- case DumpStyleResolvedPointerDescription:
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- addr_t load_addr = GetLoadAddress (target);
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- Error memory_error;
- addr_t dereferenced_load_addr = process->ReadPointerFromMemory(load_addr, memory_error);
- if (dereferenced_load_addr != LLDB_INVALID_ADDRESS)
- {
- Address dereferenced_addr;
- if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr, target))
- {
- StreamString strm;
- if (dereferenced_addr.Dump (&strm, exe_scope, DumpStyleResolvedDescription, DumpStyleInvalid, addr_size))
- {
- s->Address (dereferenced_load_addr, addr_size, " -> ", " ");
- s->Write(strm.GetData(), strm.GetSize());
- return true;
- }
- }
- }
- }
+ if (show_stop_context) {
+ // We have a function or a symbol from the same
+ // sections as this address.
+ sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
+ show_module, show_inlined_frames,
+ show_function_arguments, show_function_name);
+ } else {
+ // We found a symbol but it was in a different
+ // section so it isn't the symbol we should be
+ // showing, just show the section name + offset
+ Dump(s, exe_scope, DumpStyleSectionNameOffset);
}
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
- }
- break;
- }
-
- return true;
-}
-
-bool
-Address::SectionWasDeleted() const
-{
- if (GetSection())
- return false;
- return SectionWasDeletedPrivate();
-}
-
-bool
-Address::SectionWasDeletedPrivate() const
-{
- lldb::SectionWP empty_section_wp;
-
- // If either call to "std::weak_ptr::owner_before(...) value returns true, this
- // indicates that m_section_wp once contained (possibly still does) a reference
- // to a valid shared pointer. This helps us know if we had a valid reference to
- // a section which is now invalid because the module it was in was unloaded/deleted,
- // or if the address doesn't have a valid reference to a section.
- return empty_section_wp.owner_before(m_section_wp) || m_section_wp.owner_before(empty_section_wp);
-}
-
-uint32_t
-Address::CalculateSymbolContext (SymbolContext *sc, uint32_t resolve_scope) const
-{
- sc->Clear(false);
- // Absolute addresses don't have enough information to reconstruct even their target.
-
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- ModuleSP module_sp (section_sp->GetModule());
- if (module_sp)
- {
- sc->module_sp = module_sp;
- if (sc->module_sp)
- return sc->module_sp->ResolveSymbolContextForAddress (*this, resolve_scope, *sc);
+ }
}
- }
- return 0;
-}
-
-ModuleSP
-Address::CalculateSymbolContextModule () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- return section_sp->GetModule();
- return ModuleSP();
-}
-
-CompileUnit *
-Address::CalculateSymbolContextCompileUnit () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- SymbolContext sc;
- sc.module_sp = section_sp->GetModule();
- if (sc.module_sp)
- {
- sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextCompUnit, sc);
- return sc.comp_unit;
- }
- }
- return nullptr;
-}
-
-Function *
-Address::CalculateSymbolContextFunction () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
+ }
+ } else {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ break;
+
+ case DumpStyleDetailedSymbolContext:
+ if (IsSectionOffset()) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
SymbolContext sc;
- sc.module_sp = section_sp->GetModule();
- if (sc.module_sp)
- {
- sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextFunction, sc);
- return sc.function;
+ module_sp->ResolveSymbolContextForAddress(
+ *this, eSymbolContextEverything | eSymbolContextVariable, sc);
+ if (sc.symbol) {
+ // If we have just a symbol make sure it is in the same section
+ // as our address. If it isn't, then we might have just found
+ // the last symbol that came before the address that we are
+ // looking up that has nothing to do with our address lookup.
+ if (sc.symbol->ValueIsAddress() &&
+ sc.symbol->GetAddressRef().GetSection() != GetSection())
+ sc.symbol = nullptr;
}
- }
- return nullptr;
-}
-
-Block *
-Address::CalculateSymbolContextBlock () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- SymbolContext sc;
- sc.module_sp = section_sp->GetModule();
- if (sc.module_sp)
- {
- sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextBlock, sc);
- return sc.block;
- }
- }
- return nullptr;
-}
-
-Symbol *
-Address::CalculateSymbolContextSymbol () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- SymbolContext sc;
- sc.module_sp = section_sp->GetModule();
- if (sc.module_sp)
- {
- sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextSymbol, sc);
- return sc.symbol;
+ sc.GetDescription(s, eDescriptionLevelBrief, target);
+
+ if (sc.block) {
+ bool can_create = true;
+ bool get_parent_variables = true;
+ bool stop_if_block_is_inlined_function = false;
+ VariableList variable_list;
+ sc.block->AppendVariables(can_create, get_parent_variables,
+ stop_if_block_is_inlined_function,
+ [](Variable *) { return true; },
+ &variable_list);
+
+ const size_t num_variables = variable_list.GetSize();
+ for (size_t var_idx = 0; var_idx < num_variables; ++var_idx) {
+ Variable *var = variable_list.GetVariableAtIndex(var_idx).get();
+ if (var && var->LocationIsValidForAddress(*this)) {
+ s->Indent();
+ s->Printf(" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
+ var->GetID(), var->GetName().GetCString());
+ Type *type = var->GetType();
+ if (type)
+ s->Printf(", type = \"%s\"", type->GetName().GetCString());
+ else
+ s->PutCString(", type = <unknown>");
+ s->PutCString(", location = ");
+ var->DumpLocationForAddress(s, *this);
+ s->PutCString(", decl = ");
+ var->GetDeclaration().DumpStopContext(s, false);
+ s->EOL();
+ }
+ }
}
- }
- return nullptr;
-}
-
-bool
-Address::CalculateSymbolContextLineEntry (LineEntry &line_entry) const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- SymbolContext sc;
- sc.module_sp = section_sp->GetModule();
- if (sc.module_sp)
- {
- sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextLineEntry, sc);
- if (sc.line_entry.IsValid())
- {
- line_entry = sc.line_entry;
- return true;
+ }
+ } else {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ break;
+
+ case DumpStyleResolvedPointerDescription: {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ addr_t load_addr = GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ Error memory_error;
+ addr_t dereferenced_load_addr =
+ process->ReadPointerFromMemory(load_addr, memory_error);
+ if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
+ Address dereferenced_addr;
+ if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
+ target)) {
+ StreamString strm;
+ if (dereferenced_addr.Dump(&strm, exe_scope,
+ DumpStyleResolvedDescription,
+ DumpStyleInvalid, addr_size)) {
+ s->Address(dereferenced_load_addr, addr_size, " -> ", " ");
+ s->Write(strm.GetString().data(), strm.GetSize());
+ return true;
}
+ }
}
+ }
}
- line_entry.Clear();
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
return false;
-}
+ } break;
+ }
-int
-Address::CompareFileAddress (const Address& a, const Address& b)
-{
- addr_t a_file_addr = a.GetFileAddress();
- addr_t b_file_addr = b.GetFileAddress();
- if (a_file_addr < b_file_addr)
- return -1;
- if (a_file_addr > b_file_addr)
- return +1;
- return 0;
-}
-
-int
-Address::CompareLoadAddress (const Address& a, const Address& b, Target *target)
-{
- assert(target != nullptr);
- addr_t a_load_addr = a.GetLoadAddress (target);
- addr_t b_load_addr = b.GetLoadAddress (target);
- if (a_load_addr < b_load_addr)
- return -1;
- if (a_load_addr > b_load_addr)
- return +1;
- return 0;
+ return true;
}
-int
-Address::CompareModulePointerAndOffset (const Address& a, const Address& b)
-{
- ModuleSP a_module_sp (a.GetModule());
- ModuleSP b_module_sp (b.GetModule());
- Module *a_module = a_module_sp.get();
- Module *b_module = b_module_sp.get();
- if (a_module < b_module)
- return -1;
- if (a_module > b_module)
- return +1;
- // Modules are the same, just compare the file address since they should
- // be unique
- addr_t a_file_addr = a.GetFileAddress();
- addr_t b_file_addr = b.GetFileAddress();
- if (a_file_addr < b_file_addr)
- return -1;
- if (a_file_addr > b_file_addr)
- return +1;
- return 0;
-}
-
-size_t
-Address::MemorySize () const
-{
- // Noting special for the memory size of a single Address object,
- // it is just the size of itself.
- return sizeof(Address);
+bool Address::SectionWasDeleted() const {
+ if (GetSection())
+ return false;
+ return SectionWasDeletedPrivate();
+}
+
+bool Address::SectionWasDeletedPrivate() const {
+ lldb::SectionWP empty_section_wp;
+
+ // If either call to "std::weak_ptr::owner_before(...) value returns true,
+ // this
+ // indicates that m_section_wp once contained (possibly still does) a
+ // reference
+ // to a valid shared pointer. This helps us know if we had a valid reference
+ // to
+ // a section which is now invalid because the module it was in was
+ // unloaded/deleted,
+ // or if the address doesn't have a valid reference to a section.
+ return empty_section_wp.owner_before(m_section_wp) ||
+ m_section_wp.owner_before(empty_section_wp);
+}
+
+uint32_t Address::CalculateSymbolContext(SymbolContext *sc,
+ uint32_t resolve_scope) const {
+ sc->Clear(false);
+ // Absolute addresses don't have enough information to reconstruct even their
+ // target.
+
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ ModuleSP module_sp(section_sp->GetModule());
+ if (module_sp) {
+ sc->module_sp = module_sp;
+ if (sc->module_sp)
+ return sc->module_sp->ResolveSymbolContextForAddress(
+ *this, resolve_scope, *sc);
+ }
+ }
+ return 0;
+}
+
+ModuleSP Address::CalculateSymbolContextModule() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp)
+ return section_sp->GetModule();
+ return ModuleSP();
+}
+
+CompileUnit *Address::CalculateSymbolContextCompileUnit() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this,
+ eSymbolContextCompUnit, sc);
+ return sc.comp_unit;
+ }
+ }
+ return nullptr;
+}
+
+Function *Address::CalculateSymbolContextFunction() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this,
+ eSymbolContextFunction, sc);
+ return sc.function;
+ }
+ }
+ return nullptr;
+}
+
+Block *Address::CalculateSymbolContextBlock() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextBlock,
+ sc);
+ return sc.block;
+ }
+ }
+ return nullptr;
+}
+
+Symbol *Address::CalculateSymbolContextSymbol() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextSymbol,
+ sc);
+ return sc.symbol;
+ }
+ }
+ return nullptr;
+}
+
+bool Address::CalculateSymbolContextLineEntry(LineEntry &line_entry) const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this,
+ eSymbolContextLineEntry, sc);
+ if (sc.line_entry.IsValid()) {
+ line_entry = sc.line_entry;
+ return true;
+ }
+ }
+ }
+ line_entry.Clear();
+ return false;
+}
+
+int Address::CompareFileAddress(const Address &a, const Address &b) {
+ addr_t a_file_addr = a.GetFileAddress();
+ addr_t b_file_addr = b.GetFileAddress();
+ if (a_file_addr < b_file_addr)
+ return -1;
+ if (a_file_addr > b_file_addr)
+ return +1;
+ return 0;
+}
+
+int Address::CompareLoadAddress(const Address &a, const Address &b,
+ Target *target) {
+ assert(target != nullptr);
+ addr_t a_load_addr = a.GetLoadAddress(target);
+ addr_t b_load_addr = b.GetLoadAddress(target);
+ if (a_load_addr < b_load_addr)
+ return -1;
+ if (a_load_addr > b_load_addr)
+ return +1;
+ return 0;
+}
+
+int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
+ ModuleSP a_module_sp(a.GetModule());
+ ModuleSP b_module_sp(b.GetModule());
+ Module *a_module = a_module_sp.get();
+ Module *b_module = b_module_sp.get();
+ if (a_module < b_module)
+ return -1;
+ if (a_module > b_module)
+ return +1;
+ // Modules are the same, just compare the file address since they should
+ // be unique
+ addr_t a_file_addr = a.GetFileAddress();
+ addr_t b_file_addr = b.GetFileAddress();
+ if (a_file_addr < b_file_addr)
+ return -1;
+ if (a_file_addr > b_file_addr)
+ return +1;
+ return 0;
+}
+
+size_t Address::MemorySize() const {
+ // Noting special for the memory size of a single Address object,
+ // it is just the size of itself.
+ return sizeof(Address);
}
//----------------------------------------------------------------------
-// NOTE: Be careful using this operator. It can correctly compare two
-// addresses from the same Module correctly. It can't compare two
+// NOTE: Be careful using this operator. It can correctly compare two
+// addresses from the same Module correctly. It can't compare two
// addresses from different modules in any meaningful way, but it will
// compare the module pointers.
-//
+//
// To sum things up:
// - works great for addresses within the same module
// - it works for addresses across multiple modules, but don't expect the
// address results to make much sense
//
-// This basically lets Address objects be used in ordered collection
+// This basically lets Address objects be used in ordered collection
// classes.
//----------------------------------------------------------------------
-bool
-lldb_private::operator< (const Address& lhs, const Address& rhs)
-{
- ModuleSP lhs_module_sp (lhs.GetModule());
- ModuleSP rhs_module_sp (rhs.GetModule());
- Module *lhs_module = lhs_module_sp.get();
- Module *rhs_module = rhs_module_sp.get();
- if (lhs_module == rhs_module)
- {
- // Addresses are in the same module, just compare the file addresses
- return lhs.GetFileAddress() < rhs.GetFileAddress();
- }
- else
- {
- // The addresses are from different modules, just use the module
- // pointer value to get consistent ordering
- return lhs_module < rhs_module;
- }
-}
-
-bool
-lldb_private::operator> (const Address& lhs, const Address& rhs)
-{
- ModuleSP lhs_module_sp (lhs.GetModule());
- ModuleSP rhs_module_sp (rhs.GetModule());
- Module *lhs_module = lhs_module_sp.get();
- Module *rhs_module = rhs_module_sp.get();
- if (lhs_module == rhs_module)
- {
- // Addresses are in the same module, just compare the file addresses
- return lhs.GetFileAddress() > rhs.GetFileAddress();
- }
- else
- {
- // The addresses are from different modules, just use the module
- // pointer value to get consistent ordering
- return lhs_module > rhs_module;
- }
+bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
+ ModuleSP lhs_module_sp(lhs.GetModule());
+ ModuleSP rhs_module_sp(rhs.GetModule());
+ Module *lhs_module = lhs_module_sp.get();
+ Module *rhs_module = rhs_module_sp.get();
+ if (lhs_module == rhs_module) {
+ // Addresses are in the same module, just compare the file addresses
+ return lhs.GetFileAddress() < rhs.GetFileAddress();
+ } else {
+ // The addresses are from different modules, just use the module
+ // pointer value to get consistent ordering
+ return lhs_module < rhs_module;
+ }
+}
+
+bool lldb_private::operator>(const Address &lhs, const Address &rhs) {
+ ModuleSP lhs_module_sp(lhs.GetModule());
+ ModuleSP rhs_module_sp(rhs.GetModule());
+ Module *lhs_module = lhs_module_sp.get();
+ Module *rhs_module = rhs_module_sp.get();
+ if (lhs_module == rhs_module) {
+ // Addresses are in the same module, just compare the file addresses
+ return lhs.GetFileAddress() > rhs.GetFileAddress();
+ } else {
+ // The addresses are from different modules, just use the module
+ // pointer value to get consistent ordering
+ return lhs_module > rhs_module;
+ }
}
// The operator == checks for exact equality only (same section, same offset)
-bool
-lldb_private::operator== (const Address& a, const Address& rhs)
-{
- return a.GetOffset() == rhs.GetOffset() &&
- a.GetSection() == rhs.GetSection();
+bool lldb_private::operator==(const Address &a, const Address &rhs) {
+ return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection();
}
// The operator != checks for exact inequality only (differing section, or
// different offset)
-bool
-lldb_private::operator!= (const Address& a, const Address& rhs)
-{
- return a.GetOffset() != rhs.GetOffset() ||
- a.GetSection() != rhs.GetSection();
+bool lldb_private::operator!=(const Address &a, const Address &rhs) {
+ return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection();
}
-AddressClass
-Address::GetAddressClass () const
-{
- ModuleSP module_sp (GetModule());
- if (module_sp)
- {
- ObjectFile *obj_file = module_sp->GetObjectFile();
- if (obj_file)
- {
- // Give the symbol vendor a chance to add to the unified section list.
- module_sp->GetSymbolVendor();
- return obj_file->GetAddressClass (GetFileAddress());
- }
+AddressClass Address::GetAddressClass() const {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ ObjectFile *obj_file = module_sp->GetObjectFile();
+ if (obj_file) {
+ // Give the symbol vendor a chance to add to the unified section list.
+ module_sp->GetSymbolVendor();
+ return obj_file->GetAddressClass(GetFileAddress());
}
- return eAddressClassUnknown;
+ }
+ return eAddressClassUnknown;
}
-bool
-Address::SetLoadAddress (lldb::addr_t load_addr, Target *target)
-{
- if (target && target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this))
- return true;
- m_section_wp.reset();
- m_offset = load_addr;
- return false;
+bool Address::SetLoadAddress(lldb::addr_t load_addr, Target *target) {
+ if (target &&
+ target->GetSectionLoadList().ResolveLoadAddress(load_addr, *this))
+ return true;
+ m_section_wp.reset();
+ m_offset = load_addr;
+ return false;
}
diff --git a/source/Core/AddressRange.cpp b/source/Core/AddressRange.cpp
index 072c2450836c..e03d721b566d 100644
--- a/source/Core/AddressRange.cpp
+++ b/source/Core/AddressRange.cpp
@@ -16,194 +16,165 @@
using namespace lldb;
using namespace lldb_private;
-AddressRange::AddressRange () :
- m_base_addr(),
- m_byte_size(0)
-{
-}
+AddressRange::AddressRange() : m_base_addr(), m_byte_size(0) {}
-AddressRange::AddressRange (addr_t file_addr, addr_t byte_size, const SectionList *section_list) :
- m_base_addr(file_addr, section_list),
- m_byte_size(byte_size)
-{
-}
+AddressRange::AddressRange(addr_t file_addr, addr_t byte_size,
+ const SectionList *section_list)
+ : m_base_addr(file_addr, section_list), m_byte_size(byte_size) {}
-AddressRange::AddressRange (const lldb::SectionSP &section, addr_t offset, addr_t byte_size) :
- m_base_addr(section, offset),
- m_byte_size(byte_size)
-{
-}
+AddressRange::AddressRange(const lldb::SectionSP &section, addr_t offset,
+ addr_t byte_size)
+ : m_base_addr(section, offset), m_byte_size(byte_size) {}
-AddressRange::AddressRange (const Address& so_addr, addr_t byte_size) :
- m_base_addr(so_addr),
- m_byte_size(byte_size)
-{
-}
+AddressRange::AddressRange(const Address &so_addr, addr_t byte_size)
+ : m_base_addr(so_addr), m_byte_size(byte_size) {}
-AddressRange::~AddressRange ()
-{
-}
+AddressRange::~AddressRange() {}
-//bool
-//AddressRange::Contains (const Address &addr) const
+// bool
+// AddressRange::Contains (const Address &addr) const
//{
// const addr_t byte_size = GetByteSize();
// if (byte_size)
-// return addr.GetSection() == m_base_addr.GetSection() && (addr.GetOffset() - m_base_addr.GetOffset()) < byte_size;
+// return addr.GetSection() == m_base_addr.GetSection() &&
+// (addr.GetOffset() - m_base_addr.GetOffset()) < byte_size;
//}
//
-//bool
-//AddressRange::Contains (const Address *addr) const
+// bool
+// AddressRange::Contains (const Address *addr) const
//{
// if (addr)
// return Contains (*addr);
// return false;
//}
-bool
-AddressRange::ContainsFileAddress (const Address &addr) const
-{
- if (addr.GetSection() == m_base_addr.GetSection())
- return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize();
- addr_t file_base_addr = GetBaseAddress().GetFileAddress();
- if (file_base_addr == LLDB_INVALID_ADDRESS)
- return false;
+bool AddressRange::ContainsFileAddress(const Address &addr) const {
+ if (addr.GetSection() == m_base_addr.GetSection())
+ return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize();
+ addr_t file_base_addr = GetBaseAddress().GetFileAddress();
+ if (file_base_addr == LLDB_INVALID_ADDRESS)
+ return false;
- addr_t file_addr = addr.GetFileAddress();
- if (file_addr == LLDB_INVALID_ADDRESS)
- return false;
+ addr_t file_addr = addr.GetFileAddress();
+ if (file_addr == LLDB_INVALID_ADDRESS)
+ return false;
- if (file_base_addr <= file_addr)
- return (file_addr - file_base_addr) < GetByteSize();
+ if (file_base_addr <= file_addr)
+ return (file_addr - file_base_addr) < GetByteSize();
- return false;
+ return false;
}
-bool
-AddressRange::ContainsFileAddress (addr_t file_addr) const
-{
- if (file_addr == LLDB_INVALID_ADDRESS)
- return false;
+bool AddressRange::ContainsFileAddress(addr_t file_addr) const {
+ if (file_addr == LLDB_INVALID_ADDRESS)
+ return false;
- addr_t file_base_addr = GetBaseAddress().GetFileAddress();
- if (file_base_addr == LLDB_INVALID_ADDRESS)
- return false;
+ addr_t file_base_addr = GetBaseAddress().GetFileAddress();
+ if (file_base_addr == LLDB_INVALID_ADDRESS)
+ return false;
- if (file_base_addr <= file_addr)
- return (file_addr - file_base_addr) < GetByteSize();
+ if (file_base_addr <= file_addr)
+ return (file_addr - file_base_addr) < GetByteSize();
- return false;
+ return false;
}
+bool AddressRange::ContainsLoadAddress(const Address &addr,
+ Target *target) const {
+ if (addr.GetSection() == m_base_addr.GetSection())
+ return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize();
+ addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);
+ if (load_base_addr == LLDB_INVALID_ADDRESS)
+ return false;
-bool
-AddressRange::ContainsLoadAddress (const Address &addr, Target *target) const
-{
- if (addr.GetSection() == m_base_addr.GetSection())
- return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize();
- addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);
- if (load_base_addr == LLDB_INVALID_ADDRESS)
- return false;
-
- addr_t load_addr = addr.GetLoadAddress(target);
- if (load_addr == LLDB_INVALID_ADDRESS)
- return false;
+ addr_t load_addr = addr.GetLoadAddress(target);
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return false;
- if (load_base_addr <= load_addr)
- return (load_addr - load_base_addr) < GetByteSize();
+ if (load_base_addr <= load_addr)
+ return (load_addr - load_base_addr) < GetByteSize();
- return false;
+ return false;
}
-bool
-AddressRange::ContainsLoadAddress (addr_t load_addr, Target *target) const
-{
- if (load_addr == LLDB_INVALID_ADDRESS)
- return false;
+bool AddressRange::ContainsLoadAddress(addr_t load_addr, Target *target) const {
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return false;
- addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);
- if (load_base_addr == LLDB_INVALID_ADDRESS)
- return false;
+ addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);
+ if (load_base_addr == LLDB_INVALID_ADDRESS)
+ return false;
- if (load_base_addr <= load_addr)
- return (load_addr - load_base_addr) < GetByteSize();
+ if (load_base_addr <= load_addr)
+ return (load_addr - load_base_addr) < GetByteSize();
- return false;
+ return false;
}
-void
-AddressRange::Clear()
-{
- m_base_addr.Clear();
- m_byte_size = 0;
+void AddressRange::Clear() {
+ m_base_addr.Clear();
+ m_byte_size = 0;
}
-bool
-AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style, Address::DumpStyle fallback_style) const
-{
- addr_t vmaddr = LLDB_INVALID_ADDRESS;
- int addr_size = sizeof (addr_t);
- if (target)
- addr_size = target->GetArchitecture().GetAddressByteSize ();
-
- bool show_module = false;
- switch (style)
- {
- default:
- break;
- case Address::DumpStyleSectionNameOffset:
- case Address::DumpStyleSectionPointerOffset:
- s->PutChar ('[');
- m_base_addr.Dump(s, target, style, fallback_style);
- s->PutChar ('-');
- s->Address (m_base_addr.GetOffset() + GetByteSize(), addr_size);
- s->PutChar (')');
- return true;
- break;
-
- case Address::DumpStyleModuleWithFileAddress:
- show_module = true;
- LLVM_FALLTHROUGH;
- case Address::DumpStyleFileAddress:
- vmaddr = m_base_addr.GetFileAddress();
- break;
-
- case Address::DumpStyleLoadAddress:
- vmaddr = m_base_addr.GetLoadAddress(target);
- break;
+bool AddressRange::Dump(Stream *s, Target *target, Address::DumpStyle style,
+ Address::DumpStyle fallback_style) const {
+ addr_t vmaddr = LLDB_INVALID_ADDRESS;
+ int addr_size = sizeof(addr_t);
+ if (target)
+ addr_size = target->GetArchitecture().GetAddressByteSize();
+
+ bool show_module = false;
+ switch (style) {
+ default:
+ break;
+ case Address::DumpStyleSectionNameOffset:
+ case Address::DumpStyleSectionPointerOffset:
+ s->PutChar('[');
+ m_base_addr.Dump(s, target, style, fallback_style);
+ s->PutChar('-');
+ s->Address(m_base_addr.GetOffset() + GetByteSize(), addr_size);
+ s->PutChar(')');
+ return true;
+ break;
+
+ case Address::DumpStyleModuleWithFileAddress:
+ show_module = true;
+ LLVM_FALLTHROUGH;
+ case Address::DumpStyleFileAddress:
+ vmaddr = m_base_addr.GetFileAddress();
+ break;
+
+ case Address::DumpStyleLoadAddress:
+ vmaddr = m_base_addr.GetLoadAddress(target);
+ break;
+ }
+
+ if (vmaddr != LLDB_INVALID_ADDRESS) {
+ if (show_module) {
+ ModuleSP module_sp(GetBaseAddress().GetModule());
+ if (module_sp)
+ s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString(
+ "<Unknown>"));
}
+ s->AddressRange(vmaddr, vmaddr + GetByteSize(), addr_size);
+ return true;
+ } else if (fallback_style != Address::DumpStyleInvalid) {
+ return Dump(s, target, fallback_style, Address::DumpStyleInvalid);
+ }
- if (vmaddr != LLDB_INVALID_ADDRESS)
- {
- if (show_module)
- {
- ModuleSP module_sp (GetBaseAddress().GetModule());
- if (module_sp)
- s->Printf("%s", module_sp->GetFileSpec().GetFilename().AsCString("<Unknown>"));
- }
- s->AddressRange(vmaddr, vmaddr + GetByteSize(), addr_size);
- return true;
- }
- else if (fallback_style != Address::DumpStyleInvalid)
- {
- return Dump(s, target, fallback_style, Address::DumpStyleInvalid);
- }
-
- return false;
+ return false;
}
-
-void
-AddressRange::DumpDebug (Stream *s) const
-{
- s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64 ", byte_size = 0x%16.16" PRIx64 "\n",
- static_cast<const void*>(this),
- static_cast<void*>(m_base_addr.GetSection().get()),
- m_base_addr.GetOffset(), GetByteSize());
+void AddressRange::DumpDebug(Stream *s) const {
+ s->Printf("%p: AddressRange section = %p, offset = 0x%16.16" PRIx64
+ ", byte_size = 0x%16.16" PRIx64 "\n",
+ static_cast<const void *>(this),
+ static_cast<void *>(m_base_addr.GetSection().get()),
+ m_base_addr.GetOffset(), GetByteSize());
}
//
-//bool
-//lldb::operator== (const AddressRange& lhs, const AddressRange& rhs)
+// bool
+// lldb::operator== (const AddressRange& lhs, const AddressRange& rhs)
//{
// if (lhs.GetBaseAddress() == rhs.GetBaseAddress())
// return lhs.GetByteSize() == rhs.GetByteSize();
diff --git a/source/Core/AddressResolver.cpp b/source/Core/AddressResolver.cpp
index aa457015b4fd..40f4d55340ec 100644
--- a/source/Core/AddressResolver.cpp
+++ b/source/Core/AddressResolver.cpp
@@ -9,7 +9,6 @@
#include "lldb/Core/AddressResolver.h"
-
// Project includes
#include "lldb/Core/Address.h"
@@ -26,41 +25,27 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// AddressResolver:
//----------------------------------------------------------------------
-AddressResolver::AddressResolver ()
-{
-}
+AddressResolver::AddressResolver() {}
-AddressResolver::~AddressResolver ()
-{
-
-}
+AddressResolver::~AddressResolver() {}
-void
-AddressResolver::ResolveAddressInModules (SearchFilter &filter, ModuleList &modules)
-{
- filter.SearchInModuleList(*this, modules);
+void AddressResolver::ResolveAddressInModules(SearchFilter &filter,
+ ModuleList &modules) {
+ filter.SearchInModuleList(*this, modules);
}
-void
-AddressResolver::ResolveAddress (SearchFilter &filter)
-{
- filter.Search (*this);
+void AddressResolver::ResolveAddress(SearchFilter &filter) {
+ filter.Search(*this);
}
-std::vector<AddressRange> &
-AddressResolver::GetAddressRanges ()
-{
- return m_address_ranges;
+std::vector<AddressRange> &AddressResolver::GetAddressRanges() {
+ return m_address_ranges;
}
-size_t
-AddressResolver::GetNumberOfAddresses ()
-{
- return m_address_ranges.size();
+size_t AddressResolver::GetNumberOfAddresses() {
+ return m_address_ranges.size();
}
-AddressRange &
-AddressResolver::GetAddressRangeAtIndex (size_t idx)
-{
+AddressRange &AddressResolver::GetAddressRangeAtIndex(size_t idx) {
return m_address_ranges[idx];
}
diff --git a/source/Core/AddressResolverFileLine.cpp b/source/Core/AddressResolverFileLine.cpp
index e45076e9bfc6..939cf45f3e88 100644
--- a/source/Core/AddressResolverFileLine.cpp
+++ b/source/Core/AddressResolverFileLine.cpp
@@ -21,81 +21,58 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// AddressResolverFileLine:
//----------------------------------------------------------------------
-AddressResolverFileLine::AddressResolverFileLine
-(
- const FileSpec &file_spec,
- uint32_t line_no,
- bool check_inlines
-) :
- AddressResolver (),
- m_file_spec (file_spec),
- m_line_number (line_no),
- m_inlines (check_inlines)
-{
-}
+AddressResolverFileLine::AddressResolverFileLine(const FileSpec &file_spec,
+ uint32_t line_no,
+ bool check_inlines)
+ : AddressResolver(), m_file_spec(file_spec), m_line_number(line_no),
+ m_inlines(check_inlines) {}
-AddressResolverFileLine::~AddressResolverFileLine ()
-{
-}
+AddressResolverFileLine::~AddressResolverFileLine() {}
Searcher::CallbackReturn
-AddressResolverFileLine::SearchCallback
-(
- SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing
-)
-{
- SymbolContextList sc_list;
- uint32_t sc_list_size;
- CompileUnit *cu = context.comp_unit;
+AddressResolverFileLine::SearchCallback(SearchFilter &filter,
+ SymbolContext &context, Address *addr,
+ bool containing) {
+ SymbolContextList sc_list;
+ uint32_t sc_list_size;
+ CompileUnit *cu = context.comp_unit;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
- sc_list_size = cu->ResolveSymbolContext (m_file_spec, m_line_number, m_inlines, false, eSymbolContextEverything,
- sc_list);
- for (uint32_t i = 0; i < sc_list_size; i++)
- {
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(i, sc))
- {
- Address line_start = sc.line_entry.range.GetBaseAddress();
- addr_t byte_size = sc.line_entry.range.GetByteSize();
- if (line_start.IsValid())
- {
- AddressRange new_range (line_start, byte_size);
- m_address_ranges.push_back (new_range);
- if (log)
- {
- StreamString s;
- //new_bp_loc->GetDescription (&s, lldb::eDescriptionLevelVerbose);
- //log->Printf ("Added address: %s\n", s.GetData());
- }
- }
- else
- {
- if (log)
- log->Printf ("error: Unable to resolve address at file address 0x%" PRIx64 " for %s:%d\n",
- line_start.GetFileAddress(),
- m_file_spec.GetFilename().AsCString("<Unknown>"),
- m_line_number);
- }
+ sc_list_size =
+ cu->ResolveSymbolContext(m_file_spec, m_line_number, m_inlines, false,
+ eSymbolContextEverything, sc_list);
+ for (uint32_t i = 0; i < sc_list_size; i++) {
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(i, sc)) {
+ Address line_start = sc.line_entry.range.GetBaseAddress();
+ addr_t byte_size = sc.line_entry.range.GetByteSize();
+ if (line_start.IsValid()) {
+ AddressRange new_range(line_start, byte_size);
+ m_address_ranges.push_back(new_range);
+ if (log) {
+ StreamString s;
+ // new_bp_loc->GetDescription (&s, lldb::eDescriptionLevelVerbose);
+ // log->Printf ("Added address: %s\n", s.GetData());
}
+ } else {
+ if (log)
+ log->Printf(
+ "error: Unable to resolve address at file address 0x%" PRIx64
+ " for %s:%d\n",
+ line_start.GetFileAddress(),
+ m_file_spec.GetFilename().AsCString("<Unknown>"), m_line_number);
+ }
}
- return Searcher::eCallbackReturnContinue;
+ }
+ return Searcher::eCallbackReturnContinue;
}
-Searcher::Depth
-AddressResolverFileLine::GetDepth()
-{
- return Searcher::eDepthCompUnit;
+Searcher::Depth AddressResolverFileLine::GetDepth() {
+ return Searcher::eDepthCompUnit;
}
-void
-AddressResolverFileLine::GetDescription (Stream *s)
-{
- s->Printf ("File and line address - file: \"%s\" line: %u", m_file_spec.GetFilename().AsCString("<Unknown>"), m_line_number);
+void AddressResolverFileLine::GetDescription(Stream *s) {
+ s->Printf("File and line address - file: \"%s\" line: %u",
+ m_file_spec.GetFilename().AsCString("<Unknown>"), m_line_number);
}
-
-
diff --git a/source/Core/AddressResolverName.cpp b/source/Core/AddressResolverName.cpp
index dacc7d777f85..d9b6dad5e4e3 100644
--- a/source/Core/AddressResolverName.cpp
+++ b/source/Core/AddressResolverName.cpp
@@ -17,223 +17,176 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
using namespace lldb;
using namespace lldb_private;
AddressResolverName::AddressResolverName(const char *func_name,
- AddressResolver::MatchType type) :
- AddressResolver(),
- m_func_name(func_name),
- m_class_name(nullptr),
- m_regex(),
- m_match_type(type)
-{
- if (m_match_type == AddressResolver::Regexp)
- {
- if (!m_regex.Compile (m_func_name.AsCString()))
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-
- if (log)
- log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString());
- }
+ AddressResolver::MatchType type)
+ : AddressResolver(), m_func_name(func_name), m_class_name(nullptr),
+ m_regex(), m_match_type(type) {
+ if (m_match_type == AddressResolver::Regexp) {
+ if (!m_regex.Compile(m_func_name.GetStringRef())) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ if (log)
+ log->Warning("function name regexp: \"%s\" did not compile.",
+ m_func_name.AsCString());
}
+ }
}
-AddressResolverName::AddressResolverName(RegularExpression &func_regex) :
- AddressResolver(),
- m_func_name(nullptr),
- m_class_name(nullptr),
- m_regex(func_regex),
- m_match_type(AddressResolver::Regexp)
-{
-}
+AddressResolverName::AddressResolverName(RegularExpression &func_regex)
+ : AddressResolver(), m_func_name(nullptr), m_class_name(nullptr),
+ m_regex(func_regex), m_match_type(AddressResolver::Regexp) {}
AddressResolverName::AddressResolverName(const char *class_name,
const char *method,
- AddressResolver::MatchType type) :
- AddressResolver (),
- m_func_name (method),
- m_class_name (class_name),
- m_regex (),
- m_match_type (type)
-{
-}
+ AddressResolver::MatchType type)
+ : AddressResolver(), m_func_name(method), m_class_name(class_name),
+ m_regex(), m_match_type(type) {}
AddressResolverName::~AddressResolverName() = default;
-// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
-// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
-// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
+// FIXME: Right now we look at the module level, and call the module's
+// "FindFunctions".
+// Greg says he will add function tables, maybe at the CompileUnit level to
+// accelerate function
+// lookup. At that point, we should switch the depth to CompileUnit, and look
+// in these tables.
Searcher::CallbackReturn
AddressResolverName::SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing)
-{
- SymbolContextList func_list;
- SymbolContextList sym_list;
-
- bool skip_prologue = true;
- uint32_t i;
- SymbolContext sc;
- Address func_addr;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-
- if (m_class_name)
- {
- if (log)
- log->Warning ("Class/method function specification not supported yet.\n");
- return Searcher::eCallbackReturnStop;
+ SymbolContext &context, Address *addr,
+ bool containing) {
+ SymbolContextList func_list;
+ SymbolContextList sym_list;
+
+ bool skip_prologue = true;
+ uint32_t i;
+ SymbolContext sc;
+ Address func_addr;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ if (m_class_name) {
+ if (log)
+ log->Warning("Class/method function specification not supported yet.\n");
+ return Searcher::eCallbackReturnStop;
+ }
+
+ const bool include_symbols = false;
+ const bool include_inlines = true;
+ const bool append = false;
+ switch (m_match_type) {
+ case AddressResolver::Exact:
+ if (context.module_sp) {
+ context.module_sp->FindSymbolsWithNameAndType(m_func_name,
+ eSymbolTypeCode, sym_list);
+ context.module_sp->FindFunctions(m_func_name, nullptr,
+ eFunctionNameTypeAuto, include_symbols,
+ include_inlines, append, func_list);
}
-
- const bool include_symbols = false;
- const bool include_inlines = true;
- const bool append = false;
- switch (m_match_type)
- {
- case AddressResolver::Exact:
- if (context.module_sp)
- {
- context.module_sp->FindSymbolsWithNameAndType (m_func_name,
- eSymbolTypeCode,
- sym_list);
- context.module_sp->FindFunctions(m_func_name,
- nullptr,
- eFunctionNameTypeAuto,
- include_symbols,
- include_inlines,
- append,
- func_list);
- }
- break;
-
- case AddressResolver::Regexp:
- if (context.module_sp)
- {
- context.module_sp->FindSymbolsMatchingRegExAndType (m_regex,
- eSymbolTypeCode,
- sym_list);
- context.module_sp->FindFunctions (m_regex,
- include_symbols,
- include_inlines,
- append,
- func_list);
+ break;
+
+ case AddressResolver::Regexp:
+ if (context.module_sp) {
+ context.module_sp->FindSymbolsMatchingRegExAndType(
+ m_regex, eSymbolTypeCode, sym_list);
+ context.module_sp->FindFunctions(m_regex, include_symbols,
+ include_inlines, append, func_list);
+ }
+ break;
+
+ case AddressResolver::Glob:
+ if (log)
+ log->Warning("glob is not supported yet.");
+ break;
+ }
+
+ // Remove any duplicates between the function list and the symbol list
+ if (func_list.GetSize()) {
+ for (i = 0; i < func_list.GetSize(); i++) {
+ if (!func_list.GetContextAtIndex(i, sc))
+ continue;
+
+ if (sc.function == nullptr)
+ continue;
+ uint32_t j = 0;
+ while (j < sym_list.GetSize()) {
+ SymbolContext symbol_sc;
+ if (sym_list.GetContextAtIndex(j, symbol_sc)) {
+ if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) {
+ if (sc.function->GetAddressRange().GetBaseAddress() ==
+ symbol_sc.symbol->GetAddressRef()) {
+ sym_list.RemoveContextAtIndex(j);
+ continue; // Don't increment j
+ }
+ }
}
- break;
- case AddressResolver::Glob:
- if (log)
- log->Warning ("glob is not supported yet.");
- break;
+ j++;
+ }
}
- // Remove any duplicates between the function list and the symbol list
- if (func_list.GetSize())
- {
- for (i = 0; i < func_list.GetSize(); i++)
- {
- if (!func_list.GetContextAtIndex(i, sc))
- continue;
-
- if (sc.function == nullptr)
- continue;
- uint32_t j = 0;
- while (j < sym_list.GetSize())
- {
- SymbolContext symbol_sc;
- if (sym_list.GetContextAtIndex(j, symbol_sc))
- {
- if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress())
- {
- if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef())
- {
- sym_list.RemoveContextAtIndex(j);
- continue; // Don't increment j
- }
- }
- }
-
- j++;
+ for (i = 0; i < func_list.GetSize(); i++) {
+ if (func_list.GetContextAtIndex(i, sc)) {
+ if (sc.function) {
+ func_addr = sc.function->GetAddressRange().GetBaseAddress();
+ addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
+ if (skip_prologue) {
+ const uint32_t prologue_byte_size =
+ sc.function->GetPrologueByteSize();
+ if (prologue_byte_size) {
+ func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size);
+ byte_size -= prologue_byte_size;
}
- }
+ }
- for (i = 0; i < func_list.GetSize(); i++)
- {
- if (func_list.GetContextAtIndex(i, sc))
- {
- if (sc.function)
- {
- func_addr = sc.function->GetAddressRange().GetBaseAddress();
- addr_t byte_size = sc.function->GetAddressRange().GetByteSize();
- if (skip_prologue)
- {
- const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
- if (prologue_byte_size)
- {
- func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
- byte_size -= prologue_byte_size;
- }
- }
-
- if (filter.AddressPasses (func_addr))
- {
- AddressRange new_range (func_addr, byte_size);
- m_address_ranges.push_back (new_range);
- }
- }
- }
+ if (filter.AddressPasses(func_addr)) {
+ AddressRange new_range(func_addr, byte_size);
+ m_address_ranges.push_back(new_range);
+ }
}
+ }
}
+ }
+
+ for (i = 0; i < sym_list.GetSize(); i++) {
+ if (sym_list.GetContextAtIndex(i, sc)) {
+ if (sc.symbol && sc.symbol->ValueIsAddress()) {
+ func_addr = sc.symbol->GetAddressRef();
+ addr_t byte_size = sc.symbol->GetByteSize();
+
+ if (skip_prologue) {
+ const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
+ if (prologue_byte_size) {
+ func_addr.SetOffset(func_addr.GetOffset() + prologue_byte_size);
+ byte_size -= prologue_byte_size;
+ }
+ }
- for (i = 0; i < sym_list.GetSize(); i++)
- {
- if (sym_list.GetContextAtIndex(i, sc))
- {
- if (sc.symbol && sc.symbol->ValueIsAddress())
- {
- func_addr = sc.symbol->GetAddressRef();
- addr_t byte_size = sc.symbol->GetByteSize();
-
- if (skip_prologue)
- {
- const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
- if (prologue_byte_size)
- {
- func_addr.SetOffset (func_addr.GetOffset() + prologue_byte_size);
- byte_size -= prologue_byte_size;
- }
- }
-
- if (filter.AddressPasses (func_addr))
- {
- AddressRange new_range (func_addr, byte_size);
- m_address_ranges.push_back (new_range);
- }
- }
+ if (filter.AddressPasses(func_addr)) {
+ AddressRange new_range(func_addr, byte_size);
+ m_address_ranges.push_back(new_range);
}
+ }
}
- return Searcher::eCallbackReturnContinue;
+ }
+ return Searcher::eCallbackReturnContinue;
}
-Searcher::Depth
-AddressResolverName::GetDepth()
-{
- return Searcher::eDepthModule;
+Searcher::Depth AddressResolverName::GetDepth() {
+ return Searcher::eDepthModule;
}
-void
-AddressResolverName::GetDescription (Stream *s)
-{
- s->PutCString("Address by function name: ");
+void AddressResolverName::GetDescription(Stream *s) {
+ s->PutCString("Address by function name: ");
- if (m_match_type == AddressResolver::Regexp)
- s->Printf("'%s' (regular expression)", m_regex.GetText());
- else
- s->Printf("'%s'", m_func_name.AsCString());
+ if (m_match_type == AddressResolver::Regexp)
+ s->Printf("'%s' (regular expression)", m_regex.GetText().str().c_str());
+ else
+ s->Printf("'%s'", m_func_name.AsCString());
}
diff --git a/source/Core/ArchSpec.cpp b/source/Core/ArchSpec.cpp
index efdbf11d93e3..cf7afb83dabd 100644
--- a/source/Core/ArchSpec.cpp
+++ b/source/Core/ArchSpec.cpp
@@ -11,8 +11,8 @@
// C Includes
// C++ Includes
-#include <cstdio>
#include <cerrno>
+#include <cstdio>
#include <string>
// Other libraries and framework includes
@@ -22,6 +22,8 @@
#include "llvm/Support/Host.h"
// Project includes
+#include "Plugins/Process/Utility/ARMDefines.h"
+#include "Plugins/Process/Utility/InstructionUtils.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/StringList.h"
#include "lldb/Host/Endian.h"
@@ -32,166 +34,239 @@
#include "lldb/Target/Thread.h"
#include "lldb/Utility/NameMatches.h"
#include "lldb/Utility/SafeMachO.h"
-#include "Plugins/Process/Utility/ARMDefines.h"
-#include "Plugins/Process/Utility/InstructionUtils.h"
using namespace lldb;
using namespace lldb_private;
-static bool cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match);
+static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
+ bool try_inverse, bool enforce_exact_match);
namespace lldb_private {
- struct CoreDefinition
- {
- ByteOrder default_byte_order;
- uint32_t addr_byte_size;
- uint32_t min_opcode_byte_size;
- uint32_t max_opcode_byte_size;
- llvm::Triple::ArchType machine;
- ArchSpec::Core core;
- const char * const name;
- };
+struct CoreDefinition {
+ ByteOrder default_byte_order;
+ uint32_t addr_byte_size;
+ uint32_t min_opcode_byte_size;
+ uint32_t max_opcode_byte_size;
+ llvm::Triple::ArchType machine;
+ ArchSpec::Core core;
+ const char *const name;
+};
} // namespace lldb_private
// This core information can be looked using the ArchSpec::Core as the index
-static const CoreDefinition g_core_definitions[] =
-{
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_generic , "arm" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4 , "armv4" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv4t , "armv4t" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5 , "armv5" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5e , "armv5e" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv5t , "armv5t" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6 , "armv6" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv6m , "armv6m" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7 , "armv7" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7f , "armv7f" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7s , "armv7s" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7k , "armv7k" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7m , "armv7m" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_armv7em , "armv7em" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::arm , ArchSpec::eCore_arm_xscale , "xscale" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumb , "thumb" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv4t , "thumbv4t" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv5 , "thumbv5" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv5e , "thumbv5e" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv6 , "thumbv6" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv6m , "thumbv6m" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7 , "thumbv7" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7f , "thumbv7f" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7s , "thumbv7s" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7k , "thumbv7k" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7m , "thumbv7m" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb , ArchSpec::eCore_thumbv7em , "thumbv7em" },
- { eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_arm64 , "arm64" },
- { eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_armv8 , "armv8" },
- { eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64, ArchSpec::eCore_arm_aarch64 , "aarch64" },
+static const CoreDefinition g_core_definitions[] = {
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_generic,
+ "arm"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv4,
+ "armv4"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv4t,
+ "armv4t"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv5,
+ "armv5"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv5e,
+ "armv5e"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv5t,
+ "armv5t"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv6,
+ "armv6"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv6m,
+ "armv6m"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv7,
+ "armv7"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv7f,
+ "armv7f"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv7s,
+ "armv7s"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv7k,
+ "armv7k"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv7m,
+ "armv7m"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_armv7em,
+ "armv7em"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::arm, ArchSpec::eCore_arm_xscale,
+ "xscale"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumb,
+ "thumb"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv4t,
+ "thumbv4t"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv5,
+ "thumbv5"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv5e,
+ "thumbv5e"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv6,
+ "thumbv6"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv6m,
+ "thumbv6m"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv7,
+ "thumbv7"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv7f,
+ "thumbv7f"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv7s,
+ "thumbv7s"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv7k,
+ "thumbv7k"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv7m,
+ "thumbv7m"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::thumb, ArchSpec::eCore_thumbv7em,
+ "thumbv7em"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
+ ArchSpec::eCore_arm_arm64, "arm64"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
+ ArchSpec::eCore_arm_armv8, "armv8"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::aarch64,
+ ArchSpec::eCore_arm_aarch64, "aarch64"},
// mips32, mips32r2, mips32r3, mips32r5, mips32r6
- { eByteOrderBig , 4, 2, 4, llvm::Triple::mips , ArchSpec::eCore_mips32 , "mips" },
- { eByteOrderBig , 4, 2, 4, llvm::Triple::mips , ArchSpec::eCore_mips32r2 , "mipsr2" },
- { eByteOrderBig , 4, 2, 4, llvm::Triple::mips , ArchSpec::eCore_mips32r3 , "mipsr3" },
- { eByteOrderBig , 4, 2, 4, llvm::Triple::mips , ArchSpec::eCore_mips32r5 , "mipsr5" },
- { eByteOrderBig , 4, 2, 4, llvm::Triple::mips , ArchSpec::eCore_mips32r6 , "mipsr6" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32el , "mipsel" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r2el , "mipsr2el" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r3el , "mipsr3el" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r5el , "mipsr5el" },
- { eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32r6el , "mipsr6el" },
-
- // mips64, mips64r2, mips64r3, mips64r5, mips64r6
- { eByteOrderBig , 8, 2, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64 , "mips64" },
- { eByteOrderBig , 8, 2, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64r2 , "mips64r2" },
- { eByteOrderBig , 8, 2, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64r3 , "mips64r3" },
- { eByteOrderBig , 8, 2, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64r5 , "mips64r5" },
- { eByteOrderBig , 8, 2, 4, llvm::Triple::mips64 , ArchSpec::eCore_mips64r6 , "mips64r6" },
- { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64el , "mips64el" },
- { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r2el , "mips64r2el" },
- { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r3el , "mips64r3el" },
- { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r5el , "mips64r5el" },
- { eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r6el , "mips64r6el" },
-
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_generic , "powerpc" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc601 , "ppc601" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc602 , "ppc602" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603 , "ppc603" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603e , "ppc603e" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc603ev , "ppc603ev" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604 , "ppc604" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc604e , "ppc604e" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc620 , "ppc620" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc750 , "ppc750" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7400 , "ppc7400" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc7450 , "ppc7450" },
- { eByteOrderBig , 4, 4, 4, llvm::Triple::ppc , ArchSpec::eCore_ppc_ppc970 , "ppc970" },
-
- { eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_generic , "powerpc64" },
- { eByteOrderBig , 8, 4, 4, llvm::Triple::ppc64 , ArchSpec::eCore_ppc64_ppc970_64 , "ppc970-64" },
-
- { eByteOrderBig , 8, 2, 6, llvm::Triple::systemz, ArchSpec::eCore_s390x_generic , "s390x" },
-
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },
- { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" },
-
- { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" },
- { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" },
- { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" },
- { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i686 , "i686" },
-
- { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" },
- { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64h , "x86_64h" },
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon , ArchSpec::eCore_hexagon_generic, "hexagon" },
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon , ArchSpec::eCore_hexagon_hexagonv4, "hexagonv4" },
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon , ArchSpec::eCore_hexagon_hexagonv5, "hexagonv5" },
-
- { eByteOrderLittle, 4, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach32 , "unknown-mach-32" },
- { eByteOrderLittle, 8, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach64 , "unknown-mach-64" },
-
- { eByteOrderBig , 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba3 , "kalimba3" },
- { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba4 , "kalimba4" },
- { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba5 , "kalimba5" }
-};
+ {eByteOrderBig, 4, 2, 4, llvm::Triple::mips, ArchSpec::eCore_mips32,
+ "mips"},
+ {eByteOrderBig, 4, 2, 4, llvm::Triple::mips, ArchSpec::eCore_mips32r2,
+ "mipsr2"},
+ {eByteOrderBig, 4, 2, 4, llvm::Triple::mips, ArchSpec::eCore_mips32r3,
+ "mipsr3"},
+ {eByteOrderBig, 4, 2, 4, llvm::Triple::mips, ArchSpec::eCore_mips32r5,
+ "mipsr5"},
+ {eByteOrderBig, 4, 2, 4, llvm::Triple::mips, ArchSpec::eCore_mips32r6,
+ "mipsr6"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel, ArchSpec::eCore_mips32el,
+ "mipsel"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel,
+ ArchSpec::eCore_mips32r2el, "mipsr2el"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel,
+ ArchSpec::eCore_mips32r3el, "mipsr3el"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel,
+ ArchSpec::eCore_mips32r5el, "mipsr5el"},
+ {eByteOrderLittle, 4, 2, 4, llvm::Triple::mipsel,
+ ArchSpec::eCore_mips32r6el, "mipsr6el"},
-// Ensure that we have an entry in the g_core_definitions for each core. If you comment out an entry above,
+ // mips64, mips64r2, mips64r3, mips64r5, mips64r6
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64,
+ "mips64"},
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64r2,
+ "mips64r2"},
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64r3,
+ "mips64r3"},
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64r5,
+ "mips64r5"},
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64r6,
+ "mips64r6"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64el, "mips64el"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64r2el, "mips64r2el"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64r3el, "mips64r3el"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64r5el, "mips64r5el"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64r6el, "mips64r6el"},
+
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_generic,
+ "powerpc"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc601,
+ "ppc601"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc602,
+ "ppc602"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc603,
+ "ppc603"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc603e,
+ "ppc603e"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc603ev,
+ "ppc603ev"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc604,
+ "ppc604"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc604e,
+ "ppc604e"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc620,
+ "ppc620"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc750,
+ "ppc750"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc7400,
+ "ppc7400"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc7450,
+ "ppc7450"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc970,
+ "ppc970"},
+
+ {eByteOrderBig, 8, 4, 4, llvm::Triple::ppc64, ArchSpec::eCore_ppc64_generic,
+ "powerpc64"},
+ {eByteOrderBig, 8, 4, 4, llvm::Triple::ppc64,
+ ArchSpec::eCore_ppc64_ppc970_64, "ppc970-64"},
+
+ {eByteOrderBig, 8, 2, 6, llvm::Triple::systemz,
+ ArchSpec::eCore_s390x_generic, "s390x"},
+
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc,
+ ArchSpec::eCore_sparc_generic, "sparc"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9,
+ ArchSpec::eCore_sparc9_generic, "sparcv9"},
+
+ {eByteOrderLittle, 4, 1, 15, llvm::Triple::x86, ArchSpec::eCore_x86_32_i386,
+ "i386"},
+ {eByteOrderLittle, 4, 1, 15, llvm::Triple::x86, ArchSpec::eCore_x86_32_i486,
+ "i486"},
+ {eByteOrderLittle, 4, 1, 15, llvm::Triple::x86,
+ ArchSpec::eCore_x86_32_i486sx, "i486sx"},
+ {eByteOrderLittle, 4, 1, 15, llvm::Triple::x86, ArchSpec::eCore_x86_32_i686,
+ "i686"},
+
+ {eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64,
+ ArchSpec::eCore_x86_64_x86_64, "x86_64"},
+ {eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64,
+ ArchSpec::eCore_x86_64_x86_64h, "x86_64h"},
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon,
+ ArchSpec::eCore_hexagon_generic, "hexagon"},
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon,
+ ArchSpec::eCore_hexagon_hexagonv4, "hexagonv4"},
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon,
+ ArchSpec::eCore_hexagon_hexagonv5, "hexagonv5"},
+
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::UnknownArch,
+ ArchSpec::eCore_uknownMach32, "unknown-mach-32"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch,
+ ArchSpec::eCore_uknownMach64, "unknown-mach-64"},
+
+ {eByteOrderBig, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba3,
+ "kalimba3"},
+ {eByteOrderLittle, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba4,
+ "kalimba4"},
+ {eByteOrderLittle, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba5,
+ "kalimba5"}};
+
+// Ensure that we have an entry in the g_core_definitions for each core. If you
+// comment out an entry above,
// you will need to comment out the corresponding ArchSpec::Core enumeration.
-static_assert(sizeof(g_core_definitions) / sizeof(CoreDefinition) == ArchSpec::kNumCores, "make sure we have one core definition for each core");
-
-struct ArchDefinitionEntry
-{
- ArchSpec::Core core;
- uint32_t cpu;
- uint32_t sub;
- uint32_t cpu_mask;
- uint32_t sub_mask;
+static_assert(sizeof(g_core_definitions) / sizeof(CoreDefinition) ==
+ ArchSpec::kNumCores,
+ "make sure we have one core definition for each core");
+
+struct ArchDefinitionEntry {
+ ArchSpec::Core core;
+ uint32_t cpu;
+ uint32_t sub;
+ uint32_t cpu_mask;
+ uint32_t sub_mask;
};
-struct ArchDefinition
-{
- ArchitectureType type;
- size_t num_entries;
- const ArchDefinitionEntry *entries;
- const char *name;
+struct ArchDefinition {
+ ArchitectureType type;
+ size_t num_entries;
+ const ArchDefinitionEntry *entries;
+ const char *name;
};
-size_t
-ArchSpec::AutoComplete (const char *name, StringList &matches)
-{
- if (name && name[0])
- {
- for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
- {
- if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name))
- matches.AppendString (g_core_definitions[i].name);
- }
+size_t ArchSpec::AutoComplete(llvm::StringRef name, StringList &matches) {
+ if (!name.empty()) {
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
+ if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name))
+ matches.AppendString(g_core_definitions[i].name);
}
- else
- {
- for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
- matches.AppendString (g_core_definitions[i].name);
- }
- return matches.GetSize();
+ } else {
+ for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
+ matches.AppendString(g_core_definitions[i].name);
+ }
+ return matches.GetSize();
}
#define CPU_ANY (UINT32_MAX)
@@ -203,267 +278,305 @@ ArchSpec::AutoComplete (const char *name, StringList &matches)
// allows the precedence to be set when the table is built.
#define SUBTYPE_MASK 0x00FFFFFFu
-static const ArchDefinitionEntry g_macho_arch_entries[] =
-{
- { ArchSpec::eCore_arm_generic , llvm::MachO::CPU_TYPE_ARM , CPU_ANY, UINT32_MAX , UINT32_MAX },
- { ArchSpec::eCore_arm_generic , llvm::MachO::CPU_TYPE_ARM , 0 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv4 , llvm::MachO::CPU_TYPE_ARM , 5 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv4t , llvm::MachO::CPU_TYPE_ARM , 5 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv6 , llvm::MachO::CPU_TYPE_ARM , 6 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv6m , llvm::MachO::CPU_TYPE_ARM , 14 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv5 , llvm::MachO::CPU_TYPE_ARM , 7 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv5e , llvm::MachO::CPU_TYPE_ARM , 7 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv5t , llvm::MachO::CPU_TYPE_ARM , 7 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_xscale , llvm::MachO::CPU_TYPE_ARM , 8 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv7 , llvm::MachO::CPU_TYPE_ARM , 9 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv7f , llvm::MachO::CPU_TYPE_ARM , 10 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv7s , llvm::MachO::CPU_TYPE_ARM , 11 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv7k , llvm::MachO::CPU_TYPE_ARM , 12 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv7m , llvm::MachO::CPU_TYPE_ARM , 15 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_armv7em , llvm::MachO::CPU_TYPE_ARM , 16 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 1 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 0 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , 13 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_arm_arm64 , llvm::MachO::CPU_TYPE_ARM64 , CPU_ANY, UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumb , llvm::MachO::CPU_TYPE_ARM , 0 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv4t , llvm::MachO::CPU_TYPE_ARM , 5 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv5 , llvm::MachO::CPU_TYPE_ARM , 7 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv5e , llvm::MachO::CPU_TYPE_ARM , 7 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv6 , llvm::MachO::CPU_TYPE_ARM , 6 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv6m , llvm::MachO::CPU_TYPE_ARM , 14 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv7 , llvm::MachO::CPU_TYPE_ARM , 9 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv7f , llvm::MachO::CPU_TYPE_ARM , 10 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv7s , llvm::MachO::CPU_TYPE_ARM , 11 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv7k , llvm::MachO::CPU_TYPE_ARM , 12 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv7m , llvm::MachO::CPU_TYPE_ARM , 15 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_thumbv7em , llvm::MachO::CPU_TYPE_ARM , 16 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_generic , llvm::MachO::CPU_TYPE_POWERPC , CPU_ANY, UINT32_MAX , UINT32_MAX },
- { ArchSpec::eCore_ppc_generic , llvm::MachO::CPU_TYPE_POWERPC , 0 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc601 , llvm::MachO::CPU_TYPE_POWERPC , 1 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc602 , llvm::MachO::CPU_TYPE_POWERPC , 2 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc603 , llvm::MachO::CPU_TYPE_POWERPC , 3 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc603e , llvm::MachO::CPU_TYPE_POWERPC , 4 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc603ev , llvm::MachO::CPU_TYPE_POWERPC , 5 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc604 , llvm::MachO::CPU_TYPE_POWERPC , 6 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc604e , llvm::MachO::CPU_TYPE_POWERPC , 7 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc620 , llvm::MachO::CPU_TYPE_POWERPC , 8 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc750 , llvm::MachO::CPU_TYPE_POWERPC , 9 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc7400 , llvm::MachO::CPU_TYPE_POWERPC , 10 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc7450 , llvm::MachO::CPU_TYPE_POWERPC , 11 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc_ppc970 , llvm::MachO::CPU_TYPE_POWERPC , 100 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc64_generic , llvm::MachO::CPU_TYPE_POWERPC64 , 0 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_ppc64_ppc970_64 , llvm::MachO::CPU_TYPE_POWERPC64 , 100 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_x86_32_i386 , llvm::MachO::CPU_TYPE_I386 , 3 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_x86_32_i486 , llvm::MachO::CPU_TYPE_I386 , 4 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_x86_32_i486sx , llvm::MachO::CPU_TYPE_I386 , 0x84 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_x86_32_i386 , llvm::MachO::CPU_TYPE_I386 , CPU_ANY, UINT32_MAX , UINT32_MAX },
- { ArchSpec::eCore_x86_64_x86_64 , llvm::MachO::CPU_TYPE_X86_64 , 3 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_x86_64_x86_64 , llvm::MachO::CPU_TYPE_X86_64 , 4 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_x86_64_x86_64h , llvm::MachO::CPU_TYPE_X86_64 , 8 , UINT32_MAX , SUBTYPE_MASK },
- { ArchSpec::eCore_x86_64_x86_64 , llvm::MachO::CPU_TYPE_X86_64 , CPU_ANY, UINT32_MAX , UINT32_MAX },
- // Catch any unknown mach architectures so we can always use the object and symbol mach-o files
- { ArchSpec::eCore_uknownMach32 , 0 , 0 , 0xFF000000u, 0x00000000u },
- { ArchSpec::eCore_uknownMach64 , llvm::MachO::CPU_ARCH_ABI64 , 0 , 0xFF000000u, 0x00000000u }
-};
+static const ArchDefinitionEntry g_macho_arch_entries[] = {
+ {ArchSpec::eCore_arm_generic, llvm::MachO::CPU_TYPE_ARM, CPU_ANY,
+ UINT32_MAX, UINT32_MAX},
+ {ArchSpec::eCore_arm_generic, llvm::MachO::CPU_TYPE_ARM, 0, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv4, llvm::MachO::CPU_TYPE_ARM, 5, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv4t, llvm::MachO::CPU_TYPE_ARM, 5, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv6, llvm::MachO::CPU_TYPE_ARM, 6, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv6m, llvm::MachO::CPU_TYPE_ARM, 14, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv5, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv5e, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv5t, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_xscale, llvm::MachO::CPU_TYPE_ARM, 8, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7, llvm::MachO::CPU_TYPE_ARM, 9, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7f, llvm::MachO::CPU_TYPE_ARM, 10, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7s, llvm::MachO::CPU_TYPE_ARM, 11, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7k, llvm::MachO::CPU_TYPE_ARM, 12, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7m, llvm::MachO::CPU_TYPE_ARM, 15, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_armv7em, llvm::MachO::CPU_TYPE_ARM, 16, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 1, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 0, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, 13, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_arm_arm64, llvm::MachO::CPU_TYPE_ARM64, CPU_ANY,
+ UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_thumb, llvm::MachO::CPU_TYPE_ARM, 0, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv4t, llvm::MachO::CPU_TYPE_ARM, 5, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv5, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv5e, llvm::MachO::CPU_TYPE_ARM, 7, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv6, llvm::MachO::CPU_TYPE_ARM, 6, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv6m, llvm::MachO::CPU_TYPE_ARM, 14, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7, llvm::MachO::CPU_TYPE_ARM, 9, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7f, llvm::MachO::CPU_TYPE_ARM, 10, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7s, llvm::MachO::CPU_TYPE_ARM, 11, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7k, llvm::MachO::CPU_TYPE_ARM, 12, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7m, llvm::MachO::CPU_TYPE_ARM, 15, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_thumbv7em, llvm::MachO::CPU_TYPE_ARM, 16, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_generic, llvm::MachO::CPU_TYPE_POWERPC, CPU_ANY,
+ UINT32_MAX, UINT32_MAX},
+ {ArchSpec::eCore_ppc_generic, llvm::MachO::CPU_TYPE_POWERPC, 0, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc601, llvm::MachO::CPU_TYPE_POWERPC, 1, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc602, llvm::MachO::CPU_TYPE_POWERPC, 2, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc603, llvm::MachO::CPU_TYPE_POWERPC, 3, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc603e, llvm::MachO::CPU_TYPE_POWERPC, 4, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc603ev, llvm::MachO::CPU_TYPE_POWERPC, 5, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc604, llvm::MachO::CPU_TYPE_POWERPC, 6, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc604e, llvm::MachO::CPU_TYPE_POWERPC, 7, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc620, llvm::MachO::CPU_TYPE_POWERPC, 8, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc750, llvm::MachO::CPU_TYPE_POWERPC, 9, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc7400, llvm::MachO::CPU_TYPE_POWERPC, 10, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc7450, llvm::MachO::CPU_TYPE_POWERPC, 11, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc_ppc970, llvm::MachO::CPU_TYPE_POWERPC, 100, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc64_generic, llvm::MachO::CPU_TYPE_POWERPC64, 0,
+ UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_ppc64_ppc970_64, llvm::MachO::CPU_TYPE_POWERPC64, 100,
+ UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_32_i386, llvm::MachO::CPU_TYPE_I386, 3, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_32_i486, llvm::MachO::CPU_TYPE_I386, 4, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_32_i486sx, llvm::MachO::CPU_TYPE_I386, 0x84,
+ UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_32_i386, llvm::MachO::CPU_TYPE_I386, CPU_ANY,
+ UINT32_MAX, UINT32_MAX},
+ {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, 3, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, 4, UINT32_MAX,
+ SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_64_x86_64h, llvm::MachO::CPU_TYPE_X86_64, 8,
+ UINT32_MAX, SUBTYPE_MASK},
+ {ArchSpec::eCore_x86_64_x86_64, llvm::MachO::CPU_TYPE_X86_64, CPU_ANY,
+ UINT32_MAX, UINT32_MAX},
+ // Catch any unknown mach architectures so we can always use the object and
+ // symbol mach-o files
+ {ArchSpec::eCore_uknownMach32, 0, 0, 0xFF000000u, 0x00000000u},
+ {ArchSpec::eCore_uknownMach64, llvm::MachO::CPU_ARCH_ABI64, 0, 0xFF000000u,
+ 0x00000000u}};
static const ArchDefinition g_macho_arch_def = {
- eArchTypeMachO,
- llvm::array_lengthof(g_macho_arch_entries),
- g_macho_arch_entries,
- "mach-o"
-};
+ eArchTypeMachO, llvm::array_lengthof(g_macho_arch_entries),
+ g_macho_arch_entries, "mach-o"};
//===----------------------------------------------------------------------===//
// A table that gets searched linearly for matches. This table is used to
// convert cpu type and subtypes to architecture names, and to convert
// architecture names to cpu types and subtypes. The ordering is important and
// allows the precedence to be set when the table is built.
-static const ArchDefinitionEntry g_elf_arch_entries[] =
-{
- { ArchSpec::eCore_sparc_generic , llvm::ELF::EM_SPARC , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Sparc
- { ArchSpec::eCore_x86_32_i386 , llvm::ELF::EM_386 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Intel 80386
- { ArchSpec::eCore_x86_32_i486 , llvm::ELF::EM_IAMCU , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Intel MCU // FIXME: is this correct?
- { ArchSpec::eCore_ppc_generic , llvm::ELF::EM_PPC , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC
- { ArchSpec::eCore_ppc64_generic , llvm::ELF::EM_PPC64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC64
- { ArchSpec::eCore_arm_generic , llvm::ELF::EM_ARM , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM
- { ArchSpec::eCore_arm_aarch64 , llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM64
- { ArchSpec::eCore_s390x_generic , llvm::ELF::EM_S390 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SystemZ
- { ArchSpec::eCore_sparc9_generic , llvm::ELF::EM_SPARCV9, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // SPARC V9
- { ArchSpec::eCore_x86_64_x86_64 , llvm::ELF::EM_X86_64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // AMD64
- { ArchSpec::eCore_mips32 , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips32, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips32
- { ArchSpec::eCore_mips32r2 , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips32r2, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips32r2
- { ArchSpec::eCore_mips32r6 , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips32r6, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips32r6
- { ArchSpec::eCore_mips32el , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips32el, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips32el
- { ArchSpec::eCore_mips32r2el , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips32r2el, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips32r2el
- { ArchSpec::eCore_mips32r6el , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips32r6el, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips32r6el
- { ArchSpec::eCore_mips64 , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips64, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64
- { ArchSpec::eCore_mips64r2 , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips64r2, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64r2
- { ArchSpec::eCore_mips64r6 , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips64r6, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64r6
- { ArchSpec::eCore_mips64el , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips64el, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64el
- { ArchSpec::eCore_mips64r2el , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips64r2el, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64r2el
- { ArchSpec::eCore_mips64r6el , llvm::ELF::EM_MIPS , ArchSpec::eMIPSSubType_mips64r6el, 0xFFFFFFFFu, 0xFFFFFFFFu }, // mips64r6el
- { ArchSpec::eCore_hexagon_generic , llvm::ELF::EM_HEXAGON, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // HEXAGON
- { ArchSpec::eCore_kalimba3 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v3, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
- { ArchSpec::eCore_kalimba4 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v4, 0xFFFFFFFFu, 0xFFFFFFFFu }, // KALIMBA
- { ArchSpec::eCore_kalimba5 , llvm::ELF::EM_CSR_KALIMBA, llvm::Triple::KalimbaSubArch_v5, 0xFFFFFFFFu, 0xFFFFFFFFu } // KALIMBA
+static const ArchDefinitionEntry g_elf_arch_entries[] = {
+ {ArchSpec::eCore_sparc_generic, llvm::ELF::EM_SPARC, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // Sparc
+ {ArchSpec::eCore_x86_32_i386, llvm::ELF::EM_386, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel 80386
+ {ArchSpec::eCore_x86_32_i486, llvm::ELF::EM_IAMCU, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel MCU // FIXME: is this correct?
+ {ArchSpec::eCore_ppc_generic, llvm::ELF::EM_PPC, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC
+ {ArchSpec::eCore_ppc64_generic, llvm::ELF::EM_PPC64, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC64
+ {ArchSpec::eCore_arm_generic, llvm::ELF::EM_ARM, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM
+ {ArchSpec::eCore_arm_aarch64, llvm::ELF::EM_AARCH64, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM64
+ {ArchSpec::eCore_s390x_generic, llvm::ELF::EM_S390, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // SystemZ
+ {ArchSpec::eCore_sparc9_generic, llvm::ELF::EM_SPARCV9,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // SPARC V9
+ {ArchSpec::eCore_x86_64_x86_64, llvm::ELF::EM_X86_64, LLDB_INVALID_CPUTYPE,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // AMD64
+ {ArchSpec::eCore_mips32, llvm::ELF::EM_MIPS, ArchSpec::eMIPSSubType_mips32,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32
+ {ArchSpec::eCore_mips32r2, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips32r2, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r2
+ {ArchSpec::eCore_mips32r6, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips32r6, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r6
+ {ArchSpec::eCore_mips32el, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips32el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32el
+ {ArchSpec::eCore_mips32r2el, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips32r2el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r2el
+ {ArchSpec::eCore_mips32r6el, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips32r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips32r6el
+ {ArchSpec::eCore_mips64, llvm::ELF::EM_MIPS, ArchSpec::eMIPSSubType_mips64,
+ 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64
+ {ArchSpec::eCore_mips64r2, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips64r2, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r2
+ {ArchSpec::eCore_mips64r6, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips64r6, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6
+ {ArchSpec::eCore_mips64el, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips64el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64el
+ {ArchSpec::eCore_mips64r2el, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips64r2el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r2el
+ {ArchSpec::eCore_mips64r6el, llvm::ELF::EM_MIPS,
+ ArchSpec::eMIPSSubType_mips64r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6el
+ {ArchSpec::eCore_hexagon_generic, llvm::ELF::EM_HEXAGON,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON
+ {ArchSpec::eCore_kalimba3, llvm::ELF::EM_CSR_KALIMBA,
+ llvm::Triple::KalimbaSubArch_v3, 0xFFFFFFFFu, 0xFFFFFFFFu}, // KALIMBA
+ {ArchSpec::eCore_kalimba4, llvm::ELF::EM_CSR_KALIMBA,
+ llvm::Triple::KalimbaSubArch_v4, 0xFFFFFFFFu, 0xFFFFFFFFu}, // KALIMBA
+ {ArchSpec::eCore_kalimba5, llvm::ELF::EM_CSR_KALIMBA,
+ llvm::Triple::KalimbaSubArch_v5, 0xFFFFFFFFu, 0xFFFFFFFFu} // KALIMBA
};
static const ArchDefinition g_elf_arch_def = {
- eArchTypeELF,
- llvm::array_lengthof(g_elf_arch_entries),
- g_elf_arch_entries,
+ eArchTypeELF, llvm::array_lengthof(g_elf_arch_entries), g_elf_arch_entries,
"elf",
};
-static const ArchDefinitionEntry g_coff_arch_entries[] =
-{
- { ArchSpec::eCore_x86_32_i386 , llvm::COFF::IMAGE_FILE_MACHINE_I386 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // Intel 80x86
- { ArchSpec::eCore_ppc_generic , llvm::COFF::IMAGE_FILE_MACHINE_POWERPC , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC
- { ArchSpec::eCore_ppc_generic , llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // PowerPC (with FPU)
- { ArchSpec::eCore_arm_generic , llvm::COFF::IMAGE_FILE_MACHINE_ARM , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARM
- { ArchSpec::eCore_arm_armv7 , llvm::COFF::IMAGE_FILE_MACHINE_ARMNT , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARMv7
- { ArchSpec::eCore_thumb , llvm::COFF::IMAGE_FILE_MACHINE_THUMB , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu }, // ARMv7
- { ArchSpec::eCore_x86_64_x86_64, llvm::COFF::IMAGE_FILE_MACHINE_AMD64 , LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu } // AMD64
+static const ArchDefinitionEntry g_coff_arch_entries[] = {
+ {ArchSpec::eCore_x86_32_i386, llvm::COFF::IMAGE_FILE_MACHINE_I386,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // Intel 80x86
+ {ArchSpec::eCore_ppc_generic, llvm::COFF::IMAGE_FILE_MACHINE_POWERPC,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC
+ {ArchSpec::eCore_ppc_generic, llvm::COFF::IMAGE_FILE_MACHINE_POWERPCFP,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // PowerPC (with FPU)
+ {ArchSpec::eCore_arm_generic, llvm::COFF::IMAGE_FILE_MACHINE_ARM,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARM
+ {ArchSpec::eCore_arm_armv7, llvm::COFF::IMAGE_FILE_MACHINE_ARMNT,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARMv7
+ {ArchSpec::eCore_thumb, llvm::COFF::IMAGE_FILE_MACHINE_THUMB,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // ARMv7
+ {ArchSpec::eCore_x86_64_x86_64, llvm::COFF::IMAGE_FILE_MACHINE_AMD64,
+ LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu} // AMD64
};
static const ArchDefinition g_coff_arch_def = {
- eArchTypeCOFF,
- llvm::array_lengthof(g_coff_arch_entries),
- g_coff_arch_entries,
- "pe-coff",
+ eArchTypeCOFF, llvm::array_lengthof(g_coff_arch_entries),
+ g_coff_arch_entries, "pe-coff",
};
//===----------------------------------------------------------------------===//
// Table of all ArchDefinitions
static const ArchDefinition *g_arch_definitions[] = {
- &g_macho_arch_def,
- &g_elf_arch_def,
- &g_coff_arch_def
-};
+ &g_macho_arch_def, &g_elf_arch_def, &g_coff_arch_def};
-static const size_t k_num_arch_definitions = llvm::array_lengthof(g_arch_definitions);
+static const size_t k_num_arch_definitions =
+ llvm::array_lengthof(g_arch_definitions);
//===----------------------------------------------------------------------===//
// Static helper functions.
// Get the architecture definition for a given object type.
-static const ArchDefinition *
-FindArchDefinition (ArchitectureType arch_type)
-{
- for (unsigned int i = 0; i < k_num_arch_definitions; ++i)
- {
- const ArchDefinition *def = g_arch_definitions[i];
- if (def->type == arch_type)
- return def;
- }
- return nullptr;
+static const ArchDefinition *FindArchDefinition(ArchitectureType arch_type) {
+ for (unsigned int i = 0; i < k_num_arch_definitions; ++i) {
+ const ArchDefinition *def = g_arch_definitions[i];
+ if (def->type == arch_type)
+ return def;
+ }
+ return nullptr;
}
// Get an architecture definition by name.
-static const CoreDefinition *
-FindCoreDefinition (llvm::StringRef name)
-{
- for (unsigned int i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
- {
- if (name.equals_lower(g_core_definitions[i].name))
- return &g_core_definitions[i];
- }
- return nullptr;
+static const CoreDefinition *FindCoreDefinition(llvm::StringRef name) {
+ for (unsigned int i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
+ if (name.equals_lower(g_core_definitions[i].name))
+ return &g_core_definitions[i];
+ }
+ return nullptr;
}
-static inline const CoreDefinition *
-FindCoreDefinition (ArchSpec::Core core)
-{
- if (core >= 0 && core < llvm::array_lengthof(g_core_definitions))
- return &g_core_definitions[core];
- return nullptr;
+static inline const CoreDefinition *FindCoreDefinition(ArchSpec::Core core) {
+ if (core >= 0 && core < llvm::array_lengthof(g_core_definitions))
+ return &g_core_definitions[core];
+ return nullptr;
}
// Get a definition entry by cpu type and subtype.
static const ArchDefinitionEntry *
-FindArchDefinitionEntry (const ArchDefinition *def, uint32_t cpu, uint32_t sub)
-{
- if (def == nullptr)
- return nullptr;
-
- const ArchDefinitionEntry *entries = def->entries;
- for (size_t i = 0; i < def->num_entries; ++i)
- {
- if (entries[i].cpu == (cpu & entries[i].cpu_mask))
- if (entries[i].sub == (sub & entries[i].sub_mask))
- return &entries[i];
- }
+FindArchDefinitionEntry(const ArchDefinition *def, uint32_t cpu, uint32_t sub) {
+ if (def == nullptr)
return nullptr;
+
+ const ArchDefinitionEntry *entries = def->entries;
+ for (size_t i = 0; i < def->num_entries; ++i) {
+ if (entries[i].cpu == (cpu & entries[i].cpu_mask))
+ if (entries[i].sub == (sub & entries[i].sub_mask))
+ return &entries[i];
+ }
+ return nullptr;
}
static const ArchDefinitionEntry *
-FindArchDefinitionEntry (const ArchDefinition *def, ArchSpec::Core core)
-{
- if (def == nullptr)
- return nullptr;
-
- const ArchDefinitionEntry *entries = def->entries;
- for (size_t i = 0; i < def->num_entries; ++i)
- {
- if (entries[i].core == core)
- return &entries[i];
- }
+FindArchDefinitionEntry(const ArchDefinition *def, ArchSpec::Core core) {
+ if (def == nullptr)
return nullptr;
+
+ const ArchDefinitionEntry *entries = def->entries;
+ for (size_t i = 0; i < def->num_entries; ++i) {
+ if (entries[i].core == core)
+ return &entries[i];
+ }
+ return nullptr;
}
//===----------------------------------------------------------------------===//
// Constructors and destructors.
-ArchSpec::ArchSpec() :
- m_triple (),
- m_core (kCore_invalid),
- m_byte_order (eByteOrderInvalid),
- m_flags (0),
- m_distribution_id ()
-{
-}
+ArchSpec::ArchSpec() {}
-ArchSpec::ArchSpec (const char *triple_cstr, Platform *platform) :
- m_triple (),
- m_core (kCore_invalid),
- m_byte_order (eByteOrderInvalid),
- m_flags (0),
- m_distribution_id ()
-{
- if (triple_cstr)
- SetTriple(triple_cstr, platform);
+ArchSpec::ArchSpec(const char *triple_cstr, Platform *platform) {
+ if (triple_cstr)
+ SetTriple(triple_cstr, platform);
}
-
-ArchSpec::ArchSpec (const char *triple_cstr) :
- m_triple (),
- m_core (kCore_invalid),
- m_byte_order (eByteOrderInvalid),
- m_flags (0),
- m_distribution_id ()
-{
- if (triple_cstr)
- SetTriple(triple_cstr);
+ArchSpec::ArchSpec(llvm::StringRef triple_str, Platform *platform) {
+ SetTriple(triple_str, platform);
}
-ArchSpec::ArchSpec(const llvm::Triple &triple) :
- m_triple (),
- m_core (kCore_invalid),
- m_byte_order (eByteOrderInvalid),
- m_flags (0),
- m_distribution_id ()
-{
- SetTriple(triple);
+ArchSpec::ArchSpec(const char *triple_cstr) {
+ if (triple_cstr)
+ SetTriple(triple_cstr);
}
-ArchSpec::ArchSpec (ArchitectureType arch_type, uint32_t cpu, uint32_t subtype) :
- m_triple (),
- m_core (kCore_invalid),
- m_byte_order (eByteOrderInvalid),
- m_flags (0),
- m_distribution_id ()
-{
- SetArchitecture (arch_type, cpu, subtype);
+ArchSpec::ArchSpec(llvm::StringRef triple_str) { SetTriple(triple_str); }
+
+ArchSpec::ArchSpec(const llvm::Triple &triple) { SetTriple(triple); }
+
+ArchSpec::ArchSpec(ArchitectureType arch_type, uint32_t cpu, uint32_t subtype) {
+ SetArchitecture(arch_type, cpu, subtype);
}
ArchSpec::~ArchSpec() = default;
@@ -471,55 +584,43 @@ ArchSpec::~ArchSpec() = default;
//===----------------------------------------------------------------------===//
// Assignment and initialization.
-const ArchSpec&
-ArchSpec::operator= (const ArchSpec& rhs)
-{
- if (this != &rhs)
- {
- m_triple = rhs.m_triple;
- m_core = rhs.m_core;
- m_byte_order = rhs.m_byte_order;
- m_distribution_id = rhs.m_distribution_id;
- m_flags = rhs.m_flags;
- }
- return *this;
+const ArchSpec &ArchSpec::operator=(const ArchSpec &rhs) {
+ if (this != &rhs) {
+ m_triple = rhs.m_triple;
+ m_core = rhs.m_core;
+ m_byte_order = rhs.m_byte_order;
+ m_distribution_id = rhs.m_distribution_id;
+ m_flags = rhs.m_flags;
+ }
+ return *this;
}
-void
-ArchSpec::Clear()
-{
- m_triple = llvm::Triple();
- m_core = kCore_invalid;
- m_byte_order = eByteOrderInvalid;
- m_distribution_id.Clear ();
- m_flags = 0;
+void ArchSpec::Clear() {
+ m_triple = llvm::Triple();
+ m_core = kCore_invalid;
+ m_byte_order = eByteOrderInvalid;
+ m_distribution_id.Clear();
+ m_flags = 0;
}
//===----------------------------------------------------------------------===//
// Predicates.
-const char *
-ArchSpec::GetArchitectureName () const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- return core_def->name;
- return "unknown";
+const char *ArchSpec::GetArchitectureName() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->name;
+ return "unknown";
}
-bool
-ArchSpec::IsMIPS() const
-{
- const llvm::Triple::ArchType machine = GetMachine();
- if(machine == llvm::Triple::mips ||
- machine == llvm::Triple::mipsel ||
- machine == llvm::Triple::mips64 ||
- machine == llvm::Triple::mips64el)
- return true;
- return false;
+bool ArchSpec::IsMIPS() const {
+ const llvm::Triple::ArchType machine = GetMachine();
+ if (machine == llvm::Triple::mips || machine == llvm::Triple::mipsel ||
+ machine == llvm::Triple::mips64 || machine == llvm::Triple::mips64el)
+ return true;
+ return false;
}
-
std::string ArchSpec::GetTargetABI() const {
std::string abi;
@@ -560,953 +661,894 @@ std::string ArchSpec::GetClangTargetCPU() {
std::string cpu;
const llvm::Triple::ArchType machine = GetMachine();
- if (machine == llvm::Triple::mips ||
- machine == llvm::Triple::mipsel ||
- machine == llvm::Triple::mips64 ||
- machine == llvm::Triple::mips64el)
- {
- switch (m_core)
- {
- case ArchSpec::eCore_mips32:
- case ArchSpec::eCore_mips32el:
- cpu = "mips32"; break;
- case ArchSpec::eCore_mips32r2:
- case ArchSpec::eCore_mips32r2el:
- cpu = "mips32r2"; break;
- case ArchSpec::eCore_mips32r3:
- case ArchSpec::eCore_mips32r3el:
- cpu = "mips32r3"; break;
- case ArchSpec::eCore_mips32r5:
- case ArchSpec::eCore_mips32r5el:
- cpu = "mips32r5"; break;
- case ArchSpec::eCore_mips32r6:
- case ArchSpec::eCore_mips32r6el:
- cpu = "mips32r6"; break;
- case ArchSpec::eCore_mips64:
- case ArchSpec::eCore_mips64el:
- cpu = "mips64"; break;
- case ArchSpec::eCore_mips64r2:
- case ArchSpec::eCore_mips64r2el:
- cpu = "mips64r2"; break;
- case ArchSpec::eCore_mips64r3:
- case ArchSpec::eCore_mips64r3el:
- cpu = "mips64r3"; break;
- case ArchSpec::eCore_mips64r5:
- case ArchSpec::eCore_mips64r5el:
- cpu = "mips64r5"; break;
- case ArchSpec::eCore_mips64r6:
- case ArchSpec::eCore_mips64r6el:
- cpu = "mips64r6"; break;
- default:
- break;
- }
+ if (machine == llvm::Triple::mips || machine == llvm::Triple::mipsel ||
+ machine == llvm::Triple::mips64 || machine == llvm::Triple::mips64el) {
+ switch (m_core) {
+ case ArchSpec::eCore_mips32:
+ case ArchSpec::eCore_mips32el:
+ cpu = "mips32";
+ break;
+ case ArchSpec::eCore_mips32r2:
+ case ArchSpec::eCore_mips32r2el:
+ cpu = "mips32r2";
+ break;
+ case ArchSpec::eCore_mips32r3:
+ case ArchSpec::eCore_mips32r3el:
+ cpu = "mips32r3";
+ break;
+ case ArchSpec::eCore_mips32r5:
+ case ArchSpec::eCore_mips32r5el:
+ cpu = "mips32r5";
+ break;
+ case ArchSpec::eCore_mips32r6:
+ case ArchSpec::eCore_mips32r6el:
+ cpu = "mips32r6";
+ break;
+ case ArchSpec::eCore_mips64:
+ case ArchSpec::eCore_mips64el:
+ cpu = "mips64";
+ break;
+ case ArchSpec::eCore_mips64r2:
+ case ArchSpec::eCore_mips64r2el:
+ cpu = "mips64r2";
+ break;
+ case ArchSpec::eCore_mips64r3:
+ case ArchSpec::eCore_mips64r3el:
+ cpu = "mips64r3";
+ break;
+ case ArchSpec::eCore_mips64r5:
+ case ArchSpec::eCore_mips64r5el:
+ cpu = "mips64r5";
+ break;
+ case ArchSpec::eCore_mips64r6:
+ case ArchSpec::eCore_mips64r6el:
+ cpu = "mips64r6";
+ break;
+ default:
+ break;
}
- return cpu;
+ }
+ return cpu;
}
-uint32_t
-ArchSpec::GetMachOCPUType () const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- {
- const ArchDefinitionEntry *arch_def = FindArchDefinitionEntry (&g_macho_arch_def, core_def->core);
- if (arch_def)
- {
- return arch_def->cpu;
- }
+uint32_t ArchSpec::GetMachOCPUType() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def) {
+ const ArchDefinitionEntry *arch_def =
+ FindArchDefinitionEntry(&g_macho_arch_def, core_def->core);
+ if (arch_def) {
+ return arch_def->cpu;
}
- return LLDB_INVALID_CPUTYPE;
+ }
+ return LLDB_INVALID_CPUTYPE;
}
-uint32_t
-ArchSpec::GetMachOCPUSubType () const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- {
- const ArchDefinitionEntry *arch_def = FindArchDefinitionEntry (&g_macho_arch_def, core_def->core);
- if (arch_def)
- {
- return arch_def->sub;
- }
+uint32_t ArchSpec::GetMachOCPUSubType() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def) {
+ const ArchDefinitionEntry *arch_def =
+ FindArchDefinitionEntry(&g_macho_arch_def, core_def->core);
+ if (arch_def) {
+ return arch_def->sub;
}
- return LLDB_INVALID_CPUTYPE;
+ }
+ return LLDB_INVALID_CPUTYPE;
}
-uint32_t
-ArchSpec::GetDataByteSize () const
-{
- switch (m_core)
- {
- case eCore_kalimba3:
- return 4;
- case eCore_kalimba4:
- return 1;
- case eCore_kalimba5:
- return 4;
- default:
- return 1;
- }
+uint32_t ArchSpec::GetDataByteSize() const {
+ switch (m_core) {
+ case eCore_kalimba3:
+ return 4;
+ case eCore_kalimba4:
+ return 1;
+ case eCore_kalimba5:
+ return 4;
+ default:
return 1;
+ }
+ return 1;
}
-uint32_t
-ArchSpec::GetCodeByteSize () const
-{
- switch (m_core)
- {
- case eCore_kalimba3:
- return 4;
- case eCore_kalimba4:
- return 1;
- case eCore_kalimba5:
- return 1;
- default:
- return 1;
- }
+uint32_t ArchSpec::GetCodeByteSize() const {
+ switch (m_core) {
+ case eCore_kalimba3:
+ return 4;
+ case eCore_kalimba4:
return 1;
+ case eCore_kalimba5:
+ return 1;
+ default:
+ return 1;
+ }
+ return 1;
}
-llvm::Triple::ArchType
-ArchSpec::GetMachine () const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- return core_def->machine;
+llvm::Triple::ArchType ArchSpec::GetMachine() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->machine;
- return llvm::Triple::UnknownArch;
+ return llvm::Triple::UnknownArch;
}
-const ConstString&
-ArchSpec::GetDistributionId () const
-{
- return m_distribution_id;
+const ConstString &ArchSpec::GetDistributionId() const {
+ return m_distribution_id;
}
-void
-ArchSpec::SetDistributionId (const char* distribution_id)
-{
- m_distribution_id.SetCString (distribution_id);
+void ArchSpec::SetDistributionId(const char *distribution_id) {
+ m_distribution_id.SetCString(distribution_id);
}
-uint32_t
-ArchSpec::GetAddressByteSize() const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- {
- 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;
+uint32_t ArchSpec::GetAddressByteSize() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def) {
+ 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 0;
+ return core_def->addr_byte_size;
+ }
+ return 0;
}
-ByteOrder
-ArchSpec::GetDefaultEndian () const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- return core_def->default_byte_order;
- return eByteOrderInvalid;
+ByteOrder ArchSpec::GetDefaultEndian() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->default_byte_order;
+ return eByteOrderInvalid;
}
-bool
-ArchSpec::CharIsSignedByDefault () const
-{
- switch (m_triple.getArch()) {
- default:
- return true;
-
- case llvm::Triple::aarch64:
- case llvm::Triple::aarch64_be:
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- return m_triple.isOSDarwin() || m_triple.isOSWindows();
-
- case llvm::Triple::ppc:
- case llvm::Triple::ppc64:
- return m_triple.isOSDarwin();
-
- case llvm::Triple::ppc64le:
- case llvm::Triple::systemz:
- case llvm::Triple::xcore:
- return false;
- }
+bool ArchSpec::CharIsSignedByDefault() const {
+ switch (m_triple.getArch()) {
+ default:
+ return true;
+
+ case llvm::Triple::aarch64:
+ case llvm::Triple::aarch64_be:
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ return m_triple.isOSDarwin() || m_triple.isOSWindows();
+
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppc64:
+ return m_triple.isOSDarwin();
+
+ case llvm::Triple::ppc64le:
+ case llvm::Triple::systemz:
+ case llvm::Triple::xcore:
+ return false;
+ }
}
-lldb::ByteOrder
-ArchSpec::GetByteOrder () const
-{
- if (m_byte_order == eByteOrderInvalid)
- return GetDefaultEndian();
- return m_byte_order;
+lldb::ByteOrder ArchSpec::GetByteOrder() const {
+ if (m_byte_order == eByteOrderInvalid)
+ return GetDefaultEndian();
+ return m_byte_order;
}
//===----------------------------------------------------------------------===//
// Mutators.
-bool
-ArchSpec::SetTriple (const llvm::Triple &triple)
-{
- m_triple = triple;
-
- llvm::StringRef arch_name (m_triple.getArchName());
- const CoreDefinition *core_def = FindCoreDefinition (arch_name);
- if (core_def)
- {
- m_core = core_def->core;
- // Set the byte order to the default byte order for an architecture.
- // This can be modified if needed for cases when cores handle both
- // big and little endian
- m_byte_order = core_def->default_byte_order;
- }
- else
- {
- Clear();
- }
+bool ArchSpec::SetTriple(const llvm::Triple &triple) {
+ m_triple = triple;
+
+ llvm::StringRef arch_name(m_triple.getArchName());
+ const CoreDefinition *core_def = FindCoreDefinition(arch_name);
+ if (core_def) {
+ m_core = core_def->core;
+ // Set the byte order to the default byte order for an architecture.
+ // This can be modified if needed for cases when cores handle both
+ // big and little endian
+ m_byte_order = core_def->default_byte_order;
+ } else {
+ Clear();
+ }
- return IsValid();
+ return IsValid();
}
-static bool
-ParseMachCPUDashSubtypeTriple (const char *triple_cstr, ArchSpec &arch)
-{
- // Accept "12-10" or "12.10" as cpu type/subtype
- if (isdigit(triple_cstr[0]))
- {
- char *end = nullptr;
- errno = 0;
- uint32_t cpu = (uint32_t)::strtoul (triple_cstr, &end, 0);
- if (errno == 0 && cpu != 0 && end && ((*end == '-') || (*end == '.')))
- {
- errno = 0;
- uint32_t sub = (uint32_t)::strtoul (end + 1, &end, 0);
- if (errno == 0 && end && ((*end == '-') || (*end == '.') || (*end == '\0')))
- {
- if (arch.SetArchitecture (eArchTypeMachO, cpu, sub))
- {
- if (*end == '-')
- {
- llvm::StringRef vendor_os (end + 1);
- size_t dash_pos = vendor_os.find('-');
- if (dash_pos != llvm::StringRef::npos)
- {
- llvm::StringRef vendor_str(vendor_os.substr(0, dash_pos));
- arch.GetTriple().setVendorName(vendor_str);
- const size_t vendor_start_pos = dash_pos+1;
- dash_pos = vendor_os.find('-', vendor_start_pos);
- if (dash_pos == llvm::StringRef::npos)
- {
- if (vendor_start_pos < vendor_os.size())
- arch.GetTriple().setOSName(vendor_os.substr(vendor_start_pos));
- }
- else
- {
- arch.GetTriple().setOSName(vendor_os.substr(vendor_start_pos, dash_pos - vendor_start_pos));
- }
- }
- }
- return true;
- }
- }
- }
- }
+bool lldb_private::ParseMachCPUDashSubtypeTriple(llvm::StringRef triple_str,
+ ArchSpec &arch) {
+ // Accept "12-10" or "12.10" as cpu type/subtype
+ if (triple_str.empty())
+ return false;
+
+ size_t pos = triple_str.find_first_of("-.");
+ if (pos == llvm::StringRef::npos)
+ return false;
+
+ llvm::StringRef cpu_str = triple_str.substr(0, pos);
+ llvm::StringRef remainder = triple_str.substr(pos + 1);
+ if (cpu_str.empty() || remainder.empty())
return false;
+
+ llvm::StringRef sub_str;
+ llvm::StringRef vendor;
+ llvm::StringRef os;
+ std::tie(sub_str, remainder) = remainder.split('-');
+ std::tie(vendor, os) = remainder.split('-');
+
+ uint32_t cpu = 0;
+ uint32_t sub = 0;
+ if (cpu_str.getAsInteger(10, cpu) || sub_str.getAsInteger(10, sub))
+ return false;
+
+ if (!arch.SetArchitecture(eArchTypeMachO, cpu, sub))
+ return false;
+ if (!vendor.empty() && !os.empty()) {
+ arch.GetTriple().setVendorName(vendor);
+ arch.GetTriple().setOSName(os);
+ }
+
+ return true;
}
-bool
-ArchSpec::SetTriple (const char *triple_cstr)
-{
- if (triple_cstr && triple_cstr[0])
- {
- if (ParseMachCPUDashSubtypeTriple (triple_cstr, *this))
- return true;
-
- llvm::StringRef triple_stref (triple_cstr);
- if (triple_stref.startswith (LLDB_ARCH_DEFAULT))
- {
- // Special case for the current host default architectures...
- if (triple_stref.equals (LLDB_ARCH_DEFAULT_32BIT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- else if (triple_stref.equals (LLDB_ARCH_DEFAULT_64BIT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKind64);
- else if (triple_stref.equals (LLDB_ARCH_DEFAULT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- }
- else
- {
- std::string normalized_triple_sstr (llvm::Triple::normalize(triple_stref));
- triple_stref = normalized_triple_sstr;
- SetTriple (llvm::Triple (triple_stref));
- }
- }
- else
- Clear();
- return IsValid();
+bool ArchSpec::SetTriple(const char *triple_cstr) {
+ llvm::StringRef str(triple_cstr ? triple_cstr : "");
+ return SetTriple(str);
}
-bool
-ArchSpec::SetTriple (const char *triple_cstr, Platform *platform)
-{
- if (triple_cstr && triple_cstr[0])
- {
- if (ParseMachCPUDashSubtypeTriple (triple_cstr, *this))
- return true;
-
- llvm::StringRef triple_stref (triple_cstr);
- if (triple_stref.startswith (LLDB_ARCH_DEFAULT))
- {
- // Special case for the current host default architectures...
- if (triple_stref.equals (LLDB_ARCH_DEFAULT_32BIT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKind32);
- else if (triple_stref.equals (LLDB_ARCH_DEFAULT_64BIT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKind64);
- else if (triple_stref.equals (LLDB_ARCH_DEFAULT))
- *this = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
- }
- else
- {
- ArchSpec raw_arch (triple_cstr);
-
- std::string normalized_triple_sstr (llvm::Triple::normalize(triple_stref));
- triple_stref = normalized_triple_sstr;
- llvm::Triple normalized_triple (triple_stref);
-
- const bool os_specified = normalized_triple.getOSName().size() > 0;
- const bool vendor_specified = normalized_triple.getVendorName().size() > 0;
- const bool env_specified = normalized_triple.getEnvironmentName().size() > 0;
-
- // If we got an arch only, then default the vendor, os, environment
- // to match the platform if one is supplied
- if (!(os_specified || vendor_specified || env_specified))
- {
- if (platform)
- {
- // If we were given a platform, use the platform's system
- // architecture. If this is not available (might not be
- // connected) use the first supported architecture.
- ArchSpec compatible_arch;
- if (platform->IsCompatibleArchitecture (raw_arch, false, &compatible_arch))
- {
- if (compatible_arch.IsValid())
- {
- const llvm::Triple &compatible_triple = compatible_arch.GetTriple();
- if (!vendor_specified)
- normalized_triple.setVendor(compatible_triple.getVendor());
- if (!os_specified)
- normalized_triple.setOS(compatible_triple.getOS());
- if (!env_specified && compatible_triple.getEnvironmentName().size())
- normalized_triple.setEnvironment(compatible_triple.getEnvironment());
- }
- }
- else
- {
- *this = raw_arch;
- return IsValid();
- }
- }
- else
- {
- // No platform specified, fall back to the host system for
- // the default vendor, os, and environment.
- llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
- if (!vendor_specified)
- normalized_triple.setVendor(host_triple.getVendor());
- if (!vendor_specified)
- normalized_triple.setOS(host_triple.getOS());
- if (!env_specified && host_triple.getEnvironmentName().size())
- normalized_triple.setEnvironment(host_triple.getEnvironment());
- }
- }
- SetTriple (normalized_triple);
- }
- }
- else
- Clear();
+bool ArchSpec::SetTriple(const char *triple_cstr, Platform *platform) {
+ llvm::StringRef str(triple_cstr ? triple_cstr : "");
+ return SetTriple(str, platform);
+}
+
+bool ArchSpec::SetTriple(llvm::StringRef triple) {
+ if (triple.empty()) {
+ Clear();
+ return false;
+ }
+
+ if (ParseMachCPUDashSubtypeTriple(triple, *this))
+ return true;
+
+ if (triple.startswith(LLDB_ARCH_DEFAULT)) {
+ // Special case for the current host default architectures...
+ if (triple.equals(LLDB_ARCH_DEFAULT_32BIT))
+ *this = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ else if (triple.equals(LLDB_ARCH_DEFAULT_64BIT))
+ *this = HostInfo::GetArchitecture(HostInfo::eArchKind64);
+ else if (triple.equals(LLDB_ARCH_DEFAULT))
+ *this = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ } else {
+ SetTriple(llvm::Triple(llvm::Triple::normalize(triple)));
+ }
+ return IsValid();
+}
+
+bool ArchSpec::SetTriple(llvm::StringRef triple, Platform *platform) {
+ if (triple.empty()) {
+ Clear();
+ return false;
+ }
+ if (ParseMachCPUDashSubtypeTriple(triple, *this))
+ return true;
+
+ if (triple.startswith(LLDB_ARCH_DEFAULT)) {
+ // Special case for the current host default architectures...
+ if (triple.equals(LLDB_ARCH_DEFAULT_32BIT))
+ *this = HostInfo::GetArchitecture(HostInfo::eArchKind32);
+ else if (triple.equals(LLDB_ARCH_DEFAULT_64BIT))
+ *this = HostInfo::GetArchitecture(HostInfo::eArchKind64);
+ else if (triple.equals(LLDB_ARCH_DEFAULT))
+ *this = HostInfo::GetArchitecture(HostInfo::eArchKindDefault);
+ return IsValid();
+ }
+
+ ArchSpec raw_arch(triple);
+
+ llvm::Triple normalized_triple(llvm::Triple::normalize(triple));
+
+ const bool os_specified = !normalized_triple.getOSName().empty();
+ const bool vendor_specified = !normalized_triple.getVendorName().empty();
+ const bool env_specified = !normalized_triple.getEnvironmentName().empty();
+
+ if (os_specified || vendor_specified || env_specified) {
+ SetTriple(normalized_triple);
+ return IsValid();
+ }
+
+ // We got an arch only. If there is no platform, fallback to the host system
+ // for defaults.
+ if (!platform) {
+ llvm::Triple host_triple(llvm::sys::getDefaultTargetTriple());
+ if (!vendor_specified)
+ normalized_triple.setVendor(host_triple.getVendor());
+ if (!vendor_specified)
+ normalized_triple.setOS(host_triple.getOS());
+ if (!env_specified && host_triple.getEnvironmentName().size())
+ normalized_triple.setEnvironment(host_triple.getEnvironment());
+ SetTriple(normalized_triple);
+ return IsValid();
+ }
+
+ // If we were given a platform, use the platform's system architecture. If
+ // this is not available (might not be connected) use the first supported
+ // architecture.
+ ArchSpec compatible_arch;
+ if (!platform->IsCompatibleArchitecture(raw_arch, false, &compatible_arch)) {
+ *this = raw_arch;
return IsValid();
+ }
+
+ if (compatible_arch.IsValid()) {
+ const llvm::Triple &compatible_triple = compatible_arch.GetTriple();
+ if (!vendor_specified)
+ normalized_triple.setVendor(compatible_triple.getVendor());
+ if (!os_specified)
+ normalized_triple.setOS(compatible_triple.getOS());
+ if (!env_specified && compatible_triple.hasEnvironment())
+ normalized_triple.setEnvironment(compatible_triple.getEnvironment());
+ }
+
+ SetTriple(normalized_triple);
+ return IsValid();
}
-void
-ArchSpec::MergeFrom(const ArchSpec &other)
-{
- if (TripleVendorIsUnspecifiedUnknown() && !other.TripleVendorIsUnspecifiedUnknown())
- GetTriple().setVendor(other.GetTriple().getVendor());
- 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 && !TripleVendorWasSpecified())
- {
- if (other.TripleVendorWasSpecified())
- GetTriple().setEnvironment(other.GetTriple().getEnvironment());
- }
- // If this and other are both arm ArchSpecs and this ArchSpec is a generic "some kind of arm"
- // spec but the other ArchSpec is a specific arm core, adopt the specific arm core.
- if (GetTriple().getArch() == llvm::Triple::arm
- && other.GetTriple().getArch() == llvm::Triple::arm
- && IsCompatibleMatch (other)
- && GetCore() == ArchSpec::eCore_arm_generic
- && other.GetCore() != ArchSpec::eCore_arm_generic)
- {
- m_core = other.GetCore();
- CoreUpdated (true);
- }
+void ArchSpec::MergeFrom(const ArchSpec &other) {
+ if (TripleVendorIsUnspecifiedUnknown() &&
+ !other.TripleVendorIsUnspecifiedUnknown())
+ GetTriple().setVendor(other.GetTriple().getVendor());
+ 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 &&
+ !TripleVendorWasSpecified()) {
+ if (other.TripleVendorWasSpecified())
+ GetTriple().setEnvironment(other.GetTriple().getEnvironment());
+ }
+ // If this and other are both arm ArchSpecs and this ArchSpec is a generic
+ // "some kind of arm"
+ // spec but the other ArchSpec is a specific arm core, adopt the specific arm
+ // core.
+ if (GetTriple().getArch() == llvm::Triple::arm &&
+ other.GetTriple().getArch() == llvm::Triple::arm &&
+ IsCompatibleMatch(other) && GetCore() == ArchSpec::eCore_arm_generic &&
+ other.GetCore() != ArchSpec::eCore_arm_generic) {
+ m_core = other.GetCore();
+ CoreUpdated(true);
+ }
}
-bool
-ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os)
-{
- m_core = kCore_invalid;
- bool update_triple = true;
- const ArchDefinition *arch_def = FindArchDefinition(arch_type);
- if (arch_def)
- {
- const ArchDefinitionEntry *arch_def_entry = FindArchDefinitionEntry (arch_def, cpu, sub);
- if (arch_def_entry)
- {
- const CoreDefinition *core_def = FindCoreDefinition (arch_def_entry->core);
- if (core_def)
- {
- m_core = core_def->core;
- update_triple = false;
- // Always use the architecture name because it might be more descriptive
- // than the architecture enum ("armv7" -> llvm::Triple::arm).
- m_triple.setArchName(llvm::StringRef(core_def->name));
- if (arch_type == eArchTypeMachO)
- {
- m_triple.setVendor (llvm::Triple::Apple);
-
- // 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)
- {
- switch (os)
- {
- case llvm::ELF::ELFOSABI_AIX: m_triple.setOS (llvm::Triple::OSType::AIX); break;
- case llvm::ELF::ELFOSABI_FREEBSD: m_triple.setOS (llvm::Triple::OSType::FreeBSD); break;
- case llvm::ELF::ELFOSABI_GNU: m_triple.setOS (llvm::Triple::OSType::Linux); break;
- case llvm::ELF::ELFOSABI_NETBSD: m_triple.setOS (llvm::Triple::OSType::NetBSD); break;
- case llvm::ELF::ELFOSABI_OPENBSD: m_triple.setOS (llvm::Triple::OSType::OpenBSD); break;
- 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);
- }
+bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
+ uint32_t sub, uint32_t os) {
+ m_core = kCore_invalid;
+ bool update_triple = true;
+ const ArchDefinition *arch_def = FindArchDefinition(arch_type);
+ if (arch_def) {
+ const ArchDefinitionEntry *arch_def_entry =
+ FindArchDefinitionEntry(arch_def, cpu, sub);
+ if (arch_def_entry) {
+ const CoreDefinition *core_def = FindCoreDefinition(arch_def_entry->core);
+ if (core_def) {
+ m_core = core_def->core;
+ update_triple = false;
+ // Always use the architecture name because it might be more descriptive
+ // than the architecture enum ("armv7" -> llvm::Triple::arm).
+ m_triple.setArchName(llvm::StringRef(core_def->name));
+ if (arch_type == eArchTypeMachO) {
+ m_triple.setVendor(llvm::Triple::Apple);
+
+ // 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) {
+ switch (os) {
+ case llvm::ELF::ELFOSABI_AIX:
+ m_triple.setOS(llvm::Triple::OSType::AIX);
+ break;
+ case llvm::ELF::ELFOSABI_FREEBSD:
+ m_triple.setOS(llvm::Triple::OSType::FreeBSD);
+ break;
+ case llvm::ELF::ELFOSABI_GNU:
+ m_triple.setOS(llvm::Triple::OSType::Linux);
+ break;
+ case llvm::ELF::ELFOSABI_NETBSD:
+ m_triple.setOS(llvm::Triple::OSType::NetBSD);
+ break;
+ case llvm::ELF::ELFOSABI_OPENBSD:
+ m_triple.setOS(llvm::Triple::OSType::OpenBSD);
+ break;
+ case llvm::ELF::ELFOSABI_SOLARIS:
+ m_triple.setOS(llvm::Triple::OSType::Solaris);
+ break;
+ }
+ } else if (arch_type == eArchTypeCOFF && os == llvm::Triple::Win32) {
+ m_triple.setVendor(llvm::Triple::PC);
+ m_triple.setOS(llvm::Triple::Win32);
+ } 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);
+ }
}
- CoreUpdated(update_triple);
- return IsValid();
+ }
+ CoreUpdated(update_triple);
+ return IsValid();
}
-uint32_t
-ArchSpec::GetMinimumOpcodeByteSize() const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- return core_def->min_opcode_byte_size;
- return 0;
+uint32_t ArchSpec::GetMinimumOpcodeByteSize() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->min_opcode_byte_size;
+ return 0;
}
-uint32_t
-ArchSpec::GetMaximumOpcodeByteSize() const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- return core_def->max_opcode_byte_size;
- return 0;
+uint32_t ArchSpec::GetMaximumOpcodeByteSize() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->max_opcode_byte_size;
+ return 0;
}
-bool
-ArchSpec::IsExactMatch (const ArchSpec& rhs) const
-{
- return IsEqualTo (rhs, true);
+bool ArchSpec::IsExactMatch(const ArchSpec &rhs) const {
+ return IsEqualTo(rhs, true);
}
-bool
-ArchSpec::IsCompatibleMatch (const ArchSpec& rhs) const
-{
- return IsEqualTo (rhs, false);
+bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const {
+ return IsEqualTo(rhs, false);
}
-static bool
-isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs)
-{
- if (lhs == rhs)
- return true;
+static bool isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
+ llvm::Triple::EnvironmentType rhs) {
+ if (lhs == rhs)
+ return true;
+
+ // If any of the environment is unknown then they are compatible
+ if (lhs == llvm::Triple::UnknownEnvironment ||
+ rhs == llvm::Triple::UnknownEnvironment)
+ return true;
+
+ // If one of the environment is Android and the other one is EABI then they
+ // are considered to
+ // be compatible. This is required as a workaround for shared libraries
+ // compiled for Android
+ // without the NOTE section indicating that they are using the Android ABI.
+ if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) ||
+ (rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) ||
+ (lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) ||
+ (rhs == llvm::Triple::GNUEABI && lhs == llvm::Triple::EABI) ||
+ (lhs == llvm::Triple::GNUEABIHF && rhs == llvm::Triple::EABIHF) ||
+ (rhs == llvm::Triple::GNUEABIHF && lhs == llvm::Triple::EABIHF))
+ return true;
+
+ return false;
+}
- // If any of the environment is unknown then they are compatible
- if (lhs == llvm::Triple::UnknownEnvironment || rhs == llvm::Triple::UnknownEnvironment)
- return true;
-
- // If one of the environment is Android and the other one is EABI then they are considered to
- // be compatible. This is required as a workaround for shared libraries compiled for Android
- // without the NOTE section indicating that they are using the Android ABI.
- if ((lhs == llvm::Triple::Android && rhs == llvm::Triple::EABI) ||
- (rhs == llvm::Triple::Android && lhs == llvm::Triple::EABI) ||
- (lhs == llvm::Triple::GNUEABI && rhs == llvm::Triple::EABI) ||
- (rhs == llvm::Triple::GNUEABI && lhs == llvm::Triple::EABI) ||
- (lhs == llvm::Triple::GNUEABIHF && rhs == llvm::Triple::EABIHF) ||
- (rhs == llvm::Triple::GNUEABIHF && lhs == llvm::Triple::EABIHF))
- return true;
+bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
+ // explicitly ignoring m_distribution_id in this method.
+ if (GetByteOrder() != rhs.GetByteOrder())
return false;
-}
-bool
-ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const
-{
- // explicitly ignoring m_distribution_id in this method.
+ const ArchSpec::Core lhs_core = GetCore();
+ const ArchSpec::Core rhs_core = rhs.GetCore();
- if (GetByteOrder() != rhs.GetByteOrder())
+ const bool core_match = cores_match(lhs_core, rhs_core, true, exact_match);
+
+ if (core_match) {
+ const llvm::Triple &lhs_triple = GetTriple();
+ const llvm::Triple &rhs_triple = rhs.GetTriple();
+
+ const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
+ const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
+ if (lhs_triple_vendor != rhs_triple_vendor) {
+ 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 ArchSpec::Core lhs_core = GetCore ();
- const ArchSpec::Core rhs_core = rhs.GetCore ();
-
- const bool core_match = cores_match (lhs_core, rhs_core, true, exact_match);
-
- if (core_match)
- {
- const llvm::Triple &lhs_triple = GetTriple();
- const llvm::Triple &rhs_triple = rhs.GetTriple();
-
- const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
- const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
- if (lhs_triple_vendor != rhs_triple_vendor)
- {
- 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 &&
- rhs_triple_vendor != llvm::Triple::UnknownVendor)
- return false;
- }
-
- const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
- const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
- if (lhs_triple_os != rhs_triple_os)
- {
- 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 &&
- rhs_triple_os != llvm::Triple::UnknownOS)
- return false;
- }
- const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment();
- const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment();
-
- if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env))
- return false;
- return true;
+ // Only fail if both vendor types are not unknown
+ if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
+ rhs_triple_vendor != llvm::Triple::UnknownVendor)
+ return false;
}
- return false;
+
+ const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
+ const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
+ if (lhs_triple_os != rhs_triple_os) {
+ 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 &&
+ rhs_triple_os != llvm::Triple::UnknownOS)
+ return false;
+ }
+
+ const llvm::Triple::EnvironmentType lhs_triple_env =
+ lhs_triple.getEnvironment();
+ const llvm::Triple::EnvironmentType rhs_triple_env =
+ rhs_triple.getEnvironment();
+
+ if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env))
+ return false;
+ return true;
+ }
+ return false;
}
//===----------------------------------------------------------------------===//
// Helper methods.
-void
-ArchSpec::CoreUpdated (bool update_triple)
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- {
- if (update_triple)
- m_triple = llvm::Triple(core_def->name, "unknown", "unknown");
- m_byte_order = core_def->default_byte_order;
- }
- else
- {
- if (update_triple)
- m_triple = llvm::Triple();
- m_byte_order = eByteOrderInvalid;
- }
+void ArchSpec::CoreUpdated(bool update_triple) {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def) {
+ if (update_triple)
+ m_triple = llvm::Triple(core_def->name, "unknown", "unknown");
+ m_byte_order = core_def->default_byte_order;
+ } else {
+ if (update_triple)
+ m_triple = llvm::Triple();
+ m_byte_order = eByteOrderInvalid;
+ }
}
//===----------------------------------------------------------------------===//
// Operators.
-static bool
-cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match)
-{
- if (core1 == core2)
+static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
+ bool try_inverse, bool enforce_exact_match) {
+ if (core1 == core2)
+ return true;
+
+ switch (core1) {
+ case ArchSpec::kCore_any:
+ return true;
+
+ case ArchSpec::eCore_arm_generic:
+ if (enforce_exact_match)
+ break;
+ LLVM_FALLTHROUGH;
+ case ArchSpec::kCore_arm_any:
+ if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last)
+ return true;
+ if (core2 >= ArchSpec::kCore_thumb_first &&
+ core2 <= ArchSpec::kCore_thumb_last)
+ return true;
+ if (core2 == ArchSpec::kCore_arm_any)
+ return true;
+ break;
+
+ case ArchSpec::kCore_x86_32_any:
+ if ((core2 >= ArchSpec::kCore_x86_32_first &&
+ core2 <= ArchSpec::kCore_x86_32_last) ||
+ (core2 == ArchSpec::kCore_x86_32_any))
+ return true;
+ break;
+
+ case ArchSpec::kCore_x86_64_any:
+ if ((core2 >= ArchSpec::kCore_x86_64_first &&
+ core2 <= ArchSpec::kCore_x86_64_last) ||
+ (core2 == ArchSpec::kCore_x86_64_any))
+ return true;
+ break;
+
+ case ArchSpec::kCore_ppc_any:
+ if ((core2 >= ArchSpec::kCore_ppc_first &&
+ core2 <= ArchSpec::kCore_ppc_last) ||
+ (core2 == ArchSpec::kCore_ppc_any))
+ return true;
+ break;
+
+ case ArchSpec::kCore_ppc64_any:
+ if ((core2 >= ArchSpec::kCore_ppc64_first &&
+ core2 <= ArchSpec::kCore_ppc64_last) ||
+ (core2 == ArchSpec::kCore_ppc64_any))
+ return true;
+ break;
+
+ case ArchSpec::eCore_arm_armv6m:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_generic)
+ return true;
+ try_inverse = false;
+ if (core2 == ArchSpec::eCore_arm_armv7)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv6m)
+ return true;
+ }
+ break;
+
+ case ArchSpec::kCore_hexagon_any:
+ if ((core2 >= ArchSpec::kCore_hexagon_first &&
+ core2 <= ArchSpec::kCore_hexagon_last) ||
+ (core2 == ArchSpec::kCore_hexagon_any))
+ 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) {
+ if (core2 == ArchSpec::eCore_arm_generic)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv7m)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv6m)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv7)
+ return true;
+ try_inverse = 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_armv7m:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_generic)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv6m)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv7)
return true;
+ if (core2 == ArchSpec::eCore_arm_armv7em)
+ return true;
+ try_inverse = true;
+ }
+ break;
- switch (core1)
- {
- case ArchSpec::kCore_any:
+ case ArchSpec::eCore_arm_armv7f:
+ case ArchSpec::eCore_arm_armv7k:
+ case ArchSpec::eCore_arm_armv7s:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_generic)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv7)
return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_arm_generic:
- if (enforce_exact_match)
- break;
- LLVM_FALLTHROUGH;
- case ArchSpec::kCore_arm_any:
- if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last)
- return true;
- if (core2 >= ArchSpec::kCore_thumb_first && core2 <= ArchSpec::kCore_thumb_last)
- return true;
- if (core2 == ArchSpec::kCore_arm_any)
- return true;
- break;
-
- case ArchSpec::kCore_x86_32_any:
- if ((core2 >= ArchSpec::kCore_x86_32_first && core2 <= ArchSpec::kCore_x86_32_last) || (core2 == ArchSpec::kCore_x86_32_any))
- return true;
- break;
-
- case ArchSpec::kCore_x86_64_any:
- if ((core2 >= ArchSpec::kCore_x86_64_first && core2 <= ArchSpec::kCore_x86_64_last) || (core2 == ArchSpec::kCore_x86_64_any))
- return true;
- break;
-
- case ArchSpec::kCore_ppc_any:
- if ((core2 >= ArchSpec::kCore_ppc_first && core2 <= ArchSpec::kCore_ppc_last) || (core2 == ArchSpec::kCore_ppc_any))
- return true;
- break;
-
- case ArchSpec::kCore_ppc64_any:
- if ((core2 >= ArchSpec::kCore_ppc64_first && core2 <= ArchSpec::kCore_ppc64_last) || (core2 == ArchSpec::kCore_ppc64_any))
- return true;
- break;
-
- case ArchSpec::eCore_arm_armv6m:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_generic)
- return true;
- try_inverse = false;
- if (core2 == ArchSpec::eCore_arm_armv7)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv6m)
- return true;
- }
- break;
-
- case ArchSpec::kCore_hexagon_any:
- if ((core2 >= ArchSpec::kCore_hexagon_first && core2 <= ArchSpec::kCore_hexagon_last) || (core2 == ArchSpec::kCore_hexagon_any))
- 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)
- {
- if (core2 == ArchSpec::eCore_arm_generic)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7m)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv6m)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7)
- return true;
- try_inverse = 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_armv7m:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_generic)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv6m)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7em)
- return true;
- try_inverse = true;
- }
- break;
-
- case ArchSpec::eCore_arm_armv7f:
- case ArchSpec::eCore_arm_armv7k:
- case ArchSpec::eCore_arm_armv7s:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_generic)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7)
- return true;
- try_inverse = false;
- }
- break;
-
- case ArchSpec::eCore_x86_64_x86_64h:
- if (!enforce_exact_match)
- {
- try_inverse = false;
- if (core2 == ArchSpec::eCore_x86_64_x86_64)
- return true;
- }
- break;
-
- case ArchSpec::eCore_arm_armv8:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_arm64)
- return true;
- if (core2 == ArchSpec::eCore_arm_aarch64)
- return true;
- try_inverse = false;
- }
- break;
-
- case ArchSpec::eCore_arm_aarch64:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_arm64)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv8)
- return true;
- try_inverse = false;
- }
- break;
-
- case ArchSpec::eCore_arm_arm64:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_aarch64)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv8)
- return true;
- try_inverse = false;
- }
- break;
+ case ArchSpec::eCore_x86_64_x86_64h:
+ if (!enforce_exact_match) {
+ try_inverse = false;
+ if (core2 == ArchSpec::eCore_x86_64_x86_64)
+ return true;
+ }
+ break;
- case ArchSpec::eCore_mips32:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32_first && core2 <= ArchSpec::kCore_mips32_last)
- return true;
- try_inverse = false;
- }
- break;
+ case ArchSpec::eCore_arm_armv8:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_arm64)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_aarch64)
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips32el:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= ArchSpec::kCore_mips32el_last)
- return true;
- try_inverse = false;
- }
- break;
+ case ArchSpec::eCore_arm_aarch64:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_arm64)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv8)
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips64:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32_first && core2 <= ArchSpec::kCore_mips32_last)
- return true;
- if (core2 >= ArchSpec::kCore_mips64_first && core2 <= ArchSpec::kCore_mips64_last)
- return true;
- try_inverse = false;
- }
- break;
+ case ArchSpec::eCore_arm_arm64:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_aarch64)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv8)
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips64el:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= ArchSpec::kCore_mips32el_last)
- return true;
- if (core2 >= ArchSpec::kCore_mips64el_first && core2 <= ArchSpec::kCore_mips64el_last)
- return true;
- try_inverse = false;
- }
- break;
+ case ArchSpec::eCore_mips32:
+ if (!enforce_exact_match) {
+ if (core2 >= ArchSpec::kCore_mips32_first &&
+ core2 <= ArchSpec::kCore_mips32_last)
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips64r2:
- case ArchSpec::eCore_mips64r3:
- case ArchSpec::eCore_mips64r5:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32_first && core2 <= (core1 - 10))
- return true;
- if (core2 >= ArchSpec::kCore_mips64_first && core2 <= (core1 - 1))
- return true;
- try_inverse = false;
- }
- break;
+ case ArchSpec::eCore_mips32el:
+ if (!enforce_exact_match) {
+ if (core2 >= ArchSpec::kCore_mips32el_first &&
+ core2 <= ArchSpec::kCore_mips32el_last)
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips64r2el:
- case ArchSpec::eCore_mips64r3el:
- case ArchSpec::eCore_mips64r5el:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= (core1 - 10))
- return true;
- if (core2 >= ArchSpec::kCore_mips64el_first && core2 <= (core1 - 1))
- return true;
- try_inverse = false;
- }
- break;
+ case ArchSpec::eCore_mips64:
+ if (!enforce_exact_match) {
+ if (core2 >= ArchSpec::kCore_mips32_first &&
+ core2 <= ArchSpec::kCore_mips32_last)
+ return true;
+ if (core2 >= ArchSpec::kCore_mips64_first &&
+ core2 <= ArchSpec::kCore_mips64_last)
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips32r2:
- case ArchSpec::eCore_mips32r3:
- case ArchSpec::eCore_mips32r5:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32_first && core2 <= core1)
- return true;
- }
- break;
+ case ArchSpec::eCore_mips64el:
+ if (!enforce_exact_match) {
+ if (core2 >= ArchSpec::kCore_mips32el_first &&
+ core2 <= ArchSpec::kCore_mips32el_last)
+ return true;
+ if (core2 >= ArchSpec::kCore_mips64el_first &&
+ core2 <= ArchSpec::kCore_mips64el_last)
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips32r2el:
- case ArchSpec::eCore_mips32r3el:
- case ArchSpec::eCore_mips32r5el:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= core1)
- return true;
- }
- break;
+ case ArchSpec::eCore_mips64r2:
+ case ArchSpec::eCore_mips64r3:
+ case ArchSpec::eCore_mips64r5:
+ if (!enforce_exact_match) {
+ if (core2 >= ArchSpec::kCore_mips32_first && core2 <= (core1 - 10))
+ return true;
+ if (core2 >= ArchSpec::kCore_mips64_first && core2 <= (core1 - 1))
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips32r6:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6)
- return true;
- }
- break;
+ case ArchSpec::eCore_mips64r2el:
+ case ArchSpec::eCore_mips64r3el:
+ case ArchSpec::eCore_mips64r5el:
+ if (!enforce_exact_match) {
+ if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= (core1 - 10))
+ return true;
+ if (core2 >= ArchSpec::kCore_mips64el_first && core2 <= (core1 - 1))
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_mips32r6el:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el)
- return true;
- }
- break;
+ case ArchSpec::eCore_mips32r2:
+ case ArchSpec::eCore_mips32r3:
+ case ArchSpec::eCore_mips32r5:
+ if (!enforce_exact_match) {
+ if (core2 >= ArchSpec::kCore_mips32_first && core2 <= core1)
+ return true;
+ }
+ break;
- case ArchSpec::eCore_mips64r6:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6)
- return true;
- if (core2 == ArchSpec::eCore_mips64 || core2 == ArchSpec::eCore_mips64r6)
- return true;
- }
- break;
+ case ArchSpec::eCore_mips32r2el:
+ case ArchSpec::eCore_mips32r3el:
+ case ArchSpec::eCore_mips32r5el:
+ if (!enforce_exact_match) {
+ if (core2 >= ArchSpec::kCore_mips32el_first && core2 <= core1)
+ return true;
+ }
+ break;
- case ArchSpec::eCore_mips64r6el:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el)
- return true;
- if (core2 == ArchSpec::eCore_mips64el || core2 == ArchSpec::eCore_mips64r6el)
- return true;
- }
- break;
+ case ArchSpec::eCore_mips32r6:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6)
+ return true;
+ }
+ break;
- default:
- break;
+ case ArchSpec::eCore_mips32r6el:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_mips32el ||
+ core2 == ArchSpec::eCore_mips32r6el)
+ return true;
}
- if (try_inverse)
- return cores_match (core2, core1, false, enforce_exact_match);
- return false;
+ break;
+
+ case ArchSpec::eCore_mips64r6:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6)
+ return true;
+ if (core2 == ArchSpec::eCore_mips64 || core2 == ArchSpec::eCore_mips64r6)
+ return true;
+ }
+ break;
+
+ case ArchSpec::eCore_mips64r6el:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_mips32el ||
+ core2 == ArchSpec::eCore_mips32r6el)
+ return true;
+ if (core2 == ArchSpec::eCore_mips64el ||
+ core2 == ArchSpec::eCore_mips64r6el)
+ return true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ if (try_inverse)
+ return cores_match(core2, core1, false, enforce_exact_match);
+ return false;
}
-bool
-lldb_private::operator<(const ArchSpec& lhs, const ArchSpec& rhs)
-{
- const ArchSpec::Core lhs_core = lhs.GetCore ();
- const ArchSpec::Core rhs_core = rhs.GetCore ();
- return lhs_core < rhs_core;
+bool lldb_private::operator<(const ArchSpec &lhs, const ArchSpec &rhs) {
+ const ArchSpec::Core lhs_core = lhs.GetCore();
+ const ArchSpec::Core rhs_core = rhs.GetCore();
+ return lhs_core < rhs_core;
}
-static void
-StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread)
-{
- // We need to check if we are stopped in Thumb mode in a IT instruction
- // and detect if the condition doesn't pass. If this is the case it means
- // we won't actually execute this instruction. If this happens we need to
- // clear the stop reason to no thread plans think we are stopped for a
- // reason and the plans should keep going.
- //
- // We do this because when single stepping many ARM processes, debuggers
- // often use the BVR/BCR registers that says "stop when the PC is not
- // equal to its current value". This method of stepping means we can end
- // up stopping on instructions inside an if/then block that wouldn't get
- // executed. By fixing this we can stop the debugger from seeming like
- // you stepped through both the "if" _and_ the "else" clause when source
- // level stepping because the debugger stops regardless due to the BVR/BCR
- // triggering a stop.
- //
- // It also means we can set breakpoints on instructions inside an an
- // if/then block and correctly skip them if we use the BKPT instruction.
- // The ARM and Thumb BKPT instructions are unconditional even when executed
- // in a Thumb IT block.
- //
- // If your debugger inserts software traps in ARM/Thumb code, it will
- // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
- // instructions respectively. If your debugger inserts a 16 bit thumb
- // trap on top of a 32 bit thumb instruction for an opcode that is inside
- // an if/then, it will change the it/then to conditionally execute your
- // 16 bit trap and then cause your program to crash if it executes the
- // trailing 16 bits (the second half of the 32 bit thumb instruction you
- // partially overwrote).
-
- RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
- if (reg_ctx_sp)
- {
- const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
- if (cpsr != 0)
- {
- // Read the J and T bits to get the ISETSTATE
- const uint32_t J = Bit32(cpsr, 24);
- const uint32_t T = Bit32(cpsr, 5);
- const uint32_t ISETSTATE = J << 1 | T;
- if (ISETSTATE == 0)
- {
- // NOTE: I am pretty sure we want to enable the code below
- // that detects when we stop on an instruction in ARM mode
- // that is conditional and the condition doesn't pass. This
- // can happen if you set a breakpoint on an instruction that
- // is conditional. We currently will _always_ stop on the
- // instruction which is bad. You can also run into this while
- // single stepping and you could appear to run code in the "if"
- // and in the "else" clause because it would stop at all of the
- // conditional instructions in both.
- // In such cases, we really don't want to stop at this location.
- // I will check with the lldb-dev list first before I enable this.
+static void StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread) {
+ // We need to check if we are stopped in Thumb mode in a IT instruction
+ // and detect if the condition doesn't pass. If this is the case it means
+ // we won't actually execute this instruction. If this happens we need to
+ // clear the stop reason to no thread plans think we are stopped for a
+ // reason and the plans should keep going.
+ //
+ // We do this because when single stepping many ARM processes, debuggers
+ // often use the BVR/BCR registers that says "stop when the PC is not
+ // equal to its current value". This method of stepping means we can end
+ // up stopping on instructions inside an if/then block that wouldn't get
+ // executed. By fixing this we can stop the debugger from seeming like
+ // you stepped through both the "if" _and_ the "else" clause when source
+ // level stepping because the debugger stops regardless due to the BVR/BCR
+ // triggering a stop.
+ //
+ // It also means we can set breakpoints on instructions inside an an
+ // if/then block and correctly skip them if we use the BKPT instruction.
+ // The ARM and Thumb BKPT instructions are unconditional even when executed
+ // in a Thumb IT block.
+ //
+ // If your debugger inserts software traps in ARM/Thumb code, it will
+ // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
+ // instructions respectively. If your debugger inserts a 16 bit thumb
+ // trap on top of a 32 bit thumb instruction for an opcode that is inside
+ // an if/then, it will change the it/then to conditionally execute your
+ // 16 bit trap and then cause your program to crash if it executes the
+ // trailing 16 bits (the second half of the 32 bit thumb instruction you
+ // partially overwrote).
+
+ RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
+ if (reg_ctx_sp) {
+ const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
+ if (cpsr != 0) {
+ // Read the J and T bits to get the ISETSTATE
+ const uint32_t J = Bit32(cpsr, 24);
+ const uint32_t T = Bit32(cpsr, 5);
+ const uint32_t ISETSTATE = J << 1 | T;
+ if (ISETSTATE == 0) {
+// NOTE: I am pretty sure we want to enable the code below
+// that detects when we stop on an instruction in ARM mode
+// that is conditional and the condition doesn't pass. This
+// can happen if you set a breakpoint on an instruction that
+// is conditional. We currently will _always_ stop on the
+// instruction which is bad. You can also run into this while
+// single stepping and you could appear to run code in the "if"
+// and in the "else" clause because it would stop at all of the
+// conditional instructions in both.
+// In such cases, we really don't want to stop at this location.
+// I will check with the lldb-dev list first before I enable this.
#if 0
// ARM mode: check for condition on intsruction
const addr_t pc = reg_ctx_sp->GetPC();
@@ -1527,120 +1569,101 @@ StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread)
}
}
#endif
- }
- else if (ISETSTATE == 1)
- {
- // Thumb mode
- const uint32_t ITSTATE = Bits32 (cpsr, 15, 10) << 2 | Bits32 (cpsr, 26, 25);
- if (ITSTATE != 0)
- {
- const uint32_t condition = Bits32(ITSTATE, 7, 4);
- if (!ARMConditionPassed(condition, cpsr))
- {
- // We ARE stopped in a Thumb IT instruction on an instruction whose
- // condition doesn't pass so this instruction won't get executed.
- // Regardless of why it stopped, we need to clear the stop info
- thread.SetStopInfo (StopInfoSP());
- }
- }
- }
+ } else if (ISETSTATE == 1) {
+ // Thumb mode
+ const uint32_t ITSTATE =
+ Bits32(cpsr, 15, 10) << 2 | Bits32(cpsr, 26, 25);
+ if (ITSTATE != 0) {
+ const uint32_t condition = Bits32(ITSTATE, 7, 4);
+ if (!ARMConditionPassed(condition, cpsr)) {
+ // We ARE stopped in a Thumb IT instruction on an instruction whose
+ // condition doesn't pass so this instruction won't get executed.
+ // Regardless of why it stopped, we need to clear the stop info
+ thread.SetStopInfo(StopInfoSP());
+ }
}
+ }
}
+ }
}
ArchSpec::StopInfoOverrideCallbackType
-ArchSpec::GetStopInfoOverrideCallback () const
-{
- const llvm::Triple::ArchType machine = GetMachine();
- if (machine == llvm::Triple::arm)
- return StopInfoOverrideCallbackTypeARM;
- return nullptr;
+ArchSpec::GetStopInfoOverrideCallback() const {
+ const llvm::Triple::ArchType machine = GetMachine();
+ if (machine == llvm::Triple::arm)
+ return StopInfoOverrideCallbackTypeARM;
+ return nullptr;
}
-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;
- }
- }
+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;
+ }
+
+ 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::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());
}
-bool
-ArchSpec::IsAlwaysThumbInstructions () const
-{
- std::string Error;
- if (GetTriple().getArch() == llvm::Triple::arm || GetTriple().getArch() == llvm::Triple::thumb)
- {
- // v. https://en.wikipedia.org/wiki/ARM_Cortex-M
- //
- // Cortex-M0 through Cortex-M7 are ARM processor cores which can only
- // execute thumb instructions. We map the cores to arch names like this:
- //
- // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m
- // Cortex-M3: armv7m
- // Cortex-M4, Cortex-M7: armv7em
-
- if (GetCore() == ArchSpec::Core::eCore_arm_armv7m
- || GetCore() == ArchSpec::Core::eCore_arm_armv7em
- || GetCore() == ArchSpec::Core::eCore_arm_armv6m)
- {
- return true;
- }
+bool ArchSpec::IsAlwaysThumbInstructions() const {
+ std::string Error;
+ if (GetTriple().getArch() == llvm::Triple::arm ||
+ GetTriple().getArch() == llvm::Triple::thumb) {
+ // v. https://en.wikipedia.org/wiki/ARM_Cortex-M
+ //
+ // Cortex-M0 through Cortex-M7 are ARM processor cores which can only
+ // execute thumb instructions. We map the cores to arch names like this:
+ //
+ // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m
+ // Cortex-M3: armv7m
+ // Cortex-M4, Cortex-M7: armv7em
+
+ if (GetCore() == ArchSpec::Core::eCore_arm_armv7m ||
+ GetCore() == ArchSpec::Core::eCore_arm_armv7em ||
+ GetCore() == ArchSpec::Core::eCore_arm_armv6m) {
+ return true;
}
- return false;
+ }
+ return false;
}
-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();
- llvm::StringRef environ_str = triple.getEnvironmentName();
-
- 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()
- );
-
- if (!environ_str.empty())
- s.Printf("-%s", environ_str.str().c_str());
+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();
+ llvm::StringRef environ_str = triple.getEnvironmentName();
+
+ 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());
+
+ if (!environ_str.empty())
+ s.Printf("-%s", environ_str.str().c_str());
}
diff --git a/source/Core/Baton.cpp b/source/Core/Baton.cpp
index 8bed01be8839..998a5dffca9c 100644
--- a/source/Core/Baton.cpp
+++ b/source/Core/Baton.cpp
@@ -18,7 +18,5 @@
using namespace lldb;
using namespace lldb_private;
-void
-Baton::GetDescription (Stream *s, lldb::DescriptionLevel level) const
-{
-}
+void UntypedBaton::GetDescription(Stream *s,
+ lldb::DescriptionLevel level) const {}
diff --git a/source/Core/Broadcaster.cpp b/source/Core/Broadcaster.cpp
index 30bc78b48220..d2cca7a2a654 100644
--- a/source/Core/Broadcaster.cpp
+++ b/source/Core/Broadcaster.cpp
@@ -13,571 +13,463 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Log.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/Listener.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
using namespace lldb;
using namespace lldb_private;
-Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name) :
- m_broadcaster_sp(new BroadcasterImpl(*this)),
- m_manager_sp(manager_sp),
- m_broadcaster_name(name)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf ("%p Broadcaster::Broadcaster(\"%s\")",
- static_cast<void*>(this), GetBroadcasterName().AsCString());
+Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name)
+ : m_broadcaster_sp(new BroadcasterImpl(*this)), m_manager_sp(manager_sp),
+ m_broadcaster_name(name) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("%p Broadcaster::Broadcaster(\"%s\")",
+ static_cast<void *>(this), GetBroadcasterName().AsCString());
}
Broadcaster::BroadcasterImpl::BroadcasterImpl(Broadcaster &broadcaster)
- : m_broadcaster(broadcaster), m_listeners(), m_listeners_mutex(), m_hijacking_listeners(), m_hijacking_masks()
-{
-}
+ : m_broadcaster(broadcaster), m_listeners(), m_listeners_mutex(),
+ m_hijacking_listeners(), m_hijacking_masks() {}
-Broadcaster::~Broadcaster()
-{
- Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- if (log)
- log->Printf ("%p Broadcaster::~Broadcaster(\"%s\")",
- static_cast<void*>(this), m_broadcaster_name.AsCString());
+Broadcaster::~Broadcaster() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log)
+ log->Printf("%p Broadcaster::~Broadcaster(\"%s\")",
+ static_cast<void *>(this), m_broadcaster_name.AsCString());
- Clear();
+ Clear();
}
-void
-Broadcaster::CheckInWithManager ()
-{
- if (m_manager_sp)
- {
- m_manager_sp->SignUpListenersForBroadcaster(*this);
- }
+void Broadcaster::CheckInWithManager() {
+ if (m_manager_sp) {
+ m_manager_sp->SignUpListenersForBroadcaster(*this);
+ }
}
-void
-Broadcaster::BroadcasterImpl::ListenerIterator (std::function <bool (const lldb::ListenerSP &listener_sp, uint32_t &event_mask)> const &callback)
-{
- // Private iterator that should be used by everyone except BroadcasterImpl::RemoveListener().
- // We have weak pointers to our listeners which means that at any point the listener can
- // expire which means we will need to take it out of our list. To take care of this, we
- // iterate and check that the weak pointer can be made into a valid shared pointer before
- // we call the callback. If the weak pointer has expired, we remove it from our list.
- collection::iterator pos = m_listeners.begin();
- while (pos != m_listeners.end())
- {
- lldb::ListenerSP curr_listener_sp(pos->first.lock());
- if (curr_listener_sp)
- {
- if (callback(curr_listener_sp, pos->second))
- ++pos; // Keep iterating
- else
- return; // Done iterating
- }
- else
- {
- // The listener has been expired. Remove this entry.
- pos = m_listeners.erase(pos);
- }
- }
+llvm::SmallVector<std::pair<ListenerSP, uint32_t &>, 4>
+Broadcaster::BroadcasterImpl::GetListeners() {
+ llvm::SmallVector<std::pair<ListenerSP, uint32_t &>, 4> listeners;
+ listeners.reserve(m_listeners.size());
+
+ for (auto it = m_listeners.begin(); it != m_listeners.end();) {
+ lldb::ListenerSP curr_listener_sp(it->first.lock());
+ if (curr_listener_sp && it->second) {
+ listeners.emplace_back(std::move(curr_listener_sp), it->second);
+ ++it;
+ } else
+ it = m_listeners.erase(it);
+ }
+
+ return listeners;
}
-void
-Broadcaster::BroadcasterImpl::Clear()
-{
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
-
- // Make sure the listener forgets about this broadcaster. We do
- // this in the broadcaster in case the broadcaster object initiates
- // the removal.
-
- ListenerIterator([this](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
- curr_listener_sp->BroadcasterWillDestruct (&m_broadcaster);
- return true; // Keep iterating
- });
-
- m_listeners.clear();
+void Broadcaster::BroadcasterImpl::Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ // Make sure the listener forgets about this broadcaster. We do
+ // this in the broadcaster in case the broadcaster object initiates
+ // the removal.
+ for (auto &pair : GetListeners())
+ pair.first->BroadcasterWillDestruct(&m_broadcaster);
+
+ m_listeners.clear();
}
-Broadcaster *
-Broadcaster::BroadcasterImpl::GetBroadcaster()
-{
- return &m_broadcaster;
+Broadcaster *Broadcaster::BroadcasterImpl::GetBroadcaster() {
+ return &m_broadcaster;
}
-bool
-Broadcaster::BroadcasterImpl::GetEventNames (Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const
-{
- uint32_t num_names_added = 0;
- if (event_mask && !m_event_names.empty())
- {
- event_names_map::const_iterator end = m_event_names.end();
- for (uint32_t bit=1u, mask=event_mask; mask != 0 && bit != 0; bit <<= 1, mask >>= 1)
- {
- if (mask & 1)
- {
- event_names_map::const_iterator pos = m_event_names.find(bit);
- if (pos != end)
- {
- if (num_names_added > 0)
- s.PutCString(", ");
-
- if (prefix_with_broadcaster_name)
- {
- s.PutCString (GetBroadcasterName());
- s.PutChar('.');
- }
- s.PutCString(pos->second.c_str());
- ++num_names_added;
- }
- }
+bool Broadcaster::BroadcasterImpl::GetEventNames(
+ Stream &s, uint32_t event_mask, bool prefix_with_broadcaster_name) const {
+ uint32_t num_names_added = 0;
+ if (event_mask && !m_event_names.empty()) {
+ event_names_map::const_iterator end = m_event_names.end();
+ for (uint32_t bit = 1u, mask = event_mask; mask != 0 && bit != 0;
+ bit <<= 1, mask >>= 1) {
+ if (mask & 1) {
+ event_names_map::const_iterator pos = m_event_names.find(bit);
+ if (pos != end) {
+ if (num_names_added > 0)
+ s.PutCString(", ");
+
+ if (prefix_with_broadcaster_name) {
+ s.PutCString(GetBroadcasterName());
+ s.PutChar('.');
+ }
+ s.PutCString(pos->second);
+ ++num_names_added;
}
+ }
}
- return num_names_added > 0;
+ }
+ return num_names_added > 0;
}
-void
-Broadcaster::AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events)
-{
-}
+void Broadcaster::AddInitialEventsToListener(
+ const lldb::ListenerSP &listener_sp, uint32_t requested_events) {}
uint32_t
-Broadcaster::BroadcasterImpl::AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
-{
- if (!listener_sp)
- return 0;
+Broadcaster::BroadcasterImpl::AddListener(const lldb::ListenerSP &listener_sp,
+ uint32_t event_mask) {
+ if (!listener_sp)
+ return 0;
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- // See if we already have this listener, and if so, update its mask
+ // See if we already have this listener, and if so, update its mask
- bool handled = false;
+ bool handled = false;
- ListenerIterator([this, &listener_sp, &handled, event_mask](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
- if (curr_listener_sp == listener_sp)
- {
- handled = true;
- curr_event_mask |= event_mask;
- m_broadcaster.AddInitialEventsToListener (listener_sp, event_mask);
- return false; // Stop iterating
- }
- return true; // Keep iterating
- });
+ for (auto &pair : GetListeners()) {
+ if (pair.first == listener_sp) {
+ handled = true;
+ pair.second |= event_mask;
+ m_broadcaster.AddInitialEventsToListener(listener_sp, event_mask);
+ break;
+ }
+ }
- if (!handled)
- {
- // Grant a new listener the available event bits
- m_listeners.push_back(std::make_pair(lldb::ListenerWP(listener_sp), event_mask));
+ if (!handled) {
+ // Grant a new listener the available event bits
+ m_listeners.push_back(
+ std::make_pair(lldb::ListenerWP(listener_sp), event_mask));
- // Individual broadcasters decide whether they have outstanding data when a
- // listener attaches, and insert it into the listener with this method.
- m_broadcaster.AddInitialEventsToListener (listener_sp, event_mask);
- }
+ // Individual broadcasters decide whether they have outstanding data when a
+ // listener attaches, and insert it into the listener with this method.
+ m_broadcaster.AddInitialEventsToListener(listener_sp, event_mask);
+ }
- // Return the event bits that were granted to the listener
- return event_mask;
+ // Return the event bits that were granted to the listener
+ return event_mask;
}
-bool
-Broadcaster::BroadcasterImpl::EventTypeHasListeners (uint32_t event_type)
-{
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
-
- if (!m_hijacking_listeners.empty() && event_type & m_hijacking_masks.back())
- return true;
-
- if (m_listeners.empty())
- return false;
+bool Broadcaster::BroadcasterImpl::EventTypeHasListeners(uint32_t event_type) {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- bool result = false;
- ListenerIterator([this, event_type, &result](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
+ if (!m_hijacking_listeners.empty() && event_type & m_hijacking_masks.back())
+ return true;
- if (curr_event_mask & event_type)
- {
- result = true;
- return false; // Stop iterating
- }
- else
- {
- return true; // Keep iterating
- }
- });
- return result;
+ for (auto &pair : GetListeners()) {
+ if (pair.second & event_type)
+ return true;
+ }
+ return false;
}
-bool
-Broadcaster::BroadcasterImpl::RemoveListener (lldb_private::Listener *listener, uint32_t event_mask)
-{
- if (listener)
- {
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- collection::iterator pos = m_listeners.begin();
- // See if we already have this listener, and if so, update its mask
- while (pos != m_listeners.end())
- {
- lldb::ListenerSP curr_listener_sp(pos->first.lock());
- if (curr_listener_sp)
- {
- if (curr_listener_sp.get() == listener)
- {
- // Relinquish all event bits in "event_mask"
- pos->second &= ~event_mask;
- // If all bits have been relinquished then remove this listener
- if (pos->second == 0)
- m_listeners.erase (pos);
- return true;
- }
- ++pos;
- }
- else
- {
- // The listener has been destroyed since we couldn't turn the std::weak_ptr
- // into a valid shared pointer, so we can remove it.
- pos = m_listeners.erase (pos);
- }
- }
- }
+bool Broadcaster::BroadcasterImpl::RemoveListener(
+ lldb_private::Listener *listener, uint32_t event_mask) {
+ if (!listener)
return false;
+
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+ for (auto &pair : GetListeners()) {
+ if (pair.first.get() == listener) {
+ pair.second &= ~event_mask;
+ return true;
+ }
+ }
+ return false;
}
-bool
-Broadcaster::BroadcasterImpl::RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
-{
- return RemoveListener (listener_sp.get(), event_mask);
+bool Broadcaster::BroadcasterImpl::RemoveListener(
+ const lldb::ListenerSP &listener_sp, uint32_t event_mask) {
+ return RemoveListener(listener_sp.get(), event_mask);
}
-void
-Broadcaster::BroadcasterImpl::BroadcastEvent (EventSP &event_sp)
-{
- return PrivateBroadcastEvent (event_sp, false);
+void Broadcaster::BroadcasterImpl::BroadcastEvent(EventSP &event_sp) {
+ return PrivateBroadcastEvent(event_sp, false);
}
-void
-Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (EventSP &event_sp)
-{
- return PrivateBroadcastEvent (event_sp, true);
+void Broadcaster::BroadcasterImpl::BroadcastEventIfUnique(EventSP &event_sp) {
+ return PrivateBroadcastEvent(event_sp, true);
}
-void
-Broadcaster::BroadcasterImpl::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
-{
- // Can't add a nullptr event...
- if (!event_sp)
- return;
+void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp,
+ bool unique) {
+ // Can't add a nullptr event...
+ if (!event_sp)
+ return;
- // Update the broadcaster on this event
- event_sp->SetBroadcaster (&m_broadcaster);
+ // Update the broadcaster on this event
+ event_sp->SetBroadcaster(&m_broadcaster);
- const uint32_t event_type = event_sp->GetType();
+ const uint32_t event_type = event_sp->GetType();
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- ListenerSP hijacking_listener_sp;
+ ListenerSP hijacking_listener_sp;
- if (!m_hijacking_listeners.empty())
- {
- assert (!m_hijacking_masks.empty());
- hijacking_listener_sp = m_hijacking_listeners.back();
- if ((event_type & m_hijacking_masks.back()) == 0)
- hijacking_listener_sp.reset();
- }
+ if (!m_hijacking_listeners.empty()) {
+ assert(!m_hijacking_masks.empty());
+ hijacking_listener_sp = m_hijacking_listeners.back();
+ if ((event_type & m_hijacking_masks.back()) == 0)
+ hijacking_listener_sp.reset();
+ }
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log)
- {
- StreamString event_description;
- event_sp->Dump (&event_description);
- log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i) hijack = %p",
- static_cast<void*>(this), GetBroadcasterName(),
- event_description.GetData(), unique,
- static_cast<void*>(hijacking_listener_sp.get()));
- }
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log) {
+ StreamString event_description;
+ event_sp->Dump(&event_description);
+ log->Printf("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, "
+ "unique =%i) hijack = %p",
+ static_cast<void *>(this), GetBroadcasterName(),
+ event_description.GetData(), unique,
+ static_cast<void *>(hijacking_listener_sp.get()));
+ }
- if (hijacking_listener_sp)
- {
- if (unique && hijacking_listener_sp->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type))
- return;
- hijacking_listener_sp->AddEvent (event_sp);
- }
- else
- {
+ if (hijacking_listener_sp) {
+ if (unique &&
+ hijacking_listener_sp->PeekAtNextEventForBroadcasterWithType(
+ &m_broadcaster, event_type))
+ return;
+ hijacking_listener_sp->AddEvent(event_sp);
+ } else {
+ for (auto &pair : GetListeners()) {
+ if (!(pair.second & event_type))
+ continue;
+ if (unique &&
+ pair.first->PeekAtNextEventForBroadcasterWithType(&m_broadcaster,
+ event_type))
+ continue;
- ListenerIterator([this, unique, event_type, &event_sp](const lldb::ListenerSP &curr_listener_sp, uint32_t &curr_event_mask) -> bool {
-
- if (event_type & curr_event_mask)
- {
- if (!unique || curr_listener_sp->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type) == nullptr)
- curr_listener_sp->AddEvent (event_sp);
- }
- return true; // Keep iterating
- });
+ pair.first->AddEvent(event_sp);
}
+ }
}
-void
-Broadcaster::BroadcasterImpl::BroadcastEvent (uint32_t event_type, EventData *event_data)
-{
- EventSP event_sp (new Event (event_type, event_data));
- PrivateBroadcastEvent (event_sp, false);
+void Broadcaster::BroadcasterImpl::BroadcastEvent(uint32_t event_type,
+ EventData *event_data) {
+ EventSP event_sp(new Event(event_type, event_data));
+ PrivateBroadcastEvent(event_sp, false);
}
-void
-Broadcaster::BroadcasterImpl::BroadcastEvent (uint32_t event_type, const lldb::EventDataSP &event_data_sp)
-{
- EventSP event_sp (new Event (event_type, event_data_sp));
- PrivateBroadcastEvent (event_sp, false);
+void Broadcaster::BroadcasterImpl::BroadcastEvent(
+ uint32_t event_type, const lldb::EventDataSP &event_data_sp) {
+ EventSP event_sp(new Event(event_type, event_data_sp));
+ PrivateBroadcastEvent(event_sp, false);
}
-void
-Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (uint32_t event_type, EventData *event_data)
-{
- EventSP event_sp (new Event (event_type, event_data));
- PrivateBroadcastEvent (event_sp, true);
+void Broadcaster::BroadcasterImpl::BroadcastEventIfUnique(
+ uint32_t event_type, EventData *event_data) {
+ EventSP event_sp(new Event(event_type, event_data));
+ PrivateBroadcastEvent(event_sp, true);
}
-bool
-Broadcaster::BroadcasterImpl::HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
-{
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log)
- log->Printf ("%p Broadcaster(\"%s\")::HijackBroadcaster (listener(\"%s\")=%p)",
- static_cast<void*>(this), GetBroadcasterName(),
- listener_sp->m_name.c_str(), static_cast<void*>(listener_sp.get()));
- m_hijacking_listeners.push_back(listener_sp);
- m_hijacking_masks.push_back(event_mask);
- return true;
+bool Broadcaster::BroadcasterImpl::HijackBroadcaster(
+ const lldb::ListenerSP &listener_sp, uint32_t event_mask) {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log)
+ log->Printf(
+ "%p Broadcaster(\"%s\")::HijackBroadcaster (listener(\"%s\")=%p)",
+ static_cast<void *>(this), GetBroadcasterName(),
+ listener_sp->m_name.c_str(), static_cast<void *>(listener_sp.get()));
+ m_hijacking_listeners.push_back(listener_sp);
+ m_hijacking_masks.push_back(event_mask);
+ return true;
}
-bool
-Broadcaster::BroadcasterImpl::IsHijackedForEvent (uint32_t event_mask)
-{
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+bool Broadcaster::BroadcasterImpl::IsHijackedForEvent(uint32_t event_mask) {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- if (!m_hijacking_listeners.empty())
- return (event_mask & m_hijacking_masks.back()) != 0;
- return false;
+ if (!m_hijacking_listeners.empty())
+ return (event_mask & m_hijacking_masks.back()) != 0;
+ return false;
}
-const char *
-Broadcaster::BroadcasterImpl::GetHijackingListenerName()
-{
- if (m_hijacking_listeners.size())
- {
- return m_hijacking_listeners.back()->GetName();
- }
- else
- {
- return nullptr;
- }
+const char *Broadcaster::BroadcasterImpl::GetHijackingListenerName() {
+ if (m_hijacking_listeners.size()) {
+ return m_hijacking_listeners.back()->GetName();
+ } else {
+ return nullptr;
+ }
}
-void
-Broadcaster::BroadcasterImpl::RestoreBroadcaster ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
-
- if (!m_hijacking_listeners.empty())
- {
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log)
- {
- ListenerSP listener_sp = m_hijacking_listeners.back();
- log->Printf ("%p Broadcaster(\"%s\")::RestoreBroadcaster (about to pop listener(\"%s\")=%p)",
- static_cast<void*>(this),
- GetBroadcasterName(),
- listener_sp->m_name.c_str(), static_cast<void*>(listener_sp.get()));
- }
- m_hijacking_listeners.pop_back();
+void Broadcaster::BroadcasterImpl::RestoreBroadcaster() {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ if (!m_hijacking_listeners.empty()) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log) {
+ ListenerSP listener_sp = m_hijacking_listeners.back();
+ log->Printf("%p Broadcaster(\"%s\")::RestoreBroadcaster (about to pop "
+ "listener(\"%s\")=%p)",
+ static_cast<void *>(this), GetBroadcasterName(),
+ listener_sp->m_name.c_str(),
+ static_cast<void *>(listener_sp.get()));
}
- if (!m_hijacking_masks.empty())
- m_hijacking_masks.pop_back();
+ m_hijacking_listeners.pop_back();
+ }
+ if (!m_hijacking_masks.empty())
+ m_hijacking_masks.pop_back();
}
-ConstString &
-Broadcaster::GetBroadcasterClass() const
-{
- static ConstString class_name ("lldb.anonymous");
- return class_name;
+ConstString &Broadcaster::GetBroadcasterClass() const {
+ static ConstString class_name("lldb.anonymous");
+ return class_name;
}
BroadcastEventSpec::BroadcastEventSpec(const BroadcastEventSpec &rhs) = default;
-bool
-BroadcastEventSpec::operator< (const BroadcastEventSpec &rhs) const
-{
- if (GetBroadcasterClass() == rhs.GetBroadcasterClass())
- {
- return GetEventBits() < rhs.GetEventBits();
- }
- else
- {
- return GetBroadcasterClass() < rhs.GetBroadcasterClass();
- }
+bool BroadcastEventSpec::operator<(const BroadcastEventSpec &rhs) const {
+ if (GetBroadcasterClass() == rhs.GetBroadcasterClass()) {
+ return GetEventBits() < rhs.GetEventBits();
+ } else {
+ return GetBroadcasterClass() < rhs.GetBroadcasterClass();
+ }
}
-BroadcastEventSpec &
-BroadcastEventSpec::operator=(const BroadcastEventSpec &rhs) = default;
+BroadcastEventSpec &BroadcastEventSpec::
+operator=(const BroadcastEventSpec &rhs) = default;
+
+BroadcasterManager::BroadcasterManager() : m_manager_mutex() {}
-BroadcasterManager::BroadcasterManager() : m_manager_mutex()
-{
+lldb::BroadcasterManagerSP BroadcasterManager::MakeBroadcasterManager() {
+ return BroadcasterManagerSP(new BroadcasterManager());
}
-lldb::BroadcasterManagerSP
-BroadcasterManager::MakeBroadcasterManager()
-{
- return BroadcasterManagerSP(new BroadcasterManager());
+uint32_t BroadcasterManager::RegisterListenerForEvents(
+ const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+
+ collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
+ uint32_t available_bits = event_spec.GetEventBits();
+
+ while (iter != end_iter &&
+ (iter = find_if(iter, end_iter,
+ BroadcasterClassMatches(
+ event_spec.GetBroadcasterClass()))) != end_iter) {
+ available_bits &= ~((*iter).first.GetEventBits());
+ iter++;
+ }
+
+ if (available_bits != 0) {
+ m_event_map.insert(event_listener_key(
+ BroadcastEventSpec(event_spec.GetBroadcasterClass(), available_bits),
+ listener_sp));
+ m_listeners.insert(listener_sp);
+ }
+
+ return available_bits;
}
-uint32_t
-BroadcasterManager::RegisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec)
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
-
- collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
- uint32_t available_bits = event_spec.GetEventBits();
-
- while (iter != end_iter
- && (iter = find_if (iter, end_iter, BroadcasterClassMatches(event_spec.GetBroadcasterClass()))) != end_iter)
- {
- available_bits &= ~((*iter).first.GetEventBits());
- iter++;
- }
-
- if (available_bits != 0)
- {
- m_event_map.insert (event_listener_key (BroadcastEventSpec (event_spec.GetBroadcasterClass(), available_bits), listener_sp));
- m_listeners.insert(listener_sp);
+bool BroadcasterManager::UnregisterListenerForEvents(
+ const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ bool removed_some = false;
+
+ if (m_listeners.erase(listener_sp) == 0)
+ return false;
+
+ ListenerMatchesAndSharedBits predicate(event_spec, listener_sp);
+ std::vector<BroadcastEventSpec> to_be_readded;
+ uint32_t event_bits_to_remove = event_spec.GetEventBits();
+
+ // Go through the map and delete the exact matches, and build a list of
+ // matches that weren't exact to re-add:
+ while (true) {
+ collection::iterator iter, end_iter = m_event_map.end();
+ iter = find_if(m_event_map.begin(), end_iter, predicate);
+ if (iter == end_iter) {
+ break;
+ } else {
+ uint32_t iter_event_bits = (*iter).first.GetEventBits();
+ removed_some = true;
+
+ if (event_bits_to_remove != iter_event_bits) {
+ uint32_t new_event_bits = iter_event_bits & ~event_bits_to_remove;
+ to_be_readded.push_back(BroadcastEventSpec(
+ event_spec.GetBroadcasterClass(), new_event_bits));
+ }
+ m_event_map.erase(iter);
}
-
- return available_bits;
+ }
+
+ // Okay now add back the bits that weren't completely removed:
+ for (size_t i = 0; i < to_be_readded.size(); i++) {
+ m_event_map.insert(event_listener_key(to_be_readded[i], listener_sp));
+ }
+
+ return removed_some;
}
-bool
-BroadcasterManager::UnregisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec)
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
- bool removed_some = false;
-
- if (m_listeners.erase(listener_sp) == 0)
- return false;
-
- ListenerMatchesAndSharedBits predicate (event_spec, listener_sp);
- std::vector<BroadcastEventSpec> to_be_readded;
- uint32_t event_bits_to_remove = event_spec.GetEventBits();
-
- // Go through the map and delete the exact matches, and build a list of matches that weren't exact to re-add:
- while (true)
- {
- collection::iterator iter, end_iter = m_event_map.end();
- iter = find_if (m_event_map.begin(), end_iter, predicate);
- if (iter == end_iter)
- {
- break;
- }
- else
- {
- uint32_t iter_event_bits = (*iter).first.GetEventBits();
- removed_some = true;
-
- if (event_bits_to_remove != iter_event_bits)
- {
- uint32_t new_event_bits = iter_event_bits & ~event_bits_to_remove;
- to_be_readded.push_back(BroadcastEventSpec (event_spec.GetBroadcasterClass(), new_event_bits));
- }
- m_event_map.erase (iter);
- }
- }
-
- // Okay now add back the bits that weren't completely removed:
- for (size_t i = 0; i < to_be_readded.size(); i++)
- {
- m_event_map.insert (event_listener_key (to_be_readded[i], listener_sp));
- }
-
- return removed_some;
+ListenerSP BroadcasterManager::GetListenerForEventSpec(
+ BroadcastEventSpec event_spec) const {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+
+ collection::const_iterator iter, end_iter = m_event_map.end();
+ iter = find_if(m_event_map.begin(), end_iter,
+ BroadcastEventSpecMatches(event_spec));
+ if (iter != end_iter)
+ return (*iter).second;
+ else
+ return nullptr;
}
-
-ListenerSP
-BroadcasterManager::GetListenerForEventSpec (BroadcastEventSpec event_spec) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
-
- collection::const_iterator iter, end_iter = m_event_map.end();
- iter = find_if (m_event_map.begin(), end_iter, BroadcastEventSpecMatches (event_spec));
- if (iter != end_iter)
- return (*iter).second;
+
+void BroadcasterManager::RemoveListener(Listener *listener) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ ListenerMatchesPointer predicate(listener);
+ listener_collection::iterator iter = m_listeners.begin(),
+ end_iter = m_listeners.end();
+
+ std::find_if(iter, end_iter, predicate);
+ if (iter != end_iter)
+ m_listeners.erase(iter);
+
+ while (true) {
+ collection::iterator iter, end_iter = m_event_map.end();
+ iter = find_if(m_event_map.begin(), end_iter, predicate);
+ if (iter == end_iter)
+ break;
else
- return nullptr;
+ m_event_map.erase(iter);
+ }
}
-void
-BroadcasterManager::RemoveListener(Listener *listener)
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
- ListenerMatchesPointer predicate (listener);
- listener_collection::iterator iter = m_listeners.begin(), end_iter = m_listeners.end();
-
- std::find_if (iter, end_iter, predicate);
- if (iter != end_iter)
- m_listeners.erase(iter);
-
- while (true)
- {
- collection::iterator iter, end_iter = m_event_map.end();
- iter = find_if (m_event_map.begin(), end_iter, predicate);
- if (iter == end_iter)
- break;
- else
- m_event_map.erase(iter);
- }
-}
+void BroadcasterManager::RemoveListener(const lldb::ListenerSP &listener_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ ListenerMatches predicate(listener_sp);
-void
-BroadcasterManager::RemoveListener (const lldb::ListenerSP &listener_sp)
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
- ListenerMatches predicate (listener_sp);
-
- if (m_listeners.erase (listener_sp) == 0)
- return;
-
- while (true)
- {
- collection::iterator iter, end_iter = m_event_map.end();
- iter = find_if (m_event_map.begin(), end_iter, predicate);
- if (iter == end_iter)
- break;
- else
- m_event_map.erase(iter);
- }
+ if (m_listeners.erase(listener_sp) == 0)
+ return;
+
+ while (true) {
+ collection::iterator iter, end_iter = m_event_map.end();
+ iter = find_if(m_event_map.begin(), end_iter, predicate);
+ if (iter == end_iter)
+ break;
+ else
+ m_event_map.erase(iter);
+ }
}
-
-void
-BroadcasterManager::SignUpListenersForBroadcaster (Broadcaster &broadcaster)
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
-
- collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
-
- while (iter != end_iter
- && (iter = find_if (iter, end_iter, BroadcasterClassMatches(broadcaster.GetBroadcasterClass()))) != end_iter)
- {
- (*iter).second->StartListeningForEvents (&broadcaster, (*iter).first.GetEventBits());
- iter++;
- }
+
+void BroadcasterManager::SignUpListenersForBroadcaster(
+ Broadcaster &broadcaster) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+
+ collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
+
+ while (iter != end_iter &&
+ (iter = find_if(iter, end_iter,
+ BroadcasterClassMatches(
+ broadcaster.GetBroadcasterClass()))) != end_iter) {
+ (*iter).second->StartListeningForEvents(&broadcaster,
+ (*iter).first.GetEventBits());
+ iter++;
+ }
}
-void
-BroadcasterManager::Clear ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
- listener_collection::iterator end_iter = m_listeners.end();
-
- for (listener_collection::iterator iter = m_listeners.begin(); iter != end_iter; iter++)
- (*iter)->BroadcasterManagerWillDestruct(this->shared_from_this());
- m_listeners.clear();
- m_event_map.clear();
+void BroadcasterManager::Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ listener_collection::iterator end_iter = m_listeners.end();
+
+ for (listener_collection::iterator iter = m_listeners.begin();
+ iter != end_iter; iter++)
+ (*iter)->BroadcasterManagerWillDestruct(this->shared_from_this());
+ m_listeners.clear();
+ m_event_map.clear();
}
diff --git a/source/Core/CMakeLists.txt b/source/Core/CMakeLists.txt
index b975fb88e784..2bbe7455418a 100644
--- a/source/Core/CMakeLists.txt
+++ b/source/Core/CMakeLists.txt
@@ -9,10 +9,7 @@ add_lldb_library(lldbCore
Broadcaster.cpp
Communication.cpp
Connection.cpp
- ConnectionMachPort.cpp
- ConnectionSharedMemory.cpp
ConstString.cpp
- CxaDemangle.cpp
DataBufferHeap.cpp
DataBufferMemoryMap.cpp
DataEncoder.cpp
diff --git a/source/Core/Communication.cpp b/source/Core/Communication.cpp
index f1dcb95e8af0..3d3abea62489 100644
--- a/source/Core/Communication.cpp
+++ b/source/Core/Communication.cpp
@@ -15,10 +15,10 @@
// Project includes
#include "lldb/Core/Communication.h"
#include "lldb/Core/Connection.h"
+#include "lldb/Core/Event.h"
#include "lldb/Core/Listener.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Timer.h"
-#include "lldb/Core/Event.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ThreadLauncher.h"
@@ -26,445 +26,392 @@
using namespace lldb;
using namespace lldb_private;
-ConstString &
-Communication::GetStaticBroadcasterClass ()
-{
- static ConstString class_name ("lldb.communication");
- return class_name;
+ConstString &Communication::GetStaticBroadcasterClass() {
+ static ConstString class_name("lldb.communication");
+ return class_name;
}
Communication::Communication(const char *name)
- : Broadcaster(nullptr, name),
- m_connection_sp(),
- m_read_thread_enabled(false),
- m_read_thread_did_exit(false),
- m_bytes(),
- m_bytes_mutex(),
- m_write_mutex(),
- m_synchronize_mutex(),
- m_callback(nullptr),
- m_callback_baton(nullptr),
- m_close_on_eof(true)
+ : Broadcaster(nullptr, name), m_connection_sp(),
+ m_read_thread_enabled(false), m_read_thread_did_exit(false), m_bytes(),
+ m_bytes_mutex(), m_write_mutex(), m_synchronize_mutex(),
+ m_callback(nullptr), m_callback_baton(nullptr), m_close_on_eof(true)
{
- lldb_private::LogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Communication (name = %s)", this, name);
-
- SetEventName(eBroadcastBitDisconnected, "disconnected");
- SetEventName(eBroadcastBitReadThreadGotBytes, "got bytes");
- SetEventName(eBroadcastBitReadThreadDidExit, "read thread did exit");
- SetEventName(eBroadcastBitReadThreadShouldExit, "read thread should exit");
- SetEventName(eBroadcastBitPacketAvailable, "packet available");
- SetEventName(eBroadcastBitNoMorePendingInput, "no more pending input");
-
- CheckInWithManager();
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::Communication (name = %s)", this, name);
+
+ SetEventName(eBroadcastBitDisconnected, "disconnected");
+ SetEventName(eBroadcastBitReadThreadGotBytes, "got bytes");
+ SetEventName(eBroadcastBitReadThreadDidExit, "read thread did exit");
+ SetEventName(eBroadcastBitReadThreadShouldExit, "read thread should exit");
+ SetEventName(eBroadcastBitPacketAvailable, "packet available");
+ SetEventName(eBroadcastBitNoMorePendingInput, "no more pending input");
+
+ CheckInWithManager();
}
-Communication::~Communication()
-{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::~Communication (name = %s)",
- this, GetBroadcasterName().AsCString());
- Clear();
+Communication::~Communication() {
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::~Communication (name = %s)", this,
+ GetBroadcasterName().AsCString());
+ Clear();
}
-void
-Communication::Clear()
-{
- SetReadThreadBytesReceivedCallback(nullptr, nullptr);
- Disconnect(nullptr);
- StopReadThread(nullptr);
+void Communication::Clear() {
+ SetReadThreadBytesReceivedCallback(nullptr, nullptr);
+ Disconnect(nullptr);
+ StopReadThread(nullptr);
}
-ConnectionStatus
-Communication::Connect (const char *url, Error *error_ptr)
-{
- Clear();
+ConnectionStatus Communication::Connect(const char *url, Error *error_ptr) {
+ Clear();
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url);
+ lldb_private::LogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::Connect (url = %s)",
+ this, url);
- lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp)
- return connection_sp->Connect (url, error_ptr);
- if (error_ptr)
- error_ptr->SetErrorString("Invalid connection.");
- return eConnectionStatusNoConnection;
+ lldb::ConnectionSP connection_sp(m_connection_sp);
+ if (connection_sp)
+ return connection_sp->Connect(url, error_ptr);
+ if (error_ptr)
+ error_ptr->SetErrorString("Invalid connection.");
+ return eConnectionStatusNoConnection;
}
-ConnectionStatus
-Communication::Disconnect (Error *error_ptr)
-{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Disconnect ()", this);
-
- lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp)
- {
- ConnectionStatus status = connection_sp->Disconnect (error_ptr);
- // We currently don't protect connection_sp with any mutex for
- // multi-threaded environments. So lets not nuke our connection class
- // without putting some multi-threaded protections in. We also probably
- // don't want to pay for the overhead it might cause if every time we
- // access the connection we have to take a lock.
- //
- // This unique pointer will cleanup after itself when this object goes away,
- // so there is no need to currently have it destroy itself immediately
- // upon disconnnect.
- //connection_sp.reset();
- return status;
- }
- return eConnectionStatusNoConnection;
+ConnectionStatus Communication::Disconnect(Error *error_ptr) {
+ lldb_private::LogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::Disconnect ()", this);
+
+ lldb::ConnectionSP connection_sp(m_connection_sp);
+ if (connection_sp) {
+ ConnectionStatus status = connection_sp->Disconnect(error_ptr);
+ // We currently don't protect connection_sp with any mutex for
+ // multi-threaded environments. So lets not nuke our connection class
+ // without putting some multi-threaded protections in. We also probably
+ // don't want to pay for the overhead it might cause if every time we
+ // access the connection we have to take a lock.
+ //
+ // This unique pointer will cleanup after itself when this object goes away,
+ // so there is no need to currently have it destroy itself immediately
+ // upon disconnnect.
+ // connection_sp.reset();
+ return status;
+ }
+ return eConnectionStatusNoConnection;
}
-bool
-Communication::IsConnected () const
-{
- lldb::ConnectionSP connection_sp(m_connection_sp);
- return (connection_sp ? connection_sp->IsConnected() : false);
+bool Communication::IsConnected() const {
+ lldb::ConnectionSP connection_sp(m_connection_sp);
+ return (connection_sp ? connection_sp->IsConnected() : false);
}
-bool
-Communication::HasConnection () const
-{
- return m_connection_sp.get() != nullptr;
+bool Communication::HasConnection() const {
+ return m_connection_sp.get() != nullptr;
}
-size_t
-Communication::Read (void *dst, size_t dst_len, uint32_t timeout_usec, ConnectionStatus &status, Error *error_ptr)
-{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Read (dst = %p, dst_len = %" PRIu64 ", timeout = %u usec) connection = %p",
- this,
- dst,
- (uint64_t)dst_len,
- timeout_usec,
- m_connection_sp.get());
-
- if (m_read_thread_enabled)
- {
- // We have a dedicated read thread that is getting data for us
- size_t cached_bytes = GetCachedBytes (dst, dst_len);
- if (cached_bytes > 0 || timeout_usec == 0)
- {
- status = eConnectionStatusSuccess;
- return cached_bytes;
- }
-
- if (!m_connection_sp)
- {
- if (error_ptr)
- error_ptr->SetErrorString("Invalid connection.");
- status = eConnectionStatusNoConnection;
- return 0;
- }
- // Set the timeout appropriately
- TimeValue timeout_time;
- if (timeout_usec != UINT32_MAX)
- {
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithMicroSeconds (timeout_usec);
- }
-
- ListenerSP listener_sp(Listener::MakeListener("Communication::Read"));
- listener_sp->StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
- EventSP event_sp;
- while (listener_sp->WaitForEvent (timeout_time.IsValid() ? &timeout_time : nullptr, event_sp))
- {
- const uint32_t event_type = event_sp->GetType();
- if (event_type & eBroadcastBitReadThreadGotBytes)
- {
- return GetCachedBytes (dst, dst_len);
- }
-
- if (event_type & eBroadcastBitReadThreadDidExit)
- {
- if (GetCloseOnEOF ())
- Disconnect(nullptr);
- break;
- }
- }
- return 0;
+size_t Communication::Read(void *dst, size_t dst_len,
+ const Timeout<std::micro> &timeout,
+ ConnectionStatus &status, Error *error_ptr) {
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::Read (dst = %p, dst_len = %" PRIu64
+ ", timeout = %u usec) connection = %p",
+ this, dst, (uint64_t)dst_len, timeout ? timeout->count() : -1,
+ m_connection_sp.get());
+
+ if (m_read_thread_enabled) {
+ // We have a dedicated read thread that is getting data for us
+ size_t cached_bytes = GetCachedBytes(dst, dst_len);
+ if (cached_bytes > 0 || (timeout && timeout->count() == 0)) {
+ status = eConnectionStatusSuccess;
+ return cached_bytes;
}
- // We aren't using a read thread, just read the data synchronously in this
- // thread.
- lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp)
- {
- return connection_sp->Read (dst, dst_len, timeout_usec, status, error_ptr);
+ if (!m_connection_sp) {
+ if (error_ptr)
+ error_ptr->SetErrorString("Invalid connection.");
+ status = eConnectionStatusNoConnection;
+ return 0;
}
- if (error_ptr)
- error_ptr->SetErrorString("Invalid connection.");
- status = eConnectionStatusNoConnection;
+ ListenerSP listener_sp(Listener::MakeListener("Communication::Read"));
+ listener_sp->StartListeningForEvents(
+ this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
+ EventSP event_sp;
+ while (listener_sp->GetEvent(event_sp, timeout)) {
+ const uint32_t event_type = event_sp->GetType();
+ if (event_type & eBroadcastBitReadThreadGotBytes) {
+ return GetCachedBytes(dst, dst_len);
+ }
+
+ if (event_type & eBroadcastBitReadThreadDidExit) {
+ if (GetCloseOnEOF())
+ Disconnect(nullptr);
+ break;
+ }
+ }
return 0;
+ }
+
+ // We aren't using a read thread, just read the data synchronously in this
+ // thread.
+ return ReadFromConnection(dst, dst_len, timeout, status, error_ptr);
}
-size_t
-Communication::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
-{
- lldb::ConnectionSP connection_sp (m_connection_sp);
+size_t Communication::Write(const void *src, size_t src_len,
+ ConnectionStatus &status, Error *error_ptr) {
+ lldb::ConnectionSP connection_sp(m_connection_sp);
- std::lock_guard<std::mutex> guard(m_write_mutex);
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Write (src = %p, src_len = %" PRIu64 ") connection = %p",
- this,
- src,
- (uint64_t)src_len,
- connection_sp.get());
+ std::lock_guard<std::mutex> guard(m_write_mutex);
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::Write (src = %p, src_len = %" PRIu64
+ ") connection = %p",
+ this, src, (uint64_t)src_len, connection_sp.get());
- if (connection_sp)
- return connection_sp->Write (src, src_len, status, error_ptr);
+ if (connection_sp)
+ return connection_sp->Write(src, src_len, status, error_ptr);
- if (error_ptr)
- error_ptr->SetErrorString("Invalid connection.");
- status = eConnectionStatusNoConnection;
- return 0;
+ if (error_ptr)
+ error_ptr->SetErrorString("Invalid connection.");
+ status = eConnectionStatusNoConnection;
+ return 0;
}
-bool
-Communication::StartReadThread (Error *error_ptr)
-{
- if (error_ptr)
- error_ptr->Clear();
+bool Communication::StartReadThread(Error *error_ptr) {
+ if (error_ptr)
+ error_ptr->Clear();
- if (m_read_thread.IsJoinable())
- return true;
+ if (m_read_thread.IsJoinable())
+ return true;
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::StartReadThread ()", this);
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_COMMUNICATION, "%p Communication::StartReadThread ()", this);
- char thread_name[1024];
- snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>", GetBroadcasterName().AsCString());
+ char thread_name[1024];
+ snprintf(thread_name, sizeof(thread_name), "<lldb.comm.%s>",
+ GetBroadcasterName().AsCString());
- m_read_thread_enabled = true;
- m_read_thread_did_exit = false;
- m_read_thread = ThreadLauncher::LaunchThread(thread_name, Communication::ReadThread, this, error_ptr);
- if (!m_read_thread.IsJoinable())
- m_read_thread_enabled = false;
- return m_read_thread_enabled;
+ m_read_thread_enabled = true;
+ m_read_thread_did_exit = false;
+ m_read_thread = ThreadLauncher::LaunchThread(
+ thread_name, Communication::ReadThread, this, error_ptr);
+ if (!m_read_thread.IsJoinable())
+ m_read_thread_enabled = false;
+ return m_read_thread_enabled;
}
-bool
-Communication::StopReadThread (Error *error_ptr)
-{
- if (!m_read_thread.IsJoinable())
- return true;
+bool Communication::StopReadThread(Error *error_ptr) {
+ if (!m_read_thread.IsJoinable())
+ return true;
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::StopReadThread ()", this);
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_COMMUNICATION, "%p Communication::StopReadThread ()", this);
- m_read_thread_enabled = false;
+ m_read_thread_enabled = false;
- BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr);
+ BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr);
- // error = m_read_thread.Cancel();
+ // error = m_read_thread.Cancel();
- Error error = m_read_thread.Join(nullptr);
- return error.Success();
+ Error error = m_read_thread.Join(nullptr);
+ return error.Success();
}
-bool
-Communication::JoinReadThread (Error *error_ptr)
-{
- if (!m_read_thread.IsJoinable())
- return true;
+bool Communication::JoinReadThread(Error *error_ptr) {
+ if (!m_read_thread.IsJoinable())
+ return true;
- Error error = m_read_thread.Join(nullptr);
- return error.Success();
+ Error error = m_read_thread.Join(nullptr);
+ return error.Success();
}
-size_t
-Communication::GetCachedBytes (void *dst, size_t dst_len)
-{
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
- if (!m_bytes.empty())
- {
- // If DST is nullptr and we have a thread, then return the number
- // of bytes that are available so the caller can call again
- if (dst == nullptr)
- return m_bytes.size();
+size_t Communication::GetCachedBytes(void *dst, size_t dst_len) {
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+ if (!m_bytes.empty()) {
+ // If DST is nullptr and we have a thread, then return the number
+ // of bytes that are available so the caller can call again
+ if (dst == nullptr)
+ return m_bytes.size();
- const size_t len = std::min<size_t>(dst_len, m_bytes.size());
+ const size_t len = std::min<size_t>(dst_len, m_bytes.size());
- ::memcpy (dst, m_bytes.c_str(), len);
- m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len);
+ ::memcpy(dst, m_bytes.c_str(), len);
+ m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len);
- return len;
- }
- return 0;
+ return len;
+ }
+ return 0;
}
-void
-Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status)
-{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)",
- this, bytes, (uint64_t)len, broadcast);
- if ((bytes == nullptr || len == 0)
- && (status != lldb::eConnectionStatusEndOfFile))
- return;
- if (m_callback)
- {
- // If the user registered a callback, then call it and do not broadcast
- m_callback (m_callback_baton, bytes, len);
- }
- else if (bytes != nullptr && len > 0)
- {
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
- m_bytes.append ((const char *)bytes, len);
- if (broadcast)
- BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes);
- }
+void Communication::AppendBytesToCache(const uint8_t *bytes, size_t len,
+ bool broadcast,
+ ConnectionStatus status) {
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64
+ ", broadcast = %i)",
+ this, bytes, (uint64_t)len, broadcast);
+ if ((bytes == nullptr || len == 0) &&
+ (status != lldb::eConnectionStatusEndOfFile))
+ return;
+ if (m_callback) {
+ // If the user registered a callback, then call it and do not broadcast
+ m_callback(m_callback_baton, bytes, len);
+ } else if (bytes != nullptr && len > 0) {
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+ m_bytes.append((const char *)bytes, len);
+ if (broadcast)
+ BroadcastEventIfUnique(eBroadcastBitReadThreadGotBytes);
+ }
}
-size_t
-Communication::ReadFromConnection (void *dst,
- size_t dst_len,
- uint32_t timeout_usec,
- ConnectionStatus &status,
- Error *error_ptr)
-{
- lldb::ConnectionSP connection_sp(m_connection_sp);
- return (connection_sp ? connection_sp->Read(dst, dst_len, timeout_usec, status, error_ptr) : 0);
+size_t Communication::ReadFromConnection(void *dst, size_t dst_len,
+ const Timeout<std::micro> &timeout,
+ ConnectionStatus &status,
+ Error *error_ptr) {
+ lldb::ConnectionSP connection_sp(m_connection_sp);
+ if (connection_sp)
+ return connection_sp->Read(dst, dst_len, timeout, status, error_ptr);
+
+ if (error_ptr)
+ error_ptr->SetErrorString("Invalid connection.");
+ status = eConnectionStatusNoConnection;
+ return 0;
}
-bool
-Communication::ReadThreadIsRunning ()
-{
- return m_read_thread_enabled;
-}
+bool Communication::ReadThreadIsRunning() { return m_read_thread_enabled; }
-lldb::thread_result_t
-Communication::ReadThread (lldb::thread_arg_t p)
-{
- Communication *comm = (Communication *)p;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION));
-
- if (log)
- log->Printf ("%p Communication::ReadThread () thread starting...", p);
-
- uint8_t buf[1024];
-
- Error error;
- ConnectionStatus status = eConnectionStatusSuccess;
- bool done = false;
- while (!done && comm->m_read_thread_enabled)
- {
- size_t bytes_read = comm->ReadFromConnection (buf, sizeof(buf), 5 * TimeValue::MicroSecPerSec, status, &error);
- if (bytes_read > 0)
- comm->AppendBytesToCache (buf, bytes_read, true, status);
- else if ((bytes_read == 0)
- && status == eConnectionStatusEndOfFile)
- {
- if (comm->GetCloseOnEOF ())
- comm->Disconnect ();
- comm->AppendBytesToCache (buf, bytes_read, true, status);
- }
-
- switch (status)
- {
- case eConnectionStatusSuccess:
- break;
-
- case eConnectionStatusEndOfFile:
- done = true;
- break;
- case eConnectionStatusError: // Check GetError() for details
- if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO)
- {
- // EIO on a pipe is usually caused by remote shutdown
- comm->Disconnect ();
- done = true;
- }
- if (log)
- error.LogIfError (log,
- "%p Communication::ReadFromConnection () => status = %s",
- p,
- Communication::ConnectionStatusAsCString (status));
- break;
- case eConnectionStatusInterrupted: // Synchronization signal from SynchronizeWithReadThread()
- // The connection returns eConnectionStatusInterrupted only when there is no
- // input pending to be read, so we can signal that.
- comm->BroadcastEvent (eBroadcastBitNoMorePendingInput);
- break;
- case eConnectionStatusNoConnection: // No connection
- case eConnectionStatusLostConnection: // Lost connection while connected to a valid connection
- done = true;
- LLVM_FALLTHROUGH;
- case eConnectionStatusTimedOut: // Request timed out
- if (log)
- error.LogIfError (log,
- "%p Communication::ReadFromConnection () => status = %s",
- p,
- Communication::ConnectionStatusAsCString (status));
- break;
- }
+lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) {
+ Communication *comm = (Communication *)p;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION));
+
+ if (log)
+ log->Printf("%p Communication::ReadThread () thread starting...", p);
+
+ uint8_t buf[1024];
+
+ Error error;
+ ConnectionStatus status = eConnectionStatusSuccess;
+ bool done = false;
+ while (!done && comm->m_read_thread_enabled) {
+ size_t bytes_read = comm->ReadFromConnection(
+ buf, sizeof(buf), std::chrono::seconds(5), status, &error);
+ if (bytes_read > 0)
+ comm->AppendBytesToCache(buf, bytes_read, true, status);
+ else if ((bytes_read == 0) && status == eConnectionStatusEndOfFile) {
+ if (comm->GetCloseOnEOF())
+ comm->Disconnect();
+ comm->AppendBytesToCache(buf, bytes_read, true, status);
}
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMUNICATION);
- if (log)
- log->Printf ("%p Communication::ReadThread () thread exiting...", p);
-
- comm->m_read_thread_did_exit = true;
- // Let clients know that this thread is exiting
- comm->BroadcastEvent (eBroadcastBitNoMorePendingInput);
- comm->BroadcastEvent (eBroadcastBitReadThreadDidExit);
- return NULL;
+
+ switch (status) {
+ case eConnectionStatusSuccess:
+ break;
+
+ case eConnectionStatusEndOfFile:
+ done = true;
+ break;
+ case eConnectionStatusError: // Check GetError() for details
+ if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) {
+ // EIO on a pipe is usually caused by remote shutdown
+ comm->Disconnect();
+ done = true;
+ }
+ if (log)
+ error.LogIfError(
+ log, "%p Communication::ReadFromConnection () => status = %s", p,
+ Communication::ConnectionStatusAsCString(status));
+ break;
+ case eConnectionStatusInterrupted: // Synchronization signal from
+ // SynchronizeWithReadThread()
+ // The connection returns eConnectionStatusInterrupted only when there is
+ // no
+ // input pending to be read, so we can signal that.
+ comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
+ break;
+ case eConnectionStatusNoConnection: // No connection
+ case eConnectionStatusLostConnection: // Lost connection while connected to
+ // a valid connection
+ done = true;
+ LLVM_FALLTHROUGH;
+ case eConnectionStatusTimedOut: // Request timed out
+ if (log)
+ error.LogIfError(
+ log, "%p Communication::ReadFromConnection () => status = %s", p,
+ Communication::ConnectionStatusAsCString(status));
+ break;
+ }
+ }
+ log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION);
+ if (log)
+ log->Printf("%p Communication::ReadThread () thread exiting...", p);
+
+ comm->m_read_thread_did_exit = true;
+ // Let clients know that this thread is exiting
+ comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
+ comm->BroadcastEvent(eBroadcastBitReadThreadDidExit);
+ return NULL;
}
-void
-Communication::SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback,
- void *callback_baton)
-{
- m_callback = callback;
- m_callback_baton = callback_baton;
+void Communication::SetReadThreadBytesReceivedCallback(
+ ReadThreadBytesReceived callback, void *callback_baton) {
+ m_callback = callback;
+ m_callback_baton = callback_baton;
}
-void
-Communication::SynchronizeWithReadThread ()
-{
- // Only one thread can do the synchronization dance at a time.
- std::lock_guard<std::mutex> guard(m_synchronize_mutex);
+void Communication::SynchronizeWithReadThread() {
+ // Only one thread can do the synchronization dance at a time.
+ std::lock_guard<std::mutex> guard(m_synchronize_mutex);
- // First start listening for the synchronization event.
- ListenerSP listener_sp(Listener::MakeListener("Communication::SyncronizeWithReadThread"));
- listener_sp->StartListeningForEvents(this, eBroadcastBitNoMorePendingInput);
+ // First start listening for the synchronization event.
+ ListenerSP listener_sp(
+ Listener::MakeListener("Communication::SyncronizeWithReadThread"));
+ listener_sp->StartListeningForEvents(this, eBroadcastBitNoMorePendingInput);
- // If the thread is not running, there is no point in synchronizing.
- if (!m_read_thread_enabled || m_read_thread_did_exit)
- return;
+ // If the thread is not running, there is no point in synchronizing.
+ if (!m_read_thread_enabled || m_read_thread_did_exit)
+ return;
- // Notify the read thread.
- m_connection_sp->InterruptRead();
+ // Notify the read thread.
+ m_connection_sp->InterruptRead();
- // Wait for the synchronization event.
- EventSP event_sp;
- listener_sp->WaitForEvent(nullptr, event_sp);
+ // Wait for the synchronization event.
+ EventSP event_sp;
+ listener_sp->GetEvent(event_sp, llvm::None);
}
-void
-Communication::SetConnection (Connection *connection)
-{
- Disconnect(nullptr);
- StopReadThread(nullptr);
- m_connection_sp.reset(connection);
+void Communication::SetConnection(Connection *connection) {
+ Disconnect(nullptr);
+ StopReadThread(nullptr);
+ m_connection_sp.reset(connection);
}
const char *
-Communication::ConnectionStatusAsCString (lldb::ConnectionStatus status)
-{
- switch (status)
- {
- case eConnectionStatusSuccess: return "success";
- case eConnectionStatusError: return "error";
- case eConnectionStatusTimedOut: return "timed out";
- case eConnectionStatusNoConnection: return "no connection";
- case eConnectionStatusLostConnection: return "lost connection";
- case eConnectionStatusEndOfFile: return "end of file";
- case eConnectionStatusInterrupted: return "interrupted";
- }
-
- static char unknown_state_string[64];
- snprintf(unknown_state_string, sizeof (unknown_state_string), "ConnectionStatus = %i", status);
- return unknown_state_string;
+Communication::ConnectionStatusAsCString(lldb::ConnectionStatus status) {
+ switch (status) {
+ case eConnectionStatusSuccess:
+ return "success";
+ case eConnectionStatusError:
+ return "error";
+ case eConnectionStatusTimedOut:
+ return "timed out";
+ case eConnectionStatusNoConnection:
+ return "no connection";
+ case eConnectionStatusLostConnection:
+ return "lost connection";
+ case eConnectionStatusEndOfFile:
+ return "end of file";
+ case eConnectionStatusInterrupted:
+ return "interrupted";
+ }
+
+ static char unknown_state_string[64];
+ snprintf(unknown_state_string, sizeof(unknown_state_string),
+ "ConnectionStatus = %i", status);
+ return unknown_state_string;
}
diff --git a/source/Core/Connection.cpp b/source/Core/Connection.cpp
index 3f740a1ed82a..1ae046b8a018 100644
--- a/source/Core/Connection.cpp
+++ b/source/Core/Connection.cpp
@@ -21,20 +21,14 @@
using namespace lldb_private;
-Connection::Connection ()
-{
-}
+Connection::Connection() {}
-Connection::~Connection ()
-{
-}
+Connection::~Connection() {}
-Connection *
-Connection::CreateDefaultConnection(const char *url)
-{
+Connection *Connection::CreateDefaultConnection(const char *url) {
#if defined(_WIN32)
- if (strstr(url, "file://") == url)
- return new ConnectionGenericFile();
+ if (strstr(url, "file://") == url)
+ return new ConnectionGenericFile();
#endif
- return new ConnectionFileDescriptor();
+ return new ConnectionFileDescriptor();
}
diff --git a/source/Core/ConnectionMachPort.cpp b/source/Core/ConnectionMachPort.cpp
deleted file mode 100644
index e04c48905570..000000000000
--- a/source/Core/ConnectionMachPort.cpp
+++ /dev/null
@@ -1,331 +0,0 @@
-//===-- ConnectionMachPort.cpp ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-#if defined(__APPLE__)
-
-#include "lldb/Core/ConnectionMachPort.h"
-
-// C Includes
-#include <mach/mach.h>
-#include <servers/bootstrap.h>
-
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
-#include "lldb/Core/Communication.h"
-#include "lldb/Core/Log.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-struct MessageType
-{
- mach_msg_header_t head;
- ConnectionMachPort::PayloadType payload;
-};
-
-
-
-ConnectionMachPort::ConnectionMachPort () :
- Connection(),
- m_task(mach_task_self()),
- m_port(MACH_PORT_TYPE_NONE)
-{
-}
-
-ConnectionMachPort::~ConnectionMachPort ()
-{
- Disconnect (NULL);
-}
-
-bool
-ConnectionMachPort::IsConnected () const
-{
- return m_port != MACH_PORT_TYPE_NONE;
-}
-
-ConnectionStatus
-ConnectionMachPort::Connect (const char *s, Error *error_ptr)
-{
- if (IsConnected())
- {
- if (error_ptr)
- error_ptr->SetErrorString ("already connected");
- return eConnectionStatusError;
- }
-
- if (s == NULL || s[0] == '\0')
- {
- if (error_ptr)
- error_ptr->SetErrorString ("empty connect URL");
- return eConnectionStatusError;
- }
-
- ConnectionStatus status = eConnectionStatusError;
-
- if (0 == strncmp (s, "bootstrap-checkin://", strlen("bootstrap-checkin://")))
- {
- s += strlen("bootstrap-checkin://");
-
- if (*s)
- {
- status = BootstrapCheckIn (s, error_ptr);
- }
- else
- {
- if (error_ptr)
- error_ptr->SetErrorString ("bootstrap port name is empty");
- }
- }
- else if (0 == strncmp (s, "bootstrap-lookup://", strlen("bootstrap-lookup://")))
- {
- s += strlen("bootstrap-lookup://");
- if (*s)
- {
- status = BootstrapLookup (s, error_ptr);
- }
- else
- {
- if (error_ptr)
- error_ptr->SetErrorString ("bootstrap port name is empty");
- }
- }
- else
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat ("unsupported connection URL: '%s'", s);
- }
-
-
- if (status == eConnectionStatusSuccess)
- {
- if (error_ptr)
- error_ptr->Clear();
- m_uri.assign(s);
- }
- else
- {
- Disconnect(NULL);
- }
-
- return status;
-}
-
-ConnectionStatus
-ConnectionMachPort::BootstrapCheckIn (const char *port, Error *error_ptr)
-{
- mach_port_t bootstrap_port = MACH_PORT_TYPE_NONE;
-
- /* Getting bootstrap server port */
- kern_return_t kret = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
- if (kret == KERN_SUCCESS)
- {
- name_t port_name;
- int len = snprintf(port_name, sizeof(port_name), "%s", port);
- if (static_cast<size_t>(len) < sizeof(port_name))
- {
- kret = ::bootstrap_check_in (bootstrap_port,
- port_name,
- &m_port);
- }
- else
- {
- Disconnect(NULL);
- if (error_ptr)
- error_ptr->SetErrorString ("bootstrap is too long");
- return eConnectionStatusError;
- }
- }
-
- if (kret != KERN_SUCCESS)
- {
- Disconnect(NULL);
- if (error_ptr)
- error_ptr->SetError (kret, eErrorTypeMachKernel);
- return eConnectionStatusError;
- }
- return eConnectionStatusSuccess;
-}
-
-lldb::ConnectionStatus
-ConnectionMachPort::BootstrapLookup (const char *port,
- Error *error_ptr)
-{
- name_t port_name;
-
- if (port && port[0])
- {
- if (static_cast<size_t>(::snprintf (port_name, sizeof (port_name), "%s", port)) >= sizeof (port_name))
- {
- if (error_ptr)
- error_ptr->SetErrorString ("port netname is too long");
- return eConnectionStatusError;
- }
- }
- else
- {
- if (error_ptr)
- error_ptr->SetErrorString ("empty port netname");
- return eConnectionStatusError;
- }
-
- mach_port_t bootstrap_port = MACH_PORT_TYPE_NONE;
-
- /* Getting bootstrap server port */
- kern_return_t kret = task_get_bootstrap_port(mach_task_self(), &bootstrap_port);
- if (kret == KERN_SUCCESS)
- {
- kret = ::bootstrap_look_up (bootstrap_port,
- port_name,
- &m_port);
- }
-
- if (kret != KERN_SUCCESS)
- {
- if (error_ptr)
- error_ptr->SetError (kret, eErrorTypeMachKernel);
- return eConnectionStatusError;
- }
-
- return eConnectionStatusSuccess;
-}
-
-ConnectionStatus
-ConnectionMachPort::Disconnect (Error *error_ptr)
-{
- kern_return_t kret;
-
- // TODO: verify if we need to netname_check_out for
- // either or both
- if (m_port != MACH_PORT_TYPE_NONE)
- {
- kret = ::mach_port_deallocate (m_task, m_port);
- if (error_ptr)
- error_ptr->SetError (kret, eErrorTypeMachKernel);
- m_port = MACH_PORT_TYPE_NONE;
- }
- m_uri.clear();
-
- return eConnectionStatusSuccess;
-}
-
-size_t
-ConnectionMachPort::Read (void *dst,
- size_t dst_len,
- uint32_t timeout_usec,
- ConnectionStatus &status,
- Error *error_ptr)
-{
- PayloadType payload;
-
- kern_return_t kret = Receive (payload);
- if (kret == KERN_SUCCESS)
- {
- memcpy (dst, payload.data, payload.data_length);
- status = eConnectionStatusSuccess;
- return payload.data_length;
- }
-
- if (error_ptr)
- error_ptr->SetError (kret, eErrorTypeMachKernel);
- status = eConnectionStatusError;
- return 0;
-}
-
-size_t
-ConnectionMachPort::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
-{
- PayloadType payload;
- payload.command = 0;
- payload.data_length = src_len;
- const size_t max_payload_size = sizeof(payload.data);
- if (src_len > max_payload_size)
- payload.data_length = max_payload_size;
- memcpy (payload.data, src, payload.data_length);
-
- if (Send (payload) == KERN_SUCCESS)
- {
- status = eConnectionStatusSuccess;
- return payload.data_length;
- }
- status = eConnectionStatusError;
- return 0;
-}
-
-std::string
-ConnectionMachPort::GetURI()
-{
- return m_uri;
-}
-
-ConnectionStatus
-ConnectionMachPort::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
-{
- return eConnectionStatusLostConnection;
-}
-
-kern_return_t
-ConnectionMachPort::Send (const PayloadType &payload)
-{
- struct MessageType message;
-
- /* (i) Form the message : */
-
- /* (i.a) Fill the header fields : */
- message.head.msgh_bits = MACH_MSGH_BITS_REMOTE (MACH_MSG_TYPE_MAKE_SEND) |
- MACH_MSGH_BITS_OTHER (MACH_MSGH_BITS_COMPLEX);
- message.head.msgh_size = sizeof(MessageType);
- message.head.msgh_local_port = MACH_PORT_NULL;
- message.head.msgh_remote_port = m_port;
-
- /* (i.b) Explain the message type ( an integer ) */
- // message.type.msgt_name = MACH_MSG_TYPE_INTEGER_32;
- // message.type.msgt_size = 32;
- // message.type.msgt_number = 1;
- // message.type.msgt_inline = TRUE;
- // message.type.msgt_longform = FALSE;
- // message.type.msgt_deallocate = FALSE;
- /* message.type.msgt_unused = 0; */ /* not needed, I think */
-
- /* (i.c) Fill the message with the given integer : */
- message.payload = payload;
-
- /* (ii) Send the message : */
- kern_return_t kret = ::mach_msg (&message.head,
- MACH_SEND_MSG,
- message.head.msgh_size,
- 0,
- MACH_PORT_NULL,
- MACH_MSG_TIMEOUT_NONE,
- MACH_PORT_NULL);
-
- return kret;
-}
-
-kern_return_t
-ConnectionMachPort::Receive (PayloadType &payload)
-{
- MessageType message;
- message.head.msgh_size = sizeof(MessageType);
-
- kern_return_t kret = ::mach_msg (&message.head,
- MACH_RCV_MSG,
- 0,
- sizeof(MessageType),
- m_port,
- MACH_MSG_TIMEOUT_NONE,
- MACH_PORT_NULL);
-
- if (kret == KERN_SUCCESS)
- payload = message.payload;
-
- return kret;
-}
-
-
-#endif // #if defined(__APPLE__)
diff --git a/source/Core/ConnectionSharedMemory.cpp b/source/Core/ConnectionSharedMemory.cpp
deleted file mode 100644
index 707644d36b1c..000000000000
--- a/source/Core/ConnectionSharedMemory.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-//===-- ConnectionSharedMemory.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef __ANDROID_NDK__
-
-#include "lldb/Core/ConnectionSharedMemory.h"
-
-// C Includes
-#ifdef _WIN32
-#include "lldb/Host/windows/windows.h"
-#else
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
-// C++ Includes
-#include <cerrno>
-#include <cstdlib>
-
-// Other libraries and framework includes
-#include "llvm/Support/MathExtras.h"
-
-// Project includes
-#include "lldb/Core/Communication.h"
-#include "lldb/Core/Log.h"
-
-#include "llvm/Support/ConvertUTF.h"
-
-using namespace lldb;
-using namespace lldb_private;
-
-ConnectionSharedMemory::ConnectionSharedMemory () :
- Connection(),
- m_name(),
- m_fd (-1),
- m_mmap()
-{
-}
-
-ConnectionSharedMemory::~ConnectionSharedMemory ()
-{
- Disconnect(nullptr);
-}
-
-bool
-ConnectionSharedMemory::IsConnected () const
-{
- return m_fd >= 0;
-}
-
-ConnectionStatus
-ConnectionSharedMemory::Connect (const char *s, Error *error_ptr)
-{
-// if (s && s[0])
-// {
-// if (strstr(s, "shm-create://"))
-// {
-// }
-// else if (strstr(s, "shm-connect://"))
-// {
-// }
-// if (error_ptr)
-// error_ptr->SetErrorStringWithFormat ("unsupported connection URL: '%s'", s);
-// return eConnectionStatusError;
-// }
- if (error_ptr)
- error_ptr->SetErrorString("invalid connect arguments");
- return eConnectionStatusError;
-}
-
-ConnectionStatus
-ConnectionSharedMemory::Disconnect (Error *error_ptr)
-{
- m_mmap.Clear();
- if (!m_name.empty())
- {
-#ifdef _WIN32
- close(m_fd);
- m_fd = -1;
-#else
- shm_unlink (m_name.c_str());
-#endif
- m_name.clear();
- }
- return eConnectionStatusSuccess;
-}
-
-size_t
-ConnectionSharedMemory::Read (void *dst,
- size_t dst_len,
- uint32_t timeout_usec,
- ConnectionStatus &status,
- Error *error_ptr)
-{
- status = eConnectionStatusSuccess;
- return 0;
-}
-
-size_t
-ConnectionSharedMemory::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
-{
- status = eConnectionStatusSuccess;
- return 0;
-}
-
-std::string
-ConnectionSharedMemory::GetURI()
-{
- // TODO: fix when Connect is fixed?
- return "";
-}
-
-ConnectionStatus
-ConnectionSharedMemory::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
-{
- return eConnectionStatusLostConnection;
-}
-
-ConnectionStatus
-ConnectionSharedMemory::Open (bool create, const char *name, size_t size, Error *error_ptr)
-{
- if (m_fd != -1)
- {
- if (error_ptr)
- error_ptr->SetErrorString("already open");
- return eConnectionStatusError;
- }
-
- m_name.assign (name);
-
-#ifdef _WIN32
- HANDLE handle = INVALID_HANDLE_VALUE;
- std::wstring wname;
- if (llvm::ConvertUTF8toWide(name, wname))
- {
- if (create)
- {
- handle = CreateFileMappingW(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, llvm::Hi_32(size),
- llvm::Lo_32(size), wname.c_str());
- }
- else
- handle = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, wname.c_str());
- }
-
- m_fd = _open_osfhandle((intptr_t)handle, 0);
-#else
- int oflag = O_RDWR;
- if (create)
- oflag |= O_CREAT;
- m_fd = ::shm_open (m_name.c_str(), oflag, S_IRUSR|S_IWUSR);
-
- if (create)
- ::ftruncate (m_fd, size);
-#endif
-
- if (m_mmap.MemoryMapFromFileDescriptor(m_fd, 0, size, true, false) == size)
- return eConnectionStatusSuccess;
-
- Disconnect(nullptr);
- return eConnectionStatusError;
-}
-
-#endif // __ANDROID_NDK__
diff --git a/source/Core/ConstString.cpp b/source/Core/ConstString.cpp
index f983f1444d7c..21b4d3d76f1c 100644
--- a/source/Core/ConstString.cpp
+++ b/source/Core/ConstString.cpp
@@ -15,8 +15,8 @@
#include <mutex>
// Other libraries and framework includes
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/RWMutex.h"
// Project includes
@@ -24,180 +24,159 @@
using namespace lldb_private;
-class Pool
-{
+class Pool {
public:
- typedef const char * StringPoolValueType;
- typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator> StringPool;
- typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType;
-
- static StringPoolEntryType &
- GetStringMapEntryFromKeyData (const char *keyData)
- {
- char *ptr = const_cast<char*>(keyData) - sizeof (StringPoolEntryType);
- return *reinterpret_cast<StringPoolEntryType*>(ptr);
- }
-
- size_t
- GetConstCStringLength (const char *ccstr) const
- {
- if (ccstr != nullptr)
- {
- 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;
+ typedef const char *StringPoolValueType;
+ typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator>
+ StringPool;
+ typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType;
+
+ static StringPoolEntryType &
+ GetStringMapEntryFromKeyData(const char *keyData) {
+ char *ptr = const_cast<char *>(keyData) - sizeof(StringPoolEntryType);
+ return *reinterpret_cast<StringPoolEntryType *>(ptr);
+ }
+
+ size_t GetConstCStringLength(const char *ccstr) const {
+ if (ccstr != nullptr) {
+ 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();
}
-
- StringPoolValueType
- GetMangledCounterpart (const char *ccstr) const
- {
- if (ccstr != nullptr)
- {
- const uint8_t h = hash (llvm::StringRef(ccstr));
- llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
- return GetStringMapEntryFromKeyData (ccstr).getValue();
- }
- return nullptr;
+ return 0;
+ }
+
+ StringPoolValueType GetMangledCounterpart(const char *ccstr) const {
+ if (ccstr != nullptr) {
+ const uint8_t h = hash(llvm::StringRef(ccstr));
+ llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
+ return GetStringMapEntryFromKeyData(ccstr).getValue();
}
-
- bool
- SetMangledCounterparts (const char *key_ccstr, const char *value_ccstr)
- {
- if (key_ccstr != nullptr && value_ccstr != nullptr)
- {
- {
- 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;
+ return nullptr;
+ }
+
+ bool SetMangledCounterparts(const char *key_ccstr, const char *value_ccstr) {
+ if (key_ccstr != nullptr && value_ccstr != nullptr) {
+ {
+ 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;
+ }
- const char *
- GetConstCString (const char *cstr)
- {
- if (cstr != nullptr)
- return GetConstCStringWithLength (cstr, strlen (cstr));
- return nullptr;
- }
+ const char *GetConstCString(const char *cstr) {
+ if (cstr != nullptr)
+ return GetConstCStringWithLength(cstr, strlen(cstr));
+ return nullptr;
+ }
- const char *
- GetConstCStringWithLength (const char *cstr, size_t cstr_len)
- {
- if (cstr != nullptr)
- return GetConstCStringWithStringRef(llvm::StringRef(cstr, cstr_len));
- return nullptr;
+ const char *GetConstCStringWithLength(const char *cstr, size_t cstr_len) {
+ if (cstr != nullptr)
+ return GetConstCStringWithStringRef(llvm::StringRef(cstr, cstr_len));
+ return nullptr;
+ }
+
+ const char *GetConstCStringWithStringRef(const llvm::StringRef &string_ref) {
+ if (string_ref.data()) {
+ 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();
}
-
- const char *
- GetConstCStringWithStringRef (const llvm::StringRef &string_ref)
- {
- if (string_ref.data())
- {
- 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 nullptr;
+ return nullptr;
+ }
+
+ const char *
+ GetConstCStringAndSetMangledCounterPart(const char *demangled_cstr,
+ const char *mangled_ccstr) {
+ if (demangled_cstr != nullptr) {
+ 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;
}
-
- const char *
- GetConstCStringAndSetMangledCounterPart (const char *demangled_cstr, const char *mangled_ccstr)
- {
- if (demangled_cstr != nullptr)
- {
- 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 nullptr;
+ return nullptr;
+ }
+
+ const char *GetConstTrimmedCStringWithLength(const char *cstr,
+ size_t cstr_len) {
+ if (cstr != nullptr) {
+ const size_t trimmed_len = std::min<size_t>(strlen(cstr), cstr_len);
+ return GetConstCStringWithLength(cstr, trimmed_len);
}
-
- const char *
- GetConstTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
- {
- if (cstr != nullptr)
- {
- const size_t trimmed_len = std::min<size_t> (strlen (cstr), cstr_len);
- return GetConstCStringWithLength (cstr, trimmed_len);
- }
- return nullptr;
- }
-
- //------------------------------------------------------------------
- // Return the size in bytes that this object and any items in its
- // collection of uniqued strings + data count values takes in
- // memory.
- //------------------------------------------------------------------
- size_t
- MemorySize() const
- {
- size_t mem_size = sizeof(Pool);
- for (const auto& pool : m_string_pools)
- {
- 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;
+ return nullptr;
+ }
+
+ //------------------------------------------------------------------
+ // Return the size in bytes that this object and any items in its
+ // collection of uniqued strings + data count values takes in
+ // memory.
+ //------------------------------------------------------------------
+ size_t MemorySize() const {
+ size_t mem_size = sizeof(Pool);
+ for (const auto &pool : m_string_pools) {
+ 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:
- uint8_t
- hash(const llvm::StringRef &s) const
- {
- uint32_t h = llvm::HashString(s);
- return ((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff;
- }
+ uint8_t hash(const llvm::StringRef &s) const {
+ uint32_t h = llvm::HashString(s);
+ return ((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff;
+ }
- struct PoolEntry
- {
- mutable llvm::sys::SmartRWMutex<false> 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;
+ std::array<PoolEntry, 256> m_string_pools;
};
//----------------------------------------------------------------------
@@ -211,177 +190,147 @@ protected:
// global destructor chain is run, and trying to make sure no destructors
// touch ConstStrings is difficult. So we leak the pool instead.
//----------------------------------------------------------------------
-static Pool &
-StringPool()
-{
- static std::once_flag g_pool_initialization_flag;
- static Pool *g_string_pool = nullptr;
-
- std::call_once(g_pool_initialization_flag, [] () {
- g_string_pool = new Pool();
- });
-
- return *g_string_pool;
-}
+static Pool &StringPool() {
+ static std::once_flag g_pool_initialization_flag;
+ static Pool *g_string_pool = nullptr;
-ConstString::ConstString (const char *cstr) :
- m_string (StringPool().GetConstCString (cstr))
-{
-}
+ std::call_once(g_pool_initialization_flag,
+ []() { g_string_pool = new Pool(); });
-ConstString::ConstString (const char *cstr, size_t cstr_len) :
- m_string (StringPool().GetConstCStringWithLength (cstr, cstr_len))
-{
+ return *g_string_pool;
}
-ConstString::ConstString (const llvm::StringRef &s) :
- m_string (StringPool().GetConstCStringWithLength (s.data(), s.size()))
-{
-}
+ConstString::ConstString(const char *cstr)
+ : m_string(StringPool().GetConstCString(cstr)) {}
-bool
-ConstString::operator < (const ConstString& rhs) const
-{
- if (m_string == rhs.m_string)
- return false;
+ConstString::ConstString(const char *cstr, size_t cstr_len)
+ : m_string(StringPool().GetConstCStringWithLength(cstr, cstr_len)) {}
- llvm::StringRef lhs_string_ref (m_string, StringPool().GetConstCStringLength (m_string));
- llvm::StringRef rhs_string_ref (rhs.m_string, StringPool().GetConstCStringLength (rhs.m_string));
+ConstString::ConstString(const llvm::StringRef &s)
+ : m_string(StringPool().GetConstCStringWithLength(s.data(), s.size())) {}
- // If both have valid C strings, then return the comparison
- if (lhs_string_ref.data() && rhs_string_ref.data())
- return lhs_string_ref < rhs_string_ref;
+bool ConstString::operator<(const ConstString &rhs) const {
+ if (m_string == rhs.m_string)
+ return false;
- // Else one of them was nullptr, so if LHS is nullptr then it is less than
- return lhs_string_ref.data() == nullptr;
+ llvm::StringRef lhs_string_ref(m_string,
+ StringPool().GetConstCStringLength(m_string));
+ llvm::StringRef rhs_string_ref(
+ rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string));
+
+ // If both have valid C strings, then return the comparison
+ if (lhs_string_ref.data() && rhs_string_ref.data())
+ return lhs_string_ref < rhs_string_ref;
+
+ // Else one of them was nullptr, so if LHS is nullptr then it is less than
+ return lhs_string_ref.data() == nullptr;
}
-Stream&
-lldb_private::operator << (Stream& s, const ConstString& str)
-{
- const char *cstr = str.GetCString();
- if (cstr != nullptr)
- s << cstr;
+Stream &lldb_private::operator<<(Stream &s, const ConstString &str) {
+ const char *cstr = str.GetCString();
+ if (cstr != nullptr)
+ s << cstr;
- return s;
+ return s;
}
-size_t
-ConstString::GetLength () const
-{
- return StringPool().GetConstCStringLength (m_string);
+size_t ConstString::GetLength() const {
+ return StringPool().GetConstCStringLength(m_string);
}
-bool
-ConstString::Equals(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive)
-{
- if (lhs.m_string == rhs.m_string)
- return true;
-
- // Since the pointers weren't equal, and identical ConstStrings always have identical pointers,
- // the result must be false for case sensitive equality test.
- if (case_sensitive)
- return false;
-
- // perform case insensitive equality test
- llvm::StringRef lhs_string_ref(lhs.m_string, StringPool().GetConstCStringLength(lhs.m_string));
- llvm::StringRef rhs_string_ref(rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string));
- return lhs_string_ref.equals_lower(rhs_string_ref);
+bool ConstString::Equals(const ConstString &lhs, const ConstString &rhs,
+ const bool case_sensitive) {
+ if (lhs.m_string == rhs.m_string)
+ return true;
+
+ // Since the pointers weren't equal, and identical ConstStrings always have
+ // identical pointers,
+ // the result must be false for case sensitive equality test.
+ if (case_sensitive)
+ return false;
+
+ // perform case insensitive equality test
+ llvm::StringRef lhs_string_ref(
+ lhs.m_string, StringPool().GetConstCStringLength(lhs.m_string));
+ llvm::StringRef rhs_string_ref(
+ rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string));
+ return lhs_string_ref.equals_lower(rhs_string_ref);
}
-int
-ConstString::Compare(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive)
-{
- // If the iterators are the same, this is the same string
- const char *lhs_cstr = lhs.m_string;
- const char *rhs_cstr = rhs.m_string;
- if (lhs_cstr == rhs_cstr)
- return 0;
- if (lhs_cstr && rhs_cstr)
- {
- llvm::StringRef lhs_string_ref (lhs_cstr, StringPool().GetConstCStringLength (lhs_cstr));
- llvm::StringRef rhs_string_ref (rhs_cstr, StringPool().GetConstCStringLength (rhs_cstr));
-
- if (case_sensitive)
- {
- return lhs_string_ref.compare(rhs_string_ref);
- }
- else
- {
- return lhs_string_ref.compare_lower(rhs_string_ref);
- }
+int ConstString::Compare(const ConstString &lhs, const ConstString &rhs,
+ const bool case_sensitive) {
+ // If the iterators are the same, this is the same string
+ const char *lhs_cstr = lhs.m_string;
+ const char *rhs_cstr = rhs.m_string;
+ if (lhs_cstr == rhs_cstr)
+ return 0;
+ if (lhs_cstr && rhs_cstr) {
+ llvm::StringRef lhs_string_ref(
+ lhs_cstr, StringPool().GetConstCStringLength(lhs_cstr));
+ llvm::StringRef rhs_string_ref(
+ rhs_cstr, StringPool().GetConstCStringLength(rhs_cstr));
+
+ if (case_sensitive) {
+ return lhs_string_ref.compare(rhs_string_ref);
+ } else {
+ return lhs_string_ref.compare_lower(rhs_string_ref);
}
+ }
- if (lhs_cstr)
- return +1; // LHS isn't nullptr but RHS is
- else
- return -1; // LHS is nullptr but RHS isn't
+ if (lhs_cstr)
+ return +1; // LHS isn't nullptr but RHS is
+ else
+ return -1; // LHS is nullptr but RHS isn't
}
-void
-ConstString::Dump(Stream *s, const char *fail_value) const
-{
- if (s != nullptr)
- {
- const char *cstr = AsCString (fail_value);
- if (cstr != nullptr)
- s->PutCString (cstr);
- }
+void ConstString::Dump(Stream *s, const char *fail_value) const {
+ if (s != nullptr) {
+ const char *cstr = AsCString(fail_value);
+ if (cstr != nullptr)
+ s->PutCString(cstr);
+ }
}
-void
-ConstString::DumpDebug(Stream *s) const
-{
- const char *cstr = GetCString ();
- size_t cstr_len = GetLength();
- // Only print the parens if we have a non-nullptr string
- const char *parens = cstr ? "\"" : "";
- s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64,
- static_cast<int>(sizeof(void*) * 2),
- static_cast<const void*>(this), parens, cstr, parens,
- static_cast<uint64_t>(cstr_len));
+void ConstString::DumpDebug(Stream *s) const {
+ const char *cstr = GetCString();
+ size_t cstr_len = GetLength();
+ // Only print the parens if we have a non-nullptr string
+ const char *parens = cstr ? "\"" : "";
+ s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64,
+ static_cast<int>(sizeof(void *) * 2),
+ static_cast<const void *>(this), parens, cstr, parens,
+ static_cast<uint64_t>(cstr_len));
}
-void
-ConstString::SetCString (const char *cstr)
-{
- m_string = StringPool().GetConstCString (cstr);
+void ConstString::SetCString(const char *cstr) {
+ m_string = StringPool().GetConstCString(cstr);
}
-void
-ConstString::SetString (const llvm::StringRef &s)
-{
- m_string = StringPool().GetConstCStringWithLength (s.data(), s.size());
+void ConstString::SetString(const llvm::StringRef &s) {
+ m_string = StringPool().GetConstCStringWithLength(s.data(), s.size());
}
-void
-ConstString::SetCStringWithMangledCounterpart (const char *demangled, const ConstString &mangled)
-{
- m_string = StringPool().GetConstCStringAndSetMangledCounterPart (demangled, mangled.m_string);
+void ConstString::SetCStringWithMangledCounterpart(const char *demangled,
+ const ConstString &mangled) {
+ m_string = StringPool().GetConstCStringAndSetMangledCounterPart(
+ demangled, mangled.m_string);
}
-bool
-ConstString::GetMangledCounterpart (ConstString &counterpart) const
-{
- counterpart.m_string = StringPool().GetMangledCounterpart(m_string);
- return (bool)counterpart;
+bool ConstString::GetMangledCounterpart(ConstString &counterpart) const {
+ counterpart.m_string = StringPool().GetMangledCounterpart(m_string);
+ return (bool)counterpart;
}
-void
-ConstString::SetCStringWithLength (const char *cstr, size_t cstr_len)
-{
- m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len);
+void ConstString::SetCStringWithLength(const char *cstr, size_t cstr_len) {
+ m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len);
}
-void
-ConstString::SetTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
-{
- m_string = StringPool().GetConstTrimmedCStringWithLength (cstr, cstr_len);
+void ConstString::SetTrimmedCStringWithLength(const char *cstr,
+ size_t cstr_len) {
+ m_string = StringPool().GetConstTrimmedCStringWithLength(cstr, cstr_len);
}
-size_t
-ConstString::StaticMemorySize()
-{
- // Get the size of the static string pool
- return StringPool().MemorySize();
+size_t ConstString::StaticMemorySize() {
+ // Get the size of the static string pool
+ return StringPool().MemorySize();
}
diff --git a/source/Core/CxaDemangle.cpp b/source/Core/CxaDemangle.cpp
deleted file mode 100644
index 62335a9175cd..000000000000
--- a/source/Core/CxaDemangle.cpp
+++ /dev/null
@@ -1,5014 +0,0 @@
-//----------------------------------------------------------------------
-// Inlined copy of:
-// http://llvm.org/svn/llvm-project/libcxxabi/trunk/src/cxa_demangle.cpp
-// revision 238263.
-//
-// Changes include:
-// - Renamed the "__cxxabiv1" namespace to "lldb_private"
-// - Stripped GCC attributes()
-// - Removed extern "C" from the cxa_demangle function
-// - Added "#undef _LIBCPP_EXTERN_TEMPLATE" to avoid warning
-// - Implemented missing rebind, construct, destroy in malloc_alloc
-// - Replaced noexcept, constexpr, alignas with their LLVM_* equivalents
-// - 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)
-#include "lldb/Host/windows/win32.h" // snprintf
-#endif
-#include "llvm/Support/Compiler.h" // LLVM_{NOEXCEPT, CONSTEXPR, ALIGNAS}
-#include "lldb/lldb-private.h"
-#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below
-
-//===-------------------------- cxa_demangle.cpp --------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#define _LIBCPP_EXTERN_TEMPLATE(...)
-#define _LIBCPP_NO_EXCEPTIONS
-
-#include <vector>
-#include <algorithm>
-#include <string>
-#include <numeric>
-#include <cstdlib>
-#include <cstring>
-#include <cctype>
-#include <cstdio>
-
-namespace lldb_private
-{
-
-namespace
-{
-
-enum
-{
- unknown_error = -4,
- invalid_args = -3,
- invalid_mangled_name,
- memory_alloc_failure,
- success
-};
-
-template <class C>
- const char* parse_type(const char* first, const char* last, C& db);
-template <class C>
- const char* parse_encoding(const char* first, const char* last, C& db);
-template <class C>
- const char* parse_name(const char* first, const char* last, C& db,
- bool* ends_with_template_args = 0);
-template <class C>
- const char* parse_expression(const char* first, const char* last, C& db);
-template <class C>
- const char* parse_template_args(const char* first, const char* last, C& db);
-template <class C>
- const char* parse_operator_name(const char* first, const char* last, C& db);
-template <class C>
- const char* parse_unqualified_name(const char* first, const char* last, C& db);
-template <class C>
- const char* parse_decltype(const char* first, const char* last, C& db);
-
-template <class C>
-void
-print_stack(const C& db)
-{
- fprintf(stderr, "---------\n");
- fprintf(stderr, "names:\n");
- for (auto& s : db.names)
- fprintf(stderr, "{%s#%s}\n", s.first.c_str(), s.second.c_str());
- int i = -1;
- fprintf(stderr, "subs:\n");
- for (auto& v : db.subs)
- {
- if (i >= 0)
- fprintf(stderr, "S%i_ = {", i);
- else
- fprintf(stderr, "S_ = {");
- for (auto& s : v)
- fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());
- fprintf(stderr, "}\n");
- ++i;
- }
- fprintf(stderr, "template_param:\n");
- for (auto& t : db.template_param)
- {
- fprintf(stderr, "--\n");
- i = -1;
- for (auto& v : t)
- {
- if (i >= 0)
- fprintf(stderr, "T%i_ = {", i);
- else
- fprintf(stderr, "T_ = {");
- for (auto& s : v)
- fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());
- fprintf(stderr, "}\n");
- ++i;
- }
- }
- fprintf(stderr, "---------\n\n");
-}
-
-template <class C>
-void
-print_state(const char* msg, const char* first, const char* last, const C& db)
-{
- fprintf(stderr, "%s: ", msg);
- for (; first != last; ++first)
- fprintf(stderr, "%c", *first);
- fprintf(stderr, "\n");
- print_stack(db);
-}
-
-// <number> ::= [n] <non-negative decimal integer>
-
-const char*
-parse_number(const char* first, const char* last)
-{
- if (first != last)
- {
- const char* t = first;
- if (*t == 'n')
- ++t;
- if (t != last)
- {
- if (*t == '0')
- {
- first = t+1;
- }
- else if ('1' <= *t && *t <= '9')
- {
- first = t+1;
- while (first != last && std::isdigit(*first))
- ++first;
- }
- }
- }
- return first;
-}
-
-template <class Float>
-struct float_data;
-
-template <>
-struct float_data<float>
-{
- static const size_t mangled_size = 8;
- static const size_t max_demangled_size = 24;
- static const char* spec;
-};
-
-const char* float_data<float>::spec = "%af";
-
-template <>
-struct float_data<double>
-{
- static const size_t mangled_size = 16;
- static const size_t max_demangled_size = 32;
- static const char* spec;
-};
-
-const char* float_data<double>::spec = "%a";
-
-template <>
-struct float_data<long double>
-{
-#if defined(__arm__)
- static const size_t mangled_size = 16;
-#else
- static const size_t mangled_size = 20; // May need to be adjusted to 16 or 24 on other platforms
-#endif
- static const size_t max_demangled_size = 40;
- static const char* spec;
-};
-
-const char* float_data<long double>::spec = "%LaL";
-
-template <class Float, class C>
-const char*
-parse_floating_number(const char* first, const char* last, C& db)
-{
- const size_t N = float_data<Float>::mangled_size;
- if (static_cast<std::size_t>(last - first) > N)
- {
- last = first + N;
- union
- {
- Float value;
- char buf[sizeof(Float)];
- };
- const char* t = first;
- char* e = buf;
- for (; t != last; ++t, ++e)
- {
- if (!isxdigit(*t))
- return first;
- unsigned d1 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :
- static_cast<unsigned>(*t - 'a' + 10);
- ++t;
- unsigned d0 = isdigit(*t) ? static_cast<unsigned>(*t - '0') :
- static_cast<unsigned>(*t - 'a' + 10);
- *e = static_cast<char>((d1 << 4) + d0);
- }
- if (*t == 'E')
- {
-#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- std::reverse(buf, e);
-#endif
- char num[float_data<Float>::max_demangled_size] = {0};
- int n = snprintf(num, sizeof(num), float_data<Float>::spec, value);
- if (static_cast<std::size_t>(n) >= sizeof(num))
- return first;
- db.names.push_back(typename C::String(num, static_cast<std::size_t>(n)));
- first = t+1;
- }
- }
- return first;
-}
-
-// <source-name> ::= <positive length number> <identifier>
-
-template <class C>
-const char*
-parse_source_name(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- char c = *first;
- if (isdigit(c) && first+1 != last)
- {
- const char* t = first+1;
- size_t n = static_cast<size_t>(c - '0');
- for (c = *t; isdigit(c); c = *t)
- {
- n = n * 10 + static_cast<size_t>(c - '0');
- if (++t == last)
- return first;
- }
- if (static_cast<size_t>(last - t) >= n)
- {
- typename C::String r(t, n);
- if (r.substr(0, 10) == "_GLOBAL__N")
- db.names.push_back("(anonymous namespace)");
- else
- db.names.push_back(std::move(r));
- first = t + n;
- }
- }
- }
- return first;
-}
-
-// <substitution> ::= S <seq-id> _
-// ::= S_
-// <substitution> ::= Sa # ::std::allocator
-// <substitution> ::= Sb # ::std::basic_string
-// <substitution> ::= Ss # ::std::basic_string < char,
-// ::std::char_traits<char>,
-// ::std::allocator<char> >
-// <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
-// <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
-// <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
-
-template <class C>
-const char*
-parse_substitution(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- if (*first == 'S')
- {
- switch (first[1])
- {
- case 'a':
- db.names.push_back("std::allocator");
- first += 2;
- break;
- case 'b':
- db.names.push_back("std::basic_string");
- first += 2;
- break;
- case 's':
- db.names.push_back("std::string");
- first += 2;
- break;
- case 'i':
- db.names.push_back("std::istream");
- first += 2;
- break;
- case 'o':
- db.names.push_back("std::ostream");
- first += 2;
- break;
- case 'd':
- db.names.push_back("std::iostream");
- first += 2;
- break;
- case '_':
- if (!db.subs.empty())
- {
- for (const auto& n : db.subs.front())
- db.names.push_back(n);
- first += 2;
- }
- break;
- default:
- if (std::isdigit(first[1]) || std::isupper(first[1]))
- {
- size_t sub = 0;
- const char* t = first+1;
- if (std::isdigit(*t))
- sub = static_cast<size_t>(*t - '0');
- else
- sub = static_cast<size_t>(*t - 'A') + 10;
- for (++t; t != last && (std::isdigit(*t) || std::isupper(*t)); ++t)
- {
- sub *= 36;
- if (std::isdigit(*t))
- sub += static_cast<size_t>(*t - '0');
- else
- sub += static_cast<size_t>(*t - 'A') + 10;
- }
- if (t == last || *t != '_')
- return first;
- ++sub;
- if (sub < db.subs.size())
- {
- for (const auto& n : db.subs[sub])
- db.names.push_back(n);
- first = t+1;
- }
- }
- break;
- }
- }
- }
- return first;
-}
-
-// <builtin-type> ::= v # void
-// ::= w # wchar_t
-// ::= b # bool
-// ::= c # char
-// ::= a # signed char
-// ::= h # unsigned char
-// ::= s # short
-// ::= t # unsigned short
-// ::= i # int
-// ::= j # unsigned int
-// ::= l # long
-// ::= m # unsigned long
-// ::= x # long long, __int64
-// ::= y # unsigned long long, __int64
-// ::= n # __int128
-// ::= o # unsigned __int128
-// ::= f # float
-// ::= d # double
-// ::= e # long double, __float80
-// ::= g # __float128
-// ::= z # ellipsis
-// ::= Dd # IEEE 754r decimal floating point (64 bits)
-// ::= De # IEEE 754r decimal floating point (128 bits)
-// ::= Df # IEEE 754r decimal floating point (32 bits)
-// ::= Dh # IEEE 754r half-precision floating point (16 bits)
-// ::= Di # char32_t
-// ::= Ds # char16_t
-// ::= Da # auto (in dependent new-expressions)
-// ::= Dc # decltype(auto)
-// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
-// ::= u <source-name> # vendor extended type
-
-template <class C>
-const char*
-parse_builtin_type(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- switch (*first)
- {
- case 'v':
- db.names.push_back("void");
- ++first;
- break;
- case 'w':
- db.names.push_back("wchar_t");
- ++first;
- break;
- case 'b':
- db.names.push_back("bool");
- ++first;
- break;
- case 'c':
- db.names.push_back("char");
- ++first;
- break;
- case 'a':
- db.names.push_back("signed char");
- ++first;
- break;
- case 'h':
- db.names.push_back("unsigned char");
- ++first;
- break;
- case 's':
- db.names.push_back("short");
- ++first;
- break;
- case 't':
- db.names.push_back("unsigned short");
- ++first;
- break;
- case 'i':
- db.names.push_back("int");
- ++first;
- break;
- case 'j':
- db.names.push_back("unsigned int");
- ++first;
- break;
- case 'l':
- db.names.push_back("long");
- ++first;
- break;
- case 'm':
- db.names.push_back("unsigned long");
- ++first;
- break;
- case 'x':
- db.names.push_back("long long");
- ++first;
- break;
- case 'y':
- db.names.push_back("unsigned long long");
- ++first;
- break;
- case 'n':
- db.names.push_back("__int128");
- ++first;
- break;
- case 'o':
- db.names.push_back("unsigned __int128");
- ++first;
- break;
- case 'f':
- db.names.push_back("float");
- ++first;
- break;
- case 'd':
- db.names.push_back("double");
- ++first;
- break;
- case 'e':
- db.names.push_back("long double");
- ++first;
- break;
- case 'g':
- db.names.push_back("__float128");
- ++first;
- break;
- case 'z':
- db.names.push_back("...");
- ++first;
- break;
- case 'u':
- {
- const char*t = parse_source_name(first+1, last, db);
- if (t != first+1)
- first = t;
- }
- break;
- case 'D':
- if (first+1 != last)
- {
- switch (first[1])
- {
- case 'd':
- db.names.push_back("decimal64");
- first += 2;
- break;
- case 'e':
- db.names.push_back("decimal128");
- first += 2;
- break;
- case 'f':
- db.names.push_back("decimal32");
- first += 2;
- break;
- case 'h':
- db.names.push_back("decimal16");
- first += 2;
- break;
- case 'i':
- db.names.push_back("char32_t");
- first += 2;
- break;
- case 's':
- db.names.push_back("char16_t");
- first += 2;
- break;
- case 'a':
- db.names.push_back("auto");
- first += 2;
- break;
- case 'c':
- db.names.push_back("decltype(auto)");
- first += 2;
- break;
- case 'n':
- db.names.push_back("std::nullptr_t");
- first += 2;
- break;
- }
- }
- break;
- }
- }
- return first;
-}
-
-// <CV-qualifiers> ::= [r] [V] [K]
-
-const char*
-parse_cv_qualifiers(const char* first, const char* last, unsigned& cv)
-{
- cv = 0;
- if (first != last)
- {
- if (*first == 'r')
- {
- cv |= 4;
- ++first;
- }
- if (*first == 'V')
- {
- cv |= 2;
- ++first;
- }
- if (*first == 'K')
- {
- cv |= 1;
- ++first;
- }
- }
- return first;
-}
-
-// <template-param> ::= T_ # first template parameter
-// ::= T <parameter-2 non-negative number> _
-
-template <class C>
-const char*
-parse_template_param(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- if (*first == 'T')
- {
- if (first[1] == '_')
- {
- if (db.template_param.empty())
- return first;
- if (!db.template_param.back().empty())
- {
- for (auto& t : db.template_param.back().front())
- db.names.push_back(t);
- first += 2;
- }
- else
- {
- db.names.push_back("T_");
- first += 2;
- db.fix_forward_references = true;
- }
- }
- else if (isdigit(first[1]))
- {
- const char* t = first+1;
- size_t sub = static_cast<size_t>(*t - '0');
- for (++t; t != last && isdigit(*t); ++t)
- {
- sub *= 10;
- sub += static_cast<size_t>(*t - '0');
- }
- if (t == last || *t != '_' || db.template_param.empty())
- return first;
- ++sub;
- if (sub < db.template_param.back().size())
- {
- for (auto& temp : db.template_param.back()[sub])
- db.names.push_back(temp);
- first = t+1;
- }
- else
- {
- db.names.push_back(typename C::String(first, t+1));
- first = t+1;
- db.fix_forward_references = true;
- }
- }
- }
- }
- return first;
-}
-
-// cc <type> <expression> # const_cast<type> (expression)
-
-template <class C>
-const char*
-parse_const_cast_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'c' && first[1] == 'c')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto expr = db.names.back().move_full();
- db.names.pop_back();
- db.names.back() = "const_cast<" + db.names.back().move_full() + ">(" + expr + ")";
- first = t1;
- }
- }
- }
- return first;
-}
-
-// dc <type> <expression> # dynamic_cast<type> (expression)
-
-template <class C>
-const char*
-parse_dynamic_cast_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'd' && first[1] == 'c')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto expr = db.names.back().move_full();
- db.names.pop_back();
- db.names.back() = "dynamic_cast<" + db.names.back().move_full() + ">(" + expr + ")";
- first = t1;
- }
- }
- }
- return first;
-}
-
-// rc <type> <expression> # reinterpret_cast<type> (expression)
-
-template <class C>
-const char*
-parse_reinterpret_cast_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'r' && first[1] == 'c')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto expr = db.names.back().move_full();
- db.names.pop_back();
- db.names.back() = "reinterpret_cast<" + db.names.back().move_full() + ">(" + expr + ")";
- first = t1;
- }
- }
- }
- return first;
-}
-
-// sc <type> <expression> # static_cast<type> (expression)
-
-template <class C>
-const char*
-parse_static_cast_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 's' && first[1] == 'c')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto expr = db.names.back().move_full();
- db.names.pop_back();
- db.names.back() = "static_cast<" + db.names.back().move_full() + ">(" + expr + ")";
- first = t1;
- }
- }
- }
- return first;
-}
-
-// sp <expression> # pack expansion
-
-template <class C>
-const char*
-parse_pack_expansion(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 's' && first[1] == 'p')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- first = t;
- }
- return first;
-}
-
-// st <type> # sizeof (a type)
-
-template <class C>
-const char*
-parse_sizeof_type_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 's' && first[1] == 't')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
-}
-
-// sz <expr> # sizeof (a expression)
-
-template <class C>
-const char*
-parse_sizeof_expr_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 's' && first[1] == 'z')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back() = "sizeof (" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
-}
-
-// sZ <template-param> # size of a parameter pack
-
-template <class C>
-const char*
-parse_sizeof_param_pack_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'T')
- {
- size_t k0 = db.names.size();
- const char* t = parse_template_param(first+2, last, db);
- size_t k1 = db.names.size();
- if (t != first+2)
- {
- typename C::String tmp("sizeof...(");
- size_t k = k0;
- if (k != k1)
- {
- tmp += db.names[k].move_full();
- for (++k; k != k1; ++k)
- tmp += ", " + db.names[k].move_full();
- }
- tmp += ")";
- for (; k1 != k0; --k1)
- db.names.pop_back();
- db.names.push_back(std::move(tmp));
- first = t;
- }
- }
- return first;
-}
-
-// <function-param> ::= fp <top-level CV-qualifiers> _ # L == 0, first parameter
-// ::= fp <top-level CV-qualifiers> <parameter-2 non-negative number> _ # L == 0, second and later parameters
-// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> _ # L > 0, first parameter
-// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers> <parameter-2 non-negative number> _ # L > 0, second and later parameters
-
-template <class C>
-const char*
-parse_function_param(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && *first == 'f')
- {
- if (first[1] == 'p')
- {
- unsigned cv;
- const char* t = parse_cv_qualifiers(first+2, last, cv);
- const char* t1 = parse_number(t, last);
- if (t1 != last && *t1 == '_')
- {
- db.names.push_back("fp" + typename C::String(t, t1));
- first = t1+1;
- }
- }
- else if (first[1] == 'L')
- {
- unsigned cv;
- const char* t0 = parse_number(first+2, last);
- if (t0 != last && *t0 == 'p')
- {
- ++t0;
- const char* t = parse_cv_qualifiers(t0, last, cv);
- const char* t1 = parse_number(t, last);
- if (t1 != last && *t1 == '_')
- {
- db.names.push_back("fp" + typename C::String(t, t1));
- first = t1+1;
- }
- }
- }
- }
- return first;
-}
-
-// sZ <function-param> # size of a function parameter pack
-
-template <class C>
-const char*
-parse_sizeof_function_param_pack_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' && first[2] == 'f')
- {
- const char* t = parse_function_param(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back() = "sizeof...(" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
-}
-
-// te <expression> # typeid (expression)
-// ti <type> # typeid (type)
-
-template <class C>
-const char*
-parse_typeid_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i'))
- {
- const char* t;
- if (first[1] == 'e')
- t = parse_expression(first+2, last, db);
- else
- t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back() = "typeid(" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
-}
-
-// tw <expression> # throw expression
-
-template <class C>
-const char*
-parse_throw_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 't' && first[1] == 'w')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back() = "throw " + db.names.back().move_full();
- first = t;
- }
- }
- return first;
-}
-
-// ds <expression> <expression> # expr.*expr
-
-template <class C>
-const char*
-parse_dot_star_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'd' && first[1] == 's')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto expr = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += ".*" + expr;
- first = t1;
- }
- }
- }
- return first;
-}
-
-// <simple-id> ::= <source-name> [ <template-args> ]
-
-template <class C>
-const char*
-parse_simple_id(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- const char* t = parse_source_name(first, last, db);
- if (t != first)
- {
- const char* t1 = parse_template_args(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += std::move(args);
- }
- first = t1;
- }
- else
- first = t;
- }
- return first;
-}
-
-// <unresolved-type> ::= <template-param>
-// ::= <decltype>
-// ::= <substitution>
-
-template <class C>
-const char*
-parse_unresolved_type(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- const char* t = first;
- switch (*first)
- {
- case 'T':
- {
- size_t k0 = db.names.size();
- t = parse_template_param(first, last, db);
- size_t k1 = db.names.size();
- if (t != first && k1 == k0 + 1)
- {
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- else
- {
- for (; k1 != k0; --k1)
- db.names.pop_back();
- }
- break;
- }
- case 'D':
- t = parse_decltype(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- break;
- case 'S':
- t = parse_substitution(first, last, db);
- if (t != first)
- first = t;
- else
- {
- if (last - first > 2 && first[1] == 't')
- {
- t = parse_unqualified_name(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "std::");
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- }
- }
- break;
- }
- }
- return first;
-}
-
-// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
-// ::= <simple-id> # e.g., ~A<2*N>
-
-template <class C>
-const char*
-parse_destructor_name(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- const char* t = parse_unresolved_type(first, last, db);
- if (t == first)
- t = parse_simple_id(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "~");
- first = t;
- }
- }
- return first;
-}
-
-// <base-unresolved-name> ::= <simple-id> # unresolved name
-// extension ::= <operator-name> # unresolved operator-function-id
-// extension ::= <operator-name> <template-args> # unresolved operator template-id
-// ::= on <operator-name> # unresolved operator-function-id
-// ::= on <operator-name> <template-args> # unresolved operator template-id
-// ::= dn <destructor-name> # destructor or pseudo-destructor;
-// # e.g. ~X or ~X<N-1>
-
-template <class C>
-const char*
-parse_base_unresolved_name(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n')
- {
- if (first[0] == 'o')
- {
- const char* t = parse_operator_name(first+2, last, db);
- if (t != first+2)
- {
- first = parse_template_args(t, last, db);
- if (first != t)
- {
- if (db.names.size() < 2)
- return first;
- auto args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += std::move(args);
- }
- }
- }
- else
- {
- const char* t = parse_destructor_name(first+2, last, db);
- if (t != first+2)
- first = t;
- }
- }
- else
- {
- const char* t = parse_simple_id(first, last, db);
- if (t == first)
- {
- t = parse_operator_name(first, last, db);
- if (t != first)
- {
- first = parse_template_args(t, last, db);
- if (first != t)
- {
- if (db.names.size() < 2)
- return first;
- auto args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += std::move(args);
- }
- }
- }
- else
- first = t;
- }
- }
- return first;
-}
-
-// <unresolved-qualifier-level> ::= <simple-id>
-
-template <class C>
-const char*
-parse_unresolved_qualifier_level(const char* first, const char* last, C& db)
-{
- return parse_simple_id(first, last, db);
-}
-
-// <unresolved-name>
-// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
-// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
-// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
-// # A::x, N::y, A<T>::z; "gs" means leading "::"
-// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
-// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
-// # T::N::x /decltype(p)::N::x
-// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
-
-template <class C>
-const char*
-parse_unresolved_name(const char* first, const char* last, C& db)
-{
- if (last - first > 2)
- {
- const char* t = first;
- bool global = false;
- if (t[0] == 'g' && t[1] == 's')
- {
- global = true;
- t += 2;
- }
- const char* t2 = parse_base_unresolved_name(t, last, db);
- if (t2 != t)
- {
- if (global)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "::");
- }
- first = t2;
- }
- else if (last - t > 2 && t[0] == 's' && t[1] == 'r')
- {
- if (t[2] == 'N')
- {
- t += 3;
- const char* t1 = parse_unresolved_type(t, last, db);
- if (t1 == t || t1 == last)
- return first;
- t = t1;
- t1 = parse_template_args(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += std::move(args);
- t = t1;
- if (t == last)
- {
- db.names.pop_back();
- return first;
- }
- }
- while (*t != 'E')
- {
- t1 = parse_unresolved_qualifier_level(t, last, db);
- if (t1 == t || t1 == last || db.names.size() < 2)
- return first;
- auto s = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += "::" + std::move(s);
- t = t1;
- }
- ++t;
- t1 = parse_base_unresolved_name(t, last, db);
- if (t1 == t)
- {
- if (!db.names.empty())
- db.names.pop_back();
- return first;
- }
- if (db.names.size() < 2)
- return first;
- auto s = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += "::" + std::move(s);
- first = t1;
- }
- else
- {
- t += 2;
- const char* t1 = parse_unresolved_type(t, last, db);
- if (t1 != t)
- {
- t = t1;
- t1 = parse_template_args(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += std::move(args);
- t = t1;
- }
- t1 = parse_base_unresolved_name(t, last, db);
- if (t1 == t)
- {
- if (!db.names.empty())
- db.names.pop_back();
- return first;
- }
- if (db.names.size() < 2)
- return first;
- auto s = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += "::" + std::move(s);
- first = t1;
- }
- else
- {
- t1 = parse_unresolved_qualifier_level(t, last, db);
- if (t1 == t || t1 == last)
- return first;
- t = t1;
- if (global)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "::");
- }
- while (*t != 'E')
- {
- t1 = parse_unresolved_qualifier_level(t, last, db);
- if (t1 == t || t1 == last || db.names.size() < 2)
- return first;
- auto s = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += "::" + std::move(s);
- t = t1;
- }
- ++t;
- t1 = parse_base_unresolved_name(t, last, db);
- if (t1 == t)
- {
- if (!db.names.empty())
- db.names.pop_back();
- return first;
- }
- if (db.names.size() < 2)
- return first;
- auto s = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += "::" + std::move(s);
- first = t1;
- }
- }
- }
- }
- return first;
-}
-
-// dt <expression> <unresolved-name> # expr.name
-
-template <class C>
-const char*
-parse_dot_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'd' && first[1] == 't')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- {
- const char* t1 = parse_unresolved_name(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto name = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += "." + name;
- first = t1;
- }
- }
- }
- return first;
-}
-
-// cl <expression>+ E # call
-
-template <class C>
-const char*
-parse_call_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 4 && first[0] == 'c' && first[1] == 'l')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- {
- if (t == last)
- return first;
- if (db.names.empty())
- return first;
- db.names.back().first += db.names.back().second;
- db.names.back().second = typename C::String();
- db.names.back().first.append("(");
- bool first_expr = true;
- while (*t != 'E')
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 == t || t1 == last)
- return first;
- if (db.names.empty())
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- if (!tmp.empty())
- {
- if (db.names.empty())
- return first;
- if (!first_expr)
- {
- db.names.back().first.append(", ");
- first_expr = false;
- }
- db.names.back().first.append(tmp);
- }
- t = t1;
- }
- ++t;
- if (db.names.empty())
- return first;
- db.names.back().first.append(")");
- first = t;
- }
- }
- return first;
-}
-
-// [gs] nw <expression>* _ <type> E # new (expr-list) type
-// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
-// [gs] na <expression>* _ <type> E # new[] (expr-list) type
-// [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
-// <initializer> ::= pi <expression>* E # parenthesized initialization
-
-template <class C>
-const char*
-parse_new_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 4)
- {
- const char* t = first;
- bool parsed_gs = false;
- if (t[0] == 'g' && t[1] == 's')
- {
- t += 2;
- parsed_gs = true;
- }
- if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a'))
- {
- bool is_array = t[1] == 'a';
- t += 2;
- if (t == last)
- return first;
- bool has_expr_list = false;
- bool first_expr = true;
- while (*t != '_')
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 == t || t1 == last)
- return first;
- has_expr_list = true;
- if (!first_expr)
- {
- if (db.names.empty())
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- if (!tmp.empty())
- {
- if (db.names.empty())
- return first;
- db.names.back().first.append(", ");
- db.names.back().first.append(tmp);
- first_expr = false;
- }
- }
- t = t1;
- }
- ++t;
- const char* t1 = parse_type(t, last, db);
- if (t1 == t || t1 == last)
- return first;
- t = t1;
- bool has_init = false;
- if (last - t >= 3 && t[0] == 'p' && t[1] == 'i')
- {
- t += 2;
- has_init = true;
- first_expr = true;
- while (*t != 'E')
- {
- t1 = parse_expression(t, last, db);
- if (t1 == t || t1 == last)
- return first;
- if (!first_expr)
- {
- if (db.names.empty())
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- if (!tmp.empty())
- {
- if (db.names.empty())
- return first;
- db.names.back().first.append(", ");
- db.names.back().first.append(tmp);
- first_expr = false;
- }
- }
- t = t1;
- }
- }
- if (*t != 'E')
- return first;
- typename C::String init_list;
- if (has_init)
- {
- if (db.names.empty())
- return first;
- init_list = db.names.back().move_full();
- db.names.pop_back();
- }
- if (db.names.empty())
- return first;
- auto type = db.names.back().move_full();
- db.names.pop_back();
- typename C::String expr_list;
- if (has_expr_list)
- {
- if (db.names.empty())
- return first;
- expr_list = db.names.back().move_full();
- db.names.pop_back();
- }
- typename C::String r;
- if (parsed_gs)
- r = "::";
- if (is_array)
- r += "[] ";
- else
- r += " ";
- if (has_expr_list)
- r += "(" + expr_list + ") ";
- r += type;
- if (has_init)
- r += " (" + init_list + ")";
- db.names.push_back(std::move(r));
- first = t+1;
- }
- }
- return first;
-}
-
-// cv <type> <expression> # conversion with one argument
-// cv <type> _ <expression>* E # conversion with a different number of arguments
-
-template <class C>
-const char*
-parse_conversion_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'c' && first[1] == 'v')
- {
- bool try_to_parse_template_args = db.try_to_parse_template_args;
- db.try_to_parse_template_args = false;
- const char* t = parse_type(first+2, last, db);
- db.try_to_parse_template_args = try_to_parse_template_args;
- if (t != first+2 && t != last)
- {
- if (*t != '_')
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 == t)
- return first;
- t = t1;
- }
- else
- {
- ++t;
- if (t == last)
- return first;
- if (*t == 'E')
- db.names.emplace_back();
- else
- {
- bool first_expr = true;
- while (*t != 'E')
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 == t || t1 == last)
- return first;
- if (!first_expr)
- {
- if (db.names.empty())
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- if (!tmp.empty())
- {
- if (db.names.empty())
- return first;
- db.names.back().first.append(", ");
- db.names.back().first.append(tmp);
- first_expr = false;
- }
- }
- t = t1;
- }
- }
- ++t;
- }
- if (db.names.size() < 2)
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- db.names.back() = "(" + db.names.back().move_full() + ")(" + tmp + ")";
- first = t;
- }
- }
- return first;
-}
-
-// pt <expression> <expression> # expr->name
-
-template <class C>
-const char*
-parse_arrow_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'p' && first[1] == 't')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += "->";
- db.names.back().first += tmp;
- first = t1;
- }
- }
- }
- return first;
-}
-
-// <ref-qualifier> ::= R # & ref-qualifier
-// <ref-qualifier> ::= O # && ref-qualifier
-
-// <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
-
-template <class C>
-const char*
-parse_function_type(const char* first, const char* last, C& db)
-{
- if (first != last && *first == 'F')
- {
- const char* t = first+1;
- if (t != last)
- {
- if (*t == 'Y')
- {
- /* extern "C" */
- if (++t == last)
- return first;
- }
- const char* t1 = parse_type(t, last, db);
- if (t1 != t)
- {
- t = t1;
- typename C::String sig("(");
- int ref_qual = 0;
- while (true)
- {
- if (t == last)
- {
- db.names.pop_back();
- return first;
- }
- if (*t == 'E')
- {
- ++t;
- break;
- }
- if (*t == 'v')
- {
- ++t;
- continue;
- }
- if (*t == 'R' && t+1 != last && t[1] == 'E')
- {
- ref_qual = 1;
- ++t;
- continue;
- }
- if (*t == 'O' && t+1 != last && t[1] == 'E')
- {
- ref_qual = 2;
- ++t;
- continue;
- }
- size_t k0 = db.names.size();
- t1 = parse_type(t, last, db);
- size_t k1 = db.names.size();
- if (t1 == t || t1 == last)
- return first;
- for (size_t k = k0; k < k1; ++k)
- {
- if (sig.size() > 1)
- sig += ", ";
- sig += db.names[k].move_full();
- }
- for (size_t k = k0; k < k1; ++k)
- db.names.pop_back();
- t = t1;
- }
- sig += ")";
- switch (ref_qual)
- {
- case 1:
- sig += " &";
- break;
- case 2:
- sig += " &&";
- break;
- }
- if (db.names.empty())
- return first;
- db.names.back().first += " ";
- db.names.back().second.insert(0, sig);
- first = t;
- }
- }
- }
- return first;
-}
-
-// <pointer-to-member-type> ::= M <class type> <member type>
-
-template <class C>
-const char*
-parse_pointer_to_member_type(const char* first, const char* last, C& db)
-{
- if (first != last && *first == 'M')
- {
- const char* t = parse_type(first+1, last, db);
- if (t != first+1)
- {
- const char* t2 = parse_type(t, last, db);
- if (t2 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto func = std::move(db.names.back());
- db.names.pop_back();
- auto class_type = std::move(db.names.back());
- if (!func.second.empty() && func.second.front() == '(')
- {
- db.names.back().first = std::move(func.first) + "(" + class_type.move_full() + "::*";
- db.names.back().second = ")" + std::move(func.second);
- }
- else
- {
- db.names.back().first = std::move(func.first) + " " + class_type.move_full() + "::*";
- db.names.back().second = std::move(func.second);
- }
- first = t2;
- }
- }
- }
- return first;
-}
-
-// <array-type> ::= A <positive dimension number> _ <element type>
-// ::= A [<dimension expression>] _ <element type>
-
-template <class C>
-const char*
-parse_array_type(const char* first, const char* last, C& db)
-{
- if (first != last && *first == 'A' && first+1 != last)
- {
- if (first[1] == '_')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- if (db.names.back().second.substr(0, 2) == " [")
- db.names.back().second.erase(0, 1);
- db.names.back().second.insert(0, " []");
- first = t;
- }
- }
- else if ('1' <= first[1] && first[1] <= '9')
- {
- const char* t = parse_number(first+1, last);
- if (t != last && *t == '_')
- {
- const char* t2 = parse_type(t+1, last, db);
- if (t2 != t+1)
- {
- if (db.names.empty())
- return first;
- if (db.names.back().second.substr(0, 2) == " [")
- db.names.back().second.erase(0, 1);
- db.names.back().second.insert(0, " [" + typename C::String(first+1, t) + "]");
- first = t2;
- }
- }
- }
- else
- {
- const char* t = parse_expression(first+1, last, db);
- if (t != first+1 && t != last && *t == '_')
- {
- const char* t2 = parse_type(++t, last, db);
- if (t2 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto type = std::move(db.names.back());
- db.names.pop_back();
- auto expr = std::move(db.names.back());
- db.names.back().first = std::move(type.first);
- if (type.second.substr(0, 2) == " [")
- type.second.erase(0, 1);
- db.names.back().second = " [" + expr.move_full() + "]" + std::move(type.second);
- first = t2;
- }
- }
- }
- }
- return first;
-}
-
-// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
-// ::= DT <expression> E # decltype of an expression (C++0x)
-
-template <class C>
-const char*
-parse_decltype(const char* first, const char* last, C& db)
-{
- if (last - first >= 4 && first[0] == 'D')
- {
- switch (first[1])
- {
- case 't':
- case 'T':
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2 && t != last && *t == 'E')
- {
- if (db.names.empty())
- return first;
- db.names.back() = "decltype(" + db.names.back().move_full() + ")";
- first = t+1;
- }
- }
- break;
- }
- }
- return first;
-}
-
-// extension:
-// <vector-type> ::= Dv <positive dimension number> _
-// <extended element type>
-// ::= Dv [<dimension expression>] _ <element type>
-// <extended element type> ::= <element type>
-// ::= p # AltiVec vector pixel
-
-template <class C>
-const char*
-parse_vector_type(const char* first, const char* last, C& db)
-{
- if (last - first > 3 && first[0] == 'D' && first[1] == 'v')
- {
- if ('1' <= first[2] && first[2] <= '9')
- {
- const char* t = parse_number(first+2, last);
- if (t == last || *t != '_')
- return first;
- const char* num = first + 2;
- size_t sz = static_cast<size_t>(t - num);
- if (++t != last)
- {
- if (*t != 'p')
- {
- const char* t1 = parse_type(t, last, db);
- if (t1 != t)
- {
- if (db.names.empty())
- return first;
- db.names.back().first += " vector[" + typename C::String(num, sz) + "]";
- first = t1;
- }
- }
- else
- {
- ++t;
- db.names.push_back("pixel vector[" + typename C::String(num, sz) + "]");
- first = t;
- }
- }
- }
- else
- {
- typename C::String num;
- const char* t1 = first+2;
- if (*t1 != '_')
- {
- const char* t = parse_expression(t1, last, db);
- if (t != t1)
- {
- if (db.names.empty())
- return first;
- num = db.names.back().move_full();
- db.names.pop_back();
- t1 = t;
- }
- }
- if (t1 != last && *t1 == '_' && ++t1 != last)
- {
- const char* t = parse_type(t1, last, db);
- if (t != t1)
- {
- if (db.names.empty())
- return first;
- db.names.back().first += " vector[" + num + "]";
- first = t;
- }
- }
- }
- }
- return first;
-}
-
-// <type> ::= <builtin-type>
-// ::= <function-type>
-// ::= <class-enum-type>
-// ::= <array-type>
-// ::= <pointer-to-member-type>
-// ::= <template-param>
-// ::= <template-template-param> <template-args>
-// ::= <decltype>
-// ::= <substitution>
-// ::= <CV-qualifiers> <type>
-// ::= P <type> # pointer-to
-// ::= R <type> # reference-to
-// ::= O <type> # rvalue reference-to (C++0x)
-// ::= C <type> # complex pair (C 2000)
-// ::= G <type> # imaginary (C 2000)
-// ::= Dp <type> # pack expansion (C++0x)
-// ::= U <source-name> <type> # vendor extended type qualifier
-// extension := U <objc-name> <objc-type> # objc-type<identifier>
-// extension := <vector-type> # <vector-type> starts with Dv
-
-// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
-// <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
-
-template <class C>
-const char*
-parse_type(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- switch (*first)
- {
- case 'r':
- case 'V':
- case 'K':
- {
- unsigned cv = 0;
- const char* t = parse_cv_qualifiers(first, last, cv);
- if (t != first)
- {
- bool is_function = *t == 'F';
- size_t k0 = db.names.size();
- const char* t1 = parse_type(t, last, db);
- size_t k1 = db.names.size();
- if (t1 != t)
- {
- if (is_function)
- db.subs.pop_back();
- db.subs.emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- {
- if (is_function)
- {
- size_t p = db.names[k].second.size();
- if (db.names[k].second[p-2] == '&')
- p -= 3;
- else if (db.names[k].second.back() == '&')
- p -= 2;
- if (cv & 1)
- {
- db.names[k].second.insert(p, " const");
- p += 6;
- }
- if (cv & 2)
- {
- db.names[k].second.insert(p, " volatile");
- p += 9;
- }
- if (cv & 4)
- db.names[k].second.insert(p, " restrict");
- }
- else
- {
- if (cv & 1)
- db.names[k].first.append(" const");
- if (cv & 2)
- db.names[k].first.append(" volatile");
- if (cv & 4)
- db.names[k].first.append(" restrict");
- }
- db.subs.back().push_back(db.names[k]);
- }
- first = t1;
- }
- }
- }
- break;
- default:
- {
- const char* t = parse_builtin_type(first, last, db);
- if (t != first)
- {
- first = t;
- }
- else
- {
- switch (*first)
- {
- case 'A':
- t = parse_array_type(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- first = t;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- }
- break;
- case 'C':
- t = parse_type(first+1, last, db);
- if (t != first+1)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.append(" complex");
- first = t;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- }
- break;
- case 'F':
- t = parse_function_type(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- first = t;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- }
- break;
- case 'G':
- t = parse_type(first+1, last, db);
- if (t != first+1)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.append(" imaginary");
- first = t;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- }
- break;
- case 'M':
- t = parse_pointer_to_member_type(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- first = t;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- }
- break;
- case 'O':
- {
- size_t k0 = db.names.size();
- t = parse_type(first+1, last, db);
- size_t k1 = db.names.size();
- if (t != first+1)
- {
- db.subs.emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- {
- if (db.names[k].second.substr(0, 2) == " [")
- {
- db.names[k].first += " (";
- db.names[k].second.insert(0, ")");
- }
- else if (!db.names[k].second.empty() &&
- db.names[k].second.front() == '(')
- {
- db.names[k].first += "(";
- db.names[k].second.insert(0, ")");
- }
- db.names[k].first.append("&&");
- db.subs.back().push_back(db.names[k]);
- }
- first = t;
- }
- break;
- }
- case 'P':
- {
- size_t k0 = db.names.size();
- t = parse_type(first+1, last, db);
- size_t k1 = db.names.size();
- if (t != first+1)
- {
- db.subs.emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- {
- if (db.names[k].second.substr(0, 2) == " [")
- {
- db.names[k].first += " (";
- db.names[k].second.insert(0, ")");
- }
- else if (!db.names[k].second.empty() &&
- db.names[k].second.front() == '(')
- {
- db.names[k].first += "(";
- db.names[k].second.insert(0, ")");
- }
- if (first[1] != 'U' || db.names[k].first.substr(0, 12) != "objc_object<")
- {
- db.names[k].first.append("*");
- }
- else
- {
- db.names[k].first.replace(0, 11, "id");
- }
- db.subs.back().push_back(db.names[k]);
- }
- first = t;
- }
- break;
- }
- case 'R':
- {
- size_t k0 = db.names.size();
- t = parse_type(first+1, last, db);
- size_t k1 = db.names.size();
- if (t != first+1)
- {
- db.subs.emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- {
- if (db.names[k].second.substr(0, 2) == " [")
- {
- db.names[k].first += " (";
- db.names[k].second.insert(0, ")");
- }
- else if (!db.names[k].second.empty() &&
- db.names[k].second.front() == '(')
- {
- db.names[k].first += "(";
- db.names[k].second.insert(0, ")");
- }
- db.names[k].first.append("&");
- db.subs.back().push_back(db.names[k]);
- }
- first = t;
- }
- break;
- }
- case 'T':
- {
- size_t k0 = db.names.size();
- t = parse_template_param(first, last, db);
- size_t k1 = db.names.size();
- if (t != first)
- {
- db.subs.emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- db.subs.back().push_back(db.names[k]);
- if (db.try_to_parse_template_args && k1 == k0+1)
- {
- const char* t1 = parse_template_args(t, last, db);
- if (t1 != t)
- {
- auto args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += std::move(args);
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- t = t1;
- }
- }
- first = t;
- }
- break;
- }
- case 'U':
- if (first+1 != last)
- {
- t = parse_source_name(first+1, last, db);
- if (t != first+1)
- {
- const char* t2 = parse_type(t, last, db);
- if (t2 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto type = db.names.back().move_full();
- db.names.pop_back();
- if (db.names.back().first.substr(0, 9) != "objcproto")
- {
- db.names.back() = type + " " + db.names.back().move_full();
- }
- else
- {
- auto proto = db.names.back().move_full();
- db.names.pop_back();
- t = parse_source_name(proto.data() + 9, proto.data() + proto.size(), db);
- if (t != proto.data() + 9)
- {
- db.names.back() = type + "<" + db.names.back().move_full() + ">";
- }
- else
- {
- db.names.push_back(type + " " + proto);
- }
- }
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t2;
- }
- }
- }
- break;
- case 'S':
- if (first+1 != last && first[1] == 't')
- {
- t = parse_name(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- }
- else
- {
- t = parse_substitution(first, last, db);
- if (t != first)
- {
- first = t;
- // Parsed a substitution. If the substitution is a
- // <template-param> it might be followed by <template-args>.
- t = parse_template_args(first, last, db);
- if (t != first)
- {
- if (db.names.size() < 2)
- return first;
- auto template_args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += template_args;
- // Need to create substitution for <template-template-param> <template-args>
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- }
- }
- break;
- case 'D':
- if (first+1 != last)
- {
- switch (first[1])
- {
- case 'p':
- {
- size_t k0 = db.names.size();
- t = parse_type(first+2, last, db);
- size_t k1 = db.names.size();
- if (t != first+2)
- {
- db.subs.emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- db.subs.back().push_back(db.names[k]);
- first = t;
- return first;
- }
- break;
- }
- case 't':
- case 'T':
- t = parse_decltype(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- return first;
- }
- break;
- case 'v':
- t = parse_vector_type(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- return first;
- }
- break;
- }
- }
- LLVM_FALLTHROUGH;
- default:
- // must check for builtin-types before class-enum-types to avoid
- // ambiguities with operator-names
- t = parse_builtin_type(first, last, db);
- if (t != first)
- {
- first = t;
- }
- else
- {
- t = parse_name(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- }
- break;
- }
- }
- break;
- }
- }
- }
- return first;
-}
-
-// <operator-name>
-// ::= aa # &&
-// ::= ad # & (unary)
-// ::= an # &
-// ::= aN # &=
-// ::= aS # =
-// ::= cl # ()
-// ::= cm # ,
-// ::= co # ~
-// ::= cv <type> # (cast)
-// ::= da # delete[]
-// ::= de # * (unary)
-// ::= dl # delete
-// ::= dv # /
-// ::= dV # /=
-// ::= eo # ^
-// ::= eO # ^=
-// ::= eq # ==
-// ::= ge # >=
-// ::= gt # >
-// ::= ix # []
-// ::= le # <=
-// ::= li <source-name> # operator ""
-// ::= ls # <<
-// ::= lS # <<=
-// ::= lt # <
-// ::= mi # -
-// ::= mI # -=
-// ::= ml # *
-// ::= mL # *=
-// ::= mm # -- (postfix in <expression> context)
-// ::= na # new[]
-// ::= ne # !=
-// ::= ng # - (unary)
-// ::= nt # !
-// ::= nw # new
-// ::= oo # ||
-// ::= or # |
-// ::= oR # |=
-// ::= pm # ->*
-// ::= pl # +
-// ::= pL # +=
-// ::= pp # ++ (postfix in <expression> context)
-// ::= ps # + (unary)
-// ::= pt # ->
-// ::= qu # ?
-// ::= rm # %
-// ::= rM # %=
-// ::= rs # >>
-// ::= rS # >>=
-// ::= v <digit> <source-name> # vendor extended operator
-
-template <class C>
-const char*
-parse_operator_name(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- switch (first[0])
- {
- case 'a':
- switch (first[1])
- {
- case 'a':
- db.names.push_back("operator&&");
- first += 2;
- break;
- case 'd':
- case 'n':
- db.names.push_back("operator&");
- first += 2;
- break;
- case 'N':
- db.names.push_back("operator&=");
- first += 2;
- break;
- case 'S':
- db.names.push_back("operator=");
- first += 2;
- break;
- }
- break;
- case 'c':
- switch (first[1])
- {
- case 'l':
- db.names.push_back("operator()");
- first += 2;
- break;
- case 'm':
- db.names.push_back("operator,");
- first += 2;
- break;
- case 'o':
- db.names.push_back("operator~");
- first += 2;
- break;
- case 'v':
- {
- bool try_to_parse_template_args = db.try_to_parse_template_args;
- db.try_to_parse_template_args = false;
- const char* t = parse_type(first+2, last, db);
- db.try_to_parse_template_args = try_to_parse_template_args;
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "operator ");
- db.parsed_ctor_dtor_cv = true;
- first = t;
- }
- }
- break;
- }
- break;
- case 'd':
- switch (first[1])
- {
- case 'a':
- db.names.push_back("operator delete[]");
- first += 2;
- break;
- case 'e':
- db.names.push_back("operator*");
- first += 2;
- break;
- case 'l':
- db.names.push_back("operator delete");
- first += 2;
- break;
- case 'v':
- db.names.push_back("operator/");
- first += 2;
- break;
- case 'V':
- db.names.push_back("operator/=");
- first += 2;
- break;
- }
- break;
- case 'e':
- switch (first[1])
- {
- case 'o':
- db.names.push_back("operator^");
- first += 2;
- break;
- case 'O':
- db.names.push_back("operator^=");
- first += 2;
- break;
- case 'q':
- db.names.push_back("operator==");
- first += 2;
- break;
- }
- break;
- case 'g':
- switch (first[1])
- {
- case 'e':
- db.names.push_back("operator>=");
- first += 2;
- break;
- case 't':
- db.names.push_back("operator>");
- first += 2;
- break;
- }
- break;
- case 'i':
- if (first[1] == 'x')
- {
- db.names.push_back("operator[]");
- first += 2;
- }
- break;
- case 'l':
- switch (first[1])
- {
- case 'e':
- db.names.push_back("operator<=");
- first += 2;
- break;
- case 'i':
- {
- const char* t = parse_source_name(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "operator\"\" ");
- first = t;
- }
- }
- break;
- case 's':
- db.names.push_back("operator<<");
- first += 2;
- break;
- case 'S':
- db.names.push_back("operator<<=");
- first += 2;
- break;
- case 't':
- db.names.push_back("operator<");
- first += 2;
- break;
- }
- break;
- case 'm':
- switch (first[1])
- {
- case 'i':
- db.names.push_back("operator-");
- first += 2;
- break;
- case 'I':
- db.names.push_back("operator-=");
- first += 2;
- break;
- case 'l':
- db.names.push_back("operator*");
- first += 2;
- break;
- case 'L':
- db.names.push_back("operator*=");
- first += 2;
- break;
- case 'm':
- db.names.push_back("operator--");
- first += 2;
- break;
- }
- break;
- case 'n':
- switch (first[1])
- {
- case 'a':
- db.names.push_back("operator new[]");
- first += 2;
- break;
- case 'e':
- db.names.push_back("operator!=");
- first += 2;
- break;
- case 'g':
- db.names.push_back("operator-");
- first += 2;
- break;
- case 't':
- db.names.push_back("operator!");
- first += 2;
- break;
- case 'w':
- db.names.push_back("operator new");
- first += 2;
- break;
- }
- break;
- case 'o':
- switch (first[1])
- {
- case 'o':
- db.names.push_back("operator||");
- first += 2;
- break;
- case 'r':
- db.names.push_back("operator|");
- first += 2;
- break;
- case 'R':
- db.names.push_back("operator|=");
- first += 2;
- break;
- }
- break;
- case 'p':
- switch (first[1])
- {
- case 'm':
- db.names.push_back("operator->*");
- first += 2;
- break;
- case 'l':
- db.names.push_back("operator+");
- first += 2;
- break;
- case 'L':
- db.names.push_back("operator+=");
- first += 2;
- break;
- case 'p':
- db.names.push_back("operator++");
- first += 2;
- break;
- case 's':
- db.names.push_back("operator+");
- first += 2;
- break;
- case 't':
- db.names.push_back("operator->");
- first += 2;
- break;
- }
- break;
- case 'q':
- if (first[1] == 'u')
- {
- db.names.push_back("operator?");
- first += 2;
- }
- break;
- case 'r':
- switch (first[1])
- {
- case 'm':
- db.names.push_back("operator%");
- first += 2;
- break;
- case 'M':
- db.names.push_back("operator%=");
- first += 2;
- break;
- case 's':
- db.names.push_back("operator>>");
- first += 2;
- break;
- case 'S':
- db.names.push_back("operator>>=");
- first += 2;
- break;
- }
- break;
- case 'v':
- if (std::isdigit(first[1]))
- {
- const char* t = parse_source_name(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "operator ");
- first = t;
- }
- }
- break;
- }
- }
- return first;
-}
-
-template <class C>
-const char*
-parse_integer_literal(const char* first, const char* last, const typename C::String& lit, C& db)
-{
- const char* t = parse_number(first, last);
- if (t != first && t != last && *t == 'E')
- {
- if (lit.size() > 3)
- db.names.push_back("(" + lit + ")");
- else
- db.names.emplace_back();
- if (*first == 'n')
- {
- db.names.back().first += '-';
- ++first;
- }
- db.names.back().first.append(first, t);
- if (lit.size() <= 3)
- db.names.back().first += lit;
- first = t+1;
- }
- return first;
-}
-
-// <expr-primary> ::= L <type> <value number> E # integer literal
-// ::= L <type> <value float> E # floating literal
-// ::= L <string type> E # string literal
-// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
-// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
-// ::= L <mangled-name> E # external name
-
-template <class C>
-const char*
-parse_expr_primary(const char* first, const char* last, C& db)
-{
- if (last - first >= 4 && *first == 'L')
- {
- switch (first[1])
- {
- case 'w':
- {
- const char* t = parse_integer_literal(first+2, last, "wchar_t", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'b':
- if (first[3] == 'E')
- {
- switch (first[2])
- {
- case '0':
- db.names.push_back("false");
- first += 4;
- break;
- case '1':
- db.names.push_back("true");
- first += 4;
- break;
- }
- }
- break;
- case 'c':
- {
- const char* t = parse_integer_literal(first+2, last, "char", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'a':
- {
- const char* t = parse_integer_literal(first+2, last, "signed char", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'h':
- {
- const char* t = parse_integer_literal(first+2, last, "unsigned char", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 's':
- {
- const char* t = parse_integer_literal(first+2, last, "short", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 't':
- {
- const char* t = parse_integer_literal(first+2, last, "unsigned short", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'i':
- {
- const char* t = parse_integer_literal(first+2, last, "", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'j':
- {
- const char* t = parse_integer_literal(first+2, last, "u", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'l':
- {
- const char* t = parse_integer_literal(first+2, last, "l", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'm':
- {
- const char* t = parse_integer_literal(first+2, last, "ul", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'x':
- {
- const char* t = parse_integer_literal(first+2, last, "ll", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'y':
- {
- const char* t = parse_integer_literal(first+2, last, "ull", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'n':
- {
- const char* t = parse_integer_literal(first+2, last, "__int128", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'o':
- {
- const char* t = parse_integer_literal(first+2, last, "unsigned __int128", db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'f':
- {
- const char* t = parse_floating_number<float>(first+2, last, db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'd':
- {
- const char* t = parse_floating_number<double>(first+2, last, db);
- if (t != first+2)
- first = t;
- }
- break;
- case 'e':
- {
- const char* t = parse_floating_number<long double>(first+2, last, db);
- if (t != first+2)
- first = t;
- }
- break;
- case '_':
- if (first[2] == 'Z')
- {
- const char* t = parse_encoding(first+3, last, db);
- if (t != first+3 && t != last && *t == 'E')
- first = t+1;
- }
- break;
- case 'T':
- // Invalid mangled name per
- // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
- break;
- default:
- {
- // might be named type
- const char* t = parse_type(first+1, last, db);
- if (t != first+1 && t != last)
- {
- if (*t != 'E')
- {
- const char* n = t;
- for (; n != last && isdigit(*n); ++n)
- ;
- if (n != t && n != last && *n == 'E')
- {
- if (db.names.empty())
- return first;
- db.names.back() = "(" + db.names.back().move_full() + ")" + typename C::String(t, n);
- first = n+1;
- break;
- }
- }
- else
- {
- first = t+1;
- break;
- }
- }
- }
- }
- }
- return first;
-}
-
-template <class String>
-String
-base_name(String& s)
-{
- if (s.empty())
- return s;
- if (s == "std::string")
- {
- s = "std::basic_string<char, std::char_traits<char>, std::allocator<char> >";
- return "basic_string";
- }
- if (s == "std::istream")
- {
- s = "std::basic_istream<char, std::char_traits<char> >";
- return "basic_istream";
- }
- if (s == "std::ostream")
- {
- s = "std::basic_ostream<char, std::char_traits<char> >";
- return "basic_ostream";
- }
- if (s == "std::iostream")
- {
- s = "std::basic_iostream<char, std::char_traits<char> >";
- return "basic_iostream";
- }
- const char* const pf = s.data();
- const char* pe = pf + s.size();
- if (pe[-1] == '>')
- {
- unsigned c = 1;
- while (true)
- {
- if (--pe == pf)
- return String();
- if (pe[-1] == '<')
- {
- if (--c == 0)
- {
- --pe;
- break;
- }
- }
- else if (pe[-1] == '>')
- ++c;
- }
- }
- const char* p0 = pe - 1;
- for (; p0 != pf; --p0)
- {
- if (*p0 == ':')
- {
- ++p0;
- break;
- }
- }
- return String(p0, pe);
-}
-
-// <ctor-dtor-name> ::= C1 # complete object constructor
-// ::= C2 # base object constructor
-// ::= C3 # complete object allocating constructor
-// extension ::= C5 # ?
-// ::= D0 # deleting destructor
-// ::= D1 # complete object destructor
-// ::= D2 # base object destructor
-// extension ::= D5 # ?
-
-template <class C>
-const char*
-parse_ctor_dtor_name(const char* first, const char* last, C& db)
-{
- if (last-first >= 2 && !db.names.empty())
- {
- switch (first[0])
- {
- case 'C':
- switch (first[1])
- {
- case '1':
- case '2':
- case '3':
- case '5':
- if (db.names.empty())
- return first;
- db.names.push_back(base_name(db.names.back().first));
- first += 2;
- db.parsed_ctor_dtor_cv = true;
- break;
- }
- break;
- case 'D':
- switch (first[1])
- {
- case '0':
- case '1':
- case '2':
- case '5':
- if (db.names.empty())
- return first;
- db.names.push_back("~" + base_name(db.names.back().first));
- first += 2;
- db.parsed_ctor_dtor_cv = true;
- break;
- }
- break;
- }
- }
- return first;
-}
-
-// <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
-// ::= <closure-type-name>
-//
-// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
-//
-// <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
-
-template <class C>
-const char*
-parse_unnamed_type_name(const char* first, const char* last, C& db)
-{
- if (last - first > 2 && first[0] == 'U')
- {
- char type = first[1];
- switch (type)
- {
- case 't':
- {
- db.names.push_back(typename C::String("'unnamed"));
- const char* t0 = first+2;
- if (t0 == last)
- {
- db.names.pop_back();
- return first;
- }
- if (std::isdigit(*t0))
- {
- const char* t1 = t0 + 1;
- while (t1 != last && std::isdigit(*t1))
- ++t1;
- db.names.back().first.append(t0, t1);
- t0 = t1;
- }
- db.names.back().first.push_back('\'');
- if (t0 == last || *t0 != '_')
- {
- db.names.pop_back();
- return first;
- }
- first = t0 + 1;
- }
- break;
- case 'l':
- {
- db.names.push_back(typename C::String("'lambda'("));
- const char* t0 = first+2;
- if (first[2] == 'v')
- {
- db.names.back().first += ')';
- ++t0;
- }
- else
- {
- const char* t1 = parse_type(t0, last, db);
- if (t1 == t0)
- {
- db.names.pop_back();
- return first;
- }
- if (db.names.size() < 2)
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first.append(tmp);
- t0 = t1;
- while (true)
- {
- t1 = parse_type(t0, last, db);
- if (t1 == t0)
- break;
- if (db.names.size() < 2)
- return first;
- tmp = db.names.back().move_full();
- db.names.pop_back();
- if (!tmp.empty())
- {
- db.names.back().first.append(", ");
- db.names.back().first.append(tmp);
- }
- t0 = t1;
- }
- db.names.back().first.append(")");
- }
- if (t0 == last || *t0 != 'E')
- {
- db.names.pop_back();
- return first;
- }
- ++t0;
- if (t0 == last)
- {
- db.names.pop_back();
- return first;
- }
- if (std::isdigit(*t0))
- {
- const char* t1 = t0 + 1;
- while (t1 != last && std::isdigit(*t1))
- ++t1;
- db.names.back().first.insert(db.names.back().first.begin()+7, t0, t1);
- t0 = t1;
- }
- if (t0 == last || *t0 != '_')
- {
- db.names.pop_back();
- return first;
- }
- first = t0 + 1;
- }
- break;
- }
- }
- return first;
-}
-
-// <unqualified-name> ::= <operator-name>
-// ::= <ctor-dtor-name>
-// ::= <source-name>
-// ::= <unnamed-type-name>
-
-template <class C>
-const char*
-parse_unqualified_name(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- const char* t;
- switch (*first)
- {
- case 'C':
- case 'D':
- t = parse_ctor_dtor_name(first, last, db);
- if (t != first)
- first = t;
- break;
- case 'U':
- t = parse_unnamed_type_name(first, last, db);
- if (t != first)
- first = t;
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- t = parse_source_name(first, last, db);
- if (t != first)
- first = t;
- break;
- default:
- t = parse_operator_name(first, last, db);
- if (t != first)
- first = t;
- break;
- };
- }
- return first;
-}
-
-// <unscoped-name> ::= <unqualified-name>
-// ::= St <unqualified-name> # ::std::
-// extension ::= StL<unqualified-name>
-
-template <class C>
-const char*
-parse_unscoped_name(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- const char* t0 = first;
- bool St = false;
- if (first[0] == 'S' && first[1] == 't')
- {
- t0 += 2;
- St = true;
- if (t0 != last && *t0 == 'L')
- ++t0;
- }
- const char* t1 = parse_unqualified_name(t0, last, db);
- if (t1 != t0)
- {
- if (St)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "std::");
- }
- first = t1;
- }
- }
- return first;
-}
-
-// at <type> # alignof (a type)
-
-template <class C>
-const char*
-parse_alignof_type(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'a' && first[1] == 't')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
-}
-
-// az <expression> # alignof (a expression)
-
-template <class C>
-const char*
-parse_alignof_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'a' && first[1] == 'z')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
-}
-
-template <class C>
-const char*
-parse_noexcept_expression(const char* first, const char* last, C& db)
-{
- const char* t1 = parse_expression(first, last, db);
- if (t1 != first)
- {
- if (db.names.empty())
- return first;
- db.names.back().first = "noexcept (" + db.names.back().move_full() + ")";
- first = t1;
- }
- return first;
-}
-
-template <class C>
-const char*
-parse_prefix_expression(const char* first, const char* last, const typename C::String& op, C& db)
-{
- const char* t1 = parse_expression(first, last, db);
- if (t1 != first)
- {
- if (db.names.empty())
- return first;
- db.names.back().first = op + "(" + db.names.back().move_full() + ")";
- first = t1;
- }
- return first;
-}
-
-template <class C>
-const char*
-parse_binary_expression(const char* first, const char* last, const typename C::String& op, C& db)
-{
- const char* t1 = parse_expression(first, last, db);
- if (t1 != first)
- {
- const char* t2 = parse_expression(t1, last, db);
- if (t2 != t1)
- {
- if (db.names.size() < 2)
- return first;
- auto op2 = db.names.back().move_full();
- db.names.pop_back();
- auto op1 = db.names.back().move_full();
- auto& nm = db.names.back().first;
- nm.clear();
- if (op == ">")
- nm += '(';
- nm += "(" + op1 + ") " + op + " (" + op2 + ")";
- if (op == ">")
- nm += ')';
- first = t2;
- }
- else
- db.names.pop_back();
- }
- return first;
-}
-
-// <expression> ::= <unary operator-name> <expression>
-// ::= <binary operator-name> <expression> <expression>
-// ::= <ternary operator-name> <expression> <expression> <expression>
-// ::= cl <expression>+ E # call
-// ::= cv <type> <expression> # conversion with one argument
-// ::= cv <type> _ <expression>* E # conversion with a different number of arguments
-// ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
-// ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
-// ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
-// ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
-// ::= [gs] dl <expression> # delete expression
-// ::= [gs] da <expression> # delete[] expression
-// ::= pp_ <expression> # prefix ++
-// ::= mm_ <expression> # prefix --
-// ::= ti <type> # typeid (type)
-// ::= te <expression> # typeid (expression)
-// ::= dc <type> <expression> # dynamic_cast<type> (expression)
-// ::= sc <type> <expression> # static_cast<type> (expression)
-// ::= cc <type> <expression> # const_cast<type> (expression)
-// ::= rc <type> <expression> # reinterpret_cast<type> (expression)
-// ::= st <type> # sizeof (a type)
-// ::= sz <expression> # sizeof (an expression)
-// ::= at <type> # alignof (a type)
-// ::= az <expression> # alignof (an expression)
-// ::= nx <expression> # noexcept (expression)
-// ::= <template-param>
-// ::= <function-param>
-// ::= dt <expression> <unresolved-name> # expr.name
-// ::= pt <expression> <unresolved-name> # expr->name
-// ::= ds <expression> <expression> # expr.*expr
-// ::= sZ <template-param> # size of a parameter pack
-// ::= sZ <function-param> # size of a function parameter pack
-// ::= sp <expression> # pack expansion
-// ::= tw <expression> # throw expression
-// ::= tr # throw with no operand (rethrow)
-// ::= <unresolved-name> # f(p), N::f(p), ::f(p),
-// # freestanding dependent name (e.g., T::x),
-// # objectless nonstatic member reference
-// ::= <expr-primary>
-
-template <class C>
-const char*
-parse_expression(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- const char* t = first;
- bool parsed_gs = false;
- if (last - first >= 4 && t[0] == 'g' && t[1] == 's')
- {
- t += 2;
- parsed_gs = true;
- }
- switch (*t)
- {
- case 'L':
- first = parse_expr_primary(first, last, db);
- break;
- case 'T':
- first = parse_template_param(first, last, db);
- break;
- case 'f':
- first = parse_function_param(first, last, db);
- break;
- case 'a':
- switch (t[1])
- {
- case 'a':
- t = parse_binary_expression(first+2, last, "&&", db);
- if (t != first+2)
- first = t;
- break;
- case 'd':
- t = parse_prefix_expression(first+2, last, "&", db);
- if (t != first+2)
- first = t;
- break;
- case 'n':
- t = parse_binary_expression(first+2, last, "&", db);
- if (t != first+2)
- first = t;
- break;
- case 'N':
- t = parse_binary_expression(first+2, last, "&=", db);
- if (t != first+2)
- first = t;
- break;
- case 'S':
- t = parse_binary_expression(first+2, last, "=", db);
- if (t != first+2)
- first = t;
- break;
- case 't':
- first = parse_alignof_type(first, last, db);
- break;
- case 'z':
- first = parse_alignof_expr(first, last, db);
- break;
- }
- break;
- case 'c':
- switch (t[1])
- {
- case 'c':
- first = parse_const_cast_expr(first, last, db);
- break;
- case 'l':
- first = parse_call_expr(first, last, db);
- break;
- case 'm':
- t = parse_binary_expression(first+2, last, ",", db);
- if (t != first+2)
- first = t;
- break;
- case 'o':
- t = parse_prefix_expression(first+2, last, "~", db);
- if (t != first+2)
- first = t;
- break;
- case 'v':
- first = parse_conversion_expr(first, last, db);
- break;
- }
- break;
- case 'd':
- switch (t[1])
- {
- case 'a':
- {
- const char* t1 = parse_expression(t+2, last, db);
- if (t1 != t+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
- "delete[] " + db.names.back().move_full();
- first = t1;
- }
- }
- break;
- case 'c':
- first = parse_dynamic_cast_expr(first, last, db);
- break;
- case 'e':
- t = parse_prefix_expression(first+2, last, "*", db);
- if (t != first+2)
- first = t;
- break;
- case 'l':
- {
- const char* t1 = parse_expression(t+2, last, db);
- if (t1 != t+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first = (parsed_gs ? typename C::String("::") : typename C::String()) +
- "delete " + db.names.back().move_full();
- first = t1;
- }
- }
- break;
- case 'n':
- return parse_unresolved_name(first, last, db);
- case 's':
- first = parse_dot_star_expr(first, last, db);
- break;
- case 't':
- first = parse_dot_expr(first, last, db);
- break;
- case 'v':
- t = parse_binary_expression(first+2, last, "/", db);
- if (t != first+2)
- first = t;
- break;
- case 'V':
- t = parse_binary_expression(first+2, last, "/=", db);
- if (t != first+2)
- first = t;
- break;
- }
- break;
- case 'e':
- switch (t[1])
- {
- case 'o':
- t = parse_binary_expression(first+2, last, "^", db);
- if (t != first+2)
- first = t;
- break;
- case 'O':
- t = parse_binary_expression(first+2, last, "^=", db);
- if (t != first+2)
- first = t;
- break;
- case 'q':
- t = parse_binary_expression(first+2, last, "==", db);
- if (t != first+2)
- first = t;
- break;
- }
- break;
- case 'g':
- switch (t[1])
- {
- case 'e':
- t = parse_binary_expression(first+2, last, ">=", db);
- if (t != first+2)
- first = t;
- break;
- case 't':
- t = parse_binary_expression(first+2, last, ">", db);
- if (t != first+2)
- first = t;
- break;
- }
- break;
- case 'i':
- if (t[1] == 'x')
- {
- const char* t1 = parse_expression(first+2, last, db);
- if (t1 != first+2)
- {
- const char* t2 = parse_expression(t1, last, db);
- if (t2 != t1)
- {
- if (db.names.size() < 2)
- return first;
- auto op2 = db.names.back().move_full();
- db.names.pop_back();
- auto op1 = db.names.back().move_full();
- db.names.back() = "(" + op1 + ")[" + op2 + "]";
- first = t2;
- }
- else
- db.names.pop_back();
- }
- }
- break;
- case 'l':
- switch (t[1])
- {
- case 'e':
- t = parse_binary_expression(first+2, last, "<=", db);
- if (t != first+2)
- first = t;
- break;
- case 's':
- t = parse_binary_expression(first+2, last, "<<", db);
- if (t != first+2)
- first = t;
- break;
- case 'S':
- t = parse_binary_expression(first+2, last, "<<=", db);
- if (t != first+2)
- first = t;
- break;
- case 't':
- t = parse_binary_expression(first+2, last, "<", db);
- if (t != first+2)
- first = t;
- break;
- }
- break;
- case 'm':
- switch (t[1])
- {
- case 'i':
- t = parse_binary_expression(first+2, last, "-", db);
- if (t != first+2)
- first = t;
- break;
- case 'I':
- t = parse_binary_expression(first+2, last, "-=", db);
- if (t != first+2)
- first = t;
- break;
- case 'l':
- t = parse_binary_expression(first+2, last, "*", db);
- if (t != first+2)
- first = t;
- break;
- case 'L':
- t = parse_binary_expression(first+2, last, "*=", db);
- if (t != first+2)
- first = t;
- break;
- case 'm':
- if (first+2 != last && first[2] == '_')
- {
- t = parse_prefix_expression(first+3, last, "--", db);
- if (t != first+3)
- first = t;
- }
- else
- {
- const char* t1 = parse_expression(first+2, last, db);
- if (t1 != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back() = "(" + db.names.back().move_full() + ")--";
- first = t1;
- }
- }
- break;
- }
- break;
- case 'n':
- switch (t[1])
- {
- case 'a':
- case 'w':
- first = parse_new_expr(first, last, db);
- break;
- case 'e':
- t = parse_binary_expression(first+2, last, "!=", db);
- if (t != first+2)
- first = t;
- break;
- case 'g':
- t = parse_prefix_expression(first+2, last, "-", db);
- if (t != first+2)
- first = t;
- break;
- case 't':
- t = parse_prefix_expression(first+2, last, "!", db);
- if (t != first+2)
- first = t;
- break;
- case 'x':
- t = parse_noexcept_expression(first+2, last, db);
- if (t != first+2)
- first = t;
- break;
- }
- break;
- case 'o':
- switch (t[1])
- {
- case 'n':
- return parse_unresolved_name(first, last, db);
- case 'o':
- t = parse_binary_expression(first+2, last, "||", db);
- if (t != first+2)
- first = t;
- break;
- case 'r':
- t = parse_binary_expression(first+2, last, "|", db);
- if (t != first+2)
- first = t;
- break;
- case 'R':
- t = parse_binary_expression(first+2, last, "|=", db);
- if (t != first+2)
- first = t;
- break;
- }
- break;
- case 'p':
- switch (t[1])
- {
- case 'm':
- t = parse_binary_expression(first+2, last, "->*", db);
- if (t != first+2)
- first = t;
- break;
- case 'l':
- t = parse_binary_expression(first+2, last, "+", db);
- if (t != first+2)
- first = t;
- break;
- case 'L':
- t = parse_binary_expression(first+2, last, "+=", db);
- if (t != first+2)
- first = t;
- break;
- case 'p':
- if (first+2 != last && first[2] == '_')
- {
- t = parse_prefix_expression(first+3, last, "++", db);
- if (t != first+3)
- first = t;
- }
- else
- {
- const char* t1 = parse_expression(first+2, last, db);
- if (t1 != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back() = "(" + db.names.back().move_full() + ")++";
- first = t1;
- }
- }
- break;
- case 's':
- t = parse_prefix_expression(first+2, last, "+", db);
- if (t != first+2)
- first = t;
- break;
- case 't':
- first = parse_arrow_expr(first, last, db);
- break;
- }
- break;
- case 'q':
- if (t[1] == 'u')
- {
- const char* t1 = parse_expression(first+2, last, db);
- if (t1 != first+2)
- {
- const char* t2 = parse_expression(t1, last, db);
- if (t2 != t1)
- {
- const char* t3 = parse_expression(t2, last, db);
- if (t3 != t2)
- {
- if (db.names.size() < 3)
- return first;
- auto op3 = db.names.back().move_full();
- db.names.pop_back();
- auto op2 = db.names.back().move_full();
- db.names.pop_back();
- auto op1 = db.names.back().move_full();
- db.names.back() = "(" + op1 + ") ? (" + op2 + ") : (" + op3 + ")";
- first = t3;
- }
- else
- {
- db.names.pop_back();
- db.names.pop_back();
- }
- }
- else
- db.names.pop_back();
- }
- }
- break;
- case 'r':
- switch (t[1])
- {
- case 'c':
- first = parse_reinterpret_cast_expr(first, last, db);
- break;
- case 'm':
- t = parse_binary_expression(first+2, last, "%", db);
- if (t != first+2)
- first = t;
- break;
- case 'M':
- t = parse_binary_expression(first+2, last, "%=", db);
- if (t != first+2)
- first = t;
- break;
- case 's':
- t = parse_binary_expression(first+2, last, ">>", db);
- if (t != first+2)
- first = t;
- break;
- case 'S':
- t = parse_binary_expression(first+2, last, ">>=", db);
- if (t != first+2)
- first = t;
- break;
- }
- break;
- case 's':
- switch (t[1])
- {
- case 'c':
- first = parse_static_cast_expr(first, last, db);
- break;
- case 'p':
- first = parse_pack_expansion(first, last, db);
- break;
- case 'r':
- return parse_unresolved_name(first, last, db);
- case 't':
- first = parse_sizeof_type_expr(first, last, db);
- break;
- case 'z':
- first = parse_sizeof_expr_expr(first, last, db);
- break;
- case 'Z':
- if (last - t >= 3)
- {
- switch (t[2])
- {
- case 'T':
- first = parse_sizeof_param_pack_expr(first, last, db);
- break;
- case 'f':
- first = parse_sizeof_function_param_pack_expr(first, last, db);
- break;
- }
- }
- break;
- }
- break;
- case 't':
- switch (t[1])
- {
- case 'e':
- case 'i':
- first = parse_typeid_expr(first, last, db);
- break;
- case 'r':
- db.names.push_back("throw");
- first += 2;
- break;
- case 'w':
- first = parse_throw_expr(first, last, db);
- break;
- }
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return parse_unresolved_name(first, last, db);
- }
- }
- return first;
-}
-
-// <template-arg> ::= <type> # type or template
-// ::= X <expression> E # expression
-// ::= <expr-primary> # simple expressions
-// ::= J <template-arg>* E # argument pack
-// ::= LZ <encoding> E # extension
-
-template <class C>
-const char*
-parse_template_arg(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- const char* t;
- switch (*first)
- {
- case 'X':
- t = parse_expression(first+1, last, db);
- if (t != first+1)
- {
- if (t != last && *t == 'E')
- first = t+1;
- }
- break;
- case 'J':
- t = first+1;
- if (t == last)
- return first;
- while (*t != 'E')
- {
- const char* t1 = parse_template_arg(t, last, db);
- if (t1 == t)
- return first;
- t = t1;
- }
- first = t+1;
- break;
- case 'L':
- // <expr-primary> or LZ <encoding> E
- if (first+1 != last && first[1] == 'Z')
- {
- t = parse_encoding(first+2, last, db);
- if (t != first+2 && t != last && *t == 'E')
- first = t+1;
- }
- else
- first = parse_expr_primary(first, last, db);
- break;
- default:
- // <type>
- first = parse_type(first, last, db);
- break;
- }
- }
- return first;
-}
-
-// <template-args> ::= I <template-arg>* E
-// extension, the abi says <template-arg>+
-
-template <class C>
-const char*
-parse_template_args(const char* first, const char* last, C& db)
-{
- if (last - first >= 2 && *first == 'I')
- {
- if (db.tag_templates)
- db.template_param.back().clear();
- const char* t = first+1;
- typename C::String args("<");
- while (*t != 'E')
- {
- if (db.tag_templates)
- db.template_param.emplace_back(db.names.get_allocator());
- size_t k0 = db.names.size();
- const char* t1 = parse_template_arg(t, last, db);
- size_t k1 = db.names.size();
- if (db.tag_templates)
- db.template_param.pop_back();
- if (t1 == t || t1 == last)
- return first;
- if (db.tag_templates)
- {
- db.template_param.back().emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- db.template_param.back().back().push_back(db.names[k]);
- }
- for (size_t k = k0; k < k1; ++k)
- {
- if (args.size() > 1)
- args += ", ";
- args += db.names[k].move_full();
- }
- for (; k1 != k0; --k1)
- db.names.pop_back();
- t = t1;
- }
- first = t + 1;
- if (args.back() != '>')
- args += ">";
- else
- args += " >";
- db.names.push_back(std::move(args));
-
- }
- return first;
-}
-
-// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
-// ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
-//
-// <prefix> ::= <prefix> <unqualified-name>
-// ::= <template-prefix> <template-args>
-// ::= <template-param>
-// ::= <decltype>
-// ::= # empty
-// ::= <substitution>
-// ::= <prefix> <data-member-prefix>
-// extension ::= L
-//
-// <template-prefix> ::= <prefix> <template unqualified-name>
-// ::= <template-param>
-// ::= <substitution>
-
-template <class C>
-const char*
-parse_nested_name(const char* first, const char* last, C& db,
- bool* ends_with_template_args)
-{
- if (first != last && *first == 'N')
- {
- unsigned cv;
- const char* t0 = parse_cv_qualifiers(first+1, last, cv);
- if (t0 == last)
- return first;
- db.ref = 0;
- if (*t0 == 'R')
- {
- db.ref = 1;
- ++t0;
- }
- else if (*t0 == 'O')
- {
- db.ref = 2;
- ++t0;
- }
- db.names.emplace_back();
- if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't')
- {
- t0 += 2;
- db.names.back().first = "std";
- }
- if (t0 == last)
- {
- db.names.pop_back();
- return first;
- }
- bool pop_subs = false;
- bool component_ends_with_template_args = false;
- while (*t0 != 'E')
- {
- component_ends_with_template_args = false;
- const char* t1;
- switch (*t0)
- {
- case 'S':
- if (t0 + 1 != last && t0[1] == 't')
- goto do_parse_unqualified_name;
- t1 = parse_substitution(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- if (!db.names.back().first.empty())
- {
- db.names.back().first += "::" + name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- }
- else
- db.names.back().first = name;
- pop_subs = true;
- t0 = t1;
- }
- else
- return first;
- break;
- case 'T':
- t1 = parse_template_param(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- if (!db.names.back().first.empty())
- db.names.back().first += "::" + name;
- else
- db.names.back().first = name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- pop_subs = true;
- t0 = t1;
- }
- else
- return first;
- break;
- case 'D':
- if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
- goto do_parse_unqualified_name;
- t1 = parse_decltype(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- if (!db.names.back().first.empty())
- db.names.back().first += "::" + name;
- else
- db.names.back().first = name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- pop_subs = true;
- t0 = t1;
- }
- else
- return first;
- break;
- case 'I':
- t1 = parse_template_args(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- t0 = t1;
- component_ends_with_template_args = true;
- }
- else
- return first;
- break;
- case 'L':
- if (++t0 == last)
- return first;
- break;
- default:
- do_parse_unqualified_name:
- t1 = parse_unqualified_name(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- if (!db.names.back().first.empty())
- db.names.back().first += "::" + name;
- else
- db.names.back().first = name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- pop_subs = true;
- t0 = t1;
- }
- else
- return first;
- }
- }
- first = t0 + 1;
- db.cv = cv;
- if (pop_subs && !db.subs.empty())
- db.subs.pop_back();
- if (ends_with_template_args)
- *ends_with_template_args = component_ends_with_template_args;
- }
- return first;
-}
-
-// <discriminator> := _ <non-negative number> # when number < 10
-// := __ <non-negative number> _ # when number >= 10
-// extension := decimal-digit+
-
-const char*
-parse_discriminator(const char* first, const char* last)
-{
- // parse but ignore discriminator
- if (first != last)
- {
- if (*first == '_')
- {
- const char* t1 = first+1;
- if (t1 != last)
- {
- if (std::isdigit(*t1))
- first = t1+1;
- else if (*t1 == '_')
- {
- for (++t1; t1 != last && std::isdigit(*t1); ++t1)
- ;
- if (t1 != last && *t1 == '_')
- first = t1 + 1;
- }
- }
- }
- else if (std::isdigit(*first))
- {
- const char* t1 = first+1;
- for (; t1 != last && std::isdigit(*t1); ++t1)
- ;
- first = t1;
- }
- }
- return first;
-}
-
-// <local-name> := Z <function encoding> E <entity name> [<discriminator>]
-// := Z <function encoding> E s [<discriminator>]
-// := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
-
-template <class C>
-const char*
-parse_local_name(const char* first, const char* last, C& db,
- bool* ends_with_template_args)
-{
- if (first != last && *first == 'Z')
- {
- const char* t = parse_encoding(first+1, last, db);
- if (t != first+1 && t != last && *t == 'E' && ++t != last)
- {
- switch (*t)
- {
- case 's':
- first = parse_discriminator(t+1, last);
- if (db.names.empty())
- return first;
- db.names.back().first.append("::string literal");
- break;
- case 'd':
- if (++t != last)
- {
- const char* t1 = parse_number(t, last);
- if (t1 != last && *t1 == '_')
- {
- t = t1 + 1;
- t1 = parse_name(t, last, db,
- ends_with_template_args);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto name = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first.append("::");
- db.names.back().first.append(name);
- first = t1;
- }
- else
- db.names.pop_back();
- }
- }
- break;
- default:
- {
- const char* t1 = parse_name(t, last, db,
- ends_with_template_args);
- if (t1 != t)
- {
- // parse but ignore discriminator
- first = parse_discriminator(t1, last);
- if (db.names.size() < 2)
- return first;
- auto name = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first.append("::");
- db.names.back().first.append(name);
- }
- else
- db.names.pop_back();
- }
- break;
- }
- }
- }
- return first;
-}
-
-// <name> ::= <nested-name> // N
-// ::= <local-name> # See Scope Encoding below // Z
-// ::= <unscoped-template-name> <template-args>
-// ::= <unscoped-name>
-
-// <unscoped-template-name> ::= <unscoped-name>
-// ::= <substitution>
-
-template <class C>
-const char*
-parse_name(const char* first, const char* last, C& db,
- bool* ends_with_template_args)
-{
- if (last - first >= 2)
- {
- const char* t0 = first;
- // extension: ignore L here
- if (*t0 == 'L')
- ++t0;
- switch (*t0)
- {
- case 'N':
- {
- const char* t1 = parse_nested_name(t0, last, db,
- ends_with_template_args);
- if (t1 != t0)
- first = t1;
- break;
- }
- case 'Z':
- {
- const char* t1 = parse_local_name(t0, last, db,
- ends_with_template_args);
- if (t1 != t0)
- first = t1;
- break;
- }
- default:
- {
- const char* t1 = parse_unscoped_name(t0, last, db);
- if (t1 != t0)
- {
- if (t1 != last && *t1 == 'I') // <unscoped-template-name> <template-args>
- {
- if (db.names.empty())
- return first;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- t0 = t1;
- t1 = parse_template_args(t0, last, db);
- if (t1 != t0)
- {
- if (db.names.size() < 2)
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += tmp;
- first = t1;
- if (ends_with_template_args)
- *ends_with_template_args = true;
- }
- }
- else // <unscoped-name>
- first = t1;
- }
- else
- { // try <substitution> <template-args>
- t1 = parse_substitution(t0, last, db);
- if (t1 != t0 && t1 != last && *t1 == 'I')
- {
- t0 = t1;
- t1 = parse_template_args(t0, last, db);
- if (t1 != t0)
- {
- if (db.names.size() < 2)
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += tmp;
- first = t1;
- if (ends_with_template_args)
- *ends_with_template_args = true;
- }
- }
- }
- break;
- }
- }
- }
- return first;
-}
-
-// <call-offset> ::= h <nv-offset> _
-// ::= v <v-offset> _
-//
-// <nv-offset> ::= <offset number>
-// # non-virtual base override
-//
-// <v-offset> ::= <offset number> _ <virtual offset number>
-// # virtual base override, with vcall offset
-
-const char*
-parse_call_offset(const char* first, const char* last)
-{
- if (first != last)
- {
- switch (*first)
- {
- case 'h':
- {
- const char* t = parse_number(first + 1, last);
- if (t != first + 1 && t != last && *t == '_')
- first = t + 1;
- }
- break;
- case 'v':
- {
- const char* t = parse_number(first + 1, last);
- if (t != first + 1 && t != last && *t == '_')
- {
- const char* t2 = parse_number(++t, last);
- if (t2 != t && t2 != last && *t2 == '_')
- first = t2 + 1;
- }
- }
- break;
- }
- }
- return first;
-}
-
-// <special-name> ::= TV <type> # virtual table
-// ::= TT <type> # VTT structure (construction vtable index)
-// ::= TI <type> # typeinfo structure
-// ::= TS <type> # typeinfo name (null-terminated byte string)
-// ::= Tc <call-offset> <call-offset> <base encoding>
-// # base is the nominal target function of thunk
-// # first call-offset is 'this' adjustment
-// # second call-offset is result adjustment
-// ::= T <call-offset> <base encoding>
-// # base is the nominal target function of thunk
-// ::= GV <object name> # Guard variable for one-time initialization
-// # No <type>
-// extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
-// extension ::= GR <object name> # reference temporary for object
-
-template <class C>
-const char*
-parse_special_name(const char* first, const char* last, C& db)
-{
- if (last - first > 2)
- {
- const char* t;
- switch (*first)
- {
- case 'T':
- switch (first[1])
- {
- case 'V':
- // TV <type> # virtual table
- t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "vtable for ");
- first = t;
- }
- break;
- case 'T':
- // TT <type> # VTT structure (construction vtable index)
- t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "VTT for ");
- first = t;
- }
- break;
- case 'I':
- // TI <type> # typeinfo structure
- t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "typeinfo for ");
- first = t;
- }
- break;
- case 'S':
- // TS <type> # typeinfo name (null-terminated byte string)
- t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "typeinfo name for ");
- first = t;
- }
- break;
- case 'c':
- // Tc <call-offset> <call-offset> <base encoding>
- {
- const char* t0 = parse_call_offset(first+2, last);
- if (t0 == first+2)
- break;
- const char* t1 = parse_call_offset(t0, last);
- if (t1 == t0)
- break;
- t = parse_encoding(t1, last, db);
- if (t != t1)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "covariant return thunk to ");
- first = t;
- }
- }
- break;
- case 'C':
- // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
- t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- const char* t0 = parse_number(t, last);
- if (t0 != t && t0 != last && *t0 == '_')
- {
- const char* t1 = parse_type(++t0, last, db);
- if (t1 != t0)
- {
- if (db.names.size() < 2)
- return first;
- auto left = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first = "construction vtable for " +
- std::move(left) + "-in-" +
- db.names.back().move_full();
- first = t1;
- }
- }
- }
- break;
- default:
- // T <call-offset> <base encoding>
- {
- const char* t0 = parse_call_offset(first+1, last);
- if (t0 == first+1)
- break;
- t = parse_encoding(t0, last, db);
- if (t != t0)
- {
- if (db.names.empty())
- return first;
- if (first[2] == 'v')
- {
- db.names.back().first.insert(0, "virtual thunk to ");
- first = t;
- }
- else
- {
- db.names.back().first.insert(0, "non-virtual thunk to ");
- first = t;
- }
- }
- }
- break;
- }
- break;
- case 'G':
- switch (first[1])
- {
- case 'V':
- // GV <object name> # Guard variable for one-time initialization
- t = parse_name(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "guard variable for ");
- first = t;
- }
- break;
- case 'R':
- // extension ::= GR <object name> # reference temporary for object
- t = parse_name(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "reference temporary for ");
- first = t;
- }
- break;
- }
- break;
- }
- }
- return first;
-}
-
-template <class T>
-class save_value
-{
- T& restore_;
- T original_value_;
-public:
- save_value(T& restore)
- : restore_(restore),
- original_value_(restore)
- {}
-
- ~save_value()
- {
- restore_ = std::move(original_value_);
- }
-
- save_value(const save_value&) = delete;
- save_value& operator=(const save_value&) = delete;
-};
-
-// <encoding> ::= <function name> <bare-function-type>
-// ::= <data name>
-// ::= <special-name>
-
-template <class C>
-const char*
-parse_encoding(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- save_value<decltype(db.encoding_depth)> su(db.encoding_depth);
- ++db.encoding_depth;
- save_value<decltype(db.tag_templates)> sb(db.tag_templates);
- if (db.encoding_depth > 1)
- db.tag_templates = true;
- switch (*first)
- {
- case 'G':
- case 'T':
- first = parse_special_name(first, last, db);
- break;
- default:
- {
- bool ends_with_template_args = false;
- const char* t = parse_name(first, last, db,
- &ends_with_template_args);
- unsigned cv = db.cv;
- unsigned ref = db.ref;
- if (t != first)
- {
- if (t != last && *t != 'E' && *t != '.')
- {
- save_value<bool> sb2(db.tag_templates);
- db.tag_templates = false;
- const char* t2;
- typename C::String ret2;
- if (db.names.empty())
- return first;
- const typename C::String& nm = db.names.back().first;
- if (nm.empty())
- return first;
- if (!db.parsed_ctor_dtor_cv && ends_with_template_args)
- {
- t2 = parse_type(t, last, db);
- if (t2 == t)
- return first;
- if (db.names.size() < 2)
- return first;
- auto ret1 = std::move(db.names.back().first);
- ret2 = std::move(db.names.back().second);
- if (ret2.empty())
- ret1 += ' ';
- db.names.pop_back();
- db.names.back().first.insert(0, ret1);
- t = t2;
- }
- db.names.back().first += '(';
- if (t != last && *t == 'v')
- {
- ++t;
- }
- else
- {
- bool first_arg = true;
- while (true)
- {
- size_t k0 = db.names.size();
- t2 = parse_type(t, last, db);
- size_t k1 = db.names.size();
- if (t2 == t)
- break;
- if (k1 > k0)
- {
- typename C::String tmp;
- for (size_t k = k0; k < k1; ++k)
- {
- if (!tmp.empty())
- tmp += ", ";
- tmp += db.names[k].move_full();
- }
- for (size_t k = k0; k < k1; ++k)
- db.names.pop_back();
- if (!tmp.empty())
- {
- if (db.names.empty())
- return first;
- if (!first_arg)
- db.names.back().first += ", ";
- else
- first_arg = false;
- db.names.back().first += tmp;
- }
- }
- t = t2;
- }
- }
- if (db.names.empty())
- return first;
- db.names.back().first += ')';
- if (cv & 1)
- db.names.back().first.append(" const");
- if (cv & 2)
- db.names.back().first.append(" volatile");
- if (cv & 4)
- db.names.back().first.append(" restrict");
- if (ref == 1)
- db.names.back().first.append(" &");
- else if (ref == 2)
- db.names.back().first.append(" &&");
- db.names.back().first += ret2;
- first = t;
- }
- else
- first = t;
- }
- break;
- }
- }
- }
- return first;
-}
-
-// _block_invoke
-// _block_invoke<decimal-digit>+
-// _block_invoke_<decimal-digit>+
-
-template <class C>
-const char*
-parse_block_invoke(const char* first, const char* last, C& db)
-{
- if (last - first >= 13)
- {
- const char test[] = "_block_invoke";
- const char* t = first;
- for (int i = 0; i < 13; ++i, ++t)
- {
- if (*t != test[i])
- return first;
- }
- if (t != last)
- {
- if (*t == '_')
- {
- // must have at least 1 decimal digit
- if (++t == last || !std::isdigit(*t))
- return first;
- ++t;
- }
- // parse zero or more digits
- while (t != last && isdigit(*t))
- ++t;
- }
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "invocation function for block in ");
- first = t;
- }
- return first;
-}
-
-// extension
-// <dot-suffix> := .<anything and everything>
-
-template <class C>
-const char*
-parse_dot_suffix(const char* first, const char* last, C& db)
-{
- if (first != last && *first == '.')
- {
- if (db.names.empty())
- return first;
- db.names.back().first += " (" + typename C::String(first, last) + ")";
- first = last;
- }
- return first;
-}
-
-// <block-involcaton-function> ___Z<encoding>_block_invoke
-// <block-involcaton-function> ___Z<encoding>_block_invoke<decimal-digit>+
-// <block-involcaton-function> ___Z<encoding>_block_invoke_<decimal-digit>+
-// <mangled-name> ::= _Z<encoding>
-// ::= <type>
-
-template <class C>
-void
-demangle(const char* first, const char* last, C& db, int& status)
-{
- if (first >= last)
- {
- status = invalid_mangled_name;
- return;
- }
- if (*first == '_')
- {
- if (last - first >= 4)
- {
- if (first[1] == 'Z')
- {
- const char* t = parse_encoding(first+2, last, db);
- if (t != first+2 && t != last && *t == '.')
- t = parse_dot_suffix(t, last, db);
- if (t != last)
- status = invalid_mangled_name;
- }
- else if (first[1] == '_' && first[2] == '_' && first[3] == 'Z')
- {
- const char* t = parse_encoding(first+4, last, db);
- if (t != first+4 && t != last)
- {
- const char* t1 = parse_block_invoke(t, last, db);
- if (t1 != last)
- status = invalid_mangled_name;
- }
- else
- status = invalid_mangled_name;
- }
- else
- status = invalid_mangled_name;
- }
- else
- status = invalid_mangled_name;
- }
- else
- {
- const char* t = parse_type(first, last, db);
- if (t != last)
- status = invalid_mangled_name;
- }
- if (status == success && db.names.empty())
- status = invalid_mangled_name;
-}
-
-template <std::size_t N>
-class arena
-{
- static const std::size_t alignment = 16;
- LLVM_ALIGNAS(16) char buf_[N];
- char* ptr_;
-
- std::size_t
- align_up(std::size_t n) LLVM_NOEXCEPT
- {return (n + (alignment-1)) & ~(alignment-1);}
-
- bool
- pointer_in_buffer(char* p) LLVM_NOEXCEPT
- {return buf_ <= p && p <= buf_ + N;}
-
-public:
- arena() LLVM_NOEXCEPT : ptr_(buf_) {}
- ~arena() {ptr_ = nullptr;}
- arena(const arena&) = delete;
- arena& operator=(const arena&) = delete;
-
- char* allocate(std::size_t n);
- void deallocate(char* p, std::size_t n) LLVM_NOEXCEPT;
-
- static LLVM_CONSTEXPR std::size_t size() {return N;}
- std::size_t used() const {return static_cast<std::size_t>(ptr_ - buf_);}
- void reset() {ptr_ = buf_;}
-};
-
-template <std::size_t N>
-char*
-arena<N>::allocate(std::size_t n)
-{
- n = align_up(n);
- if (static_cast<std::size_t>(buf_ + N - ptr_) >= n)
- {
- char* r = ptr_;
- ptr_ += n;
- return r;
- }
- return static_cast<char*>(std::malloc(n));
-}
-
-template <std::size_t N>
-void
-arena<N>::deallocate(char* p, std::size_t n) LLVM_NOEXCEPT
-{
- if (pointer_in_buffer(p))
- {
- n = align_up(n);
- if (p + n == ptr_)
- ptr_ = p;
- }
- else
- std::free(p);
-}
-
-template <class T, std::size_t N>
-class short_alloc
-{
- arena<N>& a_;
-public:
- typedef T value_type;
-
-public:
- template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};
-
- short_alloc(arena<N>& a) LLVM_NOEXCEPT : a_(a) {}
- template <class U>
- short_alloc(const short_alloc<U, N>& a) LLVM_NOEXCEPT
- : a_(a.a_) {}
- short_alloc(const short_alloc&) = default;
- short_alloc& operator=(const short_alloc&) = delete;
-
- T* allocate(std::size_t n)
- {
- return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
- }
- void deallocate(T* p, std::size_t n) LLVM_NOEXCEPT
- {
- a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
- }
-
- template <class T1, std::size_t N1, class U, std::size_t M>
- friend
- bool
- operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) LLVM_NOEXCEPT;
-
- template <class U, std::size_t M> friend class short_alloc;
-};
-
-template <class T, std::size_t N, class U, std::size_t M>
-inline
-bool
-operator==(const short_alloc<T, N>& x, const short_alloc<U, M>& y) LLVM_NOEXCEPT
-{
- return N == M && &x.a_ == &y.a_;
-}
-
-template <class T, std::size_t N, class U, std::size_t M>
-inline
-bool
-operator!=(const short_alloc<T, N>& x, const short_alloc<U, M>& y) LLVM_NOEXCEPT
-{
- return !(x == y);
-}
-
-template <class T>
-class malloc_alloc
-{
-public:
- typedef T value_type;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
- typedef T* pointer;
- typedef const T* const_pointer;
- typedef T& reference;
- typedef const T& const_reference;
-
- malloc_alloc() = default;
- template <class U> malloc_alloc(const malloc_alloc<U>&) LLVM_NOEXCEPT {}
-
- T* allocate(std::size_t n)
- {
- return static_cast<T*>(std::malloc(n*sizeof(T)));
- }
- void deallocate(T* p, std::size_t) LLVM_NOEXCEPT
- {
- std::free(p);
- }
- template<class Other>
- struct rebind
- {
- typedef malloc_alloc<Other> other;
- };
- void construct(T *p)
- {
- ::new (p) T();
- }
- void construct(T *p, const T& t)
- {
- ::new (p) T(t);
- }
- void destroy(T *p)
- {
- p->~T();
- }
-};
-
-template <class T, class U>
-inline
-bool
-operator==(const malloc_alloc<T>&, const malloc_alloc<U>&) LLVM_NOEXCEPT
-{
- return true;
-}
-
-template <class T, class U>
-inline
-bool
-operator!=(const malloc_alloc<T>& x, const malloc_alloc<U>& y) LLVM_NOEXCEPT
-{
- return !(x == y);
-}
-
-const size_t bs = 4 * 1024;
-template <class T> using Alloc = short_alloc<T, bs>;
-template <class T> using Vector = std::vector<T, Alloc<T>>;
-
-template <class StrT>
-struct string_pair
-{
- StrT first;
- StrT second;
-
- string_pair() = default;
- string_pair(StrT f) : first(std::move(f)) {}
- string_pair(StrT f, StrT s)
- : first(std::move(f)), second(std::move(s)) {}
- template <size_t N>
- string_pair(const char (&s)[N]) : first(s, N-1) {}
-
- size_t size() const {return first.size() + second.size();}
- StrT full() const {return first + second;}
- StrT move_full() {return std::move(first) + std::move(second);}
-};
-
-struct Db
-{
- typedef std::basic_string<char, std::char_traits<char>,
- malloc_alloc<char>> String;
- typedef Vector<string_pair<String>> sub_type;
- typedef Vector<sub_type> template_param_type;
- sub_type names;
- template_param_type subs;
- Vector<template_param_type> template_param;
- unsigned cv;
- unsigned ref;
- unsigned encoding_depth;
- bool parsed_ctor_dtor_cv;
- bool tag_templates;
- bool fix_forward_references;
- bool try_to_parse_template_args;
-
- template <size_t N>
- Db(arena<N>& ar) :
- names(ar),
- subs(0, names, ar),
- template_param(0, subs, ar)
- {}
-};
-
-} // unnamed namespace
-
-char*
-__cxa_demangle(const char* mangled_name, char* buf, size_t* n, int* status)
-{
- if (mangled_name == nullptr || (buf != nullptr && n == nullptr))
- {
- if (status)
- *status = invalid_args;
- return nullptr;
- }
- size_t internal_size = buf != nullptr ? *n : 0;
- arena<bs> a;
- Db db(a);
- db.cv = 0;
- db.ref = 0;
- db.encoding_depth = 0;
- db.parsed_ctor_dtor_cv = false;
- db.tag_templates = true;
- db.template_param.emplace_back(a);
- db.fix_forward_references = false;
- db.try_to_parse_template_args = true;
- int internal_status = success;
- size_t len = std::strlen(mangled_name);
- demangle(mangled_name, mangled_name + len, db,
- internal_status);
- if (internal_status == success && db.fix_forward_references &&
- !db.template_param.empty() && !db.template_param.front().empty())
- {
- db.fix_forward_references = false;
- db.tag_templates = false;
- db.names.clear();
- db.subs.clear();
- demangle(mangled_name, mangled_name + len, db, internal_status);
- if (db.fix_forward_references)
- internal_status = invalid_mangled_name;
- }
- if (internal_status == success)
- {
- size_t sz = db.names.back().size() + 1;
- if (sz > internal_size)
- {
- char* newbuf = static_cast<char*>(std::realloc(buf, sz));
- if (newbuf == nullptr)
- {
- internal_status = memory_alloc_failure;
- buf = nullptr;
- }
- else
- {
- buf = newbuf;
- if (n != nullptr)
- *n = sz;
- }
- }
- if (buf != nullptr)
- {
- db.names.back().first += db.names.back().second;
- std::memcpy(buf, db.names.back().first.data(), sz-1);
- buf[sz-1] = char(0);
- }
- }
- else
- buf = nullptr;
- if (status)
- *status = internal_status;
- return buf;
-}
-
-} // lldb_private
diff --git a/source/Core/DataBufferHeap.cpp b/source/Core/DataBufferHeap.cpp
index 4e5389e053e9..cdd37bfdf0fc 100644
--- a/source/Core/DataBufferHeap.cpp
+++ b/source/Core/DataBufferHeap.cpp
@@ -19,30 +19,24 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Default constructor
//----------------------------------------------------------------------
-DataBufferHeap::DataBufferHeap () :
- m_data()
-{
-}
+DataBufferHeap::DataBufferHeap() : m_data() {}
//----------------------------------------------------------------------
// Initialize this class with "n" characters and fill the buffer
// with "ch".
//----------------------------------------------------------------------
-DataBufferHeap::DataBufferHeap (lldb::offset_t n, uint8_t ch) :
- m_data()
-{
- if (n < m_data.max_size())
- m_data.assign (n, ch);
+DataBufferHeap::DataBufferHeap(lldb::offset_t n, uint8_t ch) : m_data() {
+ if (n < m_data.max_size())
+ m_data.assign(n, ch);
}
//----------------------------------------------------------------------
// Initialize this class with a copy of the "n" bytes from the "bytes"
// buffer.
//----------------------------------------------------------------------
-DataBufferHeap::DataBufferHeap (const void *src, lldb::offset_t src_len) :
- m_data()
-{
- CopyData (src, src_len);
+DataBufferHeap::DataBufferHeap(const void *src, lldb::offset_t src_len)
+ : m_data() {
+ CopyData(src, src_len);
}
//----------------------------------------------------------------------
@@ -55,61 +49,46 @@ DataBufferHeap::~DataBufferHeap() = default;
// Return a pointer to the bytes owned by this object, or nullptr if
// the object contains no bytes.
//----------------------------------------------------------------------
-uint8_t *
-DataBufferHeap::GetBytes ()
-{
- return (m_data.empty() ? nullptr : m_data.data());
+uint8_t *DataBufferHeap::GetBytes() {
+ return (m_data.empty() ? nullptr : m_data.data());
}
//----------------------------------------------------------------------
// Return a const pointer to the bytes owned by this object, or nullptr
// if the object contains no bytes.
//----------------------------------------------------------------------
-const uint8_t *
-DataBufferHeap::GetBytes () const
-{
- return (m_data.empty() ? nullptr : m_data.data());
+const uint8_t *DataBufferHeap::GetBytes() const {
+ return (m_data.empty() ? nullptr : m_data.data());
}
//----------------------------------------------------------------------
// Return the number of bytes this object currently contains.
//----------------------------------------------------------------------
-uint64_t
-DataBufferHeap::GetByteSize () const
-{
- return m_data.size();
-}
+uint64_t DataBufferHeap::GetByteSize() const { return m_data.size(); }
//----------------------------------------------------------------------
// Sets the number of bytes that this object should be able to
// contain. This can be used prior to copying data into the buffer.
//----------------------------------------------------------------------
-uint64_t
-DataBufferHeap::SetByteSize (uint64_t new_size)
-{
- m_data.resize(new_size);
- return m_data.size();
+uint64_t DataBufferHeap::SetByteSize(uint64_t new_size) {
+ m_data.resize(new_size);
+ return m_data.size();
}
-void
-DataBufferHeap::CopyData (const void *src, uint64_t src_len)
-{
- const uint8_t *src_u8 = (const uint8_t *)src;
- if (src && src_len > 0)
- m_data.assign (src_u8, src_u8 + src_len);
- else
- m_data.clear();
+void DataBufferHeap::CopyData(const void *src, uint64_t src_len) {
+ const uint8_t *src_u8 = (const uint8_t *)src;
+ if (src && src_len > 0)
+ m_data.assign(src_u8, src_u8 + src_len);
+ else
+ m_data.clear();
}
-void
-DataBufferHeap::AppendData (const void *src, uint64_t src_len)
-{
- m_data.insert(m_data.end(), (const uint8_t *)src, (const uint8_t *)src + src_len);
+void DataBufferHeap::AppendData(const void *src, uint64_t src_len) {
+ m_data.insert(m_data.end(), (const uint8_t *)src,
+ (const uint8_t *)src + src_len);
}
-void
-DataBufferHeap::Clear()
-{
- buffer_t empty;
- m_data.swap(empty);
+void DataBufferHeap::Clear() {
+ buffer_t empty;
+ m_data.swap(empty);
}
diff --git a/source/Core/DataBufferMemoryMap.cpp b/source/Core/DataBufferMemoryMap.cpp
index 48fe9e58d07d..70e8a394f69e 100644
--- a/source/Core/DataBufferMemoryMap.cpp
+++ b/source/Core/DataBufferMemoryMap.cpp
@@ -17,7 +17,7 @@
#define MAP_EXTRA_HOST_READ_FLAGS 0
-#if defined (__APPLE__)
+#if defined(__APPLE__)
//----------------------------------------------------------------------
// Newer versions of MacOSX have a flag that will allow us to read from
// binaries whose code signature is invalid without crashing by using
@@ -27,12 +27,12 @@
// MAP_RESILIENT_MEDIA flag.
//----------------------------------------------------------------------
#if defined(MAP_RESILIENT_CODESIGN)
- #undef MAP_EXTRA_HOST_READ_FLAGS
- #if defined(MAP_RESILIENT_MEDIA)
- #define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN | MAP_RESILIENT_MEDIA
- #else
- #define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN
- #endif
+#undef MAP_EXTRA_HOST_READ_FLAGS
+#if defined(MAP_RESILIENT_MEDIA)
+#define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN | MAP_RESILIENT_MEDIA
+#else
+#define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN
+#endif
#endif // #if defined(MAP_RESILIENT_CODESIGN)
#endif // #if defined (__APPLE__)
@@ -47,10 +47,10 @@
// Project includes
#include "lldb/Core/DataBufferMemoryMap.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Core/Log.h"
using namespace lldb;
using namespace lldb_private;
@@ -58,75 +58,53 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Default Constructor
//----------------------------------------------------------------------
-DataBufferMemoryMap::DataBufferMemoryMap() :
- m_mmap_addr(nullptr),
- m_mmap_size(0),
- m_data(nullptr),
- m_size(0)
-{
-}
+DataBufferMemoryMap::DataBufferMemoryMap()
+ : m_mmap_addr(nullptr), m_mmap_size(0), m_data(nullptr), m_size(0) {}
//----------------------------------------------------------------------
// Virtual destructor since this class inherits from a pure virtual
// base class.
//----------------------------------------------------------------------
-DataBufferMemoryMap::~DataBufferMemoryMap()
-{
- Clear();
-}
+DataBufferMemoryMap::~DataBufferMemoryMap() { Clear(); }
//----------------------------------------------------------------------
// Return a pointer to the bytes owned by this object, or nullptr if
// the object contains no bytes.
//----------------------------------------------------------------------
-uint8_t *
-DataBufferMemoryMap::GetBytes()
-{
- return m_data;
-}
+uint8_t *DataBufferMemoryMap::GetBytes() { return m_data; }
//----------------------------------------------------------------------
// Return a const pointer to the bytes owned by this object, or nullptr
// if the object contains no bytes.
//----------------------------------------------------------------------
-const uint8_t *
-DataBufferMemoryMap::GetBytes() const
-{
- return m_data;
-}
+const uint8_t *DataBufferMemoryMap::GetBytes() const { return m_data; }
//----------------------------------------------------------------------
// Return the number of bytes this object currently contains.
//----------------------------------------------------------------------
-uint64_t
-DataBufferMemoryMap::GetByteSize() const
-{
- return m_size;
-}
+uint64_t DataBufferMemoryMap::GetByteSize() const { return m_size; }
//----------------------------------------------------------------------
// Reverts this object to an empty state by unmapping any memory
// that is currently owned.
//----------------------------------------------------------------------
-void
-DataBufferMemoryMap::Clear()
-{
- if (m_mmap_addr != nullptr)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
- if (log)
- log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size = %" PRIu64 "", (void *)m_mmap_addr,
- (uint64_t)m_mmap_size);
+void DataBufferMemoryMap::Clear() {
+ if (m_mmap_addr != nullptr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP));
+ if (log)
+ log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size "
+ "= %" PRIu64 "",
+ (void *)m_mmap_addr, (uint64_t)m_mmap_size);
#ifdef _WIN32
- UnmapViewOfFile(m_mmap_addr);
+ UnmapViewOfFile(m_mmap_addr);
#else
- ::munmap((void *)m_mmap_addr, m_mmap_size);
+ ::munmap((void *)m_mmap_addr, m_mmap_size);
#endif
- m_mmap_addr = nullptr;
- m_mmap_size = 0;
- m_data = nullptr;
- m_size = 0;
- }
+ m_mmap_addr = nullptr;
+ m_mmap_size = 0;
+ m_data = nullptr;
+ m_size = 0;
+ }
}
//----------------------------------------------------------------------
@@ -137,48 +115,41 @@ DataBufferMemoryMap::Clear()
// Returns the number of bytes mapped starting from the requested
// offset.
//----------------------------------------------------------------------
-size_t
-DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec,
- lldb::offset_t offset,
- size_t length,
- bool writeable)
-{
- if (filespec != nullptr)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
- if (log)
- {
- log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s\", offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i",
- filespec->GetPath().c_str(),
- offset,
- (uint64_t)length,
- writeable);
- }
- char path[PATH_MAX];
- if (filespec->GetPath(path, sizeof(path)))
- {
- uint32_t options = File::eOpenOptionRead;
- if (writeable)
- options |= File::eOpenOptionWrite;
+size_t DataBufferMemoryMap::MemoryMapFromFileSpec(const FileSpec *filespec,
+ lldb::offset_t offset,
+ size_t length,
+ bool writeable) {
+ if (filespec != nullptr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP));
+ if (log) {
+ log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s\", "
+ "offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i",
+ filespec->GetPath().c_str(), offset, (uint64_t)length,
+ writeable);
+ }
+ char path[PATH_MAX];
+ if (filespec->GetPath(path, sizeof(path))) {
+ uint32_t options = File::eOpenOptionRead;
+ if (writeable)
+ options |= File::eOpenOptionWrite;
- File file;
- Error error (file.Open(path, options));
- if (error.Success())
- {
- const bool fd_is_file = true;
- return MemoryMapFromFileDescriptor (file.GetDescriptor(), offset, length, writeable, fd_is_file);
- }
- }
+ File file;
+ Error error(file.Open(path, options));
+ if (error.Success()) {
+ const bool fd_is_file = true;
+ return MemoryMapFromFileDescriptor(file.GetDescriptor(), offset, length,
+ writeable, fd_is_file);
+ }
}
- // We should only get here if there was an error
- Clear();
- return 0;
+ }
+ // We should only get here if there was an error
+ Clear();
+ return 0;
}
#ifdef _WIN32
static size_t win32memmapalignment = 0;
-void LoadWin32MemMapAlignment ()
-{
+void LoadWin32MemMapAlignment() {
SYSTEM_INFO data;
GetSystemInfo(&data);
win32memmapalignment = data.dwAllocationGranularity;
@@ -197,151 +168,140 @@ void LoadWin32MemMapAlignment ()
// RETURNS
// Number of bytes mapped starting from the requested offset.
//----------------------------------------------------------------------
-size_t
-DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd,
- lldb::offset_t offset,
- size_t length,
- bool writeable,
- bool fd_is_file)
-{
- Clear();
- if (fd >= 0)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP|LIBLLDB_LOG_VERBOSE));
- if (log)
- {
- log->Printf("DataBufferMemoryMap::MemoryMapFromFileDescriptor(fd=%i, offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i, fd_is_file=%i)",
- fd,
- offset,
- (uint64_t)length,
- writeable,
- fd_is_file);
- }
+size_t DataBufferMemoryMap::MemoryMapFromFileDescriptor(int fd,
+ lldb::offset_t offset,
+ size_t length,
+ bool writeable,
+ bool fd_is_file) {
+ Clear();
+ if (fd >= 0) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP |
+ LIBLLDB_LOG_VERBOSE));
+ if (log) {
+ log->Printf("DataBufferMemoryMap::MemoryMapFromFileDescriptor(fd=%i, "
+ "offset=0x%" PRIx64 ", length=0x%" PRIx64
+ ", writeable=%i, fd_is_file=%i)",
+ fd, offset, (uint64_t)length, writeable, fd_is_file);
+ }
#ifdef _WIN32
- HANDLE handle = (HANDLE)_get_osfhandle(fd);
- DWORD file_size_low, file_size_high;
- file_size_low = GetFileSize(handle, &file_size_high);
- const lldb::offset_t file_size = llvm::Make_64(file_size_high, file_size_low);
- const lldb::offset_t max_bytes_available = file_size - offset;
- const size_t max_bytes_mappable = (size_t)std::min<lldb::offset_t>(SIZE_MAX, max_bytes_available);
- if (length == SIZE_MAX || length > max_bytes_mappable)
- {
- // Cap the length if too much data was requested
- length = max_bytes_mappable;
- }
+ HANDLE handle = (HANDLE)_get_osfhandle(fd);
+ DWORD file_size_low, file_size_high;
+ file_size_low = GetFileSize(handle, &file_size_high);
+ const lldb::offset_t file_size =
+ llvm::Make_64(file_size_high, file_size_low);
+ const lldb::offset_t max_bytes_available = file_size - offset;
+ const size_t max_bytes_mappable =
+ (size_t)std::min<lldb::offset_t>(SIZE_MAX, max_bytes_available);
+ if (length == SIZE_MAX || length > max_bytes_mappable) {
+ // Cap the length if too much data was requested
+ length = max_bytes_mappable;
+ }
- if (length > 0)
- {
- HANDLE fileMapping = CreateFileMapping(handle, nullptr, writeable ? PAGE_READWRITE : PAGE_READONLY, file_size_high, file_size_low, nullptr);
- if (fileMapping != nullptr)
- {
- if (win32memmapalignment == 0) LoadWin32MemMapAlignment();
- lldb::offset_t realoffset = offset;
- lldb::offset_t delta = 0;
- if (realoffset % win32memmapalignment != 0) {
- realoffset = realoffset / win32memmapalignment * win32memmapalignment;
- delta = offset - realoffset;
- }
+ if (length > 0) {
+ HANDLE fileMapping = CreateFileMapping(
+ handle, nullptr, writeable ? PAGE_READWRITE : PAGE_READONLY,
+ file_size_high, file_size_low, nullptr);
+ if (fileMapping != nullptr) {
+ if (win32memmapalignment == 0)
+ LoadWin32MemMapAlignment();
+ lldb::offset_t realoffset = offset;
+ lldb::offset_t delta = 0;
+ if (realoffset % win32memmapalignment != 0) {
+ realoffset = realoffset / win32memmapalignment * win32memmapalignment;
+ delta = offset - realoffset;
+ }
- LPVOID data = MapViewOfFile(fileMapping, writeable ? FILE_MAP_WRITE : FILE_MAP_READ, 0, realoffset, length + delta);
- m_mmap_addr = (uint8_t *)data;
- if (!data) {
- Error error;
- error.SetErrorToErrno ();
- } else {
- m_data = m_mmap_addr + delta;
- m_size = length;
- }
- CloseHandle(fileMapping);
- }
+ LPVOID data = MapViewOfFile(fileMapping,
+ writeable ? FILE_MAP_WRITE : FILE_MAP_READ,
+ 0, realoffset, length + delta);
+ m_mmap_addr = (uint8_t *)data;
+ if (!data) {
+ Error error;
+ error.SetErrorToErrno();
+ } else {
+ m_data = m_mmap_addr + delta;
+ m_size = length;
}
+ CloseHandle(fileMapping);
+ }
+ }
#else
- struct stat stat;
- if (::fstat(fd, &stat) == 0)
- {
- if (S_ISREG(stat.st_mode) &&
- (stat.st_size > static_cast<off_t>(offset)))
- {
- const size_t max_bytes_available = stat.st_size - offset;
- if (length == SIZE_MAX)
- {
- length = max_bytes_available;
- }
- else if (length > max_bytes_available)
- {
- // Cap the length if too much data was requested
- length = max_bytes_available;
- }
+ struct stat stat;
+ if (::fstat(fd, &stat) == 0) {
+ if (S_ISREG(stat.st_mode) &&
+ (stat.st_size > static_cast<off_t>(offset))) {
+ const size_t max_bytes_available = stat.st_size - offset;
+ if (length == SIZE_MAX) {
+ length = max_bytes_available;
+ } else if (length > max_bytes_available) {
+ // Cap the length if too much data was requested
+ length = max_bytes_available;
+ }
- if (length > 0)
- {
- int prot = PROT_READ;
- int flags = MAP_PRIVATE;
- if (writeable)
- prot |= PROT_WRITE;
- else
- flags |= MAP_EXTRA_HOST_READ_FLAGS;
+ if (length > 0) {
+ int prot = PROT_READ;
+ int flags = MAP_PRIVATE;
+ if (writeable)
+ prot |= PROT_WRITE;
+ else
+ flags |= MAP_EXTRA_HOST_READ_FLAGS;
- if (fd_is_file)
- flags |= MAP_FILE;
+ if (fd_is_file)
+ flags |= MAP_FILE;
- m_mmap_addr = (uint8_t *)::mmap(nullptr, length, prot, flags, fd, offset);
- Error error;
+ m_mmap_addr =
+ (uint8_t *)::mmap(nullptr, length, prot, flags, fd, offset);
+ Error error;
- if (m_mmap_addr == (void*)-1)
- {
- error.SetErrorToErrno ();
- if (error.GetError() == EINVAL)
- {
- // We may still have a shot at memory mapping if we align things correctly
- size_t page_offset = offset % HostInfo::GetPageSize();
- if (page_offset != 0)
- {
- m_mmap_addr = (uint8_t *)::mmap(nullptr, length + page_offset, prot, flags, fd, offset - page_offset);
- if (m_mmap_addr == (void*)-1)
- {
- // Failed to map file
- m_mmap_addr = nullptr;
- }
- else if (m_mmap_addr != nullptr)
- {
- // We recovered and were able to memory map
- // after we aligned things to page boundaries
+ if (m_mmap_addr == (void *)-1) {
+ error.SetErrorToErrno();
+ if (error.GetError() == EINVAL) {
+ // We may still have a shot at memory mapping if we align things
+ // correctly
+ size_t page_offset = offset % HostInfo::GetPageSize();
+ if (page_offset != 0) {
+ m_mmap_addr =
+ (uint8_t *)::mmap(nullptr, length + page_offset, prot,
+ flags, fd, offset - page_offset);
+ if (m_mmap_addr == (void *)-1) {
+ // Failed to map file
+ m_mmap_addr = nullptr;
+ } else if (m_mmap_addr != nullptr) {
+ // We recovered and were able to memory map
+ // after we aligned things to page boundaries
- // Save the actual mmap'ed size
- m_mmap_size = length + page_offset;
- // Our data is at an offset into the mapped data
- m_data = m_mmap_addr + page_offset;
- // Our pretend size is the size that was requested
- m_size = length;
- }
- }
- }
- if (error.GetError() == ENOMEM)
- {
- error.SetErrorStringWithFormat("could not allocate %" PRId64 " bytes of memory to mmap in file", (uint64_t) length);
- }
- }
- else
- {
- // We were able to map the requested data in one chunk
- // where our mmap and actual data are the same.
- m_mmap_size = length;
- m_data = m_mmap_addr;
- m_size = length;
- }
-
- if (log)
- {
- log->Printf(
- "DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = %p, m_mmap_size = %" PRIu64
- ", error = %s",
- (void *)m_mmap_addr, (uint64_t)m_mmap_size, error.AsCString());
- }
+ // Save the actual mmap'ed size
+ m_mmap_size = length + page_offset;
+ // Our data is at an offset into the mapped data
+ m_data = m_mmap_addr + page_offset;
+ // Our pretend size is the size that was requested
+ m_size = length;
}
+ }
}
+ if (error.GetError() == ENOMEM) {
+ error.SetErrorStringWithFormat("could not allocate %" PRId64
+ " bytes of memory to mmap in file",
+ (uint64_t)length);
+ }
+ } else {
+ // We were able to map the requested data in one chunk
+ // where our mmap and actual data are the same.
+ m_mmap_size = length;
+ m_data = m_mmap_addr;
+ m_size = length;
+ }
+
+ if (log) {
+ log->Printf(
+ "DataBufferMemoryMap::MemoryMapFromFileSpec() m_mmap_addr = "
+ "%p, m_mmap_size = %" PRIu64 ", error = %s",
+ (void *)m_mmap_addr, (uint64_t)m_mmap_size, error.AsCString());
+ }
}
-#endif
+ }
}
- return GetByteSize ();
+#endif
+ }
+ return GetByteSize();
}
diff --git a/source/Core/DataEncoder.cpp b/source/Core/DataEncoder.cpp
index 3ef829507704..dd6adc0a8688 100644
--- a/source/Core/DataEncoder.cpp
+++ b/source/Core/DataEncoder.cpp
@@ -24,66 +24,52 @@
using namespace lldb;
using namespace lldb_private;
-static inline void
-WriteInt16(unsigned char* ptr, unsigned offset, uint16_t value)
-{
- *(uint16_t *)(ptr + offset) = value;
+static inline void WriteInt16(unsigned char *ptr, unsigned offset,
+ uint16_t value) {
+ *(uint16_t *)(ptr + offset) = value;
}
-static inline void
-WriteInt32 (unsigned char* ptr, unsigned offset, uint32_t value)
-{
- *(uint32_t *)(ptr + offset) = value;
+static inline void WriteInt32(unsigned char *ptr, unsigned offset,
+ uint32_t value) {
+ *(uint32_t *)(ptr + offset) = value;
}
-static inline void
-WriteInt64(unsigned char* ptr, unsigned offset, uint64_t value)
-{
- *(uint64_t *)(ptr + offset) = value;
+static inline void WriteInt64(unsigned char *ptr, unsigned offset,
+ uint64_t value) {
+ *(uint64_t *)(ptr + offset) = value;
}
-static inline void
-WriteSwappedInt16(unsigned char* ptr, unsigned offset, uint16_t value)
-{
- *(uint16_t *)(ptr + offset) = llvm::ByteSwap_16(value);
+static inline void WriteSwappedInt16(unsigned char *ptr, unsigned offset,
+ uint16_t value) {
+ *(uint16_t *)(ptr + offset) = llvm::ByteSwap_16(value);
}
-static inline void
-WriteSwappedInt32 (unsigned char* ptr, unsigned offset, uint32_t value)
-{
- *(uint32_t *)(ptr + offset) = llvm::ByteSwap_32(value);
+static inline void WriteSwappedInt32(unsigned char *ptr, unsigned offset,
+ uint32_t value) {
+ *(uint32_t *)(ptr + offset) = llvm::ByteSwap_32(value);
}
-static inline void
-WriteSwappedInt64(unsigned char* ptr, unsigned offset, uint64_t value)
-{
- *(uint64_t *)(ptr + offset) = llvm::ByteSwap_64(value);
+static inline void WriteSwappedInt64(unsigned char *ptr, unsigned offset,
+ uint64_t value) {
+ *(uint64_t *)(ptr + offset) = llvm::ByteSwap_64(value);
}
//----------------------------------------------------------------------
// Default constructor.
//----------------------------------------------------------------------
-DataEncoder::DataEncoder () :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(endian::InlHostByteOrder()),
- m_addr_size(sizeof(void*)),
- m_data_sp()
-{
-}
+DataEncoder::DataEncoder()
+ : m_start(nullptr), m_end(nullptr),
+ m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
+ m_data_sp() {}
//----------------------------------------------------------------------
// This constructor allows us to use data that is owned by someone else.
// The data must stay around as long as this object is valid.
//----------------------------------------------------------------------
-DataEncoder::DataEncoder (void* data, uint32_t length, ByteOrder endian, uint8_t addr_size) :
- m_start ((uint8_t*)data),
- m_end ((uint8_t*)data + length),
- m_byte_order(endian),
- m_addr_size (addr_size),
- m_data_sp ()
-{
-}
+DataEncoder::DataEncoder(void *data, uint32_t length, ByteOrder endian,
+ uint8_t addr_size)
+ : m_start((uint8_t *)data), m_end((uint8_t *)data + length),
+ m_byte_order(endian), m_addr_size(addr_size), m_data_sp() {}
//----------------------------------------------------------------------
// Make a shared pointer reference to the shared data in "data_sp" and
@@ -92,14 +78,11 @@ DataEncoder::DataEncoder (void* data, uint32_t length, ByteOrder endian, uint8_t
// as long as any DataEncoder objects exist that have a reference to
// this data.
//----------------------------------------------------------------------
-DataEncoder::DataEncoder (const DataBufferSP& data_sp, ByteOrder endian, uint8_t addr_size) :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(endian),
- m_addr_size(addr_size),
- m_data_sp()
-{
- SetData (data_sp);
+DataEncoder::DataEncoder(const DataBufferSP &data_sp, ByteOrder endian,
+ uint8_t addr_size)
+ : m_start(nullptr), m_end(nullptr), m_byte_order(endian),
+ m_addr_size(addr_size), m_data_sp() {
+ SetData(data_sp);
}
DataEncoder::~DataEncoder() = default;
@@ -109,37 +92,30 @@ DataEncoder::~DataEncoder() = default;
// release any references to shared data that this object may
// contain.
//------------------------------------------------------------------
-void
-DataEncoder::Clear ()
-{
- m_start = nullptr;
- m_end = nullptr;
- m_byte_order = endian::InlHostByteOrder();
- m_addr_size = sizeof(void*);
- m_data_sp.reset();
+void DataEncoder::Clear() {
+ m_start = nullptr;
+ m_end = nullptr;
+ m_byte_order = endian::InlHostByteOrder();
+ m_addr_size = sizeof(void *);
+ m_data_sp.reset();
}
//------------------------------------------------------------------
// If this object contains shared data, this function returns the
// offset into that shared data. Else zero is returned.
//------------------------------------------------------------------
-size_t
-DataEncoder::GetSharedDataOffset () const
-{
- if (m_start != nullptr)
- {
- const DataBuffer * data = m_data_sp.get();
- if (data != nullptr)
- {
- const uint8_t * data_bytes = data->GetBytes();
- if (data_bytes != nullptr)
- {
- assert(m_start >= data_bytes);
- return m_start - data_bytes;
- }
- }
+size_t DataEncoder::GetSharedDataOffset() const {
+ if (m_start != nullptr) {
+ const DataBuffer *data = m_data_sp.get();
+ if (data != nullptr) {
+ const uint8_t *data_bytes = data->GetBytes();
+ if (data_bytes != nullptr) {
+ assert(m_start >= data_bytes);
+ return m_start - data_bytes;
+ }
}
- return 0;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -152,22 +128,17 @@ DataEncoder::GetSharedDataOffset () const
// reference to that data will be released. Is SWAP is set to true,
// any data extracted will be endian swapped.
//----------------------------------------------------------------------
-uint32_t
-DataEncoder::SetData (void *bytes, uint32_t length, ByteOrder endian)
-{
- m_byte_order = endian;
- m_data_sp.reset();
- if (bytes == nullptr || length == 0)
- {
- m_start = nullptr;
- m_end = nullptr;
- }
- else
- {
- m_start = (uint8_t *)bytes;
- m_end = m_start + length;
- }
- return GetByteSize();
+uint32_t DataEncoder::SetData(void *bytes, uint32_t length, ByteOrder endian) {
+ m_byte_order = endian;
+ m_data_sp.reset();
+ if (bytes == nullptr || length == 0) {
+ m_start = nullptr;
+ m_end = nullptr;
+ } else {
+ m_start = (uint8_t *)bytes;
+ m_end = m_start + length;
+ }
+ return GetByteSize();
}
//----------------------------------------------------------------------
@@ -184,38 +155,35 @@ DataEncoder::SetData (void *bytes, uint32_t length, ByteOrder endian)
// around as long as it is needed. The address size and endian swap
// settings will remain unchanged from their current settings.
//----------------------------------------------------------------------
-uint32_t
-DataEncoder::SetData (const DataBufferSP& data_sp, uint32_t data_offset, uint32_t data_length)
-{
- m_start = m_end = nullptr;
-
- if (data_length > 0)
- {
- m_data_sp = data_sp;
- if (data_sp)
- {
- const size_t data_size = data_sp->GetByteSize();
- if (data_offset < data_size)
- {
- m_start = data_sp->GetBytes() + data_offset;
- const size_t bytes_left = data_size - data_offset;
- // Cap the length of we asked for too many
- if (data_length <= bytes_left)
- m_end = m_start + data_length; // We got all the bytes we wanted
- else
- m_end = m_start + bytes_left; // Not all the bytes requested were available in the shared data
- }
- }
+uint32_t DataEncoder::SetData(const DataBufferSP &data_sp, uint32_t data_offset,
+ uint32_t data_length) {
+ m_start = m_end = nullptr;
+
+ if (data_length > 0) {
+ m_data_sp = data_sp;
+ if (data_sp) {
+ const size_t data_size = data_sp->GetByteSize();
+ if (data_offset < data_size) {
+ m_start = data_sp->GetBytes() + data_offset;
+ const size_t bytes_left = data_size - data_offset;
+ // Cap the length of we asked for too many
+ if (data_length <= bytes_left)
+ m_end = m_start + data_length; // We got all the bytes we wanted
+ else
+ m_end = m_start + bytes_left; // Not all the bytes requested were
+ // available in the shared data
+ }
}
+ }
- uint32_t new_size = GetByteSize();
+ uint32_t new_size = GetByteSize();
- // Don't hold a shared pointer to the data buffer if we don't share
- // any valid bytes in the shared buffer.
- if (new_size == 0)
- m_data_sp.reset();
+ // Don't hold a shared pointer to the data buffer if we don't share
+ // any valid bytes in the shared buffer.
+ if (new_size == 0)
+ m_data_sp.reset();
- return new_size;
+ return new_size;
}
//----------------------------------------------------------------------
@@ -224,60 +192,48 @@ DataEncoder::SetData (const DataBufferSP& data_sp, uint32_t data_offset, uint32_
//
// RETURNS the byte that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint32_t
-DataEncoder::PutU8 (uint32_t offset, uint8_t value)
-{
- if (ValidOffset(offset))
- {
- m_start[offset] = value;
- return offset + 1;
- }
- return UINT32_MAX;
+uint32_t DataEncoder::PutU8(uint32_t offset, uint8_t value) {
+ if (ValidOffset(offset)) {
+ m_start[offset] = value;
+ return offset + 1;
+ }
+ return UINT32_MAX;
}
-uint32_t
-DataEncoder::PutU16 (uint32_t offset, uint16_t value)
-{
- if (ValidOffsetForDataOfSize(offset, sizeof(value)))
- {
- if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt16 (m_start, offset, value);
- else
- WriteInt16 (m_start, offset, value);
+uint32_t DataEncoder::PutU16(uint32_t offset, uint16_t value) {
+ if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
+ if (m_byte_order != endian::InlHostByteOrder())
+ WriteSwappedInt16(m_start, offset, value);
+ else
+ WriteInt16(m_start, offset, value);
- return offset + sizeof (value);
- }
- return UINT32_MAX;
+ return offset + sizeof(value);
+ }
+ return UINT32_MAX;
}
-uint32_t
-DataEncoder::PutU32 (uint32_t offset, uint32_t value)
-{
- if (ValidOffsetForDataOfSize(offset, sizeof(value)))
- {
- if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt32 (m_start, offset, value);
- else
- WriteInt32 (m_start, offset, value);
-
- return offset + sizeof (value);
- }
- return UINT32_MAX;
+uint32_t DataEncoder::PutU32(uint32_t offset, uint32_t value) {
+ if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
+ if (m_byte_order != endian::InlHostByteOrder())
+ WriteSwappedInt32(m_start, offset, value);
+ else
+ WriteInt32(m_start, offset, value);
+
+ return offset + sizeof(value);
+ }
+ return UINT32_MAX;
}
-uint32_t
-DataEncoder::PutU64 (uint32_t offset, uint64_t value)
-{
- if (ValidOffsetForDataOfSize(offset, sizeof(value)))
- {
- if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt64 (m_start, offset, value);
- else
- WriteInt64 (m_start, offset, value);
-
- return offset + sizeof (value);
- }
- return UINT32_MAX;
+uint32_t DataEncoder::PutU64(uint32_t offset, uint64_t value) {
+ if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
+ if (m_byte_order != endian::InlHostByteOrder())
+ WriteSwappedInt64(m_start, offset, value);
+ else
+ WriteInt64(m_start, offset, value);
+
+ return offset + sizeof(value);
+ }
+ return UINT32_MAX;
}
//----------------------------------------------------------------------
@@ -290,46 +246,42 @@ DataEncoder::PutU64 (uint32_t offset, uint64_t value)
//
// RETURNS the integer value that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint32_t
-DataEncoder::PutMaxU64 (uint32_t offset, uint32_t byte_size, uint64_t value)
-{
- switch (byte_size)
- {
- case 1: return PutU8 (offset, value);
- case 2: return PutU16(offset, value);
- case 4: return PutU32(offset, value);
- case 8: return PutU64(offset, value);
- default:
- assert(!"GetMax64 unhandled case!");
- break;
- }
- return UINT32_MAX;
+uint32_t DataEncoder::PutMaxU64(uint32_t offset, uint32_t byte_size,
+ uint64_t value) {
+ switch (byte_size) {
+ case 1:
+ return PutU8(offset, value);
+ case 2:
+ return PutU16(offset, value);
+ case 4:
+ return PutU32(offset, value);
+ case 8:
+ return PutU64(offset, value);
+ default:
+ assert(!"GetMax64 unhandled case!");
+ break;
+ }
+ return UINT32_MAX;
}
-uint32_t
-DataEncoder::PutData (uint32_t offset, const void *src, uint32_t src_len)
-{
- if (src == nullptr || src_len == 0)
- return offset;
+uint32_t DataEncoder::PutData(uint32_t offset, const void *src,
+ uint32_t src_len) {
+ if (src == nullptr || src_len == 0)
+ return offset;
- if (ValidOffsetForDataOfSize(offset, src_len))
- {
- memcpy (m_start + offset, src, src_len);
- return offset + src_len;
- }
- return UINT32_MAX;
+ if (ValidOffsetForDataOfSize(offset, src_len)) {
+ memcpy(m_start + offset, src, src_len);
+ return offset + src_len;
+ }
+ return UINT32_MAX;
}
-uint32_t
-DataEncoder::PutAddress (uint32_t offset, lldb::addr_t addr)
-{
- return PutMaxU64 (offset, GetAddressByteSize(), addr);
+uint32_t DataEncoder::PutAddress(uint32_t offset, lldb::addr_t addr) {
+ return PutMaxU64(offset, GetAddressByteSize(), addr);
}
-uint32_t
-DataEncoder::PutCString (uint32_t offset, const char *cstr)
-{
- if (cstr != nullptr)
- return PutData (offset, cstr, strlen(cstr) + 1);
- return UINT32_MAX;
+uint32_t DataEncoder::PutCString(uint32_t offset, const char *cstr) {
+ if (cstr != nullptr)
+ return PutData(offset, cstr, strlen(cstr) + 1);
+ return UINT32_MAX;
}
diff --git a/source/Core/DataExtractor.cpp b/source/Core/DataExtractor.cpp
index 84446147a363..fbc6e80bea07 100644
--- a/source/Core/DataExtractor.cpp
+++ b/source/Core/DataExtractor.cpp
@@ -11,8 +11,8 @@
// C++ Includes
#include <bitset>
#include <cassert>
-#include <cstddef>
#include <cmath>
+#include <cstddef>
#include <sstream>
#include <string>
@@ -21,15 +21,15 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MD5.h"
+#include "llvm/Support/MathExtras.h"
#include "clang/AST/ASTContext.h"
// Project includes
+#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
@@ -46,112 +46,92 @@
using namespace lldb;
using namespace lldb_private;
-static inline uint16_t
-ReadInt16(const unsigned char* ptr, offset_t offset)
-{
- uint16_t value;
- memcpy (&value, ptr + offset, 2);
- return value;
+static inline uint16_t ReadInt16(const unsigned char *ptr, offset_t offset) {
+ uint16_t value;
+ memcpy(&value, ptr + offset, 2);
+ return value;
}
-static inline uint32_t
-ReadInt32 (const unsigned char* ptr, offset_t offset = 0)
-{
- uint32_t value;
- memcpy (&value, ptr + offset, 4);
- return value;
+static inline uint32_t ReadInt32(const unsigned char *ptr,
+ offset_t offset = 0) {
+ uint32_t value;
+ memcpy(&value, ptr + offset, 4);
+ return value;
}
-static inline uint64_t
-ReadInt64(const unsigned char* ptr, offset_t offset = 0)
-{
- uint64_t value;
- memcpy (&value, ptr + offset, 8);
- return value;
+static inline uint64_t ReadInt64(const unsigned char *ptr,
+ offset_t offset = 0) {
+ uint64_t value;
+ memcpy(&value, ptr + offset, 8);
+ return value;
}
-static inline uint16_t
-ReadInt16(const void* ptr)
-{
- uint16_t value;
- memcpy (&value, ptr, 2);
- return value;
+static inline uint16_t ReadInt16(const void *ptr) {
+ uint16_t value;
+ memcpy(&value, ptr, 2);
+ return value;
}
-static inline uint16_t
-ReadSwapInt16(const unsigned char* ptr, offset_t offset)
-{
- uint16_t value;
- memcpy (&value, ptr + offset, 2);
- return llvm::ByteSwap_16(value);
+static inline uint16_t ReadSwapInt16(const unsigned char *ptr,
+ offset_t offset) {
+ uint16_t value;
+ memcpy(&value, ptr + offset, 2);
+ return llvm::ByteSwap_16(value);
}
-static inline uint32_t
-ReadSwapInt32 (const unsigned char* ptr, offset_t offset)
-{
- uint32_t value;
- memcpy (&value, ptr + offset, 4);
- return llvm::ByteSwap_32(value);
+static inline uint32_t ReadSwapInt32(const unsigned char *ptr,
+ offset_t offset) {
+ uint32_t value;
+ memcpy(&value, ptr + offset, 4);
+ return llvm::ByteSwap_32(value);
}
-static inline uint64_t
-ReadSwapInt64(const unsigned char* ptr, offset_t offset)
-{
- uint64_t value;
- memcpy (&value, ptr + offset, 8);
- return llvm::ByteSwap_64(value);
+static inline uint64_t ReadSwapInt64(const unsigned char *ptr,
+ offset_t offset) {
+ uint64_t value;
+ memcpy(&value, ptr + offset, 8);
+ return llvm::ByteSwap_64(value);
}
-static inline uint16_t
-ReadSwapInt16(const void* ptr)
-{
- uint16_t value;
- memcpy (&value, ptr, 2);
- return llvm::ByteSwap_16(value);
+static inline uint16_t ReadSwapInt16(const void *ptr) {
+ uint16_t value;
+ memcpy(&value, ptr, 2);
+ return llvm::ByteSwap_16(value);
}
-static inline uint32_t
-ReadSwapInt32 (const void* ptr)
-{
- uint32_t value;
- memcpy (&value, ptr, 4);
- return llvm::ByteSwap_32(value);
+static inline uint32_t ReadSwapInt32(const void *ptr) {
+ uint32_t value;
+ memcpy(&value, ptr, 4);
+ return llvm::ByteSwap_32(value);
}
-static inline uint64_t
-ReadSwapInt64(const void* ptr)
-{
- uint64_t value;
- memcpy (&value, ptr, 8);
- return llvm::ByteSwap_64(value);
+static inline uint64_t ReadSwapInt64(const void *ptr) {
+ uint64_t value;
+ memcpy(&value, ptr, 8);
+ return llvm::ByteSwap_64(value);
}
#define NON_PRINTABLE_CHAR '.'
-DataExtractor::DataExtractor () :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(endian::InlHostByteOrder()),
- m_addr_size(sizeof(void *)),
- m_data_sp(),
- m_target_byte_size(1)
-{
-}
+DataExtractor::DataExtractor()
+ : m_start(nullptr), m_end(nullptr),
+ m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
+ m_data_sp(), m_target_byte_size(1) {}
//----------------------------------------------------------------------
// This constructor allows us to use data that is owned by someone else.
// 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 (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)
-{
+DataExtractor::DataExtractor(const void *data, offset_t length,
+ ByteOrder endian, uint32_t addr_size,
+ uint32_t target_byte_size /*=1*/)
+ : 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);
+ assert(addr_size == 4 || addr_size == 8);
#endif
}
@@ -162,18 +142,16 @@ DataExtractor::DataExtractor (const void* data, offset_t length, ByteOrder endia
// as long as any DataExtractor objects exist that have a reference to
// this data.
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uint32_t addr_size, uint32_t target_byte_size/*=1*/) :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(endian),
- m_addr_size(addr_size),
- m_data_sp(),
- m_target_byte_size(target_byte_size)
-{
+DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian,
+ uint32_t addr_size,
+ uint32_t target_byte_size /*=1*/)
+ : m_start(nullptr), m_end(nullptr), m_byte_order(endian),
+ m_addr_size(addr_size), m_data_sp(),
+ m_target_byte_size(target_byte_size) {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (addr_size == 4 || addr_size == 8);
+ assert(addr_size == 4 || addr_size == 8);
#endif
- SetData (data_sp);
+ SetData(data_sp);
}
//----------------------------------------------------------------------
@@ -183,54 +161,43 @@ DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uin
// as any object contains a reference to that data. The endian
// swap and address size settings are copied from "data".
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const DataExtractor& data, offset_t offset, offset_t length, uint32_t target_byte_size/*=1*/) :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(data.m_byte_order),
- m_addr_size(data.m_addr_size),
- m_data_sp(),
- m_target_byte_size(target_byte_size)
-{
+DataExtractor::DataExtractor(const DataExtractor &data, offset_t offset,
+ offset_t length, uint32_t target_byte_size /*=1*/)
+ : m_start(nullptr), m_end(nullptr), m_byte_order(data.m_byte_order),
+ m_addr_size(data.m_addr_size), m_data_sp(),
+ m_target_byte_size(target_byte_size) {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
- if (data.ValidOffset(offset))
- {
- offset_t bytes_available = data.GetByteSize() - offset;
- if (length > bytes_available)
- length = bytes_available;
- SetData(data, offset, length);
- }
-}
-
-DataExtractor::DataExtractor (const DataExtractor& rhs) :
- m_start (rhs.m_start),
- m_end (rhs.m_end),
- m_byte_order (rhs.m_byte_order),
- m_addr_size (rhs.m_addr_size),
- m_data_sp (rhs.m_data_sp),
- m_target_byte_size(rhs.m_target_byte_size)
-{
+ if (data.ValidOffset(offset)) {
+ offset_t bytes_available = data.GetByteSize() - offset;
+ if (length > bytes_available)
+ length = bytes_available;
+ SetData(data, offset, length);
+ }
+}
+
+DataExtractor::DataExtractor(const DataExtractor &rhs)
+ : m_start(rhs.m_start), m_end(rhs.m_end), m_byte_order(rhs.m_byte_order),
+ m_addr_size(rhs.m_addr_size), m_data_sp(rhs.m_data_sp),
+ m_target_byte_size(rhs.m_target_byte_size) {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
}
//----------------------------------------------------------------------
// Assignment operator
//----------------------------------------------------------------------
-const DataExtractor&
-DataExtractor::operator= (const DataExtractor& rhs)
-{
- if (this != &rhs)
- {
- m_start = rhs.m_start;
- m_end = rhs.m_end;
- m_byte_order = rhs.m_byte_order;
- m_addr_size = rhs.m_addr_size;
- m_data_sp = rhs.m_data_sp;
- }
- return *this;
+const DataExtractor &DataExtractor::operator=(const DataExtractor &rhs) {
+ if (this != &rhs) {
+ m_start = rhs.m_start;
+ m_end = rhs.m_end;
+ m_byte_order = rhs.m_byte_order;
+ m_addr_size = rhs.m_addr_size;
+ m_data_sp = rhs.m_data_sp;
+ }
+ return *this;
}
DataExtractor::~DataExtractor() = default;
@@ -240,37 +207,30 @@ DataExtractor::~DataExtractor() = default;
// release any references to shared data that this object may
// contain.
//------------------------------------------------------------------
-void
-DataExtractor::Clear ()
-{
- m_start = nullptr;
- m_end = nullptr;
- m_byte_order = endian::InlHostByteOrder();
- m_addr_size = sizeof(void *);
- m_data_sp.reset();
+void DataExtractor::Clear() {
+ m_start = nullptr;
+ m_end = nullptr;
+ m_byte_order = endian::InlHostByteOrder();
+ m_addr_size = sizeof(void *);
+ m_data_sp.reset();
}
//------------------------------------------------------------------
// If this object contains shared data, this function returns the
// offset into that shared data. Else zero is returned.
//------------------------------------------------------------------
-size_t
-DataExtractor::GetSharedDataOffset () const
-{
- if (m_start != nullptr)
- {
- const DataBuffer * data = m_data_sp.get();
- if (data != nullptr)
- {
- const uint8_t * data_bytes = data->GetBytes();
- if (data_bytes != nullptr)
- {
- assert(m_start >= data_bytes);
- return m_start - data_bytes;
- }
- }
+size_t DataExtractor::GetSharedDataOffset() const {
+ if (m_start != nullptr) {
+ const DataBuffer *data = m_data_sp.get();
+ if (data != nullptr) {
+ const uint8_t *data_bytes = data->GetBytes();
+ if (data_bytes != nullptr) {
+ assert(m_start >= data_bytes);
+ return m_start - data_bytes;
+ }
}
- return 0;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -283,22 +243,18 @@ DataExtractor::GetSharedDataOffset () const
// reference to that data will be released. Is SWAP is set to true,
// any data extracted will be endian swapped.
//----------------------------------------------------------------------
-lldb::offset_t
-DataExtractor::SetData (const void *bytes, offset_t length, ByteOrder endian)
-{
- m_byte_order = endian;
- m_data_sp.reset();
- if (bytes == nullptr || length == 0)
- {
- m_start = nullptr;
- m_end = nullptr;
- }
- else
- {
- m_start = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(bytes));
- m_end = m_start + length;
- }
- return GetByteSize();
+lldb::offset_t DataExtractor::SetData(const void *bytes, offset_t length,
+ ByteOrder endian) {
+ m_byte_order = endian;
+ m_data_sp.reset();
+ if (bytes == nullptr || length == 0) {
+ m_start = nullptr;
+ m_end = nullptr;
+ } else {
+ m_start = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(bytes));
+ m_end = m_start + length;
+ }
+ return GetByteSize();
}
//----------------------------------------------------------------------
@@ -315,28 +271,28 @@ DataExtractor::SetData (const void *bytes, offset_t length, ByteOrder endian)
// refers to those bytes. The address size and endian swap settings
// are copied from the current values in "data".
//----------------------------------------------------------------------
-lldb::offset_t
-DataExtractor::SetData (const DataExtractor& data, offset_t data_offset, offset_t data_length)
-{
- m_addr_size = data.m_addr_size;
+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);
+ 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)
- {
- m_byte_order = data.m_byte_order;
- return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset, data_length);
- }
-
- // We have a DataExtractor object that just has a pointer to bytes
- if (data.ValidOffset(data_offset))
- {
- if (data_length > data.GetByteSize() - data_offset)
- data_length = data.GetByteSize() - data_offset;
- return SetData (data.GetDataStart() + data_offset, data_length, data.GetByteOrder());
- }
- return 0;
+ // If "data" contains shared pointer to data, then we can use that
+ if (data.m_data_sp) {
+ m_byte_order = data.m_byte_order;
+ return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset,
+ data_length);
+ }
+
+ // We have a DataExtractor object that just has a pointer to bytes
+ if (data.ValidOffset(data_offset)) {
+ if (data_length > data.GetByteSize() - data_offset)
+ data_length = data.GetByteSize() - data_offset;
+ return SetData(data.GetDataStart() + data_offset, data_length,
+ data.GetByteOrder());
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -353,38 +309,36 @@ DataExtractor::SetData (const DataExtractor& data, offset_t data_offset, offset_
// around as long as it is needed. The address size and endian swap
// settings will remain unchanged from their current settings.
//----------------------------------------------------------------------
-lldb::offset_t
-DataExtractor::SetData (const DataBufferSP& data_sp, offset_t data_offset, offset_t data_length)
-{
- m_start = m_end = nullptr;
-
- if (data_length > 0)
- {
- m_data_sp = data_sp;
- if (data_sp)
- {
- const size_t data_size = data_sp->GetByteSize();
- if (data_offset < data_size)
- {
- m_start = data_sp->GetBytes() + data_offset;
- const size_t bytes_left = data_size - data_offset;
- // Cap the length of we asked for too many
- if (data_length <= bytes_left)
- m_end = m_start + data_length; // We got all the bytes we wanted
- else
- m_end = m_start + bytes_left; // Not all the bytes requested were available in the shared data
- }
- }
+lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp,
+ offset_t data_offset,
+ offset_t data_length) {
+ m_start = m_end = nullptr;
+
+ if (data_length > 0) {
+ m_data_sp = data_sp;
+ if (data_sp) {
+ const size_t data_size = data_sp->GetByteSize();
+ if (data_offset < data_size) {
+ m_start = data_sp->GetBytes() + data_offset;
+ const size_t bytes_left = data_size - data_offset;
+ // Cap the length of we asked for too many
+ if (data_length <= bytes_left)
+ m_end = m_start + data_length; // We got all the bytes we wanted
+ else
+ m_end = m_start + bytes_left; // Not all the bytes requested were
+ // available in the shared data
+ }
}
+ }
- size_t new_size = GetByteSize();
+ size_t new_size = GetByteSize();
- // Don't hold a shared pointer to the data buffer if we don't share
- // any valid bytes in the shared buffer.
- if (new_size == 0)
- m_data_sp.reset();
+ // Don't hold a shared pointer to the data buffer if we don't share
+ // any valid bytes in the shared buffer.
+ if (new_size == 0)
+ m_data_sp.reset();
- return new_size;
+ return new_size;
}
//----------------------------------------------------------------------
@@ -393,13 +347,11 @@ DataExtractor::SetData (const DataBufferSP& data_sp, offset_t data_offset, offse
//
// RETURNS the byte that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint8_t
-DataExtractor::GetU8 (offset_t *offset_ptr) const
-{
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, 1);
- if (data)
- return *data;
- return 0;
+uint8_t DataExtractor::GetU8(offset_t *offset_ptr) const {
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, 1);
+ if (data)
+ return *data;
+ return 0;
}
//----------------------------------------------------------------------
@@ -411,18 +363,17 @@ DataExtractor::GetU8 (offset_t *offset_ptr) const
// all the requested bytes, or nullptr when the data is not available in
// the buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
-void *
-DataExtractor::GetU8 (offset_t *offset_ptr, void *dst, uint32_t count) const
-{
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, count);
- if (data)
- {
- // Copy the data into the buffer
- memcpy (dst, data, count);
- // Return a non-nullptr pointer to the converted data as an indicator of success
- return dst;
- }
- return nullptr;
+void *DataExtractor::GetU8(offset_t *offset_ptr, void *dst,
+ uint32_t count) const {
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, count);
+ if (data) {
+ // Copy the data into the buffer
+ memcpy(dst, data, count);
+ // Return a non-nullptr pointer to the converted data as an indicator of
+ // success
+ return dst;
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -431,55 +382,46 @@ DataExtractor::GetU8 (offset_t *offset_ptr, void *dst, uint32_t count) const
//
// RETURNS the uint16_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint16_t
-DataExtractor::GetU16 (offset_t *offset_ptr) const
-{
- uint16_t val = 0;
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
- if (data)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- val = ReadSwapInt16(data);
- else
- val = ReadInt16 (data);
- }
- return val;
+uint16_t DataExtractor::GetU16(offset_t *offset_ptr) const {
+ uint16_t val = 0;
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val));
+ if (data) {
+ if (m_byte_order != endian::InlHostByteOrder())
+ val = ReadSwapInt16(data);
+ else
+ val = ReadInt16(data);
+ }
+ return val;
}
-uint16_t
-DataExtractor::GetU16_unchecked (offset_t *offset_ptr) const
-{
- uint16_t val;
- if (m_byte_order == endian::InlHostByteOrder())
- val = ReadInt16 (m_start, *offset_ptr);
- else
- val = ReadSwapInt16(m_start, *offset_ptr);
- *offset_ptr += sizeof(val);
- return val;
+uint16_t DataExtractor::GetU16_unchecked(offset_t *offset_ptr) const {
+ uint16_t val;
+ if (m_byte_order == endian::InlHostByteOrder())
+ val = ReadInt16(m_start, *offset_ptr);
+ else
+ val = ReadSwapInt16(m_start, *offset_ptr);
+ *offset_ptr += sizeof(val);
+ return val;
}
-uint32_t
-DataExtractor::GetU32_unchecked (offset_t *offset_ptr) const
-{
- uint32_t val;
- if (m_byte_order == endian::InlHostByteOrder())
- val = ReadInt32 (m_start, *offset_ptr);
- else
- val = ReadSwapInt32 (m_start, *offset_ptr);
- *offset_ptr += sizeof(val);
- return val;
+uint32_t DataExtractor::GetU32_unchecked(offset_t *offset_ptr) const {
+ uint32_t val;
+ if (m_byte_order == endian::InlHostByteOrder())
+ val = ReadInt32(m_start, *offset_ptr);
+ else
+ val = ReadSwapInt32(m_start, *offset_ptr);
+ *offset_ptr += sizeof(val);
+ return val;
}
-uint64_t
-DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const
-{
- uint64_t val;
- if (m_byte_order == endian::InlHostByteOrder())
- val = ReadInt64 (m_start, *offset_ptr);
- else
- val = ReadSwapInt64 (m_start, *offset_ptr);
- *offset_ptr += sizeof(val);
- return val;
+uint64_t DataExtractor::GetU64_unchecked(offset_t *offset_ptr) const {
+ uint64_t val;
+ if (m_byte_order == endian::InlHostByteOrder())
+ val = ReadInt64(m_start, *offset_ptr);
+ else
+ val = ReadSwapInt64(m_start, *offset_ptr);
+ *offset_ptr += sizeof(val);
+ return val;
}
//----------------------------------------------------------------------
@@ -491,33 +433,28 @@ DataExtractor::GetU64_unchecked (offset_t *offset_ptr) const
// all the requested bytes, or nullptr when the data is not available
// in the buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
-void *
-DataExtractor::GetU16 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
-{
- const size_t src_size = sizeof(uint16_t) * count;
- const uint16_t *src = (const uint16_t *)GetData (offset_ptr, src_size);
- if (src)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- uint16_t *dst_pos = (uint16_t *)void_dst;
- uint16_t *dst_end = dst_pos + count;
- const uint16_t *src_pos = src;
- while (dst_pos < dst_end)
- {
- *dst_pos = ReadSwapInt16 (src_pos);
- ++dst_pos;
- ++src_pos;
- }
- }
- else
- {
- memcpy (void_dst, src, src_size);
- }
- // Return a non-nullptr pointer to the converted data as an indicator of success
- return void_dst;
+void *DataExtractor::GetU16(offset_t *offset_ptr, void *void_dst,
+ uint32_t count) const {
+ const size_t src_size = sizeof(uint16_t) * count;
+ const uint16_t *src = (const uint16_t *)GetData(offset_ptr, src_size);
+ if (src) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ uint16_t *dst_pos = (uint16_t *)void_dst;
+ uint16_t *dst_end = dst_pos + count;
+ const uint16_t *src_pos = src;
+ while (dst_pos < dst_end) {
+ *dst_pos = ReadSwapInt16(src_pos);
+ ++dst_pos;
+ ++src_pos;
+ }
+ } else {
+ memcpy(void_dst, src, src_size);
}
- return nullptr;
+ // Return a non-nullptr pointer to the converted data as an indicator of
+ // success
+ return void_dst;
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -526,23 +463,17 @@ DataExtractor::GetU16 (offset_t *offset_ptr, void *void_dst, uint32_t count) con
//
// RETURNS the uint32_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::GetU32 (offset_t *offset_ptr) const
-{
- uint32_t val = 0;
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
- if (data)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- val = ReadSwapInt32 (data);
- }
- else
- {
- memcpy (&val, data, 4);
- }
+uint32_t DataExtractor::GetU32(offset_t *offset_ptr) const {
+ uint32_t val = 0;
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val));
+ if (data) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ val = ReadSwapInt32(data);
+ } else {
+ memcpy(&val, data, 4);
}
- return val;
+ }
+ return val;
}
//----------------------------------------------------------------------
@@ -554,33 +485,28 @@ DataExtractor::GetU32 (offset_t *offset_ptr) const
// all the requested bytes, or nullptr when the data is not available
// in the buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
-void *
-DataExtractor::GetU32 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
-{
- const size_t src_size = sizeof(uint32_t) * count;
- const uint32_t *src = (const uint32_t *)GetData (offset_ptr, src_size);
- if (src)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- uint32_t *dst_pos = (uint32_t *)void_dst;
- uint32_t *dst_end = dst_pos + count;
- const uint32_t *src_pos = src;
- while (dst_pos < dst_end)
- {
- *dst_pos = ReadSwapInt32 (src_pos);
- ++dst_pos;
- ++src_pos;
- }
- }
- else
- {
- memcpy (void_dst, src, src_size);
- }
- // Return a non-nullptr pointer to the converted data as an indicator of success
- return void_dst;
+void *DataExtractor::GetU32(offset_t *offset_ptr, void *void_dst,
+ uint32_t count) const {
+ const size_t src_size = sizeof(uint32_t) * count;
+ const uint32_t *src = (const uint32_t *)GetData(offset_ptr, src_size);
+ if (src) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ uint32_t *dst_pos = (uint32_t *)void_dst;
+ uint32_t *dst_end = dst_pos + count;
+ const uint32_t *src_pos = src;
+ while (dst_pos < dst_end) {
+ *dst_pos = ReadSwapInt32(src_pos);
+ ++dst_pos;
+ ++src_pos;
+ }
+ } else {
+ memcpy(void_dst, src, src_size);
}
- return nullptr;
+ // Return a non-nullptr pointer to the converted data as an indicator of
+ // success
+ return void_dst;
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -589,23 +515,17 @@ DataExtractor::GetU32 (offset_t *offset_ptr, void *void_dst, uint32_t count) con
//
// RETURNS the uint64_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint64_t
-DataExtractor::GetU64 (offset_t *offset_ptr) const
-{
- uint64_t val = 0;
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
- if (data)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- val = ReadSwapInt64 (data);
- }
- else
- {
- memcpy (&val, data, 8);
- }
+uint64_t DataExtractor::GetU64(offset_t *offset_ptr) const {
+ uint64_t val = 0;
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val));
+ if (data) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ val = ReadSwapInt64(data);
+ } else {
+ memcpy(&val, data, 8);
}
- return val;
+ }
+ return val;
}
//----------------------------------------------------------------------
@@ -615,33 +535,28 @@ DataExtractor::GetU64 (offset_t *offset_ptr) const
// read succeeds and increment the offset pointed to by offset_ptr, else
// return false and leave the offset pointed to by offset_ptr unchanged.
//----------------------------------------------------------------------
-void *
-DataExtractor::GetU64 (offset_t *offset_ptr, void *void_dst, uint32_t count) const
-{
- const size_t src_size = sizeof(uint64_t) * count;
- const uint64_t *src = (const uint64_t *)GetData (offset_ptr, src_size);
- if (src)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- uint64_t *dst_pos = (uint64_t *)void_dst;
- uint64_t *dst_end = dst_pos + count;
- const uint64_t *src_pos = src;
- while (dst_pos < dst_end)
- {
- *dst_pos = ReadSwapInt64 (src_pos);
- ++dst_pos;
- ++src_pos;
- }
- }
- else
- {
- memcpy (void_dst, src, src_size);
- }
- // Return a non-nullptr pointer to the converted data as an indicator of success
- return void_dst;
+void *DataExtractor::GetU64(offset_t *offset_ptr, void *void_dst,
+ uint32_t count) const {
+ const size_t src_size = sizeof(uint64_t) * count;
+ const uint64_t *src = (const uint64_t *)GetData(offset_ptr, src_size);
+ if (src) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ uint64_t *dst_pos = (uint64_t *)void_dst;
+ uint64_t *dst_end = dst_pos + count;
+ const uint64_t *src_pos = src;
+ while (dst_pos < dst_end) {
+ *dst_pos = ReadSwapInt64(src_pos);
+ ++dst_pos;
+ ++src_pos;
+ }
+ } else {
+ memcpy(void_dst, src, src_size);
}
- return nullptr;
+ // Return a non-nullptr pointer to the converted data as an indicator of
+ // success
+ return void_dst;
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -654,19 +569,23 @@ DataExtractor::GetU64 (offset_t *offset_ptr, void *void_dst, uint32_t count) con
//
// RETURNS the integer value that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::GetMaxU32 (offset_t *offset_ptr, size_t byte_size) const
-{
- switch (byte_size)
- {
- case 1: return GetU8 (offset_ptr); break;
- case 2: return GetU16(offset_ptr); break;
- case 4: return GetU32(offset_ptr); break;
- default:
- assert(false && "GetMaxU32 unhandled case!");
- break;
- }
- return 0;
+uint32_t DataExtractor::GetMaxU32(offset_t *offset_ptr,
+ size_t byte_size) const {
+ switch (byte_size) {
+ case 1:
+ return GetU8(offset_ptr);
+ break;
+ case 2:
+ return GetU16(offset_ptr);
+ break;
+ case 4:
+ return GetU32(offset_ptr);
+ break;
+ default:
+ assert(false && "GetMaxU32 unhandled case!");
+ break;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -679,153 +598,154 @@ DataExtractor::GetMaxU32 (offset_t *offset_ptr, size_t byte_size) const
//
// RETURNS the integer value that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint64_t
-DataExtractor::GetMaxU64 (offset_t *offset_ptr, size_t size) const
-{
- switch (size)
- {
- case 1: return GetU8 (offset_ptr); break;
- case 2: return GetU16(offset_ptr); break;
- case 4: return GetU32(offset_ptr); break;
- case 8: return GetU64(offset_ptr); break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
- }
- return 0;
-}
-
-uint64_t
-DataExtractor::GetMaxU64_unchecked (offset_t *offset_ptr, size_t size) const
-{
- switch (size)
- {
- case 1: return GetU8_unchecked (offset_ptr); break;
- case 2: return GetU16_unchecked (offset_ptr); break;
- case 4: return GetU32_unchecked (offset_ptr); break;
- case 8: return GetU64_unchecked (offset_ptr); break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
- }
- return 0;
-}
-
-int64_t
-DataExtractor::GetMaxS64 (offset_t *offset_ptr, size_t size) const
-{
- switch (size)
- {
- case 1: return (int8_t)GetU8 (offset_ptr); break;
- case 2: return (int16_t)GetU16(offset_ptr); break;
- case 4: return (int32_t)GetU32(offset_ptr); break;
- case 8: return (int64_t)GetU64(offset_ptr); break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
- }
- return 0;
-}
-
-uint64_t
-DataExtractor::GetMaxU64Bitfield (offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
-{
- uint64_t uval64 = GetMaxU64 (offset_ptr, size);
- if (bitfield_bit_size > 0)
- {
- int32_t lsbcount = bitfield_bit_offset;
- if (m_byte_order == eByteOrderBig)
- lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
- if (lsbcount > 0)
- uval64 >>= lsbcount;
- uint64_t bitfield_mask = ((1ul << bitfield_bit_size) - 1);
- if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64)
- return uval64;
- uval64 &= bitfield_mask;
+uint64_t DataExtractor::GetMaxU64(offset_t *offset_ptr, size_t size) const {
+ switch (size) {
+ case 1:
+ return GetU8(offset_ptr);
+ break;
+ case 2:
+ return GetU16(offset_ptr);
+ break;
+ case 4:
+ return GetU32(offset_ptr);
+ break;
+ case 8:
+ return GetU64(offset_ptr);
+ break;
+ default:
+ assert(false && "GetMax64 unhandled case!");
+ break;
+ }
+ return 0;
+}
+
+uint64_t DataExtractor::GetMaxU64_unchecked(offset_t *offset_ptr,
+ size_t size) const {
+ switch (size) {
+ case 1:
+ return GetU8_unchecked(offset_ptr);
+ break;
+ case 2:
+ return GetU16_unchecked(offset_ptr);
+ break;
+ case 4:
+ return GetU32_unchecked(offset_ptr);
+ break;
+ case 8:
+ return GetU64_unchecked(offset_ptr);
+ break;
+ default:
+ assert(false && "GetMax64 unhandled case!");
+ break;
+ }
+ return 0;
+}
+
+int64_t DataExtractor::GetMaxS64(offset_t *offset_ptr, size_t size) const {
+ switch (size) {
+ case 1:
+ return (int8_t)GetU8(offset_ptr);
+ break;
+ case 2:
+ return (int16_t)GetU16(offset_ptr);
+ break;
+ case 4:
+ return (int32_t)GetU32(offset_ptr);
+ break;
+ case 8:
+ return (int64_t)GetU64(offset_ptr);
+ break;
+ default:
+ assert(false && "GetMax64 unhandled case!");
+ break;
+ }
+ return 0;
+}
+
+uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset) const {
+ uint64_t uval64 = GetMaxU64(offset_ptr, size);
+ if (bitfield_bit_size > 0) {
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ uval64 >>= lsbcount;
+ uint64_t bitfield_mask = ((1ul << bitfield_bit_size) - 1);
+ if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64)
+ return uval64;
+ uval64 &= bitfield_mask;
+ }
+ return uval64;
+}
+
+int64_t DataExtractor::GetMaxS64Bitfield(offset_t *offset_ptr, size_t size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset) const {
+ int64_t sval64 = GetMaxS64(offset_ptr, size);
+ if (bitfield_bit_size > 0) {
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ sval64 >>= lsbcount;
+ uint64_t bitfield_mask = (((uint64_t)1) << bitfield_bit_size) - 1;
+ sval64 &= bitfield_mask;
+ // sign extend if needed
+ if (sval64 & (((uint64_t)1) << (bitfield_bit_size - 1)))
+ sval64 |= ~bitfield_mask;
+ }
+ return sval64;
+}
+
+float DataExtractor::GetFloat(offset_t *offset_ptr) const {
+ typedef float float_type;
+ float_type val = 0.0;
+ const size_t src_size = sizeof(float_type);
+ const float_type *src = (const float_type *)GetData(offset_ptr, src_size);
+ if (src) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ const uint8_t *src_data = (const uint8_t *)src;
+ uint8_t *dst_data = (uint8_t *)&val;
+ for (size_t i = 0; i < sizeof(float_type); ++i)
+ dst_data[sizeof(float_type) - 1 - i] = src_data[i];
+ } else {
+ val = *src;
}
- return uval64;
-}
-
-int64_t
-DataExtractor::GetMaxS64Bitfield (offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
-{
- int64_t sval64 = GetMaxS64 (offset_ptr, size);
- if (bitfield_bit_size > 0)
- {
- int32_t lsbcount = bitfield_bit_offset;
- if (m_byte_order == eByteOrderBig)
- lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
- if (lsbcount > 0)
- sval64 >>= lsbcount;
- uint64_t bitfield_mask = (((uint64_t)1) << bitfield_bit_size) - 1;
- sval64 &= bitfield_mask;
- // sign extend if needed
- if (sval64 & (((uint64_t)1) << (bitfield_bit_size - 1)))
- sval64 |= ~bitfield_mask;
- }
- return sval64;
-}
-
-
-float
-DataExtractor::GetFloat (offset_t *offset_ptr) const
-{
- typedef float float_type;
- float_type val = 0.0;
- const size_t src_size = sizeof(float_type);
- const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
- if (src)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- const uint8_t *src_data = (const uint8_t *)src;
- uint8_t *dst_data = (uint8_t *)&val;
- for (size_t i = 0; i < sizeof(float_type); ++i)
- dst_data[sizeof(float_type) - 1 - i] = src_data[i];
- }
- else
- {
- val = *src;
- }
- }
- return val;
-}
-
-double
-DataExtractor::GetDouble (offset_t *offset_ptr) const
-{
- typedef double float_type;
- float_type val = 0.0;
- const size_t src_size = sizeof(float_type);
- const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
- if (src)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- const uint8_t *src_data = (const uint8_t *)src;
- uint8_t *dst_data = (uint8_t *)&val;
- for (size_t i = 0; i < sizeof(float_type); ++i)
- dst_data[sizeof(float_type) - 1 - i] = src_data[i];
- }
- else
- {
- val = *src;
- }
+ }
+ return val;
+}
+
+double DataExtractor::GetDouble(offset_t *offset_ptr) const {
+ typedef double float_type;
+ float_type val = 0.0;
+ const size_t src_size = sizeof(float_type);
+ const float_type *src = (const float_type *)GetData(offset_ptr, src_size);
+ if (src) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ const uint8_t *src_data = (const uint8_t *)src;
+ uint8_t *dst_data = (uint8_t *)&val;
+ for (size_t i = 0; i < sizeof(float_type); ++i)
+ dst_data[sizeof(float_type) - 1 - i] = src_data[i];
+ } else {
+ val = *src;
}
- return val;
+ }
+ return val;
}
-
-long double
-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), endian::InlHostByteOrder());
+long double 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),
+ endian::InlHostByteOrder());
#else
- *offset_ptr += CopyByteOrderedData (*offset_ptr, sizeof(val), &val, sizeof(val), endian::InlHostByteOrder());
+ *offset_ptr += CopyByteOrderedData(*offset_ptr, sizeof(val), &val,
+ sizeof(val), endian::InlHostByteOrder());
#endif
- return val;
+ return val;
}
//------------------------------------------------------------------
@@ -836,22 +756,18 @@ DataExtractor::GetLongDouble (offset_t *offset_ptr) const
//
// RETURNS the address that was extracted, or zero on failure.
//------------------------------------------------------------------
-uint64_t
-DataExtractor::GetAddress (offset_t *offset_ptr) const
-{
+uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
- return GetMaxU64 (offset_ptr, m_addr_size);
+ return GetMaxU64(offset_ptr, m_addr_size);
}
-uint64_t
-DataExtractor::GetAddress_unchecked (offset_t *offset_ptr) const
-{
+uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
- return GetMaxU64_unchecked (offset_ptr, m_addr_size);
+ return GetMaxU64_unchecked(offset_ptr, m_addr_size);
}
//------------------------------------------------------------------
@@ -862,13 +778,11 @@ DataExtractor::GetAddress_unchecked (offset_t *offset_ptr) const
//
// RETURNS the pointer that was extracted, or zero on failure.
//------------------------------------------------------------------
-uint64_t
-DataExtractor::GetPointer (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);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
- return GetMaxU64 (offset_ptr, m_addr_size);
+ return GetMaxU64(offset_ptr, m_addr_size);
}
//----------------------------------------------------------------------
@@ -878,256 +792,239 @@ DataExtractor::GetPointer (offset_t *offset_ptr) const
// pointer encoding.
//----------------------------------------------------------------------
-uint64_t
-DataExtractor::GetGNUEHPointer (offset_t *offset_ptr, uint32_t eh_ptr_enc, lldb::addr_t pc_rel_addr, lldb::addr_t text_addr, lldb::addr_t data_addr)//, BSDRelocs *data_relocs) const
+uint64_t DataExtractor::GetGNUEHPointer(
+ offset_t *offset_ptr, uint32_t eh_ptr_enc, lldb::addr_t pc_rel_addr,
+ lldb::addr_t text_addr,
+ lldb::addr_t data_addr) //, BSDRelocs *data_relocs) const
{
- if (eh_ptr_enc == DW_EH_PE_omit)
- return ULLONG_MAX; // Value isn't in the buffer...
+ if (eh_ptr_enc == DW_EH_PE_omit)
+ return ULLONG_MAX; // Value isn't in the buffer...
- uint64_t baseAddress = 0;
- uint64_t addressValue = 0;
- const uint32_t addr_size = GetAddressByteSize();
+ 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);
+ assert(addr_size == 4 || addr_size == 8);
#endif
- bool signExtendValue = false;
- // Decode the base part or adjust our offset
- switch (eh_ptr_enc & 0x70)
- {
- case DW_EH_PE_pcrel:
- signExtendValue = true;
- baseAddress = *offset_ptr;
- if (pc_rel_addr != LLDB_INVALID_ADDRESS)
- baseAddress += pc_rel_addr;
-// else
-// Log::GlobalWarning ("PC relative pointer encoding found with invalid pc relative address.");
- break;
-
- case DW_EH_PE_textrel:
- signExtendValue = true;
- if (text_addr != LLDB_INVALID_ADDRESS)
- baseAddress = text_addr;
-// else
-// Log::GlobalWarning ("text relative pointer encoding being decoded with invalid text section address, setting base address to zero.");
- break;
-
- case DW_EH_PE_datarel:
- signExtendValue = true;
- if (data_addr != LLDB_INVALID_ADDRESS)
- baseAddress = data_addr;
-// else
-// Log::GlobalWarning ("data relative pointer encoding being decoded with invalid data section address, setting base address to zero.");
- break;
-
- case DW_EH_PE_funcrel:
- signExtendValue = true;
- break;
-
- case DW_EH_PE_aligned:
- {
- // SetPointerSize should be called prior to extracting these so the
- // pointer size is cached
- assert(addr_size != 0);
- if (addr_size)
- {
- // Align to a address size boundary first
- uint32_t alignOffset = *offset_ptr % addr_size;
- if (alignOffset)
- offset_ptr += addr_size - alignOffset;
- }
- }
- break;
-
- default:
- break;
- }
-
- // Decode the value part
- switch (eh_ptr_enc & DW_EH_PE_MASK_ENCODING)
- {
- case DW_EH_PE_absptr :
- {
- addressValue = GetAddress (offset_ptr);
-// if (data_relocs)
-// addressValue = data_relocs->Relocate(*offset_ptr - addr_size, *this, addressValue);
- }
- break;
- case DW_EH_PE_uleb128 : addressValue = GetULEB128(offset_ptr); break;
- case DW_EH_PE_udata2 : addressValue = GetU16(offset_ptr); break;
- case DW_EH_PE_udata4 : addressValue = GetU32(offset_ptr); break;
- case DW_EH_PE_udata8 : addressValue = GetU64(offset_ptr); break;
- case DW_EH_PE_sleb128 : addressValue = GetSLEB128(offset_ptr); break;
- case DW_EH_PE_sdata2 : addressValue = (int16_t)GetU16(offset_ptr); break;
- case DW_EH_PE_sdata4 : addressValue = (int32_t)GetU32(offset_ptr); break;
- case DW_EH_PE_sdata8 : addressValue = (int64_t)GetU64(offset_ptr); break;
- default:
- // Unhandled encoding type
- assert(eh_ptr_enc);
- break;
+ bool signExtendValue = false;
+ // Decode the base part or adjust our offset
+ switch (eh_ptr_enc & 0x70) {
+ case DW_EH_PE_pcrel:
+ signExtendValue = true;
+ baseAddress = *offset_ptr;
+ if (pc_rel_addr != LLDB_INVALID_ADDRESS)
+ baseAddress += pc_rel_addr;
+ // else
+ // Log::GlobalWarning ("PC relative pointer encoding found with
+ // invalid pc relative address.");
+ break;
+
+ case DW_EH_PE_textrel:
+ signExtendValue = true;
+ if (text_addr != LLDB_INVALID_ADDRESS)
+ baseAddress = text_addr;
+ // else
+ // Log::GlobalWarning ("text relative pointer encoding being
+ // decoded with invalid text section address, setting base address
+ // to zero.");
+ break;
+
+ case DW_EH_PE_datarel:
+ signExtendValue = true;
+ if (data_addr != LLDB_INVALID_ADDRESS)
+ baseAddress = data_addr;
+ // else
+ // Log::GlobalWarning ("data relative pointer encoding being
+ // decoded with invalid data section address, setting base address
+ // to zero.");
+ break;
+
+ case DW_EH_PE_funcrel:
+ signExtendValue = true;
+ break;
+
+ case DW_EH_PE_aligned: {
+ // SetPointerSize should be called prior to extracting these so the
+ // pointer size is cached
+ assert(addr_size != 0);
+ if (addr_size) {
+ // Align to a address size boundary first
+ uint32_t alignOffset = *offset_ptr % addr_size;
+ if (alignOffset)
+ offset_ptr += addr_size - alignOffset;
}
-
- // Since we promote everything to 64 bit, we may need to sign extend
- if (signExtendValue && addr_size < sizeof(baseAddress))
- {
- uint64_t sign_bit = 1ull << ((addr_size * 8ull) - 1ull);
- if (sign_bit & addressValue)
- {
- uint64_t mask = ~sign_bit + 1;
- addressValue |= mask;
- }
+ } break;
+
+ default:
+ break;
+ }
+
+ // Decode the value part
+ switch (eh_ptr_enc & DW_EH_PE_MASK_ENCODING) {
+ case DW_EH_PE_absptr: {
+ addressValue = GetAddress(offset_ptr);
+ // if (data_relocs)
+ // addressValue = data_relocs->Relocate(*offset_ptr -
+ // addr_size, *this, addressValue);
+ } break;
+ case DW_EH_PE_uleb128:
+ addressValue = GetULEB128(offset_ptr);
+ break;
+ case DW_EH_PE_udata2:
+ addressValue = GetU16(offset_ptr);
+ break;
+ case DW_EH_PE_udata4:
+ addressValue = GetU32(offset_ptr);
+ break;
+ case DW_EH_PE_udata8:
+ addressValue = GetU64(offset_ptr);
+ break;
+ case DW_EH_PE_sleb128:
+ addressValue = GetSLEB128(offset_ptr);
+ break;
+ case DW_EH_PE_sdata2:
+ addressValue = (int16_t)GetU16(offset_ptr);
+ break;
+ case DW_EH_PE_sdata4:
+ addressValue = (int32_t)GetU32(offset_ptr);
+ break;
+ case DW_EH_PE_sdata8:
+ addressValue = (int64_t)GetU64(offset_ptr);
+ break;
+ default:
+ // Unhandled encoding type
+ assert(eh_ptr_enc);
+ break;
+ }
+
+ // Since we promote everything to 64 bit, we may need to sign extend
+ if (signExtendValue && addr_size < sizeof(baseAddress)) {
+ uint64_t sign_bit = 1ull << ((addr_size * 8ull) - 1ull);
+ if (sign_bit & addressValue) {
+ uint64_t mask = ~sign_bit + 1;
+ addressValue |= mask;
}
- return baseAddress + addressValue;
+ }
+ return baseAddress + addressValue;
}
-size_t
-DataExtractor::ExtractBytes (offset_t offset, offset_t length, ByteOrder dst_byte_order, void *dst) const
-{
- const uint8_t *src = PeekData (offset, length);
- if (src)
- {
- if (dst_byte_order != GetByteOrder())
- {
- // Validate that only a word- or register-sized dst is byte swapped
- assert (length == 1 || length == 2 || length == 4 || length == 8 ||
- length == 10 || length == 16 || length == 32);
-
- for (uint32_t i = 0; i < length; ++i)
- ((uint8_t*)dst)[i] = src[length - i - 1];
- }
- else
- ::memcpy (dst, src, length);
- return length;
- }
- return 0;
+size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length,
+ ByteOrder dst_byte_order, void *dst) const {
+ const uint8_t *src = PeekData(offset, length);
+ if (src) {
+ if (dst_byte_order != GetByteOrder()) {
+ // Validate that only a word- or register-sized dst is byte swapped
+ assert(length == 1 || length == 2 || length == 4 || length == 8 ||
+ length == 10 || length == 16 || length == 32);
+
+ for (uint32_t i = 0; i < length; ++i)
+ ((uint8_t *)dst)[i] = src[length - i - 1];
+ } else
+ ::memcpy(dst, src, length);
+ return length;
+ }
+ return 0;
}
// Extract data as it exists in target memory
-lldb::offset_t
-DataExtractor::CopyData (offset_t offset,
- offset_t length,
- void *dst) const
-{
- const uint8_t *src = PeekData (offset, length);
- if (src)
- {
- ::memcpy (dst, src, length);
- return length;
- }
- return 0;
+lldb::offset_t DataExtractor::CopyData(offset_t offset, offset_t length,
+ void *dst) const {
+ const uint8_t *src = PeekData(offset, length);
+ if (src) {
+ ::memcpy(dst, src, length);
+ return length;
+ }
+ return 0;
}
// Extract data and swap if needed when doing the copy
lldb::offset_t
-DataExtractor::CopyByteOrderedData (offset_t src_offset,
- offset_t src_len,
- void *dst_void_ptr,
- offset_t dst_len,
- ByteOrder dst_byte_order) const
-{
- // Validate the source info
- if (!ValidOffsetForDataOfSize(src_offset, src_len))
- assert (ValidOffsetForDataOfSize(src_offset, src_len));
- assert (src_len > 0);
- assert (m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle);
-
- // Validate the destination info
- assert(dst_void_ptr != nullptr);
- assert (dst_len > 0);
- assert (dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle);
-
- // Validate that only a word- or register-sized dst is byte swapped
- assert (dst_byte_order == m_byte_order || dst_len == 1 || dst_len == 2 ||
- dst_len == 4 || dst_len == 8 || dst_len == 10 || dst_len == 16 ||
- dst_len == 32);
-
- // Must have valid byte orders set in this object and for destination
- if (!(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle) ||
- !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle))
- return 0;
-
- uint8_t* dst = (uint8_t*)dst_void_ptr;
- const uint8_t* src = (const uint8_t *)PeekData (src_offset, src_len);
- if (src)
- {
- if (dst_len >= src_len)
- {
- // We are copying the entire value from src into dst.
- // Calculate how many, if any, zeroes we need for the most
- // significant bytes if "dst_len" is greater than "src_len"...
- const size_t num_zeroes = dst_len - src_len;
- if (dst_byte_order == eByteOrderBig)
- {
- // Big endian, so we lead with zeroes...
- if (num_zeroes > 0)
- ::memset (dst, 0, num_zeroes);
- // Then either copy or swap the rest
- if (m_byte_order == eByteOrderBig)
- {
- ::memcpy (dst + num_zeroes, src, src_len);
- }
- else
- {
- for (uint32_t i = 0; i < src_len; ++i)
- dst[i+num_zeroes] = src[src_len - 1 - i];
- }
- }
- else
- {
- // Little endian destination, so we lead the value bytes
- if (m_byte_order == eByteOrderBig)
- {
- for (uint32_t i = 0; i < src_len; ++i)
- dst[i] = src[src_len - 1 - i];
- }
- else
- {
- ::memcpy (dst, src, src_len);
- }
- // And zero the rest...
- if (num_zeroes > 0)
- ::memset (dst + src_len, 0, num_zeroes);
- }
- return src_len;
+DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len,
+ void *dst_void_ptr, offset_t dst_len,
+ ByteOrder dst_byte_order) const {
+ // Validate the source info
+ if (!ValidOffsetForDataOfSize(src_offset, src_len))
+ assert(ValidOffsetForDataOfSize(src_offset, src_len));
+ assert(src_len > 0);
+ assert(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle);
+
+ // Validate the destination info
+ assert(dst_void_ptr != nullptr);
+ assert(dst_len > 0);
+ assert(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle);
+
+ // Validate that only a word- or register-sized dst is byte swapped
+ assert(dst_byte_order == m_byte_order || dst_len == 1 || dst_len == 2 ||
+ dst_len == 4 || dst_len == 8 || dst_len == 10 || dst_len == 16 ||
+ dst_len == 32);
+
+ // Must have valid byte orders set in this object and for destination
+ if (!(dst_byte_order == eByteOrderBig ||
+ dst_byte_order == eByteOrderLittle) ||
+ !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle))
+ return 0;
+
+ uint8_t *dst = (uint8_t *)dst_void_ptr;
+ const uint8_t *src = (const uint8_t *)PeekData(src_offset, src_len);
+ if (src) {
+ if (dst_len >= src_len) {
+ // We are copying the entire value from src into dst.
+ // Calculate how many, if any, zeroes we need for the most
+ // significant bytes if "dst_len" is greater than "src_len"...
+ const size_t num_zeroes = dst_len - src_len;
+ if (dst_byte_order == eByteOrderBig) {
+ // Big endian, so we lead with zeroes...
+ if (num_zeroes > 0)
+ ::memset(dst, 0, num_zeroes);
+ // Then either copy or swap the rest
+ if (m_byte_order == eByteOrderBig) {
+ ::memcpy(dst + num_zeroes, src, src_len);
+ } else {
+ for (uint32_t i = 0; i < src_len; ++i)
+ dst[i + num_zeroes] = src[src_len - 1 - i];
}
- else
- {
- // We are only copying some of the value from src into dst..
-
- if (dst_byte_order == eByteOrderBig)
- {
- // Big endian dst
- if (m_byte_order == eByteOrderBig)
- {
- // Big endian dst, with big endian src
- ::memcpy (dst, src + (src_len - dst_len), dst_len);
- }
- else
- {
- // Big endian dst, with little endian src
- for (uint32_t i = 0; i < dst_len; ++i)
- dst[i] = src[dst_len - 1 - i];
- }
- }
- else
- {
- // Little endian dst
- if (m_byte_order == eByteOrderBig)
- {
- // Little endian dst, with big endian src
- for (uint32_t i = 0; i < dst_len; ++i)
- dst[i] = src[src_len - 1 - i];
- }
- else
- {
- // Little endian dst, with big endian src
- ::memcpy (dst, src, dst_len);
- }
- }
- return dst_len;
- }
+ } else {
+ // Little endian destination, so we lead the value bytes
+ if (m_byte_order == eByteOrderBig) {
+ for (uint32_t i = 0; i < src_len; ++i)
+ dst[i] = src[src_len - 1 - i];
+ } else {
+ ::memcpy(dst, src, src_len);
+ }
+ // And zero the rest...
+ if (num_zeroes > 0)
+ ::memset(dst + src_len, 0, num_zeroes);
+ }
+ return src_len;
+ } else {
+ // We are only copying some of the value from src into dst..
+
+ if (dst_byte_order == eByteOrderBig) {
+ // Big endian dst
+ if (m_byte_order == eByteOrderBig) {
+ // Big endian dst, with big endian src
+ ::memcpy(dst, src + (src_len - dst_len), dst_len);
+ } else {
+ // Big endian dst, with little endian src
+ for (uint32_t i = 0; i < dst_len; ++i)
+ dst[i] = src[dst_len - 1 - i];
+ }
+ } else {
+ // Little endian dst
+ if (m_byte_order == eByteOrderBig) {
+ // Little endian dst, with big endian src
+ for (uint32_t i = 0; i < dst_len; ++i)
+ dst[i] = src[src_len - 1 - i];
+ } else {
+ // Little endian dst, with big endian src
+ ::memcpy(dst, src, dst_len);
+ }
+ }
+ return dst_len;
}
- return 0;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -1141,32 +1038,28 @@ DataExtractor::CopyByteOrderedData (offset_t src_offset,
// bytes, nullptr will be returned and "offset_ptr" will not be
// updated.
//----------------------------------------------------------------------
-const char*
-DataExtractor::GetCStr (offset_t *offset_ptr) const
-{
- const char *cstr = (const char *)PeekData (*offset_ptr, 1);
- if (cstr)
- {
- const char *cstr_end = cstr;
- const char *end = (const char *)m_end;
- while (cstr_end < end && *cstr_end)
- ++cstr_end;
-
- // Now we are either at the end of the data or we point to the
- // NULL C string terminator with cstr_end...
- if (*cstr_end == '\0')
- {
- // Advance the offset with one extra byte for the NULL terminator
- *offset_ptr += (cstr_end - cstr + 1);
- return cstr;
- }
-
- // We reached the end of the data without finding a NULL C string
- // terminator. Fall through and return nullptr otherwise anyone that
- // would have used the result as a C string can wander into
- // unknown memory...
+const char *DataExtractor::GetCStr(offset_t *offset_ptr) const {
+ const char *cstr = (const char *)PeekData(*offset_ptr, 1);
+ if (cstr) {
+ const char *cstr_end = cstr;
+ const char *end = (const char *)m_end;
+ while (cstr_end < end && *cstr_end)
+ ++cstr_end;
+
+ // Now we are either at the end of the data or we point to the
+ // NULL C string terminator with cstr_end...
+ if (*cstr_end == '\0') {
+ // Advance the offset with one extra byte for the NULL terminator
+ *offset_ptr += (cstr_end - cstr + 1);
+ return cstr;
}
- return nullptr;
+
+ // We reached the end of the data without finding a NULL C string
+ // terminator. Fall through and return nullptr otherwise anyone that
+ // would have used the result as a C string can wander into
+ // unknown memory...
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -1180,20 +1073,16 @@ DataExtractor::GetCStr (offset_t *offset_ptr) const
// field does not contain a NULL terminator byte, nullptr will be returned
// and "offset_ptr" will not be updated.
//----------------------------------------------------------------------
-const char*
-DataExtractor::GetCStr (offset_t *offset_ptr, offset_t len) const
-{
- const char *cstr = (const char *)PeekData (*offset_ptr, len);
- if (cstr != nullptr)
- {
- if (memchr(cstr, '\0', len) == nullptr)
- {
- return nullptr;
- }
- *offset_ptr += len;
- return cstr;
+const char *DataExtractor::GetCStr(offset_t *offset_ptr, offset_t len) const {
+ const char *cstr = (const char *)PeekData(*offset_ptr, len);
+ if (cstr != nullptr) {
+ if (memchr(cstr, '\0', len) == nullptr) {
+ return nullptr;
}
- return nullptr;
+ *offset_ptr += len;
+ return cstr;
+ }
+ return nullptr;
}
//------------------------------------------------------------------
@@ -1204,10 +1093,8 @@ DataExtractor::GetCStr (offset_t *offset_ptr, offset_t len) const
// Returns a valid C string pointer if "offset" is a valid offset in
// this object's data, else nullptr is returned.
//------------------------------------------------------------------
-const char *
-DataExtractor::PeekCStr (offset_t offset) const
-{
- return (const char *)PeekData (offset, 1);
+const char *DataExtractor::PeekCStr(offset_t offset) const {
+ return (const char *)PeekData(offset, 1);
}
//----------------------------------------------------------------------
@@ -1218,36 +1105,31 @@ DataExtractor::PeekCStr (offset_t offset) const
//
// Returned the extracted integer value.
//----------------------------------------------------------------------
-uint64_t
-DataExtractor::GetULEB128 (offset_t *offset_ptr) const
-{
- const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == nullptr)
- return 0;
-
- const uint8_t *end = m_end;
-
- if (src < end)
- {
- uint64_t result = *src++;
- if (result >= 0x80)
- {
- result &= 0x7f;
- int shift = 7;
- while (src < end)
- {
- uint8_t byte = *src++;
- result |= (uint64_t)(byte & 0x7f) << shift;
- if ((byte & 0x80) == 0)
- break;
- shift += 7;
- }
- }
- *offset_ptr = src - m_start;
- return result;
- }
-
+uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const {
+ const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
+ if (src == nullptr)
return 0;
+
+ const uint8_t *end = m_end;
+
+ if (src < end) {
+ uint64_t result = *src++;
+ if (result >= 0x80) {
+ result &= 0x7f;
+ int shift = 7;
+ while (src < end) {
+ uint8_t byte = *src++;
+ result |= (uint64_t)(byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0)
+ break;
+ shift += 7;
+ }
+ }
+ *offset_ptr = src - m_start;
+ return result;
+ }
+
+ return 0;
}
//----------------------------------------------------------------------
@@ -1258,42 +1140,38 @@ DataExtractor::GetULEB128 (offset_t *offset_ptr) const
//
// Returned the extracted integer value.
//----------------------------------------------------------------------
-int64_t
-DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
-{
- const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == nullptr)
- return 0;
-
- const uint8_t *end = m_end;
-
- if (src < end)
- {
- int64_t result = 0;
- int shift = 0;
- int size = sizeof (int64_t) * 8;
-
- uint8_t byte = 0;
- int bytecount = 0;
-
- while (src < end)
- {
- bytecount++;
- byte = *src++;
- result |= (int64_t)(byte & 0x7f) << shift;
- shift += 7;
- if ((byte & 0x80) == 0)
- break;
- }
+int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const {
+ const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
+ if (src == nullptr)
+ return 0;
- // Sign bit of byte is 2nd high order bit (0x40)
- if (shift < size && (byte & 0x40))
- result |= - (1 << shift);
+ const uint8_t *end = m_end;
- *offset_ptr += bytecount;
- return result;
+ if (src < end) {
+ int64_t result = 0;
+ int shift = 0;
+ int size = sizeof(int64_t) * 8;
+
+ uint8_t byte = 0;
+ int bytecount = 0;
+
+ while (src < end) {
+ bytecount++;
+ byte = *src++;
+ result |= (int64_t)(byte & 0x7f) << shift;
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
}
- return 0;
+
+ // Sign bit of byte is 2nd high order bit (0x40)
+ if (shift < size && (byte & 0x40))
+ result |= -(1 << shift);
+
+ *offset_ptr += bytecount;
+ return result;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -1304,761 +1182,774 @@ DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
//
// Returns the number of bytes consumed during the extraction.
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::Skip_LEB128 (offset_t *offset_ptr) const
-{
- uint32_t bytes_consumed = 0;
- const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == nullptr)
- return 0;
-
- const uint8_t *end = m_end;
-
- if (src < end)
- {
- const uint8_t *src_pos = src;
- while ((src_pos < end) && (*src_pos++ & 0x80))
- ++bytes_consumed;
- *offset_ptr += src_pos - src;
- }
- return bytes_consumed;
-}
+uint32_t DataExtractor::Skip_LEB128(offset_t *offset_ptr) const {
+ uint32_t bytes_consumed = 0;
+ const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
+ if (src == nullptr)
+ return 0;
-static bool
-GetAPInt (const DataExtractor &data, lldb::offset_t *offset_ptr, lldb::offset_t byte_size, llvm::APInt &result)
-{
- llvm::SmallVector<uint64_t, 2> uint64_array;
- lldb::offset_t bytes_left = byte_size;
- uint64_t u64;
- const lldb::ByteOrder byte_order = data.GetByteOrder();
- if (byte_order == lldb::eByteOrderLittle)
- {
- while (bytes_left > 0)
- {
- if (bytes_left >= 8)
- {
- u64 = data.GetU64(offset_ptr);
- bytes_left -= 8;
- }
- else
- {
- u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
- bytes_left = 0;
- }
- uint64_array.push_back(u64);
- }
- result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
- return true;
- }
- else if (byte_order == lldb::eByteOrderBig)
- {
- lldb::offset_t be_offset = *offset_ptr + byte_size;
- lldb::offset_t temp_offset;
- while (bytes_left > 0)
- {
- if (bytes_left >= 8)
- {
- be_offset -= 8;
- temp_offset = be_offset;
- u64 = data.GetU64(&temp_offset);
- bytes_left -= 8;
- }
- else
- {
- be_offset -= bytes_left;
- temp_offset = be_offset;
- u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
- bytes_left = 0;
- }
- uint64_array.push_back(u64);
- }
- *offset_ptr += byte_size;
- result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
- return true;
+ const uint8_t *end = m_end;
+
+ if (src < end) {
+ const uint8_t *src_pos = src;
+ while ((src_pos < end) && (*src_pos++ & 0x80))
+ ++bytes_consumed;
+ *offset_ptr += src_pos - src;
+ }
+ return bytes_consumed;
+}
+
+static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ lldb::offset_t byte_size, llvm::APInt &result) {
+ llvm::SmallVector<uint64_t, 2> uint64_array;
+ lldb::offset_t bytes_left = byte_size;
+ uint64_t u64;
+ const lldb::ByteOrder byte_order = data.GetByteOrder();
+ if (byte_order == lldb::eByteOrderLittle) {
+ while (bytes_left > 0) {
+ if (bytes_left >= 8) {
+ u64 = data.GetU64(offset_ptr);
+ bytes_left -= 8;
+ } else {
+ u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
+ bytes_left = 0;
+ }
+ uint64_array.push_back(u64);
}
- return false;
-}
-
-static lldb::offset_t
-DumpAPInt (Stream *s, const DataExtractor &data, lldb::offset_t offset, lldb::offset_t byte_size, bool is_signed, unsigned radix)
-{
- llvm::APInt apint;
- if (GetAPInt (data, &offset, byte_size, apint))
- {
- std::string apint_str(apint.toString(radix, is_signed));
- switch (radix)
- {
- case 2:
- s->Write ("0b", 2);
- break;
- case 8:
- s->Write ("0", 1);
- break;
- case 10:
- break;
- }
- s->Write(apint_str.c_str(), apint_str.size());
+ result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
+ return true;
+ } else if (byte_order == lldb::eByteOrderBig) {
+ lldb::offset_t be_offset = *offset_ptr + byte_size;
+ lldb::offset_t temp_offset;
+ while (bytes_left > 0) {
+ if (bytes_left >= 8) {
+ be_offset -= 8;
+ temp_offset = be_offset;
+ u64 = data.GetU64(&temp_offset);
+ bytes_left -= 8;
+ } else {
+ be_offset -= bytes_left;
+ temp_offset = be_offset;
+ u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
+ bytes_left = 0;
+ }
+ uint64_array.push_back(u64);
}
- return offset;
-}
-
-static float
-half2float (uint16_t half)
-{
- union { float f; uint32_t u; } u;
- int32_t v = (int16_t) half;
-
- if (0 == (v & 0x7c00))
- {
- u.u = v & 0x80007FFFU;
- return u.f * ldexpf(1, 125);
+ *offset_ptr += byte_size;
+ result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
+ return true;
+ }
+ return false;
+}
+
+static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data,
+ lldb::offset_t offset, lldb::offset_t byte_size,
+ bool is_signed, unsigned radix) {
+ llvm::APInt apint;
+ if (GetAPInt(data, &offset, byte_size, apint)) {
+ std::string apint_str(apint.toString(radix, is_signed));
+ switch (radix) {
+ case 2:
+ s->Write("0b", 2);
+ break;
+ case 8:
+ s->Write("0", 1);
+ break;
+ case 10:
+ break;
}
+ s->Write(apint_str.c_str(), apint_str.size());
+ }
+ return offset;
+}
+
+static float half2float(uint16_t half) {
+ union {
+ float f;
+ uint32_t u;
+ } u;
+ int32_t v = (int16_t)half;
+
+ 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);
+}
+
+lldb::offset_t DataExtractor::Dump(
+ Stream *s, offset_t start_offset, lldb::Format item_format,
+ size_t item_byte_size, size_t item_count, size_t num_per_line,
+ uint64_t base_addr,
+ uint32_t item_bit_size, // If zero, this is not a bitfield value, if
+ // non-zero, the value is a bitfield
+ uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the
+ // shift amount to apply to a bitfield
+ ExecutionContextScope *exe_scope) const {
+ if (s == nullptr)
+ return start_offset;
+
+ if (item_format == eFormatPointer) {
+ if (item_byte_size != 4 && item_byte_size != 8)
+ item_byte_size = s->GetAddressByteSize();
+ }
+
+ offset_t offset = start_offset;
+
+ if (item_format == eFormatInstruction) {
+ TargetSP target_sp;
+ if (exe_scope)
+ target_sp = exe_scope->CalculateTarget();
+ if (target_sp) {
+ DisassemblerSP disassembler_sp(Disassembler::FindPlugin(
+ target_sp->GetArchitecture(), nullptr, nullptr));
+ if (disassembler_sp) {
+ lldb::addr_t addr = base_addr + start_offset;
+ lldb_private::Address so_addr;
+ bool data_from_file = true;
+ if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) {
+ data_from_file = false;
+ } else {
+ if (target_sp->GetSectionLoadList().IsEmpty() ||
+ !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
+ so_addr.SetRawAddress(addr);
+ }
- v <<= 13;
- u.u = v | 0x70000000U;
- return u.f * ldexpf(1, -112);
-}
-
-lldb::offset_t
-DataExtractor::Dump (Stream *s,
- offset_t start_offset,
- lldb::Format item_format,
- size_t item_byte_size,
- size_t item_count,
- size_t num_per_line,
- uint64_t base_addr,
- uint32_t item_bit_size, // If zero, this is not a bitfield value, if non-zero, the value is a bitfield
- uint32_t item_bit_offset, // If "item_bit_size" is non-zero, this is the shift amount to apply to a bitfield
- ExecutionContextScope *exe_scope) const
-{
- if (s == nullptr)
- return start_offset;
-
- if (item_format == eFormatPointer)
- {
- if (item_byte_size != 4 && item_byte_size != 8)
- item_byte_size = s->GetAddressByteSize();
- }
-
- offset_t offset = start_offset;
-
- if (item_format == eFormatInstruction)
- {
- TargetSP target_sp;
- if (exe_scope)
- target_sp = exe_scope->CalculateTarget();
- if (target_sp)
- {
- DisassemblerSP disassembler_sp(Disassembler::FindPlugin(target_sp->GetArchitecture(), nullptr, nullptr));
- if (disassembler_sp)
- {
- lldb::addr_t addr = base_addr + start_offset;
- lldb_private::Address so_addr;
- bool data_from_file = true;
- if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
- {
- data_from_file = false;
- }
- else
- {
- if (target_sp->GetSectionLoadList().IsEmpty() || !target_sp->GetImages().ResolveFileAddress(addr, so_addr))
- so_addr.SetRawAddress(addr);
- }
-
- size_t bytes_consumed = disassembler_sp->DecodeInstructions (so_addr, *this, start_offset, item_count, false, data_from_file);
-
- if (bytes_consumed)
- {
- offset += bytes_consumed;
- const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
- const bool show_bytes = true;
- ExecutionContext exe_ctx;
- exe_scope->CalculateExecutionContext(exe_ctx);
- disassembler_sp->GetInstructionList().Dump (s, show_address, show_bytes, &exe_ctx);
- }
- }
+ size_t bytes_consumed = disassembler_sp->DecodeInstructions(
+ so_addr, *this, start_offset, item_count, false, data_from_file);
+
+ if (bytes_consumed) {
+ offset += bytes_consumed;
+ const bool show_address = base_addr != LLDB_INVALID_ADDRESS;
+ const bool show_bytes = true;
+ ExecutionContext exe_ctx;
+ exe_scope->CalculateExecutionContext(exe_ctx);
+ disassembler_sp->GetInstructionList().Dump(s, show_address,
+ show_bytes, &exe_ctx);
}
- else
- s->Printf ("invalid target");
+ }
+ } else
+ s->Printf("invalid target");
- return offset;
+ return offset;
+ }
+
+ if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) &&
+ item_byte_size > 8)
+ item_format = eFormatHex;
+
+ lldb::offset_t line_start_offset = start_offset;
+ for (uint32_t count = 0; ValidOffset(offset) && count < item_count; ++count) {
+ if ((count % num_per_line) == 0) {
+ if (count > 0) {
+ if (item_format == eFormatBytesWithASCII &&
+ offset > line_start_offset) {
+ s->Printf("%*s",
+ static_cast<int>(
+ (num_per_line - (offset - line_start_offset)) * 3 + 2),
+ "");
+ Dump(s, line_start_offset, eFormatCharPrintable, 1,
+ offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0,
+ 0);
+ }
+ s->EOL();
+ }
+ if (base_addr != LLDB_INVALID_ADDRESS)
+ s->Printf("0x%8.8" PRIx64 ": ",
+ (uint64_t)(base_addr +
+ (offset - start_offset) / m_target_byte_size));
+
+ line_start_offset = offset;
+ } else if (item_format != eFormatChar &&
+ item_format != eFormatCharPrintable &&
+ item_format != eFormatCharArray && count > 0) {
+ s->PutChar(' ');
}
- if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && item_byte_size > 8)
- item_format = eFormatHex;
-
- lldb::offset_t line_start_offset = start_offset;
- for (uint32_t count = 0; ValidOffset(offset) && count < item_count; ++count)
- {
- if ((count % num_per_line) == 0)
- {
- if (count > 0)
- {
- if (item_format == eFormatBytesWithASCII && offset > line_start_offset)
- {
- s->Printf("%*s", static_cast<int>((num_per_line - (offset - line_start_offset)) * 3 + 2), "");
- Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0);
- }
- s->EOL();
- }
- if (base_addr != LLDB_INVALID_ADDRESS)
- s->Printf ("0x%8.8" PRIx64 ": ",
- (uint64_t)(base_addr + (offset - start_offset)/m_target_byte_size ));
-
- line_start_offset = offset;
- }
- else if (item_format != eFormatChar &&
- item_format != eFormatCharPrintable &&
- item_format != eFormatCharArray &&
- count > 0)
- {
- s->PutChar(' ');
+ switch (item_format) {
+ case eFormatBoolean:
+ if (item_byte_size <= 8)
+ s->Printf("%s", GetMaxU64Bitfield(&offset, item_byte_size,
+ item_bit_size, item_bit_offset)
+ ? "true"
+ : "false");
+ else {
+ s->Printf("error: unsupported byte size (%" PRIu64
+ ") for boolean format",
+ (uint64_t)item_byte_size);
+ return offset;
+ }
+ break;
+
+ case eFormatBinary:
+ if (item_byte_size <= 8) {
+ uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size,
+ item_bit_size, item_bit_offset);
+ // Avoid std::bitset<64>::to_string() since it is missing in
+ // earlier C++ libraries
+ std::string binary_value(64, '0');
+ std::bitset<64> bits(uval64);
+ for (uint32_t i = 0; i < 64; ++i)
+ if (bits[i])
+ binary_value[64 - 1 - i] = '1';
+ if (item_bit_size > 0)
+ s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
+ else if (item_byte_size > 0 && item_byte_size <= 8)
+ s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
+ } else {
+ const bool is_signed = false;
+ const unsigned radix = 2;
+ offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
+ }
+ break;
+
+ case eFormatBytes:
+ case eFormatBytesWithASCII:
+ for (uint32_t i = 0; i < item_byte_size; ++i) {
+ s->Printf("%2.2x", GetU8(&offset));
+ }
+
+ // Put an extra space between the groups of bytes if more than one
+ // is being dumped in a group (item_byte_size is more than 1).
+ if (item_byte_size > 1)
+ s->PutChar(' ');
+ break;
+
+ case eFormatChar:
+ case eFormatCharPrintable:
+ case eFormatCharArray: {
+ // If we are only printing one character surround it with single
+ // quotes
+ if (item_count == 1 && item_format == eFormatChar)
+ s->PutChar('\'');
+
+ const uint64_t ch = GetMaxU64Bitfield(&offset, item_byte_size,
+ item_bit_size, item_bit_offset);
+ if (isprint(ch))
+ s->Printf("%c", (char)ch);
+ else if (item_format != eFormatCharPrintable) {
+ switch (ch) {
+ case '\033':
+ s->Printf("\\e");
+ break;
+ case '\a':
+ s->Printf("\\a");
+ break;
+ case '\b':
+ s->Printf("\\b");
+ break;
+ case '\f':
+ s->Printf("\\f");
+ break;
+ case '\n':
+ s->Printf("\\n");
+ break;
+ case '\r':
+ s->Printf("\\r");
+ break;
+ case '\t':
+ s->Printf("\\t");
+ break;
+ case '\v':
+ s->Printf("\\v");
+ break;
+ case '\0':
+ s->Printf("\\0");
+ break;
+ default:
+ if (item_byte_size == 1)
+ s->Printf("\\x%2.2x", (uint8_t)ch);
+ else
+ s->Printf("%" PRIu64, ch);
+ break;
}
-
- switch (item_format)
- {
- case eFormatBoolean:
- if (item_byte_size <= 8)
- s->Printf ("%s", GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset) ? "true" : "false");
- else
- {
- s->Printf("error: unsupported byte size (%" PRIu64 ") for boolean format", (uint64_t)item_byte_size);
- return offset;
- }
+ } else {
+ s->PutChar(NON_PRINTABLE_CHAR);
+ }
+
+ // If we are only printing one character surround it with single quotes
+ if (item_count == 1 && item_format == eFormatChar)
+ s->PutChar('\'');
+ } break;
+
+ case eFormatEnum: // Print enum value as a signed integer when we don't get
+ // the enum type
+ case eFormatDecimal:
+ if (item_byte_size <= 8)
+ s->Printf("%" PRId64,
+ GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
+ item_bit_offset));
+ else {
+ const bool is_signed = true;
+ const unsigned radix = 10;
+ offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
+ }
+ break;
+
+ case eFormatUnsigned:
+ if (item_byte_size <= 8)
+ s->Printf("%" PRIu64,
+ GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
+ item_bit_offset));
+ else {
+ const bool is_signed = false;
+ const unsigned radix = 10;
+ offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
+ }
+ break;
+
+ case eFormatOctal:
+ if (item_byte_size <= 8)
+ s->Printf("0%" PRIo64,
+ GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size,
+ item_bit_offset));
+ else {
+ const bool is_signed = false;
+ const unsigned radix = 8;
+ offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
+ }
+ break;
+
+ case eFormatOSType: {
+ uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size,
+ item_bit_size, item_bit_offset);
+ s->PutChar('\'');
+ for (uint32_t i = 0; i < item_byte_size; ++i) {
+ uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
+ if (isprint(ch))
+ s->Printf("%c", ch);
+ else {
+ switch (ch) {
+ case '\033':
+ s->Printf("\\e");
break;
-
- case eFormatBinary:
- if (item_byte_size <= 8)
- {
- uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset);
- // Avoid std::bitset<64>::to_string() since it is missing in
- // earlier C++ libraries
- std::string binary_value(64, '0');
- std::bitset<64> bits(uval64);
- for (uint32_t i = 0; i < 64; ++i)
- if (bits[i])
- binary_value[64 - 1 - i] = '1';
- if (item_bit_size > 0)
- s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
- else if (item_byte_size > 0 && item_byte_size <= 8)
- s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
- }
- else
- {
- const bool is_signed = false;
- const unsigned radix = 2;
- offset = DumpAPInt (s, *this, offset, item_byte_size, is_signed, radix);
- }
+ case '\a':
+ s->Printf("\\a");
break;
-
- case eFormatBytes:
- case eFormatBytesWithASCII:
- for (uint32_t i = 0; i < item_byte_size; ++i)
- {
- s->Printf ("%2.2x", GetU8(&offset));
- }
-
- // Put an extra space between the groups of bytes if more than one
- // is being dumped in a group (item_byte_size is more than 1).
- if (item_byte_size > 1)
- s->PutChar(' ');
+ case '\b':
+ s->Printf("\\b");
break;
-
- case eFormatChar:
- case eFormatCharPrintable:
- case eFormatCharArray:
- {
- // If we are only printing one character surround it with single
- // quotes
- if (item_count == 1 && item_format == eFormatChar)
- s->PutChar('\'');
-
- const uint64_t ch = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset);
- if (isprint(ch))
- s->Printf ("%c", (char)ch);
- else if (item_format != eFormatCharPrintable)
- {
- switch (ch)
- {
- case '\033': s->Printf ("\\e"); break;
- case '\a': s->Printf ("\\a"); break;
- case '\b': s->Printf ("\\b"); break;
- case '\f': s->Printf ("\\f"); break;
- case '\n': s->Printf ("\\n"); break;
- case '\r': s->Printf ("\\r"); break;
- case '\t': s->Printf ("\\t"); break;
- case '\v': s->Printf ("\\v"); break;
- case '\0': s->Printf ("\\0"); break;
- default:
- if (item_byte_size == 1)
- s->Printf ("\\x%2.2x", (uint8_t)ch);
- else
- s->Printf ("%" PRIu64, ch);
- break;
- }
- }
- else
- {
- s->PutChar(NON_PRINTABLE_CHAR);
- }
-
- // If we are only printing one character surround it with single quotes
- if (item_count == 1 && item_format == eFormatChar)
- s->PutChar('\'');
- }
+ case '\f':
+ s->Printf("\\f");
break;
-
- case eFormatEnum: // Print enum value as a signed integer when we don't get the enum type
- case eFormatDecimal:
- if (item_byte_size <= 8)
- s->Printf ("%" PRId64, GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
- else
- {
- const bool is_signed = true;
- const unsigned radix = 10;
- offset = DumpAPInt (s, *this, offset, item_byte_size, is_signed, radix);
- }
+ case '\n':
+ s->Printf("\\n");
break;
-
- case eFormatUnsigned:
- if (item_byte_size <= 8)
- s->Printf ("%" PRIu64, GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
- else
- {
- const bool is_signed = false;
- const unsigned radix = 10;
- offset = DumpAPInt (s, *this, offset, item_byte_size, is_signed, radix);
- }
+ case '\r':
+ s->Printf("\\r");
break;
-
- case eFormatOctal:
- if (item_byte_size <= 8)
- s->Printf ("0%" PRIo64, GetMaxS64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
- else
- {
- const bool is_signed = false;
- const unsigned radix = 8;
- offset = DumpAPInt (s, *this, offset, item_byte_size, is_signed, radix);
- }
+ case '\t':
+ s->Printf("\\t");
break;
-
- case eFormatOSType:
- {
- uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset);
- s->PutChar('\'');
- for (uint32_t i = 0; i < item_byte_size; ++i)
- {
- uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8));
- if (isprint(ch))
- s->Printf ("%c", ch);
- else
- {
- switch (ch)
- {
- case '\033': s->Printf ("\\e"); break;
- case '\a': s->Printf ("\\a"); break;
- case '\b': s->Printf ("\\b"); break;
- case '\f': s->Printf ("\\f"); break;
- case '\n': s->Printf ("\\n"); break;
- case '\r': s->Printf ("\\r"); break;
- case '\t': s->Printf ("\\t"); break;
- case '\v': s->Printf ("\\v"); break;
- case '\0': s->Printf ("\\0"); break;
- default: s->Printf ("\\x%2.2x", ch); break;
- }
- }
- }
- s->PutChar('\'');
- }
+ case '\v':
+ s->Printf("\\v");
break;
-
- case eFormatCString:
- {
- const char *cstr = GetCStr(&offset);
-
- if (!cstr)
- {
- s->Printf("NULL");
- offset = LLDB_INVALID_OFFSET;
- }
- else
- {
- s->PutChar('\"');
-
- while (const char c = *cstr)
- {
- if (isprint(c))
- {
- s->PutChar(c);
- }
- else
- {
- switch (c)
- {
- case '\033': s->Printf ("\\e"); break;
- case '\a': s->Printf ("\\a"); break;
- case '\b': s->Printf ("\\b"); break;
- case '\f': s->Printf ("\\f"); break;
- case '\n': s->Printf ("\\n"); break;
- case '\r': s->Printf ("\\r"); break;
- case '\t': s->Printf ("\\t"); break;
- case '\v': s->Printf ("\\v"); break;
- default: s->Printf ("\\x%2.2x", c); break;
- }
- }
-
- ++cstr;
- }
-
- s->PutChar('\"');
- }
- }
+ case '\0':
+ s->Printf("\\0");
break;
-
-
- case eFormatPointer:
- s->Address(GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset), sizeof (addr_t));
+ default:
+ s->Printf("\\x%2.2x", ch);
break;
-
-
- case eFormatComplexInteger:
- {
- size_t complex_int_byte_size = item_byte_size / 2;
-
- if (complex_int_byte_size > 0 && complex_int_byte_size <= 8)
- {
- s->Printf("%" PRIu64, GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
- s->Printf(" + %" PRIu64 "i", GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
- }
- else
- {
- s->Printf("error: unsupported byte size (%" PRIu64 ") for complex integer format", (uint64_t)item_byte_size);
- return offset;
- }
- }
- break;
-
- case eFormatComplex:
- if (sizeof(float) * 2 == item_byte_size)
- {
- float f32_1 = GetFloat (&offset);
- float f32_2 = GetFloat (&offset);
-
- s->Printf ("%g + %gi", f32_1, f32_2);
- break;
+ }
+ }
+ }
+ s->PutChar('\'');
+ } break;
+
+ case eFormatCString: {
+ const char *cstr = GetCStr(&offset);
+
+ if (!cstr) {
+ s->Printf("NULL");
+ offset = LLDB_INVALID_OFFSET;
+ } else {
+ s->PutChar('\"');
+
+ while (const char c = *cstr) {
+ if (isprint(c)) {
+ s->PutChar(c);
+ } else {
+ switch (c) {
+ case '\033':
+ s->Printf("\\e");
+ break;
+ case '\a':
+ s->Printf("\\a");
+ break;
+ case '\b':
+ s->Printf("\\b");
+ break;
+ case '\f':
+ s->Printf("\\f");
+ break;
+ case '\n':
+ s->Printf("\\n");
+ break;
+ case '\r':
+ s->Printf("\\r");
+ break;
+ case '\t':
+ s->Printf("\\t");
+ break;
+ case '\v':
+ s->Printf("\\v");
+ break;
+ default:
+ s->Printf("\\x%2.2x", c);
+ break;
}
- else if (sizeof(double) * 2 == item_byte_size)
- {
- double d64_1 = GetDouble (&offset);
- double d64_2 = GetDouble (&offset);
+ }
- s->Printf ("%lg + %lgi", d64_1, d64_2);
- break;
- }
- else if (sizeof(long double) * 2 == item_byte_size)
- {
- long double ld64_1 = GetLongDouble (&offset);
- long double ld64_2 = GetLongDouble (&offset);
- s->Printf ("%Lg + %Lgi", ld64_1, ld64_2);
- break;
- }
- else
- {
- s->Printf("error: unsupported byte size (%" PRIu64 ") for complex float format", (uint64_t)item_byte_size);
- return offset;
- }
- break;
+ ++cstr;
+ }
- default:
- case eFormatDefault:
- case eFormatHex:
- case eFormatHexUppercase:
- {
- bool wantsuppercase = (item_format == eFormatHexUppercase);
- switch (item_byte_size)
- {
- case 1:
- case 2:
- case 4:
- case 8:
- s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64, (int)(2 * item_byte_size), (int)(2 * item_byte_size), GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset));
- break;
- default:
- {
- assert (item_bit_size == 0 && item_bit_offset == 0);
- const uint8_t *bytes = (const uint8_t* )GetData(&offset, item_byte_size);
- if (bytes)
- {
- s->PutCString("0x");
- uint32_t idx;
- if (m_byte_order == eByteOrderBig)
- {
- for (idx = 0; idx < item_byte_size; ++idx)
- s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]);
- }
- else
- {
- for (idx = 0; idx < item_byte_size; ++idx)
- s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[item_byte_size - 1 - idx]);
- }
- }
- }
- break;
- }
- }
- break;
+ s->PutChar('\"');
+ }
+ } break;
+
+ case eFormatPointer:
+ s->Address(GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
+ item_bit_offset),
+ sizeof(addr_t));
+ break;
+
+ case eFormatComplexInteger: {
+ size_t complex_int_byte_size = item_byte_size / 2;
+
+ if (complex_int_byte_size > 0 && complex_int_byte_size <= 8) {
+ s->Printf("%" PRIu64,
+ GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
+ s->Printf(" + %" PRIu64 "i",
+ GetMaxU64Bitfield(&offset, complex_int_byte_size, 0, 0));
+ } else {
+ s->Printf("error: unsupported byte size (%" PRIu64
+ ") for complex integer format",
+ (uint64_t)item_byte_size);
+ return offset;
+ }
+ } break;
- case eFormatFloat:
- {
- TargetSP target_sp;
- bool used_apfloat = false;
- if (exe_scope)
- target_sp = exe_scope->CalculateTarget();
- if (target_sp)
- {
- ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
- if (clang_ast)
- {
- clang::ASTContext *ast = clang_ast->getASTContext();
- if (ast)
- {
- llvm::SmallVector<char, 256> sv;
- // Show full precision when printing float values
- const unsigned format_precision = 0;
- const unsigned format_max_padding = 100;
- size_t item_bit_size = item_byte_size * 8;
-
- if (item_bit_size == ast->getTypeSize(ast->FloatTy))
- {
- llvm::APInt apint(item_bit_size, this->GetMaxU64(&offset, item_byte_size));
- llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->FloatTy), apint);
- apfloat.toString(sv, format_precision, format_max_padding);
- }
- else if (item_bit_size == ast->getTypeSize(ast->DoubleTy))
- {
- llvm::APInt apint;
- if (GetAPInt (*this, &offset, item_byte_size, apint))
- {
- llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->DoubleTy), apint);
- apfloat.toString(sv, format_precision, format_max_padding);
- }
- }
- else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy))
- {
- const auto &semantics = ast->getFloatTypeSemantics(ast->LongDoubleTy);
- const auto byte_size = (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
-
- llvm::APInt apint;
- if (GetAPInt(*this, &offset, byte_size, apint))
- {
- llvm::APFloat apfloat(semantics, apint);
- apfloat.toString(sv, format_precision, format_max_padding);
- }
- }
- else if (item_bit_size == ast->getTypeSize(ast->HalfTy))
- {
- llvm::APInt apint(item_bit_size, this->GetU16(&offset));
- llvm::APFloat apfloat (ast->getFloatTypeSemantics(ast->HalfTy), apint);
- apfloat.toString(sv, format_precision, format_max_padding);
- }
-
- if (!sv.empty())
- {
- s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
- used_apfloat = true;
- }
- }
- }
- }
-
- if (!used_apfloat)
- {
- std::ostringstream ss;
- if (item_byte_size == sizeof(float) || item_byte_size == 2)
- {
- float f;
- if (item_byte_size == 2)
- {
- uint16_t half = this->GetU16(&offset);
- f = half2float(half);
- }
- else
- {
- f = GetFloat (&offset);
- }
- ss.precision(std::numeric_limits<float>::digits10);
- ss << f;
- }
- else if (item_byte_size == sizeof(double))
- {
- ss.precision(std::numeric_limits<double>::digits10);
- ss << GetDouble(&offset);
- }
- else if (item_byte_size == sizeof(long double) || item_byte_size == 10)
- {
- ss.precision(std::numeric_limits<long double>::digits10);
- ss << GetLongDouble(&offset);
- }
- else
- {
- s->Printf("error: unsupported byte size (%" PRIu64 ") for float format", (uint64_t)item_byte_size);
- return offset;
- }
- ss.flush();
- s->Printf("%s", ss.str().c_str());
- }
- }
- break;
+ case eFormatComplex:
+ if (sizeof(float) * 2 == item_byte_size) {
+ float f32_1 = GetFloat(&offset);
+ float f32_2 = GetFloat(&offset);
- case eFormatUnicode16:
- s->Printf("U+%4.4x", GetU16 (&offset));
- break;
+ s->Printf("%g + %gi", f32_1, f32_2);
+ break;
+ } else if (sizeof(double) * 2 == item_byte_size) {
+ double d64_1 = GetDouble(&offset);
+ double d64_2 = GetDouble(&offset);
- case eFormatUnicode32:
- s->Printf("U+0x%8.8x", GetU32 (&offset));
- break;
+ s->Printf("%lg + %lgi", d64_1, d64_2);
+ break;
+ } else if (sizeof(long double) * 2 == item_byte_size) {
+ long double ld64_1 = GetLongDouble(&offset);
+ long double ld64_2 = GetLongDouble(&offset);
+ s->Printf("%Lg + %Lgi", ld64_1, ld64_2);
+ break;
+ } else {
+ s->Printf("error: unsupported byte size (%" PRIu64
+ ") for complex float format",
+ (uint64_t)item_byte_size);
+ return offset;
+ }
+ break;
- case eFormatAddressInfo:
- {
- addr_t addr = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset);
- s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size), (int)(2 * item_byte_size), addr);
- if (exe_scope)
- {
- TargetSP target_sp (exe_scope->CalculateTarget());
- lldb_private::Address so_addr;
- if (target_sp)
- {
- if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
- {
- s->PutChar(' ');
- so_addr.Dump (s,
- exe_scope,
- Address::DumpStyleResolvedDescription,
- Address::DumpStyleModuleWithFileAddress);
- }
- else
- {
- so_addr.SetOffset(addr);
- so_addr.Dump (s, exe_scope, Address::DumpStyleResolvedPointerDescription);
- }
- }
- }
+ default:
+ case eFormatDefault:
+ case eFormatHex:
+ case eFormatHexUppercase: {
+ bool wantsuppercase = (item_format == eFormatHexUppercase);
+ switch (item_byte_size) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ s->Printf(wantsuppercase ? "0x%*.*" PRIX64 : "0x%*.*" PRIx64,
+ (int)(2 * item_byte_size), (int)(2 * item_byte_size),
+ GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
+ item_bit_offset));
+ break;
+ default: {
+ assert(item_bit_size == 0 && item_bit_offset == 0);
+ const uint8_t *bytes =
+ (const uint8_t *)GetData(&offset, item_byte_size);
+ if (bytes) {
+ s->PutCString("0x");
+ uint32_t idx;
+ if (m_byte_order == eByteOrderBig) {
+ for (idx = 0; idx < item_byte_size; ++idx)
+ s->Printf(wantsuppercase ? "%2.2X" : "%2.2x", bytes[idx]);
+ } else {
+ for (idx = 0; idx < item_byte_size; ++idx)
+ s->Printf(wantsuppercase ? "%2.2X" : "%2.2x",
+ bytes[item_byte_size - 1 - idx]);
+ }
+ }
+ } break;
+ }
+ } break;
+
+ case eFormatFloat: {
+ TargetSP target_sp;
+ bool used_apfloat = false;
+ if (exe_scope)
+ target_sp = exe_scope->CalculateTarget();
+ if (target_sp) {
+ ClangASTContext *clang_ast = target_sp->GetScratchClangASTContext();
+ if (clang_ast) {
+ clang::ASTContext *ast = clang_ast->getASTContext();
+ if (ast) {
+ llvm::SmallVector<char, 256> sv;
+ // Show full precision when printing float values
+ const unsigned format_precision = 0;
+ const unsigned format_max_padding = 100;
+ size_t item_bit_size = item_byte_size * 8;
+
+ if (item_bit_size == ast->getTypeSize(ast->FloatTy)) {
+ llvm::APInt apint(item_bit_size,
+ this->GetMaxU64(&offset, item_byte_size));
+ llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->FloatTy),
+ apint);
+ apfloat.toString(sv, format_precision, format_max_padding);
+ } else if (item_bit_size == ast->getTypeSize(ast->DoubleTy)) {
+ llvm::APInt apint;
+ if (GetAPInt(*this, &offset, item_byte_size, apint)) {
+ llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->DoubleTy),
+ apint);
+ apfloat.toString(sv, format_precision, format_max_padding);
+ }
+ } else if (item_bit_size == ast->getTypeSize(ast->LongDoubleTy)) {
+ const auto &semantics =
+ ast->getFloatTypeSemantics(ast->LongDoubleTy);
+ const auto byte_size =
+ (llvm::APFloat::getSizeInBits(semantics) + 7) / 8;
+
+ llvm::APInt apint;
+ if (GetAPInt(*this, &offset, byte_size, apint)) {
+ llvm::APFloat apfloat(semantics, apint);
+ apfloat.toString(sv, format_precision, format_max_padding);
+ }
+ } else if (item_bit_size == ast->getTypeSize(ast->HalfTy)) {
+ llvm::APInt apint(item_bit_size, this->GetU16(&offset));
+ llvm::APFloat apfloat(ast->getFloatTypeSemantics(ast->HalfTy),
+ apint);
+ apfloat.toString(sv, format_precision, format_max_padding);
}
- break;
- case eFormatHexFloat:
- if (sizeof(float) == item_byte_size)
- {
- char float_cstr[256];
- llvm::APFloat ap_float (GetFloat (&offset));
- ap_float.convertToHexString (float_cstr, 0, false, llvm::APFloat::rmNearestTiesToEven);
- s->Printf ("%s", float_cstr);
- break;
- }
- else if (sizeof(double) == item_byte_size)
- {
- char float_cstr[256];
- llvm::APFloat ap_float (GetDouble (&offset));
- ap_float.convertToHexString (float_cstr, 0, false, llvm::APFloat::rmNearestTiesToEven);
- s->Printf ("%s", float_cstr);
- break;
+ if (!sv.empty()) {
+ s->Printf("%*.*s", (int)sv.size(), (int)sv.size(), sv.data());
+ used_apfloat = true;
}
- else
- {
- s->Printf("error: unsupported byte size (%" PRIu64 ") for hex float format", (uint64_t)item_byte_size);
- return offset;
- }
- break;
-
-// please keep the single-item formats below in sync with FormatManager::GetSingleItemFormat
-// if you fail to do so, users will start getting different outputs depending on internal
-// implementation details they should not care about ||
- case eFormatVectorOfChar: // ||
- s->PutChar('{'); // \/
- offset = Dump (s, offset, eFormatCharArray, 1, item_byte_size, item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfSInt8:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatDecimal, 1, item_byte_size, item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfUInt8:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatHex, 1, item_byte_size, item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfSInt16:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatDecimal, sizeof(uint16_t), item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfUInt16:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatHex, sizeof(uint16_t), item_byte_size / sizeof(uint16_t), item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfSInt32:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatDecimal, sizeof(uint32_t), item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfUInt32:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatHex, sizeof(uint32_t), item_byte_size / sizeof(uint32_t), item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfSInt64:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatDecimal, sizeof(uint64_t), item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfUInt64:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatHex, sizeof(uint64_t), item_byte_size / sizeof(uint64_t), item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0);
- 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);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfFloat64:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatFloat, 8, item_byte_size / 8, item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
-
- case eFormatVectorOfUInt128:
- s->PutChar('{');
- offset = Dump (s, offset, eFormatHex, 16, item_byte_size / 16, item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
- s->PutChar('}');
- break;
+ }
+ }
+ }
+
+ if (!used_apfloat) {
+ std::ostringstream ss;
+ if (item_byte_size == sizeof(float) || item_byte_size == 2) {
+ float f;
+ if (item_byte_size == 2) {
+ uint16_t half = this->GetU16(&offset);
+ f = half2float(half);
+ } else {
+ f = GetFloat(&offset);
+ }
+ ss.precision(std::numeric_limits<float>::digits10);
+ ss << f;
+ } else if (item_byte_size == sizeof(double)) {
+ ss.precision(std::numeric_limits<double>::digits10);
+ ss << GetDouble(&offset);
+ } else if (item_byte_size == sizeof(long double) ||
+ item_byte_size == 10) {
+ ss.precision(std::numeric_limits<long double>::digits10);
+ ss << GetLongDouble(&offset);
+ } else {
+ s->Printf("error: unsupported byte size (%" PRIu64
+ ") for float format",
+ (uint64_t)item_byte_size);
+ return offset;
+ }
+ ss.flush();
+ s->Printf("%s", ss.str().c_str());
+ }
+ } break;
+
+ case eFormatUnicode16:
+ s->Printf("U+%4.4x", GetU16(&offset));
+ break;
+
+ case eFormatUnicode32:
+ s->Printf("U+0x%8.8x", GetU32(&offset));
+ break;
+
+ case eFormatAddressInfo: {
+ addr_t addr = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size,
+ item_bit_offset);
+ s->Printf("0x%*.*" PRIx64, (int)(2 * item_byte_size),
+ (int)(2 * item_byte_size), addr);
+ if (exe_scope) {
+ TargetSP target_sp(exe_scope->CalculateTarget());
+ lldb_private::Address so_addr;
+ if (target_sp) {
+ if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr,
+ so_addr)) {
+ s->PutChar(' ');
+ so_addr.Dump(s, exe_scope, Address::DumpStyleResolvedDescription,
+ Address::DumpStyleModuleWithFileAddress);
+ } else {
+ so_addr.SetOffset(addr);
+ so_addr.Dump(s, exe_scope,
+ Address::DumpStyleResolvedPointerDescription);
+ }
}
+ }
+ } break;
+
+ case eFormatHexFloat:
+ if (sizeof(float) == item_byte_size) {
+ char float_cstr[256];
+ llvm::APFloat ap_float(GetFloat(&offset));
+ ap_float.convertToHexString(float_cstr, 0, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ s->Printf("%s", float_cstr);
+ break;
+ } else if (sizeof(double) == item_byte_size) {
+ char float_cstr[256];
+ llvm::APFloat ap_float(GetDouble(&offset));
+ ap_float.convertToHexString(float_cstr, 0, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ s->Printf("%s", float_cstr);
+ break;
+ } else {
+ s->Printf("error: unsupported byte size (%" PRIu64
+ ") for hex float format",
+ (uint64_t)item_byte_size);
+ return offset;
+ }
+ break;
+
+ // please keep the single-item formats below in sync with
+ // FormatManager::GetSingleItemFormat
+ // if you fail to do so, users will start getting different outputs
+ // depending on internal
+ // implementation details they should not care about ||
+ case eFormatVectorOfChar: // ||
+ s->PutChar('{'); // \/
+ offset = Dump(s, offset, eFormatCharArray, 1, item_byte_size,
+ item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfSInt8:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatDecimal, 1, item_byte_size,
+ item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt8:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatHex, 1, item_byte_size, item_byte_size,
+ LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfSInt16:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatDecimal, sizeof(uint16_t),
+ item_byte_size / sizeof(uint16_t),
+ item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt16:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatHex, sizeof(uint16_t),
+ item_byte_size / sizeof(uint16_t),
+ item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfSInt32:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatDecimal, sizeof(uint32_t),
+ item_byte_size / sizeof(uint32_t),
+ item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt32:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatHex, sizeof(uint32_t),
+ item_byte_size / sizeof(uint32_t),
+ item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfSInt64:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatDecimal, sizeof(uint64_t),
+ item_byte_size / sizeof(uint64_t),
+ item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt64:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatHex, sizeof(uint64_t),
+ item_byte_size / sizeof(uint64_t),
+ item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0);
+ 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);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfFloat64:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatFloat, 8, item_byte_size / 8,
+ item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt128:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatHex, 16, item_byte_size / 16,
+ item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
}
+ }
- if (item_format == eFormatBytesWithASCII && offset > line_start_offset)
- {
- s->Printf("%*s", static_cast<int>((num_per_line - (offset - line_start_offset)) * 3 + 2), "");
- Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0);
- }
- return offset; // Return the offset at which we ended up
+ if (item_format == eFormatBytesWithASCII && offset > line_start_offset) {
+ s->Printf("%*s", static_cast<int>(
+ (num_per_line - (offset - line_start_offset)) * 3 + 2),
+ "");
+ Dump(s, line_start_offset, eFormatCharPrintable, 1,
+ offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+ }
+ return offset; // Return the offset at which we ended up
}
//----------------------------------------------------------------------
@@ -2073,59 +1964,65 @@ DataExtractor::Dump (Stream *s,
// string will be used for the supplied "type". If the stream "s"
// is nullptr, then the output will be send to Log().
//----------------------------------------------------------------------
-lldb::offset_t
-DataExtractor::PutToLog(Log *log,
- offset_t start_offset,
- offset_t length,
- uint64_t base_addr,
- uint32_t num_per_line,
- DataExtractor::Type type,
- const char *format) const
-{
- if (log == nullptr)
- return start_offset;
-
- offset_t offset;
- offset_t end_offset;
- uint32_t count;
- StreamString sstr;
- for (offset = start_offset, end_offset = offset + length, count = 0; ValidOffset(offset) && offset < end_offset; ++count)
- {
- if ((count % num_per_line) == 0)
- {
- // Print out any previous string
- if (sstr.GetSize() > 0)
- {
- log->Printf("%s", sstr.GetData());
- sstr.Clear();
- }
- // Reset string offset and fill the current line string with address:
- if (base_addr != LLDB_INVALID_ADDRESS)
- sstr.Printf("0x%8.8" PRIx64 ":", (uint64_t)(base_addr + (offset - start_offset)));
- }
+lldb::offset_t DataExtractor::PutToLog(Log *log, offset_t start_offset,
+ offset_t length, uint64_t base_addr,
+ uint32_t num_per_line,
+ DataExtractor::Type type,
+ const char *format) const {
+ if (log == nullptr)
+ return start_offset;
+
+ offset_t offset;
+ offset_t end_offset;
+ uint32_t count;
+ StreamString sstr;
+ for (offset = start_offset, end_offset = offset + length, count = 0;
+ ValidOffset(offset) && offset < end_offset; ++count) {
+ if ((count % num_per_line) == 0) {
+ // Print out any previous string
+ if (sstr.GetSize() > 0) {
+ log->PutString(sstr.GetString());
+ sstr.Clear();
+ }
+ // Reset string offset and fill the current line string with address:
+ if (base_addr != LLDB_INVALID_ADDRESS)
+ sstr.Printf("0x%8.8" PRIx64 ":",
+ (uint64_t)(base_addr + (offset - start_offset)));
+ }
- switch (type)
- {
- case TypeUInt8: sstr.Printf (format ? format : " %2.2x", GetU8(&offset)); break;
- case TypeChar:
- {
- char ch = GetU8(&offset);
- sstr.Printf (format ? format : " %c", isprint(ch) ? ch : ' ');
- }
- break;
- case TypeUInt16: sstr.Printf (format ? format : " %4.4x", GetU16(&offset)); break;
- case TypeUInt32: sstr.Printf (format ? format : " %8.8x", GetU32(&offset)); break;
- case TypeUInt64: sstr.Printf (format ? format : " %16.16" PRIx64, GetU64(&offset)); break;
- case TypePointer: sstr.Printf (format ? format : " 0x%" PRIx64, GetAddress(&offset)); break;
- case TypeULEB128: sstr.Printf (format ? format : " 0x%" PRIx64, GetULEB128(&offset)); break;
- case TypeSLEB128: sstr.Printf (format ? format : " %" PRId64, GetSLEB128(&offset)); break;
- }
+ switch (type) {
+ case TypeUInt8:
+ sstr.Printf(format ? format : " %2.2x", GetU8(&offset));
+ break;
+ case TypeChar: {
+ char ch = GetU8(&offset);
+ sstr.Printf(format ? format : " %c", isprint(ch) ? ch : ' ');
+ } break;
+ case TypeUInt16:
+ sstr.Printf(format ? format : " %4.4x", GetU16(&offset));
+ break;
+ case TypeUInt32:
+ sstr.Printf(format ? format : " %8.8x", GetU32(&offset));
+ break;
+ case TypeUInt64:
+ sstr.Printf(format ? format : " %16.16" PRIx64, GetU64(&offset));
+ break;
+ case TypePointer:
+ sstr.Printf(format ? format : " 0x%" PRIx64, GetAddress(&offset));
+ break;
+ case TypeULEB128:
+ sstr.Printf(format ? format : " 0x%" PRIx64, GetULEB128(&offset));
+ break;
+ case TypeSLEB128:
+ sstr.Printf(format ? format : " %" PRId64, GetSLEB128(&offset));
+ break;
}
+ }
- if (sstr.GetSize() > 0)
- log->Printf("%s", sstr.GetData());
+ if (!sstr.Empty())
+ log->PutString(sstr.GetString());
- return offset; // Return the offset at which we ended up
+ return offset; // Return the offset at which we ended up
}
//----------------------------------------------------------------------
@@ -2133,137 +2030,114 @@ DataExtractor::PutToLog(Log *log,
//
// Dump out a UUID starting at 'offset' bytes into the buffer
//----------------------------------------------------------------------
-void
-DataExtractor::DumpUUID (Stream *s, offset_t offset) const
-{
- if (s)
- {
- const uint8_t *uuid_data = PeekData(offset, 16);
- if ( uuid_data )
- {
- lldb_private::UUID uuid(uuid_data, 16);
- uuid.Dump(s);
- }
- else
- {
- s->Printf("<not enough data for UUID at offset 0x%8.8" PRIx64 ">", offset);
- }
+void DataExtractor::DumpUUID(Stream *s, offset_t offset) const {
+ if (s) {
+ const uint8_t *uuid_data = PeekData(offset, 16);
+ if (uuid_data) {
+ lldb_private::UUID uuid(uuid_data, 16);
+ uuid.Dump(s);
+ } else {
+ s->Printf("<not enough data for UUID at offset 0x%8.8" PRIx64 ">",
+ offset);
}
-}
-
-void
-DataExtractor::DumpHexBytes (Stream *s,
- const void *src,
- size_t src_len,
- uint32_t bytes_per_line,
- addr_t base_addr)
-{
- DataExtractor data (src, src_len, eByteOrderLittle, 4);
- data.Dump (s,
- 0, // Offset into "src"
- eFormatBytes, // Dump as hex bytes
- 1, // Size of each item is 1 for single bytes
- src_len, // Number of bytes
- bytes_per_line, // Num bytes per line
- base_addr, // Base address
- 0, 0); // Bitfield info
-}
-
-size_t
-DataExtractor::Copy (DataExtractor &dest_data) const
-{
- if (m_data_sp)
- {
- // we can pass along the SP to the data
- dest_data.SetData(m_data_sp);
- }
- else
- {
- const uint8_t *base_ptr = m_start;
- size_t data_size = GetByteSize();
- dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size)));
- }
- return GetByteSize();
-}
+ }
+}
+
+void DataExtractor::DumpHexBytes(Stream *s, const void *src, size_t src_len,
+ uint32_t bytes_per_line, addr_t base_addr) {
+ DataExtractor data(src, src_len, eByteOrderLittle, 4);
+ data.Dump(s,
+ 0, // Offset into "src"
+ eFormatBytes, // Dump as hex bytes
+ 1, // Size of each item is 1 for single bytes
+ src_len, // Number of bytes
+ bytes_per_line, // Num bytes per line
+ base_addr, // Base address
+ 0, 0); // Bitfield info
+}
+
+size_t DataExtractor::Copy(DataExtractor &dest_data) const {
+ if (m_data_sp) {
+ // we can pass along the SP to the data
+ dest_data.SetData(m_data_sp);
+ } else {
+ const uint8_t *base_ptr = m_start;
+ size_t data_size = GetByteSize();
+ dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size)));
+ }
+ return GetByteSize();
+}
+
+bool DataExtractor::Append(DataExtractor &rhs) {
+ if (rhs.GetByteOrder() != GetByteOrder())
+ return false;
-bool
-DataExtractor::Append(DataExtractor& rhs)
-{
- if (rhs.GetByteOrder() != GetByteOrder())
- return false;
-
- if (rhs.GetByteSize() == 0)
- return true;
-
- if (GetByteSize() == 0)
- return (rhs.Copy(*this) > 0);
-
- size_t bytes = GetByteSize() + rhs.GetByteSize();
-
- DataBufferHeap *buffer_heap_ptr = nullptr;
- DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
-
- if (!buffer_sp || buffer_heap_ptr == nullptr)
- return false;
-
- uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes();
-
- memcpy(bytes_ptr, GetDataStart(), GetByteSize());
- memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize());
-
- SetData(buffer_sp);
-
+ if (rhs.GetByteSize() == 0)
return true;
+
+ if (GetByteSize() == 0)
+ return (rhs.Copy(*this) > 0);
+
+ size_t bytes = GetByteSize() + rhs.GetByteSize();
+
+ DataBufferHeap *buffer_heap_ptr = nullptr;
+ DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
+
+ if (!buffer_sp || buffer_heap_ptr == nullptr)
+ return false;
+
+ uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes();
+
+ memcpy(bytes_ptr, GetDataStart(), GetByteSize());
+ memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize());
+
+ SetData(buffer_sp);
+
+ return true;
}
-bool
-DataExtractor::Append(void* buf, offset_t length)
-{
- if (buf == nullptr)
- return false;
-
- if (length == 0)
- return true;
-
- size_t bytes = GetByteSize() + length;
-
- DataBufferHeap *buffer_heap_ptr = nullptr;
- DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
-
- if (!buffer_sp || buffer_heap_ptr == nullptr)
- return false;
-
- uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes();
-
- if (GetByteSize() > 0)
- memcpy(bytes_ptr, GetDataStart(), GetByteSize());
-
- memcpy(bytes_ptr + GetByteSize(), buf, length);
-
- SetData(buffer_sp);
-
+bool DataExtractor::Append(void *buf, offset_t length) {
+ if (buf == nullptr)
+ return false;
+
+ if (length == 0)
return true;
+
+ size_t bytes = GetByteSize() + length;
+
+ DataBufferHeap *buffer_heap_ptr = nullptr;
+ DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
+
+ if (!buffer_sp || buffer_heap_ptr == nullptr)
+ return false;
+
+ uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes();
+
+ if (GetByteSize() > 0)
+ memcpy(bytes_ptr, GetDataStart(), GetByteSize());
+
+ memcpy(bytes_ptr + GetByteSize(), buf, length);
+
+ SetData(buffer_sp);
+
+ return true;
}
-void
-DataExtractor::Checksum (llvm::SmallVectorImpl<uint8_t> &dest,
- uint64_t max_data)
-{
- if (max_data == 0)
- max_data = GetByteSize();
- else
- max_data = std::min(max_data, GetByteSize());
+void DataExtractor::Checksum(llvm::SmallVectorImpl<uint8_t> &dest,
+ uint64_t max_data) {
+ if (max_data == 0)
+ max_data = GetByteSize();
+ else
+ max_data = std::min(max_data, GetByteSize());
- llvm::MD5 md5;
+ llvm::MD5 md5;
- const llvm::ArrayRef<uint8_t> data(GetDataStart(),max_data);
- md5.update(data);
+ const llvm::ArrayRef<uint8_t> data(GetDataStart(), max_data);
+ md5.update(data);
- llvm::MD5::MD5Result result;
- md5.final(result);
+ llvm::MD5::MD5Result result;
+ md5.final(result);
- dest.resize(16);
- std::copy(result,
- result+16,
- dest.begin());
+ dest.resize(16);
+ std::copy(result, result + 16, dest.begin());
}
diff --git a/source/Core/Debugger.cpp b/source/Core/Debugger.cpp
index 34608d0193fc..8f888a518d5b 100644
--- a/source/Core/Debugger.cpp
+++ b/source/Core/Debugger.cpp
@@ -19,7 +19,6 @@
#include "llvm/Support/DynamicLibrary.h"
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginInterface.h"
@@ -50,15 +49,17 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/VariableList.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"
#include "lldb/Target/StopInfo.h"
+#include "lldb/Target/StructuredDataPlugin.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/TargetList.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/AnsiTerminal.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
@@ -69,1124 +70,1052 @@ static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024;
#pragma mark Static Functions
typedef std::vector<DebuggerSP> DebuggerList;
-static std::recursive_mutex *g_debugger_list_mutex_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
-static DebuggerList *g_debugger_list_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
-
-OptionEnumValueElement
-g_show_disassembly_enum_values[] =
-{
- { 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, nullptr, nullptr }
-};
-
-OptionEnumValueElement
-g_language_enumerators[] =
-{
- { eScriptLanguageNone, "none", "Disable scripting languages."},
- { eScriptLanguagePython, "python", "Select python as the default scripting language."},
- { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."},
- { 0, nullptr, nullptr }
-};
-
-#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
+static std::recursive_mutex *g_debugger_list_mutex_ptr =
+ nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
+static DebuggerList *g_debugger_list_ptr =
+ nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
+
+OptionEnumValueElement g_show_disassembly_enum_values[] = {
+ {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, nullptr, nullptr}};
+
+OptionEnumValueElement g_language_enumerators[] = {
+ {eScriptLanguageNone, "none", "Disable scripting languages."},
+ {eScriptLanguagePython, "python",
+ "Select python as the default scripting language."},
+ {eScriptLanguageDefault, "default",
+ "Select the lldb default as the default scripting language."},
+ {0, nullptr, nullptr}};
+
+#define MODULE_WITH_FUNC \
+ "{ " \
+ "${module.file.basename}{`${function.name-with-args}" \
+ "{${frame.no-debug}${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}}"\
- MODULE_WITH_FUNC\
- FILE_AND_LINE\
- "{, name = '${thread.name}'}"\
- "{, queue = '${thread.queue}'}"\
- "{, activity = '${thread.info.activity.name}'}" \
- "{, ${thread.info.trace_messages} messages}" \
- "{, stop reason = ${thread.stop-reason}}"\
- "{\\nReturn value: ${thread.return-value}}"\
- "{\\nCompleted expression: ${thread.completed-expression}}"\
- "\\n"
-
-#define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
- MODULE_WITH_FUNC\
- FILE_AND_LINE\
- IS_OPTIMIZED\
- "\\n"
+#define DEFAULT_THREAD_FORMAT \
+ "thread #${thread.index}: tid = ${thread.id%tid}" \
+ "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \
+ "{, name = '${thread.name}'}" \
+ "{, queue = '${thread.queue}'}" \
+ "{, activity = '${thread.info.activity.name}'}" \
+ "{, ${thread.info.trace_messages} messages}" \
+ "{, stop reason = ${thread.stop-reason}}" \
+ "{\\nReturn value: ${thread.return-value}}" \
+ "{\\nCompleted expression: ${thread.completed-expression}}" \
+ "\\n"
+
+#define DEFAULT_THREAD_STOP_FORMAT \
+ "thread #${thread.index}{, name = '${thread.name}'}" \
+ "{, queue = '${thread.queue}'}" \
+ "{, activity = '${thread.info.activity.name}'}" \
+ "{, ${thread.info.trace_messages} messages}" \
+ "{, stop reason = ${thread.stop-reason}}" \
+ "{\\nReturn value: ${thread.return-value}}" \
+ "{\\nCompleted expression: ${thread.completed-expression}}" \
+ "\\n"
+
+#define DEFAULT_FRAME_FORMAT \
+ "frame #${frame.index}:{ ${frame.no-debug}${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \
+ IS_OPTIMIZED "\\n"
// Three parts to this disassembly format specification:
// 1. If this is a new function/symbol (no previous symbol/function), print
// dylib`funcname:\n
-// 2. If this is a symbol context change (different from previous symbol/function), print
+// 2. If this is a symbol context change (different from previous
+// symbol/function), print
// dylib`funcname:\n
-// 3. print
-// address <+offset>:
-#define DEFAULT_DISASSEMBLY_FORMAT "{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: "
+// 3. print
+// address <+offset>:
+#define DEFAULT_DISASSEMBLY_FORMAT \
+ "{${function.initial-function}{${module.file.basename}`}{${function.name-" \
+ "without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${" \
+ "function.name-without-args}}:\n}{${current-pc-arrow} " \
+ "}${addr-file-or-load}{ " \
+ "<${function.concrete-only-addr-offset-no-padding}>}: "
// gdb's disassembly format can be emulated with
-// ${current-pc-arrow}${addr-file-or-load}{ <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
+// ${current-pc-arrow}${addr-file-or-load}{
+// <${function.name-without-args}${function.concrete-only-addr-offset-no-padding}>}:
// lldb's original format for disassembly would look like this format string -
-// {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}:
-
-static PropertyDefinition
-g_properties[] =
-{
-{ "auto-confirm", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "If true all confirmation prompts will receive their default reply." },
-{ "disassembly-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_DISASSEMBLY_FORMAT, nullptr, "The default disassembly format string to use when disassembling instruction sequences." },
-{ "frame-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_FRAME_FORMAT, nullptr, "The default frame format string to use when displaying stack frame information for threads." },
-{ "notify-void", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "Notify the user explicitly if an expression returns void (default: false)." },
-{ "prompt", OptionValue::eTypeString , true, OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", nullptr, "The debugger command line prompt displayed for the user." },
-{ "script-lang", OptionValue::eTypeEnum , true, eScriptLanguagePython, nullptr, g_language_enumerators, "The script language to be used for evaluating user-written scripts." },
-{ "stop-disassembly-count", OptionValue::eTypeSInt64 , true, 4 , nullptr, nullptr, "The number of disassembly lines to show when displaying a stopped context." },
-{ "stop-disassembly-display", OptionValue::eTypeEnum , true, Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr, g_show_disassembly_enum_values, "Control when to display disassembly when displaying a stopped context." },
-{ "stop-line-count-after", OptionValue::eTypeSInt64 , true, 3 , nullptr, nullptr, "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 , nullptr, nullptr, "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 , nullptr, nullptr, "The maximum number of columns to use for displaying text." },
-{ "thread-format", OptionValue::eTypeFormatEntity, true, 0 , DEFAULT_THREAD_FORMAT, nullptr, "The default thread format string to use when displaying thread information." },
-{ "use-external-editor", OptionValue::eTypeBoolean , true, false, nullptr, nullptr, "Whether to use an external editor or not." },
-{ "use-color", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "Whether to use Ansi color codes or not." },
-{ "auto-one-line-summaries", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, LLDB will automatically display small structs in one-liner format (default: true)." },
-{ "auto-indent", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "If true, LLDB will auto indent/outdent code. Currently only supported in the REPL (default: true)." },
-{ "print-decls", OptionValue::eTypeBoolean , true, true , nullptr, nullptr, "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 , nullptr, nullptr, "The tab size to use when indenting code in multi-line input mode (default: 4)." },
-{ "escape-non-printables", OptionValue::eTypeBoolean , true, true, nullptr, nullptr, "If true, LLDB will automatically escape non-printable and escape characters when formatting strings." },
-{ nullptr, OptionValue::eTypeInvalid , true, 0 , nullptr, nullptr, nullptr }
-};
-
-enum
-{
- ePropertyAutoConfirm = 0,
- ePropertyDisassemblyFormat,
- ePropertyFrameFormat,
- ePropertyNotiftVoid,
- ePropertyPrompt,
- ePropertyScriptLanguage,
- ePropertyStopDisassemblyCount,
- ePropertyStopDisassemblyDisplay,
- ePropertyStopLineCountAfter,
- ePropertyStopLineCountBefore,
- ePropertyTerminalWidth,
- ePropertyThreadFormat,
- ePropertyUseExternalEditor,
- ePropertyUseColor,
- ePropertyAutoOneLineSummaries,
- ePropertyAutoIndent,
- ePropertyPrintDecls,
- ePropertyTabSize,
- ePropertyEscapeNonPrintables
+// {${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name-without-args}}:\n}{${current-pc-arrow}
+// }{${addr-file-or-load}}:
+
+#define DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX "${ansi.underline}"
+#define DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX "${ansi.normal}"
+
+static OptionEnumValueElement s_stop_show_column_values[] = {
+ {eStopShowColumnAnsiOrCaret, "ansi-or-caret",
+ "Highlight the stop column with ANSI terminal codes when color/ANSI mode "
+ "is enabled; otherwise, fall back to using a text-only caret (^) as if "
+ "\"caret-only\" mode was selected."},
+ {eStopShowColumnAnsi, "ansi", "Highlight the stop column with ANSI "
+ "terminal codes when running LLDB with "
+ "color/ANSI enabled."},
+ {eStopShowColumnCaret, "caret",
+ "Highlight the stop column with a caret character (^) underneath the stop "
+ "column. This method introduces a new line in source listings that "
+ "display thread stop locations."},
+ {eStopShowColumnNone, "none", "Do not highlight the stop column."},
+ {0, nullptr, nullptr}};
+
+static PropertyDefinition g_properties[] = {
+ {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, nullptr,
+ "If true all confirmation prompts will receive their default reply."},
+ {"disassembly-format", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_DISASSEMBLY_FORMAT, nullptr, "The default disassembly format "
+ "string to use when disassembling "
+ "instruction sequences."},
+ {"frame-format", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_FRAME_FORMAT, nullptr, "The default frame format string to use "
+ "when displaying stack frame information "
+ "for threads."},
+ {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, nullptr,
+ "Notify the user explicitly if an expression returns void (default: "
+ "false)."},
+ {"prompt", OptionValue::eTypeString, true,
+ OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ",
+ nullptr, "The debugger command line prompt displayed for the user."},
+ {"script-lang", OptionValue::eTypeEnum, true, eScriptLanguagePython,
+ nullptr, g_language_enumerators,
+ "The script language to be used for evaluating user-written scripts."},
+ {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr,
+ nullptr, "The number of disassembly lines to show when displaying a "
+ "stopped context."},
+ {"stop-disassembly-display", OptionValue::eTypeEnum, true,
+ Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr,
+ g_show_disassembly_enum_values,
+ "Control when to display disassembly when displaying a stopped context."},
+ {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr,
+ nullptr, "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, nullptr,
+ nullptr, "The number of sources lines to display that come before the "
+ "current source line when displaying a stopped context."},
+ {"stop-show-column", OptionValue::eTypeEnum, false,
+ eStopShowColumnAnsiOrCaret, nullptr, s_stop_show_column_values,
+ "If true, LLDB will use the column information from the debug info to "
+ "mark the current position when displaying a stopped context."},
+ {"stop-show-column-ansi-prefix", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX, nullptr,
+ "When displaying the column marker in a color-enabled (i.e. ANSI) "
+ "terminal, use the ANSI terminal code specified in this format at the "
+ "immediately before the column to be marked."},
+ {"stop-show-column-ansi-suffix", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX, nullptr,
+ "When displaying the column marker in a color-enabled (i.e. ANSI) "
+ "terminal, use the ANSI terminal code specified in this format "
+ "immediately after the column to be marked."},
+ {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, nullptr,
+ "The maximum number of columns to use for displaying text."},
+ {"thread-format", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_THREAD_FORMAT, nullptr, "The default thread format string to use "
+ "when displaying thread information."},
+ {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0,
+ DEFAULT_THREAD_STOP_FORMAT, nullptr, "The default thread format "
+ "string to usewhen displaying thread "
+ "information as part of the stop display."},
+ {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr,
+ nullptr, "Whether to use an external editor or not."},
+ {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
+ "Whether to use Ansi color codes or not."},
+ {"auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, nullptr,
+ nullptr, "If true, LLDB will automatically display small structs in "
+ "one-liner format (default: true)."},
+ {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
+ "If true, LLDB will auto indent/outdent code. Currently only supported in "
+ "the REPL (default: true)."},
+ {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, nullptr,
+ "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, nullptr, nullptr,
+ "The tab size to use when indenting code in multi-line input mode "
+ "(default: 4)."},
+ {"escape-non-printables", OptionValue::eTypeBoolean, true, true, nullptr,
+ nullptr, "If true, LLDB will automatically escape non-printable and "
+ "escape characters when formatting strings."},
+ {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}};
+
+enum {
+ ePropertyAutoConfirm = 0,
+ ePropertyDisassemblyFormat,
+ ePropertyFrameFormat,
+ ePropertyNotiftVoid,
+ ePropertyPrompt,
+ ePropertyScriptLanguage,
+ ePropertyStopDisassemblyCount,
+ ePropertyStopDisassemblyDisplay,
+ ePropertyStopLineCountAfter,
+ ePropertyStopLineCountBefore,
+ ePropertyStopShowColumn,
+ ePropertyStopShowColumnAnsiPrefix,
+ ePropertyStopShowColumnAnsiSuffix,
+ ePropertyTerminalWidth,
+ ePropertyThreadFormat,
+ ePropertyThreadStopFormat,
+ ePropertyUseExternalEditor,
+ ePropertyUseColor,
+ ePropertyAutoOneLineSummaries,
+ ePropertyAutoIndent,
+ ePropertyPrintDecls,
+ ePropertyTabSize,
+ ePropertyEscapeNonPrintables
};
LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;
-Error
-Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
- VarSetOperationType op,
- const char *property_path,
- const char *value)
-{
- bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
- bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
- TargetSP target_sp;
- LoadScriptFromSymFile load_script_old_value;
- if (is_load_script && exe_ctx->GetTargetSP())
- {
- target_sp = exe_ctx->GetTargetSP();
- load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
- }
- Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
- if (error.Success())
- {
- // FIXME it would be nice to have "on-change" callbacks for properties
- if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
- {
- const char *new_prompt = GetPrompt();
- std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
- if (str.length())
- new_prompt = str.c_str();
- GetCommandInterpreter().UpdatePrompt(new_prompt);
- EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
- GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
- }
- else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
- {
- // use-color changed. Ping the prompt so it can reset the ansi terminal codes.
- SetPrompt (GetPrompt());
- }
- else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
- {
- if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
- {
- std::list<Error> errors;
- StreamString feedback_stream;
- if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
- {
- StreamFileSP stream_sp (GetErrorFile());
- if (stream_sp)
- {
- for (auto error : errors)
- {
- stream_sp->Printf("%s\n",error.AsCString());
- }
- if (feedback_stream.GetSize())
- stream_sp->Printf("%s",feedback_stream.GetData());
- }
- }
+Error Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ llvm::StringRef property_path, llvm::StringRef value) {
+ bool is_load_script = (property_path == "target.load-script-from-symbol-file");
+ bool is_escape_non_printables = (property_path == "escape-non-printables");
+ TargetSP target_sp;
+ LoadScriptFromSymFile load_script_old_value;
+ if (is_load_script && exe_ctx->GetTargetSP()) {
+ target_sp = exe_ctx->GetTargetSP();
+ load_script_old_value =
+ target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
+ }
+ Error error(Properties::SetPropertyValue(exe_ctx, op, property_path, value));
+ if (error.Success()) {
+ // FIXME it would be nice to have "on-change" callbacks for properties
+ if (property_path == g_properties[ePropertyPrompt].name) {
+ llvm::StringRef new_prompt = GetPrompt();
+ std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes(
+ new_prompt, GetUseColor());
+ if (str.length())
+ new_prompt = str;
+ GetCommandInterpreter().UpdatePrompt(new_prompt);
+ EventSP prompt_change_event_sp(
+ new Event(CommandInterpreter::eBroadcastBitResetPrompt,
+ new EventDataBytes(new_prompt)));
+ GetCommandInterpreter().BroadcastEvent(prompt_change_event_sp);
+ } else if (property_path == g_properties[ePropertyUseColor].name) {
+ // use-color changed. Ping the prompt so it can reset the ansi terminal
+ // codes.
+ SetPrompt(GetPrompt());
+ } else if (is_load_script && target_sp &&
+ load_script_old_value == eLoadScriptFromSymFileWarn) {
+ if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() ==
+ eLoadScriptFromSymFileTrue) {
+ std::list<Error> errors;
+ StreamString feedback_stream;
+ if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) {
+ StreamFileSP stream_sp(GetErrorFile());
+ if (stream_sp) {
+ for (auto error : errors) {
+ stream_sp->Printf("%s\n", error.AsCString());
}
+ if (feedback_stream.GetSize())
+ stream_sp->PutCString(feedback_stream.GetString());
+ }
}
- else if (is_escape_non_printables)
- {
- DataVisualization::ForceUpdate();
- }
+ }
+ } else if (is_escape_non_printables) {
+ DataVisualization::ForceUpdate();
}
- return error;
+ }
+ return error;
}
-bool
-Debugger::GetAutoConfirm () const
-{
- const uint32_t idx = ePropertyAutoConfirm;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::GetAutoConfirm() const {
+ const uint32_t idx = ePropertyAutoConfirm;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-const FormatEntity::Entry *
-Debugger::GetDisassemblyFormat() const
-{
- const uint32_t idx = ePropertyDisassemblyFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const {
+ const uint32_t idx = ePropertyDisassemblyFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-const FormatEntity::Entry *
-Debugger::GetFrameFormat() const
-{
- const uint32_t idx = ePropertyFrameFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetFrameFormat() const {
+ const uint32_t idx = ePropertyFrameFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::GetNotifyVoid () const
-{
- const uint32_t idx = ePropertyNotiftVoid;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::GetNotifyVoid() const {
+ const uint32_t idx = ePropertyNotiftVoid;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-const char *
-Debugger::GetPrompt() const
-{
- const uint32_t idx = ePropertyPrompt;
- return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, g_properties[idx].default_cstr_value);
+llvm::StringRef Debugger::GetPrompt() const {
+ const uint32_t idx = ePropertyPrompt;
+ return m_collection_sp->GetPropertyAtIndexAsString(
+ nullptr, idx, g_properties[idx].default_cstr_value);
}
-void
-Debugger::SetPrompt(const char *p)
-{
- const uint32_t idx = ePropertyPrompt;
- m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
- const char *new_prompt = GetPrompt();
- std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
- if (str.length())
- new_prompt = str.c_str();
- GetCommandInterpreter().UpdatePrompt(new_prompt);
+void Debugger::SetPrompt(llvm::StringRef p) {
+ const uint32_t idx = ePropertyPrompt;
+ m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p);
+ llvm::StringRef new_prompt = GetPrompt();
+ std::string str =
+ lldb_utility::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor());
+ if (str.length())
+ new_prompt = str;
+ GetCommandInterpreter().UpdatePrompt(new_prompt);
}
-const FormatEntity::Entry *
-Debugger::GetThreadFormat() const
-{
- const uint32_t idx = ePropertyThreadFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetThreadFormat() const {
+ const uint32_t idx = ePropertyThreadFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-lldb::ScriptLanguage
-Debugger::GetScriptLanguage() const
-{
- const uint32_t idx = ePropertyScriptLanguage;
- return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+const FormatEntity::Entry *Debugger::GetThreadStopFormat() const {
+ const uint32_t idx = ePropertyThreadStopFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::SetScriptLanguage (lldb::ScriptLanguage script_lang)
-{
- const uint32_t idx = ePropertyScriptLanguage;
- return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, script_lang);
+lldb::ScriptLanguage Debugger::GetScriptLanguage() const {
+ const uint32_t idx = ePropertyScriptLanguage;
+ return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-uint32_t
-Debugger::GetTerminalWidth () const
-{
- const uint32_t idx = ePropertyTerminalWidth;
- return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
+ const uint32_t idx = ePropertyScriptLanguage;
+ return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx,
+ script_lang);
}
-bool
-Debugger::SetTerminalWidth (uint32_t term_width)
-{
- const uint32_t idx = ePropertyTerminalWidth;
- return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
+uint32_t Debugger::GetTerminalWidth() const {
+ const uint32_t idx = ePropertyTerminalWidth;
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-bool
-Debugger::GetUseExternalEditor () const
-{
- const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::SetTerminalWidth(uint32_t term_width) {
+ const uint32_t idx = ePropertyTerminalWidth;
+ return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
}
-bool
-Debugger::SetUseExternalEditor (bool b)
-{
- const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+bool Debugger::GetUseExternalEditor() const {
+ const uint32_t idx = ePropertyUseExternalEditor;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-bool
-Debugger::GetUseColor () const
-{
- const uint32_t idx = ePropertyUseColor;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::SetUseExternalEditor(bool b) {
+ const uint32_t idx = ePropertyUseExternalEditor;
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
-bool
-Debugger::SetUseColor (bool b)
-{
- const uint32_t idx = ePropertyUseColor;
- bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
- SetPrompt (GetPrompt());
- return ret;
+bool Debugger::GetUseColor() const {
+ const uint32_t idx = ePropertyUseColor;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-uint32_t
-Debugger::GetStopSourceLineCount (bool before) const
-{
- const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
- return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+bool Debugger::SetUseColor(bool b) {
+ const uint32_t idx = ePropertyUseColor;
+ bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+ SetPrompt(GetPrompt());
+ return ret;
}
-Debugger::StopDisassemblyType
-Debugger::GetStopDisassemblyDisplay () const
-{
- const uint32_t idx = ePropertyStopDisassemblyDisplay;
- return (Debugger::StopDisassemblyType)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+StopShowColumn Debugger::GetStopShowColumn() const {
+ const uint32_t idx = ePropertyStopShowColumn;
+ return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-uint32_t
-Debugger::GetDisassemblyLineCount () const
-{
- const uint32_t idx = ePropertyStopDisassemblyCount;
- return m_collection_sp->GetPropertyAtIndexAsSInt64(nullptr, idx, g_properties[idx].default_uint_value);
+const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiPrefix() const {
+ const uint32_t idx = ePropertyStopShowColumnAnsiPrefix;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::GetAutoOneLineSummaries () const
-{
- const uint32_t idx = ePropertyAutoOneLineSummaries;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiSuffix() const {
+ const uint32_t idx = ePropertyStopShowColumnAnsiSuffix;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::GetEscapeNonPrintables () const
-{
- const uint32_t idx = ePropertyEscapeNonPrintables;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+uint32_t Debugger::GetStopSourceLineCount(bool before) const {
+ const uint32_t idx =
+ before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-bool
-Debugger::GetAutoIndent () const
-{
- const uint32_t idx = ePropertyAutoIndent;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const {
+ const uint32_t idx = ePropertyStopDisassemblyDisplay;
+ return (Debugger::StopDisassemblyType)
+ m_collection_sp->GetPropertyAtIndexAsEnumeration(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-bool
-Debugger::SetAutoIndent (bool b)
-{
- const uint32_t idx = ePropertyAutoIndent;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+uint32_t Debugger::GetDisassemblyLineCount() const {
+ const uint32_t idx = ePropertyStopDisassemblyCount;
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-bool
-Debugger::GetPrintDecls () const
-{
- const uint32_t idx = ePropertyPrintDecls;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+bool Debugger::GetAutoOneLineSummaries() const {
+ const uint32_t idx = ePropertyAutoOneLineSummaries;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
-bool
-Debugger::SetPrintDecls (bool b)
-{
- const uint32_t idx = ePropertyPrintDecls;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+bool Debugger::GetEscapeNonPrintables() const {
+ const uint32_t idx = ePropertyEscapeNonPrintables;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
-uint32_t
-Debugger::GetTabSize () const
-{
- const uint32_t idx = ePropertyTabSize;
- return m_collection_sp->GetPropertyAtIndexAsUInt64(nullptr, idx, g_properties[idx].default_uint_value);
+bool Debugger::GetAutoIndent() const {
+ const uint32_t idx = ePropertyAutoIndent;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
-bool
-Debugger::SetTabSize (uint32_t tab_size)
-{
- const uint32_t idx = ePropertyTabSize;
- return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size);
+bool Debugger::SetAutoIndent(bool b) {
+ const uint32_t idx = ePropertyAutoIndent;
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+}
+
+bool Debugger::GetPrintDecls() const {
+ const uint32_t idx = ePropertyPrintDecls;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+}
+
+bool Debugger::SetPrintDecls(bool b) {
+ const uint32_t idx = ePropertyPrintDecls;
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+}
+
+uint32_t Debugger::GetTabSize() const {
+ const uint32_t idx = ePropertyTabSize;
+ return m_collection_sp->GetPropertyAtIndexAsUInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
+}
+
+bool Debugger::SetTabSize(uint32_t tab_size) {
+ const uint32_t idx = ePropertyTabSize;
+ return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size);
}
#pragma mark Debugger
-//const DebuggerPropertiesSP &
-//Debugger::GetSettings() const
+// const DebuggerPropertiesSP &
+// Debugger::GetSettings() const
//{
// return m_properties_sp;
//}
//
-void
-Debugger::Initialize(LoadPluginCallbackType load_plugin_callback)
-{
- assert(g_debugger_list_ptr == nullptr && "Debugger::Initialize called more than once!");
- g_debugger_list_mutex_ptr = new std::recursive_mutex();
- g_debugger_list_ptr = new DebuggerList();
- g_load_plugin_callback = load_plugin_callback;
+void Debugger::Initialize(LoadPluginCallbackType load_plugin_callback) {
+ assert(g_debugger_list_ptr == nullptr &&
+ "Debugger::Initialize called more than once!");
+ g_debugger_list_mutex_ptr = new std::recursive_mutex();
+ g_debugger_list_ptr = new DebuggerList();
+ g_load_plugin_callback = load_plugin_callback;
}
-void
-Debugger::Terminate ()
-{
- assert(g_debugger_list_ptr && "Debugger::Terminate called without a matching Debugger::Initialize!");
+void Debugger::Terminate() {
+ assert(g_debugger_list_ptr &&
+ "Debugger::Terminate called without a matching Debugger::Initialize!");
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ // Clear our master list of debugger objects
{
- // Clear our master list of debugger objects
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- for (const auto& debugger: *g_debugger_list_ptr)
- debugger->Clear();
- g_debugger_list_ptr->clear();
- }
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ for (const auto &debugger : *g_debugger_list_ptr)
+ debugger->Clear();
+ g_debugger_list_ptr->clear();
}
+ }
}
-void
-Debugger::SettingsInitialize ()
-{
- Target::SettingsInitialize ();
-}
+void Debugger::SettingsInitialize() { Target::SettingsInitialize(); }
-void
-Debugger::SettingsTerminate ()
-{
- Target::SettingsTerminate ();
-}
+void Debugger::SettingsTerminate() { Target::SettingsTerminate(); }
-bool
-Debugger::LoadPlugin (const FileSpec& spec, Error& error)
-{
- if (g_load_plugin_callback)
- {
- llvm::sys::DynamicLibrary dynlib = g_load_plugin_callback (shared_from_this(), spec, error);
- if (dynlib.isValid())
- {
- m_loaded_plugins.push_back(dynlib);
- return true;
- }
+bool Debugger::LoadPlugin(const FileSpec &spec, Error &error) {
+ if (g_load_plugin_callback) {
+ llvm::sys::DynamicLibrary dynlib =
+ g_load_plugin_callback(shared_from_this(), spec, error);
+ if (dynlib.isValid()) {
+ m_loaded_plugins.push_back(dynlib);
+ return true;
}
- else
- {
- // The g_load_plugin_callback is registered in SBDebugger::Initialize()
- // and if the public API layer isn't available (code is linking against
- // all of the internal LLDB static libraries), then we can't load plugins
- error.SetErrorString("Public API layer is not available");
- }
- return false;
+ } else {
+ // The g_load_plugin_callback is registered in SBDebugger::Initialize()
+ // and if the public API layer isn't available (code is linking against
+ // all of the internal LLDB static libraries), then we can't load plugins
+ error.SetErrorString("Public API layer is not available");
+ }
+ return false;
}
static FileSpec::EnumerateDirectoryResult
-LoadPluginCallback(void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- Error error;
-
- static ConstString g_dylibext("dylib");
- static ConstString g_solibext("so");
-
- if (!baton)
- return FileSpec::eEnumerateDirectoryResultQuit;
-
- Debugger *debugger = (Debugger*)baton;
-
- // If we have a regular file, a symbolic link or unknown file type, try
- // and process the file. We must handle unknown as sometimes the directory
- // enumeration might be enumerating a file system that doesn't have correct
- // file type information.
- if (file_type == FileSpec::eFileTypeRegular ||
- file_type == FileSpec::eFileTypeSymbolicLink ||
- file_type == FileSpec::eFileTypeUnknown )
- {
- FileSpec plugin_file_spec (file_spec);
- plugin_file_spec.ResolvePath ();
-
- if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
- plugin_file_spec.GetFileNameExtension() != g_solibext)
- {
- return FileSpec::eEnumerateDirectoryResultNext;
- }
-
- Error plugin_load_error;
- debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
-
- return FileSpec::eEnumerateDirectoryResultNext;
- }
- else if (file_type == FileSpec::eFileTypeUnknown ||
- file_type == FileSpec::eFileTypeDirectory ||
- file_type == FileSpec::eFileTypeSymbolicLink )
- {
- // Try and recurse into anything that a directory or symbolic link.
- // We must also do this for unknown as sometimes the directory enumeration
- // might be enumerating a file system that doesn't have correct file type
- // information.
- return FileSpec::eEnumerateDirectoryResultEnter;
+LoadPluginCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &file_spec) {
+ Error error;
+
+ static ConstString g_dylibext("dylib");
+ static ConstString g_solibext("so");
+
+ if (!baton)
+ return FileSpec::eEnumerateDirectoryResultQuit;
+
+ Debugger *debugger = (Debugger *)baton;
+
+ // If we have a regular file, a symbolic link or unknown file type, try
+ // and process the file. We must handle unknown as sometimes the directory
+ // enumeration might be enumerating a file system that doesn't have correct
+ // file type information.
+ if (file_type == FileSpec::eFileTypeRegular ||
+ file_type == FileSpec::eFileTypeSymbolicLink ||
+ file_type == FileSpec::eFileTypeUnknown) {
+ FileSpec plugin_file_spec(file_spec);
+ plugin_file_spec.ResolvePath();
+
+ if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
+ plugin_file_spec.GetFileNameExtension() != g_solibext) {
+ return FileSpec::eEnumerateDirectoryResultNext;
}
-
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-void
-Debugger::InstanceInitialize ()
-{
- FileSpec dir_spec;
- const bool find_directories = true;
- const bool find_files = true;
- const bool find_other = true;
- char dir_path[PATH_MAX];
- if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
- {
- if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
- {
- FileSpec::EnumerateDirectory (dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- this);
- }
+ Error plugin_load_error;
+ debugger->LoadPlugin(plugin_file_spec, plugin_load_error);
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+ } else if (file_type == FileSpec::eFileTypeUnknown ||
+ file_type == FileSpec::eFileTypeDirectory ||
+ file_type == FileSpec::eFileTypeSymbolicLink) {
+ // Try and recurse into anything that a directory or symbolic link.
+ // We must also do this for unknown as sometimes the directory enumeration
+ // might be enumerating a file system that doesn't have correct file type
+ // information.
+ return FileSpec::eEnumerateDirectoryResultEnter;
+ }
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+void Debugger::InstanceInitialize() {
+ FileSpec dir_spec;
+ const bool find_directories = true;
+ const bool find_files = true;
+ const bool find_other = true;
+ char dir_path[PATH_MAX];
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
+ FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
+ find_other, LoadPluginCallback, this);
}
+ }
- if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
- {
- if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
- {
- FileSpec::EnumerateDirectory (dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- this);
- }
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
+ FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
+ find_other, LoadPluginCallback, this);
}
-
- PluginManager::DebuggerInitialize (*this);
+ }
+
+ PluginManager::DebuggerInitialize(*this);
}
-DebuggerSP
-Debugger::CreateInstance (lldb::LogOutputCallback log_callback, void *baton)
-{
- DebuggerSP debugger_sp (new Debugger(log_callback, baton));
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- g_debugger_list_ptr->push_back(debugger_sp);
- }
- debugger_sp->InstanceInitialize ();
- return debugger_sp;
+DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback,
+ void *baton) {
+ DebuggerSP debugger_sp(new Debugger(log_callback, baton));
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ g_debugger_list_ptr->push_back(debugger_sp);
+ }
+ debugger_sp->InstanceInitialize();
+ return debugger_sp;
}
-void
-Debugger::Destroy (DebuggerSP &debugger_sp)
-{
- if (!debugger_sp)
- return;
-
- debugger_sp->Clear();
+void Debugger::Destroy(DebuggerSP &debugger_sp) {
+ if (!debugger_sp)
+ return;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- if ((*pos).get() == debugger_sp.get())
- {
- g_debugger_list_ptr->erase (pos);
- return;
- }
- }
+ debugger_sp->Clear();
+
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ if ((*pos).get() == debugger_sp.get()) {
+ g_debugger_list_ptr->erase(pos);
+ return;
+ }
}
+ }
}
DebuggerSP
-Debugger::FindDebuggerWithInstanceName (const ConstString &instance_name)
-{
- DebuggerSP debugger_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- if ((*pos)->m_instance_name == instance_name)
- {
- debugger_sp = *pos;
- break;
- }
- }
+Debugger::FindDebuggerWithInstanceName(const ConstString &instance_name) {
+ DebuggerSP debugger_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ if ((*pos)->m_instance_name == instance_name) {
+ debugger_sp = *pos;
+ break;
+ }
}
- return debugger_sp;
-}
-
-TargetSP
-Debugger::FindTargetWithProcessID (lldb::pid_t pid)
-{
- TargetSP target_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
- if (target_sp)
- break;
- }
+ }
+ return debugger_sp;
+}
+
+TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) {
+ TargetSP target_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
+ if (target_sp)
+ break;
}
- return target_sp;
-}
-
-TargetSP
-Debugger::FindTargetWithProcess (Process *process)
-{
- TargetSP target_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
- if (target_sp)
- break;
- }
+ }
+ return target_sp;
+}
+
+TargetSP Debugger::FindTargetWithProcess(Process *process) {
+ TargetSP target_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
+ if (target_sp)
+ break;
}
- return target_sp;
-}
-
-Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
- UserID(g_unique_id++),
- Properties(OptionValuePropertiesSP(new OptionValueProperties())),
- m_input_file_sp(new StreamFile(stdin, false)),
- m_output_file_sp(new StreamFile(stdout, false)),
- m_error_file_sp(new StreamFile(stderr, false)),
- m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
- m_terminal_state(),
- m_target_list(*this),
- m_platform_list(),
- m_listener_sp(Listener::MakeListener("lldb.Debugger")),
- m_source_manager_ap(),
- m_source_file_cache(),
- m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
- m_input_reader_stack(),
- m_instance_name(),
- m_loaded_plugins(),
- m_event_handler_thread(),
- m_io_handler_thread(),
- m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
- m_forward_listener_sp(),
- m_clear_once()
-{
- char instance_cstr[256];
- snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
- m_instance_name.SetCString(instance_cstr);
- if (log_callback)
- m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
- m_command_interpreter_ap->Initialize ();
- // Always add our default platform to the platform list
- PlatformSP default_platform_sp (Platform::GetHostPlatform());
- assert(default_platform_sp);
- m_platform_list.Append (default_platform_sp, true);
-
- m_collection_sp->Initialize (g_properties);
- m_collection_sp->AppendProperty (ConstString("target"),
- ConstString("Settings specify to debugging targets."),
- true,
- Target::GetGlobalProperties()->GetValueProperties());
- m_collection_sp->AppendProperty (ConstString("platform"),
- ConstString("Platform settings."),
- true,
- Platform::GetGlobalPlatformProperties()->GetValueProperties());
- if (m_command_interpreter_ap)
- {
- m_collection_sp->AppendProperty (ConstString("interpreter"),
- ConstString("Settings specify to the debugger's command interpreter."),
- true,
- m_command_interpreter_ap->GetValueProperties());
+ }
+ return target_sp;
+}
+
+Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
+ : UserID(g_unique_id++),
+ Properties(OptionValuePropertiesSP(new OptionValueProperties())),
+ m_input_file_sp(new StreamFile(stdin, false)),
+ m_output_file_sp(new StreamFile(stdout, false)),
+ m_error_file_sp(new StreamFile(stderr, false)),
+ m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
+ m_terminal_state(), m_target_list(*this), m_platform_list(),
+ m_listener_sp(Listener::MakeListener("lldb.Debugger")),
+ m_source_manager_ap(), m_source_file_cache(),
+ m_command_interpreter_ap(
+ new CommandInterpreter(*this, eScriptLanguageDefault, false)),
+ m_input_reader_stack(), m_instance_name(), m_loaded_plugins(),
+ m_event_handler_thread(), m_io_handler_thread(),
+ m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
+ m_forward_listener_sp(), m_clear_once() {
+ char instance_cstr[256];
+ snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
+ m_instance_name.SetCString(instance_cstr);
+ if (log_callback)
+ m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton));
+ m_command_interpreter_ap->Initialize();
+ // Always add our default platform to the platform list
+ PlatformSP default_platform_sp(Platform::GetHostPlatform());
+ assert(default_platform_sp);
+ m_platform_list.Append(default_platform_sp, true);
+
+ m_collection_sp->Initialize(g_properties);
+ m_collection_sp->AppendProperty(
+ ConstString("target"),
+ ConstString("Settings specify to debugging targets."), true,
+ Target::GetGlobalProperties()->GetValueProperties());
+ m_collection_sp->AppendProperty(
+ ConstString("platform"), ConstString("Platform settings."), true,
+ Platform::GetGlobalPlatformProperties()->GetValueProperties());
+ if (m_command_interpreter_ap) {
+ m_collection_sp->AppendProperty(
+ ConstString("interpreter"),
+ ConstString("Settings specify to the debugger's command interpreter."),
+ true, m_command_interpreter_ap->GetValueProperties());
+ }
+ OptionValueSInt64 *term_width =
+ m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(
+ nullptr, ePropertyTerminalWidth);
+ term_width->SetMinimumValue(10);
+ term_width->SetMaximumValue(1024);
+
+ // Turn off use-color if this is a dumb terminal.
+ const char *term = getenv("TERM");
+ if (term && !strcmp(term, "dumb"))
+ SetUseColor(false);
+}
+
+Debugger::~Debugger() { Clear(); }
+
+void Debugger::Clear() {
+ //----------------------------------------------------------------------
+ // Make sure we call this function only once. With the C++ global
+ // destructor chain having a list of debuggers and with code that can be
+ // running on other threads, we need to ensure this doesn't happen
+ // multiple times.
+ //
+ // The following functions call Debugger::Clear():
+ // Debugger::~Debugger();
+ // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
+ // static void Debugger::Terminate();
+ //----------------------------------------------------------------------
+ std::call_once(m_clear_once, [this]() {
+ ClearIOHandlers();
+ StopIOHandlerThread();
+ StopEventHandlerThread();
+ m_listener_sp->Clear();
+ int num_targets = m_target_list.GetNumTargets();
+ for (int i = 0; i < num_targets; i++) {
+ TargetSP target_sp(m_target_list.GetTargetAtIndex(i));
+ if (target_sp) {
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ if (process_sp)
+ process_sp->Finalize();
+ target_sp->Destroy();
+ }
}
- OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(nullptr, ePropertyTerminalWidth);
- term_width->SetMinimumValue(10);
- term_width->SetMaximumValue(1024);
+ m_broadcaster_manager_sp->Clear();
+
+ // Close the input file _before_ we close the input read communications
+ // class
+ // as it does NOT own the input file, our m_input_file does.
+ m_terminal_state.Clear();
+ if (m_input_file_sp)
+ m_input_file_sp->GetFile().Close();
- // Turn off use-color if this is a dumb terminal.
- const char *term = getenv ("TERM");
- if (term && !strcmp (term, "dumb"))
- SetUseColor (false);
+ m_command_interpreter_ap->Clear();
+ });
}
-Debugger::~Debugger ()
-{
- Clear();
+bool Debugger::GetCloseInputOnEOF() const {
+ // return m_input_comm.GetCloseOnEOF();
+ return false;
}
-void
-Debugger::Clear()
-{
- //----------------------------------------------------------------------
- // Make sure we call this function only once. With the C++ global
- // destructor chain having a list of debuggers and with code that can be
- // running on other threads, we need to ensure this doesn't happen
- // multiple times.
- //
- // The following functions call Debugger::Clear():
- // Debugger::~Debugger();
- // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
- // static void Debugger::Terminate();
- //----------------------------------------------------------------------
- std::call_once(m_clear_once, [this]() {
- ClearIOHandlers();
- StopIOHandlerThread();
- StopEventHandlerThread();
- m_listener_sp->Clear();
- int num_targets = m_target_list.GetNumTargets();
- for (int i = 0; i < num_targets; i++)
- {
- TargetSP target_sp (m_target_list.GetTargetAtIndex (i));
- if (target_sp)
- {
- ProcessSP process_sp (target_sp->GetProcessSP());
- if (process_sp)
- process_sp->Finalize();
- target_sp->Destroy();
- }
- }
- m_broadcaster_manager_sp->Clear ();
-
- // Close the input file _before_ we close the input read communications class
- // as it does NOT own the input file, our m_input_file does.
- m_terminal_state.Clear();
- if (m_input_file_sp)
- m_input_file_sp->GetFile().Close ();
-
- m_command_interpreter_ap->Clear();
- });
-}
-
-bool
-Debugger::GetCloseInputOnEOF () const
-{
-// return m_input_comm.GetCloseOnEOF();
- return false;
+void Debugger::SetCloseInputOnEOF(bool b) {
+ // m_input_comm.SetCloseOnEOF(b);
}
-void
-Debugger::SetCloseInputOnEOF (bool b)
-{
-// m_input_comm.SetCloseOnEOF(b);
+bool Debugger::GetAsyncExecution() {
+ return !m_command_interpreter_ap->GetSynchronous();
}
-bool
-Debugger::GetAsyncExecution ()
-{
- return !m_command_interpreter_ap->GetSynchronous();
+void Debugger::SetAsyncExecution(bool async_execution) {
+ m_command_interpreter_ap->SetSynchronous(!async_execution);
}
-void
-Debugger::SetAsyncExecution (bool async_execution)
-{
- m_command_interpreter_ap->SetSynchronous (!async_execution);
+void Debugger::SetInputFileHandle(FILE *fh, bool tranfer_ownership) {
+ if (m_input_file_sp)
+ m_input_file_sp->GetFile().SetStream(fh, tranfer_ownership);
+ else
+ m_input_file_sp.reset(new StreamFile(fh, tranfer_ownership));
+
+ File &in_file = m_input_file_sp->GetFile();
+ if (!in_file.IsValid())
+ in_file.SetStream(stdin, true);
+
+ // Save away the terminal state if that is relevant, so that we can restore it
+ // in RestoreInputState.
+ SaveInputTerminalState();
}
-void
-Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
-{
- if (m_input_file_sp)
- m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
- else
- m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
+void Debugger::SetOutputFileHandle(FILE *fh, bool tranfer_ownership) {
+ if (m_output_file_sp)
+ m_output_file_sp->GetFile().SetStream(fh, tranfer_ownership);
+ else
+ m_output_file_sp.reset(new StreamFile(fh, tranfer_ownership));
- File &in_file = m_input_file_sp->GetFile();
- if (!in_file.IsValid())
- in_file.SetStream (stdin, true);
+ File &out_file = m_output_file_sp->GetFile();
+ if (!out_file.IsValid())
+ out_file.SetStream(stdout, false);
- // Save away the terminal state if that is relevant, so that we can restore it in RestoreInputState.
- SaveInputTerminalState ();
+ // do not create the ScriptInterpreter just for setting the output file handle
+ // as the constructor will know how to do the right thing on its own
+ const bool can_create = false;
+ ScriptInterpreter *script_interpreter =
+ GetCommandInterpreter().GetScriptInterpreter(can_create);
+ if (script_interpreter)
+ script_interpreter->ResetOutputFileHandle(fh);
}
-void
-Debugger::SetOutputFileHandle (FILE *fh, bool tranfer_ownership)
-{
- if (m_output_file_sp)
- m_output_file_sp->GetFile().SetStream (fh, tranfer_ownership);
- else
- m_output_file_sp.reset (new StreamFile (fh, tranfer_ownership));
-
- File &out_file = m_output_file_sp->GetFile();
- if (!out_file.IsValid())
- out_file.SetStream (stdout, false);
-
- // do not create the ScriptInterpreter just for setting the output file handle
- // as the constructor will know how to do the right thing on its own
- const bool can_create = false;
- ScriptInterpreter* script_interpreter = GetCommandInterpreter().GetScriptInterpreter(can_create);
- if (script_interpreter)
- script_interpreter->ResetOutputFileHandle (fh);
-}
-
-void
-Debugger::SetErrorFileHandle (FILE *fh, bool tranfer_ownership)
-{
- if (m_error_file_sp)
- m_error_file_sp->GetFile().SetStream (fh, tranfer_ownership);
- else
- m_error_file_sp.reset (new StreamFile (fh, tranfer_ownership));
-
- File &err_file = m_error_file_sp->GetFile();
- if (!err_file.IsValid())
- err_file.SetStream (stderr, false);
+void Debugger::SetErrorFileHandle(FILE *fh, bool tranfer_ownership) {
+ if (m_error_file_sp)
+ m_error_file_sp->GetFile().SetStream(fh, tranfer_ownership);
+ else
+ m_error_file_sp.reset(new StreamFile(fh, tranfer_ownership));
+
+ File &err_file = m_error_file_sp->GetFile();
+ if (!err_file.IsValid())
+ err_file.SetStream(stderr, false);
}
-void
-Debugger::SaveInputTerminalState ()
-{
- if (m_input_file_sp)
- {
- File &in_file = m_input_file_sp->GetFile();
- if (in_file.GetDescriptor() != File::kInvalidDescriptor)
- m_terminal_state.Save(in_file.GetDescriptor(), true);
+void Debugger::SaveInputTerminalState() {
+ if (m_input_file_sp) {
+ File &in_file = m_input_file_sp->GetFile();
+ if (in_file.GetDescriptor() != File::kInvalidDescriptor)
+ m_terminal_state.Save(in_file.GetDescriptor(), true);
+ }
+}
+
+void Debugger::RestoreInputTerminalState() { m_terminal_state.Restore(); }
+
+ExecutionContext Debugger::GetSelectedExecutionContext() {
+ ExecutionContext exe_ctx;
+ TargetSP target_sp(GetSelectedTarget());
+ exe_ctx.SetTargetSP(target_sp);
+
+ if (target_sp) {
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ exe_ctx.SetProcessSP(process_sp);
+ if (process_sp && !process_sp->IsRunning()) {
+ ThreadSP thread_sp(process_sp->GetThreadList().GetSelectedThread());
+ if (thread_sp) {
+ exe_ctx.SetThreadSP(thread_sp);
+ exe_ctx.SetFrameSP(thread_sp->GetSelectedFrame());
+ if (exe_ctx.GetFramePtr() == nullptr)
+ exe_ctx.SetFrameSP(thread_sp->GetStackFrameAtIndex(0));
+ }
}
+ }
+ return exe_ctx;
}
-void
-Debugger::RestoreInputTerminalState ()
-{
- m_terminal_state.Restore();
+void Debugger::DispatchInputInterrupt() {
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
+ if (reader_sp)
+ reader_sp->Interrupt();
}
-ExecutionContext
-Debugger::GetSelectedExecutionContext ()
-{
- ExecutionContext exe_ctx;
- TargetSP target_sp(GetSelectedTarget());
- exe_ctx.SetTargetSP (target_sp);
-
- if (target_sp)
- {
- ProcessSP process_sp (target_sp->GetProcessSP());
- exe_ctx.SetProcessSP (process_sp);
- if (process_sp && !process_sp->IsRunning())
- {
- ThreadSP thread_sp (process_sp->GetThreadList().GetSelectedThread());
- if (thread_sp)
- {
- exe_ctx.SetThreadSP (thread_sp);
- exe_ctx.SetFrameSP (thread_sp->GetSelectedFrame());
- if (exe_ctx.GetFramePtr() == nullptr)
- exe_ctx.SetFrameSP (thread_sp->GetStackFrameAtIndex (0));
- }
- }
- }
- return exe_ctx;
+void Debugger::DispatchInputEndOfFile() {
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
+ if (reader_sp)
+ reader_sp->GotEOF();
}
-void
-Debugger::DispatchInputInterrupt()
-{
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+void Debugger::ClearIOHandlers() {
+ // The bottom input reader should be the main debugger input reader. We do
+ // not want to close that one here.
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ while (m_input_reader_stack.GetSize() > 1) {
IOHandlerSP reader_sp(m_input_reader_stack.Top());
if (reader_sp)
- reader_sp->Interrupt();
+ PopIOHandler(reader_sp);
+ }
}
-void
-Debugger::DispatchInputEndOfFile()
-{
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+void Debugger::ExecuteIOHandlers() {
+ while (true) {
IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (reader_sp)
- reader_sp->GotEOF();
-}
+ if (!reader_sp)
+ break;
-void
-Debugger::ClearIOHandlers()
-{
- // The bottom input reader should be the main debugger input reader. We do not want to close that one here.
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- while (m_input_reader_stack.GetSize() > 1)
- {
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (reader_sp)
- PopIOHandler(reader_sp);
- }
-}
+ reader_sp->Run();
-void
-Debugger::ExecuteIOHandlers()
-{
- while (true)
- {
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (!reader_sp)
- break;
-
- reader_sp->Run();
-
- // Remove all input readers that are done from the top of the stack
- while (true)
- {
- IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
- if (top_reader_sp && top_reader_sp->GetIsDone())
- PopIOHandler (top_reader_sp);
- else
- break;
- }
+ // Remove all input readers that are done from the top of the stack
+ while (true) {
+ IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
+ if (top_reader_sp && top_reader_sp->GetIsDone())
+ PopIOHandler(top_reader_sp);
+ else
+ break;
}
- ClearIOHandlers();
+ }
+ ClearIOHandlers();
}
-bool
-Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
-{
- return m_input_reader_stack.IsTop (reader_sp);
+bool 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);
+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)
-{
- lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
- m_input_reader_stack.PrintAsync(stream.get(), s, len);
+void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
+ lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
+ m_input_reader_stack.PrintAsync(stream.get(), s, len);
}
-ConstString
-Debugger::GetTopIOHandlerControlSequence(char ch)
-{
- return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
+ConstString Debugger::GetTopIOHandlerControlSequence(char ch) {
+ return m_input_reader_stack.GetTopIOHandlerControlSequence(ch);
}
-const char *
-Debugger::GetIOHandlerCommandPrefix()
-{
- return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
+const char *Debugger::GetIOHandlerCommandPrefix() {
+ return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
}
-const char *
-Debugger::GetIOHandlerHelpPrologue()
-{
- return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
+const char *Debugger::GetIOHandlerHelpPrologue() {
+ return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
}
-void
-Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
-{
- PushIOHandler (reader_sp);
+void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) {
+ PushIOHandler(reader_sp);
- IOHandlerSP top_reader_sp = reader_sp;
- while (top_reader_sp)
- {
- top_reader_sp->Run();
+ IOHandlerSP top_reader_sp = reader_sp;
+ while (top_reader_sp) {
+ top_reader_sp->Run();
- if (top_reader_sp.get() == reader_sp.get())
- {
- if (PopIOHandler (reader_sp))
- break;
- }
+ if (top_reader_sp.get() == reader_sp.get()) {
+ if (PopIOHandler(reader_sp))
+ break;
+ }
- while (true)
- {
- top_reader_sp = m_input_reader_stack.Top();
- if (top_reader_sp && top_reader_sp->GetIsDone())
- PopIOHandler (top_reader_sp);
- else
- break;
- }
+ while (true) {
+ top_reader_sp = m_input_reader_stack.Top();
+ if (top_reader_sp && top_reader_sp->GetIsDone())
+ PopIOHandler(top_reader_sp);
+ else
+ break;
}
-}
+ }
+}
+
+void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in,
+ StreamFileSP &out,
+ StreamFileSP &err) {
+ // Before an IOHandler runs, it must have in/out/err streams.
+ // This function is called when one ore more of the streams
+ // are nullptr. We use the top input reader's in/out/err streams,
+ // or fall back to the debugger file handles, or we fall back
+ // onto stdin/stdout/stderr as a last resort.
+
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
+ // If no STDIN has been set, then set it appropriately
+ if (!in) {
+ if (top_reader_sp)
+ in = top_reader_sp->GetInputStreamFile();
+ else
+ in = GetInputFile();
-void
-Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
-{
- // Before an IOHandler runs, it must have in/out/err streams.
- // This function is called when one ore more of the streams
- // are nullptr. We use the top input reader's in/out/err streams,
- // or fall back to the debugger file handles, or we fall back
- // onto stdin/stdout/stderr as a last resort.
-
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
- // If no STDIN has been set, then set it appropriately
+ // If there is nothing, use stdin
if (!in)
- {
- if (top_reader_sp)
- in = top_reader_sp->GetInputStreamFile();
- else
- in = GetInputFile();
-
- // If there is nothing, use stdin
- if (!in)
- in = StreamFileSP(new StreamFile(stdin, false));
- }
- // If no STDOUT has been set, then set it appropriately
+ in = StreamFileSP(new StreamFile(stdin, false));
+ }
+ // If no STDOUT has been set, then set it appropriately
+ if (!out) {
+ if (top_reader_sp)
+ out = top_reader_sp->GetOutputStreamFile();
+ else
+ out = GetOutputFile();
+
+ // If there is nothing, use stdout
if (!out)
- {
- if (top_reader_sp)
- out = top_reader_sp->GetOutputStreamFile();
- else
- out = GetOutputFile();
-
- // If there is nothing, use stdout
- if (!out)
- out = StreamFileSP(new StreamFile(stdout, false));
- }
- // If no STDERR has been set, then set it appropriately
+ out = StreamFileSP(new StreamFile(stdout, false));
+ }
+ // If no STDERR has been set, then set it appropriately
+ if (!err) {
+ if (top_reader_sp)
+ err = top_reader_sp->GetErrorStreamFile();
+ else
+ err = GetErrorFile();
+
+ // If there is nothing, use stderr
if (!err)
- {
- if (top_reader_sp)
- err = top_reader_sp->GetErrorStreamFile();
- else
- err = GetErrorFile();
-
- // If there is nothing, use stderr
- if (!err)
- err = StreamFileSP(new StreamFile(stdout, false));
- }
+ err = StreamFileSP(new StreamFile(stdout, false));
+ }
}
-void
-Debugger::PushIOHandler(const IOHandlerSP &reader_sp)
-{
- if (!reader_sp)
- return;
+void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) {
+ if (!reader_sp)
+ return;
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- // Get the current top input reader...
- IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
+ // Get the current top input reader...
+ IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
- // Don't push the same IO handler twice...
- if (reader_sp == top_reader_sp)
- return;
+ // Don't push the same IO handler twice...
+ if (reader_sp == top_reader_sp)
+ return;
- // Push our new input reader
- m_input_reader_stack.Push(reader_sp);
- reader_sp->Activate();
+ // Push our new input reader
+ m_input_reader_stack.Push(reader_sp);
+ reader_sp->Activate();
- // Interrupt the top input reader to it will exit its Run() function
- // and let this new input reader take over
- if (top_reader_sp)
- {
- top_reader_sp->Deactivate();
- top_reader_sp->Cancel();
- }
+ // Interrupt the top input reader to it will exit its Run() function
+ // and let this new input reader take over
+ if (top_reader_sp) {
+ top_reader_sp->Deactivate();
+ top_reader_sp->Cancel();
+ }
}
-bool
-Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp)
-{
- if (!pop_reader_sp)
- return false;
+bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
+ if (!pop_reader_sp)
+ return false;
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- // The reader on the stop of the stack is done, so let the next
- // read on the stack refresh its prompt and if there is one...
- if (m_input_reader_stack.IsEmpty())
- return false;
+ // The reader on the stop of the stack is done, so let the next
+ // read on the stack refresh its prompt and if there is one...
+ if (m_input_reader_stack.IsEmpty())
+ return false;
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (pop_reader_sp != reader_sp)
- return false;
+ if (pop_reader_sp != reader_sp)
+ return false;
- reader_sp->Deactivate();
- reader_sp->Cancel();
- m_input_reader_stack.Pop();
+ reader_sp->Deactivate();
+ reader_sp->Cancel();
+ m_input_reader_stack.Pop();
- reader_sp = m_input_reader_stack.Top();
- if (reader_sp)
- reader_sp->Activate();
+ reader_sp = m_input_reader_stack.Top();
+ if (reader_sp)
+ reader_sp->Activate();
- return true;
+ return true;
}
-StreamSP
-Debugger::GetAsyncOutputStream ()
-{
- return StreamSP (new StreamAsynchronousIO (*this, true));
+StreamSP Debugger::GetAsyncOutputStream() {
+ return StreamSP(new StreamAsynchronousIO(*this, true));
}
-StreamSP
-Debugger::GetAsyncErrorStream ()
-{
- return StreamSP (new StreamAsynchronousIO (*this, false));
-}
+StreamSP Debugger::GetAsyncErrorStream() {
+ return StreamSP(new StreamAsynchronousIO(*this, false));
+}
-size_t
-Debugger::GetNumDebuggers()
-{
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- return g_debugger_list_ptr->size();
- }
- return 0;
+size_t Debugger::GetNumDebuggers() {
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ return g_debugger_list_ptr->size();
+ }
+ return 0;
}
-lldb::DebuggerSP
-Debugger::GetDebuggerAtIndex (size_t index)
-{
- DebuggerSP debugger_sp;
-
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- if (index < g_debugger_list_ptr->size())
- debugger_sp = g_debugger_list_ptr->at(index);
- }
+lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) {
+ DebuggerSP debugger_sp;
- return debugger_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ if (index < g_debugger_list_ptr->size())
+ debugger_sp = g_debugger_list_ptr->at(index);
+ }
+
+ return debugger_sp;
}
-DebuggerSP
-Debugger::FindDebuggerWithID (lldb::user_id_t id)
-{
- DebuggerSP debugger_sp;
+DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) {
+ DebuggerSP debugger_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- if ((*pos)->GetID() == id)
- {
- debugger_sp = *pos;
- break;
- }
- }
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ if ((*pos)->GetID() == id) {
+ debugger_sp = *pos;
+ break;
+ }
}
- return debugger_sp;
+ }
+ return debugger_sp;
}
#if 0
@@ -1258,582 +1187,535 @@ TestPromptFormats (StackFrame *frame)
}
#endif
-bool
-Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
- const SymbolContext *sc,
- const SymbolContext *prev_sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- Stream &s)
-{
- FormatEntity::Entry format_entry;
-
- if (format == nullptr)
- {
- if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
- format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
- if (format == nullptr)
- {
- FormatEntity::Parse("${addr}: ", format_entry);
- format = &format_entry;
- }
+bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
+ const SymbolContext *sc,
+ const SymbolContext *prev_sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr, Stream &s) {
+ FormatEntity::Entry format_entry;
+
+ if (format == nullptr) {
+ if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
+ format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
+ if (format == nullptr) {
+ FormatEntity::Parse("${addr}: ", format_entry);
+ format = &format_entry;
}
- bool function_changed = false;
- bool initial_function = false;
- if (prev_sc && (prev_sc->function || prev_sc->symbol))
- {
- if (sc && (sc->function || sc->symbol))
- {
- if (prev_sc->symbol && sc->symbol)
- {
- if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
- {
- function_changed = true;
- }
- }
- else if (prev_sc->function && sc->function)
- {
- if (prev_sc->function->GetMangled() != sc->function->GetMangled())
- {
- function_changed = true;
- }
- }
+ }
+ bool function_changed = false;
+ bool initial_function = false;
+ if (prev_sc && (prev_sc->function || prev_sc->symbol)) {
+ if (sc && (sc->function || sc->symbol)) {
+ if (prev_sc->symbol && sc->symbol) {
+ if (!sc->symbol->Compare(prev_sc->symbol->GetName(),
+ prev_sc->symbol->GetType())) {
+ function_changed = true;
+ }
+ } else if (prev_sc->function && sc->function) {
+ if (prev_sc->function->GetMangled() != sc->function->GetMangled()) {
+ function_changed = true;
}
+ }
}
- // The first context on a list of instructions will have a prev_sc that
- // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
- // would return false. But we do get a prev_sc pointer.
- if ((sc && (sc->function || sc->symbol))
- && prev_sc && (prev_sc->function == nullptr && prev_sc->symbol == nullptr))
- {
- initial_function = true;
+ }
+ // The first context on a list of instructions will have a prev_sc that
+ // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
+ // would return false. But we do get a prev_sc pointer.
+ if ((sc && (sc->function || sc->symbol)) && prev_sc &&
+ (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
+ initial_function = true;
+ }
+ return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr,
+ function_changed, initial_function);
+}
+
+void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
+ void *baton) {
+ // For simplicity's sake, I am not going to deal with how to close down any
+ // open logging streams, I just redirect everything from here on out to the
+ // callback.
+ m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton));
+}
+
+bool Debugger::EnableLog(const char *channel, const char **categories,
+ const char *log_file, uint32_t log_options,
+ Stream &error_stream) {
+ StreamSP log_stream_sp;
+ if (m_log_callback_stream_sp) {
+ log_stream_sp = m_log_callback_stream_sp;
+ // For now when using the callback mode you always get thread & timestamp.
+ log_options |=
+ LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
+ } else if (log_file == nullptr || *log_file == '\0') {
+ log_stream_sp = GetOutputFile();
+ } else {
+ LogStreamMap::iterator pos = m_log_streams.find(log_file);
+ if (pos != m_log_streams.end())
+ log_stream_sp = pos->second.lock();
+ if (!log_stream_sp) {
+ uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
+ if (!(log_options & LLDB_LOG_OPTION_APPEND))
+ options |= File::eOpenOptionTruncate;
+
+ log_stream_sp.reset(new StreamFile(log_file, options));
+ m_log_streams[log_file] = log_stream_sp;
}
- return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, function_changed, initial_function);
-}
+ }
+ assert(log_stream_sp);
-void
-Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
-{
- // For simplicity's sake, I am not going to deal with how to close down any
- // open logging streams, I just redirect everything from here on out to the
- // callback.
- m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
-}
+ if (log_options == 0)
+ log_options =
+ LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
-bool
-Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
-{
- StreamSP log_stream_sp;
- if (m_log_callback_stream_sp)
- {
- log_stream_sp = m_log_callback_stream_sp;
- // For now when using the callback mode you always get thread & timestamp.
- log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
- }
- else if (log_file == nullptr || *log_file == '\0')
- {
- log_stream_sp = GetOutputFile();
- }
- else
- {
- LogStreamMap::iterator pos = m_log_streams.find(log_file);
- if (pos != m_log_streams.end())
- log_stream_sp = pos->second.lock();
- if (!log_stream_sp)
- {
- uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate
- | File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
- if (! (log_options & LLDB_LOG_OPTION_APPEND))
- options |= File::eOpenOptionTruncate;
-
- log_stream_sp.reset (new StreamFile (log_file, options));
- m_log_streams[log_file] = log_stream_sp;
- }
- }
- assert(log_stream_sp);
-
- if (log_options == 0)
- log_options = LLDB_LOG_OPTION_PREPEND_THREAD_NAME | LLDB_LOG_OPTION_THREADSAFE;
-
- return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories, error_stream);
+ return Log::EnableLogChannel(log_stream_sp, log_options, channel, categories,
+ error_stream);
}
-SourceManager &
-Debugger::GetSourceManager ()
-{
- if (!m_source_manager_ap)
- m_source_manager_ap.reset (new SourceManager (shared_from_this()));
- return *m_source_manager_ap;
+SourceManager &Debugger::GetSourceManager() {
+ if (!m_source_manager_ap)
+ m_source_manager_ap.reset(new SourceManager(shared_from_this()));
+ return *m_source_manager_ap;
}
// This function handles events that were broadcast by the process.
-void
-Debugger::HandleBreakpointEvent (const EventSP &event_sp)
-{
- using namespace lldb;
- const uint32_t event_type = Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent (event_sp);
-
-// if (event_type & eBreakpointEventTypeAdded
-// || event_type & eBreakpointEventTypeRemoved
-// || event_type & eBreakpointEventTypeEnabled
-// || event_type & eBreakpointEventTypeDisabled
-// || event_type & eBreakpointEventTypeCommandChanged
-// || event_type & eBreakpointEventTypeConditionChanged
-// || event_type & eBreakpointEventTypeIgnoreChanged
-// || event_type & eBreakpointEventTypeLocationsResolved)
-// {
-// // Don't do anything about these events, since the breakpoint commands already echo these actions.
-// }
-//
- if (event_type & eBreakpointEventTypeLocationsAdded)
- {
- uint32_t num_new_locations = Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(event_sp);
- if (num_new_locations > 0)
- {
- BreakpointSP breakpoint = Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
- StreamSP output_sp (GetAsyncOutputStream());
- if (output_sp)
- {
- output_sp->Printf("%d location%s added to breakpoint %d\n",
- num_new_locations,
- num_new_locations == 1 ? "" : "s",
- breakpoint->GetID());
- output_sp->Flush();
- }
- }
+void Debugger::HandleBreakpointEvent(const EventSP &event_sp) {
+ using namespace lldb;
+ const uint32_t event_type =
+ Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
+ event_sp);
+
+ // if (event_type & eBreakpointEventTypeAdded
+ // || event_type & eBreakpointEventTypeRemoved
+ // || event_type & eBreakpointEventTypeEnabled
+ // || event_type & eBreakpointEventTypeDisabled
+ // || event_type & eBreakpointEventTypeCommandChanged
+ // || event_type & eBreakpointEventTypeConditionChanged
+ // || event_type & eBreakpointEventTypeIgnoreChanged
+ // || event_type & eBreakpointEventTypeLocationsResolved)
+ // {
+ // // Don't do anything about these events, since the breakpoint
+ // commands already echo these actions.
+ // }
+ //
+ if (event_type & eBreakpointEventTypeLocationsAdded) {
+ uint32_t num_new_locations =
+ Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
+ event_sp);
+ if (num_new_locations > 0) {
+ BreakpointSP breakpoint =
+ Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
+ StreamSP output_sp(GetAsyncOutputStream());
+ if (output_sp) {
+ output_sp->Printf("%d location%s added to breakpoint %d\n",
+ num_new_locations, num_new_locations == 1 ? "" : "s",
+ breakpoint->GetID());
+ output_sp->Flush();
+ }
}
-// else if (event_type & eBreakpointEventTypeLocationsRemoved)
-// {
-// // These locations just get disabled, not sure it is worth spamming folks about this on the command line.
-// }
-// else if (event_type & eBreakpointEventTypeLocationsResolved)
-// {
-// // This might be an interesting thing to note, but I'm going to leave it quiet for now, it just looked noisy.
-// }
-}
-
-size_t
-Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
-{
- size_t total_bytes = 0;
- if (stream == nullptr)
- stream = GetOutputFile().get();
-
- if (stream)
- {
- // The process has stuff waiting for stdout; get it and write it out to the appropriate place.
- if (process == nullptr)
- {
- TargetSP target_sp = GetTargetList().GetSelectedTarget();
- if (target_sp)
- process = target_sp->GetProcessSP().get();
- }
- if (process)
- {
- Error error;
- size_t len;
- char stdio_buffer[1024];
- while ((len = process->GetSTDOUT (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
- {
- stream->Write(stdio_buffer, len);
- total_bytes += len;
- }
- }
- stream->Flush();
+ }
+ // else if (event_type & eBreakpointEventTypeLocationsRemoved)
+ // {
+ // // These locations just get disabled, not sure it is worth spamming
+ // folks about this on the command line.
+ // }
+ // else if (event_type & eBreakpointEventTypeLocationsResolved)
+ // {
+ // // This might be an interesting thing to note, but I'm going to
+ // leave it quiet for now, it just looked noisy.
+ // }
+}
+
+size_t Debugger::GetProcessSTDOUT(Process *process, Stream *stream) {
+ size_t total_bytes = 0;
+ if (stream == nullptr)
+ stream = GetOutputFile().get();
+
+ if (stream) {
+ // The process has stuff waiting for stdout; get it and write it out to the
+ // appropriate place.
+ if (process == nullptr) {
+ TargetSP target_sp = GetTargetList().GetSelectedTarget();
+ if (target_sp)
+ process = target_sp->GetProcessSP().get();
}
- return total_bytes;
-}
-
-size_t
-Debugger::GetProcessSTDERR (Process *process, Stream *stream)
-{
- size_t total_bytes = 0;
- if (stream == nullptr)
- stream = GetOutputFile().get();
-
- if (stream)
- {
- // The process has stuff waiting for stderr; get it and write it out to the appropriate place.
- if (process == nullptr)
- {
- TargetSP target_sp = GetTargetList().GetSelectedTarget();
- if (target_sp)
- process = target_sp->GetProcessSP().get();
- }
- if (process)
- {
- Error error;
- size_t len;
- char stdio_buffer[1024];
- while ((len = process->GetSTDERR (stdio_buffer, sizeof (stdio_buffer), error)) > 0)
- {
- stream->Write(stdio_buffer, len);
- total_bytes += len;
- }
- }
- stream->Flush();
+ if (process) {
+ Error error;
+ size_t len;
+ char stdio_buffer[1024];
+ while ((len = process->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
+ error)) > 0) {
+ stream->Write(stdio_buffer, len);
+ total_bytes += len;
+ }
+ }
+ stream->Flush();
+ }
+ return total_bytes;
+}
+
+size_t Debugger::GetProcessSTDERR(Process *process, Stream *stream) {
+ size_t total_bytes = 0;
+ if (stream == nullptr)
+ stream = GetOutputFile().get();
+
+ if (stream) {
+ // The process has stuff waiting for stderr; get it and write it out to the
+ // appropriate place.
+ if (process == nullptr) {
+ TargetSP target_sp = GetTargetList().GetSelectedTarget();
+ if (target_sp)
+ process = target_sp->GetProcessSP().get();
}
- return total_bytes;
+ if (process) {
+ Error error;
+ size_t len;
+ char stdio_buffer[1024];
+ while ((len = process->GetSTDERR(stdio_buffer, sizeof(stdio_buffer),
+ error)) > 0) {
+ stream->Write(stdio_buffer, len);
+ total_bytes += len;
+ }
+ }
+ stream->Flush();
+ }
+ return total_bytes;
}
-
// This function handles events that were broadcast by the process.
-void
-Debugger::HandleProcessEvent (const EventSP &event_sp)
-{
- using namespace lldb;
- const uint32_t event_type = event_sp->GetType();
- ProcessSP process_sp = Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
-
- StreamSP output_stream_sp = GetAsyncOutputStream();
- StreamSP error_stream_sp = GetAsyncErrorStream();
- const bool gui_enabled = IsForwardingEvents();
-
- if (!gui_enabled)
- {
- bool pop_process_io_handler = false;
- assert (process_sp);
-
- bool state_is_stopped = false;
- const bool got_state_changed = (event_type & Process::eBroadcastBitStateChanged) != 0;
- const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
- const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
- if (got_state_changed)
- {
- StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
- state_is_stopped = StateIsStoppedState(event_state, false);
- }
-
- // Display running state changes first before any STDIO
- if (got_state_changed && !state_is_stopped)
- {
- Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
- }
-
- // Now display and STDOUT
- if (got_stdout || got_state_changed)
- {
- GetProcessSTDOUT (process_sp.get(), output_stream_sp.get());
- }
-
- // Now display and STDERR
- if (got_stderr || got_state_changed)
- {
- GetProcessSTDERR (process_sp.get(), error_stream_sp.get());
- }
+void Debugger::HandleProcessEvent(const EventSP &event_sp) {
+ using namespace lldb;
+ const uint32_t event_type = event_sp->GetType();
+ ProcessSP process_sp =
+ (event_type == Process::eBroadcastBitStructuredData)
+ ? EventDataStructuredData::GetProcessFromEvent(event_sp.get())
+ : Process::ProcessEventData::GetProcessFromEvent(event_sp.get());
+
+ StreamSP output_stream_sp = GetAsyncOutputStream();
+ StreamSP error_stream_sp = GetAsyncErrorStream();
+ const bool gui_enabled = IsForwardingEvents();
+
+ if (!gui_enabled) {
+ bool pop_process_io_handler = false;
+ assert(process_sp);
+
+ bool state_is_stopped = false;
+ const bool got_state_changed =
+ (event_type & Process::eBroadcastBitStateChanged) != 0;
+ const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
+ const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
+ const bool got_structured_data =
+ (event_type & Process::eBroadcastBitStructuredData) != 0;
+
+ if (got_state_changed) {
+ StateType event_state =
+ Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+ state_is_stopped = StateIsStoppedState(event_state, false);
+ }
- // Now display any stopped state changes after any STDIO
- if (got_state_changed && state_is_stopped)
- {
- Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
- }
+ // Display running state changes first before any STDIO
+ if (got_state_changed && !state_is_stopped) {
+ Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
+ pop_process_io_handler);
+ }
- output_stream_sp->Flush();
- error_stream_sp->Flush();
+ // Now display and STDOUT
+ if (got_stdout || got_state_changed) {
+ GetProcessSTDOUT(process_sp.get(), output_stream_sp.get());
+ }
- if (pop_process_io_handler)
- process_sp->PopProcessIOHandler();
+ // Now display and STDERR
+ if (got_stderr || got_state_changed) {
+ GetProcessSTDERR(process_sp.get(), error_stream_sp.get());
}
-}
-void
-Debugger::HandleThreadEvent (const EventSP &event_sp)
-{
- // At present the only thread event we handle is the Frame Changed event,
- // and all we do for that is just reprint the thread status for that thread.
- using namespace lldb;
- const uint32_t event_type = event_sp->GetType();
- if (event_type == Thread::eBroadcastBitStackChanged ||
- event_type == Thread::eBroadcastBitThreadSelected )
- {
- ThreadSP thread_sp (Thread::ThreadEventData::GetThreadFromEvent (event_sp.get()));
- if (thread_sp)
- {
- thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1);
+ // Give structured data events an opportunity to display.
+ if (got_structured_data) {
+ StructuredDataPluginSP plugin_sp =
+ EventDataStructuredData::GetPluginFromEvent(event_sp.get());
+ if (plugin_sp) {
+ auto structured_data_sp =
+ EventDataStructuredData::GetObjectFromEvent(event_sp.get());
+ if (output_stream_sp) {
+ StreamString content_stream;
+ Error error =
+ plugin_sp->GetDescription(structured_data_sp, content_stream);
+ if (error.Success()) {
+ if (!content_stream.GetString().empty()) {
+ // Add newline.
+ content_stream.PutChar('\n');
+ content_stream.Flush();
+
+ // Print it.
+ output_stream_sp->PutCString(content_stream.GetString());
+ }
+ } else {
+ error_stream_sp->Printf("Failed to print structured "
+ "data with plugin %s: %s",
+ plugin_sp->GetPluginName().AsCString(),
+ error.AsCString());
+ }
}
+ }
}
-}
-
-bool
-Debugger::IsForwardingEvents ()
-{
- return (bool)m_forward_listener_sp;
-}
-
-void
-Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
-{
- m_forward_listener_sp = listener_sp;
-}
-
-void
-Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
-{
- m_forward_listener_sp.reset();
-}
+ // Now display any stopped state changes after any STDIO
+ if (got_state_changed && state_is_stopped) {
+ Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
+ pop_process_io_handler);
+ }
-void
-Debugger::DefaultEventHandler()
-{
- ListenerSP listener_sp(GetListener());
- ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
- ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
- ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
- BroadcastEventSpec target_event_spec (broadcaster_class_target,
- Target::eBroadcastBitBreakpointChanged);
-
- BroadcastEventSpec process_event_spec (broadcaster_class_process,
- Process::eBroadcastBitStateChanged |
- Process::eBroadcastBitSTDOUT |
- Process::eBroadcastBitSTDERR);
-
- BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
- Thread::eBroadcastBitStackChanged |
- Thread::eBroadcastBitThreadSelected );
-
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, target_event_spec);
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, process_event_spec);
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, thread_event_spec);
- listener_sp->StartListeningForEvents (m_command_interpreter_ap.get(),
- CommandInterpreter::eBroadcastBitQuitCommandReceived |
- CommandInterpreter::eBroadcastBitAsynchronousOutputData |
- CommandInterpreter::eBroadcastBitAsynchronousErrorData );
-
- // Let the thread that spawned us know that we have started up and
- // that we are now listening to all required events so no events get missed
- m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
-
- bool done = false;
- while (!done)
- {
- EventSP event_sp;
- if (listener_sp->WaitForEvent(nullptr, event_sp))
- {
- if (event_sp)
- {
- Broadcaster *broadcaster = event_sp->GetBroadcaster();
- if (broadcaster)
- {
- uint32_t event_type = event_sp->GetType();
- ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
- if (broadcaster_class == broadcaster_class_process)
- {
- HandleProcessEvent (event_sp);
- }
- else if (broadcaster_class == broadcaster_class_target)
- {
- if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(event_sp.get()))
- {
- HandleBreakpointEvent (event_sp);
- }
- }
- else if (broadcaster_class == broadcaster_class_thread)
- {
- HandleThreadEvent (event_sp);
- }
- else if (broadcaster == m_command_interpreter_ap.get())
- {
- if (event_type & CommandInterpreter::eBroadcastBitQuitCommandReceived)
- {
- done = true;
- }
- else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousErrorData)
- {
- const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
- if (data && data[0])
- {
- StreamSP error_sp (GetAsyncErrorStream());
- if (error_sp)
- {
- error_sp->PutCString(data);
- error_sp->Flush();
- }
- }
- }
- else if (event_type & CommandInterpreter::eBroadcastBitAsynchronousOutputData)
- {
- const char *data = reinterpret_cast<const char *>(EventDataBytes::GetBytesFromEvent (event_sp.get()));
- if (data && data[0])
- {
- StreamSP output_sp (GetAsyncOutputStream());
- if (output_sp)
- {
- output_sp->PutCString(data);
- output_sp->Flush();
- }
- }
- }
- }
+ output_stream_sp->Flush();
+ error_stream_sp->Flush();
+
+ if (pop_process_io_handler)
+ process_sp->PopProcessIOHandler();
+ }
+}
+
+void Debugger::HandleThreadEvent(const EventSP &event_sp) {
+ // At present the only thread event we handle is the Frame Changed event,
+ // and all we do for that is just reprint the thread status for that thread.
+ using namespace lldb;
+ const uint32_t event_type = event_sp->GetType();
+ const bool stop_format = true;
+ if (event_type == Thread::eBroadcastBitStackChanged ||
+ event_type == Thread::eBroadcastBitThreadSelected) {
+ ThreadSP thread_sp(
+ Thread::ThreadEventData::GetThreadFromEvent(event_sp.get()));
+ if (thread_sp) {
+ thread_sp->GetStatus(*GetAsyncOutputStream(), 0, 1, 1, stop_format);
+ }
+ }
+}
+
+bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; }
+
+void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) {
+ m_forward_listener_sp = listener_sp;
+}
+
+void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
+ m_forward_listener_sp.reset();
+}
+
+void Debugger::DefaultEventHandler() {
+ ListenerSP listener_sp(GetListener());
+ ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
+ ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
+ ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
+ BroadcastEventSpec target_event_spec(broadcaster_class_target,
+ Target::eBroadcastBitBreakpointChanged);
+
+ BroadcastEventSpec process_event_spec(
+ broadcaster_class_process,
+ Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT |
+ Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData);
+
+ BroadcastEventSpec thread_event_spec(broadcaster_class_thread,
+ Thread::eBroadcastBitStackChanged |
+ Thread::eBroadcastBitThreadSelected);
+
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ target_event_spec);
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ process_event_spec);
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ thread_event_spec);
+ listener_sp->StartListeningForEvents(
+ m_command_interpreter_ap.get(),
+ CommandInterpreter::eBroadcastBitQuitCommandReceived |
+ CommandInterpreter::eBroadcastBitAsynchronousOutputData |
+ CommandInterpreter::eBroadcastBitAsynchronousErrorData);
+
+ // Let the thread that spawned us know that we have started up and
+ // that we are now listening to all required events so no events get missed
+ m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
+
+ bool done = false;
+ while (!done) {
+ EventSP event_sp;
+ if (listener_sp->GetEvent(event_sp, llvm::None)) {
+ if (event_sp) {
+ Broadcaster *broadcaster = event_sp->GetBroadcaster();
+ if (broadcaster) {
+ uint32_t event_type = event_sp->GetType();
+ ConstString broadcaster_class(broadcaster->GetBroadcasterClass());
+ if (broadcaster_class == broadcaster_class_process) {
+ HandleProcessEvent(event_sp);
+ } else if (broadcaster_class == broadcaster_class_target) {
+ if (Breakpoint::BreakpointEventData::GetEventDataFromEvent(
+ event_sp.get())) {
+ HandleBreakpointEvent(event_sp);
+ }
+ } else if (broadcaster_class == broadcaster_class_thread) {
+ HandleThreadEvent(event_sp);
+ } else if (broadcaster == m_command_interpreter_ap.get()) {
+ if (event_type &
+ CommandInterpreter::eBroadcastBitQuitCommandReceived) {
+ done = true;
+ } else if (event_type &
+ CommandInterpreter::eBroadcastBitAsynchronousErrorData) {
+ const char *data = reinterpret_cast<const char *>(
+ EventDataBytes::GetBytesFromEvent(event_sp.get()));
+ if (data && data[0]) {
+ StreamSP error_sp(GetAsyncErrorStream());
+ if (error_sp) {
+ error_sp->PutCString(data);
+ error_sp->Flush();
+ }
+ }
+ } else if (event_type & CommandInterpreter::
+ eBroadcastBitAsynchronousOutputData) {
+ const char *data = reinterpret_cast<const char *>(
+ EventDataBytes::GetBytesFromEvent(event_sp.get()));
+ if (data && data[0]) {
+ StreamSP output_sp(GetAsyncOutputStream());
+ if (output_sp) {
+ output_sp->PutCString(data);
+ output_sp->Flush();
}
-
- if (m_forward_listener_sp)
- m_forward_listener_sp->AddEvent(event_sp);
+ }
}
+ }
}
- }
-}
-
-lldb::thread_result_t
-Debugger::EventHandlerThread (lldb::thread_arg_t arg)
-{
- ((Debugger *)arg)->DefaultEventHandler();
- return NULL;
-}
-bool
-Debugger::StartEventHandlerThread()
-{
- if (!m_event_handler_thread.IsJoinable())
- {
- // We must synchronize with the DefaultEventHandler() thread to ensure
- // it is up and running and listening to events before we return from
- // this function. We do this by listening to events for the
- // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
- ListenerSP listener_sp(Listener::MakeListener("lldb.debugger.event-handler"));
- listener_sp->StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
-
- // Use larger 8MB stack for this thread
- m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler",
- EventHandlerThread,
- this,
- nullptr,
- g_debugger_event_thread_stack_bytes);
-
- // Make sure DefaultEventHandler() is running and listening to events before we return
- // from this function. We are only listening for events of type
- // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
- // to wait an infinite amount of time for it (nullptr timeout as the first parameter)
- lldb::EventSP event_sp;
- listener_sp->WaitForEvent(nullptr, event_sp);
+ if (m_forward_listener_sp)
+ m_forward_listener_sp->AddEvent(event_sp);
+ }
}
- return m_event_handler_thread.IsJoinable();
+ }
+}
+
+lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) {
+ ((Debugger *)arg)->DefaultEventHandler();
+ return NULL;
+}
+
+bool Debugger::StartEventHandlerThread() {
+ if (!m_event_handler_thread.IsJoinable()) {
+ // We must synchronize with the DefaultEventHandler() thread to ensure
+ // it is up and running and listening to events before we return from
+ // this function. We do this by listening to events for the
+ // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
+ ListenerSP listener_sp(
+ Listener::MakeListener("lldb.debugger.event-handler"));
+ listener_sp->StartListeningForEvents(&m_sync_broadcaster,
+ eBroadcastBitEventThreadIsListening);
+
+ // Use larger 8MB stack for this thread
+ m_event_handler_thread = ThreadLauncher::LaunchThread(
+ "lldb.debugger.event-handler", EventHandlerThread, this, nullptr,
+ g_debugger_event_thread_stack_bytes);
+
+ // Make sure DefaultEventHandler() is running and listening to events before
+ // we return
+ // from this function. We are only listening for events of type
+ // eBroadcastBitEventThreadIsListening so we don't need to check the event,
+ // we just need
+ // to wait an infinite amount of time for it (nullptr timeout as the first
+ // parameter)
+ lldb::EventSP event_sp;
+ listener_sp->GetEvent(event_sp, llvm::None);
+ }
+ return m_event_handler_thread.IsJoinable();
+}
+
+void Debugger::StopEventHandlerThread() {
+ if (m_event_handler_thread.IsJoinable()) {
+ GetCommandInterpreter().BroadcastEvent(
+ CommandInterpreter::eBroadcastBitQuitCommandReceived);
+ m_event_handler_thread.Join(nullptr);
+ }
+}
+
+lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) {
+ Debugger *debugger = (Debugger *)arg;
+ debugger->ExecuteIOHandlers();
+ debugger->StopEventHandlerThread();
+ return NULL;
+}
+
+bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }
+
+bool Debugger::StartIOHandlerThread() {
+ if (!m_io_handler_thread.IsJoinable())
+ m_io_handler_thread = ThreadLauncher::LaunchThread(
+ "lldb.debugger.io-handler", IOHandlerThread, this, nullptr,
+ 8 * 1024 * 1024); // Use larger 8MB stack for this thread
+ return m_io_handler_thread.IsJoinable();
+}
+
+void Debugger::StopIOHandlerThread() {
+ if (m_io_handler_thread.IsJoinable()) {
+ if (m_input_file_sp)
+ m_input_file_sp->GetFile().Close();
+ m_io_handler_thread.Join(nullptr);
+ }
}
-void
-Debugger::StopEventHandlerThread()
-{
- if (m_event_handler_thread.IsJoinable())
- {
- GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
- m_event_handler_thread.Join(nullptr);
- }
+void Debugger::JoinIOHandlerThread() {
+ if (HasIOHandlerThread()) {
+ thread_result_t result;
+ m_io_handler_thread.Join(&result);
+ m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
+ }
}
-lldb::thread_result_t
-Debugger::IOHandlerThread (lldb::thread_arg_t arg)
-{
- Debugger *debugger = (Debugger *)arg;
- debugger->ExecuteIOHandlers();
- debugger->StopEventHandlerThread();
- return NULL;
+Target *Debugger::GetDummyTarget() {
+ return m_target_list.GetDummyTarget(*this).get();
}
-bool
-Debugger::HasIOHandlerThread()
-{
- return m_io_handler_thread.IsJoinable();
-}
+Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
+ Target *target = nullptr;
+ if (!prefer_dummy) {
+ target = m_target_list.GetSelectedTarget().get();
+ if (target)
+ return target;
+ }
-bool
-Debugger::StartIOHandlerThread()
-{
- if (!m_io_handler_thread.IsJoinable())
- m_io_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.io-handler",
- IOHandlerThread,
- this,
- nullptr,
- 8*1024*1024); // Use larger 8MB stack for this thread
- return m_io_handler_thread.IsJoinable();
+ return GetDummyTarget();
}
-void
-Debugger::StopIOHandlerThread()
-{
- if (m_io_handler_thread.IsJoinable())
- {
- if (m_input_file_sp)
- m_input_file_sp->GetFile().Close();
- m_io_handler_thread.Join(nullptr);
- }
-}
+Error Debugger::RunREPL(LanguageType language, const char *repl_options) {
+ Error err;
+ FileSpec repl_executable;
-void
-Debugger::JoinIOHandlerThread()
-{
- if (HasIOHandlerThread())
- {
- thread_result_t result;
- m_io_handler_thread.Join(&result);
- m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
- }
-}
+ if (language == eLanguageTypeUnknown) {
+ std::set<LanguageType> repl_languages;
-Target *
-Debugger::GetDummyTarget()
-{
- return m_target_list.GetDummyTarget (*this).get();
-}
+ Language::GetLanguagesSupportingREPLs(repl_languages);
-Target *
-Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
-{
- Target *target = nullptr;
- if (!prefer_dummy)
- {
- target = m_target_list.GetSelectedTarget().get();
- if (target)
- return target;
+ if (repl_languages.size() == 1) {
+ language = *repl_languages.begin();
+ } else if (repl_languages.empty()) {
+ err.SetErrorStringWithFormat(
+ "LLDB isn't configured with REPL support for any languages.");
+ return err;
+ } else {
+ err.SetErrorStringWithFormat(
+ "Multiple possible REPL languages. Please specify a language.");
+ return err;
}
-
- 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.empty())
- {
- err.SetErrorStringWithFormat("LLDB isn't configured with REPL support for any languages.");
- 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
- 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));
+ 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();
-
+ 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 1e6a245261bb..7cac29491c8c 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -29,6 +29,7 @@
#include "lldb/Interpreter/OptionValue.h"
#include "lldb/Interpreter/OptionValueArray.h"
#include "lldb/Interpreter/OptionValueDictionary.h"
+#include "lldb/Interpreter/OptionValueRegex.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Interpreter/OptionValueUInt64.h"
#include "lldb/Symbol/Function.h"
@@ -45,1271 +46,1405 @@
using namespace lldb;
using namespace lldb_private;
-DisassemblerSP
-Disassembler::FindPlugin (const ArchSpec &arch, const char *flavor, const char *plugin_name)
-{
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
- arch.GetArchitectureName(),
- plugin_name);
-
- DisassemblerCreateInstance create_callback = nullptr;
-
- if (plugin_name)
- {
- ConstString const_plugin_name (plugin_name);
- create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName (const_plugin_name);
- if (create_callback)
- {
- DisassemblerSP disassembler_sp(create_callback(arch, flavor));
-
- if (disassembler_sp)
- return disassembler_sp;
- }
+DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch,
+ const char *flavor,
+ const char *plugin_name) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
+ arch.GetArchitectureName(), plugin_name);
+
+ DisassemblerCreateInstance create_callback = nullptr;
+
+ if (plugin_name) {
+ ConstString const_plugin_name(plugin_name);
+ create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName(
+ const_plugin_name);
+ if (create_callback) {
+ DisassemblerSP disassembler_sp(create_callback(arch, flavor));
+
+ if (disassembler_sp)
+ return disassembler_sp;
}
- else
- {
- for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(idx)) != nullptr; ++idx)
- {
- DisassemblerSP disassembler_sp(create_callback(arch, flavor));
-
- if (disassembler_sp)
- return disassembler_sp;
- }
+ } else {
+ for (uint32_t idx = 0;
+ (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(
+ idx)) != nullptr;
+ ++idx) {
+ DisassemblerSP disassembler_sp(create_callback(arch, flavor));
+
+ if (disassembler_sp)
+ return disassembler_sp;
}
- return DisassemblerSP();
+ }
+ return DisassemblerSP();
}
-DisassemblerSP
-Disassembler::FindPluginForTarget(const TargetSP target_sp, const ArchSpec &arch, const char *flavor, const char *plugin_name)
-{
- if (target_sp && flavor == nullptr)
- {
- // FIXME - we don't have the mechanism in place to do per-architecture settings. But since we know that for now
- // we only support flavors on x86 & x86_64,
- if (arch.GetTriple().getArch() == llvm::Triple::x86
- || arch.GetTriple().getArch() == llvm::Triple::x86_64)
- flavor = target_sp->GetDisassemblyFlavor();
- }
- return FindPlugin(arch, flavor, plugin_name);
+DisassemblerSP Disassembler::FindPluginForTarget(const TargetSP target_sp,
+ const ArchSpec &arch,
+ const char *flavor,
+ const char *plugin_name) {
+ if (target_sp && flavor == nullptr) {
+ // FIXME - we don't have the mechanism in place to do per-architecture
+ // settings. But since we know that for now
+ // we only support flavors on x86 & x86_64,
+ if (arch.GetTriple().getArch() == llvm::Triple::x86 ||
+ arch.GetTriple().getArch() == llvm::Triple::x86_64)
+ flavor = target_sp->GetDisassemblyFlavor();
+ }
+ return FindPlugin(arch, flavor, plugin_name);
}
-static void
-ResolveAddress (const ExecutionContext &exe_ctx,
- const Address &addr,
- Address &resolved_addr)
-{
- if (!addr.IsSectionOffset())
- {
- // If we weren't passed in a section offset address range,
- // try and resolve it to something
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- if (target->GetSectionLoadList().IsEmpty())
- {
- target->GetImages().ResolveFileAddress (addr.GetOffset(), resolved_addr);
- }
- else
- {
- target->GetSectionLoadList().ResolveLoadAddress (addr.GetOffset(), resolved_addr);
- }
- // We weren't able to resolve the address, just treat it as a
- // raw address
- if (resolved_addr.IsValid())
- return;
- }
+static void ResolveAddress(const ExecutionContext &exe_ctx, const Address &addr,
+ Address &resolved_addr) {
+ if (!addr.IsSectionOffset()) {
+ // If we weren't passed in a section offset address range,
+ // try and resolve it to something
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ if (target->GetSectionLoadList().IsEmpty()) {
+ target->GetImages().ResolveFileAddress(addr.GetOffset(), resolved_addr);
+ } else {
+ target->GetSectionLoadList().ResolveLoadAddress(addr.GetOffset(),
+ resolved_addr);
+ }
+ // We weren't able to resolve the address, just treat it as a
+ // raw address
+ if (resolved_addr.IsValid())
+ return;
}
- resolved_addr = addr;
+ }
+ resolved_addr = addr;
}
-size_t
-Disassembler::Disassemble(Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- SymbolContextList &sc_list,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm)
-{
- size_t success_count = 0;
- const size_t count = sc_list.GetSize();
- SymbolContext sc;
- AddressRange range;
- const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
- const bool use_inline_block_range = true;
- for (size_t i = 0; i < count; ++i)
- {
- if (!sc_list.GetContextAtIndex(i, sc))
- break;
- for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
- {
- if (Disassemble (debugger,
- arch,
- plugin_name,
- flavor,
- exe_ctx,
- range,
- num_instructions,
- num_mixed_context_lines,
- options,
- strm))
- {
- ++success_count;
- strm.EOL();
- }
- }
+size_t Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
+ const char *plugin_name, const char *flavor,
+ const ExecutionContext &exe_ctx,
+ SymbolContextList &sc_list,
+ uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines,
+ uint32_t options, Stream &strm) {
+ size_t success_count = 0;
+ const size_t count = sc_list.GetSize();
+ SymbolContext sc;
+ AddressRange range;
+ const uint32_t scope =
+ eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
+ const bool use_inline_block_range = true;
+ for (size_t i = 0; i < count; ++i) {
+ if (!sc_list.GetContextAtIndex(i, sc))
+ break;
+ for (uint32_t range_idx = 0;
+ sc.GetAddressRange(scope, range_idx, use_inline_block_range, range);
+ ++range_idx) {
+ if (Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range,
+ num_instructions, mixed_source_and_assembly,
+ num_mixed_context_lines, options, strm)) {
+ ++success_count;
+ strm.EOL();
+ }
}
- return success_count;
+ }
+ return success_count;
}
-bool
-Disassembler::Disassemble(Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- const ConstString &name,
- Module *module,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm)
-{
- SymbolContextList sc_list;
- if (name)
- {
- const bool include_symbols = true;
- const bool include_inlines = true;
- if (module)
- {
- module->FindFunctions(name,
- nullptr,
- eFunctionNameTypeAuto,
- include_symbols,
- include_inlines,
- true,
- sc_list);
- }
- else if (exe_ctx.GetTargetPtr())
- {
- exe_ctx.GetTargetPtr()->GetImages().FindFunctions (name,
- eFunctionNameTypeAuto,
- include_symbols,
- include_inlines,
- false,
- sc_list);
- }
+bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
+ const char *plugin_name, const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const ConstString &name, Module *module,
+ uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines,
+ uint32_t options, Stream &strm) {
+ SymbolContextList sc_list;
+ if (name) {
+ const bool include_symbols = true;
+ const bool include_inlines = true;
+ if (module) {
+ module->FindFunctions(name, nullptr, eFunctionNameTypeAuto,
+ include_symbols, include_inlines, true, sc_list);
+ } else if (exe_ctx.GetTargetPtr()) {
+ exe_ctx.GetTargetPtr()->GetImages().FindFunctions(
+ name, eFunctionNameTypeAuto, include_symbols, include_inlines, false,
+ sc_list);
}
-
- if (sc_list.GetSize ())
- {
- return Disassemble (debugger,
- arch,
- plugin_name,
- flavor,
- exe_ctx,
- sc_list,
- num_instructions,
- num_mixed_context_lines,
- options,
- strm);
+ }
+
+ if (sc_list.GetSize()) {
+ return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, sc_list,
+ num_instructions, mixed_source_and_assembly,
+ num_mixed_context_lines, options, strm);
+ }
+ return false;
+}
+
+lldb::DisassemblerSP Disassembler::DisassembleRange(
+ const ArchSpec &arch, const char *plugin_name, const char *flavor,
+ const ExecutionContext &exe_ctx, const AddressRange &range,
+ bool prefer_file_cache) {
+ lldb::DisassemblerSP disasm_sp;
+ if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid()) {
+ disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch,
+ flavor, plugin_name);
+
+ if (disasm_sp) {
+ size_t bytes_disassembled = disasm_sp->ParseInstructions(
+ &exe_ctx, range, nullptr, prefer_file_cache);
+ if (bytes_disassembled == 0)
+ disasm_sp.reset();
}
- return false;
+ }
+ return disasm_sp;
}
lldb::DisassemblerSP
-Disassembler::DisassembleRange(const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- const AddressRange &range,
- bool prefer_file_cache)
-{
- lldb::DisassemblerSP disasm_sp;
- if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
- {
- disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
-
- if (disasm_sp)
- {
- size_t bytes_disassembled = disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache);
- if (bytes_disassembled == 0)
- disasm_sp.reset();
- }
+Disassembler::DisassembleBytes(const ArchSpec &arch, const char *plugin_name,
+ const char *flavor, const Address &start,
+ const void *src, size_t src_len,
+ uint32_t num_instructions, bool data_from_file) {
+ lldb::DisassemblerSP disasm_sp;
+
+ if (src) {
+ disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
+
+ if (disasm_sp) {
+ DataExtractor data(src, src_len, arch.GetByteOrder(),
+ arch.GetAddressByteSize());
+
+ (void)disasm_sp->DecodeInstructions(start, data, 0, num_instructions,
+ false, data_from_file);
}
- return disasm_sp;
+ }
+
+ return disasm_sp;
}
-lldb::DisassemblerSP
-Disassembler::DisassembleBytes (const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const Address &start,
- const void *src,
- size_t src_len,
- uint32_t num_instructions,
- bool data_from_file)
-{
- lldb::DisassemblerSP disasm_sp;
-
- if (src)
- {
- disasm_sp = Disassembler::FindPlugin(arch, flavor, plugin_name);
-
- if (disasm_sp)
- {
- DataExtractor data(src, src_len, arch.GetByteOrder(), arch.GetAddressByteSize());
-
- (void)disasm_sp->DecodeInstructions (start,
- data,
- 0,
- num_instructions,
- false,
- data_from_file);
- }
+bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
+ const char *plugin_name, const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const AddressRange &disasm_range,
+ uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines,
+ uint32_t options, Stream &strm) {
+ if (disasm_range.GetByteSize()) {
+ lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget(
+ exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
+
+ if (disasm_sp) {
+ AddressRange range;
+ ResolveAddress(exe_ctx, disasm_range.GetBaseAddress(),
+ range.GetBaseAddress());
+ range.SetByteSize(disasm_range.GetByteSize());
+ const bool prefer_file_cache = false;
+ size_t bytes_disassembled = disasm_sp->ParseInstructions(
+ &exe_ctx, range, &strm, prefer_file_cache);
+ if (bytes_disassembled == 0)
+ return false;
+
+ return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx,
+ num_instructions, mixed_source_and_assembly,
+ num_mixed_context_lines, options, strm);
}
-
- return disasm_sp;
+ }
+ return false;
}
-bool
-Disassembler::Disassemble(Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- const AddressRange &disasm_range,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm)
-{
- if (disasm_range.GetByteSize())
- {
- lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
-
- if (disasm_sp)
- {
- AddressRange range;
- ResolveAddress (exe_ctx, disasm_range.GetBaseAddress(), range.GetBaseAddress());
- range.SetByteSize (disasm_range.GetByteSize());
- const bool prefer_file_cache = false;
- size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, &strm, prefer_file_cache);
- if (bytes_disassembled == 0)
- return false;
-
- return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions,
- num_mixed_context_lines, options, strm);
- }
+bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
+ const char *plugin_name, const char *flavor,
+ const ExecutionContext &exe_ctx,
+ const Address &start_address,
+ uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines,
+ uint32_t options, Stream &strm) {
+ if (num_instructions > 0) {
+ lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget(
+ exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
+ if (disasm_sp) {
+ Address addr;
+ ResolveAddress(exe_ctx, start_address, addr);
+ const bool prefer_file_cache = false;
+ size_t bytes_disassembled = disasm_sp->ParseInstructions(
+ &exe_ctx, addr, num_instructions, prefer_file_cache);
+ if (bytes_disassembled == 0)
+ return false;
+ return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx,
+ num_instructions, mixed_source_and_assembly,
+ num_mixed_context_lines, options, strm);
}
- return false;
+ }
+ return false;
}
-
-bool
-Disassembler::Disassemble(Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- const Address &start_address,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm)
-{
- if (num_instructions > 0)
- {
- lldb::DisassemblerSP disasm_sp (Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(),
- arch,
- flavor,
- plugin_name));
- if (disasm_sp)
- {
- Address addr;
- ResolveAddress (exe_ctx, start_address, addr);
- const bool prefer_file_cache = false;
- size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx,
- addr,
- num_instructions,
- prefer_file_cache);
- if (bytes_disassembled == 0)
- return false;
- return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions,
- num_mixed_context_lines, options, strm);
- }
+
+Disassembler::SourceLine
+Disassembler::GetFunctionDeclLineEntry(const SymbolContext &sc) {
+ SourceLine decl_line;
+ if (sc.function && sc.line_entry.IsValid()) {
+ LineEntry prologue_end_line = sc.line_entry;
+ FileSpec func_decl_file;
+ uint32_t func_decl_line;
+ sc.function->GetStartLineSourceInfo(func_decl_file, func_decl_line);
+ if (func_decl_file == prologue_end_line.file ||
+ func_decl_file == prologue_end_line.original_file) {
+ decl_line.file = func_decl_file;
+ decl_line.line = func_decl_line;
+ // TODO do we care about column on these entries? If so, we need to
+ // plumb that through GetStartLineSourceInfo.
+ decl_line.column = 0;
}
- return false;
+ }
+ return decl_line;
}
-bool
-Disassembler::PrintInstructions(Disassembler *disasm_ptr, Debugger &debugger, const ArchSpec &arch,
- const ExecutionContext &exe_ctx, uint32_t num_instructions,
- uint32_t num_mixed_context_lines, uint32_t options, Stream &strm)
-{
- // We got some things disassembled...
- size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
-
- if (num_instructions > 0 && num_instructions < num_instructions_found)
- num_instructions_found = num_instructions;
-
- const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
- uint32_t offset = 0;
- SymbolContext sc;
- SymbolContext prev_sc;
- AddressRange sc_range;
- const Address *pc_addr_ptr = nullptr;
- StackFrame *frame = exe_ctx.GetFramePtr();
-
- TargetSP target_sp (exe_ctx.GetTargetSP());
- SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
-
- if (frame)
- {
- pc_addr_ptr = &frame->GetFrameCodeAddress();
+void Disassembler::AddLineToSourceLineTables(
+ SourceLine &line,
+ std::map<FileSpec, std::set<uint32_t>> &source_lines_seen) {
+ if (line.IsValid()) {
+ auto source_lines_seen_pos = source_lines_seen.find(line.file);
+ if (source_lines_seen_pos == source_lines_seen.end()) {
+ std::set<uint32_t> lines;
+ lines.insert(line.line);
+ source_lines_seen.emplace(line.file, lines);
+ } else {
+ source_lines_seen_pos->second.insert(line.line);
}
- const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
- const bool use_inline_block_range = false;
-
- const FormatEntity::Entry *disassembly_format = nullptr;
- FormatEntity::Entry format;
- if (exe_ctx.HasTargetScope())
- {
- disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
+ }
+}
+
+bool Disassembler::ElideMixedSourceAndDisassemblyLine(
+ const ExecutionContext &exe_ctx, const SymbolContext &sc,
+ SourceLine &line) {
+
+ // TODO: should we also check target.process.thread.step-avoid-libraries ?
+
+ const RegularExpression *avoid_regex = nullptr;
+
+ // Skip any line #0 entries - they are implementation details
+ if (line.line == 0)
+ return false;
+
+ ThreadSP thread_sp = exe_ctx.GetThreadSP();
+ if (thread_sp) {
+ avoid_regex = thread_sp->GetSymbolsToAvoidRegexp();
+ } else {
+ TargetSP target_sp = exe_ctx.GetTargetSP();
+ if (target_sp) {
+ Error error;
+ OptionValueSP value_sp = target_sp->GetDebugger().GetPropertyValue(
+ &exe_ctx, "target.process.thread.step-avoid-regexp", false, error);
+ if (value_sp && value_sp->GetType() == OptionValue::eTypeRegex) {
+ OptionValueRegex *re = value_sp->GetAsRegex();
+ if (re) {
+ avoid_regex = re->GetCurrentValue();
+ }
+ }
}
- else
- {
- FormatEntity::Parse("${addr}: ", format);
- disassembly_format = &format;
+ }
+ if (avoid_regex && sc.symbol != nullptr) {
+ const char *function_name =
+ sc.GetFunctionName(Mangled::ePreferDemangledWithoutArguments)
+ .GetCString();
+ if (function_name) {
+ RegularExpression::Match regex_match(1);
+ if (avoid_regex->Execute(function_name, &regex_match)) {
+ // skip this source line
+ return true;
+ }
}
+ }
+ // don't skip this source line
+ return false;
+}
- // First pass: step through the list of instructions,
- // find how long the initial addresses strings are, insert padding
- // in the second pass so the opcodes all line up nicely.
- size_t address_text_size = 0;
- for (size_t i = 0; i < num_instructions_found; ++i)
- {
- Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
- if (inst)
- {
- const Address &addr = inst->GetAddress();
- ModuleSP module_sp (addr.GetModule());
- if (module_sp)
- {
- const uint32_t resolve_mask = eSymbolContextFunction | eSymbolContextSymbol;
- uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc);
- if (resolved_mask)
- {
- StreamString strmstr;
- Debugger::FormatDisassemblerAddress(disassembly_format, &sc, nullptr, &exe_ctx, &addr, strmstr);
- size_t cur_line = strmstr.GetSizeOfLastLine();
- if (cur_line > address_text_size)
- address_text_size = cur_line;
- }
- sc.Clear(false);
+bool Disassembler::PrintInstructions(Disassembler *disasm_ptr,
+ Debugger &debugger, const ArchSpec &arch,
+ const ExecutionContext &exe_ctx,
+ uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines,
+ uint32_t options, Stream &strm) {
+ // We got some things disassembled...
+ size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
+
+ if (num_instructions > 0 && num_instructions < num_instructions_found)
+ num_instructions_found = num_instructions;
+
+ const uint32_t max_opcode_byte_size =
+ disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize();
+ SymbolContext sc;
+ SymbolContext prev_sc;
+ AddressRange current_source_line_range;
+ const Address *pc_addr_ptr = nullptr;
+ StackFrame *frame = exe_ctx.GetFramePtr();
+
+ TargetSP target_sp(exe_ctx.GetTargetSP());
+ SourceManager &source_manager =
+ target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
+
+ if (frame) {
+ pc_addr_ptr = &frame->GetFrameCodeAddress();
+ }
+ const uint32_t scope =
+ eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
+ const bool use_inline_block_range = false;
+
+ const FormatEntity::Entry *disassembly_format = nullptr;
+ FormatEntity::Entry format;
+ if (exe_ctx.HasTargetScope()) {
+ disassembly_format =
+ exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat();
+ } else {
+ FormatEntity::Parse("${addr}: ", format);
+ disassembly_format = &format;
+ }
+
+ // First pass: step through the list of instructions,
+ // find how long the initial addresses strings are, insert padding
+ // in the second pass so the opcodes all line up nicely.
+
+ // Also build up the source line mapping if this is mixed source & assembly
+ // mode.
+ // Calculate the source line for each assembly instruction (eliding inlined
+ // functions
+ // which the user wants to skip).
+
+ std::map<FileSpec, std::set<uint32_t>> source_lines_seen;
+ Symbol *previous_symbol = nullptr;
+
+ size_t address_text_size = 0;
+ for (size_t i = 0; i < num_instructions_found; ++i) {
+ Instruction *inst =
+ disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get();
+ if (inst) {
+ const Address &addr = inst->GetAddress();
+ ModuleSP module_sp(addr.GetModule());
+ if (module_sp) {
+ const uint32_t resolve_mask = eSymbolContextFunction |
+ eSymbolContextSymbol |
+ eSymbolContextLineEntry;
+ uint32_t resolved_mask =
+ module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc);
+ if (resolved_mask) {
+ StreamString strmstr;
+ Debugger::FormatDisassemblerAddress(disassembly_format, &sc, nullptr,
+ &exe_ctx, &addr, strmstr);
+ size_t cur_line = strmstr.GetSizeOfLastLine();
+ if (cur_line > address_text_size)
+ address_text_size = cur_line;
+
+ // Add entries to our "source_lines_seen" map+set which list which
+ // sources lines occur in this disassembly session. We will print
+ // lines of context around a source line, but we don't want to print
+ // a source line that has a line table entry of its own - we'll leave
+ // that source line to be printed when it actually occurs in the
+ // disassembly.
+
+ if (mixed_source_and_assembly && sc.line_entry.IsValid()) {
+ if (sc.symbol != previous_symbol) {
+ SourceLine decl_line = GetFunctionDeclLineEntry(sc);
+ if (ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, decl_line) ==
+ false)
+ AddLineToSourceLineTables(decl_line, source_lines_seen);
+ }
+ if (sc.line_entry.IsValid()) {
+ SourceLine this_line;
+ this_line.file = sc.line_entry.file;
+ this_line.line = sc.line_entry.line;
+ this_line.column = sc.line_entry.column;
+ if (ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, this_line) ==
+ false)
+ AddLineToSourceLineTables(this_line, source_lines_seen);
}
+ }
}
+ sc.Clear(false);
+ }
}
+ }
+
+ previous_symbol = nullptr;
+ SourceLine previous_line;
+ for (size_t i = 0; i < num_instructions_found; ++i) {
+ Instruction *inst =
+ disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get();
+
+ if (inst) {
+ const Address &addr = inst->GetAddress();
+ const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
+ SourceLinesToDisplay source_lines_to_display;
+
+ prev_sc = sc;
+
+ ModuleSP module_sp(addr.GetModule());
+ if (module_sp) {
+ uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(
+ addr, eSymbolContextEverything, sc);
+ if (resolved_mask) {
+ if (mixed_source_and_assembly) {
+
+ // If we've started a new function (non-inlined), print all of the
+ // source lines from the
+ // function declaration until the first line table entry - typically
+ // the opening curly brace of
+ // the function.
+ if (previous_symbol != sc.symbol) {
+ // The default disassembly format puts an extra blank line between
+ // functions - so
+ // when we're displaying the source context for a function, we
+ // don't want to add
+ // a blank line after the source context or we'll end up with two
+ // of them.
+ if (previous_symbol != nullptr)
+ source_lines_to_display.print_source_context_end_eol = false;
+
+ previous_symbol = sc.symbol;
+ if (sc.function && sc.line_entry.IsValid()) {
+ LineEntry prologue_end_line = sc.line_entry;
+ if (ElideMixedSourceAndDisassemblyLine(
+ exe_ctx, sc, prologue_end_line) == false) {
+ FileSpec func_decl_file;
+ uint32_t func_decl_line;
+ sc.function->GetStartLineSourceInfo(func_decl_file,
+ func_decl_line);
+ if (func_decl_file == prologue_end_line.file ||
+ func_decl_file == prologue_end_line.original_file) {
+ // Add all the lines between the function declaration
+ // and the first non-prologue source line to the list
+ // of lines to print.
+ for (uint32_t lineno = func_decl_line;
+ lineno <= prologue_end_line.line; lineno++) {
+ SourceLine this_line;
+ this_line.file = func_decl_file;
+ this_line.line = lineno;
+ source_lines_to_display.lines.push_back(this_line);
+ }
+ // Mark the last line as the "current" one. Usually
+ // this is the open curly brace.
+ if (source_lines_to_display.lines.size() > 0)
+ source_lines_to_display.current_source_line =
+ source_lines_to_display.lines.size() - 1;
+ }
+ }
+ }
+ sc.GetAddressRange(scope, 0, use_inline_block_range,
+ current_source_line_range);
+ }
- for (size_t i = 0; i < num_instructions_found; ++i)
- {
- Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
- if (inst)
- {
- const Address &addr = inst->GetAddress();
- const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
-
- prev_sc = sc;
-
- ModuleSP module_sp (addr.GetModule());
- if (module_sp)
- {
- uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
- if (resolved_mask)
- {
- if (num_mixed_context_lines)
- {
- if (!sc_range.ContainsFileAddress (addr))
- {
- sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
-
- if (sc != prev_sc)
- {
- if (offset != 0)
- strm.EOL();
-
- sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false, true);
- strm.EOL();
-
- if (sc.comp_unit && sc.line_entry.IsValid())
- {
- source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
- sc.line_entry.line,
- num_mixed_context_lines,
- num_mixed_context_lines,
- ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
- &strm);
- }
- }
+ // If we've left a previous source line's address range, print a new
+ // source line
+ if (!current_source_line_range.ContainsFileAddress(addr)) {
+ sc.GetAddressRange(scope, 0, use_inline_block_range,
+ current_source_line_range);
+
+ if (sc != prev_sc && sc.comp_unit && sc.line_entry.IsValid()) {
+ SourceLine this_line;
+ this_line.file = sc.line_entry.file;
+ this_line.line = sc.line_entry.line;
+
+ if (ElideMixedSourceAndDisassemblyLine(exe_ctx, sc,
+ this_line) == false) {
+ // Only print this source line if it is different from the
+ // last source line we printed. There may have been inlined
+ // functions between these lines that we elided, resulting in
+ // the same line being printed twice in a row for a contiguous
+ // block of assembly instructions.
+ if (this_line != previous_line) {
+
+ std::vector<uint32_t> previous_lines;
+ for (uint32_t i = 0;
+ i < num_mixed_context_lines &&
+ (this_line.line - num_mixed_context_lines) > 0;
+ i++) {
+ uint32_t line =
+ this_line.line - num_mixed_context_lines + i;
+ auto pos = source_lines_seen.find(this_line.file);
+ if (pos != source_lines_seen.end()) {
+ if (pos->second.count(line) == 1) {
+ previous_lines.clear();
+ } else {
+ previous_lines.push_back(line);
}
+ }
}
+ for (size_t i = 0; i < previous_lines.size(); i++) {
+ SourceLine previous_line;
+ previous_line.file = this_line.file;
+ previous_line.line = previous_lines[i];
+ auto pos = source_lines_seen.find(previous_line.file);
+ if (pos != source_lines_seen.end()) {
+ pos->second.insert(previous_line.line);
+ }
+ source_lines_to_display.lines.push_back(previous_line);
+ }
+
+ source_lines_to_display.lines.push_back(this_line);
+ source_lines_to_display.current_source_line =
+ source_lines_to_display.lines.size() - 1;
+
+ for (uint32_t i = 0; i < num_mixed_context_lines; i++) {
+ SourceLine next_line;
+ next_line.file = this_line.file;
+ next_line.line = this_line.line + i + 1;
+ auto pos = source_lines_seen.find(next_line.file);
+ if (pos != source_lines_seen.end()) {
+ if (pos->second.count(next_line.line) == 1)
+ break;
+ pos->second.insert(next_line.line);
+ }
+ source_lines_to_display.lines.push_back(next_line);
+ }
+ }
+ previous_line = this_line;
}
- else
- {
- sc.Clear(true);
- }
+ }
}
-
- const bool show_bytes = (options & eOptionShowBytes) != 0;
- inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, nullptr, address_text_size);
- strm.EOL();
+ }
+ } else {
+ sc.Clear(true);
}
- else
- {
- break;
+ }
+
+ if (source_lines_to_display.lines.size() > 0) {
+ strm.EOL();
+ for (size_t idx = 0; idx < source_lines_to_display.lines.size();
+ idx++) {
+ SourceLine ln = source_lines_to_display.lines[idx];
+ const char *line_highlight = "";
+ if (inst_is_at_pc && (options & eOptionMarkPCSourceLine)) {
+ line_highlight = "->";
+ } else if (idx == source_lines_to_display.current_source_line) {
+ line_highlight = "**";
+ }
+ source_manager.DisplaySourceLinesWithLineNumbers(
+ ln.file, ln.line, ln.column, 0, 0, line_highlight, &strm);
}
+ if (source_lines_to_display.print_source_context_end_eol)
+ strm.EOL();
+ }
+
+ const bool show_bytes = (options & eOptionShowBytes) != 0;
+ inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc,
+ &prev_sc, nullptr, address_text_size);
+ strm.EOL();
+ } else {
+ break;
}
-
- return true;
-}
+ }
-bool
-Disassembler::Disassemble(Debugger &debugger,
- const ArchSpec &arch,
- const char *plugin_name,
- const char *flavor,
- const ExecutionContext &exe_ctx,
- uint32_t num_instructions,
- uint32_t num_mixed_context_lines,
- uint32_t options,
- Stream &strm)
-{
- AddressRange range;
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame)
- {
- SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
- if (sc.function)
- {
- range = sc.function->GetAddressRange();
- }
- else if (sc.symbol && sc.symbol->ValueIsAddress())
- {
- range.GetBaseAddress() = sc.symbol->GetAddressRef();
- range.SetByteSize (sc.symbol->GetByteSize());
- }
- else
- {
- range.GetBaseAddress() = frame->GetFrameCodeAddress();
- }
+ return true;
+}
- if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
- range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
+bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
+ const char *plugin_name, const char *flavor,
+ const ExecutionContext &exe_ctx,
+ uint32_t num_instructions,
+ bool mixed_source_and_assembly,
+ uint32_t num_mixed_context_lines,
+ uint32_t options, Stream &strm) {
+ AddressRange range;
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame) {
+ SymbolContext sc(
+ frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
+ if (sc.function) {
+ range = sc.function->GetAddressRange();
+ } else if (sc.symbol && sc.symbol->ValueIsAddress()) {
+ range.GetBaseAddress() = sc.symbol->GetAddressRef();
+ range.SetByteSize(sc.symbol->GetByteSize());
+ } else {
+ range.GetBaseAddress() = frame->GetFrameCodeAddress();
}
- return Disassemble (debugger,
- arch,
- plugin_name,
- flavor,
- exe_ctx,
- range,
- num_instructions,
- num_mixed_context_lines,
- options,
- strm);
-}
+ if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
+ range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
+ }
-Instruction::Instruction(const Address &address, AddressClass addr_class) :
- m_address (address),
- m_address_class (addr_class),
- m_opcode(),
- m_calculated_strings(false)
-{
+ return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range,
+ num_instructions, mixed_source_and_assembly,
+ num_mixed_context_lines, options, strm);
}
+Instruction::Instruction(const Address &address, AddressClass addr_class)
+ : m_address(address), m_address_class(addr_class), m_opcode(),
+ m_calculated_strings(false) {}
+
Instruction::~Instruction() = default;
-AddressClass
-Instruction::GetAddressClass ()
-{
- if (m_address_class == eAddressClassInvalid)
- m_address_class = m_address.GetAddressClass();
- return m_address_class;
+AddressClass Instruction::GetAddressClass() {
+ if (m_address_class == eAddressClassInvalid)
+ m_address_class = m_address.GetAddressClass();
+ return m_address_class;
}
-void
-Instruction::Dump (lldb_private::Stream *s,
- uint32_t max_opcode_byte_size,
- bool show_address,
- bool show_bytes,
- const ExecutionContext* exe_ctx,
- const SymbolContext *sym_ctx,
- const SymbolContext *prev_sym_ctx,
- const FormatEntity::Entry *disassembly_addr_format,
- size_t max_address_text_size)
-{
- size_t opcode_column_width = 7;
- const size_t operand_column_width = 25;
-
- CalculateMnemonicOperandsAndCommentIfNeeded (exe_ctx);
-
- StreamString ss;
-
- if (show_address)
- {
- Debugger::FormatDisassemblerAddress (disassembly_addr_format, sym_ctx, prev_sym_ctx, exe_ctx, &m_address, ss);
- ss.FillLastLineToColumn (max_address_text_size, ' ');
- }
-
- if (show_bytes)
- {
- if (m_opcode.GetType() == Opcode::eTypeBytes)
- {
- // x86_64 and i386 are the only ones that use bytes right now so
- // pad out the byte dump to be able to always show 15 bytes (3 chars each)
- // plus a space
- if (max_opcode_byte_size > 0)
- m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
- else
- m_opcode.Dump (&ss, 15 * 3 + 1);
- }
- else
- {
- // Else, we have ARM or MIPS which can show up to a uint32_t
- // 0x00000000 (10 spaces) plus two for padding...
- if (max_opcode_byte_size > 0)
- m_opcode.Dump (&ss, max_opcode_byte_size * 3 + 1);
- else
- m_opcode.Dump (&ss, 12);
- }
- }
-
- const size_t opcode_pos = ss.GetSizeOfLastLine();
-
- // The default opcode size of 7 characters is plenty for most architectures
- // but some like arm can pull out the occasional vqrshrun.s16. We won't get
- // consistent column spacing in these cases, unfortunately.
- if (m_opcode_name.length() >= opcode_column_width)
- {
- opcode_column_width = m_opcode_name.length() + 1;
- }
-
- ss.PutCString (m_opcode_name.c_str());
- ss.FillLastLineToColumn (opcode_pos + opcode_column_width, ' ');
- ss.PutCString (m_mnemonics.c_str());
-
- if (!m_comment.empty())
- {
- ss.FillLastLineToColumn (opcode_pos + opcode_column_width + operand_column_width, ' ');
- ss.PutCString (" ; ");
- ss.PutCString (m_comment.c_str());
+void Instruction::Dump(lldb_private::Stream *s, uint32_t max_opcode_byte_size,
+ bool show_address, bool show_bytes,
+ const ExecutionContext *exe_ctx,
+ const SymbolContext *sym_ctx,
+ const SymbolContext *prev_sym_ctx,
+ const FormatEntity::Entry *disassembly_addr_format,
+ size_t max_address_text_size) {
+ size_t opcode_column_width = 7;
+ const size_t operand_column_width = 25;
+
+ CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx);
+
+ StreamString ss;
+
+ if (show_address) {
+ Debugger::FormatDisassemblerAddress(disassembly_addr_format, sym_ctx,
+ prev_sym_ctx, exe_ctx, &m_address, ss);
+ ss.FillLastLineToColumn(max_address_text_size, ' ');
+ }
+
+ if (show_bytes) {
+ if (m_opcode.GetType() == Opcode::eTypeBytes) {
+ // x86_64 and i386 are the only ones that use bytes right now so
+ // pad out the byte dump to be able to always show 15 bytes (3 chars each)
+ // plus a space
+ if (max_opcode_byte_size > 0)
+ m_opcode.Dump(&ss, max_opcode_byte_size * 3 + 1);
+ else
+ m_opcode.Dump(&ss, 15 * 3 + 1);
+ } else {
+ // Else, we have ARM or MIPS which can show up to a uint32_t
+ // 0x00000000 (10 spaces) plus two for padding...
+ if (max_opcode_byte_size > 0)
+ m_opcode.Dump(&ss, max_opcode_byte_size * 3 + 1);
+ else
+ m_opcode.Dump(&ss, 12);
}
- s->Write (ss.GetData(), ss.GetSize());
+ }
+
+ const size_t opcode_pos = ss.GetSizeOfLastLine();
+
+ // The default opcode size of 7 characters is plenty for most architectures
+ // but some like arm can pull out the occasional vqrshrun.s16. We won't get
+ // consistent column spacing in these cases, unfortunately.
+ if (m_opcode_name.length() >= opcode_column_width) {
+ opcode_column_width = m_opcode_name.length() + 1;
+ }
+
+ ss.PutCString(m_opcode_name);
+ ss.FillLastLineToColumn(opcode_pos + opcode_column_width, ' ');
+ ss.PutCString(m_mnemonics);
+
+ if (!m_comment.empty()) {
+ ss.FillLastLineToColumn(
+ opcode_pos + opcode_column_width + operand_column_width, ' ');
+ ss.PutCString(" ; ");
+ ss.PutCString(m_comment);
+ }
+ s->PutCString(ss.GetString());
}
-bool
-Instruction::DumpEmulation (const ArchSpec &arch)
-{
- std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
- if (insn_emulator_ap)
- {
- insn_emulator_ap->SetInstruction(GetOpcode(), GetAddress(), nullptr);
- return insn_emulator_ap->EvaluateInstruction (0);
- }
+bool Instruction::DumpEmulation(const ArchSpec &arch) {
+ std::unique_ptr<EmulateInstruction> insn_emulator_ap(
+ EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
+ if (insn_emulator_ap) {
+ insn_emulator_ap->SetInstruction(GetOpcode(), GetAddress(), nullptr);
+ return insn_emulator_ap->EvaluateInstruction(0);
+ }
- return false;
+ return false;
}
-bool
-Instruction::HasDelaySlot ()
-{
- // Default is false.
- return false;
+bool Instruction::HasDelaySlot() {
+ // Default is false.
+ return false;
}
-OptionValueSP
-Instruction::ReadArray (FILE *in_file, Stream *out_stream, OptionValue::Type data_type)
-{
- bool done = false;
- char buffer[1024];
-
- OptionValueSP option_value_sp (new OptionValueArray (1u << data_type));
-
- int idx = 0;
- while (!done)
- {
- if (!fgets (buffer, 1023, in_file))
- {
- out_stream->Printf ("Instruction::ReadArray: Error reading file (fgets).\n");
- option_value_sp.reset ();
- return option_value_sp;
- }
+OptionValueSP Instruction::ReadArray(FILE *in_file, Stream *out_stream,
+ OptionValue::Type data_type) {
+ bool done = false;
+ char buffer[1024];
- std::string line (buffer);
-
- size_t len = line.size();
- if (line[len-1] == '\n')
- {
- line[len-1] = '\0';
- line.resize (len-1);
- }
+ OptionValueSP option_value_sp(new OptionValueArray(1u << data_type));
- if ((line.size() == 1) && line[0] == ']')
- {
- done = true;
- line.clear();
- }
+ int idx = 0;
+ while (!done) {
+ if (!fgets(buffer, 1023, in_file)) {
+ out_stream->Printf(
+ "Instruction::ReadArray: Error reading file (fgets).\n");
+ option_value_sp.reset();
+ return option_value_sp;
+ }
- if (!line.empty())
- {
- std::string value;
- static RegularExpression g_reg_exp ("^[ \t]*([^ \t]+)[ \t]*$");
- RegularExpression::Match regex_match(1);
- bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
- if (reg_exp_success)
- regex_match.GetMatchAtIndex (line.c_str(), 1, value);
- else
- value = line;
-
- OptionValueSP data_value_sp;
- switch (data_type)
- {
- case OptionValue::eTypeUInt64:
- data_value_sp.reset (new OptionValueUInt64 (0, 0));
- data_value_sp->SetValueFromString (value);
- break;
- // Other types can be added later as needed.
- default:
- data_value_sp.reset (new OptionValueString (value.c_str(), ""));
- break;
- }
+ std::string line(buffer);
- option_value_sp->GetAsArray()->InsertValue (idx, data_value_sp);
- ++idx;
- }
+ size_t len = line.size();
+ if (line[len - 1] == '\n') {
+ line[len - 1] = '\0';
+ line.resize(len - 1);
}
-
- return option_value_sp;
-}
-OptionValueSP
-Instruction::ReadDictionary (FILE *in_file, Stream *out_stream)
-{
- bool done = false;
- char buffer[1024];
-
- OptionValueSP option_value_sp (new OptionValueDictionary());
- static ConstString encoding_key ("data_encoding");
- OptionValue::Type data_type = OptionValue::eTypeInvalid;
-
-
- while (!done)
- {
- // Read the next line in the file
- if (!fgets (buffer, 1023, in_file))
- {
- out_stream->Printf ("Instruction::ReadDictionary: Error reading file (fgets).\n");
- option_value_sp.reset ();
- return option_value_sp;
- }
-
- // Check to see if the line contains the end-of-dictionary marker ("}")
- std::string line (buffer);
-
- size_t len = line.size();
- if (line[len-1] == '\n')
- {
- line[len-1] = '\0';
- line.resize (len-1);
- }
-
- if ((line.size() == 1) && (line[0] == '}'))
- {
- done = true;
- line.clear();
- }
-
- // Try to find a key-value pair in the current line and add it to the dictionary.
- if (!line.empty())
- {
- static RegularExpression g_reg_exp ("^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$");
- RegularExpression::Match regex_match(2);
-
- bool reg_exp_success = g_reg_exp.Execute (line.c_str(), &regex_match);
- std::string key;
- std::string value;
- if (reg_exp_success)
- {
- regex_match.GetMatchAtIndex (line.c_str(), 1, key);
- regex_match.GetMatchAtIndex (line.c_str(), 2, value);
- }
- else
- {
- out_stream->Printf ("Instruction::ReadDictionary: Failure executing regular expression.\n");
- option_value_sp.reset();
- return option_value_sp;
- }
-
- ConstString const_key (key.c_str());
- // Check value to see if it's the start of an array or dictionary.
-
- lldb::OptionValueSP value_sp;
- assert (value.empty() == false);
- assert (key.empty() == false);
-
- if (value[0] == '{')
- {
- assert (value.size() == 1);
- // value is a dictionary
- value_sp = ReadDictionary (in_file, out_stream);
- if (!value_sp)
- {
- option_value_sp.reset ();
- return option_value_sp;
- }
- }
- else if (value[0] == '[')
- {
- assert (value.size() == 1);
- // value is an array
- value_sp = ReadArray (in_file, out_stream, data_type);
- if (!value_sp)
- {
- option_value_sp.reset ();
- return option_value_sp;
- }
- // We've used the data_type to read an array; re-set the type to Invalid
- data_type = OptionValue::eTypeInvalid;
- }
- else if ((value[0] == '0') && (value[1] == 'x'))
- {
- value_sp.reset (new OptionValueUInt64 (0, 0));
- value_sp->SetValueFromString (value);
- }
- else
- {
- size_t len = value.size();
- if ((value[0] == '"') && (value[len-1] == '"'))
- value = value.substr (1, len-2);
- value_sp.reset (new OptionValueString (value.c_str(), ""));
- }
+ if ((line.size() == 1) && line[0] == ']') {
+ done = true;
+ line.clear();
+ }
- if (const_key == encoding_key)
- {
- // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data indicating the
- // data type of an upcoming array (usually the next bit of data to be read in).
- if (strcmp (value.c_str(), "uint32_t") == 0)
- data_type = OptionValue::eTypeUInt64;
- }
- else
- option_value_sp->GetAsDictionary()->SetValueForKey (const_key, value_sp, false);
- }
+ if (!line.empty()) {
+ std::string value;
+ static RegularExpression g_reg_exp(
+ llvm::StringRef("^[ \t]*([^ \t]+)[ \t]*$"));
+ RegularExpression::Match regex_match(1);
+ bool reg_exp_success = g_reg_exp.Execute(line, &regex_match);
+ if (reg_exp_success)
+ regex_match.GetMatchAtIndex(line.c_str(), 1, value);
+ else
+ value = line;
+
+ OptionValueSP data_value_sp;
+ switch (data_type) {
+ case OptionValue::eTypeUInt64:
+ data_value_sp.reset(new OptionValueUInt64(0, 0));
+ data_value_sp->SetValueFromString(value);
+ break;
+ // Other types can be added later as needed.
+ default:
+ data_value_sp.reset(new OptionValueString(value.c_str(), ""));
+ break;
+ }
+
+ option_value_sp->GetAsArray()->InsertValue(idx, data_value_sp);
+ ++idx;
}
-
- return option_value_sp;
-}
+ }
-bool
-Instruction::TestEmulation (Stream *out_stream, const char *file_name)
-{
- if (!out_stream)
- return false;
+ return option_value_sp;
+}
- if (!file_name)
- {
- out_stream->Printf ("Instruction::TestEmulation: Missing file_name.");
- return false;
+OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) {
+ bool done = false;
+ char buffer[1024];
+
+ OptionValueSP option_value_sp(new OptionValueDictionary());
+ static ConstString encoding_key("data_encoding");
+ OptionValue::Type data_type = OptionValue::eTypeInvalid;
+
+ while (!done) {
+ // Read the next line in the file
+ if (!fgets(buffer, 1023, in_file)) {
+ out_stream->Printf(
+ "Instruction::ReadDictionary: Error reading file (fgets).\n");
+ option_value_sp.reset();
+ return option_value_sp;
}
- FILE *test_file = FileSystem::Fopen(file_name, "r");
- if (!test_file)
- {
- out_stream->Printf ("Instruction::TestEmulation: Attempt to open test file failed.");
- return false;
+
+ // Check to see if the line contains the end-of-dictionary marker ("}")
+ std::string line(buffer);
+
+ size_t len = line.size();
+ if (line[len - 1] == '\n') {
+ line[len - 1] = '\0';
+ line.resize(len - 1);
}
- char buffer[256];
- if (!fgets (buffer, 255, test_file))
- {
- out_stream->Printf ("Instruction::TestEmulation: Error reading first line of test file.\n");
- fclose (test_file);
- return false;
+ if ((line.size() == 1) && (line[0] == '}')) {
+ done = true;
+ line.clear();
}
-
- if (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
- {
- out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
- fclose (test_file);
- return false;
+
+ // Try to find a key-value pair in the current line and add it to the
+ // dictionary.
+ if (!line.empty()) {
+ static RegularExpression g_reg_exp(llvm::StringRef(
+ "^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"));
+ RegularExpression::Match regex_match(2);
+
+ bool reg_exp_success = g_reg_exp.Execute(line, &regex_match);
+ std::string key;
+ std::string value;
+ if (reg_exp_success) {
+ regex_match.GetMatchAtIndex(line.c_str(), 1, key);
+ regex_match.GetMatchAtIndex(line.c_str(), 2, value);
+ } else {
+ out_stream->Printf("Instruction::ReadDictionary: Failure executing "
+ "regular expression.\n");
+ option_value_sp.reset();
+ return option_value_sp;
+ }
+
+ ConstString const_key(key.c_str());
+ // Check value to see if it's the start of an array or dictionary.
+
+ lldb::OptionValueSP value_sp;
+ assert(value.empty() == false);
+ assert(key.empty() == false);
+
+ if (value[0] == '{') {
+ assert(value.size() == 1);
+ // value is a dictionary
+ value_sp = ReadDictionary(in_file, out_stream);
+ if (!value_sp) {
+ option_value_sp.reset();
+ return option_value_sp;
+ }
+ } else if (value[0] == '[') {
+ assert(value.size() == 1);
+ // value is an array
+ value_sp = ReadArray(in_file, out_stream, data_type);
+ if (!value_sp) {
+ option_value_sp.reset();
+ return option_value_sp;
+ }
+ // We've used the data_type to read an array; re-set the type to Invalid
+ data_type = OptionValue::eTypeInvalid;
+ } else if ((value[0] == '0') && (value[1] == 'x')) {
+ value_sp.reset(new OptionValueUInt64(0, 0));
+ value_sp->SetValueFromString(value);
+ } else {
+ size_t len = value.size();
+ if ((value[0] == '"') && (value[len - 1] == '"'))
+ value = value.substr(1, len - 2);
+ value_sp.reset(new OptionValueString(value.c_str(), ""));
+ }
+
+ if (const_key == encoding_key) {
+ // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data
+ // indicating the
+ // data type of an upcoming array (usually the next bit of data to be
+ // read in).
+ if (strcmp(value.c_str(), "uint32_t") == 0)
+ data_type = OptionValue::eTypeUInt64;
+ } else
+ option_value_sp->GetAsDictionary()->SetValueForKey(const_key, value_sp,
+ false);
}
+ }
- // Read all the test information from the test file into an OptionValueDictionary.
+ return option_value_sp;
+}
- OptionValueSP data_dictionary_sp (ReadDictionary (test_file, out_stream));
- if (!data_dictionary_sp)
- {
- out_stream->Printf ("Instruction::TestEmulation: Error reading Dictionary Object.\n");
- fclose (test_file);
- return false;
- }
+bool Instruction::TestEmulation(Stream *out_stream, const char *file_name) {
+ if (!out_stream)
+ return false;
- fclose (test_file);
+ if (!file_name) {
+ out_stream->Printf("Instruction::TestEmulation: Missing file_name.");
+ return false;
+ }
+ FILE *test_file = FileSystem::Fopen(file_name, "r");
+ if (!test_file) {
+ out_stream->Printf(
+ "Instruction::TestEmulation: Attempt to open test file failed.");
+ return false;
+ }
- OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary();
- static ConstString description_key ("assembly_string");
- static ConstString triple_key ("triple");
+ char buffer[256];
+ if (!fgets(buffer, 255, test_file)) {
+ out_stream->Printf(
+ "Instruction::TestEmulation: Error reading first line of test file.\n");
+ fclose(test_file);
+ return false;
+ }
- OptionValueSP value_sp = data_dictionary->GetValueForKey (description_key);
-
- if (!value_sp)
- {
- out_stream->Printf ("Instruction::TestEmulation: Test file does not contain description string.\n");
- return false;
- }
+ if (strncmp(buffer, "InstructionEmulationState={", 27) != 0) {
+ out_stream->Printf("Instructin::TestEmulation: Test file does not contain "
+ "emulation state dictionary\n");
+ fclose(test_file);
+ return false;
+ }
- SetDescription (value_sp->GetStringValue());
+ // Read all the test information from the test file into an
+ // OptionValueDictionary.
- value_sp = data_dictionary->GetValueForKey (triple_key);
- if (!value_sp)
- {
- out_stream->Printf ("Instruction::TestEmulation: Test file does not contain triple.\n");
- return false;
- }
-
- ArchSpec arch;
- arch.SetTriple (llvm::Triple (value_sp->GetStringValue()));
-
- bool success = false;
- std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
- if (insn_emulator_ap)
- success = insn_emulator_ap->TestEmulation (out_stream, arch, data_dictionary);
-
- if (success)
- out_stream->Printf ("Emulation test succeeded.");
- else
- out_stream->Printf ("Emulation test failed.");
-
- return success;
-}
+ OptionValueSP data_dictionary_sp(ReadDictionary(test_file, out_stream));
+ if (!data_dictionary_sp) {
+ out_stream->Printf(
+ "Instruction::TestEmulation: Error reading Dictionary Object.\n");
+ fclose(test_file);
+ return false;
+ }
-bool
-Instruction::Emulate (const ArchSpec &arch,
- uint32_t evaluate_options,
- void *baton,
- EmulateInstruction::ReadMemoryCallback read_mem_callback,
- EmulateInstruction::WriteMemoryCallback write_mem_callback,
- EmulateInstruction::ReadRegisterCallback read_reg_callback,
- EmulateInstruction::WriteRegisterCallback write_reg_callback)
-{
- std::unique_ptr<EmulateInstruction> insn_emulator_ap(EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
- if (insn_emulator_ap)
- {
- insn_emulator_ap->SetBaton(baton);
- insn_emulator_ap->SetCallbacks(read_mem_callback, write_mem_callback, read_reg_callback, write_reg_callback);
- insn_emulator_ap->SetInstruction(GetOpcode(), GetAddress(), nullptr);
- return insn_emulator_ap->EvaluateInstruction(evaluate_options);
- }
+ fclose(test_file);
+
+ OptionValueDictionary *data_dictionary =
+ data_dictionary_sp->GetAsDictionary();
+ static ConstString description_key("assembly_string");
+ static ConstString triple_key("triple");
+
+ OptionValueSP value_sp = data_dictionary->GetValueForKey(description_key);
+ if (!value_sp) {
+ out_stream->Printf("Instruction::TestEmulation: Test file does not "
+ "contain description string.\n");
return false;
-}
+ }
-uint32_t
-Instruction::GetData (DataExtractor &data)
-{
- return m_opcode.GetData(data);
-}
+ SetDescription(value_sp->GetStringValue());
-InstructionList::InstructionList() :
- m_instructions()
-{
-}
+ value_sp = data_dictionary->GetValueForKey(triple_key);
+ if (!value_sp) {
+ out_stream->Printf(
+ "Instruction::TestEmulation: Test file does not contain triple.\n");
+ return false;
+ }
-InstructionList::~InstructionList() = default;
+ ArchSpec arch;
+ arch.SetTriple(llvm::Triple(value_sp->GetStringValue()));
-size_t
-InstructionList::GetSize() const
-{
- return m_instructions.size();
+ bool success = false;
+ std::unique_ptr<EmulateInstruction> insn_emulator_ap(
+ EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
+ if (insn_emulator_ap)
+ success =
+ insn_emulator_ap->TestEmulation(out_stream, arch, data_dictionary);
+
+ if (success)
+ out_stream->Printf("Emulation test succeeded.");
+ else
+ out_stream->Printf("Emulation test failed.");
+
+ return success;
}
-uint32_t
-InstructionList::GetMaxOpcocdeByteSize () const
-{
- uint32_t max_inst_size = 0;
- collection::const_iterator pos, end;
- for (pos = m_instructions.begin(), end = m_instructions.end();
- pos != end;
- ++pos)
- {
- uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
- if (max_inst_size < inst_size)
- max_inst_size = inst_size;
- }
- return max_inst_size;
+bool Instruction::Emulate(
+ const ArchSpec &arch, uint32_t evaluate_options, void *baton,
+ EmulateInstruction::ReadMemoryCallback read_mem_callback,
+ EmulateInstruction::WriteMemoryCallback write_mem_callback,
+ EmulateInstruction::ReadRegisterCallback read_reg_callback,
+ EmulateInstruction::WriteRegisterCallback write_reg_callback) {
+ std::unique_ptr<EmulateInstruction> insn_emulator_ap(
+ EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
+ if (insn_emulator_ap) {
+ insn_emulator_ap->SetBaton(baton);
+ insn_emulator_ap->SetCallbacks(read_mem_callback, write_mem_callback,
+ read_reg_callback, write_reg_callback);
+ insn_emulator_ap->SetInstruction(GetOpcode(), GetAddress(), nullptr);
+ return insn_emulator_ap->EvaluateInstruction(evaluate_options);
+ }
+
+ return false;
}
-InstructionSP
-InstructionList::GetInstructionAtIndex (size_t idx) const
-{
- InstructionSP inst_sp;
- if (idx < m_instructions.size())
- inst_sp = m_instructions[idx];
- return inst_sp;
+uint32_t Instruction::GetData(DataExtractor &data) {
+ return m_opcode.GetData(data);
}
-void
-InstructionList::Dump (Stream *s,
- bool show_address,
- bool show_bytes,
- const ExecutionContext* exe_ctx)
-{
- const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
- collection::const_iterator pos, begin, end;
-
- const FormatEntity::Entry *disassembly_format = nullptr;
- FormatEntity::Entry format;
- if (exe_ctx && exe_ctx->HasTargetScope())
- {
- disassembly_format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat ();
- }
- else
- {
- FormatEntity::Parse("${addr}: ", format);
- disassembly_format = &format;
- }
+InstructionList::InstructionList() : m_instructions() {}
- for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
- pos != end;
- ++pos)
- {
- if (pos != begin)
- s->EOL();
- (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx, nullptr, nullptr, disassembly_format, 0);
- }
+InstructionList::~InstructionList() = default;
+
+size_t InstructionList::GetSize() const { return m_instructions.size(); }
+
+uint32_t InstructionList::GetMaxOpcocdeByteSize() const {
+ uint32_t max_inst_size = 0;
+ collection::const_iterator pos, end;
+ for (pos = m_instructions.begin(), end = m_instructions.end(); pos != end;
+ ++pos) {
+ uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
+ if (max_inst_size < inst_size)
+ max_inst_size = inst_size;
+ }
+ return max_inst_size;
}
-void
-InstructionList::Clear()
-{
- m_instructions.clear();
+InstructionSP InstructionList::GetInstructionAtIndex(size_t idx) const {
+ InstructionSP inst_sp;
+ if (idx < m_instructions.size())
+ inst_sp = m_instructions[idx];
+ return inst_sp;
}
-void
-InstructionList::Append (lldb::InstructionSP &inst_sp)
-{
- if (inst_sp)
- m_instructions.push_back(inst_sp);
+void InstructionList::Dump(Stream *s, bool show_address, bool show_bytes,
+ const ExecutionContext *exe_ctx) {
+ const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
+ collection::const_iterator pos, begin, end;
+
+ const FormatEntity::Entry *disassembly_format = nullptr;
+ FormatEntity::Entry format;
+ if (exe_ctx && exe_ctx->HasTargetScope()) {
+ disassembly_format =
+ exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
+ } else {
+ FormatEntity::Parse("${addr}: ", format);
+ disassembly_format = &format;
+ }
+
+ for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
+ pos != end; ++pos) {
+ if (pos != begin)
+ s->EOL();
+ (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx,
+ nullptr, nullptr, disassembly_format, 0);
+ }
+}
+
+void InstructionList::Clear() { m_instructions.clear(); }
+
+void InstructionList::Append(lldb::InstructionSP &inst_sp) {
+ if (inst_sp)
+ m_instructions.push_back(inst_sp);
}
uint32_t
-InstructionList::GetIndexOfNextBranchInstruction(uint32_t start, Target &target) const
-{
- size_t num_instructions = m_instructions.size();
-
- uint32_t next_branch = UINT32_MAX;
- size_t i;
- for (i = start; i < num_instructions; i++)
- {
- if (m_instructions[i]->DoesBranch())
- {
- next_branch = i;
- break;
- }
+InstructionList::GetIndexOfNextBranchInstruction(uint32_t start,
+ Target &target) const {
+ size_t num_instructions = m_instructions.size();
+
+ uint32_t next_branch = UINT32_MAX;
+ size_t i;
+ for (i = start; i < num_instructions; i++) {
+ if (m_instructions[i]->DoesBranch()) {
+ next_branch = i;
+ break;
+ }
+ }
+
+ // Hexagon needs the first instruction of the packet with the branch.
+ // Go backwards until we find an instruction marked end-of-packet, or
+ // until we hit start.
+ if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon) {
+ // If we didn't find a branch, find the last packet start.
+ if (next_branch == UINT32_MAX) {
+ i = num_instructions - 1;
}
- // Hexagon needs the first instruction of the packet with the branch.
- // Go backwards until we find an instruction marked end-of-packet, or
- // until we hit start.
- if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon)
- {
- // If we didn't find a branch, find the last packet start.
- if (next_branch == UINT32_MAX)
- {
- i = num_instructions - 1;
- }
-
- while (i > start)
- {
- --i;
-
- Error error;
- uint32_t inst_bytes;
- bool prefer_file_cache = false; // Read from process if process is running
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
- target.ReadMemory(m_instructions[i]->GetAddress(),
- prefer_file_cache,
- &inst_bytes,
- sizeof(inst_bytes),
- error,
- &load_addr);
- // If we have an error reading memory, return start
- if (!error.Success())
- return start;
- // check if this is the last instruction in a packet
- // bits 15:14 will be 11b or 00b for a duplex
- if (((inst_bytes & 0xC000) == 0xC000) ||
- ((inst_bytes & 0xC000) == 0x0000))
- {
- // instruction after this should be the start of next packet
- next_branch = i + 1;
- break;
- }
- }
+ while (i > start) {
+ --i;
+
+ Error error;
+ uint32_t inst_bytes;
+ bool prefer_file_cache = false; // Read from process if process is running
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+ target.ReadMemory(m_instructions[i]->GetAddress(), prefer_file_cache,
+ &inst_bytes, sizeof(inst_bytes), error, &load_addr);
+ // If we have an error reading memory, return start
+ if (!error.Success())
+ return start;
+ // check if this is the last instruction in a packet
+ // bits 15:14 will be 11b or 00b for a duplex
+ if (((inst_bytes & 0xC000) == 0xC000) ||
+ ((inst_bytes & 0xC000) == 0x0000)) {
+ // instruction after this should be the start of next packet
+ next_branch = i + 1;
+ break;
+ }
+ }
- if (next_branch == UINT32_MAX)
- {
- // We couldn't find the previous packet, so return start
- next_branch = start;
- }
+ if (next_branch == UINT32_MAX) {
+ // We couldn't find the previous packet, so return start
+ next_branch = start;
}
- return next_branch;
+ }
+ return next_branch;
}
uint32_t
-InstructionList::GetIndexOfInstructionAtAddress (const Address &address)
-{
- size_t num_instructions = m_instructions.size();
- uint32_t index = UINT32_MAX;
- for (size_t i = 0; i < num_instructions; i++)
- {
- if (m_instructions[i]->GetAddress() == address)
- {
- index = i;
- break;
- }
+InstructionList::GetIndexOfInstructionAtAddress(const Address &address) {
+ size_t num_instructions = m_instructions.size();
+ uint32_t index = UINT32_MAX;
+ for (size_t i = 0; i < num_instructions; i++) {
+ if (m_instructions[i]->GetAddress() == address) {
+ index = i;
+ break;
}
- return index;
+ }
+ return index;
}
uint32_t
-InstructionList::GetIndexOfInstructionAtLoadAddress (lldb::addr_t load_addr, Target &target)
-{
- Address address;
- address.SetLoadAddress(load_addr, &target);
- return GetIndexOfInstructionAtAddress(address);
+InstructionList::GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr,
+ Target &target) {
+ Address address;
+ address.SetLoadAddress(load_addr, &target);
+ return GetIndexOfInstructionAtAddress(address);
}
-size_t
-Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
- const AddressRange &range,
- Stream *error_strm_ptr,
- bool prefer_file_cache)
-{
- if (exe_ctx)
- {
- Target *target = exe_ctx->GetTargetPtr();
- const addr_t byte_size = range.GetByteSize();
- if (target == nullptr || byte_size == 0 || !range.GetBaseAddress().IsValid())
- return 0;
-
- DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
- DataBufferSP data_sp(heap_buffer);
-
- Error error;
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
- const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
- prefer_file_cache,
- heap_buffer->GetBytes(),
- heap_buffer->GetByteSize(),
- error,
- &load_addr);
-
- if (bytes_read > 0)
- {
- if (bytes_read != heap_buffer->GetByteSize())
- heap_buffer->SetByteSize (bytes_read);
- DataExtractor data (data_sp,
- m_arch.GetByteOrder(),
- m_arch.GetAddressByteSize());
- const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
- return DecodeInstructions(range.GetBaseAddress(), data, 0, UINT32_MAX, false,
- data_from_file);
- }
- else if (error_strm_ptr)
- {
- const char *error_cstr = error.AsCString();
- if (error_cstr)
- {
- error_strm_ptr->Printf("error: %s\n", error_cstr);
- }
- }
- }
- else if (error_strm_ptr)
- {
- error_strm_ptr->PutCString("error: invalid execution context\n");
+size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx,
+ const AddressRange &range,
+ Stream *error_strm_ptr,
+ bool prefer_file_cache) {
+ if (exe_ctx) {
+ Target *target = exe_ctx->GetTargetPtr();
+ const addr_t byte_size = range.GetByteSize();
+ if (target == nullptr || byte_size == 0 ||
+ !range.GetBaseAddress().IsValid())
+ return 0;
+
+ DataBufferHeap *heap_buffer = new DataBufferHeap(byte_size, '\0');
+ DataBufferSP data_sp(heap_buffer);
+
+ Error error;
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+ const size_t bytes_read = target->ReadMemory(
+ range.GetBaseAddress(), prefer_file_cache, heap_buffer->GetBytes(),
+ heap_buffer->GetByteSize(), error, &load_addr);
+
+ if (bytes_read > 0) {
+ if (bytes_read != heap_buffer->GetByteSize())
+ heap_buffer->SetByteSize(bytes_read);
+ DataExtractor data(data_sp, m_arch.GetByteOrder(),
+ m_arch.GetAddressByteSize());
+ const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
+ return DecodeInstructions(range.GetBaseAddress(), data, 0, UINT32_MAX,
+ false, data_from_file);
+ } else if (error_strm_ptr) {
+ const char *error_cstr = error.AsCString();
+ if (error_cstr) {
+ error_strm_ptr->Printf("error: %s\n", error_cstr);
+ }
}
- return 0;
+ } else if (error_strm_ptr) {
+ error_strm_ptr->PutCString("error: invalid execution context\n");
+ }
+ return 0;
}
-size_t
-Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
- const Address &start,
- uint32_t num_instructions,
- bool prefer_file_cache)
-{
- m_instruction_list.Clear();
+size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx,
+ const Address &start,
+ uint32_t num_instructions,
+ bool prefer_file_cache) {
+ m_instruction_list.Clear();
- if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid())
- return 0;
-
- Target *target = exe_ctx->GetTargetPtr();
- // Calculate the max buffer size we will need in order to disassemble
- const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
-
- if (target == nullptr || byte_size == 0)
- return 0;
+ if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid())
+ return 0;
- DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
- DataBufferSP data_sp (heap_buffer);
+ Target *target = exe_ctx->GetTargetPtr();
+ // Calculate the max buffer size we will need in order to disassemble
+ const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
- Error error;
- lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
- const size_t bytes_read = target->ReadMemory (start,
- prefer_file_cache,
- heap_buffer->GetBytes(),
- byte_size,
- error,
- &load_addr);
-
- const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
-
- if (bytes_read == 0)
- return 0;
- DataExtractor data (data_sp,
- m_arch.GetByteOrder(),
- m_arch.GetAddressByteSize());
-
- const bool append_instructions = true;
- DecodeInstructions (start,
- data,
- 0,
- num_instructions,
- append_instructions,
- data_from_file);
-
- return m_instruction_list.GetSize();
+ if (target == nullptr || byte_size == 0)
+ return 0;
+
+ DataBufferHeap *heap_buffer = new DataBufferHeap(byte_size, '\0');
+ DataBufferSP data_sp(heap_buffer);
+
+ Error error;
+ lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
+ const size_t bytes_read =
+ target->ReadMemory(start, prefer_file_cache, heap_buffer->GetBytes(),
+ byte_size, error, &load_addr);
+
+ const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
+
+ if (bytes_read == 0)
+ return 0;
+ DataExtractor data(data_sp, m_arch.GetByteOrder(),
+ m_arch.GetAddressByteSize());
+
+ const bool append_instructions = true;
+ DecodeInstructions(start, data, 0, num_instructions, append_instructions,
+ data_from_file);
+
+ return m_instruction_list.GetSize();
}
//----------------------------------------------------------------------
// Disassembler copy constructor
//----------------------------------------------------------------------
-Disassembler::Disassembler(const ArchSpec& arch, const char *flavor) :
- m_arch (arch),
- m_instruction_list(),
- m_base_addr(LLDB_INVALID_ADDRESS),
- m_flavor ()
-{
- if (flavor == nullptr)
- m_flavor.assign("default");
- else
- m_flavor.assign(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.IsAlwaysThumbInstructions())
- {
- std::string thumb_arch_name (arch.GetTriple().getArchName().str());
- // Replace "arm" with "thumb" so we get all thumb variants correct
- if (thumb_arch_name.size() > 3)
- {
- thumb_arch_name.erase(0, 3);
- thumb_arch_name.insert(0, "thumb");
- }
- m_arch.SetTriple (thumb_arch_name.c_str());
+Disassembler::Disassembler(const ArchSpec &arch, const char *flavor)
+ : m_arch(arch), m_instruction_list(), m_base_addr(LLDB_INVALID_ADDRESS),
+ m_flavor() {
+ if (flavor == nullptr)
+ m_flavor.assign("default");
+ else
+ m_flavor.assign(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.IsAlwaysThumbInstructions()) {
+ std::string thumb_arch_name(arch.GetTriple().getArchName().str());
+ // Replace "arm" with "thumb" so we get all thumb variants correct
+ if (thumb_arch_name.size() > 3) {
+ thumb_arch_name.erase(0, 3);
+ thumb_arch_name.insert(0, "thumb");
}
+ m_arch.SetTriple(thumb_arch_name.c_str());
+ }
}
Disassembler::~Disassembler() = default;
-InstructionList &
-Disassembler::GetInstructionList ()
-{
- return m_instruction_list;
+InstructionList &Disassembler::GetInstructionList() {
+ return m_instruction_list;
}
-const InstructionList &
-Disassembler::GetInstructionList () const
-{
- return m_instruction_list;
+const InstructionList &Disassembler::GetInstructionList() const {
+ return m_instruction_list;
}
//----------------------------------------------------------------------
// Class PseudoInstruction
//----------------------------------------------------------------------
-PseudoInstruction::PseudoInstruction () :
- Instruction (Address(), eAddressClassUnknown),
- m_description ()
-{
-}
+PseudoInstruction::PseudoInstruction()
+ : Instruction(Address(), eAddressClassUnknown), m_description() {}
PseudoInstruction::~PseudoInstruction() = default;
-
-bool
-PseudoInstruction::DoesBranch ()
-{
- // This is NOT a valid question for a pseudo instruction.
- return false;
+
+bool PseudoInstruction::DoesBranch() {
+ // This is NOT a valid question for a pseudo instruction.
+ return false;
}
-
-bool
-PseudoInstruction::HasDelaySlot ()
-{
- // This is NOT a valid question for a pseudo instruction.
- 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,
- lldb::offset_t data_offset)
-{
- return m_opcode.GetByteSize();
+size_t PseudoInstruction::Decode(const lldb_private::Disassembler &disassembler,
+ const lldb_private::DataExtractor &data,
+ lldb::offset_t data_offset) {
+ return m_opcode.GetByteSize();
}
-void
-PseudoInstruction::SetOpcode (size_t opcode_size, void *opcode_data)
-{
- if (!opcode_data)
- return;
+void PseudoInstruction::SetOpcode(size_t opcode_size, void *opcode_data) {
+ if (!opcode_data)
+ return;
+
+ switch (opcode_size) {
+ case 8: {
+ uint8_t value8 = *((uint8_t *)opcode_data);
+ m_opcode.SetOpcode8(value8, eByteOrderInvalid);
+ break;
+ }
+ case 16: {
+ uint16_t value16 = *((uint16_t *)opcode_data);
+ m_opcode.SetOpcode16(value16, eByteOrderInvalid);
+ break;
+ }
+ case 32: {
+ uint32_t value32 = *((uint32_t *)opcode_data);
+ m_opcode.SetOpcode32(value32, eByteOrderInvalid);
+ break;
+ }
+ case 64: {
+ uint64_t value64 = *((uint64_t *)opcode_data);
+ m_opcode.SetOpcode64(value64, eByteOrderInvalid);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+void PseudoInstruction::SetDescription(llvm::StringRef description) {
+ m_description = description;
+}
+
+Instruction::Operand Instruction::Operand::BuildRegister(ConstString &r) {
+ Operand ret;
+ ret.m_type = Type::Register;
+ ret.m_register = r;
+ return ret;
+}
+
+Instruction::Operand Instruction::Operand::BuildImmediate(lldb::addr_t imm,
+ bool neg) {
+ Operand ret;
+ ret.m_type = Type::Immediate;
+ ret.m_immediate = imm;
+ ret.m_negative = neg;
+ return ret;
+}
+
+Instruction::Operand Instruction::Operand::BuildImmediate(int64_t imm) {
+ Operand ret;
+ ret.m_type = Type::Immediate;
+ if (imm < 0) {
+ ret.m_immediate = -imm;
+ ret.m_negative = true;
+ } else {
+ ret.m_immediate = imm;
+ ret.m_negative = false;
+ }
+ return ret;
+}
+
+Instruction::Operand
+Instruction::Operand::BuildDereference(const Operand &ref) {
+ Operand ret;
+ ret.m_type = Type::Dereference;
+ ret.m_children = {ref};
+ return ret;
+}
+
+Instruction::Operand Instruction::Operand::BuildSum(const Operand &lhs,
+ const Operand &rhs) {
+ Operand ret;
+ ret.m_type = Type::Sum;
+ ret.m_children = {lhs, rhs};
+ return ret;
+}
+
+Instruction::Operand Instruction::Operand::BuildProduct(const Operand &lhs,
+ const Operand &rhs) {
+ Operand ret;
+ ret.m_type = Type::Product;
+ ret.m_children = {lhs, rhs};
+ return ret;
+}
+
+std::function<bool(const Instruction::Operand &)>
+lldb_private::OperandMatchers::MatchBinaryOp(
+ std::function<bool(const Instruction::Operand &)> base,
+ std::function<bool(const Instruction::Operand &)> left,
+ std::function<bool(const Instruction::Operand &)> right) {
+ return [base, left, right](const Instruction::Operand &op) -> bool {
+ return (base(op) && op.m_children.size() == 2 &&
+ ((left(op.m_children[0]) && right(op.m_children[1])) ||
+ (left(op.m_children[1]) && right(op.m_children[0]))));
+ };
+}
- switch (opcode_size)
- {
- case 8:
- {
- uint8_t value8 = *((uint8_t *) opcode_data);
- m_opcode.SetOpcode8 (value8, eByteOrderInvalid);
- break;
- }
- case 16:
- {
- uint16_t value16 = *((uint16_t *) opcode_data);
- m_opcode.SetOpcode16 (value16, eByteOrderInvalid);
- break;
- }
- case 32:
- {
- uint32_t value32 = *((uint32_t *) opcode_data);
- m_opcode.SetOpcode32 (value32, eByteOrderInvalid);
- break;
- }
- case 64:
- {
- uint64_t value64 = *((uint64_t *) opcode_data);
- m_opcode.SetOpcode64 (value64, eByteOrderInvalid);
- break;
- }
- default:
- break;
+std::function<bool(const Instruction::Operand &)>
+lldb_private::OperandMatchers::MatchUnaryOp(
+ std::function<bool(const Instruction::Operand &)> base,
+ std::function<bool(const Instruction::Operand &)> child) {
+ return [base, child](const Instruction::Operand &op) -> bool {
+ return (base(op) && op.m_children.size() == 1 && child(op.m_children[0]));
+ };
+}
+
+std::function<bool(const Instruction::Operand &)>
+lldb_private::OperandMatchers::MatchRegOp(const RegisterInfo &info) {
+ return [&info](const Instruction::Operand &op) {
+ return (op.m_type == Instruction::Operand::Type::Register &&
+ (op.m_register == ConstString(info.name) ||
+ op.m_register == ConstString(info.alt_name)));
+ };
+}
+
+std::function<bool(const Instruction::Operand &)>
+lldb_private::OperandMatchers::FetchRegOp(ConstString &reg) {
+ return [&reg](const Instruction::Operand &op) {
+ if (op.m_type != Instruction::Operand::Type::Register) {
+ return false;
}
+ reg = op.m_register;
+ return true;
+ };
}
-void
-PseudoInstruction::SetDescription (const char *description)
-{
- if (description && strlen (description) > 0)
- m_description = description;
+std::function<bool(const Instruction::Operand &)>
+lldb_private::OperandMatchers::MatchImmOp(int64_t imm) {
+ return [imm](const Instruction::Operand &op) {
+ return (op.m_type == Instruction::Operand::Type::Immediate &&
+ ((op.m_negative && op.m_immediate == (uint64_t)-imm) ||
+ (!op.m_negative && op.m_immediate == (uint64_t)imm)));
+ };
}
+
+std::function<bool(const Instruction::Operand &)>
+lldb_private::OperandMatchers::FetchImmOp(int64_t &imm) {
+ return [&imm](const Instruction::Operand &op) {
+ if (op.m_type != Instruction::Operand::Type::Immediate) {
+ return false;
+ }
+ if (op.m_negative) {
+ imm = -((int64_t)op.m_immediate);
+ } else {
+ imm = ((int64_t)op.m_immediate);
+ }
+ return true;
+ };
+}
+
+std::function<bool(const Instruction::Operand &)>
+lldb_private::OperandMatchers::MatchOpType(Instruction::Operand::Type type) {
+ return [type](const Instruction::Operand &op) { return op.m_type == type; };
+}
+
diff --git a/source/Core/DynamicLoader.cpp b/source/Core/DynamicLoader.cpp
index f41ff4a80c83..69c5ea30dad2 100644
--- a/source/Core/DynamicLoader.cpp
+++ b/source/Core/DynamicLoader.cpp
@@ -11,49 +11,49 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Target/DynamicLoader.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/Target.h"
-#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
+#include "lldb/Target/MemoryRegionInfo.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
-DynamicLoader*
-DynamicLoader::FindPlugin (Process *process, const char *plugin_name)
-{
- DynamicLoaderCreateInstance create_callback = nullptr;
- if (plugin_name)
- {
- ConstString const_plugin_name(plugin_name);
- create_callback = PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const_plugin_name);
- if (create_callback)
- {
- std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, true));
- if (instance_ap)
- return instance_ap.release();
- }
+DynamicLoader *DynamicLoader::FindPlugin(Process *process,
+ const char *plugin_name) {
+ DynamicLoaderCreateInstance create_callback = nullptr;
+ if (plugin_name) {
+ ConstString const_plugin_name(plugin_name);
+ create_callback =
+ PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
+ const_plugin_name);
+ if (create_callback) {
+ std::unique_ptr<DynamicLoader> instance_ap(
+ create_callback(process, true));
+ if (instance_ap)
+ return instance_ap.release();
}
- else
- {
- for (uint32_t idx = 0; (create_callback = PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) != nullptr; ++idx)
- {
- std::unique_ptr<DynamicLoader> instance_ap(create_callback(process, false));
- if (instance_ap)
- return instance_ap.release();
- }
+ } else {
+ for (uint32_t idx = 0;
+ (create_callback =
+ PluginManager::GetDynamicLoaderCreateCallbackAtIndex(idx)) !=
+ nullptr;
+ ++idx) {
+ std::unique_ptr<DynamicLoader> instance_ap(
+ create_callback(process, false));
+ if (instance_ap)
+ return instance_ap.release();
}
- return nullptr;
+ }
+ return nullptr;
}
-DynamicLoader::DynamicLoader(Process *process) :
- m_process (process)
-{
-}
+DynamicLoader::DynamicLoader(Process *process) : m_process(process) {}
DynamicLoader::~DynamicLoader() = default;
@@ -62,173 +62,174 @@ DynamicLoader::~DynamicLoader() = default;
// (shared library) loading/unloading.
//----------------------------------------------------------------------
-bool
-DynamicLoader::GetStopWhenImagesChange () const
-{
- return m_process->GetStopOnSharedLibraryEvents();
+bool DynamicLoader::GetStopWhenImagesChange() const {
+ return m_process->GetStopOnSharedLibraryEvents();
}
-void
-DynamicLoader::SetStopWhenImagesChange (bool stop)
-{
- m_process->SetStopOnSharedLibraryEvents (stop);
+void DynamicLoader::SetStopWhenImagesChange(bool stop) {
+ m_process->SetStopOnSharedLibraryEvents(stop);
}
-ModuleSP
-DynamicLoader::GetTargetExecutable()
-{
- Target &target = m_process->GetTarget();
- ModuleSP executable = target.GetExecutableModule();
-
- if (executable)
- {
- if (executable->GetFileSpec().Exists())
- {
- ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
- ModuleSP module_sp (new Module (module_spec));
-
- // Check if the executable has changed and set it to the target executable if they differ.
- if (module_sp && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
- {
- if (module_sp->GetUUID() != executable->GetUUID())
- executable.reset();
- }
- else if (executable->FileHasChanged())
- {
- executable.reset();
- }
-
- if (!executable)
- {
- executable = target.GetSharedModule(module_spec);
- if (executable.get() != target.GetExecutableModulePointer())
- {
- // Don't load dependent images since we are in dyld where we will know
- // and find out about all images that are loaded
- const bool get_dependent_images = false;
- target.SetExecutableModule(executable, get_dependent_images);
- }
- }
+ModuleSP DynamicLoader::GetTargetExecutable() {
+ Target &target = m_process->GetTarget();
+ ModuleSP executable = target.GetExecutableModule();
+
+ if (executable) {
+ if (executable->GetFileSpec().Exists()) {
+ ModuleSpec module_spec(executable->GetFileSpec(),
+ executable->GetArchitecture());
+ ModuleSP module_sp(new Module(module_spec));
+
+ // Check if the executable has changed and set it to the target executable
+ // if they differ.
+ if (module_sp && module_sp->GetUUID().IsValid() &&
+ executable->GetUUID().IsValid()) {
+ if (module_sp->GetUUID() != executable->GetUUID())
+ executable.reset();
+ } else if (executable->FileHasChanged()) {
+ executable.reset();
+ }
+
+ if (!executable) {
+ executable = target.GetSharedModule(module_spec);
+ if (executable.get() != target.GetExecutableModulePointer()) {
+ // Don't load dependent images since we are in dyld where we will know
+ // and find out about all images that are loaded
+ const bool get_dependent_images = false;
+ target.SetExecutableModule(executable, get_dependent_images);
}
+ }
}
- return executable;
+ }
+ return executable;
}
-void
-DynamicLoader::UpdateLoadedSections(ModuleSP module,
- addr_t link_map_addr,
- addr_t base_addr,
- bool base_addr_is_offset)
-{
- UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
+void DynamicLoader::UpdateLoadedSections(ModuleSP module, addr_t link_map_addr,
+ addr_t base_addr,
+ bool base_addr_is_offset) {
+ UpdateLoadedSectionsCommon(module, base_addr, base_addr_is_offset);
}
-void
-DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module,
- addr_t base_addr,
- bool base_addr_is_offset)
-{
- bool changed;
- module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset, changed);
+void DynamicLoader::UpdateLoadedSectionsCommon(ModuleSP module,
+ addr_t base_addr,
+ bool base_addr_is_offset) {
+ bool changed;
+ module->SetLoadAddress(m_process->GetTarget(), base_addr, base_addr_is_offset,
+ changed);
}
-void
-DynamicLoader::UnloadSections(const ModuleSP module)
-{
- UnloadSectionsCommon(module);
+void DynamicLoader::UnloadSections(const ModuleSP module) {
+ UnloadSectionsCommon(module);
}
-void
-DynamicLoader::UnloadSectionsCommon(const ModuleSP module)
-{
- Target &target = m_process->GetTarget();
- const SectionList *sections = GetSectionListFromModule(module);
+void DynamicLoader::UnloadSectionsCommon(const ModuleSP module) {
+ Target &target = m_process->GetTarget();
+ const SectionList *sections = GetSectionListFromModule(module);
- assert(sections && "SectionList missing from unloaded module.");
+ assert(sections && "SectionList missing from unloaded module.");
- const size_t num_sections = sections->GetSize();
- for (size_t i = 0; i < num_sections; ++i)
- {
- SectionSP section_sp (sections->GetSectionAtIndex(i));
- target.SetSectionUnloaded(section_sp);
- }
+ const size_t num_sections = sections->GetSize();
+ for (size_t i = 0; i < num_sections; ++i) {
+ SectionSP section_sp(sections->GetSectionAtIndex(i));
+ target.SetSectionUnloaded(section_sp);
+ }
}
const SectionList *
-DynamicLoader::GetSectionListFromModule(const ModuleSP module) const
-{
- SectionList *sections = nullptr;
- if (module)
- {
- ObjectFile *obj_file = module->GetObjectFile();
- if (obj_file != nullptr)
- {
- sections = obj_file->GetSectionList();
- }
+DynamicLoader::GetSectionListFromModule(const ModuleSP module) const {
+ SectionList *sections = nullptr;
+ if (module) {
+ ObjectFile *obj_file = module->GetObjectFile();
+ if (obj_file != nullptr) {
+ sections = obj_file->GetSectionList();
}
- return sections;
+ }
+ return sections;
}
-ModuleSP
-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();
- ModuleSP module_sp;
-
- ModuleSpec module_spec (file, target.GetArchitecture());
- if ((module_sp = modules.FindFirstModule (module_spec)))
- {
- UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
+ModuleSP 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();
+ ModuleSpec module_spec(file, target.GetArchitecture());
+ ModuleSP module_sp;
+
+ if ((module_sp = modules.FindFirstModule(module_spec))) {
+ UpdateLoadedSections(module_sp, link_map_addr, base_addr,
+ base_addr_is_offset);
+ return module_sp;
+ }
+
+ if ((module_sp = target.GetSharedModule(module_spec))) {
+ UpdateLoadedSections(module_sp, link_map_addr, base_addr,
+ base_addr_is_offset);
+ return module_sp;
+ }
+
+ bool check_alternative_file_name = true;
+ if (base_addr_is_offset) {
+ // 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 = false;
+ lldb::addr_t load_addr;
+ Error error = m_process->GetFileLoadAddress(file, is_loaded, load_addr);
+ if (error.Success() && is_loaded) {
+ check_alternative_file_name = false;
+ base_addr = load_addr;
}
- else if ((module_sp = target.GetSharedModule(module_spec)))
- {
- UpdateLoadedSections(module_sp, link_map_addr, base_addr, base_addr_is_offset);
+ }
+
+ // We failed to find the module based on its name. Lets try to check if we can
+ // find a
+ // different name based on the memory region info.
+ if (check_alternative_file_name) {
+ MemoryRegionInfo memory_info;
+ Error error = m_process->GetMemoryRegionInfo(base_addr, memory_info);
+ if (error.Success() && memory_info.GetMapped() &&
+ memory_info.GetRange().GetRangeBase() == base_addr) {
+ ModuleSpec new_module_spec(
+ FileSpec(memory_info.GetName().AsCString(), false),
+ target.GetArchitecture());
+
+ if ((module_sp = modules.FindFirstModule(new_module_spec))) {
+ UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
+ return module_sp;
+ }
+
+ if ((module_sp = target.GetSharedModule(new_module_spec))) {
+ UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
+ return module_sp;
+ }
}
- else
- {
- if (base_addr_is_offset)
- {
- // 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 = false;
- 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);
- }
- }
+ if ((module_sp = m_process->ReadModuleFromMemory(file, base_addr))) {
+ UpdateLoadedSections(module_sp, link_map_addr, base_addr, false);
+ target.GetImages().AppendIfNeeded(module_sp);
+ }
- return module_sp;
+ return module_sp;
}
-int64_t
-DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr, int size_in_bytes)
-{
- Error error;
- uint64_t value = m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
- if (error.Fail())
- return -1;
- else
- return (int64_t)value;
+int64_t DynamicLoader::ReadUnsignedIntWithSizeInBytes(addr_t addr,
+ int size_in_bytes) {
+ Error error;
+ uint64_t value =
+ m_process->ReadUnsignedIntegerFromMemory(addr, size_in_bytes, 0, error);
+ if (error.Fail())
+ return -1;
+ else
+ return (int64_t)value;
}
-addr_t
-DynamicLoader::ReadPointer(addr_t addr)
-{
- Error error;
- addr_t value = m_process->ReadPointerFromMemory(addr, error);
- if (error.Fail())
- return LLDB_INVALID_ADDRESS;
- else
- return value;
+addr_t DynamicLoader::ReadPointer(addr_t addr) {
+ Error error;
+ addr_t value = m_process->ReadPointerFromMemory(addr, error);
+ if (error.Fail())
+ return LLDB_INVALID_ADDRESS;
+ else
+ return value;
}
diff --git a/source/Core/EmulateInstruction.cpp b/source/Core/EmulateInstruction.cpp
index e46cfb2d8945..bc32fb2f35eb 100644
--- a/source/Core/EmulateInstruction.cpp
+++ b/source/Core/EmulateInstruction.cpp
@@ -1,4 +1,4 @@
-//===-- EmulateInstruction.h ------------------------------------*- C++ -*-===//
+//===-- EmulateInstruction.cpp ----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -32,621 +32,553 @@
using namespace lldb;
using namespace lldb_private;
-EmulateInstruction*
-EmulateInstruction::FindPlugin (const ArchSpec &arch, InstructionType supported_inst_type, const char *plugin_name)
-{
- EmulateInstructionCreateInstance create_callback = nullptr;
- if (plugin_name)
- {
- ConstString const_plugin_name (plugin_name);
- create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const_plugin_name);
- if (create_callback)
- {
- EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
- if (emulate_insn_ptr)
- return emulate_insn_ptr;
- }
+EmulateInstruction *
+EmulateInstruction::FindPlugin(const ArchSpec &arch,
+ InstructionType supported_inst_type,
+ const char *plugin_name) {
+ EmulateInstructionCreateInstance create_callback = nullptr;
+ if (plugin_name) {
+ ConstString const_plugin_name(plugin_name);
+ create_callback =
+ PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
+ const_plugin_name);
+ if (create_callback) {
+ EmulateInstruction *emulate_insn_ptr =
+ create_callback(arch, supported_inst_type);
+ if (emulate_insn_ptr)
+ return emulate_insn_ptr;
}
- else
- {
- for (uint32_t idx = 0; (create_callback = PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) != nullptr; ++idx)
- {
- EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type);
- if (emulate_insn_ptr)
- return emulate_insn_ptr;
- }
+ } else {
+ for (uint32_t idx = 0;
+ (create_callback =
+ PluginManager::GetEmulateInstructionCreateCallbackAtIndex(idx)) !=
+ nullptr;
+ ++idx) {
+ EmulateInstruction *emulate_insn_ptr =
+ create_callback(arch, supported_inst_type);
+ if (emulate_insn_ptr)
+ return emulate_insn_ptr;
}
- return nullptr;
-}
-
-EmulateInstruction::EmulateInstruction (const ArchSpec &arch) :
- m_arch(arch),
- m_baton(nullptr),
- m_read_mem_callback(&ReadMemoryDefault),
- m_write_mem_callback(&WriteMemoryDefault),
- m_read_reg_callback(&ReadRegisterDefault),
- m_write_reg_callback(&WriteRegisterDefault),
- m_addr(LLDB_INVALID_ADDRESS)
-{
- ::memset (&m_opcode, 0, sizeof (m_opcode));
-}
-
-bool
-EmulateInstruction::ReadRegister (const RegisterInfo *reg_info, RegisterValue& reg_value)
-{
- if (m_read_reg_callback != nullptr)
- return m_read_reg_callback (this, m_baton, reg_info, reg_value);
- return false;
-}
-
-bool
-EmulateInstruction::ReadRegister (lldb::RegisterKind reg_kind, uint32_t reg_num, RegisterValue& reg_value)
-{
- RegisterInfo reg_info;
- if (GetRegisterInfo(reg_kind, reg_num, reg_info))
- return ReadRegister (&reg_info, reg_value);
- return false;
-}
-
-uint64_t
-EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- uint64_t fail_value,
- bool *success_ptr)
-{
- RegisterValue reg_value;
- if (ReadRegister (reg_kind, reg_num, reg_value))
- return reg_value.GetAsUInt64(fail_value, success_ptr);
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
-}
-
-uint64_t
-EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
- uint64_t fail_value,
- bool *success_ptr)
-{
+ }
+ return nullptr;
+}
+
+EmulateInstruction::EmulateInstruction(const ArchSpec &arch)
+ : m_arch(arch), m_baton(nullptr), m_read_mem_callback(&ReadMemoryDefault),
+ m_write_mem_callback(&WriteMemoryDefault),
+ m_read_reg_callback(&ReadRegisterDefault),
+ m_write_reg_callback(&WriteRegisterDefault),
+ m_addr(LLDB_INVALID_ADDRESS) {
+ ::memset(&m_opcode, 0, sizeof(m_opcode));
+}
+
+bool EmulateInstruction::ReadRegister(const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ if (m_read_reg_callback != nullptr)
+ return m_read_reg_callback(this, m_baton, reg_info, reg_value);
+ return false;
+}
+
+bool EmulateInstruction::ReadRegister(lldb::RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterValue &reg_value) {
+ RegisterInfo reg_info;
+ if (GetRegisterInfo(reg_kind, reg_num, reg_info))
+ return ReadRegister(&reg_info, reg_value);
+ return false;
+}
+
+uint64_t EmulateInstruction::ReadRegisterUnsigned(lldb::RegisterKind reg_kind,
+ uint32_t reg_num,
+ uint64_t fail_value,
+ bool *success_ptr) {
+ RegisterValue reg_value;
+ if (ReadRegister(reg_kind, reg_num, reg_value))
+ return reg_value.GetAsUInt64(fail_value, success_ptr);
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+uint64_t EmulateInstruction::ReadRegisterUnsigned(const RegisterInfo *reg_info,
+ uint64_t fail_value,
+ bool *success_ptr) {
+ RegisterValue reg_value;
+ if (ReadRegister(reg_info, reg_value))
+ return reg_value.GetAsUInt64(fail_value, success_ptr);
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+bool EmulateInstruction::WriteRegister(const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ if (m_write_reg_callback != nullptr)
+ return m_write_reg_callback(this, m_baton, context, reg_info, reg_value);
+ return false;
+}
+
+bool EmulateInstruction::WriteRegister(const Context &context,
+ lldb::RegisterKind reg_kind,
+ uint32_t reg_num,
+ const RegisterValue &reg_value) {
+ RegisterInfo reg_info;
+ if (GetRegisterInfo(reg_kind, reg_num, reg_info))
+ return WriteRegister(context, &reg_info, reg_value);
+ return false;
+}
+
+bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
+ lldb::RegisterKind reg_kind,
+ uint32_t reg_num,
+ uint64_t uint_value) {
+ RegisterInfo reg_info;
+ if (GetRegisterInfo(reg_kind, reg_num, reg_info)) {
RegisterValue reg_value;
- if (ReadRegister (reg_info, reg_value))
- return reg_value.GetAsUInt64(fail_value, success_ptr);
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
-}
-
-bool
-EmulateInstruction::WriteRegister (const Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue& reg_value)
-{
- if (m_write_reg_callback != nullptr)
- return m_write_reg_callback (this, m_baton, context, reg_info, reg_value);
- return false;
-}
-
-bool
-EmulateInstruction::WriteRegister (const Context &context,
- lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- const RegisterValue& reg_value)
-{
- RegisterInfo reg_info;
- if (GetRegisterInfo(reg_kind, reg_num, reg_info))
- return WriteRegister (context, &reg_info, reg_value);
- return false;
+ if (reg_value.SetUInt(uint_value, reg_info.byte_size))
+ return WriteRegister(context, &reg_info, reg_value);
+ }
+ return false;
}
-bool
-EmulateInstruction::WriteRegisterUnsigned (const Context &context,
- lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- uint64_t uint_value)
-{
- RegisterInfo reg_info;
- if (GetRegisterInfo(reg_kind, reg_num, reg_info))
- {
- RegisterValue reg_value;
- if (reg_value.SetUInt(uint_value, reg_info.byte_size))
- return WriteRegister (context, &reg_info, reg_value);
+bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
+ const RegisterInfo *reg_info,
+ uint64_t uint_value) {
+ if (reg_info != nullptr) {
+ RegisterValue reg_value;
+ if (reg_value.SetUInt(uint_value, reg_info->byte_size))
+ return WriteRegister(context, reg_info, reg_value);
+ }
+ return false;
+}
+
+size_t EmulateInstruction::ReadMemory(const Context &context, lldb::addr_t addr,
+ void *dst, size_t dst_len) {
+ if (m_read_mem_callback != nullptr)
+ return m_read_mem_callback(this, m_baton, context, addr, dst, dst_len) ==
+ dst_len;
+ return false;
+}
+
+uint64_t EmulateInstruction::ReadMemoryUnsigned(const Context &context,
+ lldb::addr_t addr,
+ size_t byte_size,
+ uint64_t fail_value,
+ bool *success_ptr) {
+ uint64_t uval64 = 0;
+ bool success = false;
+ if (byte_size <= 8) {
+ uint8_t buf[sizeof(uint64_t)];
+ size_t bytes_read =
+ m_read_mem_callback(this, m_baton, context, addr, buf, byte_size);
+ if (bytes_read == byte_size) {
+ lldb::offset_t offset = 0;
+ DataExtractor data(buf, byte_size, GetByteOrder(), GetAddressByteSize());
+ uval64 = data.GetMaxU64(&offset, byte_size);
+ success = true;
}
- return false;
-}
+ }
-bool
-EmulateInstruction::WriteRegisterUnsigned (const Context &context,
- const RegisterInfo *reg_info,
- uint64_t uint_value)
-{
- if (reg_info != nullptr)
- {
- RegisterValue reg_value;
- if (reg_value.SetUInt(uint_value, reg_info->byte_size))
- return WriteRegister (context, reg_info, reg_value);
- }
- return false;
-}
+ if (success_ptr)
+ *success_ptr = success;
-size_t
-EmulateInstruction::ReadMemory (const Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t dst_len)
-{
- if (m_read_mem_callback != nullptr)
- return m_read_mem_callback (this, m_baton, context, addr, dst, dst_len) == dst_len;
- return false;
+ if (!success)
+ uval64 = fail_value;
+ return uval64;
}
-uint64_t
-EmulateInstruction::ReadMemoryUnsigned (const Context &context, lldb::addr_t addr, size_t byte_size, uint64_t fail_value, bool *success_ptr)
-{
- uint64_t uval64 = 0;
- bool success = false;
- if (byte_size <= 8)
- {
- uint8_t buf[sizeof(uint64_t)];
- size_t bytes_read = m_read_mem_callback (this, m_baton, context, addr, buf, byte_size);
- if (bytes_read == byte_size)
- {
- lldb::offset_t offset = 0;
- DataExtractor data (buf, byte_size, GetByteOrder(), GetAddressByteSize());
- uval64 = data.GetMaxU64 (&offset, byte_size);
- success = true;
- }
- }
+bool EmulateInstruction::WriteMemoryUnsigned(const Context &context,
+ lldb::addr_t addr, uint64_t uval,
+ size_t uval_byte_size) {
+ StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
+ strm.PutMaxHex64(uval, uval_byte_size);
- if (success_ptr)
- *success_ptr = success;
-
- if (!success)
- uval64 = fail_value;
- return uval64;
-}
-
-bool
-EmulateInstruction::WriteMemoryUnsigned (const Context &context,
- lldb::addr_t addr,
- uint64_t uval,
- size_t uval_byte_size)
-{
- StreamString strm(Stream::eBinary, GetAddressByteSize(), GetByteOrder());
- strm.PutMaxHex64 (uval, uval_byte_size);
-
- size_t bytes_written = m_write_mem_callback (this, m_baton, context, addr, strm.GetData(), uval_byte_size);
- return (bytes_written == uval_byte_size);
-}
-
-bool
-EmulateInstruction::WriteMemory (const Context &context,
- lldb::addr_t addr,
- const void *src,
- size_t src_len)
-{
- if (m_write_mem_callback != nullptr)
- return m_write_mem_callback (this, m_baton, context, addr, src, src_len) == src_len;
- return false;
+ size_t bytes_written = m_write_mem_callback(
+ this, m_baton, context, addr, strm.GetString().data(), uval_byte_size);
+ return (bytes_written == uval_byte_size);
}
-void
-EmulateInstruction::SetBaton (void *baton)
-{
- m_baton = baton;
+bool EmulateInstruction::WriteMemory(const Context &context, lldb::addr_t addr,
+ const void *src, size_t src_len) {
+ if (m_write_mem_callback != nullptr)
+ return m_write_mem_callback(this, m_baton, context, addr, src, src_len) ==
+ src_len;
+ return false;
}
-void
-EmulateInstruction::SetCallbacks (ReadMemoryCallback read_mem_callback,
- WriteMemoryCallback write_mem_callback,
- ReadRegisterCallback read_reg_callback,
- WriteRegisterCallback write_reg_callback)
-{
- m_read_mem_callback = read_mem_callback;
- m_write_mem_callback = write_mem_callback;
- m_read_reg_callback = read_reg_callback;
- m_write_reg_callback = write_reg_callback;
+void EmulateInstruction::SetBaton(void *baton) { m_baton = baton; }
+
+void EmulateInstruction::SetCallbacks(
+ ReadMemoryCallback read_mem_callback,
+ WriteMemoryCallback write_mem_callback,
+ ReadRegisterCallback read_reg_callback,
+ WriteRegisterCallback write_reg_callback) {
+ m_read_mem_callback = read_mem_callback;
+ m_write_mem_callback = write_mem_callback;
+ m_read_reg_callback = read_reg_callback;
+ m_write_reg_callback = write_reg_callback;
}
-void
-EmulateInstruction::SetReadMemCallback (ReadMemoryCallback read_mem_callback)
-{
- m_read_mem_callback = read_mem_callback;
+void EmulateInstruction::SetReadMemCallback(
+ ReadMemoryCallback read_mem_callback) {
+ m_read_mem_callback = read_mem_callback;
}
-void
-EmulateInstruction::SetWriteMemCallback (WriteMemoryCallback write_mem_callback)
-{
- m_write_mem_callback = write_mem_callback;
+void EmulateInstruction::SetWriteMemCallback(
+ WriteMemoryCallback write_mem_callback) {
+ m_write_mem_callback = write_mem_callback;
}
-void
-EmulateInstruction::SetReadRegCallback (ReadRegisterCallback read_reg_callback)
-{
- m_read_reg_callback = read_reg_callback;
+void EmulateInstruction::SetReadRegCallback(
+ ReadRegisterCallback read_reg_callback) {
+ m_read_reg_callback = read_reg_callback;
}
-void
-EmulateInstruction::SetWriteRegCallback (WriteRegisterCallback write_reg_callback)
-{
- m_write_reg_callback = write_reg_callback;
+void EmulateInstruction::SetWriteRegCallback(
+ WriteRegisterCallback write_reg_callback) {
+ m_write_reg_callback = write_reg_callback;
}
//
// Read & Write Memory and Registers callback functions.
//
-size_t
-EmulateInstruction::ReadMemoryFrame (EmulateInstruction *instruction,
- void *baton,
- const Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t dst_len)
-{
- if (baton == nullptr || dst == nullptr || dst_len == 0)
- return 0;
-
- StackFrame *frame = (StackFrame *) baton;
-
- ProcessSP process_sp (frame->CalculateProcess());
- if (process_sp)
- {
- Error error;
- return process_sp->ReadMemory (addr, dst, dst_len, error);
- }
+size_t EmulateInstruction::ReadMemoryFrame(EmulateInstruction *instruction,
+ void *baton, const Context &context,
+ lldb::addr_t addr, void *dst,
+ size_t dst_len) {
+ if (baton == nullptr || dst == nullptr || dst_len == 0)
return 0;
+
+ StackFrame *frame = (StackFrame *)baton;
+
+ ProcessSP process_sp(frame->CalculateProcess());
+ if (process_sp) {
+ Error error;
+ return process_sp->ReadMemory(addr, dst, dst_len, error);
+ }
+ return 0;
}
-size_t
-EmulateInstruction::WriteMemoryFrame (EmulateInstruction *instruction,
- void *baton,
- const Context &context,
- lldb::addr_t addr,
- const void *src,
- size_t src_len)
-{
- if (baton == nullptr || src == nullptr || src_len == 0)
- return 0;
-
- StackFrame *frame = (StackFrame *) baton;
-
- ProcessSP process_sp (frame->CalculateProcess());
- if (process_sp)
- {
- Error error;
- return process_sp->WriteMemory (addr, src, src_len, error);
- }
-
+size_t EmulateInstruction::WriteMemoryFrame(EmulateInstruction *instruction,
+ void *baton, const Context &context,
+ lldb::addr_t addr, const void *src,
+ size_t src_len) {
+ if (baton == nullptr || src == nullptr || src_len == 0)
return 0;
-}
-bool
-EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
- void *baton,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value)
-{
- if (baton == nullptr)
- return false;
-
- StackFrame *frame = (StackFrame *) baton;
- return frame->GetRegisterContext()->ReadRegister (reg_info, reg_value);
-}
-
-bool
-EmulateInstruction::WriteRegisterFrame (EmulateInstruction *instruction,
- void *baton,
- const Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value)
-{
- if (baton == nullptr)
- return false;
-
- StackFrame *frame = (StackFrame *) baton;
- return frame->GetRegisterContext()->WriteRegister (reg_info, reg_value);
-}
-
-size_t
-EmulateInstruction::ReadMemoryDefault (EmulateInstruction *instruction,
- void *baton,
- const Context &context,
- lldb::addr_t addr,
- void *dst,
- size_t length)
-{
- StreamFile strm (stdout, false);
- strm.Printf (" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
- context.Dump (strm, instruction);
- strm.EOL();
- *((uint64_t *) dst) = 0xdeadbeef;
- return length;
-}
-
-size_t
-EmulateInstruction::WriteMemoryDefault (EmulateInstruction *instruction,
- void *baton,
- const Context &context,
- lldb::addr_t addr,
- const void *dst,
- size_t length)
-{
- StreamFile strm (stdout, false);
- strm.Printf (" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64 ", context = ", addr, (uint64_t)length);
- context.Dump (strm, instruction);
- strm.EOL();
- return length;
-}
-
-bool
-EmulateInstruction::ReadRegisterDefault (EmulateInstruction *instruction,
- void *baton,
- const RegisterInfo *reg_info,
- RegisterValue &reg_value)
-{
- StreamFile strm (stdout, false);
- strm.Printf (" Read Register (%s)\n", reg_info->name);
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- if (GetBestRegisterKindAndNumber (reg_info, reg_kind, reg_num))
- reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
- else
- reg_value.SetUInt64(0);
+ StackFrame *frame = (StackFrame *)baton;
- return true;
-}
+ ProcessSP process_sp(frame->CalculateProcess());
+ if (process_sp) {
+ Error error;
+ return process_sp->WriteMemory(addr, src, src_len, error);
+ }
-bool
-EmulateInstruction::WriteRegisterDefault (EmulateInstruction *instruction,
- void *baton,
- const Context &context,
- const RegisterInfo *reg_info,
- const RegisterValue &reg_value)
-{
- StreamFile strm (stdout, false);
- strm.Printf (" Write to Register (name = %s, value = " , reg_info->name);
- reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
- strm.PutCString (", context = ");
- context.Dump (strm, instruction);
- strm.EOL();
- return true;
+ return 0;
}
-void
-EmulateInstruction::Context::Dump (Stream &strm,
- EmulateInstruction *instruction) const
-{
- switch (type)
- {
- case eContextReadOpcode:
- strm.PutCString ("reading opcode");
- break;
-
- case eContextImmediate:
- strm.PutCString ("immediate");
- break;
-
- case eContextPushRegisterOnStack:
- strm.PutCString ("push register");
- break;
-
- case eContextPopRegisterOffStack:
- strm.PutCString ("pop register");
- break;
-
- case eContextAdjustStackPointer:
- strm.PutCString ("adjust sp");
- break;
-
- case eContextSetFramePointer:
- strm.PutCString ("set frame pointer");
- break;
-
- case eContextAdjustBaseRegister:
- strm.PutCString ("adjusting (writing value back to) a base register");
- break;
-
- case eContextRegisterPlusOffset:
- strm.PutCString ("register + offset");
- break;
-
- case eContextRegisterStore:
- strm.PutCString ("store register");
- break;
-
- case eContextRegisterLoad:
- strm.PutCString ("load register");
- break;
-
- case eContextRelativeBranchImmediate:
- strm.PutCString ("relative branch immediate");
- break;
-
- case eContextAbsoluteBranchRegister:
- strm.PutCString ("absolute branch register");
- break;
-
- case eContextSupervisorCall:
- strm.PutCString ("supervisor call");
- break;
-
- case eContextTableBranchReadMemory:
- strm.PutCString ("table branch read memory");
- break;
-
- case eContextWriteRegisterRandomBits:
- strm.PutCString ("write random bits to a register");
- break;
-
- case eContextWriteMemoryRandomBits:
- strm.PutCString ("write random bits to a memory address");
- break;
-
- case eContextArithmetic:
- strm.PutCString ("arithmetic");
- break;
-
- case eContextReturnFromException:
- strm.PutCString ("return from exception");
- break;
-
- default:
- strm.PutCString ("unrecognized context.");
- break;
- }
-
- switch (info_type)
- {
- case eInfoTypeRegisterPlusOffset:
- strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
- info.RegisterPlusOffset.reg.name,
- info.RegisterPlusOffset.signed_offset);
- break;
-
- case eInfoTypeRegisterPlusIndirectOffset:
- strm.Printf(" (reg_plus_reg = %s + %s)",
- info.RegisterPlusIndirectOffset.base_reg.name,
- info.RegisterPlusIndirectOffset.offset_reg.name);
- break;
-
- case eInfoTypeRegisterToRegisterPlusOffset:
- strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
- info.RegisterToRegisterPlusOffset.base_reg.name,
- info.RegisterToRegisterPlusOffset.offset,
- info.RegisterToRegisterPlusOffset.data_reg.name);
- break;
-
- case eInfoTypeRegisterToRegisterPlusIndirectOffset:
- strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
- info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
- info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
- info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
- break;
-
- case eInfoTypeRegisterRegisterOperands:
- strm.Printf(" (register to register binary op: %s and %s)",
- info.RegisterRegisterOperands.operand1.name,
- info.RegisterRegisterOperands.operand2.name);
- break;
-
- case eInfoTypeOffset:
- strm.Printf (" (signed_offset = %+" PRId64 ")", info.signed_offset);
- break;
-
- case eInfoTypeRegister:
- strm.Printf (" (reg = %s)", info.reg.name);
- break;
-
- case eInfoTypeImmediate:
- strm.Printf (" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
- info.unsigned_immediate,
- info.unsigned_immediate);
- break;
-
- case eInfoTypeImmediateSigned:
- strm.Printf (" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
- info.signed_immediate,
- info.signed_immediate);
- break;
-
- case eInfoTypeAddress:
- strm.Printf (" (address = 0x%" PRIx64 ")", info.address);
- break;
-
- case eInfoTypeISAAndImmediate:
- strm.Printf (" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
- info.ISAAndImmediate.isa,
- info.ISAAndImmediate.unsigned_data32,
- info.ISAAndImmediate.unsigned_data32);
- break;
-
- case eInfoTypeISAAndImmediateSigned:
- strm.Printf (" (isa = %u, signed_immediate = %i (0x%8.8x))",
- info.ISAAndImmediateSigned.isa,
- info.ISAAndImmediateSigned.signed_data32,
- info.ISAAndImmediateSigned.signed_data32);
- break;
-
- case eInfoTypeISA:
- strm.Printf (" (isa = %u)", info.isa);
- break;
-
- case eInfoTypeNoArgs:
- break;
- }
+bool EmulateInstruction::ReadRegisterFrame(EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ if (baton == nullptr)
+ return false;
+
+ StackFrame *frame = (StackFrame *)baton;
+ return frame->GetRegisterContext()->ReadRegister(reg_info, reg_value);
}
-bool
-EmulateInstruction::SetInstruction (const Opcode &opcode, const Address &inst_addr, Target *target)
-{
- m_opcode = opcode;
- m_addr = LLDB_INVALID_ADDRESS;
- if (inst_addr.IsValid())
- {
- if (target != nullptr)
- m_addr = inst_addr.GetLoadAddress (target);
- if (m_addr == LLDB_INVALID_ADDRESS)
- m_addr = inst_addr.GetFileAddress ();
- }
+bool EmulateInstruction::WriteRegisterFrame(EmulateInstruction *instruction,
+ void *baton, const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ if (baton == nullptr)
+ return false;
+
+ StackFrame *frame = (StackFrame *)baton;
+ return frame->GetRegisterContext()->WriteRegister(reg_info, reg_value);
+}
+
+size_t EmulateInstruction::ReadMemoryDefault(EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ lldb::addr_t addr, void *dst,
+ size_t length) {
+ StreamFile strm(stdout, false);
+ strm.Printf(" Read from Memory (address = 0x%" PRIx64 ", length = %" PRIu64
+ ", context = ",
+ addr, (uint64_t)length);
+ context.Dump(strm, instruction);
+ strm.EOL();
+ *((uint64_t *)dst) = 0xdeadbeef;
+ return length;
+}
+
+size_t EmulateInstruction::WriteMemoryDefault(EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ lldb::addr_t addr,
+ const void *dst, size_t length) {
+ StreamFile strm(stdout, false);
+ strm.Printf(" Write to Memory (address = 0x%" PRIx64 ", length = %" PRIu64
+ ", context = ",
+ addr, (uint64_t)length);
+ context.Dump(strm, instruction);
+ strm.EOL();
+ return length;
+}
+
+bool EmulateInstruction::ReadRegisterDefault(EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue &reg_value) {
+ StreamFile strm(stdout, false);
+ strm.Printf(" Read Register (%s)\n", reg_info->name);
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ if (GetBestRegisterKindAndNumber(reg_info, reg_kind, reg_num))
+ reg_value.SetUInt64((uint64_t)reg_kind << 24 | reg_num);
+ else
+ reg_value.SetUInt64(0);
+
+ return true;
+}
+
+bool EmulateInstruction::WriteRegisterDefault(EmulateInstruction *instruction,
+ void *baton,
+ const Context &context,
+ const RegisterInfo *reg_info,
+ const RegisterValue &reg_value) {
+ StreamFile strm(stdout, false);
+ strm.Printf(" Write to Register (name = %s, value = ", reg_info->name);
+ reg_value.Dump(&strm, reg_info, false, false, eFormatDefault);
+ strm.PutCString(", context = ");
+ context.Dump(strm, instruction);
+ strm.EOL();
+ return true;
+}
+
+void EmulateInstruction::Context::Dump(Stream &strm,
+ EmulateInstruction *instruction) const {
+ switch (type) {
+ case eContextReadOpcode:
+ strm.PutCString("reading opcode");
+ break;
+
+ case eContextImmediate:
+ strm.PutCString("immediate");
+ break;
+
+ case eContextPushRegisterOnStack:
+ strm.PutCString("push register");
+ break;
+
+ case eContextPopRegisterOffStack:
+ strm.PutCString("pop register");
+ break;
+
+ case eContextAdjustStackPointer:
+ strm.PutCString("adjust sp");
+ break;
+
+ case eContextSetFramePointer:
+ strm.PutCString("set frame pointer");
+ break;
+
+ case eContextAdjustBaseRegister:
+ strm.PutCString("adjusting (writing value back to) a base register");
+ break;
+
+ case eContextRegisterPlusOffset:
+ strm.PutCString("register + offset");
+ break;
+
+ case eContextRegisterStore:
+ strm.PutCString("store register");
+ break;
+
+ case eContextRegisterLoad:
+ strm.PutCString("load register");
+ break;
+
+ case eContextRelativeBranchImmediate:
+ strm.PutCString("relative branch immediate");
+ break;
+
+ case eContextAbsoluteBranchRegister:
+ strm.PutCString("absolute branch register");
+ break;
+
+ case eContextSupervisorCall:
+ strm.PutCString("supervisor call");
+ break;
+
+ case eContextTableBranchReadMemory:
+ strm.PutCString("table branch read memory");
+ break;
+
+ case eContextWriteRegisterRandomBits:
+ strm.PutCString("write random bits to a register");
+ break;
+
+ case eContextWriteMemoryRandomBits:
+ strm.PutCString("write random bits to a memory address");
+ break;
+
+ case eContextArithmetic:
+ strm.PutCString("arithmetic");
+ break;
+
+ case eContextReturnFromException:
+ strm.PutCString("return from exception");
+ break;
+
+ default:
+ strm.PutCString("unrecognized context.");
+ break;
+ }
+
+ switch (info_type) {
+ case eInfoTypeRegisterPlusOffset:
+ strm.Printf(" (reg_plus_offset = %s%+" PRId64 ")",
+ info.RegisterPlusOffset.reg.name,
+ info.RegisterPlusOffset.signed_offset);
+ break;
+
+ case eInfoTypeRegisterPlusIndirectOffset:
+ strm.Printf(" (reg_plus_reg = %s + %s)",
+ info.RegisterPlusIndirectOffset.base_reg.name,
+ info.RegisterPlusIndirectOffset.offset_reg.name);
+ break;
+
+ case eInfoTypeRegisterToRegisterPlusOffset:
+ strm.Printf(" (base_and_imm_offset = %s%+" PRId64 ", data_reg = %s)",
+ info.RegisterToRegisterPlusOffset.base_reg.name,
+ info.RegisterToRegisterPlusOffset.offset,
+ info.RegisterToRegisterPlusOffset.data_reg.name);
+ break;
+
+ case eInfoTypeRegisterToRegisterPlusIndirectOffset:
+ strm.Printf(" (base_and_reg_offset = %s + %s, data_reg = %s)",
+ info.RegisterToRegisterPlusIndirectOffset.base_reg.name,
+ info.RegisterToRegisterPlusIndirectOffset.offset_reg.name,
+ info.RegisterToRegisterPlusIndirectOffset.data_reg.name);
+ break;
+
+ case eInfoTypeRegisterRegisterOperands:
+ strm.Printf(" (register to register binary op: %s and %s)",
+ info.RegisterRegisterOperands.operand1.name,
+ info.RegisterRegisterOperands.operand2.name);
+ break;
+
+ case eInfoTypeOffset:
+ strm.Printf(" (signed_offset = %+" PRId64 ")", info.signed_offset);
+ break;
+
+ case eInfoTypeRegister:
+ strm.Printf(" (reg = %s)", info.reg.name);
+ break;
+
+ case eInfoTypeImmediate:
+ strm.Printf(" (unsigned_immediate = %" PRIu64 " (0x%16.16" PRIx64 "))",
+ info.unsigned_immediate, info.unsigned_immediate);
+ break;
+
+ case eInfoTypeImmediateSigned:
+ strm.Printf(" (signed_immediate = %+" PRId64 " (0x%16.16" PRIx64 "))",
+ info.signed_immediate, info.signed_immediate);
+ break;
+
+ case eInfoTypeAddress:
+ strm.Printf(" (address = 0x%" PRIx64 ")", info.address);
+ break;
+
+ case eInfoTypeISAAndImmediate:
+ strm.Printf(" (isa = %u, unsigned_immediate = %u (0x%8.8x))",
+ info.ISAAndImmediate.isa, info.ISAAndImmediate.unsigned_data32,
+ info.ISAAndImmediate.unsigned_data32);
+ break;
+
+ case eInfoTypeISAAndImmediateSigned:
+ strm.Printf(" (isa = %u, signed_immediate = %i (0x%8.8x))",
+ info.ISAAndImmediateSigned.isa,
+ info.ISAAndImmediateSigned.signed_data32,
+ info.ISAAndImmediateSigned.signed_data32);
+ break;
+
+ case eInfoTypeISA:
+ strm.Printf(" (isa = %u)", info.isa);
+ break;
+
+ case eInfoTypeNoArgs:
+ break;
+ }
+}
+
+bool EmulateInstruction::SetInstruction(const Opcode &opcode,
+ const Address &inst_addr,
+ Target *target) {
+ m_opcode = opcode;
+ m_addr = LLDB_INVALID_ADDRESS;
+ if (inst_addr.IsValid()) {
+ if (target != nullptr)
+ m_addr = inst_addr.GetLoadAddress(target);
+ if (m_addr == LLDB_INVALID_ADDRESS)
+ m_addr = inst_addr.GetFileAddress();
+ }
+ return true;
+}
+
+bool EmulateInstruction::GetBestRegisterKindAndNumber(
+ const RegisterInfo *reg_info, lldb::RegisterKind &reg_kind,
+ uint32_t &reg_num) {
+ // Generic and DWARF should be the two most popular register kinds when
+ // emulating instructions since they are the most platform agnostic...
+ reg_num = reg_info->kinds[eRegisterKindGeneric];
+ if (reg_num != LLDB_INVALID_REGNUM) {
+ reg_kind = eRegisterKindGeneric;
return true;
-}
+ }
-bool
-EmulateInstruction::GetBestRegisterKindAndNumber (const RegisterInfo *reg_info,
- lldb::RegisterKind &reg_kind,
- uint32_t &reg_num)
-{
- // Generic and DWARF should be the two most popular register kinds when
- // emulating instructions since they are the most platform agnostic...
- reg_num = reg_info->kinds[eRegisterKindGeneric];
- if (reg_num != LLDB_INVALID_REGNUM)
- {
- reg_kind = eRegisterKindGeneric;
- return true;
- }
-
- reg_num = reg_info->kinds[eRegisterKindDWARF];
- if (reg_num != LLDB_INVALID_REGNUM)
- {
- reg_kind = eRegisterKindDWARF;
- return true;
- }
+ reg_num = reg_info->kinds[eRegisterKindDWARF];
+ if (reg_num != LLDB_INVALID_REGNUM) {
+ reg_kind = eRegisterKindDWARF;
+ return true;
+ }
- reg_num = reg_info->kinds[eRegisterKindLLDB];
- if (reg_num != LLDB_INVALID_REGNUM)
- {
- reg_kind = eRegisterKindLLDB;
- return true;
- }
+ reg_num = reg_info->kinds[eRegisterKindLLDB];
+ if (reg_num != LLDB_INVALID_REGNUM) {
+ reg_kind = eRegisterKindLLDB;
+ return true;
+ }
- reg_num = reg_info->kinds[eRegisterKindEHFrame];
- if (reg_num != LLDB_INVALID_REGNUM)
- {
- reg_kind = eRegisterKindEHFrame;
- return true;
- }
+ reg_num = reg_info->kinds[eRegisterKindEHFrame];
+ if (reg_num != LLDB_INVALID_REGNUM) {
+ reg_kind = eRegisterKindEHFrame;
+ return true;
+ }
- reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
- if (reg_num != LLDB_INVALID_REGNUM)
- {
- reg_kind = eRegisterKindProcessPlugin;
- return true;
- }
- return false;
+ reg_num = reg_info->kinds[eRegisterKindProcessPlugin];
+ if (reg_num != LLDB_INVALID_REGNUM) {
+ reg_kind = eRegisterKindProcessPlugin;
+ return true;
+ }
+ return false;
}
uint32_t
-EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo &reg_info)
-{
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- if (reg_ctx && GetBestRegisterKindAndNumber (&reg_info, reg_kind, reg_num))
- return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
- return LLDB_INVALID_REGNUM;
-}
-
-bool
-EmulateInstruction::CreateFunctionEntryUnwind (UnwindPlan &unwind_plan)
-{
- unwind_plan.Clear();
- return false;
+EmulateInstruction::GetInternalRegisterNumber(RegisterContext *reg_ctx,
+ const RegisterInfo &reg_info) {
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ if (reg_ctx && GetBestRegisterKindAndNumber(&reg_info, reg_kind, reg_num))
+ return reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
+ return LLDB_INVALID_REGNUM;
+}
+
+bool EmulateInstruction::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ return false;
}
diff --git a/source/Core/Error.cpp b/source/Core/Error.cpp
index 97c2c4cc5b67..23696127d3b4 100644
--- a/source/Core/Error.cpp
+++ b/source/Core/Error.cpp
@@ -22,63 +22,47 @@
// Project includes
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
+#include "lldb/Host/PosixApi.h"
using namespace lldb;
using namespace lldb_private;
-Error::Error ():
- m_code (0),
- m_type (eErrorTypeInvalid),
- m_string ()
-{
-}
+Error::Error() : m_code(0), m_type(eErrorTypeInvalid), m_string() {}
-Error::Error(ValueType err, ErrorType type) :
- m_code (err),
- m_type (type),
- m_string ()
-{
-}
+Error::Error(ValueType err, ErrorType type)
+ : m_code(err), m_type(type), m_string() {}
Error::Error(const Error &rhs) = default;
-Error::Error (const char* format, ...):
- m_code (0),
- m_type (eErrorTypeInvalid),
- m_string ()
-{
- va_list args;
- va_start (args, format);
- SetErrorToGenericError ();
- SetErrorStringWithVarArg (format, args);
- va_end (args);
+Error::Error(const char *format, ...)
+ : m_code(0), m_type(eErrorTypeInvalid), m_string() {
+ va_list args;
+ va_start(args, format);
+ SetErrorToGenericError();
+ SetErrorStringWithVarArg(format, args);
+ va_end(args);
}
//----------------------------------------------------------------------
// Assignment operator
//----------------------------------------------------------------------
-const Error&
-Error::operator = (const Error& rhs)
-{
- if (this != &rhs)
- {
- m_code = rhs.m_code;
- m_type = rhs.m_type;
- m_string = rhs.m_string;
- }
- return *this;
+const Error &Error::operator=(const Error &rhs) {
+ if (this != &rhs) {
+ m_code = rhs.m_code;
+ m_type = rhs.m_type;
+ m_string = rhs.m_string;
+ }
+ return *this;
}
//----------------------------------------------------------------------
// Assignment operator
//----------------------------------------------------------------------
-const Error&
-Error::operator = (uint32_t err)
-{
- m_code = err;
- m_type = eErrorTypeMachKernel;
- m_string.clear();
- return *this;
+const Error &Error::operator=(uint32_t err) {
+ m_code = err;
+ m_type = eErrorTypeMachKernel;
+ m_string.clear();
+ return *this;
}
Error::~Error() = default;
@@ -88,81 +72,62 @@ Error::~Error() = default;
// fetched and cached on demand. The cached error string value will
// remain until the error value is changed or cleared.
//----------------------------------------------------------------------
-const char *
-Error::AsCString(const char *default_error_str) const
-{
- if (Success())
- return nullptr;
-
- if (m_string.empty())
- {
- const char *s = nullptr;
- switch (m_type)
- {
- case eErrorTypeMachKernel:
-#if defined (__APPLE__)
- s = ::mach_error_string (m_code);
+const char *Error::AsCString(const char *default_error_str) const {
+ if (Success())
+ return nullptr;
+
+ if (m_string.empty()) {
+ const char *s = nullptr;
+ switch (m_type) {
+ case eErrorTypeMachKernel:
+#if defined(__APPLE__)
+ s = ::mach_error_string(m_code);
#endif
- break;
+ break;
- case eErrorTypePOSIX:
- s = ::strerror (m_code);
- break;
+ case eErrorTypePOSIX:
+ s = ::strerror(m_code);
+ break;
- default:
- break;
- }
- if (s != nullptr)
- m_string.assign(s);
+ default:
+ break;
}
- if (m_string.empty())
- {
- if (default_error_str)
- m_string.assign(default_error_str);
- else
- return nullptr; // User wanted a nullptr string back...
- }
- return m_string.c_str();
+ if (s != nullptr)
+ m_string.assign(s);
+ }
+ if (m_string.empty()) {
+ if (default_error_str)
+ m_string.assign(default_error_str);
+ else
+ return nullptr; // User wanted a nullptr string back...
+ }
+ return m_string.c_str();
}
//----------------------------------------------------------------------
// Clear the error and any cached error string that it might contain.
//----------------------------------------------------------------------
-void
-Error::Clear ()
-{
- m_code = 0;
- m_type = eErrorTypeInvalid;
- m_string.clear();
+void Error::Clear() {
+ m_code = 0;
+ m_type = eErrorTypeInvalid;
+ m_string.clear();
}
//----------------------------------------------------------------------
// Access the error value.
//----------------------------------------------------------------------
-Error::ValueType
-Error::GetError () const
-{
- return m_code;
-}
+Error::ValueType Error::GetError() const { return m_code; }
//----------------------------------------------------------------------
// Access the error type.
//----------------------------------------------------------------------
-ErrorType
-Error::GetType () const
-{
- return m_type;
-}
+ErrorType Error::GetType() const { return m_type; }
//----------------------------------------------------------------------
-// Retuns true if this object contains an value that describes an
+// Returns true if this object contains a value that describes an
// error or otherwise non-success result.
//----------------------------------------------------------------------
-bool
-Error::Fail () const
-{
- return m_code != 0;
-}
+bool Error::Fail() const { return m_code != 0; }
//----------------------------------------------------------------------
// Log the error given a string with format. If the this object
@@ -173,34 +138,29 @@ Error::Fail () const
// cached in this object. Logging always occurs even when the error
// code contains a non-error value.
//----------------------------------------------------------------------
-void
-Error::PutToLog (Log *log, const char *format, ...)
-{
- char *arg_msg = nullptr;
- va_list args;
- va_start (args, format);
- ::vasprintf (&arg_msg, format, args);
- va_end (args);
-
- if (arg_msg != nullptr)
- {
- if (Fail())
- {
- const char *err_str = AsCString();
- if (err_str == nullptr)
- err_str = "???";
-
- SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
- if (log != nullptr)
- log->Error("%s", m_string.c_str());
- }
- else
- {
- if (log != nullptr)
- log->Printf("%s err = 0x%8.8x", arg_msg, m_code);
- }
- ::free (arg_msg);
+void Error::PutToLog(Log *log, const char *format, ...) {
+ char *arg_msg = nullptr;
+ va_list args;
+ va_start(args, format);
+ ::vasprintf(&arg_msg, format, args);
+ va_end(args);
+
+ if (arg_msg != nullptr) {
+ if (Fail()) {
+ const char *err_str = AsCString();
+ if (err_str == nullptr)
+ err_str = "???";
+
+ SetErrorStringWithFormat("error: %s err = %s (0x%8.8x)", arg_msg, err_str,
+ m_code);
+ if (log != nullptr)
+ log->Error("%s", m_string.c_str());
+ } else {
+ if (log != nullptr)
+ log->Printf("%s err = 0x%8.8x", arg_msg, m_code);
}
+ ::free(arg_msg);
+ }
}
//----------------------------------------------------------------------
@@ -212,106 +172,90 @@ Error::PutToLog (Log *log, const char *format, ...)
// cached in this object. Logging only occurs even when the error
// code contains a error value.
//----------------------------------------------------------------------
-void
-Error::LogIfError (Log *log, const char *format, ...)
-{
- if (Fail())
- {
- char *arg_msg = nullptr;
- va_list args;
- va_start (args, format);
- ::vasprintf (&arg_msg, format, args);
- va_end (args);
-
- if (arg_msg != nullptr)
- {
- const char *err_str = AsCString();
- if (err_str == nullptr)
- err_str = "???";
-
- SetErrorStringWithFormat("%s err = %s (0x%8.8x)", arg_msg, err_str, m_code);
- if (log != nullptr)
- log->Error("%s", m_string.c_str());
-
- ::free (arg_msg);
- }
+void Error::LogIfError(Log *log, const char *format, ...) {
+ if (Fail()) {
+ char *arg_msg = nullptr;
+ va_list args;
+ va_start(args, format);
+ ::vasprintf(&arg_msg, format, args);
+ va_end(args);
+
+ if (arg_msg != nullptr) {
+ const char *err_str = AsCString();
+ if (err_str == nullptr)
+ err_str = "???";
+
+ SetErrorStringWithFormat("%s err = %s (0x%8.8x)", arg_msg, err_str,
+ m_code);
+ if (log != nullptr)
+ log->Error("%s", m_string.c_str());
+
+ ::free(arg_msg);
}
+ }
}
//----------------------------------------------------------------------
// Set accesssor for the error value to "err" and the type to
// "eErrorTypeMachKernel"
//----------------------------------------------------------------------
-void
-Error::SetMachError (uint32_t err)
-{
- m_code = err;
- m_type = eErrorTypeMachKernel;
- m_string.clear();
+void Error::SetMachError(uint32_t err) {
+ m_code = err;
+ m_type = eErrorTypeMachKernel;
+ m_string.clear();
}
-void
-Error::SetExpressionError (lldb::ExpressionResults result, const char *mssg)
-{
- m_code = result;
- m_type = eErrorTypeExpression;
- m_string = mssg;
+void Error::SetExpressionError(lldb::ExpressionResults result,
+ const char *mssg) {
+ m_code = result;
+ m_type = eErrorTypeExpression;
+ m_string = mssg;
}
-int
-Error::SetExpressionErrorWithFormat (lldb::ExpressionResults result, const char *format, ...)
-{
- int length = 0;
-
- if (format != nullptr && format[0])
- {
- va_list args;
- va_start (args, format);
- length = SetErrorStringWithVarArg (format, args);
- va_end (args);
- }
- else
- {
- m_string.clear();
- }
- m_code = result;
- m_type = eErrorTypeExpression;
- return length;
+int Error::SetExpressionErrorWithFormat(lldb::ExpressionResults result,
+ const char *format, ...) {
+ int length = 0;
+
+ if (format != nullptr && format[0]) {
+ va_list args;
+ va_start(args, format);
+ length = SetErrorStringWithVarArg(format, args);
+ va_end(args);
+ } else {
+ m_string.clear();
+ }
+ m_code = result;
+ m_type = eErrorTypeExpression;
+ return length;
}
//----------------------------------------------------------------------
// Set accesssor for the error value and type.
//----------------------------------------------------------------------
-void
-Error::SetError (ValueType err, ErrorType type)
-{
- m_code = err;
- m_type = type;
- m_string.clear();
+void Error::SetError(ValueType err, ErrorType type) {
+ m_code = err;
+ m_type = type;
+ m_string.clear();
}
//----------------------------------------------------------------------
// Update the error value to be "errno" and update the type to
// be "POSIX".
//----------------------------------------------------------------------
-void
-Error::SetErrorToErrno()
-{
- m_code = errno;
- m_type = eErrorTypePOSIX;
- m_string.clear();
+void Error::SetErrorToErrno() {
+ m_code = errno;
+ m_type = eErrorTypePOSIX;
+ m_string.clear();
}
//----------------------------------------------------------------------
// Update the error value to be LLDB_GENERIC_ERROR and update the type
// to be "Generic".
//----------------------------------------------------------------------
-void
-Error::SetErrorToGenericError ()
-{
- m_code = LLDB_GENERIC_ERROR;
- m_type = eErrorTypeGeneric;
- m_string.clear();
+void Error::SetErrorToGenericError() {
+ m_code = LLDB_GENERIC_ERROR;
+ m_type = eErrorTypeGeneric;
+ m_string.clear();
}
//----------------------------------------------------------------------
@@ -320,19 +264,14 @@ Error::SetErrorToGenericError ()
// The error string value will remain until the error value is
// cleared or a new error value/type is assigned.
//----------------------------------------------------------------------
-void
-Error::SetErrorString (const char *err_str)
-{
- if (err_str != nullptr && err_str[0])
- {
- // If we have an error string, we should always at least have
- // an error set to a generic value.
- if (Success())
- SetErrorToGenericError();
- m_string = err_str;
- }
- else
- m_string.clear();
+void Error::SetErrorString(llvm::StringRef err_str) {
+ if (!err_str.empty()) {
+ // If we have an error string, we should always at least have an error
+ // set to a generic value.
+ if (Success())
+ SetErrorToGenericError();
+ }
+ m_string = err_str;
}
//------------------------------------------------------------------
@@ -341,74 +280,57 @@ Error::SetErrorString (const char *err_str)
/// @param format
/// A printf style format string
//------------------------------------------------------------------
-int
-Error::SetErrorStringWithFormat (const char *format, ...)
-{
- if (format != nullptr && format[0])
- {
- va_list args;
- va_start (args, format);
- int length = SetErrorStringWithVarArg (format, args);
- va_end (args);
- return length;
- }
- else
- {
- m_string.clear();
- }
- return 0;
+int Error::SetErrorStringWithFormat(const char *format, ...) {
+ if (format != nullptr && format[0]) {
+ va_list args;
+ va_start(args, format);
+ int length = SetErrorStringWithVarArg(format, args);
+ va_end(args);
+ return length;
+ } else {
+ m_string.clear();
+ }
+ return 0;
}
-int
-Error::SetErrorStringWithVarArg (const char *format, va_list args)
-{
- if (format != nullptr && format[0])
- {
- // If we have an error string, we should always at least have
- // an error set to a generic value.
- if (Success())
- SetErrorToGenericError();
-
- // Try and fit our error into a 1024 byte buffer first...
- llvm::SmallVector<char, 1024> buf;
- buf.resize(1024);
- // Copy in case our first call to vsnprintf doesn't fit into our
- // allocated buffer above
- va_list copy_args;
- va_copy (copy_args, args);
- unsigned length = ::vsnprintf (buf.data(), buf.size(), format, args);
- if (length >= buf.size())
- {
- // The error formatted string didn't fit into our buffer, resize it
- // to the exact needed size, and retry
- buf.resize(length + 1);
- length = ::vsnprintf (buf.data(), buf.size(), format, copy_args);
- va_end (copy_args);
- assert (length < buf.size());
- }
- m_string.assign(buf.data(), length);
- va_end (args);
- return length;
- }
- else
- {
- m_string.clear();
+int Error::SetErrorStringWithVarArg(const char *format, va_list args) {
+ if (format != nullptr && format[0]) {
+ // If we have an error string, we should always at least have
+ // an error set to a generic value.
+ if (Success())
+ SetErrorToGenericError();
+
+ // Try and fit our error into a 1024 byte buffer first...
+ llvm::SmallVector<char, 1024> buf;
+ buf.resize(1024);
+ // Copy in case our first call to vsnprintf doesn't fit into our
+ // allocated buffer above
+ va_list copy_args;
+ va_copy(copy_args, args);
+ unsigned length = ::vsnprintf(buf.data(), buf.size(), format, args);
+ if (length >= buf.size()) {
+ // The error formatted string didn't fit into our buffer, resize it
+ // to the exact needed size, and retry
+ buf.resize(length + 1);
+ length = ::vsnprintf(buf.data(), buf.size(), format, copy_args);
+ va_end(copy_args);
+ assert(length < buf.size());
}
- return 0;
+ m_string.assign(buf.data(), length);
+ va_end(args);
+ return length;
+ } else {
+ m_string.clear();
+ }
+ return 0;
}
//----------------------------------------------------------------------
// Returns true if the error code in this object is considered a
// successful return value.
//----------------------------------------------------------------------
-bool
-Error::Success() const
-{
- return m_code == 0;
-}
+bool Error::Success() const { return m_code == 0; }
-bool
-Error::WasInterrupted() const
-{
- return (m_type == eErrorTypePOSIX && m_code == EINTR);
+bool Error::WasInterrupted() const {
+ return (m_type == eErrorTypePOSIX && m_code == EINTR);
}
diff --git a/source/Core/Event.cpp b/source/Core/Event.cpp
index 6b07e4d91987..bd57198f5487 100644
--- a/source/Core/Event.cpp
+++ b/source/Core/Event.cpp
@@ -13,9 +13,9 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/Event.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Event.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Stream.h"
@@ -25,202 +25,280 @@
using namespace lldb;
using namespace lldb_private;
-Event::Event (Broadcaster *broadcaster, uint32_t event_type, EventData *data) :
- m_broadcaster_wp(broadcaster->GetBroadcasterImpl()),
- m_type(event_type),
- m_data_sp(data)
-{
-}
+#pragma mark -
+#pragma mark Event
-Event::Event (Broadcaster *broadcaster, uint32_t event_type, const EventDataSP &event_data_sp) :
- m_broadcaster_wp(broadcaster->GetBroadcasterImpl()),
- m_type(event_type),
- m_data_sp(event_data_sp)
-{
-}
+//------------------------------------------------------------------
+// Event functions
+//------------------------------------------------------------------
-Event::Event(uint32_t event_type, EventData *data) :
- m_broadcaster_wp(),
- m_type(event_type),
- m_data_sp(data)
-{
-}
+Event::Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data)
+ : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type),
+ m_data_sp(data) {}
-Event::Event(uint32_t event_type, const EventDataSP &event_data_sp) :
- m_broadcaster_wp(),
- m_type(event_type),
- m_data_sp(event_data_sp)
-{
-}
+Event::Event(Broadcaster *broadcaster, uint32_t event_type,
+ const EventDataSP &event_data_sp)
+ : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type),
+ m_data_sp(event_data_sp) {}
+
+Event::Event(uint32_t event_type, EventData *data)
+ : m_broadcaster_wp(), m_type(event_type), m_data_sp(data) {}
+
+Event::Event(uint32_t event_type, const EventDataSP &event_data_sp)
+ : m_broadcaster_wp(), m_type(event_type), m_data_sp(event_data_sp) {}
Event::~Event() = default;
-void
-Event::Dump (Stream *s) const
-{
- Broadcaster *broadcaster;
- Broadcaster::BroadcasterImplSP broadcaster_impl_sp(m_broadcaster_wp.lock());
- if (broadcaster_impl_sp)
- broadcaster = broadcaster_impl_sp->GetBroadcaster();
- else
- broadcaster = nullptr;
-
- if (broadcaster)
- {
- StreamString event_name;
- if (broadcaster->GetEventNames (event_name, m_type, false))
- s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ",
- static_cast<const void*>(this),
- static_cast<void*>(broadcaster),
- broadcaster->GetBroadcasterName().GetCString(),
- m_type, event_name.GetString().c_str());
- else
- s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ",
- static_cast<const void*>(this),
- static_cast<void*>(broadcaster),
- broadcaster->GetBroadcasterName().GetCString(), m_type);
- }
- else
- s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ",
- static_cast<const void*>(this), m_type);
-
- if (m_data_sp)
- {
- s->PutChar('{');
- m_data_sp->Dump (s);
- s->PutChar('}');
- }
+void Event::Dump(Stream *s) const {
+ Broadcaster *broadcaster;
+ Broadcaster::BroadcasterImplSP broadcaster_impl_sp(m_broadcaster_wp.lock());
+ if (broadcaster_impl_sp)
+ broadcaster = broadcaster_impl_sp->GetBroadcaster();
+ else
+ broadcaster = nullptr;
+
+ if (broadcaster) {
+ StreamString event_name;
+ if (broadcaster->GetEventNames(event_name, m_type, false))
+ s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ",
+ static_cast<const void *>(this),
+ static_cast<void *>(broadcaster),
+ broadcaster->GetBroadcasterName().GetCString(), m_type,
+ event_name.GetData());
else
- s->Printf ("<NULL>");
+ s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ",
+ static_cast<const void *>(this),
+ static_cast<void *>(broadcaster),
+ broadcaster->GetBroadcasterName().GetCString(), m_type);
+ } else
+ s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ",
+ static_cast<const void *>(this), m_type);
+
+ if (m_data_sp) {
+ s->PutChar('{');
+ m_data_sp->Dump(s);
+ s->PutChar('}');
+ } else
+ s->Printf("<NULL>");
}
-void
-Event::DoOnRemoval ()
-{
- if (m_data_sp)
- m_data_sp->DoOnRemoval (this);
+void Event::DoOnRemoval() {
+ if (m_data_sp)
+ m_data_sp->DoOnRemoval(this);
}
+#pragma mark -
+#pragma mark EventData
+
+//------------------------------------------------------------------
+// EventData functions
+//------------------------------------------------------------------
+
EventData::EventData() = default;
EventData::~EventData() = default;
-void
-EventData::Dump (Stream *s) const
-{
- s->PutCString ("Generic Event Data");
-}
+void EventData::Dump(Stream *s) const { s->PutCString("Generic Event Data"); }
-EventDataBytes::EventDataBytes () :
- m_bytes()
-{
+#pragma mark -
+#pragma mark EventDataBytes
+
+//------------------------------------------------------------------
+// EventDataBytes functions
+//------------------------------------------------------------------
+
+EventDataBytes::EventDataBytes() : m_bytes() {}
+
+EventDataBytes::EventDataBytes(const char *cstr) : m_bytes() {
+ SetBytesFromCString(cstr);
}
-EventDataBytes::EventDataBytes (const char *cstr) :
- m_bytes()
-{
- SetBytesFromCString (cstr);
+EventDataBytes::EventDataBytes(llvm::StringRef str) : m_bytes() {
+ SetBytes(str.data(), str.size());
}
-EventDataBytes::EventDataBytes (const void *src, size_t src_len) :
- m_bytes()
-{
- SetBytes (src, src_len);
+EventDataBytes::EventDataBytes(const void *src, size_t src_len) : m_bytes() {
+ SetBytes(src, src_len);
}
EventDataBytes::~EventDataBytes() = default;
-const ConstString &
-EventDataBytes::GetFlavorString ()
-{
- static ConstString g_flavor ("EventDataBytes");
- return g_flavor;
+const ConstString &EventDataBytes::GetFlavorString() {
+ static ConstString g_flavor("EventDataBytes");
+ return g_flavor;
}
-const ConstString &
-EventDataBytes::GetFlavor () const
-{
- return EventDataBytes::GetFlavorString ();
+const ConstString &EventDataBytes::GetFlavor() const {
+ return EventDataBytes::GetFlavorString();
}
-void
-EventDataBytes::Dump (Stream *s) const
-{
- size_t num_printable_chars = std::count_if (m_bytes.begin(), m_bytes.end(), isprint);
- if (num_printable_chars == m_bytes.size())
- {
- s->Printf("\"%s\"", m_bytes.c_str());
- }
- else if (!m_bytes.empty())
- {
- DataExtractor data;
- data.SetData(m_bytes.data(), m_bytes.size(), endian::InlHostByteOrder());
- data.Dump(s, 0, eFormatBytes, 1, m_bytes.size(), 32, LLDB_INVALID_ADDRESS, 0, 0);
- }
+void EventDataBytes::Dump(Stream *s) const {
+ size_t num_printable_chars =
+ std::count_if(m_bytes.begin(), m_bytes.end(), isprint);
+ if (num_printable_chars == m_bytes.size()) {
+ s->Printf("\"%s\"", m_bytes.c_str());
+ } else if (!m_bytes.empty()) {
+ DataExtractor data;
+ data.SetData(m_bytes.data(), m_bytes.size(), endian::InlHostByteOrder());
+ data.Dump(s, 0, eFormatBytes, 1, m_bytes.size(), 32, LLDB_INVALID_ADDRESS,
+ 0, 0);
+ }
}
-const void *
-EventDataBytes::GetBytes() const
-{
- return (m_bytes.empty() ? nullptr : m_bytes.data());
+const void *EventDataBytes::GetBytes() const {
+ return (m_bytes.empty() ? nullptr : m_bytes.data());
}
-size_t
-EventDataBytes::GetByteSize() const
-{
- return m_bytes.size ();
-}
+size_t EventDataBytes::GetByteSize() const { return m_bytes.size(); }
-void
-EventDataBytes::SetBytes (const void *src, size_t src_len)
-{
- if (src != nullptr && src_len > 0)
- m_bytes.assign ((const char *)src, src_len);
- else
- m_bytes.clear();
+void EventDataBytes::SetBytes(const void *src, size_t src_len) {
+ if (src != nullptr && src_len > 0)
+ m_bytes.assign((const char *)src, src_len);
+ else
+ m_bytes.clear();
}
-void
-EventDataBytes::SetBytesFromCString (const char *cstr)
-{
- if (cstr != nullptr && cstr[0])
- m_bytes.assign (cstr);
- else
- m_bytes.clear();
+void EventDataBytes::SetBytesFromCString(const char *cstr) {
+ if (cstr != nullptr && cstr[0])
+ m_bytes.assign(cstr);
+ else
+ m_bytes.clear();
}
-const void *
-EventDataBytes::GetBytesFromEvent (const Event *event_ptr)
-{
- const EventDataBytes *e = GetEventDataFromEvent (event_ptr);
- if (e != nullptr)
- return e->GetBytes();
- return nullptr;
+const void *EventDataBytes::GetBytesFromEvent(const Event *event_ptr) {
+ const EventDataBytes *e = GetEventDataFromEvent(event_ptr);
+ if (e != nullptr)
+ return e->GetBytes();
+ return nullptr;
}
-size_t
-EventDataBytes::GetByteSizeFromEvent (const Event *event_ptr)
-{
- const EventDataBytes *e = GetEventDataFromEvent (event_ptr);
- if (e != nullptr)
- return e->GetByteSize();
- return 0;
+size_t EventDataBytes::GetByteSizeFromEvent(const Event *event_ptr) {
+ const EventDataBytes *e = GetEventDataFromEvent(event_ptr);
+ if (e != nullptr)
+ return e->GetByteSize();
+ return 0;
}
const EventDataBytes *
-EventDataBytes::GetEventDataFromEvent (const Event *event_ptr)
-{
- if (event_ptr != nullptr)
- {
- const EventData *event_data = event_ptr->GetData();
- if (event_data && event_data->GetFlavor() == EventDataBytes::GetFlavorString())
- return static_cast <const EventDataBytes *> (event_data);
- }
+EventDataBytes::GetEventDataFromEvent(const Event *event_ptr) {
+ if (event_ptr != nullptr) {
+ const EventData *event_data = event_ptr->GetData();
+ if (event_data &&
+ event_data->GetFlavor() == EventDataBytes::GetFlavorString())
+ return static_cast<const EventDataBytes *>(event_data);
+ }
+ return nullptr;
+}
+
+void EventDataBytes::SwapBytes(std::string &new_bytes) {
+ m_bytes.swap(new_bytes);
+}
+
+#pragma mark -
+#pragma mark EventStructuredData
+
+//------------------------------------------------------------------
+// EventDataStructuredData definitions
+//------------------------------------------------------------------
+
+EventDataStructuredData::EventDataStructuredData()
+ : EventData(), m_process_sp(), m_object_sp(), m_plugin_sp() {}
+
+EventDataStructuredData::EventDataStructuredData(
+ const ProcessSP &process_sp, const StructuredData::ObjectSP &object_sp,
+ const lldb::StructuredDataPluginSP &plugin_sp)
+ : EventData(), m_process_sp(process_sp), m_object_sp(object_sp),
+ m_plugin_sp(plugin_sp) {}
+
+EventDataStructuredData::~EventDataStructuredData() {}
+
+//------------------------------------------------------------------
+// EventDataStructuredData member functions
+//------------------------------------------------------------------
+
+const ConstString &EventDataStructuredData::GetFlavor() const {
+ return EventDataStructuredData::GetFlavorString();
+}
+
+void EventDataStructuredData::Dump(Stream *s) const {
+ if (!s)
+ return;
+
+ if (m_object_sp)
+ m_object_sp->Dump(*s);
+}
+
+const ProcessSP &EventDataStructuredData::GetProcess() const {
+ return m_process_sp;
+}
+
+const StructuredData::ObjectSP &EventDataStructuredData::GetObject() const {
+ return m_object_sp;
+}
+
+const lldb::StructuredDataPluginSP &
+EventDataStructuredData::GetStructuredDataPlugin() const {
+ return m_plugin_sp;
+}
+
+void EventDataStructuredData::SetProcess(const ProcessSP &process_sp) {
+ m_process_sp = process_sp;
+}
+
+void EventDataStructuredData::SetObject(
+ const StructuredData::ObjectSP &object_sp) {
+ m_object_sp = object_sp;
+}
+
+void EventDataStructuredData::SetStructuredDataPlugin(
+ const lldb::StructuredDataPluginSP &plugin_sp) {
+ m_plugin_sp = plugin_sp;
+}
+
+//------------------------------------------------------------------
+// EventDataStructuredData static functions
+//------------------------------------------------------------------
+
+const EventDataStructuredData *
+EventDataStructuredData::GetEventDataFromEvent(const Event *event_ptr) {
+ if (event_ptr == nullptr)
+ return nullptr;
+
+ const EventData *event_data = event_ptr->GetData();
+ if (!event_data ||
+ event_data->GetFlavor() != EventDataStructuredData::GetFlavorString())
return nullptr;
+
+ return static_cast<const EventDataStructuredData *>(event_data);
+}
+
+ProcessSP EventDataStructuredData::GetProcessFromEvent(const Event *event_ptr) {
+ auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
+ if (event_data)
+ return event_data->GetProcess();
+ else
+ return ProcessSP();
+}
+
+StructuredData::ObjectSP
+EventDataStructuredData::GetObjectFromEvent(const Event *event_ptr) {
+ auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
+ if (event_data)
+ return event_data->GetObject();
+ else
+ return StructuredData::ObjectSP();
+}
+
+lldb::StructuredDataPluginSP
+EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr) {
+ auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
+ if (event_data)
+ return event_data->GetStructuredDataPlugin();
+ else
+ return StructuredDataPluginSP();
}
-void
-EventDataBytes::SwapBytes (std::string &new_bytes)
-{
- m_bytes.swap (new_bytes);
+const ConstString &EventDataStructuredData::GetFlavorString() {
+ static ConstString s_flavor("EventDataStructuredData");
+ return s_flavor;
}
diff --git a/source/Core/FastDemangle.cpp b/source/Core/FastDemangle.cpp
index 528f7f6bd88d..0bed4a1f20ad 100644
--- a/source/Core/FastDemangle.cpp
+++ b/source/Core/FastDemangle.cpp
@@ -8,9 +8,12 @@
//===----------------------------------------------------------------------===//
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
+
+#include <functional>
+#include "lldb/Core/FastDemangle.h"
#include "lldb/lldb-private.h"
//#define DEBUG_FAILURES 1
@@ -23,57 +26,52 @@ namespace {
/// @brief Represents the collection of qualifiers on a type
-enum Qualifiers
-{
- QualifierNone = 0,
- QualifierConst = 1,
- QualifierRestrict = 2,
- QualifierVolatile = 4,
- QualifierReference = 8,
- QualifierRValueReference = 16,
- QualifierPointer = 32
+enum Qualifiers {
+ QualifierNone = 0,
+ QualifierConst = 1,
+ QualifierRestrict = 2,
+ QualifierVolatile = 4,
+ QualifierReference = 8,
+ QualifierRValueReference = 16,
+ QualifierPointer = 32
};
/// @brief Categorizes the recognized operators
-enum class OperatorKind
-{
- Unary,
- Postfix,
- Binary,
- Ternary,
- Other,
- ConversionOperator,
- Vendor,
- NoMatch
+enum class OperatorKind {
+ Unary,
+ Postfix,
+ Binary,
+ Ternary,
+ Other,
+ ConversionOperator,
+ Vendor,
+ NoMatch
};
/// @brief Represents one of the recognized two-character operator
/// abbreviations used when parsing operators as names and expressions
-struct Operator
-{
- const char *name;
- OperatorKind kind;
+struct Operator {
+ const char *name;
+ OperatorKind kind;
};
/// @brief Represents a range of characters in the output buffer, typically for
/// use with RewriteRange()
-struct BufferRange
-{
- int offset;
- int length;
+struct BufferRange {
+ int offset;
+ int length;
};
/// @brief Transient state required while parsing a name
-struct NameState
-{
- bool parse_function_params;
- bool is_last_generic;
- bool has_no_return_type;
- BufferRange last_name_range;
+struct NameState {
+ bool parse_function_params;
+ bool is_last_generic;
+ bool has_no_return_type;
+ BufferRange last_name_range;
};
/// @brief LLDB's fast C++ demangler
@@ -86,942 +84,919 @@ struct NameState
/// Over time the full mangling spec should be supported without compromising
/// performance for the most common cases.
-class SymbolDemangler
-{
+class SymbolDemangler {
public:
-
- //----------------------------------------------------
- // Public API
- //----------------------------------------------------
-
- /// @brief Create a SymbolDemangler
- ///
- /// The newly created demangler allocates and owns scratch memory sufficient
- /// for demangling typical symbols. Additional memory will be allocated if
- /// needed and managed by the demangler instance.
-
- SymbolDemangler()
- {
- m_buffer = (char *) malloc(8192);
- m_buffer_end = m_buffer + 8192;
- m_owns_buffer = true;
-
- m_rewrite_ranges = (BufferRange *) malloc(128 * sizeof (BufferRange));
- m_rewrite_ranges_size = 128;
- m_owns_m_rewrite_ranges = true;
- }
-
- /// @brief Create a SymbolDemangler that uses provided scratch memory
- ///
- /// The provided memory is not owned by the demangler. It will be
- /// overwritten during calls to GetDemangledCopy() but can be used for
- /// other purposes between calls. The provided memory will not be freed
- /// when this instance is destroyed.
- ///
- /// If demangling a symbol requires additional space it will be allocated
- /// and managed by the demangler instance.
- ///
- /// @param storage_ptr Valid pointer to at least storage_size bytes of
- /// space that the SymbolDemangler can use during demangling
- ///
- /// @param storage_size Number of bytes of space available scratch memory
- /// referenced by storage_ptr
-
- SymbolDemangler(void *storage_ptr, int storage_size)
- {
- // Use up to 1/8th of the provided space for rewrite ranges
- m_rewrite_ranges_size = (storage_size >> 3) / sizeof (BufferRange);
- m_rewrite_ranges = (BufferRange *) storage_ptr;
- m_owns_m_rewrite_ranges = false;
-
- // Use the rest for the character buffer
- m_buffer = (char *) storage_ptr + m_rewrite_ranges_size * sizeof (BufferRange);
- m_buffer_end = (const char *)storage_ptr + storage_size;
- m_owns_buffer = false;
- }
-
- /// @brief Destroys the SymbolDemangler and deallocates any scratch
- /// memory that it owns
-
- ~SymbolDemangler()
- {
- if (m_owns_buffer)
- free(m_buffer);
- if (m_owns_m_rewrite_ranges)
- free(m_rewrite_ranges);
- }
+ //----------------------------------------------------
+ // Public API
+ //----------------------------------------------------
+
+ /// @brief Create a SymbolDemangler
+ ///
+ /// The newly created demangler allocates and owns scratch memory sufficient
+ /// for demangling typical symbols. Additional memory will be allocated if
+ /// needed and managed by the demangler instance.
+
+ SymbolDemangler() {
+ m_buffer = (char *)malloc(8192);
+ m_buffer_end = m_buffer + 8192;
+ m_owns_buffer = true;
+
+ m_rewrite_ranges = (BufferRange *)malloc(128 * sizeof(BufferRange));
+ m_rewrite_ranges_size = 128;
+ m_owns_m_rewrite_ranges = true;
+ }
+
+ /// @brief Create a SymbolDemangler that uses provided scratch memory
+ ///
+ /// The provided memory is not owned by the demangler. It will be
+ /// overwritten during calls to GetDemangledCopy() but can be used for
+ /// other purposes between calls. The provided memory will not be freed
+ /// when this instance is destroyed.
+ ///
+ /// If demangling a symbol requires additional space it will be allocated
+ /// and managed by the demangler instance.
+ ///
+ /// @param storage_ptr Valid pointer to at least storage_size bytes of
+ /// space that the SymbolDemangler can use during demangling
+ ///
+ /// @param storage_size Number of bytes of space available scratch memory
+ /// referenced by storage_ptr
+
+ SymbolDemangler(void *storage_ptr, size_t storage_size,
+ std::function<void(const char *)> builtins_hook = nullptr)
+ : m_builtins_hook(builtins_hook) {
+ // Use up to 1/8th of the provided space for rewrite ranges
+ m_rewrite_ranges_size = (storage_size >> 3) / sizeof(BufferRange);
+ m_rewrite_ranges = (BufferRange *)storage_ptr;
+ m_owns_m_rewrite_ranges = false;
+
+ // Use the rest for the character buffer
+ m_buffer =
+ (char *)storage_ptr + m_rewrite_ranges_size * sizeof(BufferRange);
+ m_buffer_end = (const char *)storage_ptr + storage_size;
+ m_owns_buffer = false;
+ }
+
+ /// @brief Destroys the SymbolDemangler and deallocates any scratch
+ /// memory that it owns
+
+ ~SymbolDemangler() {
+ if (m_owns_buffer)
+ free(m_buffer);
+ if (m_owns_m_rewrite_ranges)
+ free(m_rewrite_ranges);
+ }
#ifdef DEBUG_HIGHWATER
- int highwater_store = 0;
- int highwater_buffer = 0;
+ int highwater_store = 0;
+ int highwater_buffer = 0;
#endif
- /// @brief Parses the provided mangled name and returns a newly allocated
- /// demangling
- ///
- /// @param mangled_name Valid null-terminated C++ mangled name following
- /// the Itanium C++ ABI mangling specification as implemented by Clang
- ///
- /// @result Newly allocated null-terminated demangled name when demangling
- /// is successful, and nullptr when demangling fails. The caller is
- /// responsible for freeing the allocated memory.
-
- char *
- GetDemangledCopy(const char *mangled_name,
- long mangled_name_length = 0)
- {
- if (!ParseMangling(mangled_name, mangled_name_length))
- return nullptr;
+ /// @brief Parses the provided mangled name and returns a newly allocated
+ /// demangling
+ ///
+ /// @param mangled_name Valid null-terminated C++ mangled name following
+ /// the Itanium C++ ABI mangling specification as implemented by Clang
+ ///
+ /// @result Newly allocated null-terminated demangled name when demangling
+ /// is successful, and nullptr when demangling fails. The caller is
+ /// responsible for freeing the allocated memory.
+
+ char *GetDemangledCopy(const char *mangled_name,
+ long mangled_name_length = 0) {
+ if (!ParseMangling(mangled_name, mangled_name_length))
+ return nullptr;
#ifdef DEBUG_HIGHWATER
- int rewrite_count = m_next_substitute_index +
- (m_rewrite_ranges_size - 1 - m_next_template_arg_index);
- int buffer_size = (int)(m_write_ptr - m_buffer);
- if (rewrite_count > highwater_store)
- highwater_store = rewrite_count;
- if (buffer_size > highwater_buffer)
- highwater_buffer = buffer_size;
+ int rewrite_count = m_next_substitute_index +
+ (m_rewrite_ranges_size - 1 - m_next_template_arg_index);
+ int buffer_size = (int)(m_write_ptr - m_buffer);
+ if (rewrite_count > highwater_store)
+ highwater_store = rewrite_count;
+ if (buffer_size > highwater_buffer)
+ highwater_buffer = buffer_size;
#endif
- int length = (int)(m_write_ptr - m_buffer);
- char *copy = (char *)malloc(length + 1);
- memcpy(copy, m_buffer, length);
- copy[length] = '\0';
- return copy;
- }
+ int length = (int)(m_write_ptr - m_buffer);
+ char *copy = (char *)malloc(length + 1);
+ memcpy(copy, m_buffer, length);
+ copy[length] = '\0';
+ return copy;
+ }
private:
-
- //----------------------------------------------------
- // Grow methods
- //
- // Manage the storage used during demangling
- //----------------------------------------------------
-
- void GrowBuffer(long min_growth = 0)
- {
- // By default, double the size of the buffer
- long growth = m_buffer_end - m_buffer;
-
- // Avoid growing by more than 1MB at a time
- if (growth > 1 << 20)
- growth = 1 << 20;
-
- // ... but never grow by less than requested,
- // or 1K, whichever is greater
- if (min_growth < 1024)
- min_growth = 1024;
- if (growth < min_growth)
- growth = min_growth;
-
- // Allocate the new m_buffer and migrate content
- long new_size = (m_buffer_end - m_buffer) + growth;
- char *new_buffer = (char *) malloc(new_size);
- memcpy(new_buffer, m_buffer, m_write_ptr - m_buffer);
- if (m_owns_buffer)
- free(m_buffer);
- m_owns_buffer = true;
-
- // Update references to the new buffer
- m_write_ptr = new_buffer + (m_write_ptr - m_buffer);
- m_buffer = new_buffer;
- m_buffer_end = m_buffer + new_size;
- }
-
- void
- GrowRewriteRanges()
- {
- // By default, double the size of the array
- int growth = m_rewrite_ranges_size;
-
- // Apply reasonable minimum and maximum sizes for growth
- if (growth > 128)
- growth = 128;
- if (growth < 16)
- growth = 16;
-
- // Allocate the new array and migrate content
- int bytes = (m_rewrite_ranges_size + growth) * sizeof (BufferRange);
- BufferRange *new_ranges = (BufferRange *) malloc (bytes);
- for (int index = 0; index < m_next_substitute_index; index++)
- {
- new_ranges[index] = m_rewrite_ranges[index];
- }
- for (int index = m_rewrite_ranges_size - 1;
- index > m_next_template_arg_index; index--)
- {
- new_ranges[index + growth] = m_rewrite_ranges[index];
- }
- if (m_owns_m_rewrite_ranges)
- free(m_rewrite_ranges);
- m_owns_m_rewrite_ranges = true;
-
- // Update references to the new array
- m_rewrite_ranges = new_ranges;
- m_rewrite_ranges_size += growth;
- m_next_template_arg_index += growth;
- }
-
- //----------------------------------------------------
- // Range and state management
- //----------------------------------------------------
-
- int
- GetStartCookie()
- {
- return (int)(m_write_ptr - m_buffer);
- }
-
- BufferRange
- EndRange(int start_cookie)
- {
- return { start_cookie, (int)(m_write_ptr - (m_buffer + start_cookie)) };
- }
-
- void
- ReorderRange(BufferRange source_range, int insertion_point_cookie)
- {
- // Ensure there's room the preserve the source range
- if (m_write_ptr + source_range.length > m_buffer_end)
- {
- GrowBuffer(m_write_ptr + source_range.length - m_buffer_end);
- }
-
- // Reorder the content
- memcpy(m_write_ptr, m_buffer + source_range.offset, source_range.length);
- memmove(m_buffer + insertion_point_cookie + source_range.length,
- m_buffer + insertion_point_cookie,
- source_range.offset - insertion_point_cookie);
- memcpy(m_buffer + insertion_point_cookie, m_write_ptr, source_range.length);
-
- // Fix up rewritable ranges, covering both substitutions and templates
- int index = 0;
- while (true)
- {
- if (index == m_next_substitute_index)
- index = m_next_template_arg_index + 1;
- if (index == m_rewrite_ranges_size)
- break;
-
- // Affected ranges are either shuffled forward when after the
- // insertion but before the source, or backward when inside the
- // source
- int candidate_offset = m_rewrite_ranges[index].offset;
- if (candidate_offset >= insertion_point_cookie)
- {
- if (candidate_offset < source_range.offset)
- {
- m_rewrite_ranges[index].offset += source_range.length;
- }
- else if (candidate_offset >= source_range.offset)
- {
- m_rewrite_ranges[index].offset -= (source_range.offset - insertion_point_cookie);
- }
- }
- ++index;
+ //----------------------------------------------------
+ // Grow methods
+ //
+ // Manage the storage used during demangling
+ //----------------------------------------------------
+
+ void GrowBuffer(long min_growth = 0) {
+ // By default, double the size of the buffer
+ long growth = m_buffer_end - m_buffer;
+
+ // Avoid growing by more than 1MB at a time
+ if (growth > 1 << 20)
+ growth = 1 << 20;
+
+ // ... but never grow by less than requested,
+ // or 1K, whichever is greater
+ if (min_growth < 1024)
+ min_growth = 1024;
+ if (growth < min_growth)
+ growth = min_growth;
+
+ // Allocate the new m_buffer and migrate content
+ long new_size = (m_buffer_end - m_buffer) + growth;
+ char *new_buffer = (char *)malloc(new_size);
+ memcpy(new_buffer, m_buffer, m_write_ptr - m_buffer);
+ if (m_owns_buffer)
+ free(m_buffer);
+ m_owns_buffer = true;
+
+ // Update references to the new buffer
+ m_write_ptr = new_buffer + (m_write_ptr - m_buffer);
+ m_buffer = new_buffer;
+ m_buffer_end = m_buffer + new_size;
+ }
+
+ void GrowRewriteRanges() {
+ // By default, double the size of the array
+ int growth = m_rewrite_ranges_size;
+
+ // Apply reasonable minimum and maximum sizes for growth
+ if (growth > 128)
+ growth = 128;
+ if (growth < 16)
+ growth = 16;
+
+ // Allocate the new array and migrate content
+ int bytes = (m_rewrite_ranges_size + growth) * sizeof(BufferRange);
+ BufferRange *new_ranges = (BufferRange *)malloc(bytes);
+ for (int index = 0; index < m_next_substitute_index; index++) {
+ new_ranges[index] = m_rewrite_ranges[index];
+ }
+ for (int index = m_rewrite_ranges_size - 1;
+ index > m_next_template_arg_index; index--) {
+ new_ranges[index + growth] = m_rewrite_ranges[index];
+ }
+ if (m_owns_m_rewrite_ranges)
+ free(m_rewrite_ranges);
+ m_owns_m_rewrite_ranges = true;
+
+ // Update references to the new array
+ m_rewrite_ranges = new_ranges;
+ m_rewrite_ranges_size += growth;
+ m_next_template_arg_index += growth;
+ }
+
+ //----------------------------------------------------
+ // Range and state management
+ //----------------------------------------------------
+
+ int GetStartCookie() { return (int)(m_write_ptr - m_buffer); }
+
+ BufferRange EndRange(int start_cookie) {
+ return {start_cookie, (int)(m_write_ptr - (m_buffer + start_cookie))};
+ }
+
+ void ReorderRange(BufferRange source_range, int insertion_point_cookie) {
+ // Ensure there's room the preserve the source range
+ if (m_write_ptr + source_range.length > m_buffer_end) {
+ GrowBuffer(m_write_ptr + source_range.length - m_buffer_end);
+ }
+
+ // Reorder the content
+ memcpy(m_write_ptr, m_buffer + source_range.offset, source_range.length);
+ memmove(m_buffer + insertion_point_cookie + source_range.length,
+ m_buffer + insertion_point_cookie,
+ source_range.offset - insertion_point_cookie);
+ memcpy(m_buffer + insertion_point_cookie, m_write_ptr, source_range.length);
+
+ // Fix up rewritable ranges, covering both substitutions and templates
+ int index = 0;
+ while (true) {
+ if (index == m_next_substitute_index)
+ index = m_next_template_arg_index + 1;
+ if (index == m_rewrite_ranges_size)
+ break;
+
+ // Affected ranges are either shuffled forward when after the
+ // insertion but before the source, or backward when inside the
+ // source
+ int candidate_offset = m_rewrite_ranges[index].offset;
+ if (candidate_offset >= insertion_point_cookie) {
+ if (candidate_offset < source_range.offset) {
+ m_rewrite_ranges[index].offset += source_range.length;
+ } else if (candidate_offset >= source_range.offset) {
+ m_rewrite_ranges[index].offset -=
+ (source_range.offset - insertion_point_cookie);
}
+ }
+ ++index;
}
+ }
- void
- EndSubstitution(int start_cookie)
- {
- if (m_next_substitute_index == m_next_template_arg_index)
- GrowRewriteRanges();
+ void EndSubstitution(int start_cookie) {
+ if (m_next_substitute_index == m_next_template_arg_index)
+ GrowRewriteRanges();
- int index = m_next_substitute_index++;
- m_rewrite_ranges[index] = EndRange(start_cookie);
+ int index = m_next_substitute_index++;
+ m_rewrite_ranges[index] = EndRange(start_cookie);
#ifdef DEBUG_SUBSTITUTIONS
- printf("Saved substitution # %d = %.*s\n", index,
- m_rewrite_ranges[index].length, m_buffer + start_cookie);
+ printf("Saved substitution # %d = %.*s\n", index,
+ m_rewrite_ranges[index].length, m_buffer + start_cookie);
#endif
- }
+ }
- void
- EndTemplateArg(int start_cookie)
- {
- if (m_next_substitute_index == m_next_template_arg_index)
- GrowRewriteRanges();
+ void EndTemplateArg(int start_cookie) {
+ if (m_next_substitute_index == m_next_template_arg_index)
+ GrowRewriteRanges();
- int index = m_next_template_arg_index--;
- m_rewrite_ranges[index] = EndRange(start_cookie);
+ int index = m_next_template_arg_index--;
+ m_rewrite_ranges[index] = EndRange(start_cookie);
#ifdef DEBUG_TEMPLATE_ARGS
- printf("Saved template arg # %d = %.*s\n",
- m_rewrite_ranges_size - index - 1,
- m_rewrite_ranges[index].length, m_buffer + start_cookie);
+ printf("Saved template arg # %d = %.*s\n",
+ m_rewrite_ranges_size - index - 1, m_rewrite_ranges[index].length,
+ m_buffer + start_cookie);
#endif
- }
-
- void
- ResetTemplateArgs()
- {
- //TODO: this works, but is it the right thing to do?
- // Should we push/pop somehow at the call sites?
- m_next_template_arg_index = m_rewrite_ranges_size - 1;
- }
-
- //----------------------------------------------------
- // Write methods
- //
- // Appends content to the existing output buffer
- //----------------------------------------------------
-
- void
- Write(char character)
- {
- if (m_write_ptr == m_buffer_end)
- GrowBuffer();
- *m_write_ptr++ = character;
- }
-
- void
- Write(const char *content)
- {
- Write(content, strlen(content));
- }
-
- void
- Write(const char *content, long content_length)
- {
- char *end_m_write_ptr = m_write_ptr + content_length;
- if (end_m_write_ptr > m_buffer_end)
- {
- if (content >= m_buffer && content < m_buffer_end)
- {
- long offset = content - m_buffer;
- GrowBuffer (end_m_write_ptr - m_buffer_end);
- content = m_buffer + offset;
- }
- else
- {
- GrowBuffer (end_m_write_ptr - m_buffer_end);
- }
- end_m_write_ptr = m_write_ptr + content_length;
- }
- memcpy (m_write_ptr, content, content_length);
- m_write_ptr = end_m_write_ptr;
- }
-#define WRITE(x) Write(x, sizeof (x) - 1)
-
- void
- WriteTemplateStart()
- {
- Write('<');
- }
-
- void
- WriteTemplateEnd()
- {
- // Put a space between terminal > characters when nesting templates
- if (m_write_ptr != m_buffer && *(m_write_ptr - 1) == '>')
- WRITE(" >");
- else Write('>');
- }
-
- void
- WriteCommaSpace()
- {
- WRITE(", ");
- }
-
- void
- WriteNamespaceSeparator()
- {
- WRITE("::");
- }
-
- void
- WriteStdPrefix()
- {
- WRITE("std::");
- }
-
- void
- WriteQualifiers(int qualifiers, bool space_before_reference = true)
- {
- if (qualifiers & QualifierPointer)
- Write('*');
- if (qualifiers & QualifierConst)
- WRITE(" const");
- if (qualifiers & QualifierVolatile)
- WRITE(" volatile");
- if (qualifiers & QualifierRestrict)
- WRITE(" restrict");
- if (qualifiers & QualifierReference)
- {
- if (space_before_reference)
- WRITE(" &");
- else Write('&');
- }
- if (qualifiers & QualifierRValueReference)
- {
- if (space_before_reference)
- WRITE(" &&");
- else WRITE("&&");
- }
- }
-
- //----------------------------------------------------
- // Rewrite methods
- //
- // Write another copy of content already present
- // earlier in the output buffer
- //----------------------------------------------------
-
- void
- RewriteRange(BufferRange range)
- {
- Write(m_buffer + range.offset, range.length);
- }
-
- bool
- RewriteSubstitution(int index)
- {
- if (index < 0 || index >= m_next_substitute_index)
- {
+ }
+
+ void ResetTemplateArgs() {
+ // TODO: this works, but is it the right thing to do?
+ // Should we push/pop somehow at the call sites?
+ m_next_template_arg_index = m_rewrite_ranges_size - 1;
+ }
+
+ //----------------------------------------------------
+ // Write methods
+ //
+ // Appends content to the existing output buffer
+ //----------------------------------------------------
+
+ void Write(char character) {
+ if (m_write_ptr == m_buffer_end)
+ GrowBuffer();
+ *m_write_ptr++ = character;
+ }
+
+ void Write(const char *content) { Write(content, strlen(content)); }
+
+ void Write(const char *content, long content_length) {
+ char *end_m_write_ptr = m_write_ptr + content_length;
+ if (end_m_write_ptr > m_buffer_end) {
+ if (content >= m_buffer && content < m_buffer_end) {
+ long offset = content - m_buffer;
+ GrowBuffer(end_m_write_ptr - m_buffer_end);
+ content = m_buffer + offset;
+ } else {
+ GrowBuffer(end_m_write_ptr - m_buffer_end);
+ }
+ end_m_write_ptr = m_write_ptr + content_length;
+ }
+ memcpy(m_write_ptr, content, content_length);
+ m_write_ptr = end_m_write_ptr;
+ }
+#define WRITE(x) Write(x, sizeof(x) - 1)
+
+ void WriteTemplateStart() { Write('<'); }
+
+ void WriteTemplateEnd() {
+ // Put a space between terminal > characters when nesting templates
+ if (m_write_ptr != m_buffer && *(m_write_ptr - 1) == '>')
+ WRITE(" >");
+ else
+ Write('>');
+ }
+
+ void WriteCommaSpace() { WRITE(", "); }
+
+ void WriteNamespaceSeparator() { WRITE("::"); }
+
+ void WriteStdPrefix() { WRITE("std::"); }
+
+ void WriteQualifiers(int qualifiers, bool space_before_reference = true) {
+ if (qualifiers & QualifierPointer)
+ Write('*');
+ if (qualifiers & QualifierConst)
+ WRITE(" const");
+ if (qualifiers & QualifierVolatile)
+ WRITE(" volatile");
+ if (qualifiers & QualifierRestrict)
+ WRITE(" restrict");
+ if (qualifiers & QualifierReference) {
+ if (space_before_reference)
+ WRITE(" &");
+ else
+ Write('&');
+ }
+ if (qualifiers & QualifierRValueReference) {
+ if (space_before_reference)
+ WRITE(" &&");
+ else
+ WRITE("&&");
+ }
+ }
+
+ //----------------------------------------------------
+ // Rewrite methods
+ //
+ // Write another copy of content already present
+ // earlier in the output buffer
+ //----------------------------------------------------
+
+ void RewriteRange(BufferRange range) {
+ Write(m_buffer + range.offset, range.length);
+ }
+
+ bool RewriteSubstitution(int index) {
+ if (index < 0 || index >= m_next_substitute_index) {
#ifdef DEBUG_FAILURES
- printf("*** Invalid substitution #%d\n", index);
+ printf("*** Invalid substitution #%d\n", index);
#endif
- return false;
- }
- RewriteRange(m_rewrite_ranges[index]);
- return true;
+ return false;
}
+ RewriteRange(m_rewrite_ranges[index]);
+ return true;
+ }
- bool
- RewriteTemplateArg(int template_index)
- {
- int index = m_rewrite_ranges_size - 1 - template_index;
- if (template_index < 0 || index <= m_next_template_arg_index)
- {
+ bool RewriteTemplateArg(int template_index) {
+ int index = m_rewrite_ranges_size - 1 - template_index;
+ if (template_index < 0 || index <= m_next_template_arg_index) {
#ifdef DEBUG_FAILURES
- printf("*** Invalid template arg reference #%d\n", template_index);
+ printf("*** Invalid template arg reference #%d\n", template_index);
#endif
- return false;
- }
- RewriteRange(m_rewrite_ranges[index]);
- return true;
+ return false;
+ }
+ RewriteRange(m_rewrite_ranges[index]);
+ return true;
+ }
+
+ //----------------------------------------------------
+ // TryParse methods
+ //
+ // Provide information with return values instead of
+ // writing to the output buffer
+ //
+ // Values indicating failure guarantee that the pre-
+ // call m_read_ptr is unchanged
+ //----------------------------------------------------
+
+ int TryParseNumber() {
+ unsigned char digit = *m_read_ptr - '0';
+ if (digit > 9)
+ return -1;
+
+ int count = digit;
+ while (true) {
+ digit = *++m_read_ptr - '0';
+ if (digit > 9)
+ break;
+
+ count = count * 10 + digit;
+ }
+ return count;
+ }
+
+ int TryParseBase36Number() {
+ char digit = *m_read_ptr;
+ int count;
+ if (digit >= '0' && digit <= '9')
+ count = digit -= '0';
+ else if (digit >= 'A' && digit <= 'Z')
+ count = digit -= ('A' - 10);
+ else
+ return -1;
+
+ while (true) {
+ digit = *++m_read_ptr;
+ if (digit >= '0' && digit <= '9')
+ digit -= '0';
+ else if (digit >= 'A' && digit <= 'Z')
+ digit -= ('A' - 10);
+ else
+ break;
+
+ count = count * 36 + digit;
+ }
+ return count;
+ }
+
+ // <builtin-type> ::= v # void
+ // ::= w # wchar_t
+ // ::= b # bool
+ // ::= c # char
+ // ::= a # signed char
+ // ::= h # unsigned char
+ // ::= s # short
+ // ::= t # unsigned short
+ // ::= i # int
+ // ::= j # unsigned int
+ // ::= l # long
+ // ::= m # unsigned long
+ // ::= x # long long, __int64
+ // ::= y # unsigned long long, __int64
+ // ::= n # __int128
+ // ::= o # unsigned __int128
+ // ::= f # float
+ // ::= d # double
+ // ::= e # long double, __float80
+ // ::= g # __float128
+ // ::= z # ellipsis
+ // ::= Dd # IEEE 754r decimal floating point (64 bits)
+ // ::= De # IEEE 754r decimal floating point (128 bits)
+ // ::= Df # IEEE 754r decimal floating point (32 bits)
+ // ::= Dh # IEEE 754r half-precision floating point (16 bits)
+ // ::= Di # char32_t
+ // ::= Ds # char16_t
+ // ::= Da # auto (in dependent new-expressions)
+ // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
+ // ::= u <source-name> # vendor extended type
+
+ const char *TryParseBuiltinType() {
+ if (m_builtins_hook)
+ m_builtins_hook(m_read_ptr);
+
+ switch (*m_read_ptr++) {
+ case 'v':
+ return "void";
+ case 'w':
+ return "wchar_t";
+ case 'b':
+ return "bool";
+ case 'c':
+ return "char";
+ case 'a':
+ return "signed char";
+ case 'h':
+ return "unsigned char";
+ case 's':
+ return "short";
+ case 't':
+ return "unsigned short";
+ case 'i':
+ return "int";
+ case 'j':
+ return "unsigned int";
+ case 'l':
+ return "long";
+ case 'm':
+ return "unsigned long";
+ case 'x':
+ return "long long";
+ case 'y':
+ return "unsigned long long";
+ case 'n':
+ return "__int128";
+ case 'o':
+ return "unsigned __int128";
+ case 'f':
+ return "float";
+ case 'd':
+ return "double";
+ case 'e':
+ return "long double";
+ case 'g':
+ return "__float128";
+ case 'z':
+ return "...";
+ case 'D': {
+ switch (*m_read_ptr++) {
+ case 'd':
+ return "decimal64";
+ case 'e':
+ return "decimal128";
+ case 'f':
+ return "decimal32";
+ case 'h':
+ return "decimal16";
+ case 'i':
+ return "char32_t";
+ case 's':
+ return "char16_t";
+ case 'a':
+ return "auto";
+ case 'c':
+ return "decltype(auto)";
+ case 'n':
+ return "std::nullptr_t";
+ default:
+ --m_read_ptr;
+ }
+ }
+ }
+ --m_read_ptr;
+ return nullptr;
+ }
+
+ // <operator-name>
+ // ::= aa # &&
+ // ::= ad # & (unary)
+ // ::= an # &
+ // ::= aN # &=
+ // ::= aS # =
+ // ::= cl # ()
+ // ::= cm # ,
+ // ::= co # ~
+ // ::= da # delete[]
+ // ::= de # * (unary)
+ // ::= dl # delete
+ // ::= dv # /
+ // ::= dV # /=
+ // ::= eo # ^
+ // ::= eO # ^=
+ // ::= eq # ==
+ // ::= ge # >=
+ // ::= gt # >
+ // ::= ix # []
+ // ::= le # <=
+ // ::= ls # <<
+ // ::= lS # <<=
+ // ::= lt # <
+ // ::= mi # -
+ // ::= mI # -=
+ // ::= ml # *
+ // ::= mL # *=
+ // ::= mm # -- (postfix in <expression> context)
+ // ::= na # new[]
+ // ::= ne # !=
+ // ::= ng # - (unary)
+ // ::= nt # !
+ // ::= nw # new
+ // ::= oo # ||
+ // ::= or # |
+ // ::= oR # |=
+ // ::= pm # ->*
+ // ::= pl # +
+ // ::= pL # +=
+ // ::= pp # ++ (postfix in <expression> context)
+ // ::= ps # + (unary)
+ // ::= pt # ->
+ // ::= qu # ?
+ // ::= rm # %
+ // ::= rM # %=
+ // ::= rs # >>
+ // ::= rS # >>=
+ // ::= cv <type> # (cast)
+ // ::= v <digit> <source-name> # vendor extended
+ // operator
+
+ Operator TryParseOperator() {
+ switch (*m_read_ptr++) {
+ case 'a':
+ switch (*m_read_ptr++) {
+ case 'a':
+ return {"&&", OperatorKind::Binary};
+ case 'd':
+ return {"&", OperatorKind::Unary};
+ case 'n':
+ return {"&", OperatorKind::Binary};
+ case 'N':
+ return {"&=", OperatorKind::Binary};
+ case 'S':
+ return {"=", OperatorKind::Binary};
+ }
+ --m_read_ptr;
+ break;
+ case 'c':
+ switch (*m_read_ptr++) {
+ case 'l':
+ return {"()", OperatorKind::Other};
+ case 'm':
+ return {",", OperatorKind::Other};
+ case 'o':
+ return {"~", OperatorKind::Unary};
+ case 'v':
+ return {nullptr, OperatorKind::ConversionOperator};
+ }
+ --m_read_ptr;
+ break;
+ case 'd':
+ switch (*m_read_ptr++) {
+ case 'a':
+ return {" delete[]", OperatorKind::Other};
+ case 'e':
+ return {"*", OperatorKind::Unary};
+ case 'l':
+ return {" delete", OperatorKind::Other};
+ case 'v':
+ return {"/", OperatorKind::Binary};
+ case 'V':
+ return {"/=", OperatorKind::Binary};
+ }
+ --m_read_ptr;
+ break;
+ case 'e':
+ switch (*m_read_ptr++) {
+ case 'o':
+ return {"^", OperatorKind::Binary};
+ case 'O':
+ return {"^=", OperatorKind::Binary};
+ case 'q':
+ return {"==", OperatorKind::Binary};
+ }
+ --m_read_ptr;
+ break;
+ case 'g':
+ switch (*m_read_ptr++) {
+ case 'e':
+ return {">=", OperatorKind::Binary};
+ case 't':
+ return {">", OperatorKind::Binary};
+ }
+ --m_read_ptr;
+ break;
+ case 'i':
+ switch (*m_read_ptr++) {
+ case 'x':
+ return {"[]", OperatorKind::Other};
+ }
+ --m_read_ptr;
+ break;
+ case 'l':
+ switch (*m_read_ptr++) {
+ case 'e':
+ return {"<=", OperatorKind::Binary};
+ case 's':
+ return {"<<", OperatorKind::Binary};
+ case 'S':
+ return {"<<=", OperatorKind::Binary};
+ case 't':
+ return {"<", OperatorKind::Binary};
+ // case 'i': return { "?", OperatorKind::Binary };
+ }
+ --m_read_ptr;
+ break;
+ case 'm':
+ switch (*m_read_ptr++) {
+ case 'i':
+ return {"-", OperatorKind::Binary};
+ case 'I':
+ return {"-=", OperatorKind::Binary};
+ case 'l':
+ return {"*", OperatorKind::Binary};
+ case 'L':
+ return {"*=", OperatorKind::Binary};
+ case 'm':
+ return {"--", OperatorKind::Postfix};
+ }
+ --m_read_ptr;
+ break;
+ case 'n':
+ switch (*m_read_ptr++) {
+ case 'a':
+ return {" new[]", OperatorKind::Other};
+ case 'e':
+ return {"!=", OperatorKind::Binary};
+ case 'g':
+ return {"-", OperatorKind::Unary};
+ case 't':
+ return {"!", OperatorKind::Unary};
+ case 'w':
+ return {" new", OperatorKind::Other};
+ }
+ --m_read_ptr;
+ break;
+ case 'o':
+ switch (*m_read_ptr++) {
+ case 'o':
+ return {"||", OperatorKind::Binary};
+ case 'r':
+ return {"|", OperatorKind::Binary};
+ case 'R':
+ return {"|=", OperatorKind::Binary};
+ }
+ --m_read_ptr;
+ break;
+ case 'p':
+ switch (*m_read_ptr++) {
+ case 'm':
+ return {"->*", OperatorKind::Binary};
+ case 's':
+ return {"+", OperatorKind::Unary};
+ case 'l':
+ return {"+", OperatorKind::Binary};
+ case 'L':
+ return {"+=", OperatorKind::Binary};
+ case 'p':
+ return {"++", OperatorKind::Postfix};
+ case 't':
+ return {"->", OperatorKind::Binary};
+ }
+ --m_read_ptr;
+ break;
+ case 'q':
+ switch (*m_read_ptr++) {
+ case 'u':
+ return {"?", OperatorKind::Ternary};
+ }
+ --m_read_ptr;
+ break;
+ case 'r':
+ switch (*m_read_ptr++) {
+ case 'm':
+ return {"%", OperatorKind::Binary};
+ case 'M':
+ return {"%=", OperatorKind::Binary};
+ case 's':
+ return {">>", OperatorKind::Binary};
+ case 'S':
+ return {">=", OperatorKind::Binary};
+ }
+ --m_read_ptr;
+ break;
+ case 'v':
+ char digit = *m_read_ptr;
+ if (digit >= '0' && digit <= '9') {
+ m_read_ptr++;
+ return {nullptr, OperatorKind::Vendor};
+ }
+ --m_read_ptr;
+ break;
+ }
+ --m_read_ptr;
+ return {nullptr, OperatorKind::NoMatch};
+ }
+
+ // <CV-qualifiers> ::= [r] [V] [K]
+ // <ref-qualifier> ::= R # & ref-qualifier
+ // <ref-qualifier> ::= O # && ref-qualifier
+
+ int TryParseQualifiers(bool allow_cv, bool allow_ro) {
+ int qualifiers = QualifierNone;
+ char next = *m_read_ptr;
+ if (allow_cv) {
+ if (next == 'r') // restrict
+ {
+ qualifiers |= QualifierRestrict;
+ next = *++m_read_ptr;
+ }
+ if (next == 'V') // volatile
+ {
+ qualifiers |= QualifierVolatile;
+ next = *++m_read_ptr;
+ }
+ if (next == 'K') // const
+ {
+ qualifiers |= QualifierConst;
+ next = *++m_read_ptr;
+ }
+ }
+ if (allow_ro) {
+ if (next == 'R') {
+ ++m_read_ptr;
+ qualifiers |= QualifierReference;
+ } else if (next == 'O') {
+ ++m_read_ptr;
+ qualifiers |= QualifierRValueReference;
+ }
}
+ return qualifiers;
+ }
- //----------------------------------------------------
- // TryParse methods
- //
- // Provide information with return values instead of
- // writing to the output buffer
- //
- // Values indicating failure guarantee that the pre-
- // call m_read_ptr is unchanged
- //----------------------------------------------------
-
- int
- TryParseNumber()
- {
- unsigned char digit = *m_read_ptr - '0';
- if (digit > 9)
- return -1;
-
- int count = digit;
- while (true)
- {
- digit = *++m_read_ptr - '0';
- if (digit > 9)
- break;
+ // <discriminator> := _ <non-negative number> # when number < 10
+ // := __ <non-negative number> _ # when number >= 10
+ // extension := decimal-digit+
- count = count * 10 + digit;
- }
- return count;
- }
+ int TryParseDiscriminator() {
+ const char *discriminator_start = m_read_ptr;
- int
- TryParseBase36Number()
- {
- char digit = *m_read_ptr;
- int count;
- if (digit >= '0' && digit <= '9')
- count = digit -= '0';
- else if (digit >= 'A' && digit <= 'Z')
- count = digit -= ('A' - 10);
- else return -1;
+ // Test the extension first, since it's what Clang uses
+ int discriminator_value = TryParseNumber();
+ if (discriminator_value != -1)
+ return discriminator_value;
- while (true)
- {
- digit = *++m_read_ptr;
- if (digit >= '0' && digit <= '9')
- digit -= '0';
- else if (digit >= 'A' && digit <= 'Z')
- digit -= ('A' - 10);
- else break;
-
- count = count * 36 + digit;
+ char next = *m_read_ptr;
+ if (next == '_') {
+ next = *++m_read_ptr;
+ if (next == '_') {
+ ++m_read_ptr;
+ discriminator_value = TryParseNumber();
+ if (discriminator_value != -1 && *m_read_ptr++ != '_') {
+ return discriminator_value;
}
- return count;
- }
+ } else if (next >= '0' && next <= '9') {
+ ++m_read_ptr;
+ return next - '0';
+ }
+ }
+
+ // Not a valid discriminator
+ m_read_ptr = discriminator_start;
+ return -1;
+ }
+
+ //----------------------------------------------------
+ // Parse methods
+ //
+ // Consume input starting from m_read_ptr and produce
+ // buffered output at m_write_ptr
+ //
+ // Failures return false and may leave m_read_ptr in an
+ // indeterminate state
+ //----------------------------------------------------
+
+ bool Parse(char character) {
+ if (*m_read_ptr++ == character)
+ return true;
+#ifdef DEBUG_FAILURES
+ printf("*** Expected '%c'\n", character);
+#endif
+ return false;
+ }
- // <builtin-type> ::= v # void
- // ::= w # wchar_t
- // ::= b # bool
- // ::= c # char
- // ::= a # signed char
- // ::= h # unsigned char
- // ::= s # short
- // ::= t # unsigned short
- // ::= i # int
- // ::= j # unsigned int
- // ::= l # long
- // ::= m # unsigned long
- // ::= x # long long, __int64
- // ::= y # unsigned long long, __int64
- // ::= n # __int128
- // ::= o # unsigned __int128
- // ::= f # float
- // ::= d # double
- // ::= e # long double, __float80
- // ::= g # __float128
- // ::= z # ellipsis
- // ::= Dd # IEEE 754r decimal floating point (64 bits)
- // ::= De # IEEE 754r decimal floating point (128 bits)
- // ::= Df # IEEE 754r decimal floating point (32 bits)
- // ::= Dh # IEEE 754r half-precision floating point (16 bits)
- // ::= Di # char32_t
- // ::= Ds # char16_t
- // ::= Da # auto (in dependent new-expressions)
- // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
- // ::= u <source-name> # vendor extended type
-
- const char *
- TryParseBuiltinType()
- {
- switch (*m_read_ptr++)
- {
- case 'v': return "void";
- case 'w': return "wchar_t";
- case 'b': return "bool";
- case 'c': return "char";
- case 'a': return "signed char";
- case 'h': return "unsigned char";
- case 's': return "short";
- case 't': return "unsigned short";
- case 'i': return "int";
- case 'j': return "unsigned int";
- case 'l': return "long";
- case 'm': return "unsigned long";
- case 'x': return "long long";
- case 'y': return "unsigned long long";
- case 'n': return "__int128";
- case 'o': return "unsigned __int128";
- case 'f': return "float";
- case 'd': return "double";
- case 'e': return "long double";
- case 'g': return "__float128";
- case 'z': return "...";
- case 'D':
- {
- switch (*m_read_ptr++)
- {
- case 'd': return "decimal64";
- case 'e': return "decimal128";
- case 'f': return "decimal32";
- case 'h': return "decimal16";
- case 'i': return "char32_t";
- case 's': return "char16_t";
- case 'a': return "auto";
- case 'c': return "decltype(auto)";
- case 'n': return "std::nullptr_t";
- default:
- --m_read_ptr;
- }
- }
- }
- --m_read_ptr;
- return nullptr;
- }
+ // <number> ::= [n] <non-negative decimal integer>
- // <operator-name>
- // ::= aa # &&
- // ::= ad # & (unary)
- // ::= an # &
- // ::= aN # &=
- // ::= aS # =
- // ::= cl # ()
- // ::= cm # ,
- // ::= co # ~
- // ::= da # delete[]
- // ::= de # * (unary)
- // ::= dl # delete
- // ::= dv # /
- // ::= dV # /=
- // ::= eo # ^
- // ::= eO # ^=
- // ::= eq # ==
- // ::= ge # >=
- // ::= gt # >
- // ::= ix # []
- // ::= le # <=
- // ::= ls # <<
- // ::= lS # <<=
- // ::= lt # <
- // ::= mi # -
- // ::= mI # -=
- // ::= ml # *
- // ::= mL # *=
- // ::= mm # -- (postfix in <expression> context)
- // ::= na # new[]
- // ::= ne # !=
- // ::= ng # - (unary)
- // ::= nt # !
- // ::= nw # new
- // ::= oo # ||
- // ::= or # |
- // ::= oR # |=
- // ::= pm # ->*
- // ::= pl # +
- // ::= pL # +=
- // ::= pp # ++ (postfix in <expression> context)
- // ::= ps # + (unary)
- // ::= pt # ->
- // ::= qu # ?
- // ::= rm # %
- // ::= rM # %=
- // ::= rs # >>
- // ::= rS # >>=
- // ::= cv <type> # (cast)
- // ::= v <digit> <source-name> # vendor extended operator
-
- Operator
- TryParseOperator()
- {
- switch (*m_read_ptr++)
- {
- case 'a':
- switch (*m_read_ptr++)
- {
- case 'a': return { "&&", OperatorKind::Binary };
- case 'd': return { "&", OperatorKind::Unary };
- case 'n': return { "&", OperatorKind::Binary };
- case 'N': return { "&=", OperatorKind::Binary };
- case 'S': return { "=", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'c':
- switch (*m_read_ptr++)
- {
- case 'l': return { "()", OperatorKind::Other };
- case 'm': return { ",", OperatorKind::Other };
- case 'o': return { "~", OperatorKind::Unary };
- case 'v': return { nullptr, OperatorKind::ConversionOperator };
- }
- --m_read_ptr;
- break;
- case 'd':
- switch (*m_read_ptr++)
- {
- case 'a': return { " delete[]", OperatorKind::Other };
- case 'e': return { "*", OperatorKind::Unary };
- case 'l': return { " delete", OperatorKind::Other };
- case 'v': return { "/", OperatorKind::Binary };
- case 'V': return { "/=", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'e':
- switch (*m_read_ptr++)
- {
- case 'o': return { "^", OperatorKind::Binary };
- case 'O': return { "^=", OperatorKind::Binary };
- case 'q': return { "==", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'g':
- switch (*m_read_ptr++)
- {
- case 'e': return { ">=", OperatorKind::Binary };
- case 't': return { ">", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'i':
- switch (*m_read_ptr++)
- {
- case 'x': return { "[]", OperatorKind::Other };
- }
- --m_read_ptr;
- break;
- case 'l':
- switch (*m_read_ptr++)
- {
- case 'e': return { "<=", OperatorKind::Binary };
- case 's': return { "<<", OperatorKind::Binary };
- case 'S': return { "<<=", OperatorKind::Binary };
- case 't': return { "<", OperatorKind::Binary };
- // case 'i': return { "?", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'm':
- switch (*m_read_ptr++)
- {
- case 'i': return { "-", OperatorKind::Binary };
- case 'I': return { "-=", OperatorKind::Binary };
- case 'l': return { "*", OperatorKind::Binary };
- case 'L': return { "*=", OperatorKind::Binary };
- case 'm': return { "--", OperatorKind::Postfix };
- }
- --m_read_ptr;
- break;
- case 'n':
- switch (*m_read_ptr++)
- {
- case 'a': return { " new[]", OperatorKind::Other };
- case 'e': return { "!=", OperatorKind::Binary };
- case 'g': return { "-", OperatorKind::Unary };
- case 't': return { "!", OperatorKind::Unary };
- case 'w': return { " new", OperatorKind::Other };
- }
- --m_read_ptr;
- break;
- case 'o':
- switch (*m_read_ptr++)
- {
- case 'o': return { "||", OperatorKind::Binary };
- case 'r': return { "|", OperatorKind::Binary };
- case 'R': return { "|=", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'p':
- switch (*m_read_ptr++)
- {
- case 'm': return { "->*", OperatorKind::Binary };
- case 's': return { "+", OperatorKind::Unary };
- case 'l': return { "+", OperatorKind::Binary };
- case 'L': return { "+=", OperatorKind::Binary };
- case 'p': return { "++", OperatorKind::Postfix };
- case 't': return { "->", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'q':
- switch (*m_read_ptr++)
- {
- case 'u': return { "?", OperatorKind::Ternary };
- }
- --m_read_ptr;
- break;
- case 'r':
- switch (*m_read_ptr++)
- {
- case 'm': return { "%", OperatorKind::Binary };
- case 'M': return { "%=", OperatorKind::Binary };
- case 's': return { ">>", OperatorKind::Binary };
- case 'S': return { ">=", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'v':
- char digit = *m_read_ptr;
- if (digit >= '0' && digit <= '9')
- {
- m_read_ptr++;
- return { nullptr, OperatorKind::Vendor };
- }
- --m_read_ptr;
- break;
- }
- --m_read_ptr;
- return { nullptr, OperatorKind::NoMatch };
+ bool ParseNumber(bool allow_negative = false) {
+ if (allow_negative && *m_read_ptr == 'n') {
+ Write('-');
+ ++m_read_ptr;
}
-
- // <CV-qualifiers> ::= [r] [V] [K]
- // <ref-qualifier> ::= R # & ref-qualifier
- // <ref-qualifier> ::= O # && ref-qualifier
-
- int
- TryParseQualifiers(bool allow_cv, bool allow_ro)
- {
- int qualifiers = QualifierNone;
- char next = *m_read_ptr;
- if (allow_cv)
- {
- if (next == 'r') // restrict
- {
- qualifiers |= QualifierRestrict;
- next = *++m_read_ptr;
- }
- if (next == 'V') // volatile
- {
- qualifiers |= QualifierVolatile;
- next = *++m_read_ptr;
- }
- if (next == 'K') // const
- {
- qualifiers |= QualifierConst;
- next = *++m_read_ptr;
- }
- }
- if (allow_ro)
- {
- if (next == 'R')
- {
- ++m_read_ptr;
- qualifiers |= QualifierReference;
- }
- else if (next =='O')
- {
- ++m_read_ptr;
- qualifiers |= QualifierRValueReference;
- }
- }
- return qualifiers;
+ const char *before_digits = m_read_ptr;
+ while (true) {
+ unsigned char digit = *m_read_ptr - '0';
+ if (digit > 9)
+ break;
+ ++m_read_ptr;
}
-
- // <discriminator> := _ <non-negative number> # when number < 10
- // := __ <non-negative number> _ # when number >= 10
- // extension := decimal-digit+
-
- int
- TryParseDiscriminator()
- {
- const char *discriminator_start = m_read_ptr;
-
- // Test the extension first, since it's what Clang uses
- int discriminator_value = TryParseNumber();
- if (discriminator_value != -1)
- return discriminator_value;
-
- char next = *m_read_ptr;
- if (next == '_')
- {
- next = *++m_read_ptr;
- if (next == '_')
- {
- ++m_read_ptr;
- discriminator_value = TryParseNumber();
- if (discriminator_value != -1 && *m_read_ptr++ != '_')
- {
- return discriminator_value;
- }
- }
- else if (next >= '0' && next <= '9')
- {
- ++m_read_ptr;
- return next - '0';
- }
- }
-
- // Not a valid discriminator
- m_read_ptr = discriminator_start;
- return -1;
+ if (int digit_count = (int)(m_read_ptr - before_digits)) {
+ Write(before_digits, digit_count);
+ return true;
}
-
- //----------------------------------------------------
- // Parse methods
- //
- // Consume input starting from m_read_ptr and produce
- // buffered output at m_write_ptr
- //
- // Failures return false and may leave m_read_ptr in an
- // indeterminate state
- //----------------------------------------------------
-
- bool
- Parse(char character)
- {
- if (*m_read_ptr++ == character)
- return true;
#ifdef DEBUG_FAILURES
- printf("*** Expected '%c'\n", character);
+ printf("*** Expected number\n");
#endif
- return false;
- }
-
- // <number> ::= [n] <non-negative decimal integer>
-
- bool
- ParseNumber(bool allow_negative = false)
- {
- if (allow_negative && *m_read_ptr == 'n')
- {
- Write('-');
- ++m_read_ptr;
- }
- const char *before_digits = m_read_ptr;
- while (true)
- {
- unsigned char digit = *m_read_ptr - '0';
- if (digit > 9)
- break;
- ++m_read_ptr;
- }
- if (int digit_count = (int)(m_read_ptr - before_digits))
- {
- Write(before_digits, digit_count);
- return true;
- }
+ return false;
+ }
+
+ // <substitution> ::= S <seq-id> _
+ // ::= S_
+ // <substitution> ::= Sa # ::std::allocator
+ // <substitution> ::= Sb # ::std::basic_string
+ // <substitution> ::= Ss # ::std::basic_string < char,
+ // ::std::char_traits<char>,
+ // ::std::allocator<char> >
+ // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char>
+ // >
+ // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char>
+ // >
+ // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char>
+ // >
+
+ bool ParseSubstitution() {
+ const char *substitution;
+ switch (*m_read_ptr) {
+ case 'a':
+ substitution = "std::allocator";
+ break;
+ case 'b':
+ substitution = "std::basic_string";
+ break;
+ case 's':
+ substitution = "std::string";
+ break;
+ case 'i':
+ substitution = "std::istream";
+ break;
+ case 'o':
+ substitution = "std::ostream";
+ break;
+ case 'd':
+ substitution = "std::iostream";
+ break;
+ default:
+ // A failed attempt to parse a number will return -1 which turns out to be
+ // perfect here as S_ is the first substitution, S0_ the next and so forth
+ int substitution_index = TryParseBase36Number();
+ if (*m_read_ptr++ != '_') {
#ifdef DEBUG_FAILURES
- printf("*** Expected number\n");
+ printf("*** Expected terminal _ in substitution\n");
#endif
return false;
+ }
+ return RewriteSubstitution(substitution_index + 1);
}
+ Write(substitution);
+ ++m_read_ptr;
+ return true;
+ }
- // <substitution> ::= S <seq-id> _
- // ::= S_
- // <substitution> ::= Sa # ::std::allocator
- // <substitution> ::= Sb # ::std::basic_string
- // <substitution> ::= Ss # ::std::basic_string < char,
- // ::std::char_traits<char>,
- // ::std::allocator<char> >
- // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char> >
- // <substitution> ::= So # ::std::basic_ostream<char, std::char_traits<char> >
- // <substitution> ::= Sd # ::std::basic_iostream<char, std::char_traits<char> >
-
- bool
- ParseSubstitution()
- {
- const char *substitution;
- switch (*m_read_ptr)
- {
- case 'a': substitution = "std::allocator"; break;
- case 'b': substitution = "std::basic_string"; break;
- case 's': substitution = "std::string"; break;
- case 'i': substitution = "std::istream"; break;
- case 'o': substitution = "std::ostream"; break;
- case 'd': substitution = "std::iostream"; break;
- default:
- // A failed attempt to parse a number will return -1 which turns out to be
- // perfect here as S_ is the first substitution, S0_ the next and so forth
- int substitution_index = TryParseBase36Number();
- if (*m_read_ptr++ != '_')
- {
-#ifdef DEBUG_FAILURES
- printf("*** Expected terminal _ in substitution\n");
-#endif
- return false;
- }
- return RewriteSubstitution (substitution_index + 1);
- }
- Write(substitution);
- ++m_read_ptr;
- return true;
- }
+ // <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
+ //
+ // <bare-function-type> ::= <signature type>+ # types are possible return
+ // type, then parameter types
- // <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
- //
- // <bare-function-type> ::= <signature type>+ # types are possible return type, then parameter types
-
- bool
- ParseFunctionType (int inner_qualifiers = QualifierNone)
- {
+ bool ParseFunctionType(int inner_qualifiers = QualifierNone) {
#ifdef DEBUG_FAILURES
- printf("*** Function types not supported\n");
+ printf("*** Function types not supported\n");
#endif
- //TODO: first steps toward an implementation follow, but they're far
- // from complete. Function types tend to bracket other types eg:
- // int (*)() when used as the type for "name" becomes int (*name)().
- // This makes substitution et al ... interesting.
- return false;
+ // TODO: first steps toward an implementation follow, but they're far
+ // from complete. Function types tend to bracket other types eg:
+ // int (*)() when used as the type for "name" becomes int (*name)().
+ // This makes substitution et al ... interesting.
+ return false;
-#if 0 // TODO
+#if 0 // TODO
if (*m_read_ptr == 'Y')
++m_read_ptr;
@@ -1083,28 +1058,26 @@ private:
ReorderRange (EndRange (qualifier_start_cookie), insert_cookie);
}
return true;
-#endif // TODO
- }
+#endif // TODO
+ }
- // <array-type> ::= A <positive dimension number> _ <element type>
- // ::= A [<dimension expression>] _ <element type>
+ // <array-type> ::= A <positive dimension number> _ <element type>
+ // ::= A [<dimension expression>] _ <element type>
- bool
- ParseArrayType(int qualifiers = QualifierNone)
- {
+ bool ParseArrayType(int qualifiers = QualifierNone) {
#ifdef DEBUG_FAILURES
- printf("*** Array type unsupported\n");
+ printf("*** Array type unsupported\n");
#endif
- //TODO: We fail horribly when recalling these as substitutions or
- // templates and trying to constify them eg:
- // _ZN4llvm2cl5applyIA28_cNS0_3optIbLb0ENS0_6parserIbEEEEEEvRKT_PT0_
- //
- //TODO: Chances are we don't do any better with references and pointers
- // that should be type (&) [] instead of type & []
+ // TODO: We fail horribly when recalling these as substitutions or
+ // templates and trying to constify them eg:
+ // _ZN4llvm2cl5applyIA28_cNS0_3optIbLb0ENS0_6parserIbEEEEEEvRKT_PT0_
+ //
+ // TODO: Chances are we don't do any better with references and pointers
+ // that should be type (&) [] instead of type & []
- return false;
+ return false;
-#if 0 // TODO
+#if 0 // TODO
if (*m_read_ptr == '_')
{
++m_read_ptr;
@@ -1152,589 +1125,593 @@ private:
return true;
}
#endif // TODO
- }
-
- // <pointer-to-member-type> ::= M <class type> <member type>
-
- //TODO: Determine how to handle pointers to function members correctly,
- // currently not an issue because we don't have function types at all...
- bool
- ParsePointerToMemberType()
- {
- int insertion_cookie = GetStartCookie();
- Write(' ');
- if (!ParseType())
- return false;
- WRITE("::*");
-
- int type_cookie = GetStartCookie();
- if (!ParseType())
- return false;
- ReorderRange (EndRange (type_cookie), insertion_cookie);
- return true;
- }
-
- // <template-param> ::= T_ # first template parameter
- // ::= T <parameter-2 non-negative number> _
-
- bool
- ParseTemplateParam()
- {
- int count = TryParseNumber();
- if (!Parse('_'))
- return false;
-
- // When no number is present we get -1, which is convenient since
- // T_ is the zeroth element T0_ is element 1, and so on
- return RewriteTemplateArg (count + 1);
- }
-
- // <type> ::= <builtin-type>
- // ::= <function-type>
- // ::= <class-enum-type>
- // ::= <array-type>
- // ::= <pointer-to-member-type>
- // ::= <template-param>
- // ::= <template-template-param> <template-args>
- // ::= <decltype>
- // ::= <substitution>
- // ::= <CV-qualifiers> <type>
- // ::= P <type> # pointer-to
- // ::= R <type> # reference-to
- // ::= O <type> # rvalue reference-to (C++0x)
- // ::= C <type> # complex pair (C 2000)
- // ::= G <type> # imaginary (C 2000)
- // ::= Dp <type> # pack expansion (C++0x)
- // ::= U <source-name> <type> # vendor extended type qualifier
- // extension := U <objc-name> <objc-type> # objc-type<identifier>
- // extension := <vector-type> # <vector-type> starts with Dv
-
- // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
- // <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
-
- bool
- ParseType()
- {
+ }
+
+ // <pointer-to-member-type> ::= M <class type> <member type>
+
+ // TODO: Determine how to handle pointers to function members correctly,
+ // currently not an issue because we don't have function types at all...
+ bool ParsePointerToMemberType() {
+ int insertion_cookie = GetStartCookie();
+ Write(' ');
+ if (!ParseType())
+ return false;
+ WRITE("::*");
+
+ int type_cookie = GetStartCookie();
+ if (!ParseType())
+ return false;
+ ReorderRange(EndRange(type_cookie), insertion_cookie);
+ return true;
+ }
+
+ // <template-param> ::= T_ # first template parameter
+ // ::= T <parameter-2 non-negative number> _
+
+ bool ParseTemplateParam() {
+ int count = TryParseNumber();
+ if (!Parse('_'))
+ return false;
+
+ // When no number is present we get -1, which is convenient since
+ // T_ is the zeroth element T0_ is element 1, and so on
+ return RewriteTemplateArg(count + 1);
+ }
+
+ // <vector-type>
+ // Dv <dimension number> _ <vector type>
+ bool TryParseVectorType() {
+ const int dimension = TryParseNumber();
+ if (dimension == -1)
+ return false;
+
+ if (*m_read_ptr++ != '_')
+ return false;
+
+ char vec_dimens[32] = {'\0'};
+ ::snprintf(vec_dimens, sizeof vec_dimens - 1, " __vector(%d)", dimension);
+ ParseType();
+ Write(vec_dimens);
+ return true;
+ }
+
+ // <type> ::= <builtin-type>
+ // ::= <function-type>
+ // ::= <class-enum-type>
+ // ::= <array-type>
+ // ::= <pointer-to-member-type>
+ // ::= <template-param>
+ // ::= <template-template-param> <template-args>
+ // ::= <decltype>
+ // ::= <substitution>
+ // ::= <CV-qualifiers> <type>
+ // ::= P <type> # pointer-to
+ // ::= R <type> # reference-to
+ // ::= O <type> # rvalue reference-to (C++0x)
+ // ::= C <type> # complex pair (C 2000)
+ // ::= G <type> # imaginary (C 2000)
+ // ::= Dp <type> # pack expansion (C++0x)
+ // ::= U <source-name> <type> # vendor extended type qualifier
+ // extension := U <objc-name> <objc-type> # objc-type<identifier>
+ // extension := <vector-type> # <vector-type> starts with Dv
+
+ // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 +
+ // <number of digits in k1> + k1
+ // <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name>
+ // 11objc_object -> id<source-name>
+
+ bool ParseType() {
#ifdef DEBUG_FAILURES
- const char *failed_type = m_read_ptr;
+ const char *failed_type = m_read_ptr;
#endif
- int type_start_cookie = GetStartCookie();
- bool suppress_substitution = false;
-
- int qualifiers = TryParseQualifiers (true, false);
- switch (*m_read_ptr)
- {
- case 'D':
- ++m_read_ptr;
- switch (*m_read_ptr++)
- {
- case 'p':
- if (!ParseType())
- return false;
- break;
- case 'T':
- case 't':
- case 'v':
- default:
+ int type_start_cookie = GetStartCookie();
+ bool suppress_substitution = false;
+
+ int qualifiers = TryParseQualifiers(true, false);
+ switch (*m_read_ptr) {
+ case 'D':
+ ++m_read_ptr;
+ switch (*m_read_ptr++) {
+ case 'p':
+ if (!ParseType())
+ return false;
+ break;
+ case 'v':
+ if (!TryParseVectorType())
+ return false;
+ break;
+ case 'T':
+ case 't':
+ default:
#ifdef DEBUG_FAILURES
- printf("*** Unsupported type: %.3s\n", failed_type);
+ printf("*** Unsupported type: %.3s\n", failed_type);
#endif
- return false;
- }
- break;
- case 'T':
- ++m_read_ptr;
- if (!ParseTemplateParam())
- return false;
- break;
- case 'M':
- ++m_read_ptr;
- if (!ParsePointerToMemberType())
- return false;
- break;
- case 'A':
- ++m_read_ptr;
- if (!ParseArrayType())
- return false;
- break;
- case 'F':
- ++m_read_ptr;
- if (!ParseFunctionType())
- return false;
- break;
- case 'S':
- if (*++m_read_ptr == 't')
- {
- ++m_read_ptr;
- WriteStdPrefix();
- if (!ParseName())
- return false;
- }
- else
- {
- suppress_substitution = true;
- if (!ParseSubstitution())
- return false;
- }
- break;
- case 'P':
- {
- switch (*++m_read_ptr)
- {
- case 'F':
- ++m_read_ptr;
- if (!ParseFunctionType(QualifierPointer))
- return false;
- break;
- default:
- if (!ParseType())
- return false;
- Write('*');
- break;
- }
- break;
- }
- case 'R':
- {
- ++m_read_ptr;
- if (!ParseType())
- return false;
- Write('&');
- break;
- }
- case 'O':
- {
- ++m_read_ptr;
- if (!ParseType())
- return false;
- Write('&');
- Write('&');
- break;
- }
- case 'C':
- case 'G':
- case 'U':
+ return false;
+ }
+ break;
+ case 'T':
+ ++m_read_ptr;
+ if (!ParseTemplateParam())
+ return false;
+ break;
+ case 'M':
+ ++m_read_ptr;
+ if (!ParsePointerToMemberType())
+ return false;
+ break;
+ case 'A':
+ ++m_read_ptr;
+ if (!ParseArrayType())
+ return false;
+ break;
+ case 'F':
+ ++m_read_ptr;
+ if (!ParseFunctionType())
+ return false;
+ break;
+ case 'S':
+ if (*++m_read_ptr == 't') {
+ ++m_read_ptr;
+ WriteStdPrefix();
+ if (!ParseName())
+ return false;
+ } else {
+ suppress_substitution = true;
+ if (!ParseSubstitution())
+ return false;
+ }
+ break;
+ case 'P': {
+ switch (*++m_read_ptr) {
+ case 'F':
+ ++m_read_ptr;
+ if (!ParseFunctionType(QualifierPointer))
+ return false;
+ break;
+ default:
+ if (!ParseType())
+ return false;
+ Write('*');
+ break;
+ }
+ break;
+ }
+ case 'R': {
+ ++m_read_ptr;
+ if (!ParseType())
+ return false;
+ Write('&');
+ break;
+ }
+ case 'O': {
+ ++m_read_ptr;
+ if (!ParseType())
+ return false;
+ Write('&');
+ Write('&');
+ break;
+ }
+ case 'C':
+ case 'G':
+ case 'U':
#ifdef DEBUG_FAILURES
- printf("*** Unsupported type: %.3s\n", failed_type);
+ printf("*** Unsupported type: %.3s\n", failed_type);
#endif
- return false;
- // Test for common cases to avoid TryParseBuiltinType() overhead
- case 'N':
- case 'Z':
- case 'L':
- if (!ParseName())
- return false;
- break;
- default:
- if (const char *builtin = TryParseBuiltinType())
- {
- Write(builtin);
- suppress_substitution = true;
- }
- else
- {
- if (!ParseName())
- return false;
- }
- break;
- }
-
- // Allow base substitutions to be suppressed, but always record
- // substitutions for the qualified variant
- if (!suppress_substitution)
- EndSubstitution(type_start_cookie);
- if (qualifiers)
- {
- WriteQualifiers(qualifiers, false);
- EndSubstitution(type_start_cookie);
- }
- return true;
+ return false;
+ // Test for common cases to avoid TryParseBuiltinType() overhead
+ case 'N':
+ case 'Z':
+ case 'L':
+ if (!ParseName())
+ return false;
+ break;
+ default:
+ if (const char *builtin = TryParseBuiltinType()) {
+ Write(builtin);
+ suppress_substitution = true;
+ } else {
+ if (!ParseName())
+ return false;
+ }
+ break;
+ }
+
+ // Allow base substitutions to be suppressed, but always record
+ // substitutions for the qualified variant
+ if (!suppress_substitution)
+ EndSubstitution(type_start_cookie);
+ if (qualifiers) {
+ WriteQualifiers(qualifiers, false);
+ EndSubstitution(type_start_cookie);
+ }
+ return true;
+ }
+
+ // <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
+ // ::= <closure-type-name>
+ //
+ // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
+ //
+ // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda
+ // has no parameters
+
+ bool ParseUnnamedTypeName(NameState &name_state) {
+ switch (*m_read_ptr++) {
+ case 't': {
+ int cookie = GetStartCookie();
+ WRITE("'unnamed");
+ const char *before_digits = m_read_ptr;
+ if (TryParseNumber() != -1)
+ Write(before_digits, m_read_ptr - before_digits);
+ if (!Parse('_'))
+ return false;
+ Write('\'');
+ name_state.last_name_range = EndRange(cookie);
+ return true;
+ }
+ case 'b': {
+ int cookie = GetStartCookie();
+ WRITE("'block");
+ const char *before_digits = m_read_ptr;
+ if (TryParseNumber() != -1)
+ Write(before_digits, m_read_ptr - before_digits);
+ if (!Parse('_'))
+ return false;
+ Write('\'');
+ name_state.last_name_range = EndRange(cookie);
+ return true;
}
-
- // <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
- // ::= <closure-type-name>
- //
- // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
- //
- // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda has no parameters
-
- bool
- ParseUnnamedTypeName(NameState & name_state)
- {
- switch (*m_read_ptr++)
- {
- case 't':
- {
- int cookie = GetStartCookie();
- WRITE("'unnamed");
- const char *before_digits = m_read_ptr;
- if (TryParseNumber() != -1) Write (before_digits,
- m_read_ptr - before_digits);
- if (!Parse('_'))
- return false;
- Write('\'');
- name_state.last_name_range = EndRange (cookie);
- return true;
- }
- case 'b':
- {
- int cookie = GetStartCookie();
- WRITE("'block");
- const char *before_digits = m_read_ptr;
- if (TryParseNumber() != -1) Write (before_digits,
- m_read_ptr - before_digits);
- if (!Parse('_'))
- return false;
- Write('\'');
- name_state.last_name_range = EndRange (cookie);
- return true;
- }
- case 'l':
+ case 'l':
#ifdef DEBUG_FAILURES
- printf("*** Lambda type names unsupported\n");
+ printf("*** Lambda type names unsupported\n");
#endif
- return false;
- }
+ return false;
+ }
#ifdef DEBUG_FAILURES
- printf("*** Unknown unnamed type %.3s\n", m_read_ptr - 2);
+ printf("*** Unknown unnamed type %.3s\n", m_read_ptr - 2);
#endif
- return false;
- }
+ return false;
+ }
- // <ctor-dtor-name> ::= C1 # complete object constructor
- // ::= C2 # base object constructor
- // ::= C3 # complete object allocating constructor
+ // <ctor-dtor-name> ::= C1 # complete object constructor
+ // ::= C2 # base object constructor
+ // ::= C3 # complete object allocating constructor
- bool
- ParseCtor(NameState & name_state)
- {
- char next = *m_read_ptr;
- if (next == '1' || next == '2' || next == '3' || next == '5')
- {
- RewriteRange (name_state.last_name_range);
- name_state.has_no_return_type = true;
- ++m_read_ptr;
- return true;
- }
+ bool ParseCtor(NameState &name_state) {
+ char next = *m_read_ptr;
+ if (next == '1' || next == '2' || next == '3' || next == '5') {
+ RewriteRange(name_state.last_name_range);
+ name_state.has_no_return_type = true;
+ ++m_read_ptr;
+ return true;
+ }
#ifdef DEBUG_FAILURES
- printf("*** Broken constructor\n");
+ printf("*** Broken constructor\n");
#endif
- return false;
+ return false;
+ }
+
+ // <ctor-dtor-name> ::= D0 # deleting destructor
+ // ::= D1 # complete object destructor
+ // ::= D2 # base object destructor
+
+ bool ParseDtor(NameState &name_state) {
+ char next = *m_read_ptr;
+ if (next == '0' || next == '1' || next == '2' || next == '5') {
+ Write('~');
+ RewriteRange(name_state.last_name_range);
+ name_state.has_no_return_type = true;
+ ++m_read_ptr;
+ return true;
}
-
- // <ctor-dtor-name> ::= D0 # deleting destructor
- // ::= D1 # complete object destructor
- // ::= D2 # base object destructor
-
- bool
- ParseDtor(NameState & name_state)
- {
- char next = *m_read_ptr;
- if (next == '0' || next == '1' || next == '2' || next == '5')
- {
- Write('~');
- RewriteRange(name_state.last_name_range);
- name_state.has_no_return_type = true;
- ++m_read_ptr;
- return true;
- }
#ifdef DEBUG_FAILURES
- printf("*** Broken destructor\n");
+ printf("*** Broken destructor\n");
#endif
- return false;
- }
+ return false;
+ }
- // See TryParseOperator()
+ // See TryParseOperator()
- bool
- ParseOperatorName(NameState & name_state)
- {
+ bool ParseOperatorName(NameState &name_state) {
#ifdef DEBUG_FAILURES
- const char *operator_ptr = m_read_ptr;
+ const char *operator_ptr = m_read_ptr;
#endif
- Operator parsed_operator = TryParseOperator();
- if (parsed_operator.name)
- {
- WRITE("operator");
- Write(parsed_operator.name);
- return true;
- }
-
- // Handle special operators
- switch (parsed_operator.kind)
- {
- case OperatorKind::Vendor:
- WRITE("operator ");
- return ParseSourceName();
- case OperatorKind::ConversionOperator:
- ResetTemplateArgs();
- name_state.has_no_return_type = true;
- WRITE("operator ");
- return ParseType();
- default:
+ Operator parsed_operator = TryParseOperator();
+ if (parsed_operator.name) {
+ WRITE("operator");
+ Write(parsed_operator.name);
+ return true;
+ }
+
+ // Handle special operators
+ switch (parsed_operator.kind) {
+ case OperatorKind::Vendor:
+ WRITE("operator ");
+ return ParseSourceName();
+ case OperatorKind::ConversionOperator:
+ ResetTemplateArgs();
+ name_state.has_no_return_type = true;
+ WRITE("operator ");
+ return ParseType();
+ default:
#ifdef DEBUG_FAILURES
- printf("*** Unknown operator: %.2s\n", operator_ptr);
+ printf("*** Unknown operator: %.2s\n", operator_ptr);
#endif
- return false;
- }
+ return false;
}
+ }
- // <source-name> ::= <positive length number> <identifier>
+ // <source-name> ::= <positive length number> <identifier>
- bool
- ParseSourceName()
- {
- int count = TryParseNumber();
- if (count == -1)
- {
+ bool ParseSourceName() {
+ int count = TryParseNumber();
+ if (count == -1) {
#ifdef DEBUG_FAILURES
- printf("*** Malformed source name, missing length count\n");
+ printf("*** Malformed source name, missing length count\n");
#endif
- return false;
- }
+ return false;
+ }
- const char *next_m_read_ptr = m_read_ptr + count;
- if (next_m_read_ptr > m_read_end)
- {
+ const char *next_m_read_ptr = m_read_ptr + count;
+ if (next_m_read_ptr > m_read_end) {
#ifdef DEBUG_FAILURES
- printf("*** Malformed source name, premature termination\n");
+ printf("*** Malformed source name, premature termination\n");
#endif
- return false;
- }
-
- if (count >= 10 && strncmp(m_read_ptr, "_GLOBAL__N", 10) == 0)
- WRITE("(anonymous namespace)");
- else Write(m_read_ptr, count);
-
- m_read_ptr = next_m_read_ptr;
- return true;
- }
-
- // <unqualified-name> ::= <operator-name>
- // ::= <ctor-dtor-name>
- // ::= <source-name>
- // ::= <unnamed-type-name>
-
- bool
- ParseUnqualifiedName(NameState & name_state)
- {
- // Note that these are detected directly in ParseNestedName for
- // performance rather than switching on the same options twice
- char next = *m_read_ptr;
- switch (next)
- {
- case 'C':
- ++m_read_ptr;
- return ParseCtor(name_state);
- case 'D':
- ++m_read_ptr;
- return ParseDtor(name_state);
- case 'U':
- ++m_read_ptr;
- return ParseUnnamedTypeName(name_state);
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- int name_start_cookie = GetStartCookie();
- if (!ParseSourceName())
- return false;
- name_state.last_name_range = EndRange(name_start_cookie);
- return true;
- }
- default:
- return ParseOperatorName(name_state);
- };
- }
-
- // <unscoped-name> ::= <unqualified-name>
- // ::= St <unqualified-name> # ::std::
- // extension ::= StL<unqualified-name>
-
- bool
- ParseUnscopedName(NameState & name_state)
- {
- if (*m_read_ptr == 'S' && *(m_read_ptr + 1) == 't')
- {
- WriteStdPrefix();
- if (*(m_read_ptr += 2) == 'L')
- ++m_read_ptr;
- }
- return ParseUnqualifiedName(name_state);
- }
-
- bool
- ParseIntegerLiteral(const char *prefix, const char *suffix,
- bool allow_negative)
- {
- if (prefix)
- Write(prefix);
- if (!ParseNumber(allow_negative))
- return false;
- if (suffix)
- Write(suffix);
- return Parse('E');
+ return false;
+ }
+
+ if (count >= 10 && strncmp(m_read_ptr, "_GLOBAL__N", 10) == 0)
+ WRITE("(anonymous namespace)");
+ else
+ Write(m_read_ptr, count);
+
+ m_read_ptr = next_m_read_ptr;
+ return true;
+ }
+
+ // <unqualified-name> ::= <operator-name>
+ // ::= <ctor-dtor-name>
+ // ::= <source-name>
+ // ::= <unnamed-type-name>
+
+ bool ParseUnqualifiedName(NameState &name_state) {
+ // Note that these are detected directly in ParseNestedName for
+ // performance rather than switching on the same options twice
+ char next = *m_read_ptr;
+ switch (next) {
+ case 'C':
+ ++m_read_ptr;
+ return ParseCtor(name_state);
+ case 'D':
+ ++m_read_ptr;
+ return ParseDtor(name_state);
+ case 'U':
+ ++m_read_ptr;
+ return ParseUnnamedTypeName(name_state);
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ int name_start_cookie = GetStartCookie();
+ if (!ParseSourceName())
+ return false;
+ name_state.last_name_range = EndRange(name_start_cookie);
+ return true;
+ }
+ default:
+ return ParseOperatorName(name_state);
+ };
+ }
+
+ // <unscoped-name> ::= <unqualified-name>
+ // ::= St <unqualified-name> # ::std::
+ // extension ::= StL<unqualified-name>
+
+ bool ParseUnscopedName(NameState &name_state) {
+ if (*m_read_ptr == 'S' && *(m_read_ptr + 1) == 't') {
+ WriteStdPrefix();
+ if (*(m_read_ptr += 2) == 'L')
+ ++m_read_ptr;
}
-
- bool
- ParseBooleanLiteral()
- {
- switch (*m_read_ptr++)
- {
- case '0': WRITE("false"); break;
- case '1': WRITE("true"); break;
- default:
+ return ParseUnqualifiedName(name_state);
+ }
+
+ bool ParseIntegerLiteral(const char *prefix, const char *suffix,
+ bool allow_negative) {
+ if (prefix)
+ Write(prefix);
+ if (!ParseNumber(allow_negative))
+ return false;
+ if (suffix)
+ Write(suffix);
+ return Parse('E');
+ }
+
+ bool ParseBooleanLiteral() {
+ switch (*m_read_ptr++) {
+ case '0':
+ WRITE("false");
+ break;
+ case '1':
+ WRITE("true");
+ break;
+ default:
#ifdef DEBUG_FAILURES
- printf("*** Boolean literal not 0 or 1\n");
+ printf("*** Boolean literal not 0 or 1\n");
#endif
- return false;
- }
+ return false;
+ }
+ return Parse('E');
+ }
+
+ // <expr-primary> ::= L <type> <value number> E #
+ // integer literal
+ // ::= L <type> <value float> E #
+ // floating literal
+ // ::= L <string type> E #
+ // string literal
+ // ::= L <nullptr type> E #
+ // nullptr literal (i.e., "LDnE")
+ // ::= L <type> <real-part float> _ <imag-part float> E #
+ // complex floating point literal (C 2000)
+ // ::= L <mangled-name> E #
+ // external name
+
+ bool ParseExpressionPrimary() {
+ switch (*m_read_ptr++) {
+ case 'b':
+ return ParseBooleanLiteral();
+ case 'x':
+ return ParseIntegerLiteral(nullptr, "ll", true);
+ case 'l':
+ return ParseIntegerLiteral(nullptr, "l", true);
+ case 'i':
+ return ParseIntegerLiteral(nullptr, nullptr, true);
+ case 'n':
+ return ParseIntegerLiteral("(__int128)", nullptr, true);
+ case 'j':
+ return ParseIntegerLiteral(nullptr, "u", false);
+ case 'm':
+ return ParseIntegerLiteral(nullptr, "ul", false);
+ case 'y':
+ return ParseIntegerLiteral(nullptr, "ull", false);
+ case 'o':
+ return ParseIntegerLiteral("(unsigned __int128)", nullptr, false);
+ case '_':
+ if (*m_read_ptr++ == 'Z') {
+ if (!ParseEncoding())
+ return false;
return Parse('E');
- }
-
- // <expr-primary> ::= L <type> <value number> E # integer literal
- // ::= L <type> <value float> E # floating literal
- // ::= L <string type> E # string literal
- // ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
- // ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
- // ::= L <mangled-name> E # external name
-
- bool
- ParseExpressionPrimary()
- {
- switch (*m_read_ptr++)
- {
- case 'b': return ParseBooleanLiteral();
- case 'x': return ParseIntegerLiteral(nullptr, "ll", true);
- case 'l': return ParseIntegerLiteral(nullptr, "l", true);
- case 'i': return ParseIntegerLiteral(nullptr, nullptr, true);
- case 'n': return ParseIntegerLiteral("(__int128)", nullptr, true);
- case 'j': return ParseIntegerLiteral(nullptr, "u", false);
- case 'm': return ParseIntegerLiteral(nullptr, "ul", false);
- case 'y': return ParseIntegerLiteral(nullptr, "ull", false);
- case 'o': return ParseIntegerLiteral("(unsigned __int128)",
- nullptr, false);
- case '_':
- if (*m_read_ptr++ == 'Z')
- {
- if (!ParseEncoding())
- return false;
- return Parse('E');
- }
- --m_read_ptr;
- LLVM_FALLTHROUGH;
- case 'w':
- case 'c':
- case 'a':
- case 'h':
- case 's':
- case 't':
- case 'f':
- case 'd':
- case 'e':
+ }
+ --m_read_ptr;
+ LLVM_FALLTHROUGH;
+ case 'w':
+ case 'c':
+ case 'a':
+ case 'h':
+ case 's':
+ case 't':
+ case 'f':
+ case 'd':
+ case 'e':
#ifdef DEBUG_FAILURES
- printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1);
+ printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1);
#endif
- return false;
- case 'T':
- // Invalid mangled name per
- // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
+ return false;
+ case 'T':
+// Invalid mangled name per
+// http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
#ifdef DEBUG_FAILURES
- printf("*** Invalid primary expr encoding\n");
+ printf("*** Invalid primary expr encoding\n");
#endif
- return false;
- default:
- --m_read_ptr;
- Write('(');
- if (!ParseType())
- return false;
- Write(')');
- if (!ParseNumber())
- return false;
- return Parse('E');
- }
+ return false;
+ default:
+ --m_read_ptr;
+ Write('(');
+ if (!ParseType())
+ return false;
+ Write(')');
+ if (!ParseNumber())
+ return false;
+ return Parse('E');
}
+ }
- // <unresolved-type> ::= <template-param>
- // ::= <decltype>
- // ::= <substitution>
+ // <unresolved-type> ::= <template-param>
+ // ::= <decltype>
+ // ::= <substitution>
- bool
- ParseUnresolvedType()
- {
- int type_start_cookie = GetStartCookie();
- switch (*m_read_ptr++)
- {
- case 'T':
- if (!ParseTemplateParam())
- return false;
- EndSubstitution(type_start_cookie);
- return true;
- case 'S':
- {
- if (*m_read_ptr != 't')
- return ParseSubstitution();
-
- ++m_read_ptr;
- WriteStdPrefix();
- NameState type_name = {};
- if (!ParseUnqualifiedName(type_name))
- return false;
- EndSubstitution(type_start_cookie);
- return true;
-
- }
- case 'D':
- default:
+ bool ParseUnresolvedType() {
+ int type_start_cookie = GetStartCookie();
+ switch (*m_read_ptr++) {
+ case 'T':
+ if (!ParseTemplateParam())
+ return false;
+ EndSubstitution(type_start_cookie);
+ return true;
+ case 'S': {
+ if (*m_read_ptr != 't')
+ return ParseSubstitution();
+
+ ++m_read_ptr;
+ WriteStdPrefix();
+ NameState type_name = {};
+ if (!ParseUnqualifiedName(type_name))
+ return false;
+ EndSubstitution(type_start_cookie);
+ return true;
+ }
+ case 'D':
+ default:
#ifdef DEBUG_FAILURES
- printf("*** Unsupported unqualified type: %3s\n", m_read_ptr - 1);
+ printf("*** Unsupported unqualified type: %3s\n", m_read_ptr - 1);
#endif
- return false;
- }
- }
-
- // <base-unresolved-name> ::= <simple-id> # unresolved name
- // extension ::= <operator-name> # unresolved operator-function-id
- // extension ::= <operator-name> <template-args> # unresolved operator template-id
- // ::= on <operator-name> # unresolved operator-function-id
- // ::= on <operator-name> <template-args> # unresolved operator template-id
- // ::= dn <destructor-name> # destructor or pseudo-destructor;
- // # e.g. ~X or ~X<N-1>
-
- bool
- ParseBaseUnresolvedName()
- {
+ return false;
+ }
+ }
+
+ // <base-unresolved-name> ::= <simple-id> #
+ // unresolved name
+ // extension ::= <operator-name> #
+ // unresolved operator-function-id
+ // extension ::= <operator-name> <template-args> #
+ // unresolved operator template-id
+ // ::= on <operator-name> #
+ // unresolved operator-function-id
+ // ::= on <operator-name> <template-args> #
+ // unresolved operator template-id
+ // ::= dn <destructor-name> #
+ // destructor or pseudo-destructor;
+ // #
+ // e.g.
+ // ~X
+ // or
+ // ~X<N-1>
+
+ bool ParseBaseUnresolvedName() {
#ifdef DEBUG_FAILURES
- printf("*** Base unresolved name unsupported\n");
+ printf("*** Base unresolved name unsupported\n");
#endif
- return false;
- }
-
- // <unresolved-name>
- // extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
- // ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
- // ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
- // # A::x, N::y, A<T>::z; "gs" means leading "::"
- // ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
- // extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
- // # T::N::x /decltype(p)::N::x
- // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
-
- bool
- ParseUnresolvedName()
- {
+ return false;
+ }
+
+ // <unresolved-name>
+ // extension ::= srN <unresolved-type> [<template-args>]
+ // <unresolved-qualifier-level>* E <base-unresolved-name>
+ // ::= [gs] <base-unresolved-name> # x
+ // or (with "gs") ::x
+ // ::= [gs] sr <unresolved-qualifier-level>+ E
+ // <base-unresolved-name>
+ // #
+ // A::x,
+ // N::y,
+ // A<T>::z;
+ // "gs"
+ // means
+ // leading
+ // "::"
+ // ::= sr <unresolved-type> <base-unresolved-name> #
+ // T::x / decltype(p)::x
+ // extension ::= sr <unresolved-type> <template-args>
+ // <base-unresolved-name>
+ // #
+ // T::N::x
+ // /decltype(p)::N::x
+ // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+
+ // E <base-unresolved-name>
+
+ bool ParseUnresolvedName() {
#ifdef DEBUG_FAILURES
- printf("*** Unresolved names not supported\n");
+ printf("*** Unresolved names not supported\n");
#endif
- //TODO: grammar for all of this seems unclear...
- return false;
+ // TODO: grammar for all of this seems unclear...
+ return false;
#if 0 // TODO
if (*m_read_ptr == 'g' && *(m_read_ptr + 1) == 's')
@@ -1743,677 +1720,677 @@ private:
WriteNamespaceSeparator();
}
#endif // TODO
- }
-
- // <expression> ::= <unary operator-name> <expression>
- // ::= <binary operator-name> <expression> <expression>
- // ::= <ternary operator-name> <expression> <expression> <expression>
- // ::= cl <expression>+ E # call
- // ::= cv <type> <expression> # conversion with one argument
- // ::= cv <type> _ <expression>* E # conversion with a different number of arguments
- // ::= [gs] nw <expression>* _ <type> E # new (expr-list) type
- // ::= [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
- // ::= [gs] na <expression>* _ <type> E # new[] (expr-list) type
- // ::= [gs] na <expression>* _ <type> <initializer> # new[] (expr-list) type (init)
- // ::= [gs] dl <expression> # delete expression
- // ::= [gs] da <expression> # delete[] expression
- // ::= pp_ <expression> # prefix ++
- // ::= mm_ <expression> # prefix --
- // ::= ti <type> # typeid (type)
- // ::= te <expression> # typeid (expression)
- // ::= dc <type> <expression> # dynamic_cast<type> (expression)
- // ::= sc <type> <expression> # static_cast<type> (expression)
- // ::= cc <type> <expression> # const_cast<type> (expression)
- // ::= rc <type> <expression> # reinterpret_cast<type> (expression)
- // ::= st <type> # sizeof (a type)
- // ::= sz <expression> # sizeof (an expression)
- // ::= at <type> # alignof (a type)
- // ::= az <expression> # alignof (an expression)
- // ::= nx <expression> # noexcept (expression)
- // ::= <template-param>
- // ::= <function-param>
- // ::= dt <expression> <unresolved-name> # expr.name
- // ::= pt <expression> <unresolved-name> # expr->name
- // ::= ds <expression> <expression> # expr.*expr
- // ::= sZ <template-param> # size of a parameter pack
- // ::= sZ <function-param> # size of a function parameter pack
- // ::= sp <expression> # pack expansion
- // ::= tw <expression> # throw expression
- // ::= tr # throw with no operand (rethrow)
- // ::= <unresolved-name> # f(p), N::f(p), ::f(p),
- // # freestanding dependent name (e.g., T::x),
- // # objectless nonstatic member reference
- // ::= <expr-primary>
-
- bool
- ParseExpression()
- {
- Operator expression_operator = TryParseOperator();
- switch (expression_operator.kind)
- {
- case OperatorKind::Unary:
- Write(expression_operator.name);
- Write('(');
- if (!ParseExpression())
- return false;
- Write(')');
- return true;
- case OperatorKind::Binary:
- if (!ParseExpression())
- return false;
- Write(expression_operator.name);
- return ParseExpression();
- case OperatorKind::Ternary:
- if (!ParseExpression())
- return false;
- Write('?');
- if (!ParseExpression())
- return false;
- Write(':');
- return ParseExpression();
- case OperatorKind::NoMatch:
- break;
- case OperatorKind::Other:
- default:
+ }
+
+ // <expression> ::= <unary operator-name> <expression>
+ // ::= <binary operator-name> <expression> <expression>
+ // ::= <ternary operator-name> <expression> <expression>
+ // <expression>
+ // ::= cl <expression>+ E #
+ // call
+ // ::= cv <type> <expression> #
+ // conversion with one argument
+ // ::= cv <type> _ <expression>* E #
+ // conversion with a different number of arguments
+ // ::= [gs] nw <expression>* _ <type> E # new
+ // (expr-list) type
+ // ::= [gs] nw <expression>* _ <type> <initializer> # new
+ // (expr-list) type (init)
+ // ::= [gs] na <expression>* _ <type> E #
+ // new[] (expr-list) type
+ // ::= [gs] na <expression>* _ <type> <initializer> #
+ // new[] (expr-list) type (init)
+ // ::= [gs] dl <expression> #
+ // delete expression
+ // ::= [gs] da <expression> #
+ // delete[] expression
+ // ::= pp_ <expression> #
+ // prefix ++
+ // ::= mm_ <expression> #
+ // prefix --
+ // ::= ti <type> #
+ // typeid (type)
+ // ::= te <expression> #
+ // typeid (expression)
+ // ::= dc <type> <expression> #
+ // dynamic_cast<type> (expression)
+ // ::= sc <type> <expression> #
+ // static_cast<type> (expression)
+ // ::= cc <type> <expression> #
+ // const_cast<type> (expression)
+ // ::= rc <type> <expression> #
+ // reinterpret_cast<type> (expression)
+ // ::= st <type> #
+ // sizeof (a type)
+ // ::= sz <expression> #
+ // sizeof (an expression)
+ // ::= at <type> #
+ // alignof (a type)
+ // ::= az <expression> #
+ // alignof (an expression)
+ // ::= nx <expression> #
+ // noexcept (expression)
+ // ::= <template-param>
+ // ::= <function-param>
+ // ::= dt <expression> <unresolved-name> #
+ // expr.name
+ // ::= pt <expression> <unresolved-name> #
+ // expr->name
+ // ::= ds <expression> <expression> #
+ // expr.*expr
+ // ::= sZ <template-param> #
+ // size of a parameter pack
+ // ::= sZ <function-param> #
+ // size of a function parameter pack
+ // ::= sp <expression> #
+ // pack expansion
+ // ::= tw <expression> #
+ // throw expression
+ // ::= tr #
+ // throw with no operand (rethrow)
+ // ::= <unresolved-name> #
+ // f(p), N::f(p), ::f(p),
+ // #
+ // freestanding
+ // dependent
+ // name
+ // (e.g.,
+ // T::x),
+ // #
+ // objectless
+ // nonstatic
+ // member
+ // reference
+ // ::= <expr-primary>
+
+ bool ParseExpression() {
+ Operator expression_operator = TryParseOperator();
+ switch (expression_operator.kind) {
+ case OperatorKind::Unary:
+ Write(expression_operator.name);
+ Write('(');
+ if (!ParseExpression())
+ return false;
+ Write(')');
+ return true;
+ case OperatorKind::Binary:
+ if (!ParseExpression())
+ return false;
+ Write(expression_operator.name);
+ return ParseExpression();
+ case OperatorKind::Ternary:
+ if (!ParseExpression())
+ return false;
+ Write('?');
+ if (!ParseExpression())
+ return false;
+ Write(':');
+ return ParseExpression();
+ case OperatorKind::NoMatch:
+ break;
+ case OperatorKind::Other:
+ default:
#ifdef DEBUG_FAILURES
- printf("*** Unsupported operator: %s\n", expression_operator.name);
+ printf("*** Unsupported operator: %s\n", expression_operator.name);
#endif
- return false;
- }
-
- switch (*m_read_ptr++)
- {
- case 'T': return ParseTemplateParam();
- case 'L': return ParseExpressionPrimary();
- case 's':
- if (*m_read_ptr++ == 'r')
- return ParseUnresolvedName();
- --m_read_ptr;
- LLVM_FALLTHROUGH;
- default:
- return ParseExpressionPrimary();
- }
- }
-
- // <template-arg> ::= <type> # type or template
- // ::= X <expression> E # expression
- // ::= <expr-primary> # simple expressions
- // ::= J <template-arg>* E # argument pack
- // ::= LZ <encoding> E # extension
-
- bool
- ParseTemplateArg()
- {
- switch (*m_read_ptr) {
- case 'J':
+ return false;
+ }
+
+ switch (*m_read_ptr++) {
+ case 'T':
+ return ParseTemplateParam();
+ case 'L':
+ return ParseExpressionPrimary();
+ case 's':
+ if (*m_read_ptr++ == 'r')
+ return ParseUnresolvedName();
+ --m_read_ptr;
+ LLVM_FALLTHROUGH;
+ default:
+ return ParseExpressionPrimary();
+ }
+ }
+
+ // <template-arg> ::= <type> #
+ // type or template
+ // ::= X <expression> E #
+ // expression
+ // ::= <expr-primary> #
+ // simple expressions
+ // ::= J <template-arg>* E #
+ // argument pack
+ // ::= LZ <encoding> E #
+ // extension
+
+ bool ParseTemplateArg() {
+ switch (*m_read_ptr) {
+ case 'J':
#ifdef DEBUG_FAILURES
- printf("*** Template argument packs unsupported\n");
+ printf("*** Template argument packs unsupported\n");
#endif
- return false;
- case 'X':
- ++m_read_ptr;
- if (!ParseExpression())
- return false;
- return Parse('E');
- case 'L':
- ++m_read_ptr;
- return ParseExpressionPrimary();
- default:
- return ParseType();
- }
- }
-
- // <template-args> ::= I <template-arg>* E
- // extension, the abi says <template-arg>+
-
- bool
- ParseTemplateArgs(bool record_template_args = false)
- {
- if (record_template_args)
- ResetTemplateArgs();
+ return false;
+ case 'X':
+ ++m_read_ptr;
+ if (!ParseExpression())
+ return false;
+ return Parse('E');
+ case 'L':
+ ++m_read_ptr;
+ return ParseExpressionPrimary();
+ default:
+ return ParseType();
+ }
+ }
+
+ // <template-args> ::= I <template-arg>* E
+ // extension, the abi says <template-arg>+
+
+ bool ParseTemplateArgs(bool record_template_args = false) {
+ if (record_template_args)
+ ResetTemplateArgs();
+
+ bool first_arg = true;
+ while (*m_read_ptr != 'E') {
+ if (first_arg)
+ first_arg = false;
+ else
+ WriteCommaSpace();
+
+ int template_start_cookie = GetStartCookie();
+ if (!ParseTemplateArg())
+ return false;
+ if (record_template_args)
+ EndTemplateArg(template_start_cookie);
+ }
+ ++m_read_ptr;
+ return true;
+ }
+
+ // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix>
+ // <unqualified-name> E
+ // ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix>
+ // <template-args> E
+ //
+ // <prefix> ::= <prefix> <unqualified-name>
+ // ::= <template-prefix> <template-args>
+ // ::= <template-param>
+ // ::= <decltype>
+ // ::= # empty
+ // ::= <substitution>
+ // ::= <prefix> <data-member-prefix>
+ // extension ::= L
+ //
+ // <template-prefix> ::= <prefix> <template unqualified-name>
+ // ::= <template-param>
+ // ::= <substitution>
+ //
+ // <unqualified-name> ::= <operator-name>
+ // ::= <ctor-dtor-name>
+ // ::= <source-name>
+ // ::= <unnamed-type-name>
+
+ bool ParseNestedName(NameState &name_state,
+ bool parse_discriminator = false) {
+ int qualifiers = TryParseQualifiers(true, true);
+ bool first_part = true;
+ bool suppress_substitution = true;
+ int name_start_cookie = GetStartCookie();
+ while (true) {
+ char next = *m_read_ptr;
+ if (next == 'E') {
+ ++m_read_ptr;
+ break;
+ }
- bool first_arg = true;
- while (*m_read_ptr != 'E')
- {
- if (first_arg)
- first_arg = false;
- else WriteCommaSpace();
+ // Record a substitution candidate for all prefixes, but not the full name
+ if (suppress_substitution)
+ suppress_substitution = false;
+ else
+ EndSubstitution(name_start_cookie);
- int template_start_cookie = GetStartCookie();
- if (!ParseTemplateArg())
- return false;
- if (record_template_args)
- EndTemplateArg(template_start_cookie);
- }
+ if (next == 'I') {
++m_read_ptr;
- return true;
- }
-
- // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
- // ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
- //
- // <prefix> ::= <prefix> <unqualified-name>
- // ::= <template-prefix> <template-args>
- // ::= <template-param>
- // ::= <decltype>
- // ::= # empty
- // ::= <substitution>
- // ::= <prefix> <data-member-prefix>
- // extension ::= L
- //
- // <template-prefix> ::= <prefix> <template unqualified-name>
- // ::= <template-param>
- // ::= <substitution>
- //
- // <unqualified-name> ::= <operator-name>
- // ::= <ctor-dtor-name>
- // ::= <source-name>
- // ::= <unnamed-type-name>
-
- bool
- ParseNestedName(NameState & name_state, bool parse_discriminator = false)
- {
- int qualifiers = TryParseQualifiers(true, true);
- bool first_part = true;
- bool suppress_substitution = true;
+ name_state.is_last_generic = true;
+ WriteTemplateStart();
+ if (!ParseTemplateArgs(name_state.parse_function_params))
+ return false;
+ WriteTemplateEnd();
+ continue;
+ }
+
+ if (first_part)
+ first_part = false;
+ else
+ WriteNamespaceSeparator();
+
+ name_state.is_last_generic = false;
+ switch (next) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
int name_start_cookie = GetStartCookie();
- while (true)
- {
- char next = *m_read_ptr;
- if (next == 'E')
- {
- ++m_read_ptr;
- break;
- }
-
- // Record a substitution candidate for all prefixes, but not the full name
- if (suppress_substitution)
- suppress_substitution = false;
- else EndSubstitution(name_start_cookie);
-
- if (next == 'I')
- {
- ++m_read_ptr;
- name_state.is_last_generic = true;
- WriteTemplateStart();
- if (!ParseTemplateArgs(name_state.parse_function_params))
- return false;
- WriteTemplateEnd();
- continue;
- }
-
- if (first_part)
- first_part = false;
- else WriteNamespaceSeparator();
-
- name_state.is_last_generic = false;
- switch (next)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- int name_start_cookie = GetStartCookie();
- if (!ParseSourceName())
- return false;
- name_state.last_name_range = EndRange(name_start_cookie);
- continue;
- }
- case 'S':
- if (*++m_read_ptr == 't')
- {
- WriteStdPrefix();
- ++m_read_ptr;
- if (!ParseUnqualifiedName(name_state))
- return false;
- }
- else
- {
- if (!ParseSubstitution())
- return false;
- suppress_substitution = true;
- }
- continue;
- case 'T':
- ++m_read_ptr;
- if (!ParseTemplateParam())
- return false;
- continue;
- case 'C':
- ++m_read_ptr;
- if (!ParseCtor(name_state))
- return false;
- continue;
- case 'D':
- {
- switch (*(m_read_ptr + 1))
- {
- case 't':
- case 'T':
-#ifdef DEBUG_FAILURES
- printf("*** Decltype unsupported\n");
-#endif
- return false;
- }
- ++m_read_ptr;
- if (!ParseDtor(name_state))
- return false;
- continue;
- }
- case 'U':
- ++m_read_ptr;
- if (!ParseUnnamedTypeName(name_state))
- return false;
- continue;
- case 'L':
- ++m_read_ptr;
- if (!ParseUnqualifiedName(name_state))
- return false;
- continue;
- default:
- if (!ParseOperatorName(name_state))
- return false;
- }
- }
-
- if (parse_discriminator)
- TryParseDiscriminator();
- if (name_state.parse_function_params
- && !ParseFunctionArgs(name_state, name_start_cookie))
- {
- return false;
- }
- if (qualifiers)
- WriteQualifiers(qualifiers);
- return true;
- }
-
- // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
- // := Z <function encoding> E s [<discriminator>]
- // := Z <function encoding> Ed [ <parameter number> ] _ <entity name>
-
- bool
- ParseLocalName(bool parse_function_params)
- {
- if (!ParseEncoding())
+ if (!ParseSourceName())
+ return false;
+ name_state.last_name_range = EndRange(name_start_cookie);
+ continue;
+ }
+ case 'S':
+ if (*++m_read_ptr == 't') {
+ WriteStdPrefix();
+ ++m_read_ptr;
+ if (!ParseUnqualifiedName(name_state))
return false;
- if (!Parse('E'))
+ } else {
+ if (!ParseSubstitution())
return false;
-
- switch (*m_read_ptr)
- {
- case 's':
- ++m_read_ptr;
- TryParseDiscriminator(); // Optional and ignored
- WRITE("::string literal");
- break;
- case 'd':
- ++m_read_ptr;
- TryParseNumber(); // Optional and ignored
- if (!Parse('_'))
- return false;
- WriteNamespaceSeparator();
- if (!ParseName())
- return false;
- break;
- default:
- WriteNamespaceSeparator();
- if (!ParseName(parse_function_params, true))
- return false;
- TryParseDiscriminator(); // Optional and ignored
+ suppress_substitution = true;
}
- return true;
- }
-
- // <name> ::= <nested-name>
- // ::= <local-name>
- // ::= <unscoped-template-name> <template-args>
- // ::= <unscoped-name>
-
- // <unscoped-template-name> ::= <unscoped-name>
- // ::= <substitution>
-
- bool
- ParseName(bool parse_function_params = false,
- bool parse_discriminator = false)
- {
- NameState name_state = { parse_function_params, false, false, {0, 0}};
- int name_start_cookie = GetStartCookie();
-
- switch (*m_read_ptr)
- {
- case 'N':
- ++m_read_ptr;
- return ParseNestedName(name_state, parse_discriminator);
- case 'Z':
- {
- ++m_read_ptr;
- if (!ParseLocalName(parse_function_params))
- return false;
- break;
- }
- case 'L':
- ++m_read_ptr;
- LLVM_FALLTHROUGH;
- default:
- {
- if (!ParseUnscopedName(name_state))
- return false;
-
- if (*m_read_ptr == 'I')
- {
- EndSubstitution(name_start_cookie);
-
- ++m_read_ptr;
- name_state.is_last_generic = true;
- WriteTemplateStart();
- if (!ParseTemplateArgs(parse_function_params))
- return false;
- WriteTemplateEnd();
- }
- break;
- }
- }
- if (parse_discriminator)
- TryParseDiscriminator();
- if (parse_function_params &&
- !ParseFunctionArgs(name_state, name_start_cookie))
- {
- return false;
+ continue;
+ case 'T':
+ ++m_read_ptr;
+ if (!ParseTemplateParam())
+ return false;
+ continue;
+ case 'C':
+ ++m_read_ptr;
+ if (!ParseCtor(name_state))
+ return false;
+ continue;
+ case 'D': {
+ switch (*(m_read_ptr + 1)) {
+ case 't':
+ case 'T':
+#ifdef DEBUG_FAILURES
+ printf("*** Decltype unsupported\n");
+#endif
+ return false;
}
- return true;
+ ++m_read_ptr;
+ if (!ParseDtor(name_state))
+ return false;
+ continue;
+ }
+ case 'U':
+ ++m_read_ptr;
+ if (!ParseUnnamedTypeName(name_state))
+ return false;
+ continue;
+ case 'L':
+ ++m_read_ptr;
+ if (!ParseUnqualifiedName(name_state))
+ return false;
+ continue;
+ default:
+ if (!ParseOperatorName(name_state))
+ return false;
+ }
+ }
+
+ if (parse_discriminator)
+ TryParseDiscriminator();
+ if (name_state.parse_function_params &&
+ !ParseFunctionArgs(name_state, name_start_cookie)) {
+ return false;
+ }
+ if (qualifiers)
+ WriteQualifiers(qualifiers);
+ return true;
+ }
+
+ // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
+ // := Z <function encoding> E s [<discriminator>]
+ // := Z <function encoding> Ed [ <parameter number> ] _ <entity
+ // name>
+
+ bool ParseLocalName(bool parse_function_params) {
+ if (!ParseEncoding())
+ return false;
+ if (!Parse('E'))
+ return false;
+
+ switch (*m_read_ptr) {
+ case 's':
+ ++m_read_ptr;
+ TryParseDiscriminator(); // Optional and ignored
+ WRITE("::string literal");
+ break;
+ case 'd':
+ ++m_read_ptr;
+ TryParseNumber(); // Optional and ignored
+ if (!Parse('_'))
+ return false;
+ WriteNamespaceSeparator();
+ if (!ParseName())
+ return false;
+ break;
+ default:
+ WriteNamespaceSeparator();
+ if (!ParseName(parse_function_params, true))
+ return false;
+ TryParseDiscriminator(); // Optional and ignored
+ }
+ return true;
+ }
+
+ // <name> ::= <nested-name>
+ // ::= <local-name>
+ // ::= <unscoped-template-name> <template-args>
+ // ::= <unscoped-name>
+
+ // <unscoped-template-name> ::= <unscoped-name>
+ // ::= <substitution>
+
+ bool ParseName(bool parse_function_params = false,
+ bool parse_discriminator = false) {
+ NameState name_state = {parse_function_params, false, false, {0, 0}};
+ int name_start_cookie = GetStartCookie();
+
+ switch (*m_read_ptr) {
+ case 'N':
+ ++m_read_ptr;
+ return ParseNestedName(name_state, parse_discriminator);
+ case 'Z': {
+ ++m_read_ptr;
+ if (!ParseLocalName(parse_function_params))
+ return false;
+ break;
}
+ case 'L':
+ ++m_read_ptr;
+ LLVM_FALLTHROUGH;
+ default: {
+ if (!ParseUnscopedName(name_state))
+ return false;
- // <call-offset> ::= h <nv-offset> _
- // ::= v <v-offset> _
- //
- // <nv-offset> ::= <offset number>
- // # non-virtual base override
- //
- // <v-offset> ::= <offset number> _ <virtual offset number>
- // # virtual base override, with vcall offset
+ if (*m_read_ptr == 'I') {
+ EndSubstitution(name_start_cookie);
- bool
- ParseCallOffset()
- {
- switch (*m_read_ptr++)
- {
- case 'h':
- if (*m_read_ptr == 'n')
- ++m_read_ptr;
- if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
- break;
- return true;
- case 'v':
- if (*m_read_ptr == 'n')
- ++m_read_ptr;
- if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
- break;
- if (*m_read_ptr == 'n')
- ++m_read_ptr;
- if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
- break;
- return true;
- }
+ ++m_read_ptr;
+ name_state.is_last_generic = true;
+ WriteTemplateStart();
+ if (!ParseTemplateArgs(parse_function_params))
+ return false;
+ WriteTemplateEnd();
+ }
+ break;
+ }
+ }
+ if (parse_discriminator)
+ TryParseDiscriminator();
+ if (parse_function_params &&
+ !ParseFunctionArgs(name_state, name_start_cookie)) {
+ return false;
+ }
+ return true;
+ }
+
+ // <call-offset> ::= h <nv-offset> _
+ // ::= v <v-offset> _
+ //
+ // <nv-offset> ::= <offset number>
+ // # non-virtual base override
+ //
+ // <v-offset> ::= <offset number> _ <virtual offset number>
+ // # virtual base override, with vcall offset
+
+ bool ParseCallOffset() {
+ switch (*m_read_ptr++) {
+ case 'h':
+ if (*m_read_ptr == 'n')
+ ++m_read_ptr;
+ if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
+ break;
+ return true;
+ case 'v':
+ if (*m_read_ptr == 'n')
+ ++m_read_ptr;
+ if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
+ break;
+ if (*m_read_ptr == 'n')
+ ++m_read_ptr;
+ if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
+ break;
+ return true;
+ }
#ifdef DEBUG_FAILURES
- printf("*** Malformed call offset\n");
+ printf("*** Malformed call offset\n");
#endif
- return false;
- }
-
- // <special-name> ::= TV <type> # virtual table
- // ::= TT <type> # VTT structure (construction vtable index)
- // ::= TI <type> # typeinfo structure
- // ::= TS <type> # typeinfo name (null-terminated byte string)
- // ::= Tc <call-offset> <call-offset> <base encoding>
- // # base is the nominal target function of thunk
- // # first call-offset is 'this' adjustment
- // # second call-offset is result adjustment
- // ::= T <call-offset> <base encoding>
- // # base is the nominal target function of thunk
- // extension ::= TC <first type> <number> _ <second type> # construction vtable for second-in-first
-
- bool
- ParseSpecialNameT()
- {
- switch (*m_read_ptr++)
- {
- case 'V':
- WRITE("vtable for ");
- return ParseType();
- case 'T':
- WRITE("VTT for ");
- return ParseType();
- case 'I':
- WRITE("typeinfo for ");
- return ParseType();
- case 'S':
- WRITE("typeinfo name for ");
- return ParseType();
- case 'c':
- case 'C':
+ return false;
+ }
+
+ // <special-name> ::= TV <type> # virtual table
+ // ::= TT <type> # VTT structure (construction vtable index)
+ // ::= TI <type> # typeinfo structure
+ // ::= TS <type> # typeinfo name (null-terminated byte
+ // string)
+ // ::= Tc <call-offset> <call-offset> <base encoding>
+ // # base is the nominal target function of thunk
+ // # first call-offset is 'this' adjustment
+ // # second call-offset is result adjustment
+ // ::= T <call-offset> <base encoding>
+ // # base is the nominal target function of thunk
+ // extension ::= TC <first type> <number> _ <second type> # construction
+ // vtable for second-in-first
+
+ bool ParseSpecialNameT() {
+ switch (*m_read_ptr++) {
+ case 'V':
+ WRITE("vtable for ");
+ return ParseType();
+ case 'T':
+ WRITE("VTT for ");
+ return ParseType();
+ case 'I':
+ WRITE("typeinfo for ");
+ return ParseType();
+ case 'S':
+ WRITE("typeinfo name for ");
+ return ParseType();
+ case 'c':
+ case 'C':
#ifdef DEBUG_FAILURES
- printf("*** Unsupported thunk or construction vtable name: %.3s\n", m_read_ptr - 1);
+ printf("*** Unsupported thunk or construction vtable name: %.3s\n",
+ m_read_ptr - 1);
#endif
- return false;
- default:
- if (*--m_read_ptr == 'v')
- {
- WRITE("virtual thunk to ");
- }
- else
- {
- WRITE("non-virtual thunk to ");
- }
- if (!ParseCallOffset())
- return false;
- return ParseEncoding();
- }
+ return false;
+ default:
+ if (*--m_read_ptr == 'v') {
+ WRITE("virtual thunk to ");
+ } else {
+ WRITE("non-virtual thunk to ");
+ }
+ if (!ParseCallOffset())
+ return false;
+ return ParseEncoding();
}
+ }
- // <special-name> ::= GV <object name> # Guard variable for one-time initialization
- // # No <type>
- // extension ::= GR <object name> # reference temporary for object
+ // <special-name> ::= GV <object name> # Guard variable for one-time
+ // initialization
+ // # No <type>
+ // extension ::= GR <object name> # reference temporary for object
- bool
- ParseSpecialNameG()
- {
- switch (*m_read_ptr++)
- {
- case 'V':
- WRITE("guard variable for ");
- if (!ParseName(true))
- return false;
- break;
- case 'R':
- WRITE("reference temporary for ");
- if (!ParseName(true))
- return false;
- break;
- default:
+ bool ParseSpecialNameG() {
+ switch (*m_read_ptr++) {
+ case 'V':
+ WRITE("guard variable for ");
+ if (!ParseName(true))
+ return false;
+ break;
+ case 'R':
+ WRITE("reference temporary for ");
+ if (!ParseName(true))
+ return false;
+ break;
+ default:
#ifdef DEBUG_FAILURES
- printf("*** Unknown G encoding\n");
+ printf("*** Unknown G encoding\n");
#endif
- return false;
- }
- return true;
+ return false;
}
+ return true;
+ }
- // <bare-function-type> ::= <signature type>+ # types are possible return type, then parameter types
-
- bool
- ParseFunctionArgs(NameState & name_state, int return_insert_cookie)
- {
- char next = *m_read_ptr;
- if (next == 'E' || next == '\0' || next == '.')
- return true;
-
- // Clang has a bad habit of making unique manglings by just sticking numbers on the end of a symbol,
- // which is ambiguous with malformed source name manglings
- const char *before_clang_uniquing_test = m_read_ptr;
- if (TryParseNumber())
- {
- if (*m_read_ptr == '\0')
- return true;
- m_read_ptr = before_clang_uniquing_test;
- }
+ // <bare-function-type> ::= <signature type>+ # types are possible
+ // return type, then parameter types
- if (name_state.is_last_generic && !name_state.has_no_return_type)
- {
- int return_type_start_cookie = GetStartCookie();
- if (!ParseType())
- return false;
- Write(' ');
- ReorderRange(EndRange(return_type_start_cookie),
- return_insert_cookie);
- }
-
- Write('(');
- bool first_param = true;
- while (true)
- {
- switch (*m_read_ptr)
- {
- case '\0':
- case 'E':
- case '.':
- break;
- case 'v':
- ++m_read_ptr;
- continue;
- case '_':
- // Not a formal part of the mangling specification, but clang emits suffixes starting with _block_invoke
- if (strncmp(m_read_ptr, "_block_invoke", 13) == 0)
- {
- m_read_ptr += strlen(m_read_ptr);
- break;
- }
- LLVM_FALLTHROUGH;
- default:
- if (first_param)
- first_param = false;
- else WriteCommaSpace();
+ bool ParseFunctionArgs(NameState &name_state, int return_insert_cookie) {
+ char next = *m_read_ptr;
+ if (next == 'E' || next == '\0' || next == '.')
+ return true;
- if (!ParseType())
- return false;
- continue;
- }
- break;
- }
- Write(')');
+ // Clang has a bad habit of making unique manglings by just sticking numbers
+ // on the end of a symbol,
+ // which is ambiguous with malformed source name manglings
+ const char *before_clang_uniquing_test = m_read_ptr;
+ if (TryParseNumber()) {
+ if (*m_read_ptr == '\0')
return true;
+ m_read_ptr = before_clang_uniquing_test;
}
- // <encoding> ::= <function name> <bare-function-type>
- // ::= <data name>
- // ::= <special-name>
-
- bool
- ParseEncoding()
- {
- switch (*m_read_ptr)
- {
- case 'T':
- ++m_read_ptr;
- if (!ParseSpecialNameT())
- return false;
- break;
- case 'G':
- ++m_read_ptr;
- if (!ParseSpecialNameG())
- return false;
- break;
- default:
- if (!ParseName(true))
- return false;
- break;
+ if (name_state.is_last_generic && !name_state.has_no_return_type) {
+ int return_type_start_cookie = GetStartCookie();
+ if (!ParseType())
+ return false;
+ Write(' ');
+ ReorderRange(EndRange(return_type_start_cookie), return_insert_cookie);
+ }
+
+ Write('(');
+ bool first_param = true;
+ while (true) {
+ switch (*m_read_ptr) {
+ case '\0':
+ case 'E':
+ case '.':
+ break;
+ case 'v':
+ ++m_read_ptr;
+ continue;
+ case '_':
+ // Not a formal part of the mangling specification, but clang emits
+ // suffixes starting with _block_invoke
+ if (strncmp(m_read_ptr, "_block_invoke", 13) == 0) {
+ m_read_ptr += strlen(m_read_ptr);
+ break;
}
- return true;
+ LLVM_FALLTHROUGH;
+ default:
+ if (first_param)
+ first_param = false;
+ else
+ WriteCommaSpace();
+
+ if (!ParseType())
+ return false;
+ continue;
+ }
+ break;
+ }
+ Write(')');
+ return true;
+ }
+
+ // <encoding> ::= <function name> <bare-function-type>
+ // ::= <data name>
+ // ::= <special-name>
+
+ bool ParseEncoding() {
+ switch (*m_read_ptr) {
+ case 'T':
+ ++m_read_ptr;
+ if (!ParseSpecialNameT())
+ return false;
+ break;
+ case 'G':
+ ++m_read_ptr;
+ if (!ParseSpecialNameG())
+ return false;
+ break;
+ default:
+ if (!ParseName(true))
+ return false;
+ break;
}
+ return true;
+ }
- bool
- ParseMangling(const char *mangled_name, long mangled_name_length = 0)
- {
- if (!mangled_name_length)
- mangled_name_length = strlen(mangled_name);
- m_read_end = mangled_name + mangled_name_length;
- m_read_ptr = mangled_name;
- m_write_ptr = m_buffer;
- m_next_substitute_index = 0;
- m_next_template_arg_index = m_rewrite_ranges_size - 1;
-
- if (*m_read_ptr++ != '_' || *m_read_ptr++ != 'Z')
- {
+ bool ParseMangling(const char *mangled_name, long mangled_name_length = 0) {
+ if (!mangled_name_length)
+ mangled_name_length = strlen(mangled_name);
+ m_read_end = mangled_name + mangled_name_length;
+ m_read_ptr = mangled_name;
+ m_write_ptr = m_buffer;
+ m_next_substitute_index = 0;
+ m_next_template_arg_index = m_rewrite_ranges_size - 1;
+
+ if (*m_read_ptr++ != '_' || *m_read_ptr++ != 'Z') {
#ifdef DEBUG_FAILURES
- printf("*** Missing _Z prefix\n");
+ printf("*** Missing _Z prefix\n");
#endif
- return false;
- }
- if (!ParseEncoding())
- return false;
- switch (*m_read_ptr)
- {
- case '.':
- Write(' ');
- Write('(');
- Write(m_read_ptr, m_read_end - m_read_ptr);
- Write(')');
- LLVM_FALLTHROUGH;
- case '\0':
- return true;
- default:
+ return false;
+ }
+ if (!ParseEncoding())
+ return false;
+ switch (*m_read_ptr) {
+ case '.':
+ Write(' ');
+ Write('(');
+ Write(m_read_ptr, m_read_end - m_read_ptr);
+ Write(')');
+ LLVM_FALLTHROUGH;
+ case '\0':
+ return true;
+ default:
#ifdef DEBUG_FAILURES
- printf("*** Unparsed mangled content\n");
+ printf("*** Unparsed mangled content\n");
#endif
- return false;
- }
+ return false;
}
+ }
private:
-
- // External scratch storage used during demanglings
-
- char *m_buffer;
- const char *m_buffer_end;
- BufferRange *m_rewrite_ranges;
- int m_rewrite_ranges_size;
- bool m_owns_buffer;
- bool m_owns_m_rewrite_ranges;
-
- // Internal state used during demangling
-
- const char *m_read_ptr;
- const char *m_read_end;
- char *m_write_ptr;
- int m_next_template_arg_index;
- int m_next_substitute_index;
+ // External scratch storage used during demanglings
+
+ char *m_buffer;
+ const char *m_buffer_end;
+ BufferRange *m_rewrite_ranges;
+ int m_rewrite_ranges_size;
+ bool m_owns_buffer;
+ bool m_owns_m_rewrite_ranges;
+
+ // Internal state used during demangling
+
+ const char *m_read_ptr;
+ const char *m_read_end;
+ char *m_write_ptr;
+ int m_next_template_arg_index;
+ int m_next_substitute_index;
+ std::function<void(const char *s)> m_builtins_hook;
};
} // Anonymous namespace
// Public entry points referenced from Mangled.cpp
-namespace lldb_private
-{
- char *
- FastDemangle(const char *mangled_name)
- {
- char buffer[16384];
- SymbolDemangler demangler(buffer, sizeof (buffer));
- return demangler.GetDemangledCopy(mangled_name);
- }
-
- char *
- FastDemangle(const char *mangled_name, long mangled_name_length)
- {
- char buffer[16384];
- SymbolDemangler demangler(buffer, sizeof (buffer));
- return demangler.GetDemangledCopy(mangled_name, mangled_name_length);
- }
+namespace lldb_private {
+char *FastDemangle(const char *mangled_name) {
+ char buffer[16384];
+ SymbolDemangler demangler(buffer, sizeof(buffer));
+ return demangler.GetDemangledCopy(mangled_name);
+}
+
+char *FastDemangle(const char *mangled_name, size_t mangled_name_length,
+ std::function<void(const char *s)> builtins_hook) {
+ char buffer[16384];
+ SymbolDemangler demangler(buffer, sizeof(buffer), builtins_hook);
+ return demangler.GetDemangledCopy(mangled_name, mangled_name_length);
+}
} // lldb_private namespace
diff --git a/source/Core/FileLineResolver.cpp b/source/Core/FileLineResolver.cpp
index e8ef87f009d9..db56cae9e9bc 100644
--- a/source/Core/FileLineResolver.cpp
+++ b/source/Core/FileLineResolver.cpp
@@ -21,96 +21,66 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// FileLineResolver:
//----------------------------------------------------------------------
-FileLineResolver::FileLineResolver
-(
- const FileSpec &file_spec,
- uint32_t line_no,
- bool check_inlines
-) :
- Searcher (),
- m_file_spec (file_spec),
- m_line_number (line_no),
- m_inlines (check_inlines)
-{
-}
+FileLineResolver::FileLineResolver(const FileSpec &file_spec, uint32_t line_no,
+ bool check_inlines)
+ : Searcher(), m_file_spec(file_spec), m_line_number(line_no),
+ m_inlines(check_inlines) {}
-FileLineResolver::~FileLineResolver ()
-{
-}
+FileLineResolver::~FileLineResolver() {}
Searcher::CallbackReturn
-FileLineResolver::SearchCallback
-(
- SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing
-)
-{
- CompileUnit *cu = context.comp_unit;
+FileLineResolver::SearchCallback(SearchFilter &filter, SymbolContext &context,
+ Address *addr, bool containing) {
+ CompileUnit *cu = context.comp_unit;
- if (m_inlines || m_file_spec.Compare(*cu, m_file_spec, (bool)m_file_spec.GetDirectory()))
- {
- uint32_t start_file_idx = 0;
- uint32_t file_idx = cu->GetSupportFiles().FindFileIndex(start_file_idx, m_file_spec, false);
- if (file_idx != UINT32_MAX)
- {
- LineTable *line_table = cu->GetLineTable();
- if (line_table)
- {
- if (m_line_number == 0)
- {
- // Match all lines in a file...
- const bool append = true;
- while (file_idx != UINT32_MAX)
- {
- line_table->FineLineEntriesForFileIndex (file_idx, append, m_sc_list);
- // Get the next file index in case we have multiple file
- // entries for the same file
- file_idx = cu->GetSupportFiles().FindFileIndex(file_idx + 1, m_file_spec, false);
- }
- }
- else
- {
- // Match a specific line in a file...
- }
- }
+ if (m_inlines ||
+ m_file_spec.Compare(*cu, m_file_spec, (bool)m_file_spec.GetDirectory())) {
+ uint32_t start_file_idx = 0;
+ uint32_t file_idx =
+ cu->GetSupportFiles().FindFileIndex(start_file_idx, m_file_spec, false);
+ if (file_idx != UINT32_MAX) {
+ LineTable *line_table = cu->GetLineTable();
+ if (line_table) {
+ if (m_line_number == 0) {
+ // Match all lines in a file...
+ const bool append = true;
+ while (file_idx != UINT32_MAX) {
+ line_table->FineLineEntriesForFileIndex(file_idx, append,
+ m_sc_list);
+ // Get the next file index in case we have multiple file
+ // entries for the same file
+ file_idx = cu->GetSupportFiles().FindFileIndex(file_idx + 1,
+ m_file_spec, false);
+ }
+ } else {
+ // Match a specific line in a file...
}
+ }
}
- return Searcher::eCallbackReturnContinue;
+ }
+ return Searcher::eCallbackReturnContinue;
}
-Searcher::Depth
-FileLineResolver::GetDepth()
-{
- return Searcher::eDepthCompUnit;
+Searcher::Depth FileLineResolver::GetDepth() {
+ return Searcher::eDepthCompUnit;
}
-void
-FileLineResolver::GetDescription (Stream *s)
-{
- s->Printf ("File and line resolver for file: \"%s\" line: %u",
- m_file_spec.GetPath().c_str(),
- m_line_number);
+void FileLineResolver::GetDescription(Stream *s) {
+ s->Printf("File and line resolver for file: \"%s\" line: %u",
+ m_file_spec.GetPath().c_str(), m_line_number);
}
-void
-FileLineResolver::Clear()
-{
- m_file_spec.Clear();
- m_line_number = UINT32_MAX;
- m_sc_list.Clear();
- m_inlines = true;
+void FileLineResolver::Clear() {
+ m_file_spec.Clear();
+ m_line_number = UINT32_MAX;
+ m_sc_list.Clear();
+ m_inlines = true;
}
-void
-FileLineResolver::Reset (const FileSpec &file_spec,
- uint32_t line,
- bool check_inlines)
-{
- m_file_spec = file_spec;
- m_line_number = line;
- m_sc_list.Clear();
- m_inlines = check_inlines;
+void FileLineResolver::Reset(const FileSpec &file_spec, uint32_t line,
+ bool check_inlines) {
+ m_file_spec = file_spec;
+ m_line_number = line;
+ m_sc_list.Clear();
+ m_inlines = check_inlines;
}
-
diff --git a/source/Core/FileSpecList.cpp b/source/Core/FileSpecList.cpp
index cef1bfba41b0..d4ce4b787aad 100644
--- a/source/Core/FileSpecList.cpp
+++ b/source/Core/FileSpecList.cpp
@@ -20,33 +20,26 @@
using namespace lldb_private;
using namespace std;
-FileSpecList::FileSpecList() :
- m_files()
-{
-}
+FileSpecList::FileSpecList() : m_files() {}
-FileSpecList::FileSpecList(const FileSpecList& rhs) = default;
+FileSpecList::FileSpecList(const FileSpecList &rhs) = default;
FileSpecList::~FileSpecList() = default;
//------------------------------------------------------------------
// Assignment operator
//------------------------------------------------------------------
-const FileSpecList&
-FileSpecList::operator= (const FileSpecList& rhs)
-{
- if (this != &rhs)
- m_files = rhs.m_files;
- return *this;
+const FileSpecList &FileSpecList::operator=(const FileSpecList &rhs) {
+ if (this != &rhs)
+ m_files = rhs.m_files;
+ return *this;
}
//------------------------------------------------------------------
// Append the "file_spec" to the end of the file spec list.
//------------------------------------------------------------------
-void
-FileSpecList::Append(const FileSpec &file_spec)
-{
- m_files.push_back(file_spec);
+void FileSpecList::Append(const FileSpec &file_spec) {
+ m_files.push_back(file_spec);
}
//------------------------------------------------------------------
@@ -56,40 +49,30 @@ FileSpecList::Append(const FileSpec &file_spec)
// Returns true if "file_spec" was added, false if this list already
// contained a copy of "file_spec".
//------------------------------------------------------------------
-bool
-FileSpecList::AppendIfUnique(const FileSpec &file_spec)
-{
- collection::iterator pos, end = m_files.end();
- if (find(m_files.begin(), end, file_spec) == end)
- {
- m_files.push_back(file_spec);
- return true;
- }
- return false;
+bool FileSpecList::AppendIfUnique(const FileSpec &file_spec) {
+ collection::iterator pos, end = m_files.end();
+ if (find(m_files.begin(), end, file_spec) == end) {
+ m_files.push_back(file_spec);
+ return true;
+ }
+ return false;
}
//------------------------------------------------------------------
// Clears the file list.
//------------------------------------------------------------------
-void
-FileSpecList::Clear()
-{
- m_files.clear();
-}
+void FileSpecList::Clear() { m_files.clear(); }
//------------------------------------------------------------------
// Dumps the file list to the supplied stream pointer "s".
//------------------------------------------------------------------
-void
-FileSpecList::Dump(Stream *s, const char *separator_cstr) const
-{
- collection::const_iterator pos, end = m_files.end();
- for (pos = m_files.begin(); pos != end; ++pos)
- {
- pos->Dump(s);
- if (separator_cstr && ((pos + 1) != end))
- s->PutCString(separator_cstr);
- }
+void FileSpecList::Dump(Stream *s, const char *separator_cstr) const {
+ collection::const_iterator pos, end = m_files.end();
+ for (pos = m_files.begin(); pos != end; ++pos) {
+ pos->Dump(s);
+ if (separator_cstr && ((pos + 1) != end))
+ s->PutCString(separator_cstr);
+ }
}
//------------------------------------------------------------------
@@ -99,53 +82,45 @@ FileSpecList::Dump(Stream *s, const char *separator_cstr) const
// Returns the valid index of the file that matches "file_spec" if
// it is found, else std::numeric_limits<uint32_t>::max() is returned.
//------------------------------------------------------------------
-size_t
-FileSpecList::FindFileIndex (size_t start_idx, const FileSpec &file_spec, bool full, bool remove_dots) const
-{
- const size_t num_files = m_files.size();
-
- // When looking for files, we will compare only the filename if the
- // FILE_SPEC argument is empty
- bool compare_filename_only = file_spec.GetDirectory().IsEmpty();
-
- for (size_t idx = start_idx; idx < num_files; ++idx)
- {
- if (compare_filename_only)
- {
- if (ConstString::Equals(m_files[idx].GetFilename(), file_spec.GetFilename(),
- file_spec.IsCaseSensitive() || m_files[idx].IsCaseSensitive()))
- return idx;
- }
- else
- {
- if (FileSpec::Equal (m_files[idx], file_spec, full, remove_dots))
- return idx;
- }
+size_t FileSpecList::FindFileIndex(size_t start_idx, const FileSpec &file_spec,
+ bool full, bool remove_dots) const {
+ const size_t num_files = m_files.size();
+
+ // When looking for files, we will compare only the filename if the
+ // FILE_SPEC argument is empty
+ bool compare_filename_only = file_spec.GetDirectory().IsEmpty();
+
+ for (size_t idx = start_idx; idx < num_files; ++idx) {
+ if (compare_filename_only) {
+ if (ConstString::Equals(
+ m_files[idx].GetFilename(), file_spec.GetFilename(),
+ file_spec.IsCaseSensitive() || m_files[idx].IsCaseSensitive()))
+ return idx;
+ } else {
+ if (FileSpec::Equal(m_files[idx], file_spec, full, remove_dots))
+ return idx;
}
+ }
- // We didn't find the file, return an invalid index
- return UINT32_MAX;
+ // We didn't find the file, return an invalid index
+ return UINT32_MAX;
}
//------------------------------------------------------------------
// Returns the FileSpec object at index "idx". If "idx" is out of
// range, then an empty FileSpec object will be returned.
//------------------------------------------------------------------
-const FileSpec &
-FileSpecList::GetFileSpecAtIndex(size_t idx) const
-{
- if (idx < m_files.size())
- return m_files[idx];
- static FileSpec g_empty_file_spec;
- return g_empty_file_spec;
+const FileSpec &FileSpecList::GetFileSpecAtIndex(size_t idx) const {
+ if (idx < m_files.size())
+ return m_files[idx];
+ static FileSpec g_empty_file_spec;
+ return g_empty_file_spec;
}
-const FileSpec *
-FileSpecList::GetFileSpecPointerAtIndex(size_t idx) const
-{
- if (idx < m_files.size())
- return &m_files[idx];
- return nullptr;
+const FileSpec *FileSpecList::GetFileSpecPointerAtIndex(size_t idx) const {
+ if (idx < m_files.size())
+ return &m_files[idx];
+ return nullptr;
}
//------------------------------------------------------------------
@@ -155,32 +130,25 @@ FileSpecList::GetFileSpecPointerAtIndex(size_t idx) const
// doesn't not include the string values for the directories any
// filenames as those are in shared string pools.
//------------------------------------------------------------------
-size_t
-FileSpecList::MemorySize () const
-{
- size_t mem_size = sizeof(FileSpecList);
- collection::const_iterator pos, end = m_files.end();
- for (pos = m_files.begin(); pos != end; ++pos)
- {
- mem_size += pos->MemorySize();
- }
+size_t FileSpecList::MemorySize() const {
+ size_t mem_size = sizeof(FileSpecList);
+ collection::const_iterator pos, end = m_files.end();
+ for (pos = m_files.begin(); pos != end; ++pos) {
+ mem_size += pos->MemorySize();
+ }
- return mem_size;
+ return mem_size;
}
//------------------------------------------------------------------
// Return the number of files in the file spec list.
//------------------------------------------------------------------
-size_t
-FileSpecList::GetSize() const
-{
- return m_files.size();
-}
+size_t FileSpecList::GetSize() const { return m_files.size(); }
-size_t
-FileSpecList::GetFilesMatchingPartialPath (const char *path, bool dir_okay, FileSpecList &matches)
-{
-#if 0 // FIXME: Just sketching...
+size_t FileSpecList::GetFilesMatchingPartialPath(const char *path,
+ bool dir_okay,
+ FileSpecList &matches) {
+#if 0 // FIXME: Just sketching...
matches.Clear();
FileSpec path_spec = FileSpec (path);
if (path_spec.Exists ())
@@ -220,5 +188,5 @@ FileSpecList::GetFilesMatchingPartialPath (const char *path, bool dir_okay, File
}
}
#endif
- return 0;
+ return 0;
}
diff --git a/source/Core/FormatEntity.cpp b/source/Core/FormatEntity.cpp
index e2097cc72b85..08166d208aee 100644
--- a/source/Core/FormatEntity.cpp
+++ b/source/Core/FormatEntity.cpp
@@ -49,251 +49,245 @@
using namespace lldb;
using namespace lldb_private;
-enum FileKind
-{
- FileError = 0,
- Basename,
- Dirname,
- Fullpath
+enum FileKind { FileError = 0, Basename, Dirname, Fullpath };
+
+#define ENTRY(n, t, f) \
+ { \
+ n, nullptr, FormatEntity::Entry::Type::t, \
+ FormatEntity::Entry::FormatType::f, 0, 0, nullptr, false \
+ }
+#define ENTRY_VALUE(n, t, f, v) \
+ { \
+ n, nullptr, FormatEntity::Entry::Type::t, \
+ FormatEntity::Entry::FormatType::f, v, 0, nullptr, false \
+ }
+#define ENTRY_CHILDREN(n, t, f, c) \
+ { \
+ n, nullptr, FormatEntity::Entry::Type::t, \
+ FormatEntity::Entry::FormatType::f, 0, llvm::array_lengthof(c), c, \
+ false \
+ }
+#define ENTRY_CHILDREN_KEEP_SEP(n, t, f, c) \
+ { \
+ n, nullptr, FormatEntity::Entry::Type::t, \
+ FormatEntity::Entry::FormatType::f, 0, llvm::array_lengthof(c), c, \
+ true \
+ }
+#define ENTRY_STRING(n, s) \
+ { \
+ n, s, FormatEntity::Entry::Type::InsertString, \
+ FormatEntity::Entry::FormatType::None, 0, 0, nullptr, false \
+ }
+static FormatEntity::Entry::Definition g_string_entry[] = {
+ ENTRY("*", ParentString, None)};
+
+static FormatEntity::Entry::Definition g_addr_entries[] = {
+ ENTRY("load", AddressLoad, UInt64), ENTRY("file", AddressFile, UInt64),
+ ENTRY("load", AddressLoadOrFile, UInt64),
};
-#define ENTRY(n,t,f) { n, nullptr, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0, 0, nullptr, false}
-#define ENTRY_VALUE(n,t,f,v) { n, nullptr, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, v, 0, nullptr, false}
-#define ENTRY_CHILDREN(n,t,f,c) { n, nullptr, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0, llvm::array_lengthof(c), c, false}
-#define ENTRY_CHILDREN_KEEP_SEP(n,t,f,c) { n, nullptr, FormatEntity::Entry::Type::t, FormatEntity::Entry::FormatType::f, 0, llvm::array_lengthof(c), c, true}
-#define ENTRY_STRING(n,s) { n, s, FormatEntity::Entry::Type::InsertString, FormatEntity::Entry::FormatType::None, 0, 0, nullptr, false}
-static FormatEntity::Entry::Definition g_string_entry[] =
-{
- ENTRY("*", ParentString, None)
-};
-
-static FormatEntity::Entry::Definition g_addr_entries[] =
-{
- ENTRY ("load", AddressLoad , UInt64),
- ENTRY ("file", AddressFile , UInt64),
- ENTRY ("load", AddressLoadOrFile, UInt64),
-};
-
-static FormatEntity::Entry::Definition g_file_child_entries[] =
-{
+static FormatEntity::Entry::Definition g_file_child_entries[] = {
ENTRY_VALUE("basename", ParentNumber, CString, FileKind::Basename),
ENTRY_VALUE("dirname", ParentNumber, CString, FileKind::Dirname),
- ENTRY_VALUE("fullpath", ParentNumber, CString, FileKind::Fullpath)
-};
-
-static FormatEntity::Entry::Definition g_frame_child_entries[] =
-{
- ENTRY ("index", FrameIndex , UInt32),
- ENTRY ("pc" , FrameRegisterPC , UInt64),
- ENTRY ("fp" , FrameRegisterFP , UInt64),
- ENTRY ("sp" , FrameRegisterSP , UInt64),
- ENTRY ("flags", FrameRegisterFlags, UInt64),
- ENTRY_CHILDREN ("reg", FrameRegisterByName, UInt64, g_string_entry),
+ ENTRY_VALUE("fullpath", ParentNumber, CString, FileKind::Fullpath)};
+
+static FormatEntity::Entry::Definition g_frame_child_entries[] = {
+ ENTRY("index", FrameIndex, UInt32),
+ ENTRY("pc", FrameRegisterPC, UInt64),
+ ENTRY("fp", FrameRegisterFP, UInt64),
+ ENTRY("sp", FrameRegisterSP, UInt64),
+ ENTRY("flags", FrameRegisterFlags, UInt64),
+ ENTRY("no-debug", FrameNoDebug, None),
+ ENTRY_CHILDREN("reg", FrameRegisterByName, UInt64, g_string_entry),
};
-static FormatEntity::Entry::Definition g_function_child_entries[] =
-{
- ENTRY ("id" , FunctionID , UInt64),
- ENTRY ("name" , FunctionName , CString),
- ENTRY ("name-without-args" , FunctionNameNoArgs , CString),
- ENTRY ("name-with-args" , FunctionNameWithArgs , CString),
- ENTRY ("addr-offset" , FunctionAddrOffset , UInt64),
- ENTRY ("concrete-only-addr-offset-no-padding", FunctionAddrOffsetConcrete, UInt64),
- ENTRY ("line-offset" , FunctionLineOffset , UInt64),
- ENTRY ("pc-offset" , FunctionPCOffset , UInt64),
- ENTRY ("initial-function" , FunctionInitial , None),
- ENTRY ("changed" , FunctionChanged , None),
- ENTRY ("is-optimized" , FunctionIsOptimized , None)
+static FormatEntity::Entry::Definition g_function_child_entries[] = {
+ ENTRY("id", FunctionID, UInt64), ENTRY("name", FunctionName, CString),
+ ENTRY("name-without-args", FunctionNameNoArgs, CString),
+ ENTRY("name-with-args", FunctionNameWithArgs, CString),
+ ENTRY("addr-offset", FunctionAddrOffset, UInt64),
+ ENTRY("concrete-only-addr-offset-no-padding", FunctionAddrOffsetConcrete,
+ UInt64),
+ ENTRY("line-offset", FunctionLineOffset, UInt64),
+ ENTRY("pc-offset", FunctionPCOffset, UInt64),
+ ENTRY("initial-function", FunctionInitial, None),
+ ENTRY("changed", FunctionChanged, None),
+ ENTRY("is-optimized", FunctionIsOptimized, None)};
+
+static FormatEntity::Entry::Definition g_line_child_entries[] = {
+ ENTRY_CHILDREN("file", LineEntryFile, None, g_file_child_entries),
+ ENTRY("number", LineEntryLineNumber, UInt32),
+ ENTRY("start-addr", LineEntryStartAddress, UInt64),
+ ENTRY("end-addr", LineEntryEndAddress, UInt64),
};
-static FormatEntity::Entry::Definition g_line_child_entries[] =
-{
- ENTRY_CHILDREN("file", LineEntryFile , None , g_file_child_entries),
- ENTRY("number" , LineEntryLineNumber , UInt32),
- ENTRY("start-addr" , LineEntryStartAddress, UInt64),
- ENTRY("end-addr" , LineEntryEndAddress , UInt64),
-};
-
-static FormatEntity::Entry::Definition g_module_child_entries[] =
-{
+static FormatEntity::Entry::Definition g_module_child_entries[] = {
ENTRY_CHILDREN("file", ModuleFile, None, g_file_child_entries),
};
-static FormatEntity::Entry::Definition g_process_child_entries[] =
-{
- ENTRY ( "id" , ProcessID , UInt64 ),
- ENTRY_VALUE ( "name" , ProcessFile , CString , FileKind::Basename),
- ENTRY_CHILDREN ( "file" , ProcessFile , None , g_file_child_entries),
+static FormatEntity::Entry::Definition g_process_child_entries[] = {
+ ENTRY("id", ProcessID, UInt64),
+ ENTRY_VALUE("name", ProcessFile, CString, FileKind::Basename),
+ ENTRY_CHILDREN("file", ProcessFile, None, g_file_child_entries),
};
-static FormatEntity::Entry::Definition g_svar_child_entries[] =
-{
- ENTRY ( "*" , ParentString , None)
+static FormatEntity::Entry::Definition g_svar_child_entries[] = {
+ ENTRY("*", ParentString, None)};
+
+static FormatEntity::Entry::Definition g_var_child_entries[] = {
+ ENTRY("*", ParentString, None)};
+
+static FormatEntity::Entry::Definition g_thread_child_entries[] = {
+ ENTRY("id", ThreadID, UInt64),
+ ENTRY("protocol_id", ThreadProtocolID, UInt64),
+ ENTRY("index", ThreadIndexID, UInt32),
+ ENTRY_CHILDREN("info", ThreadInfo, None, g_string_entry),
+ ENTRY("queue", ThreadQueue, CString),
+ ENTRY("name", ThreadName, CString),
+ ENTRY("stop-reason", ThreadStopReason, CString),
+ ENTRY("return-value", ThreadReturnValue, CString),
+ ENTRY("completed-expression", ThreadCompletedExpression, CString),
};
-static FormatEntity::Entry::Definition g_var_child_entries[] =
-{
- ENTRY ( "*" , ParentString , None)
-};
-
-static FormatEntity::Entry::Definition g_thread_child_entries[] =
-{
- ENTRY ( "id" , ThreadID , UInt64 ),
- ENTRY ( "protocol_id" , ThreadProtocolID , UInt64 ),
- ENTRY ( "index" , ThreadIndexID , UInt32 ),
- ENTRY_CHILDREN ( "info" , ThreadInfo , None , g_string_entry),
- ENTRY ( "queue" , ThreadQueue , CString ),
- ENTRY ( "name" , ThreadName , CString ),
- ENTRY ( "stop-reason" , ThreadStopReason , CString ),
- ENTRY ( "return-value" , ThreadReturnValue , CString ),
- ENTRY ( "completed-expression", ThreadCompletedExpression , CString ),
-};
-
-static FormatEntity::Entry::Definition g_target_child_entries[] =
-{
- ENTRY ( "arch" , TargetArch , CString ),
+static FormatEntity::Entry::Definition g_target_child_entries[] = {
+ ENTRY("arch", TargetArch, CString),
};
#define _TO_STR2(_val) #_val
#define _TO_STR(_val) _TO_STR2(_val)
-static FormatEntity::Entry::Definition g_ansi_fg_entries[] =
-{
- ENTRY_STRING ("black" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END),
- ENTRY_STRING ("red" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END),
- ENTRY_STRING ("green" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END),
- ENTRY_STRING ("yellow" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END),
- ENTRY_STRING ("blue" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END),
- ENTRY_STRING ("purple" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END),
- ENTRY_STRING ("cyan" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END),
- ENTRY_STRING ("white" , ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END),
+static FormatEntity::Entry::Definition g_ansi_fg_entries[] = {
+ ENTRY_STRING("black",
+ ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLACK) ANSI_ESC_END),
+ ENTRY_STRING("red", ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_RED) ANSI_ESC_END),
+ ENTRY_STRING("green",
+ ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_GREEN) ANSI_ESC_END),
+ ENTRY_STRING("yellow",
+ ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_YELLOW) ANSI_ESC_END),
+ ENTRY_STRING("blue",
+ ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_BLUE) ANSI_ESC_END),
+ ENTRY_STRING("purple",
+ ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_PURPLE) ANSI_ESC_END),
+ ENTRY_STRING("cyan",
+ ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_CYAN) ANSI_ESC_END),
+ ENTRY_STRING("white",
+ ANSI_ESC_START _TO_STR(ANSI_FG_COLOR_WHITE) ANSI_ESC_END),
};
-static FormatEntity::Entry::Definition g_ansi_bg_entries[] =
-{
- ENTRY_STRING ("black" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END),
- ENTRY_STRING ("red" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END),
- ENTRY_STRING ("green" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END),
- ENTRY_STRING ("yellow" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END),
- ENTRY_STRING ("blue" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END),
- ENTRY_STRING ("purple" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END),
- ENTRY_STRING ("cyan" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END),
- ENTRY_STRING ("white" , ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END),
+static FormatEntity::Entry::Definition g_ansi_bg_entries[] = {
+ ENTRY_STRING("black",
+ ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLACK) ANSI_ESC_END),
+ ENTRY_STRING("red", ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_RED) ANSI_ESC_END),
+ ENTRY_STRING("green",
+ ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_GREEN) ANSI_ESC_END),
+ ENTRY_STRING("yellow",
+ ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_YELLOW) ANSI_ESC_END),
+ ENTRY_STRING("blue",
+ ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_BLUE) ANSI_ESC_END),
+ ENTRY_STRING("purple",
+ ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_PURPLE) ANSI_ESC_END),
+ ENTRY_STRING("cyan",
+ ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_CYAN) ANSI_ESC_END),
+ ENTRY_STRING("white",
+ ANSI_ESC_START _TO_STR(ANSI_BG_COLOR_WHITE) ANSI_ESC_END),
};
-static FormatEntity::Entry::Definition g_ansi_entries[] =
-{
- ENTRY_CHILDREN ( "fg" , Invalid , None , g_ansi_fg_entries),
- ENTRY_CHILDREN ( "bg" , Invalid , None , g_ansi_bg_entries),
- ENTRY_STRING ( "normal" , ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END),
- ENTRY_STRING ( "bold" , ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END),
- ENTRY_STRING ( "faint" , ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END),
- ENTRY_STRING ( "italic" , ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END),
- ENTRY_STRING ( "underline" , ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END),
- ENTRY_STRING ( "slow-blink" , ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END),
- ENTRY_STRING ( "fast-blink" , ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END),
- ENTRY_STRING ( "negative" , ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END),
- ENTRY_STRING ( "conceal" , ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END),
- ENTRY_STRING ( "crossed-out" , ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END),
+static FormatEntity::Entry::Definition g_ansi_entries[] = {
+ ENTRY_CHILDREN("fg", Invalid, None, g_ansi_fg_entries),
+ ENTRY_CHILDREN("bg", Invalid, None, g_ansi_bg_entries),
+ ENTRY_STRING("normal",
+ ANSI_ESC_START _TO_STR(ANSI_CTRL_NORMAL) ANSI_ESC_END),
+ ENTRY_STRING("bold", ANSI_ESC_START _TO_STR(ANSI_CTRL_BOLD) ANSI_ESC_END),
+ ENTRY_STRING("faint", ANSI_ESC_START _TO_STR(ANSI_CTRL_FAINT) ANSI_ESC_END),
+ ENTRY_STRING("italic",
+ ANSI_ESC_START _TO_STR(ANSI_CTRL_ITALIC) ANSI_ESC_END),
+ ENTRY_STRING("underline",
+ ANSI_ESC_START _TO_STR(ANSI_CTRL_UNDERLINE) ANSI_ESC_END),
+ ENTRY_STRING("slow-blink",
+ ANSI_ESC_START _TO_STR(ANSI_CTRL_SLOW_BLINK) ANSI_ESC_END),
+ ENTRY_STRING("fast-blink",
+ ANSI_ESC_START _TO_STR(ANSI_CTRL_FAST_BLINK) ANSI_ESC_END),
+ ENTRY_STRING("negative",
+ ANSI_ESC_START _TO_STR(ANSI_CTRL_IMAGE_NEGATIVE) ANSI_ESC_END),
+ ENTRY_STRING("conceal",
+ ANSI_ESC_START _TO_STR(ANSI_CTRL_CONCEAL) ANSI_ESC_END),
+ ENTRY_STRING("crossed-out",
+ ANSI_ESC_START _TO_STR(ANSI_CTRL_CROSSED_OUT) ANSI_ESC_END),
};
-static FormatEntity::Entry::Definition g_script_child_entries[] =
-{
- ENTRY ( "frame" , ScriptFrame , None),
- ENTRY ( "process" , ScriptProcess , None),
- ENTRY ( "target" , ScriptTarget , None),
- ENTRY ( "thread" , ScriptThread , None),
- ENTRY ( "var" , ScriptVariable , None),
- ENTRY ( "svar" , ScriptVariableSynthetic , None),
- ENTRY ( "thread" , ScriptThread , None),
+static FormatEntity::Entry::Definition g_script_child_entries[] = {
+ ENTRY("frame", ScriptFrame, None),
+ ENTRY("process", ScriptProcess, None),
+ ENTRY("target", ScriptTarget, None),
+ ENTRY("thread", ScriptThread, None),
+ ENTRY("var", ScriptVariable, None),
+ ENTRY("svar", ScriptVariableSynthetic, None),
+ ENTRY("thread", ScriptThread, None),
};
-static FormatEntity::Entry::Definition g_top_level_entries[] =
-{
- ENTRY_CHILDREN ("addr" , AddressLoadOrFile , UInt64 , g_addr_entries),
- ENTRY ("addr-file-or-load" , AddressLoadOrFile , UInt64 ),
- ENTRY_CHILDREN ("ansi" , Invalid , None , g_ansi_entries),
- ENTRY ("current-pc-arrow" , CurrentPCArrow , CString ),
- ENTRY_CHILDREN ("file" , File , CString , g_file_child_entries),
- ENTRY ("language" , Lang , CString),
- ENTRY_CHILDREN ("frame" , Invalid , None , g_frame_child_entries),
- ENTRY_CHILDREN ("function" , Invalid , None , g_function_child_entries),
- ENTRY_CHILDREN ("line" , Invalid , None , g_line_child_entries),
- ENTRY_CHILDREN ("module" , Invalid , None , g_module_child_entries),
- ENTRY_CHILDREN ("process" , Invalid , None , g_process_child_entries),
- ENTRY_CHILDREN ("script" , Invalid , None , g_script_child_entries),
- ENTRY_CHILDREN_KEEP_SEP ("svar" , VariableSynthetic , None , g_svar_child_entries),
- ENTRY_CHILDREN ("thread" , Invalid , None , g_thread_child_entries),
- ENTRY_CHILDREN ("target" , Invalid , None , g_target_child_entries),
- ENTRY_CHILDREN_KEEP_SEP ("var" , Variable , None , g_var_child_entries),
+static FormatEntity::Entry::Definition g_top_level_entries[] = {
+ ENTRY_CHILDREN("addr", AddressLoadOrFile, UInt64, g_addr_entries),
+ ENTRY("addr-file-or-load", AddressLoadOrFile, UInt64),
+ ENTRY_CHILDREN("ansi", Invalid, None, g_ansi_entries),
+ ENTRY("current-pc-arrow", CurrentPCArrow, CString),
+ ENTRY_CHILDREN("file", File, CString, g_file_child_entries),
+ ENTRY("language", Lang, CString),
+ ENTRY_CHILDREN("frame", Invalid, None, g_frame_child_entries),
+ ENTRY_CHILDREN("function", Invalid, None, g_function_child_entries),
+ ENTRY_CHILDREN("line", Invalid, None, g_line_child_entries),
+ ENTRY_CHILDREN("module", Invalid, None, g_module_child_entries),
+ ENTRY_CHILDREN("process", Invalid, None, g_process_child_entries),
+ ENTRY_CHILDREN("script", Invalid, None, g_script_child_entries),
+ ENTRY_CHILDREN_KEEP_SEP("svar", VariableSynthetic, None,
+ g_svar_child_entries),
+ ENTRY_CHILDREN("thread", Invalid, None, g_thread_child_entries),
+ ENTRY_CHILDREN("target", Invalid, None, g_target_child_entries),
+ ENTRY_CHILDREN_KEEP_SEP("var", Variable, None, g_var_child_entries),
};
-static FormatEntity::Entry::Definition g_root = ENTRY_CHILDREN ("<root>", Root, None, g_top_level_entries);
-
-FormatEntity::Entry::Entry (llvm::StringRef s) :
- string (s.data(), s.size()),
- printf_format (),
- children (),
- definition(nullptr),
- type (Type::String),
- fmt (lldb::eFormatDefault),
- number (0),
- deref (false)
-{
-}
+static FormatEntity::Entry::Definition g_root =
+ ENTRY_CHILDREN("<root>", Root, None, g_top_level_entries);
-FormatEntity::Entry::Entry (char ch) :
- string (1, ch),
- printf_format (),
- children (),
- definition(nullptr),
- type (Type::String),
- fmt (lldb::eFormatDefault),
- number (0),
- deref (false)
-{
-}
+FormatEntity::Entry::Entry(llvm::StringRef s)
+ : string(s.data(), s.size()), printf_format(), children(),
+ definition(nullptr), type(Type::String), fmt(lldb::eFormatDefault),
+ number(0), deref(false) {}
-void
-FormatEntity::Entry::AppendChar (char ch)
-{
- if (children.empty() || children.back().type != Entry::Type::String)
- children.push_back(Entry(ch));
- else
- children.back().string.append(1, ch);
+FormatEntity::Entry::Entry(char ch)
+ : string(1, ch), printf_format(), children(), definition(nullptr),
+ type(Type::String), fmt(lldb::eFormatDefault), number(0), deref(false) {}
+
+void FormatEntity::Entry::AppendChar(char ch) {
+ if (children.empty() || children.back().type != Entry::Type::String)
+ children.push_back(Entry(ch));
+ else
+ children.back().string.append(1, ch);
}
-void
-FormatEntity::Entry::AppendText (const llvm::StringRef &s)
-{
- if (children.empty() || children.back().type != Entry::Type::String)
- children.push_back(Entry(s));
- else
- children.back().string.append(s.data(), s.size());
+void FormatEntity::Entry::AppendText(const llvm::StringRef &s) {
+ if (children.empty() || children.back().type != Entry::Type::String)
+ children.push_back(Entry(s));
+ else
+ children.back().string.append(s.data(), s.size());
}
-void
-FormatEntity::Entry::AppendText (const char *cstr)
-{
- return AppendText (llvm::StringRef(cstr));
+void FormatEntity::Entry::AppendText(const char *cstr) {
+ return AppendText(llvm::StringRef(cstr));
}
-Error
-FormatEntity::Parse (const llvm::StringRef &format_str, Entry &entry)
-{
- entry.Clear();
- entry.type = Entry::Type::Root;
- llvm::StringRef modifiable_format (format_str);
- return ParseInternal (modifiable_format, entry, 0);
+Error FormatEntity::Parse(const llvm::StringRef &format_str, Entry &entry) {
+ entry.Clear();
+ entry.type = Entry::Type::Root;
+ llvm::StringRef modifiable_format(format_str);
+ return ParseInternal(modifiable_format, entry, 0);
}
-#define ENUM_TO_CSTR(eee) case FormatEntity::Entry::Type::eee: return #eee
+#define ENUM_TO_CSTR(eee) \
+ case FormatEntity::Entry::Type::eee: \
+ return #eee
-const char *
-FormatEntity::Entry::TypeToCString (Type t)
-{
- switch (t)
- {
+const char *FormatEntity::Entry::TypeToCString(Type t) {
+ switch (t) {
ENUM_TO_CSTR(Invalid);
ENUM_TO_CSTR(ParentNumber);
ENUM_TO_CSTR(ParentString);
@@ -327,6 +321,7 @@ FormatEntity::Entry::TypeToCString (Type t)
ENUM_TO_CSTR(File);
ENUM_TO_CSTR(Lang);
ENUM_TO_CSTR(FrameIndex);
+ ENUM_TO_CSTR(FrameNoDebug);
ENUM_TO_CSTR(FrameRegisterPC);
ENUM_TO_CSTR(FrameRegisterSP);
ENUM_TO_CSTR(FrameRegisterFP);
@@ -351,2280 +346,2044 @@ FormatEntity::Entry::TypeToCString (Type t)
ENUM_TO_CSTR(LineEntryStartAddress);
ENUM_TO_CSTR(LineEntryEndAddress);
ENUM_TO_CSTR(CurrentPCArrow);
- }
- return "???";
+ }
+ return "???";
}
#undef ENUM_TO_CSTR
-void
-FormatEntity::Entry::Dump (Stream &s, int depth) const
-{
- s.Printf ("%*.*s%-20s: ", depth * 2, depth * 2, "", TypeToCString(type));
- if (fmt != eFormatDefault)
- s.Printf ("lldb-format = %s, ", FormatManager::GetFormatAsCString (fmt));
- if (!string.empty())
- s.Printf ("string = \"%s\"", string.c_str());
- if (!printf_format.empty())
- s.Printf ("printf_format = \"%s\"", printf_format.c_str());
- if (number != 0)
- s.Printf ("number = %" PRIu64 " (0x%" PRIx64 "), ", number, number);
- if (deref)
- s.Printf ("deref = true, ");
- s.EOL();
- for (const auto &child : children)
- {
- child.Dump(s, depth + 1);
- }
+void FormatEntity::Entry::Dump(Stream &s, int depth) const {
+ s.Printf("%*.*s%-20s: ", depth * 2, depth * 2, "", TypeToCString(type));
+ if (fmt != eFormatDefault)
+ s.Printf("lldb-format = %s, ", FormatManager::GetFormatAsCString(fmt));
+ if (!string.empty())
+ s.Printf("string = \"%s\"", string.c_str());
+ if (!printf_format.empty())
+ s.Printf("printf_format = \"%s\"", printf_format.c_str());
+ if (number != 0)
+ s.Printf("number = %" PRIu64 " (0x%" PRIx64 "), ", number, number);
+ if (deref)
+ s.Printf("deref = true, ");
+ s.EOL();
+ for (const auto &child : children) {
+ child.Dump(s, depth + 1);
+ }
}
template <typename T>
-static bool RunScriptFormatKeyword(Stream &s,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- T t,
- const char *script_function_name)
-{
- Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
-
- if (target)
- {
- ScriptInterpreter *script_interpreter = target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
- if (script_interpreter)
- {
- Error error;
- std::string script_output;
-
- if (script_interpreter->RunScriptFormatKeyword(script_function_name, t, script_output, error) && error.Success())
- {
- s.Printf("%s", script_output.c_str());
- return true;
- }
- else
- {
- s.Printf("<error: %s>",error.AsCString());
- }
- }
+static bool RunScriptFormatKeyword(Stream &s, const SymbolContext *sc,
+ const ExecutionContext *exe_ctx, T t,
+ const char *script_function_name) {
+ Target *target = Target::GetTargetFromContexts(exe_ctx, sc);
+
+ if (target) {
+ ScriptInterpreter *script_interpreter =
+ target->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
+ if (script_interpreter) {
+ Error error;
+ std::string script_output;
+
+ if (script_interpreter->RunScriptFormatKeyword(script_function_name, t,
+ script_output, error) &&
+ error.Success()) {
+ s.Printf("%s", script_output.c_str());
+ return true;
+ } else {
+ s.Printf("<error: %s>", error.AsCString());
+ }
}
- return false;
+ }
+ return false;
}
-static bool
-DumpAddress (Stream &s,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const Address &addr,
- bool print_file_addr_or_load_addr)
-{
- Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
- addr_t vaddr = LLDB_INVALID_ADDRESS;
- if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
- vaddr = addr.GetLoadAddress (target);
- if (vaddr == LLDB_INVALID_ADDRESS)
- vaddr = addr.GetFileAddress ();
-
- if (vaddr != LLDB_INVALID_ADDRESS)
- {
- int addr_width = 0;
- if (exe_ctx && target)
- {
- addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
- }
- if (addr_width == 0)
- addr_width = 16;
- if (print_file_addr_or_load_addr)
- {
- ExecutionContextScope *exe_scope = nullptr;
- if (exe_ctx)
- exe_scope = exe_ctx->GetBestExecutionContextScope();
- addr.Dump (&s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress, 0);
- }
- else
- {
- s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
- }
- return true;
+static bool DumpAddress(Stream &s, const SymbolContext *sc,
+ const ExecutionContext *exe_ctx, const Address &addr,
+ bool print_file_addr_or_load_addr) {
+ Target *target = Target::GetTargetFromContexts(exe_ctx, sc);
+ addr_t vaddr = LLDB_INVALID_ADDRESS;
+ if (exe_ctx && !target->GetSectionLoadList().IsEmpty())
+ vaddr = addr.GetLoadAddress(target);
+ if (vaddr == LLDB_INVALID_ADDRESS)
+ vaddr = addr.GetFileAddress();
+
+ if (vaddr != LLDB_INVALID_ADDRESS) {
+ int addr_width = 0;
+ if (exe_ctx && target) {
+ addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
}
- return false;
+ if (addr_width == 0)
+ addr_width = 16;
+ if (print_file_addr_or_load_addr) {
+ ExecutionContextScope *exe_scope = nullptr;
+ if (exe_ctx)
+ exe_scope = exe_ctx->GetBestExecutionContextScope();
+ addr.Dump(&s, exe_scope, Address::DumpStyleLoadAddress,
+ Address::DumpStyleModuleWithFileAddress, 0);
+ } else {
+ s.Printf("0x%*.*" PRIx64, addr_width, addr_width, vaddr);
+ }
+ return true;
+ }
+ return false;
}
-static bool
-DumpAddressOffsetFromFunction (Stream &s,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const Address &format_addr,
- bool concrete_only,
- bool no_padding,
- bool print_zero_offsets)
-{
- if (format_addr.IsValid())
- {
- Address func_addr;
-
- if (sc)
- {
- if (sc->function)
- {
- func_addr = sc->function->GetAddressRange().GetBaseAddress();
- if (sc->block && !concrete_only)
- {
- // Check to make sure we aren't in an inline
- // function. If we are, use the inline block
- // range that contains "format_addr" since
- // blocks can be discontiguous.
- Block *inline_block = sc->block->GetContainingInlinedBlock ();
- AddressRange inline_range;
- if (inline_block && inline_block->GetRangeContainingAddress (format_addr, inline_range))
- func_addr = inline_range.GetBaseAddress();
- }
- }
- else if (sc->symbol && sc->symbol->ValueIsAddress())
- func_addr = sc->symbol->GetAddressRef();
+static bool DumpAddressOffsetFromFunction(Stream &s, const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address &format_addr,
+ bool concrete_only, bool no_padding,
+ bool print_zero_offsets) {
+ if (format_addr.IsValid()) {
+ Address func_addr;
+
+ if (sc) {
+ if (sc->function) {
+ func_addr = sc->function->GetAddressRange().GetBaseAddress();
+ if (sc->block && !concrete_only) {
+ // Check to make sure we aren't in an inline
+ // function. If we are, use the inline block
+ // range that contains "format_addr" since
+ // blocks can be discontiguous.
+ Block *inline_block = sc->block->GetContainingInlinedBlock();
+ AddressRange inline_range;
+ if (inline_block &&
+ inline_block->GetRangeContainingAddress(format_addr,
+ inline_range))
+ func_addr = inline_range.GetBaseAddress();
}
+ } else if (sc->symbol && sc->symbol->ValueIsAddress())
+ func_addr = sc->symbol->GetAddressRef();
+ }
- if (func_addr.IsValid())
- {
- const char *addr_offset_padding = no_padding ? "" : " ";
-
- if (func_addr.GetSection() == format_addr.GetSection())
- {
- addr_t func_file_addr = func_addr.GetFileAddress();
- addr_t addr_file_addr = format_addr.GetFileAddress();
- if (addr_file_addr > func_file_addr
- || (addr_file_addr == func_file_addr && print_zero_offsets))
- {
- s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_file_addr - func_file_addr);
- }
- else if (addr_file_addr < func_file_addr)
- {
- s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_file_addr - addr_file_addr);
- }
- return true;
- }
- else
- {
- Target *target = Target::GetTargetFromContexts (exe_ctx, sc);
- if (target)
- {
- addr_t func_load_addr = func_addr.GetLoadAddress (target);
- addr_t addr_load_addr = format_addr.GetLoadAddress (target);
- if (addr_load_addr > func_load_addr
- || (addr_load_addr == func_load_addr && print_zero_offsets))
- {
- s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding, addr_load_addr - func_load_addr);
- }
- else if (addr_load_addr < func_load_addr)
- {
- s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding, func_load_addr - addr_load_addr);
- }
- return true;
- }
- }
+ if (func_addr.IsValid()) {
+ const char *addr_offset_padding = no_padding ? "" : " ";
+
+ if (func_addr.GetSection() == format_addr.GetSection()) {
+ addr_t func_file_addr = func_addr.GetFileAddress();
+ addr_t addr_file_addr = format_addr.GetFileAddress();
+ if (addr_file_addr > func_file_addr ||
+ (addr_file_addr == func_file_addr && print_zero_offsets)) {
+ s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
+ addr_file_addr - func_file_addr);
+ } else if (addr_file_addr < func_file_addr) {
+ s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
+ func_file_addr - addr_file_addr);
+ }
+ return true;
+ } else {
+ Target *target = Target::GetTargetFromContexts(exe_ctx, sc);
+ if (target) {
+ addr_t func_load_addr = func_addr.GetLoadAddress(target);
+ addr_t addr_load_addr = format_addr.GetLoadAddress(target);
+ if (addr_load_addr > func_load_addr ||
+ (addr_load_addr == func_load_addr && print_zero_offsets)) {
+ s.Printf("%s+%s%" PRIu64, addr_offset_padding, addr_offset_padding,
+ addr_load_addr - func_load_addr);
+ } else if (addr_load_addr < func_load_addr) {
+ s.Printf("%s-%s%" PRIu64, addr_offset_padding, addr_offset_padding,
+ func_load_addr - addr_load_addr);
+ }
+ return true;
}
+ }
}
- return false;
+ }
+ return false;
}
-static bool
-ScanBracketedRange (llvm::StringRef subpath,
- size_t& close_bracket_index,
- const char*& var_name_final_if_array_range,
- int64_t& index_lower,
- int64_t& index_higher)
-{
- 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)
- {
+static bool ScanBracketedRange(llvm::StringRef subpath,
+ size_t &close_bracket_index,
+ const char *&var_name_final_if_array_range,
+ int64_t &index_lower, int64_t &index_higher) {
+ 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) {
+ if (log)
+ log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
+ return false;
+ }
+
+ close_bracket_index = subpath.find(']', open_bracket_index + 1);
+
+ if (close_bracket_index == llvm::StringRef::npos) {
+ if (log)
+ log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
+ return false;
+ } else {
+ var_name_final_if_array_range = subpath.data() + open_bracket_index;
+
+ if (close_bracket_index - open_bracket_index == 1) {
+ if (log)
+ log->Printf(
+ "[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
+ index_lower = 0;
+ } else {
+ const size_t separator_index = subpath.find('-', open_bracket_index + 1);
+
+ if (separator_index == llvm::StringRef::npos) {
+ const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
+ index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
+ index_higher = index_lower;
if (log)
- log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
- return false;
+ log->Printf("[ScanBracketedRange] [%" PRId64
+ "] detected, high index is same",
+ index_lower);
+ } else {
+ const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
+ const char *index_higher_cstr = subpath.data() + separator_index + 1;
+ index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
+ index_higher = ::strtoul(index_higher_cstr, nullptr, 0);
+ if (log)
+ log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected",
+ index_lower, index_higher);
+ }
+ if (index_lower > index_higher && index_higher > 0) {
+ if (log)
+ log->Printf("[ScanBracketedRange] swapping indices");
+ const int64_t temp = index_lower;
+ index_lower = index_higher;
+ index_higher = temp;
+ }
}
+ }
+ return true;
+}
- close_bracket_index = subpath.find(']', open_bracket_index + 1);
+static bool DumpFile(Stream &s, const FileSpec &file, FileKind file_kind) {
+ switch (file_kind) {
+ case FileKind::FileError:
+ break;
- if (close_bracket_index == llvm::StringRef::npos)
- {
- if (log)
- log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
- return false;
+ case FileKind::Basename:
+ if (file.GetFilename()) {
+ s << file.GetFilename();
+ return true;
}
- else
- {
- var_name_final_if_array_range = subpath.data() + open_bracket_index;
+ break;
- if (close_bracket_index - open_bracket_index == 1)
- {
- if (log)
- log->Printf("[ScanBracketedRange] '[]' detected.. going from 0 to end of data");
- index_lower = 0;
- }
- else
- {
- const size_t separator_index = subpath.find('-', open_bracket_index + 1);
-
- if (separator_index == llvm::StringRef::npos)
- {
- const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
- index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
- index_higher = index_lower;
- if (log)
- log->Printf("[ScanBracketedRange] [%" PRId64 "] detected, high index is same", index_lower);
- }
- else
- {
- const char *index_lower_cstr = subpath.data() + open_bracket_index + 1;
- const char *index_higher_cstr = subpath.data() + separator_index + 1;
- index_lower = ::strtoul(index_lower_cstr, nullptr, 0);
- index_higher = ::strtoul(index_higher_cstr, nullptr, 0);
- if (log)
- log->Printf("[ScanBracketedRange] [%" PRId64 "-%" PRId64 "] detected", index_lower, index_higher);
- }
- if (index_lower > index_higher && index_higher > 0)
- {
- if (log)
- log->Printf("[ScanBracketedRange] swapping indices");
- const int64_t temp = index_lower;
- index_lower = index_higher;
- index_higher = temp;
- }
- }
+ case FileKind::Dirname:
+ if (file.GetDirectory()) {
+ s << file.GetDirectory();
+ return true;
}
- return true;
+ break;
+
+ case FileKind::Fullpath:
+ if (file) {
+ s << file;
+ return true;
+ }
+ break;
+ }
+ return false;
}
-static bool
-DumpFile (Stream &s, const FileSpec &file, FileKind file_kind)
-{
- switch (file_kind)
- {
- case FileKind::FileError:
- break;
+static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind,
+ uint32_t reg_num, Format format)
- case FileKind::Basename:
- if (file.GetFilename())
- {
- s << file.GetFilename();
+{
+ if (frame) {
+ RegisterContext *reg_ctx = frame->GetRegisterContext().get();
+
+ if (reg_ctx) {
+ const uint32_t lldb_reg_num =
+ reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
+ if (lldb_reg_num != LLDB_INVALID_REGNUM) {
+ const RegisterInfo *reg_info =
+ reg_ctx->GetRegisterInfoAtIndex(lldb_reg_num);
+ if (reg_info) {
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ reg_value.Dump(&s, reg_info, false, false, format);
return true;
+ }
}
- break;
+ }
+ }
+ }
+ return false;
+}
- case FileKind::Dirname:
- if (file.GetDirectory())
- {
- s << file.GetDirectory();
- return true;
- }
- break;
+static ValueObjectSP ExpandIndexedExpression(ValueObject *valobj, size_t index,
+ StackFrame *frame,
+ bool deref_pointer) {
+ 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);
+ if (log)
+ log->Printf("[ExpandIndexedExpression] name to deref: %s",
+ ptr_deref_buffer.c_str());
+ ValueObject::GetValueForExpressionPathOptions options;
+ ValueObject::ExpressionPathEndResultType final_value_type;
+ ValueObject::ExpressionPathScanEndReason reason_to_stop;
+ ValueObject::ExpressionPathAftermath what_next =
+ (deref_pointer ? ValueObject::eExpressionPathAftermathDereference
+ : ValueObject::eExpressionPathAftermathNothing);
+ ValueObjectSP item = valobj->GetValueForExpressionPath(
+ ptr_deref_buffer.c_str(), &reason_to_stop, &final_value_type, options,
+ &what_next);
+ if (!item) {
+ if (log)
+ log->Printf("[ExpandIndexedExpression] ERROR: why stopping = %d,"
+ " final_value_type %d",
+ reason_to_stop, final_value_type);
+ } else {
+ if (log)
+ log->Printf("[ExpandIndexedExpression] ALL RIGHT: why stopping = %d,"
+ " final_value_type %d",
+ reason_to_stop, final_value_type);
+ }
+ return item;
+}
- case FileKind::Fullpath:
- if (file)
- {
- s << file;
- return true;
- }
- break;
+static char ConvertValueObjectStyleToChar(
+ ValueObject::ValueObjectRepresentationStyle style) {
+ switch (style) {
+ case ValueObject::eValueObjectRepresentationStyleLanguageSpecific:
+ return '@';
+ case ValueObject::eValueObjectRepresentationStyleValue:
+ return 'V';
+ case ValueObject::eValueObjectRepresentationStyleLocation:
+ return 'L';
+ case ValueObject::eValueObjectRepresentationStyleSummary:
+ return 'S';
+ case ValueObject::eValueObjectRepresentationStyleChildrenCount:
+ return '#';
+ case ValueObject::eValueObjectRepresentationStyleType:
+ return 'T';
+ case ValueObject::eValueObjectRepresentationStyleName:
+ return 'N';
+ case ValueObject::eValueObjectRepresentationStyleExpressionPath:
+ return '>';
+ }
+ return '\0';
+}
+
+static bool DumpValue(Stream &s, const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const FormatEntity::Entry &entry, ValueObject *valobj) {
+ if (valobj == nullptr)
+ return false;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS));
+ Format custom_format = eFormatInvalid;
+ ValueObject::ValueObjectRepresentationStyle val_obj_display =
+ entry.string.empty()
+ ? ValueObject::eValueObjectRepresentationStyleValue
+ : ValueObject::eValueObjectRepresentationStyleSummary;
+
+ bool do_deref_pointer = entry.deref;
+ bool is_script = false;
+ switch (entry.type) {
+ case FormatEntity::Entry::Type::ScriptVariable:
+ is_script = true;
+ break;
+
+ case FormatEntity::Entry::Type::Variable:
+ custom_format = entry.fmt;
+ val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
+ break;
+
+ case FormatEntity::Entry::Type::ScriptVariableSynthetic:
+ is_script = true;
+ LLVM_FALLTHROUGH;
+ case FormatEntity::Entry::Type::VariableSynthetic:
+ custom_format = entry.fmt;
+ val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
+ if (!valobj->IsSynthetic()) {
+ valobj = valobj->GetSyntheticValue().get();
+ if (valobj == nullptr)
+ return false;
}
+ break;
+
+ default:
+ return false;
+ }
+
+ if (valobj == nullptr)
return false;
-}
-static bool
-DumpRegister (Stream &s,
- StackFrame *frame,
- RegisterKind reg_kind,
- uint32_t reg_num,
- Format format)
+ ValueObject::ExpressionPathAftermath what_next =
+ (do_deref_pointer ? ValueObject::eExpressionPathAftermathDereference
+ : ValueObject::eExpressionPathAftermathNothing);
+ ValueObject::GetValueForExpressionPathOptions options;
+ options.DontCheckDotVsArrowSyntax()
+ .DoAllowBitfieldSyntax()
+ .DoAllowFragileIVar()
+ .SetSyntheticChildrenTraversal(
+ ValueObject::GetValueForExpressionPathOptions::
+ SyntheticChildrenTraversal::Both);
+ ValueObject *target = nullptr;
+ const char *var_name_final_if_array_range = nullptr;
+ size_t close_bracket_index = llvm::StringRef::npos;
+ int64_t index_lower = -1;
+ int64_t index_higher = -1;
+ bool is_array_range = false;
+ bool was_plain_var = false;
+ bool was_var_format = false;
+ bool was_var_indexed = false;
+ ValueObject::ExpressionPathScanEndReason reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonEndOfString;
+ ValueObject::ExpressionPathEndResultType final_value_type =
+ ValueObject::eExpressionPathEndResultTypePlain;
+
+ if (is_script) {
+ return RunScriptFormatKeyword(s, sc, exe_ctx, valobj, entry.string.c_str());
+ }
+
+ llvm::StringRef subpath(entry.string);
+ // simplest case ${var}, just print valobj's value
+ if (entry.string.empty()) {
+ if (entry.printf_format.empty() && entry.fmt == eFormatDefault &&
+ entry.number == ValueObject::eValueObjectRepresentationStyleValue)
+ was_plain_var = true;
+ else
+ was_var_format = true;
+ target = valobj;
+ } else // this is ${var.something} or multiple .something nested
+ {
+ if (entry.string[0] == '[')
+ was_var_indexed = true;
+ ScanBracketedRange(subpath, close_bracket_index,
+ var_name_final_if_array_range, index_lower,
+ index_higher);
-{
- if (frame)
- {
- RegisterContext *reg_ctx = frame->GetRegisterContext().get();
+ Error error;
- if (reg_ctx)
- {
- const uint32_t lldb_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber(reg_kind, reg_num);
- if (lldb_reg_num != LLDB_INVALID_REGNUM)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex (lldb_reg_num);
- if (reg_info)
- {
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister (reg_info, reg_value))
- {
- reg_value.Dump(&s, reg_info, false, false, format);
- return true;
- }
- }
- }
- }
+ const std::string &expr_path = entry.string;
+
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",
+ expr_path.c_str());
+
+ target =
+ valobj
+ ->GetValueForExpressionPath(expr_path.c_str(), &reason_to_stop,
+ &final_value_type, options, &what_next)
+ .get();
+
+ if (!target) {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] ERROR: why stopping = %d,"
+ " final_value_type %d",
+ reason_to_stop, final_value_type);
+ return false;
+ } else {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] ALL RIGHT: why stopping = %d,"
+ " final_value_type %d",
+ reason_to_stop, final_value_type);
+ target = target
+ ->GetQualifiedRepresentationIfAvailable(
+ target->GetDynamicValueType(), true)
+ .get();
+ }
+ }
+
+ is_array_range =
+ (final_value_type ==
+ ValueObject::eExpressionPathEndResultTypeBoundedRange ||
+ final_value_type ==
+ ValueObject::eExpressionPathEndResultTypeUnboundedRange);
+
+ do_deref_pointer =
+ (what_next == ValueObject::eExpressionPathAftermathDereference);
+
+ if (do_deref_pointer && !is_array_range) {
+ // I have not deref-ed yet, let's do it
+ // this happens when we are not going through
+ // GetValueForVariableExpressionPath
+ // to get to the target ValueObject
+ Error error;
+ target = target->Dereference(error).get();
+ if (error.Fail()) {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] ERROR: %s\n",
+ error.AsCString("unknown"));
+ return false;
}
+ do_deref_pointer = false;
+ }
+
+ if (!target) {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] could not calculate target for "
+ "prompt expression");
return false;
-}
+ }
+
+ // we do not want to use the summary for a bitfield of type T:n
+ // if we were originally dealing with just a T - that would get
+ // us into an endless recursion
+ if (target->IsBitfield() && was_var_indexed) {
+ // TODO: check for a (T:n)-specific summary - we should still obey that
+ StreamString bitfield_name;
+ bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(),
+ target->GetBitfieldBitSize());
+ lldb::TypeNameSpecifierImplSP type_sp(
+ new TypeNameSpecifierImpl(bitfield_name.GetString(), false));
+ if (val_obj_display ==
+ ValueObject::eValueObjectRepresentationStyleSummary &&
+ !DataVisualization::GetSummaryForType(type_sp))
+ val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
+ }
+
+ // TODO use flags for these
+ const uint32_t type_info_flags =
+ target->GetCompilerType().GetTypeInfo(nullptr);
+ bool is_array = (type_info_flags & eTypeIsArray) != 0;
+ bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
+ 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
+ {
+ StreamString str_temp;
+ if (log)
+ log->Printf(
+ "[Debugger::FormatPrompt] I am into array || pointer && !range");
+
+ if (target->HasSpecialPrintableRepresentation(val_obj_display,
+ custom_format)) {
+ // try to use the special cases
+ bool success = target->DumpPrintableRepresentation(
+ str_temp, val_obj_display, custom_format);
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] special cases did%s match",
+ success ? "" : "n't");
+
+ // should not happen
+ if (success)
+ s << str_temp.GetString();
+ return true;
+ } else {
+ if (was_plain_var) // if ${var}
+ {
+ s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
+ } else if (is_pointer) // if pointer, value is the address stored
+ {
+ target->DumpPrintableRepresentation(
+ s, val_obj_display, custom_format,
+ ValueObject::PrintableRepresentationSpecialCases::eDisable);
+ }
+ return true;
+ }
+ }
-static ValueObjectSP
-ExpandIndexedExpression (ValueObject* valobj,
- size_t index,
- StackFrame* frame,
- bool deref_pointer)
-{
- 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);
+ // if directly trying to print ${var}, and this is an aggregate, display a
+ // nice
+ // type @ location message
+ if (is_aggregate && was_plain_var) {
+ s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
+ return true;
+ }
+
+ // if directly trying to print ${var%V}, and this is an aggregate, do not let
+ // the user do it
+ if (is_aggregate &&
+ ((was_var_format &&
+ val_obj_display ==
+ ValueObject::eValueObjectRepresentationStyleValue))) {
+ s << "<invalid use of aggregate type>";
+ return true;
+ }
+
+ if (!is_array_range) {
if (log)
- log->Printf("[ExpandIndexedExpression] name to deref: %s",ptr_deref_buffer.c_str());
- const char* first_unparsed;
- ValueObject::GetValueForExpressionPathOptions options;
- ValueObject::ExpressionPathEndResultType final_value_type;
- ValueObject::ExpressionPathScanEndReason reason_to_stop;
- ValueObject::ExpressionPathAftermath what_next = (deref_pointer ? ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
- ValueObjectSP item = valobj->GetValueForExpressionPath (ptr_deref_buffer.c_str(),
- &first_unparsed,
- &reason_to_stop,
- &final_value_type,
- options,
- &what_next);
- if (!item)
- {
- if (log)
- log->Printf("[ExpandIndexedExpression] ERROR: unparsed portion = %s, why stopping = %d,"
- " final_value_type %d",
- first_unparsed, reason_to_stop, final_value_type);
+ log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
+ return target->DumpPrintableRepresentation(s, val_obj_display,
+ custom_format);
+ } else {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
+ if (!is_array && !is_pointer)
+ return false;
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] handle as array");
+ StreamString special_directions_stream;
+ llvm::StringRef special_directions;
+ if (close_bracket_index != llvm::StringRef::npos &&
+ subpath.size() > close_bracket_index) {
+ ConstString additional_data(subpath.drop_front(close_bracket_index + 1));
+ special_directions_stream.Printf("${%svar%s", do_deref_pointer ? "*" : "",
+ additional_data.GetCString());
+
+ if (entry.fmt != eFormatDefault) {
+ const char format_char =
+ FormatManager::GetFormatAsFormatChar(entry.fmt);
+ if (format_char != '\0')
+ special_directions_stream.Printf("%%%c", format_char);
+ else {
+ const char *format_cstr =
+ FormatManager::GetFormatAsCString(entry.fmt);
+ special_directions_stream.Printf("%%%s", format_cstr);
+ }
+ } else if (entry.number != 0) {
+ const char style_char = ConvertValueObjectStyleToChar(
+ (ValueObject::ValueObjectRepresentationStyle)entry.number);
+ if (style_char)
+ special_directions_stream.Printf("%%%c", style_char);
+ }
+ special_directions_stream.PutChar('}');
+ special_directions =
+ llvm::StringRef(special_directions_stream.GetString());
}
- else
- {
+
+ // let us display items index_lower thru index_higher of this array
+ s.PutChar('[');
+
+ if (index_higher < 0)
+ index_higher = valobj->GetNumChildren() - 1;
+
+ uint32_t max_num_children =
+ target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+
+ bool success = true;
+ for (int64_t index = index_lower; index <= index_higher; ++index) {
+ ValueObject *item =
+ ExpandIndexedExpression(target, index, exe_ctx->GetFramePtr(), false)
+ .get();
+
+ if (!item) {
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at "
+ "index %" PRId64,
+ index);
+ } else {
if (log)
- log->Printf("[ExpandIndexedExpression] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
- " final_value_type %d",
- first_unparsed, reason_to_stop, final_value_type);
+ log->Printf(
+ "[Debugger::FormatPrompt] special_directions for child item: %s",
+ special_directions.data() ? special_directions.data() : "");
+ }
+
+ if (special_directions.empty()) {
+ success &= item->DumpPrintableRepresentation(s, val_obj_display,
+ custom_format);
+ } else {
+ success &= FormatEntity::FormatStringRef(
+ special_directions, s, sc, exe_ctx, nullptr, item, false, false);
+ }
+
+ if (--max_num_children == 0) {
+ s.PutCString(", ...");
+ break;
+ }
+
+ if (index < index_higher)
+ s.PutChar(',');
}
- return item;
+ s.PutChar(']');
+ return success;
+ }
}
-static char
-ConvertValueObjectStyleToChar(ValueObject::ValueObjectRepresentationStyle style)
-{
- switch (style)
- {
- case ValueObject::eValueObjectRepresentationStyleLanguageSpecific: return '@';
- case ValueObject::eValueObjectRepresentationStyleValue: return 'V';
- case ValueObject::eValueObjectRepresentationStyleLocation: return 'L';
- case ValueObject::eValueObjectRepresentationStyleSummary: return 'S';
- case ValueObject::eValueObjectRepresentationStyleChildrenCount: return '#';
- case ValueObject::eValueObjectRepresentationStyleType: return 'T';
- case ValueObject::eValueObjectRepresentationStyleName: return 'N';
- case ValueObject::eValueObjectRepresentationStyleExpressionPath: return '>';
- }
- return '\0';
+static bool DumpRegister(Stream &s, StackFrame *frame, const char *reg_name,
+ Format format) {
+ if (frame) {
+ RegisterContext *reg_ctx = frame->GetRegisterContext().get();
+
+ if (reg_ctx) {
+ const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
+ if (reg_info) {
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(reg_info, reg_value)) {
+ reg_value.Dump(&s, reg_info, false, false, format);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
}
-static bool
-DumpValue (Stream &s,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const FormatEntity::Entry &entry,
- ValueObject *valobj)
-{
- if (valobj == nullptr)
- return false;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DATAFORMATTERS));
- Format custom_format = eFormatInvalid;
- ValueObject::ValueObjectRepresentationStyle val_obj_display = entry.string.empty() ? ValueObject::eValueObjectRepresentationStyleValue : ValueObject::eValueObjectRepresentationStyleSummary;
+static bool FormatThreadExtendedInfoRecurse(
+ const FormatEntity::Entry &entry,
+ const StructuredData::ObjectSP &thread_info_dictionary,
+ const SymbolContext *sc, const ExecutionContext *exe_ctx, Stream &s) {
+ llvm::StringRef path(entry.string);
+
+ StructuredData::ObjectSP value =
+ thread_info_dictionary->GetObjectForDotSeparatedPath(path);
+
+ if (value) {
+ if (value->GetType() == StructuredData::Type::eTypeInteger) {
+ const char *token_format = "0x%4.4" PRIx64;
+ if (!entry.printf_format.empty())
+ token_format = entry.printf_format.c_str();
+ s.Printf(token_format, value->GetAsInteger()->GetValue());
+ return true;
+ } else if (value->GetType() == StructuredData::Type::eTypeFloat) {
+ s.Printf("%f", value->GetAsFloat()->GetValue());
+ return true;
+ } else if (value->GetType() == StructuredData::Type::eTypeString) {
+ s.Printf("%s", value->GetAsString()->GetValue().c_str());
+ return true;
+ } else if (value->GetType() == StructuredData::Type::eTypeArray) {
+ if (value->GetAsArray()->GetSize() > 0) {
+ s.Printf("%zu", value->GetAsArray()->GetSize());
+ return true;
+ }
+ } else if (value->GetType() == StructuredData::Type::eTypeDictionary) {
+ s.Printf("%zu",
+ value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
+ return true;
+ }
+ }
- bool do_deref_pointer = entry.deref;
- bool is_script = false;
- switch (entry.type)
- {
- case FormatEntity::Entry::Type::ScriptVariable:
- is_script = true;
- break;
+ return false;
+}
- case FormatEntity::Entry::Type::Variable:
- custom_format = entry.fmt;
- val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
- break;
+static inline bool IsToken(const char *var_name_begin, const char *var) {
+ return (::strncmp(var_name_begin, var, strlen(var)) == 0);
+}
- case FormatEntity::Entry::Type::ScriptVariableSynthetic:
- is_script = true;
- LLVM_FALLTHROUGH;
- case FormatEntity::Entry::Type::VariableSynthetic:
- custom_format = entry.fmt;
- val_obj_display = (ValueObject::ValueObjectRepresentationStyle)entry.number;
- if (!valobj->IsSynthetic())
- {
- valobj = valobj->GetSyntheticValue().get();
- if (valobj == nullptr)
- return false;
- }
- break;
+bool FormatEntity::FormatStringRef(const llvm::StringRef &format_str, Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr, ValueObject *valobj,
+ bool function_changed,
+ bool initial_function) {
+ if (!format_str.empty()) {
+ FormatEntity::Entry root;
+ Error error = FormatEntity::Parse(format_str, root);
+ if (error.Success()) {
+ return FormatEntity::Format(root, s, sc, exe_ctx, addr, valobj,
+ function_changed, initial_function);
+ }
+ }
+ return false;
+}
- default:
- return false;
+bool FormatEntity::FormatCString(const char *format, Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr, ValueObject *valobj,
+ bool function_changed, bool initial_function) {
+ if (format && format[0]) {
+ FormatEntity::Entry root;
+ llvm::StringRef format_str(format);
+ Error error = FormatEntity::Parse(format_str, root);
+ if (error.Success()) {
+ return FormatEntity::Format(root, s, sc, exe_ctx, addr, valobj,
+ function_changed, initial_function);
}
+ }
+ return false;
+}
- if (valobj == nullptr)
- return false;
+bool FormatEntity::Format(const Entry &entry, Stream &s,
+ const SymbolContext *sc,
+ const ExecutionContext *exe_ctx, const Address *addr,
+ ValueObject *valobj, bool function_changed,
+ bool initial_function) {
+ switch (entry.type) {
+ case Entry::Type::Invalid:
+ case Entry::Type::ParentNumber: // Only used for
+ // FormatEntity::Entry::Definition encoding
+ case Entry::Type::ParentString: // Only used for
+ // FormatEntity::Entry::Definition encoding
+ case Entry::Type::InsertString: // Only used for
+ // FormatEntity::Entry::Definition encoding
+ return false;
- ValueObject::ExpressionPathAftermath what_next = (do_deref_pointer ?
- ValueObject::eExpressionPathAftermathDereference : ValueObject::eExpressionPathAftermathNothing);
- ValueObject::GetValueForExpressionPathOptions options;
- options.DontCheckDotVsArrowSyntax().DoAllowBitfieldSyntax().DoAllowFragileIVar().SetSyntheticChildrenTraversal(ValueObject::GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both);
- ValueObject* target = nullptr;
- const char* var_name_final_if_array_range = nullptr;
- size_t close_bracket_index = llvm::StringRef::npos;
- int64_t index_lower = -1;
- int64_t index_higher = -1;
- bool is_array_range = false;
- const char* first_unparsed;
- bool was_plain_var = false;
- bool was_var_format = false;
- bool was_var_indexed = false;
- ValueObject::ExpressionPathScanEndReason reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
- ValueObject::ExpressionPathEndResultType final_value_type = ValueObject::eExpressionPathEndResultTypePlain;
-
- if (is_script)
- {
- return RunScriptFormatKeyword (s, sc, exe_ctx, valobj, entry.string.c_str());
- }
-
- llvm::StringRef subpath (entry.string);
- // simplest case ${var}, just print valobj's value
- if (entry.string.empty())
- {
- if (entry.printf_format.empty() && entry.fmt == eFormatDefault && entry.number == ValueObject::eValueObjectRepresentationStyleValue)
- was_plain_var = true;
- else
- was_var_format = true;
- target = valobj;
+ case Entry::Type::Root:
+ for (const auto &child : entry.children) {
+ if (!Format(child, s, sc, exe_ctx, addr, valobj, function_changed,
+ initial_function)) {
+ return false; // If any item of root fails, then the formatting fails
+ }
}
- else // this is ${var.something} or multiple .something nested
- {
- if (entry.string[0] == '[')
- was_var_indexed = true;
- ScanBracketedRange (subpath,
- close_bracket_index,
- var_name_final_if_array_range,
- index_lower,
- index_higher);
+ return true; // Only return true if all items succeeded
- Error error;
+ case Entry::Type::String:
+ s.PutCString(entry.string);
+ return true;
- const std::string &expr_path = entry.string;
+ case Entry::Type::Scope: {
+ StreamString scope_stream;
+ bool success = false;
+ for (const auto &child : entry.children) {
+ success = Format(child, scope_stream, sc, exe_ctx, addr, valobj,
+ function_changed, initial_function);
+ if (!success)
+ break;
+ }
+ // Only if all items in a scope succeed, then do we
+ // print the output into the main stream
+ if (success)
+ s.Write(scope_stream.GetString().data(), scope_stream.GetString().size());
+ }
+ return true; // Scopes always successfully print themselves
+
+ case Entry::Type::Variable:
+ case Entry::Type::VariableSynthetic:
+ case Entry::Type::ScriptVariable:
+ case Entry::Type::ScriptVariableSynthetic:
+ return DumpValue(s, sc, exe_ctx, entry, valobj);
+
+ case Entry::Type::AddressFile:
+ case Entry::Type::AddressLoad:
+ case Entry::Type::AddressLoadOrFile:
+ return (addr != nullptr && addr->IsValid() &&
+ DumpAddress(s, sc, exe_ctx, *addr,
+ entry.type == Entry::Type::AddressLoadOrFile));
+
+ case Entry::Type::ProcessID:
+ if (exe_ctx) {
+ Process *process = exe_ctx->GetProcessPtr();
+ if (process) {
+ const char *format = "%" PRIu64;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, process->GetID());
+ return true;
+ }
+ }
+ return false;
- if (log)
- log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",expr_path.c_str());
+ case Entry::Type::ProcessFile:
+ if (exe_ctx) {
+ Process *process = exe_ctx->GetProcessPtr();
+ if (process) {
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module) {
+ if (DumpFile(s, exe_module->GetFileSpec(), (FileKind)entry.number))
+ return true;
+ }
+ }
+ }
+ return false;
- target = valobj->GetValueForExpressionPath(expr_path.c_str(),
- &first_unparsed,
- &reason_to_stop,
- &final_value_type,
- options,
- &what_next).get();
+ case Entry::Type::ScriptProcess:
+ if (exe_ctx) {
+ Process *process = exe_ctx->GetProcessPtr();
+ if (process)
+ return RunScriptFormatKeyword(s, sc, exe_ctx, process,
+ entry.string.c_str());
+ }
+ return false;
- if (!target)
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR: unparsed portion = %s, why stopping = %d,"
- " final_value_type %d",
- first_unparsed, reason_to_stop, final_value_type);
- return false;
- }
- else
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ALL RIGHT: unparsed portion = %s, why stopping = %d,"
- " final_value_type %d",
- first_unparsed, reason_to_stop, final_value_type);
- target = target->GetQualifiedRepresentationIfAvailable(target->GetDynamicValueType(), true).get();
+ case Entry::Type::ThreadID:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ const char *format = "0x%4.4" PRIx64;
+ if (!entry.printf_format.empty()) {
+ // 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;
+ if ((ostype == llvm::Triple::FreeBSD) ||
+ (ostype == llvm::Triple::Linux)) {
+ format = "%" PRIu64;
+ }
+ } else {
+ format = entry.printf_format.c_str();
+ }
}
+ s.Printf(format, thread->GetID());
+ return true;
+ }
}
+ return false;
- is_array_range = (final_value_type == ValueObject::eExpressionPathEndResultTypeBoundedRange ||
- final_value_type == ValueObject::eExpressionPathEndResultTypeUnboundedRange);
+ case Entry::Type::ThreadProtocolID:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ const char *format = "0x%4.4" PRIx64;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, thread->GetProtocolID());
+ return true;
+ }
+ }
+ return false;
- do_deref_pointer = (what_next == ValueObject::eExpressionPathAftermathDereference);
+ case Entry::Type::ThreadIndexID:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ const char *format = "%" PRIu32;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, thread->GetIndexID());
+ return true;
+ }
+ }
+ return false;
- if (do_deref_pointer && !is_array_range)
- {
- // I have not deref-ed yet, let's do it
- // this happens when we are not going through GetValueForVariableExpressionPath
- // to get to the target ValueObject
- Error error;
- target = target->Dereference(error).get();
- if (error.Fail())
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR: %s\n", error.AsCString("unknown")); \
- return false;
+ case Entry::Type::ThreadName:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ const char *cstr = thread->GetName();
+ if (cstr && cstr[0]) {
+ s.PutCString(cstr);
+ return true;
}
- do_deref_pointer = false;
+ }
}
+ return false;
- if (!target)
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] could not calculate target for prompt expression");
- return false;
+ case Entry::Type::ThreadQueue:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ const char *cstr = thread->GetQueueName();
+ if (cstr && cstr[0]) {
+ s.PutCString(cstr);
+ return true;
+ }
+ }
}
+ return false;
- // we do not want to use the summary for a bitfield of type T:n
- // if we were originally dealing with just a T - that would get
- // us into an endless recursion
- if (target->IsBitfield() && was_var_indexed)
- {
- // TODO: check for a (T:n)-specific summary - we should still obey that
- StreamString bitfield_name;
- bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
- lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
- if (val_obj_display == ValueObject::eValueObjectRepresentationStyleSummary && !DataVisualization::GetSummaryForType(type_sp))
- val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
- }
-
- // TODO use flags for these
- const uint32_t type_info_flags = target->GetCompilerType().GetTypeInfo(nullptr);
- bool is_array = (type_info_flags & eTypeIsArray) != 0;
- bool is_pointer = (type_info_flags & eTypeIsPointer) != 0;
- 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
- {
- StreamString str_temp;
- if (log)
- log->Printf("[Debugger::FormatPrompt] I am into array || pointer && !range");
-
- if (target->HasSpecialPrintableRepresentation(val_obj_display, custom_format))
- {
- // try to use the special cases
- bool success = target->DumpPrintableRepresentation(str_temp,
- val_obj_display,
- custom_format);
- if (log)
- log->Printf("[Debugger::FormatPrompt] special cases did%s match", success ? "" : "n't");
-
- // should not happen
- if (success)
- s << str_temp.GetData();
+ case Entry::Type::ThreadStopReason:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ StopInfoSP stop_info_sp = thread->GetStopInfo();
+ if (stop_info_sp && stop_info_sp->IsValid()) {
+ const char *cstr = stop_info_sp->GetDescription();
+ if (cstr && cstr[0]) {
+ s.PutCString(cstr);
return true;
+ }
}
- else
- {
- if (was_plain_var) // if ${var}
- {
- s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
- }
- else if (is_pointer) // if pointer, value is the address stored
- {
- target->DumpPrintableRepresentation (s,
- val_obj_display,
- custom_format,
- ValueObject::ePrintableRepresentationSpecialCasesDisable);
- }
+ }
+ }
+ return false;
+
+ case Entry::Type::ThreadReturnValue:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ StopInfoSP stop_info_sp = thread->GetStopInfo();
+ if (stop_info_sp && stop_info_sp->IsValid()) {
+ ValueObjectSP return_valobj_sp =
+ StopInfo::GetReturnValueObject(stop_info_sp);
+ if (return_valobj_sp) {
+ return_valobj_sp->Dump(s);
return true;
+ }
}
+ }
}
+ return false;
- // if directly trying to print ${var}, and this is an aggregate, display a nice
- // type @ location message
- if (is_aggregate && was_plain_var)
- {
- s << target->GetTypeName() << " @ " << target->GetLocationAsCString();
- return true;
+ case Entry::Type::ThreadCompletedExpression:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ StopInfoSP stop_info_sp = thread->GetStopInfo();
+ if (stop_info_sp && stop_info_sp->IsValid()) {
+ ExpressionVariableSP expression_var_sp =
+ StopInfo::GetExpressionVariable(stop_info_sp);
+ if (expression_var_sp && expression_var_sp->GetValueObject()) {
+ expression_var_sp->GetValueObject()->Dump(s);
+ return true;
+ }
+ }
+ }
}
+ return false;
- // if directly trying to print ${var%V}, and this is an aggregate, do not let the user do it
- if (is_aggregate && ((was_var_format && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)))
- {
- s << "<invalid use of aggregate type>";
- return true;
+ case Entry::Type::ScriptThread:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread)
+ return RunScriptFormatKeyword(s, sc, exe_ctx, thread,
+ entry.string.c_str());
}
+ return false;
- if (!is_array_range)
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] dumping ordinary printable output");
- return target->DumpPrintableRepresentation(s,val_obj_display, custom_format);
- }
- else
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] checking if I can handle as array");
- if (!is_array && !is_pointer)
- return false;
- if (log)
- log->Printf("[Debugger::FormatPrompt] handle as array");
- StreamString special_directions_stream;
- llvm::StringRef special_directions;
- if (close_bracket_index != llvm::StringRef::npos && subpath.size() > close_bracket_index)
- {
- ConstString additional_data (subpath.drop_front(close_bracket_index+1));
- special_directions_stream.Printf("${%svar%s",
- do_deref_pointer ? "*" : "",
- additional_data.GetCString());
-
- if (entry.fmt != eFormatDefault)
- {
- const char format_char = FormatManager::GetFormatAsFormatChar(entry.fmt);
- if (format_char != '\0')
- special_directions_stream.Printf("%%%c", format_char);
- else
- {
- const char *format_cstr = FormatManager::GetFormatAsCString(entry.fmt);
- special_directions_stream.Printf("%%%s", format_cstr);
- }
- }
- else if (entry.number != 0)
- {
- const char style_char = ConvertValueObjectStyleToChar ((ValueObject::ValueObjectRepresentationStyle)entry.number);
- if (style_char)
- special_directions_stream.Printf("%%%c", style_char);
- }
- special_directions_stream.PutChar('}');
- special_directions = llvm::StringRef(special_directions_stream.GetString());
+ case Entry::Type::ThreadInfo:
+ if (exe_ctx) {
+ Thread *thread = exe_ctx->GetThreadPtr();
+ if (thread) {
+ StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
+ if (object_sp &&
+ object_sp->GetType() == StructuredData::Type::eTypeDictionary) {
+ if (FormatThreadExtendedInfoRecurse(entry, object_sp, sc, exe_ctx, s))
+ return true;
}
+ }
+ }
+ return false;
- // let us display items index_lower thru index_higher of this array
- s.PutChar('[');
+ case Entry::Type::TargetArch:
+ if (exe_ctx) {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target) {
+ const ArchSpec &arch = target->GetArchitecture();
+ if (arch.IsValid()) {
+ s.PutCString(arch.GetArchitectureName());
+ return true;
+ }
+ }
+ }
+ return false;
- if (index_higher < 0)
- index_higher = valobj->GetNumChildren() - 1;
+ case Entry::Type::ScriptTarget:
+ if (exe_ctx) {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target)
+ return RunScriptFormatKeyword(s, sc, exe_ctx, target,
+ entry.string.c_str());
+ }
+ return false;
- uint32_t max_num_children = target->GetTargetSP()->GetMaximumNumberOfChildrenToDisplay();
+ case Entry::Type::ModuleFile:
+ if (sc) {
+ Module *module = sc->module_sp.get();
+ if (module) {
+ if (DumpFile(s, module->GetFileSpec(), (FileKind)entry.number))
+ return true;
+ }
+ }
+ return false;
- bool success = true;
- for (int64_t index = index_lower;index<=index_higher; ++index)
- {
- ValueObject* item = ExpandIndexedExpression (target,
- index,
- exe_ctx->GetFramePtr(),
- false).get();
-
- if (!item)
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] ERROR in getting child item at index %" PRId64, index);
- }
- else
- {
- if (log)
- log->Printf("[Debugger::FormatPrompt] special_directions for child item: %s",special_directions.data() ? special_directions.data() : "");
- }
+ case Entry::Type::File:
+ if (sc) {
+ CompileUnit *cu = sc->comp_unit;
+ if (cu) {
+ // CompileUnit is a FileSpec
+ if (DumpFile(s, *cu, (FileKind)entry.number))
+ return true;
+ }
+ }
+ return false;
- if (special_directions.empty())
- {
- success &= item->DumpPrintableRepresentation(s,val_obj_display, custom_format);
- }
- else
- {
- success &= FormatEntity::FormatStringRef(special_directions, s, sc, exe_ctx, nullptr, item, false, false);
- }
+ case Entry::Type::Lang:
+ if (sc) {
+ CompileUnit *cu = sc->comp_unit;
+ if (cu) {
+ const char *lang_name =
+ Language::GetNameForLanguageType(cu->GetLanguage());
+ if (lang_name) {
+ s.PutCString(lang_name);
+ return true;
+ }
+ }
+ }
+ return false;
- if (--max_num_children == 0)
- {
- s.PutCString(", ...");
- break;
- }
+ case Entry::Type::FrameIndex:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame) {
+ const char *format = "%" PRIu32;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, frame->GetFrameIndex());
+ return true;
+ }
+ }
+ return false;
- if (index < index_higher)
- s.PutChar(',');
+ case Entry::Type::FrameRegisterPC:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame) {
+ const Address &pc_addr = frame->GetFrameCodeAddress();
+ if (pc_addr.IsValid()) {
+ if (DumpAddress(s, sc, exe_ctx, pc_addr, false))
+ return true;
}
- s.PutChar(']');
- return success;
+ }
}
-}
+ return false;
-static bool
-DumpRegister (Stream &s,
- StackFrame *frame,
- const char *reg_name,
- Format format)
-{
- if (frame)
- {
- RegisterContext *reg_ctx = frame->GetRegisterContext().get();
+ case Entry::Type::FrameRegisterSP:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame) {
+ if (DumpRegister(s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP,
+ (lldb::Format)entry.number))
+ return true;
+ }
+ }
+ return false;
- if (reg_ctx)
- {
- const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
- if (reg_info)
- {
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister (reg_info, reg_value))
- {
- reg_value.Dump(&s, reg_info, false, false, format);
- return true;
- }
- }
- }
+ case Entry::Type::FrameRegisterFP:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame) {
+ if (DumpRegister(s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP,
+ (lldb::Format)entry.number))
+ return true;
+ }
}
return false;
-}
-static bool
-FormatThreadExtendedInfoRecurse(const FormatEntity::Entry &entry,
- const StructuredData::ObjectSP &thread_info_dictionary,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- Stream &s)
-{
- llvm::StringRef path(entry.string);
+ case Entry::Type::FrameRegisterFlags:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame) {
+ if (DumpRegister(s, frame, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_FLAGS, (lldb::Format)entry.number))
+ return true;
+ }
+ }
+ return false;
- StructuredData::ObjectSP value = thread_info_dictionary->GetObjectForDotSeparatedPath (path);
+ case Entry::Type::FrameNoDebug:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame) {
+ return !frame->HasDebugInformation();
+ }
+ }
+ return true;
- if (value)
- {
- if (value->GetType() == StructuredData::Type::eTypeInteger)
- {
- const char *token_format = "0x%4.4" PRIx64;
- if (!entry.printf_format.empty())
- token_format = entry.printf_format.c_str();
- s.Printf(token_format, value->GetAsInteger()->GetValue());
- return true;
- }
- else if (value->GetType() == StructuredData::Type::eTypeFloat)
- {
- s.Printf ("%f", value->GetAsFloat()->GetValue());
- return true;
- }
- else if (value->GetType() == StructuredData::Type::eTypeString)
- {
- s.Printf("%s", value->GetAsString()->GetValue().c_str());
- return true;
- }
- else if (value->GetType() == StructuredData::Type::eTypeArray)
- {
- if (value->GetAsArray()->GetSize() > 0)
- {
- s.Printf ("%zu", value->GetAsArray()->GetSize());
- return true;
- }
- }
- else if (value->GetType() == StructuredData::Type::eTypeDictionary)
- {
- s.Printf ("%zu", value->GetAsDictionary()->GetKeys()->GetAsArray()->GetSize());
- return true;
- }
+ case Entry::Type::FrameRegisterByName:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame) {
+ if (DumpRegister(s, frame, entry.string.c_str(),
+ (lldb::Format)entry.number))
+ return true;
+ }
}
+ return false;
+ case Entry::Type::ScriptFrame:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame)
+ return RunScriptFormatKeyword(s, sc, exe_ctx, frame,
+ entry.string.c_str());
+ }
return false;
-}
-static inline bool
-IsToken(const char *var_name_begin, const char *var)
-{
- return (::strncmp (var_name_begin, var, strlen(var)) == 0);
-}
+ case Entry::Type::FunctionID:
+ if (sc) {
+ if (sc->function) {
+ s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
+ return true;
+ } else if (sc->symbol) {
+ s.Printf("symbol[%u]", sc->symbol->GetID());
+ return true;
+ }
+ }
+ return false;
-bool
-FormatEntity::FormatStringRef (const llvm::StringRef &format_str,
- Stream &s,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- ValueObject* valobj,
- bool function_changed,
- bool initial_function)
-{
- if (!format_str.empty())
- {
- FormatEntity::Entry root;
- Error error = FormatEntity::Parse(format_str, root);
- if (error.Success())
- {
- return FormatEntity::Format (root,
- s,
- sc,
- exe_ctx,
- addr,
- valobj,
- function_changed,
- initial_function);
+ case Entry::Type::FunctionDidChange:
+ return function_changed;
+
+ case Entry::Type::FunctionInitialFunction:
+ return initial_function;
+
+ case Entry::Type::FunctionName: {
+ 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) {
+ language_plugin_handled = language_plugin->GetFunctionDisplayName(
+ sc, exe_ctx, Language::FunctionNameRepresentation::eName, ss);
+ }
+ if (language_plugin_handled) {
+ s << ss.GetString();
+ return true;
+ } else {
+ const char *name = nullptr;
+ if (sc->function)
+ name = sc->function->GetName().AsCString(nullptr);
+ else if (sc->symbol)
+ name = sc->symbol->GetName().AsCString(nullptr);
+ if (name) {
+ s.PutCString(name);
+
+ if (sc->block) {
+ Block *inline_block = sc->block->GetContainingInlinedBlock();
+ if (inline_block) {
+ const InlineFunctionInfo *inline_info =
+ sc->block->GetInlinedFunctionInfo();
+ if (inline_info) {
+ s.PutCString(" [inlined] ");
+ inline_info->GetName(sc->function->GetLanguage()).Dump(&s);
+ }
+ }
}
+ return true;
+ }
}
+ }
return false;
-}
-bool
-FormatEntity::FormatCString (const char *format,
- Stream &s,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- ValueObject* valobj,
- bool function_changed,
- bool initial_function)
-{
- if (format && format[0])
- {
- FormatEntity::Entry root;
- llvm::StringRef format_str(format);
- Error error = FormatEntity::Parse(format_str, root);
- if (error.Success())
- {
- return FormatEntity::Format (root,
- s,
- sc,
- exe_ctx,
- addr,
- valobj,
- function_changed,
- initial_function);
- }
+ case Entry::Type::FunctionNameNoArgs: {
+ 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) {
+ language_plugin_handled = language_plugin->GetFunctionDisplayName(
+ sc, exe_ctx, Language::FunctionNameRepresentation::eNameWithNoArgs,
+ ss);
+ }
+ if (language_plugin_handled) {
+ s << ss.GetString();
+ 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;
-}
-bool
-FormatEntity::Format (const Entry &entry,
- Stream &s,
- const SymbolContext *sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- ValueObject* valobj,
- bool function_changed,
- bool initial_function)
-{
- switch (entry.type)
- {
- case Entry::Type::Invalid:
- case Entry::Type::ParentNumber: // Only used for FormatEntity::Entry::Definition encoding
- case Entry::Type::ParentString: // Only used for FormatEntity::Entry::Definition encoding
- case Entry::Type::InsertString: // Only used for FormatEntity::Entry::Definition encoding
- return false;
-
- case Entry::Type::Root:
- for (const auto &child : entry.children)
- {
- if (!Format(child,
- s,
- sc,
- exe_ctx,
- addr,
- valobj,
- function_changed,
- initial_function))
- {
- return false; // If any item of root fails, then the formatting fails
- }
+ case Entry::Type::FunctionNameWithArgs: {
+ 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) {
+ language_plugin_handled = language_plugin->GetFunctionDisplayName(
+ sc, exe_ctx, Language::FunctionNameRepresentation::eNameWithArgs, ss);
+ }
+ if (language_plugin_handled) {
+ s << ss.GetString();
+ return true;
+ } else {
+ // Print the function name with arguments in it
+ if (sc->function) {
+ ExecutionContextScope *exe_scope =
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
+ const char *cstr = sc->function->GetName().AsCString(nullptr);
+ if (cstr) {
+ const InlineFunctionInfo *inline_info = nullptr;
+ 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) {
+ 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) {
+ 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 {
+ 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;
+ llvm::StringRef var_representation;
+ 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)) {
+ static StringSummaryFormat format(
+ TypeSummaryImpl::Flags()
+ .SetHideItemNames(false)
+ .SetShowMembersOneLiner(true),
+ "");
+ format.FormatObject(var_value_sp.get(), buffer,
+ TypeSummaryOptions());
+ var_representation = buffer;
+ } else
+ var_value_sp->DumpPrintableRepresentation(
+ ss, ValueObject::ValueObjectRepresentationStyle::
+ eValueObjectRepresentationStyleSummary,
+ eFormatDefault,
+ ValueObject::PrintableRepresentationSpecialCases::eAllow,
+ false);
+ }
+
+ if (!ss.GetString().empty())
+ var_representation = ss.GetString();
+ if (arg_idx > 0)
+ s.PutCString(", ");
+ if (var_value_sp->GetError().Success()) {
+ if (!var_representation.empty())
+ s.Printf("%s=%s", var_name, var_representation.str().c_str());
+ else
+ s.Printf("%s=%s at %s", var_name,
+ var_value_sp->GetTypeName().GetCString(),
+ var_value_sp->GetLocationAsCString());
+ } else
+ s.Printf("%s=<unavailable>", var_name);
}
- return true; // Only return true if all items succeeded
- case Entry::Type::String:
- s.PutCString(entry.string.c_str());
- return true;
+ if (close_paren)
+ s.PutCString(close_paren);
+ else
+ s.PutChar(')');
- case Entry::Type::Scope:
- {
- StreamString scope_stream;
- bool success = false;
- for (const auto &child : entry.children)
- {
- success = Format (child, scope_stream, sc, exe_ctx, addr, valobj, function_changed, initial_function);
- if (!success)
- break;
- }
- // Only if all items in a scope succeed, then do we
- // print the output into the main stream
- if (success)
- s.Write(scope_stream.GetString().data(), scope_stream.GetString().size());
- }
- return true; // Scopes always successfully print themselves
-
- case Entry::Type::Variable:
- case Entry::Type::VariableSynthetic:
- case Entry::Type::ScriptVariable:
- case Entry::Type::ScriptVariableSynthetic:
- return DumpValue(s, sc, exe_ctx, entry, valobj);
-
- case Entry::Type::AddressFile:
- case Entry::Type::AddressLoad:
- case Entry::Type::AddressLoadOrFile:
- return (addr != nullptr && addr->IsValid() &&
- DumpAddress(s, sc, exe_ctx, *addr, entry.type == Entry::Type::AddressLoadOrFile));
-
- case Entry::Type::ProcessID:
- if (exe_ctx)
- {
- Process *process = exe_ctx->GetProcessPtr();
- if (process)
- {
- const char *format = "%" PRIu64;
- if (!entry.printf_format.empty())
- format = entry.printf_format.c_str();
- s.Printf(format, process->GetID());
- return true;
- }
- }
- return false;
-
- case Entry::Type::ProcessFile:
- if (exe_ctx)
- {
- Process *process = exe_ctx->GetProcessPtr();
- if (process)
- {
- Module *exe_module = process->GetTarget().GetExecutableModulePointer();
- if (exe_module)
- {
- if (DumpFile(s, exe_module->GetFileSpec(), (FileKind)entry.number))
- return true;
- }
- }
- }
- return false;
-
- case Entry::Type::ScriptProcess:
- if (exe_ctx)
- {
- Process *process = exe_ctx->GetProcessPtr();
- if (process)
- return RunScriptFormatKeyword (s, sc, exe_ctx, process, entry.string.c_str());
- }
- return false;
-
- case Entry::Type::ThreadID:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- const char *format = "0x%4.4" PRIx64;
- if (!entry.printf_format.empty())
- {
- // 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;
- if ((ostype == llvm::Triple::FreeBSD) || (ostype == llvm::Triple::Linux))
- {
- format = "%" PRIu64;
- }
- }
- else
- {
- format = entry.printf_format.c_str();
- }
- }
- s.Printf(format, thread->GetID());
- return true;
- }
- }
- return false;
-
- case Entry::Type::ThreadProtocolID:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- const char *format = "0x%4.4" PRIx64;
- if (!entry.printf_format.empty())
- format = entry.printf_format.c_str();
- s.Printf(format, thread->GetProtocolID());
- return true;
- }
- }
- return false;
-
- case Entry::Type::ThreadIndexID:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- const char *format = "%" PRIu32;
- if (!entry.printf_format.empty())
- format = entry.printf_format.c_str();
- s.Printf(format, thread->GetIndexID());
- return true;
- }
- }
- return false;
-
- case Entry::Type::ThreadName:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- const char *cstr = thread->GetName();
- if (cstr && cstr[0])
- {
- s.PutCString(cstr);
- return true;
- }
- }
- }
- return false;
-
- case Entry::Type::ThreadQueue:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- const char *cstr = thread->GetQueueName();
- if (cstr && cstr[0])
- {
- s.PutCString(cstr);
- return true;
- }
- }
- }
- return false;
-
- case Entry::Type::ThreadStopReason:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- StopInfoSP stop_info_sp = thread->GetStopInfo ();
- if (stop_info_sp && stop_info_sp->IsValid())
- {
- const char *cstr = stop_info_sp->GetDescription();
- if (cstr && cstr[0])
- {
- s.PutCString(cstr);
- return true;
- }
- }
- }
- }
- return false;
-
- case Entry::Type::ThreadReturnValue:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- StopInfoSP stop_info_sp = thread->GetStopInfo ();
- if (stop_info_sp && stop_info_sp->IsValid())
- {
- ValueObjectSP return_valobj_sp = StopInfo::GetReturnValueObject (stop_info_sp);
- if (return_valobj_sp)
- {
- return_valobj_sp->Dump(s);
- return true;
- }
- }
- }
- }
- return false;
-
- case Entry::Type::ThreadCompletedExpression:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- StopInfoSP stop_info_sp = thread->GetStopInfo ();
- if (stop_info_sp && stop_info_sp->IsValid())
- {
- ExpressionVariableSP expression_var_sp = StopInfo::GetExpressionVariable (stop_info_sp);
- if (expression_var_sp && expression_var_sp->GetValueObject())
- {
- expression_var_sp->GetValueObject()->Dump(s);
- return true;
- }
- }
- }
- }
- return false;
-
- case Entry::Type::ScriptThread:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- return RunScriptFormatKeyword (s, sc, exe_ctx, thread, entry.string.c_str());
- }
- return false;
-
- case Entry::Type::ThreadInfo:
- if (exe_ctx)
- {
- Thread *thread = exe_ctx->GetThreadPtr();
- if (thread)
- {
- StructuredData::ObjectSP object_sp = thread->GetExtendedInfo();
- if (object_sp && object_sp->GetType() == StructuredData::Type::eTypeDictionary)
- {
- if (FormatThreadExtendedInfoRecurse (entry, object_sp, sc, exe_ctx, s))
- return true;
- }
- }
- }
- return false;
-
- case Entry::Type::TargetArch:
- if (exe_ctx)
- {
- Target *target = exe_ctx->GetTargetPtr();
- if (target)
- {
- const ArchSpec &arch = target->GetArchitecture ();
- if (arch.IsValid())
- {
- s.PutCString (arch.GetArchitectureName());
- return true;
- }
- }
- }
- return false;
-
- case Entry::Type::ScriptTarget:
- if (exe_ctx)
- {
- Target *target = exe_ctx->GetTargetPtr();
- if (target)
- return RunScriptFormatKeyword (s, sc, exe_ctx, target, entry.string.c_str());
- }
- return false;
-
- case Entry::Type::ModuleFile:
- if (sc)
- {
- Module *module = sc->module_sp.get();
- if (module)
- {
- if (DumpFile(s, module->GetFileSpec(), (FileKind)entry.number))
- return true;
- }
- }
- return false;
-
- case Entry::Type::File:
- if (sc)
- {
- CompileUnit *cu = sc->comp_unit;
- if (cu)
- {
- // CompileUnit is a FileSpec
- if (DumpFile(s, *cu, (FileKind)entry.number))
- return true;
- }
- }
- return false;
-
- case Entry::Type::Lang:
- if (sc)
- {
- CompileUnit *cu = sc->comp_unit;
- if (cu)
- {
- const char *lang_name = Language::GetNameForLanguageType(cu->GetLanguage());
- if (lang_name)
- {
- s.PutCString(lang_name);
- return true;
- }
- }
- }
- return false;
-
- case Entry::Type::FrameIndex:
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- {
- const char *format = "%" PRIu32;
- if (!entry.printf_format.empty())
- format = entry.printf_format.c_str();
- s.Printf(format, frame->GetFrameIndex());
- return true;
- }
- }
- return false;
-
- case Entry::Type::FrameRegisterPC:
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- {
- const Address &pc_addr = frame->GetFrameCodeAddress();
- if (pc_addr.IsValid())
- {
- if (DumpAddress(s, sc, exe_ctx, pc_addr, false))
- return true;
- }
- }
- }
- return false;
-
- case Entry::Type::FrameRegisterSP:
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- {
- if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, (lldb::Format)entry.number))
- return true;
- }
- }
- return false;
-
- case Entry::Type::FrameRegisterFP:
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- {
- if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, (lldb::Format)entry.number))
- return true;
- }
- }
- return false;
-
- case Entry::Type::FrameRegisterFlags:
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- {
- if (DumpRegister (s, frame, eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS, (lldb::Format)entry.number))
- return true;
- }
- }
- return false;
-
- case Entry::Type::FrameRegisterByName:
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- {
- if (DumpRegister (s, frame, entry.string.c_str(), (lldb::Format)entry.number))
- return true;
- }
- }
- return false;
-
- case Entry::Type::ScriptFrame:
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- return RunScriptFormatKeyword (s, sc, exe_ctx, frame, entry.string.c_str());
- }
- return false;
-
- case Entry::Type::FunctionID:
- if (sc)
- {
- if (sc->function)
- {
- s.Printf("function{0x%8.8" PRIx64 "}", sc->function->GetID());
- return true;
- }
- else if (sc->symbol)
- {
- s.Printf("symbol[%u]", sc->symbol->GetID());
- return true;
- }
- }
- return false;
-
- case Entry::Type::FunctionDidChange:
- return function_changed;
-
- case Entry::Type::FunctionInitialFunction:
- return initial_function;
-
- case Entry::Type::FunctionName:
- {
- 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)
- {
- 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 = nullptr;
- if (sc->function)
- name = sc->function->GetName().AsCString(nullptr);
- else if (sc->symbol)
- name = sc->symbol->GetName().AsCString(nullptr);
- if (name)
- {
- s.PutCString(name);
-
- if (sc->block)
- {
- Block *inline_block = sc->block->GetContainingInlinedBlock ();
- if (inline_block)
- {
- const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
- if (inline_info)
- {
- s.PutCString(" [inlined] ");
- inline_info->GetName(sc->function->GetLanguage()).Dump(&s);
- }
- }
- }
- return true;
- }
- }
- }
- return false;
-
- case Entry::Type::FunctionNameNoArgs:
- {
- 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)
- {
- language_plugin_handled = language_plugin->GetFunctionDisplayName(sc,
- exe_ctx,
- Language::FunctionNameRepresentation::eNameWithNoArgs,
- ss);
- }
- if (language_plugin_handled)
- {
- 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:
- {
- 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)
- {
- 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)
- {
- ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
- const char *cstr = sc->function->GetName().AsCString(nullptr);
- if (cstr)
- {
- const InlineFunctionInfo *inline_info = nullptr;
- 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)
- {
- 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)
- {
- 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
- {
- 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))
- {
- 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=<unavailable>", var_name);
- }
-
- if (close_paren)
- s.PutCString (close_paren);
- else
- s.PutChar(')');
-
- }
- else
- {
- s.PutCString(cstr);
- }
- return true;
- }
- }
- else if (sc->symbol)
- {
- const char *cstr = sc->symbol->GetName().AsCString(nullptr);
- if (cstr)
- {
- s.PutCString(cstr);
- return true;
- }
- }
- }
- }
- return false;
+ } else {
+ s.PutCString(cstr);
+ }
+ return true;
+ }
+ } else if (sc->symbol) {
+ const char *cstr = sc->symbol->GetName().AsCString(nullptr);
+ if (cstr) {
+ s.PutCString(cstr);
+ return true;
+ }
+ }
+ }
+ }
+ return false;
- case Entry::Type::FunctionAddrOffset:
- if (addr)
- {
- if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, false, false, false))
- return true;
- }
- return false;
+ case Entry::Type::FunctionAddrOffset:
+ if (addr) {
+ if (DumpAddressOffsetFromFunction(s, sc, exe_ctx, *addr, false, false,
+ false))
+ return true;
+ }
+ return false;
- case Entry::Type::FunctionAddrOffsetConcrete:
- if (addr)
- {
- if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, *addr, true, true, true))
- return true;
- }
- return false;
-
- case Entry::Type::FunctionLineOffset:
- return (DumpAddressOffsetFromFunction (s, sc, exe_ctx, sc->line_entry.range.GetBaseAddress(), false, false, false));
-
- case Entry::Type::FunctionPCOffset:
- if (exe_ctx)
- {
- StackFrame *frame = exe_ctx->GetFramePtr();
- if (frame)
- {
- if (DumpAddressOffsetFromFunction (s, sc, exe_ctx, frame->GetFrameCodeAddress(), false, false, false))
- return true;
- }
- }
- return false;
+ case Entry::Type::FunctionAddrOffsetConcrete:
+ if (addr) {
+ if (DumpAddressOffsetFromFunction(s, sc, exe_ctx, *addr, true, true,
+ true))
+ return true;
+ }
+ return false;
- case Entry::Type::FunctionChanged:
- return function_changed;
+ case Entry::Type::FunctionLineOffset:
+ return (DumpAddressOffsetFromFunction(s, sc, exe_ctx,
+ sc->line_entry.range.GetBaseAddress(),
+ false, false, false));
+
+ case Entry::Type::FunctionPCOffset:
+ if (exe_ctx) {
+ StackFrame *frame = exe_ctx->GetFramePtr();
+ if (frame) {
+ if (DumpAddressOffsetFromFunction(s, sc, exe_ctx,
+ frame->GetFrameCodeAddress(), false,
+ false, false))
+ return true;
+ }
+ }
+ return false;
- case Entry::Type::FunctionIsOptimized:
- {
- bool is_optimized = false;
- if (sc->function && sc->function->GetIsOptimized())
- {
- is_optimized = true;
- }
- return is_optimized;
- }
+ case Entry::Type::FunctionChanged:
+ return function_changed;
- case Entry::Type::FunctionInitial:
- return initial_function;
-
- case Entry::Type::LineEntryFile:
- if (sc && sc->line_entry.IsValid())
- {
- Module *module = sc->module_sp.get();
- if (module)
- {
- if (DumpFile(s, sc->line_entry.file, (FileKind)entry.number))
- return true;
- }
- }
- return false;
-
- case Entry::Type::LineEntryLineNumber:
- if (sc && sc->line_entry.IsValid())
- {
- const char *format = "%" PRIu32;
- if (!entry.printf_format.empty())
- format = entry.printf_format.c_str();
- s.Printf(format, sc->line_entry.line);
- return true;
- }
- return false;
-
- case Entry::Type::LineEntryStartAddress:
- case Entry::Type::LineEntryEndAddress:
- if (sc && sc->line_entry.range.GetBaseAddress().IsValid())
- {
- Address addr = sc->line_entry.range.GetBaseAddress();
-
- if (entry.type == Entry::Type::LineEntryEndAddress)
- addr.Slide(sc->line_entry.range.GetByteSize());
- if (DumpAddress(s, sc, exe_ctx, addr, false))
- return true;
- }
- return false;
-
- case Entry::Type::CurrentPCArrow:
- if (addr && exe_ctx && exe_ctx->GetFramePtr())
- {
- RegisterContextSP reg_ctx = exe_ctx->GetFramePtr()->GetRegisterContextSP();
- if (reg_ctx)
- {
- addr_t pc_loadaddr = reg_ctx->GetPC();
- if (pc_loadaddr != LLDB_INVALID_ADDRESS)
- {
- Address pc;
- pc.SetLoadAddress (pc_loadaddr, exe_ctx->GetTargetPtr());
- if (pc == *addr)
- {
- s.Printf ("-> ");
- return true;
- }
- }
- }
- s.Printf(" ");
- return true;
- }
- return false;
+ 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;
+
+ case Entry::Type::LineEntryFile:
+ if (sc && sc->line_entry.IsValid()) {
+ Module *module = sc->module_sp.get();
+ if (module) {
+ if (DumpFile(s, sc->line_entry.file, (FileKind)entry.number))
+ return true;
+ }
}
return false;
-}
-static bool
-DumpCommaSeparatedChildEntryNames (Stream &s, const FormatEntity::Entry::Definition *parent)
-{
- if (parent->children)
- {
- const size_t n = parent->num_children;
- for (size_t i = 0; i < n; ++i)
- {
- if (i > 0)
- s.PutCString(", ");
- s.Printf ("\"%s\"", parent->children[i].name);
- }
- return true;
+ case Entry::Type::LineEntryLineNumber:
+ if (sc && sc->line_entry.IsValid()) {
+ const char *format = "%" PRIu32;
+ if (!entry.printf_format.empty())
+ format = entry.printf_format.c_str();
+ s.Printf(format, sc->line_entry.line);
+ return true;
}
return false;
-}
-static Error
-ParseEntry (const llvm::StringRef &format_str,
- const FormatEntity::Entry::Definition *parent,
- FormatEntity::Entry &entry)
-{
- Error error;
+ case Entry::Type::LineEntryStartAddress:
+ case Entry::Type::LineEntryEndAddress:
+ if (sc && sc->line_entry.range.GetBaseAddress().IsValid()) {
+ Address addr = sc->line_entry.range.GetBaseAddress();
- const size_t sep_pos = format_str.find_first_of(".[:");
- const char sep_char = (sep_pos == llvm::StringRef::npos) ? '\0' : format_str[sep_pos];
- llvm::StringRef key = format_str.substr(0, sep_pos);
+ if (entry.type == Entry::Type::LineEntryEndAddress)
+ addr.Slide(sc->line_entry.range.GetByteSize());
+ if (DumpAddress(s, sc, exe_ctx, addr, false))
+ return true;
+ }
+ return false;
- const size_t n = parent->num_children;
- for (size_t i = 0; i < n; ++i)
- {
- const FormatEntity::Entry::Definition *entry_def = parent->children + i;
- if (key.equals(entry_def->name) || entry_def->name[0] == '*')
- {
- llvm::StringRef value;
- if (sep_char)
- value = format_str.substr(sep_pos + (entry_def->keep_separator ? 0 : 1));
- switch (entry_def->type)
- {
- case FormatEntity::Entry::Type::ParentString:
- entry.string = format_str.str();
- return error; // Success
-
- case FormatEntity::Entry::Type::ParentNumber:
- entry.number = entry_def->data;
- return error; // Success
-
- case FormatEntity::Entry::Type::InsertString:
- entry.type = entry_def->type;
- entry.string = entry_def->string;
- return error; // Success
+ case Entry::Type::CurrentPCArrow:
+ if (addr && exe_ctx && exe_ctx->GetFramePtr()) {
+ RegisterContextSP reg_ctx =
+ exe_ctx->GetFramePtr()->GetRegisterContextSP();
+ if (reg_ctx) {
+ addr_t pc_loadaddr = reg_ctx->GetPC();
+ if (pc_loadaddr != LLDB_INVALID_ADDRESS) {
+ Address pc;
+ pc.SetLoadAddress(pc_loadaddr, exe_ctx->GetTargetPtr());
+ if (pc == *addr) {
+ s.Printf("-> ");
+ return true;
+ }
+ }
+ }
+ s.Printf(" ");
+ return true;
+ }
+ return false;
+ }
+ return false;
+}
- default:
- entry.type = entry_def->type;
- break;
- }
+static bool DumpCommaSeparatedChildEntryNames(
+ Stream &s, const FormatEntity::Entry::Definition *parent) {
+ if (parent->children) {
+ const size_t n = parent->num_children;
+ for (size_t i = 0; i < n; ++i) {
+ if (i > 0)
+ s.PutCString(", ");
+ s.Printf("\"%s\"", parent->children[i].name);
+ }
+ return true;
+ }
+ return false;
+}
- if (value.empty())
- {
- if (entry_def->type == FormatEntity::Entry::Type::Invalid)
- {
- if (entry_def->children)
- {
- StreamString error_strm;
- error_strm.Printf("'%s' can't be specified on its own, you must access one of its children: ", entry_def->name);
- DumpCommaSeparatedChildEntryNames (error_strm, entry_def);
- error.SetErrorStringWithFormat("%s", error_strm.GetString().c_str());
- }
- else if (sep_char == ':')
- {
- // 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:}").
- // In this case the string value is the empty string which is ok.
- }
- else
- {
- error.SetErrorStringWithFormat("%s", "invalid entry definitions");
- }
- }
- }
- else
- {
- if (entry_def->children)
- {
- error = ParseEntry (value, entry_def, entry);
- }
- else if (sep_char == ':')
- {
- // 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 = value.str();
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' followed by '%s' but it has no children",
- key.str().c_str(),
- value.str().c_str());
- }
- }
- return error;
+static Error ParseEntry(const llvm::StringRef &format_str,
+ const FormatEntity::Entry::Definition *parent,
+ FormatEntity::Entry &entry) {
+ Error error;
+
+ const size_t sep_pos = format_str.find_first_of(".[:");
+ const char sep_char =
+ (sep_pos == llvm::StringRef::npos) ? '\0' : format_str[sep_pos];
+ llvm::StringRef key = format_str.substr(0, sep_pos);
+
+ const size_t n = parent->num_children;
+ for (size_t i = 0; i < n; ++i) {
+ const FormatEntity::Entry::Definition *entry_def = parent->children + i;
+ if (key.equals(entry_def->name) || entry_def->name[0] == '*') {
+ llvm::StringRef value;
+ if (sep_char)
+ value =
+ format_str.substr(sep_pos + (entry_def->keep_separator ? 0 : 1));
+ switch (entry_def->type) {
+ case FormatEntity::Entry::Type::ParentString:
+ entry.string = format_str.str();
+ return error; // Success
+
+ case FormatEntity::Entry::Type::ParentNumber:
+ entry.number = entry_def->data;
+ return error; // Success
+
+ case FormatEntity::Entry::Type::InsertString:
+ entry.type = entry_def->type;
+ entry.string = entry_def->string;
+ return error; // Success
+
+ default:
+ entry.type = entry_def->type;
+ break;
+ }
+
+ if (value.empty()) {
+ if (entry_def->type == FormatEntity::Entry::Type::Invalid) {
+ if (entry_def->children) {
+ StreamString error_strm;
+ error_strm.Printf("'%s' can't be specified on its own, you must "
+ "access one of its children: ",
+ entry_def->name);
+ DumpCommaSeparatedChildEntryNames(error_strm, entry_def);
+ error.SetErrorStringWithFormat("%s", error_strm.GetData());
+ } else if (sep_char == ':') {
+ // 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:}").
+ // In this case the string value is the empty string which is ok.
+ } else {
+ error.SetErrorStringWithFormat("%s", "invalid entry definitions");
+ }
+ }
+ } else {
+ if (entry_def->children) {
+ error = ParseEntry(value, entry_def, entry);
+ } else if (sep_char == ':') {
+ // 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 = value.str();
+ } else {
+ error.SetErrorStringWithFormat(
+ "'%s' followed by '%s' but it has no children", key.str().c_str(),
+ value.str().c_str());
}
+ }
+ return error;
}
- StreamString error_strm;
- if (parent->type == FormatEntity::Entry::Type::Root)
- error_strm.Printf("invalid top level item '%s'. Valid top level items are: ", key.str().c_str());
- else
- error_strm.Printf("invalid member '%s' in '%s'. Valid members are: ", key.str().c_str(), parent->name);
- DumpCommaSeparatedChildEntryNames (error_strm, parent);
- error.SetErrorStringWithFormat("%s", error_strm.GetString().c_str());
- return error;
+ }
+ StreamString error_strm;
+ if (parent->type == FormatEntity::Entry::Type::Root)
+ error_strm.Printf(
+ "invalid top level item '%s'. Valid top level items are: ",
+ key.str().c_str());
+ else
+ error_strm.Printf("invalid member '%s' in '%s'. Valid members are: ",
+ key.str().c_str(), parent->name);
+ DumpCommaSeparatedChildEntryNames(error_strm, parent);
+ error.SetErrorStringWithFormat("%s", error_strm.GetData());
+ return error;
}
static const FormatEntity::Entry::Definition *
-FindEntry (const llvm::StringRef &format_str, const FormatEntity::Entry::Definition *parent, llvm::StringRef &remainder)
-{
- Error error;
-
- std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split('.');
- const size_t n = parent->num_children;
- for (size_t i = 0; i < n; ++i)
- {
- const FormatEntity::Entry::Definition *entry_def = parent->children + i;
- if (p.first.equals(entry_def->name) || entry_def->name[0] == '*')
- {
- if (p.second.empty())
- {
- if (format_str.back() == '.')
- remainder = format_str.drop_front(format_str.size() - 1);
- else
- remainder = llvm::StringRef(); // Exact match
- return entry_def;
- }
- else
- {
- if (entry_def->children)
- {
- return FindEntry (p.second, entry_def, remainder);
- }
- else
- {
- remainder = p.second;
- return entry_def;
- }
- }
+FindEntry(const llvm::StringRef &format_str,
+ const FormatEntity::Entry::Definition *parent,
+ llvm::StringRef &remainder) {
+ Error error;
+
+ std::pair<llvm::StringRef, llvm::StringRef> p = format_str.split('.');
+ const size_t n = parent->num_children;
+ for (size_t i = 0; i < n; ++i) {
+ const FormatEntity::Entry::Definition *entry_def = parent->children + i;
+ if (p.first.equals(entry_def->name) || entry_def->name[0] == '*') {
+ if (p.second.empty()) {
+ if (format_str.back() == '.')
+ remainder = format_str.drop_front(format_str.size() - 1);
+ else
+ remainder = llvm::StringRef(); // Exact match
+ return entry_def;
+ } else {
+ if (entry_def->children) {
+ return FindEntry(p.second, entry_def, remainder);
+ } else {
+ remainder = p.second;
+ return entry_def;
}
+ }
}
- remainder = format_str;
- return parent;
+ }
+ remainder = format_str;
+ return parent;
}
-Error
-FormatEntity::ParseInternal (llvm::StringRef &format, Entry &parent_entry, uint32_t depth)
-{
- Error error;
- while (!format.empty() && error.Success())
- {
- const size_t non_special_chars = format.find_first_of("${}\\");
+Error FormatEntity::ParseInternal(llvm::StringRef &format, Entry &parent_entry,
+ uint32_t depth) {
+ Error error;
+ while (!format.empty() && error.Success()) {
+ const size_t non_special_chars = format.find_first_of("${}\\");
+
+ if (non_special_chars == llvm::StringRef::npos) {
+ // No special characters, just string bytes so add them and we are done
+ parent_entry.AppendText(format);
+ return error;
+ }
+
+ if (non_special_chars > 0) {
+ // We have a special character, so add all characters before these as a
+ // plain string
+ parent_entry.AppendText(format.substr(0, non_special_chars));
+ format = format.drop_front(non_special_chars);
+ }
- if (non_special_chars == llvm::StringRef::npos)
+ switch (format[0]) {
+ case '\0':
+ return error;
+
+ case '{': {
+ format = format.drop_front(); // Skip the '{'
+ Entry scope_entry(Entry::Type::Scope);
+ error = FormatEntity::ParseInternal(format, scope_entry, depth + 1);
+ if (error.Fail())
+ return error;
+ parent_entry.AppendEntry(std::move(scope_entry));
+ } break;
+
+ case '}':
+ if (depth == 0)
+ error.SetErrorString("unmatched '}' character");
+ else
+ format =
+ format
+ .drop_front(); // Skip the '}' as we are at the end of the scope
+ return error;
+
+ case '\\': {
+ format = format.drop_front(); // Skip the '\' character
+ if (format.empty()) {
+ error.SetErrorString(
+ "'\\' character was not followed by another character");
+ return error;
+ }
+
+ const char desens_char = format[0];
+ format = format.drop_front(); // Skip the desensitized char character
+ switch (desens_char) {
+ case 'a':
+ parent_entry.AppendChar('\a');
+ break;
+ case 'b':
+ parent_entry.AppendChar('\b');
+ break;
+ case 'f':
+ parent_entry.AppendChar('\f');
+ break;
+ case 'n':
+ parent_entry.AppendChar('\n');
+ break;
+ case 'r':
+ parent_entry.AppendChar('\r');
+ break;
+ case 't':
+ parent_entry.AppendChar('\t');
+ break;
+ case 'v':
+ parent_entry.AppendChar('\v');
+ break;
+ case '\'':
+ parent_entry.AppendChar('\'');
+ break;
+ case '\\':
+ parent_entry.AppendChar('\\');
+ break;
+ case '0':
+ // 1 to 3 octal chars
{
- // No special characters, just string bytes so add them and we are done
- parent_entry.AppendText(format);
+ // Make a string that can hold onto the initial zero char,
+ // up to 3 octal digits, and a terminating NULL.
+ char oct_str[5] = {0, 0, 0, 0, 0};
+
+ int i;
+ for (i = 0; (format[i] >= '0' && format[i] <= '7') && i < 4; ++i)
+ oct_str[i] = format[i];
+
+ // We don't want to consume the last octal character since
+ // the main for loop will do this for us, so we advance p by
+ // one less than i (even if i is zero)
+ format = format.drop_front(i);
+ unsigned long octal_value = ::strtoul(oct_str, nullptr, 8);
+ if (octal_value <= UINT8_MAX) {
+ parent_entry.AppendChar((char)octal_value);
+ } else {
+ error.SetErrorString("octal number is larger than a single byte");
return error;
+ }
}
+ break;
- if (non_special_chars > 0)
- {
- // We have a special character, so add all characters before these as a plain string
- parent_entry.AppendText(format.substr(0,non_special_chars));
- format = format.drop_front(non_special_chars);
+ case 'x':
+ // hex number in the format
+ if (isxdigit(format[0])) {
+ // Make a string that can hold onto two hex chars plus a
+ // NULL terminator
+ char hex_str[3] = {0, 0, 0};
+ hex_str[0] = format[0];
+
+ format = format.drop_front();
+
+ if (isxdigit(format[0])) {
+ hex_str[1] = format[0];
+ format = format.drop_front();
+ }
+
+ unsigned long hex_value = strtoul(hex_str, nullptr, 16);
+ if (hex_value <= UINT8_MAX) {
+ parent_entry.AppendChar((char)hex_value);
+ } else {
+ error.SetErrorString("hex number is larger than a single byte");
+ return error;
+ }
+ } else {
+ parent_entry.AppendChar(desens_char);
}
+ break;
- switch (format[0])
- {
- case '\0':
+ default:
+ // Just desensitize any other character by just printing what
+ // came after the '\'
+ parent_entry.AppendChar(desens_char);
+ break;
+ }
+ } break;
+
+ case '$':
+ if (format.size() == 1) {
+ // '$' at the end of a format string, just print the '$'
+ parent_entry.AppendText("$");
+ } else {
+ format = format.drop_front(); // Skip the '$'
+
+ if (format[0] == '{') {
+ format = format.drop_front(); // Skip the '{'
+
+ llvm::StringRef variable, variable_format;
+ error = FormatEntity::ExtractVariableInfo(format, variable,
+ variable_format);
+ if (error.Fail())
+ return error;
+ bool verify_is_thread_id = false;
+ Entry entry;
+ if (!variable_format.empty()) {
+ 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
+ // using "0x%llx" you can use:
+ // ${thread.id%0x%llx}
+ //
+ // If there is no '%' in the format, then it is assumed to be a
+ // LLDB format name, or one of the extended formats specified in
+ // the switch statement below.
+
+ if (entry.printf_format.find('%') == std::string::npos) {
+ bool clear_printf = false;
+
+ if (FormatManager::GetFormatFromCString(
+ entry.printf_format.c_str(), false, entry.fmt)) {
+ // We have an LLDB format, so clear the printf format
+ clear_printf = true;
+ } else if (entry.printf_format.size() == 1) {
+ switch (entry.printf_format[0]) {
+ case '@': // if this is an @ sign, print ObjC description
+ entry.number = ValueObject::
+ eValueObjectRepresentationStyleLanguageSpecific;
+ clear_printf = true;
+ break;
+ case 'V': // if this is a V, print the value using the default
+ // format
+ entry.number =
+ ValueObject::eValueObjectRepresentationStyleValue;
+ clear_printf = true;
+ break;
+ case 'L': // if this is an L, print the location of the value
+ entry.number =
+ ValueObject::eValueObjectRepresentationStyleLocation;
+ clear_printf = true;
+ break;
+ case 'S': // if this is an S, print the summary after all
+ entry.number =
+ ValueObject::eValueObjectRepresentationStyleSummary;
+ clear_printf = true;
+ break;
+ case '#': // if this is a '#', print the number of children
+ entry.number =
+ ValueObject::eValueObjectRepresentationStyleChildrenCount;
+ clear_printf = true;
+ break;
+ case 'T': // if this is a 'T', print the type
+ entry.number =
+ ValueObject::eValueObjectRepresentationStyleType;
+ clear_printf = true;
+ break;
+ case 'N': // if this is a 'N', print the name
+ entry.number =
+ ValueObject::eValueObjectRepresentationStyleName;
+ clear_printf = true;
+ break;
+ case '>': // if this is a '>', print the expression path
+ entry.number = ValueObject::
+ eValueObjectRepresentationStyleExpressionPath;
+ clear_printf = true;
+ break;
+ default:
+ error.SetErrorStringWithFormat("invalid format: '%s'",
+ entry.printf_format.c_str());
+ return error;
+ }
+ } else if (FormatManager::GetFormatFromCString(
+ entry.printf_format.c_str(), true, entry.fmt)) {
+ clear_printf = true;
+ } else if (entry.printf_format == "tid") {
+ verify_is_thread_id = true;
+ } else {
+ error.SetErrorStringWithFormat("invalid format: '%s'",
+ entry.printf_format.c_str());
return error;
+ }
- case '{':
- {
- format = format.drop_front(); // Skip the '{'
- Entry scope_entry(Entry::Type::Scope);
- error = FormatEntity::ParseInternal (format, scope_entry, depth+1);
- if (error.Fail())
- return error;
- parent_entry.AppendEntry(std::move(scope_entry));
- }
- break;
+ // Our format string turned out to not be a printf style format
+ // so lets clear the string
+ if (clear_printf)
+ entry.printf_format.clear();
+ }
+ }
- case '}':
- if (depth == 0)
- error.SetErrorString("unmatched '}' character");
- else
- format = format.drop_front(); // Skip the '}' as we are at the end of the scope
- return error;
+ // Check for dereferences
+ if (variable[0] == '*') {
+ entry.deref = true;
+ variable = variable.drop_front();
+ }
- case '\\':
- {
- format = format.drop_front(); // Skip the '\' character
- if (format.empty())
- {
- error.SetErrorString("'\\' character was not followed by another character");
- return error;
- }
-
- const char desens_char = format[0];
- format = format.drop_front(); // Skip the desensitized char character
- switch (desens_char)
- {
- case 'a': parent_entry.AppendChar('\a'); break;
- case 'b': parent_entry.AppendChar('\b'); break;
- case 'f': parent_entry.AppendChar('\f'); break;
- case 'n': parent_entry.AppendChar('\n'); break;
- case 'r': parent_entry.AppendChar('\r'); break;
- case 't': parent_entry.AppendChar('\t'); break;
- case 'v': parent_entry.AppendChar('\v'); break;
- case '\'': parent_entry.AppendChar('\''); break;
- case '\\': parent_entry.AppendChar('\\'); break;
- case '0':
- // 1 to 3 octal chars
- {
- // Make a string that can hold onto the initial zero char,
- // up to 3 octal digits, and a terminating NULL.
- char oct_str[5] = { 0, 0, 0, 0, 0 };
-
- int i;
- for (i = 0; (format[i] >= '0' && format[i] <= '7') && i < 4; ++i)
- oct_str[i] = format[i];
-
- // We don't want to consume the last octal character since
- // the main for loop will do this for us, so we advance p by
- // one less than i (even if i is zero)
- format = format.drop_front(i);
- unsigned long octal_value = ::strtoul(oct_str, nullptr, 8);
- if (octal_value <= UINT8_MAX)
- {
- parent_entry.AppendChar((char)octal_value);
- }
- else
- {
- error.SetErrorString("octal number is larger than a single byte");
- return error;
- }
- }
- break;
-
- case 'x':
- // hex number in the format
- if (isxdigit(format[0]))
- {
- // Make a string that can hold onto two hex chars plus a
- // NULL terminator
- char hex_str[3] = { 0,0,0 };
- hex_str[0] = format[0];
-
- format = format.drop_front();
-
- if (isxdigit(format[0]))
- {
- hex_str[1] = format[0];
- format = format.drop_front();
- }
-
- unsigned long hex_value = strtoul(hex_str, nullptr, 16);
- if (hex_value <= UINT8_MAX)
- {
- parent_entry.AppendChar((char)hex_value);
- }
- else
- {
- error.SetErrorString("hex number is larger than a single byte");
- return error;
- }
- }
- else
- {
- parent_entry.AppendChar(desens_char);
- }
- break;
-
- default:
- // Just desensitize any other character by just printing what
- // came after the '\'
- parent_entry.AppendChar(desens_char);
- break;
- }
- }
- break;
+ error = ParseEntry(variable, &g_root, entry);
+ if (error.Fail())
+ return error;
- case '$':
- if (format.size() == 1)
- {
- // '$' at the end of a format string, just print the '$'
- parent_entry.AppendText("$");
- }
- else
- {
- format = format.drop_front(); // Skip the '$'
-
- if (format[0] == '{')
- {
- format = format.drop_front(); // Skip the '{'
-
- llvm::StringRef variable, variable_format;
- error = FormatEntity::ExtractVariableInfo (format, variable, variable_format);
- if (error.Fail())
- return error;
- bool verify_is_thread_id = false;
- Entry entry;
- if (!variable_format.empty())
- {
- 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
- // using "0x%llx" you can use:
- // ${thread.id%0x%llx}
- //
- // If there is no '%' in the format, then it is assumed to be a
- // LLDB format name, or one of the extended formats specified in
- // the switch statement below.
-
- if (entry.printf_format.find('%') == std::string::npos)
- {
- bool clear_printf = false;
-
- if (FormatManager::GetFormatFromCString(entry.printf_format.c_str(),
- false,
- entry.fmt))
- {
- // We have an LLDB format, so clear the printf format
- clear_printf = true;
- }
- else if (entry.printf_format.size() == 1)
- {
- switch (entry.printf_format[0])
- {
- case '@': // if this is an @ sign, print ObjC description
- entry.number = ValueObject::eValueObjectRepresentationStyleLanguageSpecific;
- clear_printf = true;
- break;
- case 'V': // if this is a V, print the value using the default format
- entry.number = ValueObject::eValueObjectRepresentationStyleValue;
- clear_printf = true;
- break;
- case 'L': // if this is an L, print the location of the value
- entry.number = ValueObject::eValueObjectRepresentationStyleLocation;
- clear_printf = true;
- break;
- case 'S': // if this is an S, print the summary after all
- entry.number = ValueObject::eValueObjectRepresentationStyleSummary;
- clear_printf = true;
- break;
- case '#': // if this is a '#', print the number of children
- entry.number = ValueObject::eValueObjectRepresentationStyleChildrenCount;
- clear_printf = true;
- break;
- case 'T': // if this is a 'T', print the type
- entry.number = ValueObject::eValueObjectRepresentationStyleType;
- clear_printf = true;
- break;
- case 'N': // if this is a 'N', print the name
- entry.number = ValueObject::eValueObjectRepresentationStyleName;
- clear_printf = true;
- break;
- case '>': // if this is a '>', print the expression path
- entry.number = ValueObject::eValueObjectRepresentationStyleExpressionPath;
- clear_printf = true;
- break;
- default:
- error.SetErrorStringWithFormat("invalid format: '%s'", entry.printf_format.c_str());
- return error;
- }
- }
- else if (FormatManager::GetFormatFromCString(entry.printf_format.c_str(),
- true,
- entry.fmt))
- {
- clear_printf = true;
- }
- else if (entry.printf_format == "tid")
- {
- verify_is_thread_id = true;
- }
- else
- {
- error.SetErrorStringWithFormat("invalid format: '%s'", entry.printf_format.c_str());
- return error;
- }
-
- // Our format string turned out to not be a printf style format
- // so lets clear the string
- if (clear_printf)
- entry.printf_format.clear();
- }
- }
-
- // Check for dereferences
- if (variable[0] == '*')
- {
- entry.deref = true;
- variable = variable.drop_front();
- }
-
- error = ParseEntry (variable, &g_root, entry);
- if (error.Fail())
- return error;
-
- if (verify_is_thread_id)
- {
- if (entry.type != Entry::Type::ThreadID &&
- entry.type != Entry::Type::ThreadProtocolID)
- {
- error.SetErrorString("the 'tid' format can only be used on ${thread.id} and ${thread.protocol_id}");
- }
- }
-
- switch (entry.type)
- {
- case Entry::Type::Variable:
- case Entry::Type::VariableSynthetic:
- if (entry.number == 0)
- {
- if (entry.string.empty())
- entry.number = ValueObject::eValueObjectRepresentationStyleValue;
- else
- entry.number = ValueObject::eValueObjectRepresentationStyleSummary;
- }
- break;
- default:
- // Make sure someone didn't try to dereference anything but ${var} or ${svar}
- if (entry.deref)
- {
- error.SetErrorStringWithFormat("${%s} can't be dereferenced, only ${var} and ${svar} can.", variable.str().c_str());
- return error;
- }
- }
- // Check if this entry just wants to insert a constant string
- // value into the parent_entry, if so, insert the string with
- // AppendText, else append the entry to the parent_entry.
- if (entry.type == Entry::Type::InsertString)
- parent_entry.AppendText(entry.string.c_str());
- else
- parent_entry.AppendEntry(std::move(entry));
- }
- }
- break;
+ if (verify_is_thread_id) {
+ if (entry.type != Entry::Type::ThreadID &&
+ entry.type != Entry::Type::ThreadProtocolID) {
+ error.SetErrorString("the 'tid' format can only be used on "
+ "${thread.id} and ${thread.protocol_id}");
+ }
+ }
+
+ switch (entry.type) {
+ case Entry::Type::Variable:
+ case Entry::Type::VariableSynthetic:
+ if (entry.number == 0) {
+ if (entry.string.empty())
+ entry.number =
+ ValueObject::eValueObjectRepresentationStyleValue;
+ else
+ entry.number =
+ ValueObject::eValueObjectRepresentationStyleSummary;
+ }
+ break;
+ default:
+ // Make sure someone didn't try to dereference anything but ${var}
+ // or ${svar}
+ if (entry.deref) {
+ error.SetErrorStringWithFormat(
+ "${%s} can't be dereferenced, only ${var} and ${svar} can.",
+ variable.str().c_str());
+ return error;
+ }
+ }
+ // Check if this entry just wants to insert a constant string
+ // value into the parent_entry, if so, insert the string with
+ // AppendText, else append the entry to the parent_entry.
+ if (entry.type == Entry::Type::InsertString)
+ parent_entry.AppendText(entry.string.c_str());
+ else
+ parent_entry.AppendEntry(std::move(entry));
}
+ }
+ break;
}
- return error;
+ }
+ return error;
}
-Error
-FormatEntity::ExtractVariableInfo (llvm::StringRef &format_str, llvm::StringRef &variable_name, llvm::StringRef &variable_format)
-{
- Error error;
- variable_name = llvm::StringRef();
- variable_format = llvm::StringRef();
-
- const size_t paren_pos = format_str.find('}');
- if (paren_pos != llvm::StringRef::npos)
- {
- const size_t percent_pos = format_str.find('%');
- if (percent_pos < paren_pos)
- {
- if (percent_pos > 0)
- {
- if (percent_pos > 1)
- variable_name = format_str.substr(0, percent_pos);
- variable_format = format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
- }
- }
- else
- {
- variable_name = format_str.substr(0, paren_pos);
- }
- // Strip off elements and the formatting and the trailing '}'
- format_str = format_str.substr(paren_pos + 1);
+Error FormatEntity::ExtractVariableInfo(llvm::StringRef &format_str,
+ llvm::StringRef &variable_name,
+ llvm::StringRef &variable_format) {
+ Error error;
+ variable_name = llvm::StringRef();
+ variable_format = llvm::StringRef();
+
+ const size_t paren_pos = format_str.find('}');
+ if (paren_pos != llvm::StringRef::npos) {
+ const size_t percent_pos = format_str.find('%');
+ if (percent_pos < paren_pos) {
+ if (percent_pos > 0) {
+ if (percent_pos > 1)
+ variable_name = format_str.substr(0, percent_pos);
+ variable_format =
+ format_str.substr(percent_pos + 1, paren_pos - (percent_pos + 1));
+ }
+ } else {
+ variable_name = format_str.substr(0, paren_pos);
}
- else
- {
- error.SetErrorStringWithFormat("missing terminating '}' character for '${%s'", format_str.str().c_str());
- }
- return error;
+ // Strip off elements and the formatting and the trailing '}'
+ format_str = format_str.substr(paren_pos + 1);
+ } else {
+ error.SetErrorStringWithFormat(
+ "missing terminating '}' character for '${%s'",
+ format_str.str().c_str());
+ }
+ return error;
}
-bool
-FormatEntity::FormatFileSpec (const FileSpec &file_spec, Stream &s, llvm::StringRef variable_name, llvm::StringRef variable_format)
-{
- if (variable_name.empty() || variable_name.equals(".fullpath"))
- {
- file_spec.Dump(&s);
- return true;
- }
- else if (variable_name.equals(".basename"))
- {
- s.PutCString(file_spec.GetFilename().AsCString(""));
- return true;
- }
- else if (variable_name.equals(".dirname"))
- {
- s.PutCString(file_spec.GetFilename().AsCString(""));
- return true;
- }
- return false;
+bool FormatEntity::FormatFileSpec(const FileSpec &file_spec, Stream &s,
+ llvm::StringRef variable_name,
+ llvm::StringRef variable_format) {
+ if (variable_name.empty() || variable_name.equals(".fullpath")) {
+ file_spec.Dump(&s);
+ return true;
+ } else if (variable_name.equals(".basename")) {
+ s.PutCString(file_spec.GetFilename().AsCString(""));
+ return true;
+ } else if (variable_name.equals(".dirname")) {
+ s.PutCString(file_spec.GetFilename().AsCString(""));
+ return true;
+ }
+ return false;
}
-static std::string
-MakeMatch (const llvm::StringRef &prefix, const char *suffix)
-{
- std::string match(prefix.str());
- match.append(suffix);
- return match;
+static std::string MakeMatch(const llvm::StringRef &prefix,
+ const char *suffix) {
+ std::string match(prefix.str());
+ match.append(suffix);
+ return match;
}
-static void
-AddMatches (const FormatEntity::Entry::Definition *def,
- const llvm::StringRef &prefix,
- const llvm::StringRef &match_prefix,
- StringList &matches)
-{
- const size_t n = def->num_children;
- if (n > 0)
- {
- for (size_t i = 0; i < n; ++i)
- {
- 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)
- matches.AppendString(MakeMatch (prefix, def->children[i].name + match_prefix.size()));
- }
+static void AddMatches(const FormatEntity::Entry::Definition *def,
+ const llvm::StringRef &prefix,
+ const llvm::StringRef &match_prefix,
+ StringList &matches) {
+ const size_t n = def->num_children;
+ if (n > 0) {
+ for (size_t i = 0; i < n; ++i) {
+ 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)
+ matches.AppendString(
+ MakeMatch(prefix, def->children[i].name + match_prefix.size()));
}
+ }
}
-size_t
-FormatEntity::AutoComplete (const char *s,
- int match_start_point,
- int max_return_elements,
- bool &word_complete,
- StringList &matches)
-{
- word_complete = false;
- llvm::StringRef str(s + match_start_point);
- matches.Clear();
-
- const size_t dollar_pos = str.rfind('$');
- if (dollar_pos != llvm::StringRef::npos)
- {
- // Hitting TAB after $ at the end of the string add a "{"
- if (dollar_pos == str.size() - 1)
- {
- std::string match = str.str();
- match.append("{");
- matches.AppendString(std::move(match));
- }
- else if (str[dollar_pos + 1] == '{')
- {
- const size_t close_pos = str.find('}', dollar_pos + 2);
- if (close_pos == llvm::StringRef::npos)
- {
- const size_t format_pos = str.find('%', dollar_pos + 2);
- if (format_pos == llvm::StringRef::npos)
- {
- llvm::StringRef partial_variable (str.substr(dollar_pos + 2));
- if (partial_variable.empty())
- {
- // Suggest all top level entites as we are just past "${"
- AddMatches(&g_root, str, llvm::StringRef(), matches);
- }
- else
- {
- // We have a partially specified variable, find it
- llvm::StringRef remainder;
- const FormatEntity::Entry::Definition* entry_def = FindEntry (partial_variable, &g_root, remainder);
- if (entry_def)
- {
- const size_t n = entry_def->num_children;
-
- if (remainder.empty())
- {
- // Exact match
- if (n > 0)
- {
- // "${thread.info" <TAB>
- matches.AppendString(MakeMatch(str, "."));
- }
- else
- {
- // "${thread.id" <TAB>
- matches.AppendString(MakeMatch (str, "}"));
- word_complete = true;
- }
- }
- else if (remainder.equals("."))
- {
- // "${thread." <TAB>
- AddMatches(entry_def, str, llvm::StringRef(), matches);
- }
- else
- {
- // We have a partial match
- // "${thre" <TAB>
- AddMatches(entry_def, str, remainder, matches);
- }
- }
- }
- }
- }
- }
- }
+size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
+ int max_return_elements, bool &word_complete,
+ StringList &matches) {
+ word_complete = false;
+ str = str.drop_front(match_start_point);
+ matches.Clear();
+
+ const size_t dollar_pos = str.rfind('$');
+ if (dollar_pos == llvm::StringRef::npos)
+ return 0;
+
+ // Hitting TAB after $ at the end of the string add a "{"
+ if (dollar_pos == str.size() - 1) {
+ std::string match = str.str();
+ match.append("{");
+ matches.AppendString(match);
+ return 1;
+ }
+
+ if (str[dollar_pos + 1] != '{')
+ return 0;
+
+ const size_t close_pos = str.find('}', dollar_pos + 2);
+ if (close_pos != llvm::StringRef::npos)
+ return 0;
+
+ const size_t format_pos = str.find('%', dollar_pos + 2);
+ if (format_pos != llvm::StringRef::npos)
+ return 0;
+
+ llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
+ if (partial_variable.empty()) {
+ // Suggest all top level entites as we are just past "${"
+ AddMatches(&g_root, str, llvm::StringRef(), matches);
return matches.GetSize();
+ }
+
+ // We have a partially specified variable, find it
+ llvm::StringRef remainder;
+ const FormatEntity::Entry::Definition *entry_def =
+ FindEntry(partial_variable, &g_root, remainder);
+ if (!entry_def)
+ return 0;
+
+ const size_t n = entry_def->num_children;
+
+ if (remainder.empty()) {
+ // Exact match
+ if (n > 0) {
+ // "${thread.info" <TAB>
+ matches.AppendString(MakeMatch(str, "."));
+ } else {
+ // "${thread.id" <TAB>
+ matches.AppendString(MakeMatch(str, "}"));
+ word_complete = true;
+ }
+ } else if (remainder.equals(".")) {
+ // "${thread." <TAB>
+ AddMatches(entry_def, str, llvm::StringRef(), matches);
+ } else {
+ // We have a partial match
+ // "${thre" <TAB>
+ AddMatches(entry_def, str, remainder, matches);
+ }
+ return matches.GetSize();
}
diff --git a/source/Core/History.cpp b/source/Core/History.cpp
index 0105dce730d2..0466a83da519 100644
--- a/source/Core/History.cpp
+++ b/source/Core/History.cpp
@@ -19,8 +19,6 @@
using namespace lldb;
using namespace lldb_private;
-void
-HistorySourceUInt::DumpHistoryEvent (Stream &strm, HistoryEvent event)
-{
- strm.Printf ("%s %" PRIu64, m_name.c_str(), (uint64_t)((uintptr_t)event));
+void HistorySourceUInt::DumpHistoryEvent(Stream &strm, HistoryEvent event) {
+ strm.Printf("%s %" PRIu64, m_name.c_str(), (uint64_t)((uintptr_t)event));
}
diff --git a/source/Core/IOHandler.cpp b/source/Core/IOHandler.cpp
index bab0263a0c6e..9c5e6ca80c20 100644
--- a/source/Core/IOHandler.cpp
+++ b/source/Core/IOHandler.cpp
@@ -22,8 +22,8 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointLocation.h"
-#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/Core/IOHandler.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/State.h"
#include "lldb/Core/StreamFile.h"
@@ -41,10 +41,10 @@
#ifndef LLDB_DISABLE_CURSES
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/VariableList.h"
-#include "lldb/Target/Target.h"
#include "lldb/Target/Process.h"
-#include "lldb/Target/Thread.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
#endif
#ifdef _MSC_VER
@@ -54,771 +54,584 @@
using namespace lldb;
using namespace lldb_private;
-IOHandler::IOHandler (Debugger &debugger, IOHandler::Type type) :
- IOHandler (debugger,
- type,
- StreamFileSP(), // Adopt STDIN from top input reader
- StreamFileSP(), // Adopt STDOUT from top input reader
- StreamFileSP(), // Adopt STDERR from top input reader
- 0) // Flags
-{
-}
-
-IOHandler::IOHandler (Debugger &debugger,
- IOHandler::Type type,
- const lldb::StreamFileSP &input_sp,
- const lldb::StreamFileSP &output_sp,
- const lldb::StreamFileSP &error_sp,
- uint32_t flags) :
- m_debugger (debugger),
- m_input_sp (input_sp),
- m_output_sp (output_sp),
- m_error_sp (error_sp),
- m_popped (false),
- m_flags (flags),
- m_type (type),
- m_user_data(nullptr),
- m_done (false),
- m_active (false)
-{
- // If any files are not specified, then adopt them from the top input reader.
- if (!m_input_sp || !m_output_sp || !m_error_sp)
- debugger.AdoptTopIOHandlerFilesIfInvalid (m_input_sp,
- m_output_sp,
- m_error_sp);
+IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type)
+ : IOHandler(debugger, type,
+ StreamFileSP(), // Adopt STDIN from top input reader
+ StreamFileSP(), // Adopt STDOUT from top input reader
+ StreamFileSP(), // Adopt STDERR from top input reader
+ 0) // Flags
+{}
+
+IOHandler::IOHandler(Debugger &debugger, IOHandler::Type type,
+ const lldb::StreamFileSP &input_sp,
+ const lldb::StreamFileSP &output_sp,
+ const lldb::StreamFileSP &error_sp, uint32_t flags)
+ : m_debugger(debugger), m_input_sp(input_sp), m_output_sp(output_sp),
+ m_error_sp(error_sp), m_popped(false), m_flags(flags), m_type(type),
+ m_user_data(nullptr), m_done(false), m_active(false) {
+ // If any files are not specified, then adopt them from the top input reader.
+ if (!m_input_sp || !m_output_sp || !m_error_sp)
+ debugger.AdoptTopIOHandlerFilesIfInvalid(m_input_sp, m_output_sp,
+ m_error_sp);
}
IOHandler::~IOHandler() = default;
-int
-IOHandler::GetInputFD()
-{
- return (m_input_sp ? m_input_sp->GetFile().GetDescriptor() : -1);
+int IOHandler::GetInputFD() {
+ return (m_input_sp ? m_input_sp->GetFile().GetDescriptor() : -1);
}
-int
-IOHandler::GetOutputFD()
-{
- return (m_output_sp ? m_output_sp->GetFile().GetDescriptor() : -1);
+int IOHandler::GetOutputFD() {
+ return (m_output_sp ? m_output_sp->GetFile().GetDescriptor() : -1);
}
-int
-IOHandler::GetErrorFD()
-{
- return (m_error_sp ? m_error_sp->GetFile().GetDescriptor() : -1);
+int IOHandler::GetErrorFD() {
+ return (m_error_sp ? m_error_sp->GetFile().GetDescriptor() : -1);
}
-FILE *
-IOHandler::GetInputFILE()
-{
- return (m_input_sp ? m_input_sp->GetFile().GetStream() : nullptr);
+FILE *IOHandler::GetInputFILE() {
+ return (m_input_sp ? m_input_sp->GetFile().GetStream() : nullptr);
}
-FILE *
-IOHandler::GetOutputFILE()
-{
- return (m_output_sp ? m_output_sp->GetFile().GetStream() : nullptr);
+FILE *IOHandler::GetOutputFILE() {
+ return (m_output_sp ? m_output_sp->GetFile().GetStream() : nullptr);
}
-FILE *
-IOHandler::GetErrorFILE()
-{
- return (m_error_sp ? m_error_sp->GetFile().GetStream() : nullptr);
+FILE *IOHandler::GetErrorFILE() {
+ return (m_error_sp ? m_error_sp->GetFile().GetStream() : nullptr);
}
-StreamFileSP &
-IOHandler::GetInputStreamFile()
-{
- return m_input_sp;
-}
+StreamFileSP &IOHandler::GetInputStreamFile() { return m_input_sp; }
-StreamFileSP &
-IOHandler::GetOutputStreamFile()
-{
- return m_output_sp;
-}
+StreamFileSP &IOHandler::GetOutputStreamFile() { return m_output_sp; }
-StreamFileSP &
-IOHandler::GetErrorStreamFile()
-{
- return m_error_sp;
-}
+StreamFileSP &IOHandler::GetErrorStreamFile() { return m_error_sp; }
-bool
-IOHandler::GetIsInteractive ()
-{
- return GetInputStreamFile()->GetFile().GetIsInteractive ();
+bool IOHandler::GetIsInteractive() {
+ return GetInputStreamFile()->GetFile().GetIsInteractive();
}
-bool
-IOHandler::GetIsRealTerminal ()
-{
- return GetInputStreamFile()->GetFile().GetIsRealTerminal();
+bool IOHandler::GetIsRealTerminal() {
+ return GetInputStreamFile()->GetFile().GetIsRealTerminal();
}
-void
-IOHandler::SetPopped (bool b)
-{
- m_popped.SetValue(b, eBroadcastOnChange);
-}
+void IOHandler::SetPopped(bool b) { m_popped.SetValue(b, eBroadcastOnChange); }
-void
-IOHandler::WaitForPop ()
-{
- m_popped.WaitForValueEqualTo(true);
-}
+void IOHandler::WaitForPop() { m_popped.WaitForValueEqualTo(true); }
-void
-IOHandlerStack::PrintAsync(Stream *stream, const char *s, size_t len)
-{
- if (stream)
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (m_top)
- m_top->PrintAsync(stream, s, len);
- }
+void IOHandlerStack::PrintAsync(Stream *stream, const char *s, size_t len) {
+ if (stream) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (m_top)
+ m_top->PrintAsync(stream, s, len);
+ }
}
-IOHandlerConfirm::IOHandlerConfirm (Debugger &debugger,
- const char *prompt,
- bool default_response) :
- IOHandlerEditline(debugger,
- IOHandler::Type::Confirm,
- nullptr, // nullptr editline_name means no history loaded/saved
- nullptr, // No prompt
- nullptr, // No continuation prompt
- false, // Multi-line
- false, // Don't colorize the prompt (i.e. the confirm message.)
- 0,
- *this),
- m_default_response (default_response),
- m_user_response (default_response)
-{
- StreamString prompt_stream;
- prompt_stream.PutCString(prompt);
- if (m_default_response)
- prompt_stream.Printf(": [Y/n] ");
- else
- prompt_stream.Printf(": [y/N] ");
-
- SetPrompt (prompt_stream.GetString().c_str());
+IOHandlerConfirm::IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt,
+ bool default_response)
+ : IOHandlerEditline(
+ debugger, IOHandler::Type::Confirm,
+ nullptr, // nullptr editline_name means no history loaded/saved
+ llvm::StringRef(), // No prompt
+ llvm::StringRef(), // No continuation prompt
+ false, // Multi-line
+ false, // Don't colorize the prompt (i.e. the confirm message.)
+ 0, *this),
+ m_default_response(default_response), m_user_response(default_response) {
+ StreamString prompt_stream;
+ prompt_stream.PutCString(prompt);
+ if (m_default_response)
+ prompt_stream.Printf(": [Y/n] ");
+ else
+ prompt_stream.Printf(": [y/N] ");
+
+ SetPrompt(prompt_stream.GetString());
}
IOHandlerConfirm::~IOHandlerConfirm() = default;
-int
-IOHandlerConfirm::IOHandlerComplete (IOHandler &io_handler,
- const char *current_line,
- const char *cursor,
- const char *last_char,
- int skip_first_n_matches,
- int max_matches,
- StringList &matches)
-{
- if (current_line == cursor)
- {
- if (m_default_response)
- {
- matches.AppendString("y");
- }
- else
- {
- matches.AppendString("n");
- }
+int IOHandlerConfirm::IOHandlerComplete(IOHandler &io_handler,
+ const char *current_line,
+ const char *cursor,
+ const char *last_char,
+ int skip_first_n_matches,
+ int max_matches, StringList &matches) {
+ if (current_line == cursor) {
+ if (m_default_response) {
+ matches.AppendString("y");
+ } else {
+ matches.AppendString("n");
}
- return matches.GetSize();
+ }
+ return matches.GetSize();
}
-void
-IOHandlerConfirm::IOHandlerInputComplete (IOHandler &io_handler, std::string &line)
-{
- if (line.empty())
- {
- // User just hit enter, set the response to the default
- m_user_response = m_default_response;
- io_handler.SetIsDone(true);
- return;
- }
-
- if (line.size() == 1)
- {
- switch (line[0])
- {
- case 'y':
- case 'Y':
- m_user_response = true;
- io_handler.SetIsDone(true);
- return;
- case 'n':
- case 'N':
- m_user_response = false;
- io_handler.SetIsDone(true);
- return;
- default:
- break;
- }
- }
-
- if (line == "yes" || line == "YES" || line == "Yes")
- {
- m_user_response = true;
- io_handler.SetIsDone(true);
- }
- else if (line == "no" || line == "NO" || line == "No")
- {
- m_user_response = false;
- io_handler.SetIsDone(true);
+void IOHandlerConfirm::IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &line) {
+ if (line.empty()) {
+ // User just hit enter, set the response to the default
+ m_user_response = m_default_response;
+ io_handler.SetIsDone(true);
+ return;
+ }
+
+ if (line.size() == 1) {
+ switch (line[0]) {
+ case 'y':
+ case 'Y':
+ m_user_response = true;
+ io_handler.SetIsDone(true);
+ return;
+ case 'n':
+ case 'N':
+ m_user_response = false;
+ io_handler.SetIsDone(true);
+ return;
+ default:
+ break;
}
+ }
+
+ if (line == "yes" || line == "YES" || line == "Yes") {
+ m_user_response = true;
+ io_handler.SetIsDone(true);
+ } else if (line == "no" || line == "NO" || line == "No") {
+ m_user_response = false;
+ io_handler.SetIsDone(true);
+ }
}
-int
-IOHandlerDelegate::IOHandlerComplete (IOHandler &io_handler,
- const char *current_line,
- const char *cursor,
- const char *last_char,
- int skip_first_n_matches,
- int max_matches,
- StringList &matches)
-{
- switch (m_completion)
- {
- case Completion::None:
- break;
-
- case Completion::LLDBCommand:
- return io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion (current_line,
- cursor,
- last_char,
- skip_first_n_matches,
- max_matches,
- matches);
-
- case Completion::Expression:
- {
- bool word_complete = false;
- const char *word_start = cursor;
- if (cursor > current_line)
- --word_start;
- while (word_start > current_line && !isspace(*word_start))
- --word_start;
- CommandCompletions::InvokeCommonCompletionCallbacks(io_handler.GetDebugger().GetCommandInterpreter(),
- CommandCompletions::eVariablePathCompletion,
- word_start,
- skip_first_n_matches,
- max_matches,
- nullptr,
- word_complete,
- matches);
-
- size_t num_matches = matches.GetSize();
- if (num_matches > 0)
- {
- std::string common_prefix;
- matches.LongestCommonPrefix (common_prefix);
- const size_t partial_name_len = strlen(word_start);
-
- // If we matched a unique single command, add a space...
- // Only do this if the completer told us this was a complete word, however...
- if (num_matches == 1 && word_complete)
- {
- common_prefix.push_back(' ');
- }
- common_prefix.erase (0, partial_name_len);
- matches.InsertStringAtIndex(0, std::move(common_prefix));
- }
- return num_matches;
- }
- break;
+int IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler,
+ const char *current_line,
+ const char *cursor,
+ const char *last_char,
+ int skip_first_n_matches,
+ int max_matches, StringList &matches) {
+ switch (m_completion) {
+ case Completion::None:
+ break;
+
+ case Completion::LLDBCommand:
+ return io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion(
+ current_line, cursor, last_char, skip_first_n_matches, max_matches,
+ matches);
+
+ case Completion::Expression: {
+ bool word_complete = false;
+ const char *word_start = cursor;
+ if (cursor > current_line)
+ --word_start;
+ while (word_start > current_line && !isspace(*word_start))
+ --word_start;
+ CommandCompletions::InvokeCommonCompletionCallbacks(
+ io_handler.GetDebugger().GetCommandInterpreter(),
+ CommandCompletions::eVariablePathCompletion, word_start,
+ skip_first_n_matches, max_matches, nullptr, word_complete, matches);
+
+ size_t num_matches = matches.GetSize();
+ if (num_matches > 0) {
+ std::string common_prefix;
+ matches.LongestCommonPrefix(common_prefix);
+ const size_t partial_name_len = strlen(word_start);
+
+ // If we matched a unique single command, add a space...
+ // Only do this if the completer told us this was a complete word,
+ // however...
+ if (num_matches == 1 && word_complete) {
+ common_prefix.push_back(' ');
+ }
+ common_prefix.erase(0, partial_name_len);
+ matches.InsertStringAtIndex(0, std::move(common_prefix));
}
-
- return 0;
-}
+ return num_matches;
+ } break;
+ }
-IOHandlerEditline::IOHandlerEditline (Debugger &debugger,
- IOHandler::Type type,
- const char *editline_name, // Used for saving history files
- const char *prompt,
- const char *continuation_prompt,
- bool multi_line,
- bool color_prompts,
- uint32_t line_number_start,
- IOHandlerDelegate &delegate) :
- IOHandlerEditline(debugger,
- type,
- StreamFileSP(), // Inherit input from top input reader
- StreamFileSP(), // Inherit output from top input reader
- StreamFileSP(), // Inherit error from top input reader
- 0, // Flags
- editline_name, // Used for saving history files
- prompt,
- continuation_prompt,
- multi_line,
- color_prompts,
- line_number_start,
- delegate)
-{
+ return 0;
}
-IOHandlerEditline::IOHandlerEditline (Debugger &debugger,
- IOHandler::Type type,
- const lldb::StreamFileSP &input_sp,
- const lldb::StreamFileSP &output_sp,
- const lldb::StreamFileSP &error_sp,
- uint32_t flags,
- const char *editline_name, // Used for saving history files
- const char *prompt,
- const char *continuation_prompt,
- bool multi_line,
- bool color_prompts,
- uint32_t line_number_start,
- IOHandlerDelegate &delegate) :
- IOHandler (debugger, type, input_sp, output_sp, error_sp, flags),
+IOHandlerEditline::IOHandlerEditline(
+ Debugger &debugger, IOHandler::Type type,
+ const char *editline_name, // Used for saving history files
+ llvm::StringRef prompt, llvm::StringRef continuation_prompt,
+ bool multi_line, bool color_prompts, uint32_t line_number_start,
+ IOHandlerDelegate &delegate)
+ : IOHandlerEditline(debugger, type,
+ StreamFileSP(), // Inherit input from top input reader
+ StreamFileSP(), // Inherit output from top input reader
+ StreamFileSP(), // Inherit error from top input reader
+ 0, // Flags
+ editline_name, // Used for saving history files
+ prompt, continuation_prompt, multi_line, color_prompts,
+ line_number_start, delegate) {}
+
+IOHandlerEditline::IOHandlerEditline(
+ Debugger &debugger, IOHandler::Type type,
+ const lldb::StreamFileSP &input_sp, const lldb::StreamFileSP &output_sp,
+ const lldb::StreamFileSP &error_sp, uint32_t flags,
+ const char *editline_name, // Used for saving history files
+ llvm::StringRef prompt, llvm::StringRef continuation_prompt,
+ bool multi_line, bool color_prompts, uint32_t line_number_start,
+ IOHandlerDelegate &delegate)
+ : IOHandler(debugger, type, input_sp, output_sp, error_sp, flags),
#ifndef LLDB_DISABLE_LIBEDIT
- m_editline_ap (),
+ m_editline_ap(),
#endif
- m_delegate (delegate),
- m_prompt (),
- m_continuation_prompt(),
- m_current_lines_ptr(nullptr),
- m_base_line_number (line_number_start),
- m_curr_line_idx (UINT32_MAX),
- m_multi_line (multi_line),
- m_color_prompts (color_prompts),
- m_interrupt_exits (true),
- m_editing (false)
-{
- SetPrompt(prompt);
+ m_delegate(delegate), m_prompt(), m_continuation_prompt(),
+ m_current_lines_ptr(nullptr), m_base_line_number(line_number_start),
+ m_curr_line_idx(UINT32_MAX), m_multi_line(multi_line),
+ m_color_prompts(color_prompts), m_interrupt_exits(true),
+ m_editing(false) {
+ SetPrompt(prompt);
#ifndef LLDB_DISABLE_LIBEDIT
- bool use_editline = false;
-
- use_editline = m_input_sp->GetFile().GetIsRealTerminal();
-
- if (use_editline)
- {
- m_editline_ap.reset(new Editline (editline_name,
- GetInputFILE (),
- GetOutputFILE (),
- GetErrorFILE (),
- m_color_prompts));
- m_editline_ap->SetIsInputCompleteCallback (IsInputCompleteCallback, this);
- m_editline_ap->SetAutoCompleteCallback (AutoCompleteCallback, this);
- // See if the delegate supports fixing indentation
- const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();
- if (indent_chars)
- {
- // The delegate does support indentation, hook it up so when any indentation
- // character is typed, the delegate gets a chance to fix it
- m_editline_ap->SetFixIndentationCallback (FixIndentationCallback, this, indent_chars);
- }
+ bool use_editline = false;
+
+ use_editline = m_input_sp->GetFile().GetIsRealTerminal();
+
+ if (use_editline) {
+ m_editline_ap.reset(new Editline(editline_name, GetInputFILE(),
+ GetOutputFILE(), GetErrorFILE(),
+ m_color_prompts));
+ m_editline_ap->SetIsInputCompleteCallback(IsInputCompleteCallback, this);
+ m_editline_ap->SetAutoCompleteCallback(AutoCompleteCallback, this);
+ // See if the delegate supports fixing indentation
+ const char *indent_chars = delegate.IOHandlerGetFixIndentationCharacters();
+ if (indent_chars) {
+ // The delegate does support indentation, hook it up so when any
+ // indentation
+ // character is typed, the delegate gets a chance to fix it
+ m_editline_ap->SetFixIndentationCallback(FixIndentationCallback, this,
+ indent_chars);
}
+ }
#endif
- SetBaseLineNumber (m_base_line_number);
- SetPrompt(prompt ? prompt : "");
- SetContinuationPrompt(continuation_prompt);
+ SetBaseLineNumber(m_base_line_number);
+ SetPrompt(prompt);
+ SetContinuationPrompt(continuation_prompt);
}
-IOHandlerEditline::~IOHandlerEditline ()
-{
+IOHandlerEditline::~IOHandlerEditline() {
#ifndef LLDB_DISABLE_LIBEDIT
- m_editline_ap.reset();
+ m_editline_ap.reset();
#endif
}
-void
-IOHandlerEditline::Activate ()
-{
- IOHandler::Activate();
- m_delegate.IOHandlerActivated(*this);
+void IOHandlerEditline::Activate() {
+ IOHandler::Activate();
+ m_delegate.IOHandlerActivated(*this);
}
-void
-IOHandlerEditline::Deactivate ()
-{
- IOHandler::Deactivate();
- m_delegate.IOHandlerDeactivated(*this);
+void IOHandlerEditline::Deactivate() {
+ IOHandler::Deactivate();
+ m_delegate.IOHandlerDeactivated(*this);
}
-bool
-IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
-{
+bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) {
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- {
- return m_editline_ap->GetLine (line, interrupted);
- }
- else
- {
+ if (m_editline_ap) {
+ return m_editline_ap->GetLine(line, interrupted);
+ } else {
#endif
- line.clear();
-
- FILE *in = GetInputFILE();
- if (in)
- {
- if (GetIsInteractive())
- {
- const char *prompt = nullptr;
-
- if (m_multi_line && m_curr_line_idx > 0)
- prompt = GetContinuationPrompt();
-
- if (prompt == nullptr)
- prompt = GetPrompt();
-
- if (prompt && prompt[0])
- {
- FILE *out = GetOutputFILE();
- if (out)
- {
- ::fprintf(out, "%s", prompt);
- ::fflush(out);
- }
- }
- }
- char buffer[256];
- bool done = false;
- bool got_line = false;
- m_editing = true;
- while (!done)
- {
- if (fgets(buffer, sizeof(buffer), in) == nullptr)
- {
- const int saved_errno = errno;
- if (feof(in))
- done = true;
- else if (ferror(in))
- {
- if (saved_errno != EINTR)
- done = true;
- }
- }
- else
- {
- got_line = true;
- size_t buffer_len = strlen(buffer);
- assert (buffer[buffer_len] == '\0');
- char last_char = buffer[buffer_len-1];
- if (last_char == '\r' || last_char == '\n')
- {
- done = true;
- // Strip trailing newlines
- while (last_char == '\r' || last_char == '\n')
- {
- --buffer_len;
- if (buffer_len == 0)
- break;
- last_char = buffer[buffer_len-1];
- }
- }
- line.append(buffer, buffer_len);
- }
+ line.clear();
+
+ FILE *in = GetInputFILE();
+ if (in) {
+ if (GetIsInteractive()) {
+ const char *prompt = nullptr;
+
+ if (m_multi_line && m_curr_line_idx > 0)
+ prompt = GetContinuationPrompt();
+
+ if (prompt == nullptr)
+ prompt = GetPrompt();
+
+ if (prompt && prompt[0]) {
+ FILE *out = GetOutputFILE();
+ if (out) {
+ ::fprintf(out, "%s", prompt);
+ ::fflush(out);
+ }
+ }
+ }
+ char buffer[256];
+ bool done = false;
+ bool got_line = false;
+ m_editing = true;
+ while (!done) {
+ if (fgets(buffer, sizeof(buffer), in) == nullptr) {
+ const int saved_errno = errno;
+ if (feof(in))
+ done = true;
+ else if (ferror(in)) {
+ if (saved_errno != EINTR)
+ done = true;
+ }
+ } else {
+ got_line = true;
+ size_t buffer_len = strlen(buffer);
+ assert(buffer[buffer_len] == '\0');
+ char last_char = buffer[buffer_len - 1];
+ if (last_char == '\r' || last_char == '\n') {
+ done = true;
+ // Strip trailing newlines
+ while (last_char == '\r' || last_char == '\n') {
+ --buffer_len;
+ if (buffer_len == 0)
+ break;
+ last_char = buffer[buffer_len - 1];
}
- m_editing = false;
- // We might have gotten a newline on a line by itself
- // make sure to return true in this case.
- return got_line;
- }
- else
- {
- // No more input file, we are done...
- SetIsDone(true);
- }
- return false;
-#ifndef LLDB_DISABLE_LIBEDIT
+ }
+ line.append(buffer, buffer_len);
+ }
+ }
+ m_editing = false;
+ // We might have gotten a newline on a line by itself
+ // make sure to return true in this case.
+ return got_line;
+ } else {
+ // No more input file, we are done...
+ SetIsDone(true);
}
+ return false;
+#ifndef LLDB_DISABLE_LIBEDIT
+ }
#endif
}
#ifndef LLDB_DISABLE_LIBEDIT
-bool
-IOHandlerEditline::IsInputCompleteCallback (Editline *editline,
- StringList &lines,
- void *baton)
-{
- IOHandlerEditline *editline_reader = (IOHandlerEditline *) baton;
- return editline_reader->m_delegate.IOHandlerIsInputComplete(*editline_reader, lines);
+bool IOHandlerEditline::IsInputCompleteCallback(Editline *editline,
+ StringList &lines,
+ void *baton) {
+ IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
+ return editline_reader->m_delegate.IOHandlerIsInputComplete(*editline_reader,
+ lines);
}
-int
-IOHandlerEditline::FixIndentationCallback (Editline *editline,
- const StringList &lines,
- int cursor_position,
- void *baton)
-{
- IOHandlerEditline *editline_reader = (IOHandlerEditline *) baton;
- return editline_reader->m_delegate.IOHandlerFixIndentation(*editline_reader, lines, cursor_position);
+int IOHandlerEditline::FixIndentationCallback(Editline *editline,
+ const StringList &lines,
+ int cursor_position,
+ void *baton) {
+ IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
+ return editline_reader->m_delegate.IOHandlerFixIndentation(
+ *editline_reader, lines, cursor_position);
}
-int
-IOHandlerEditline::AutoCompleteCallback (const char *current_line,
- const char *cursor,
- const char *last_char,
- int skip_first_n_matches,
- int max_matches,
- StringList &matches,
- void *baton)
-{
- IOHandlerEditline *editline_reader = (IOHandlerEditline *) baton;
- if (editline_reader)
- return editline_reader->m_delegate.IOHandlerComplete (*editline_reader,
- current_line,
- cursor,
- last_char,
- skip_first_n_matches,
- max_matches,
- matches);
- return 0;
+int IOHandlerEditline::AutoCompleteCallback(const char *current_line,
+ const char *cursor,
+ const char *last_char,
+ int skip_first_n_matches,
+ int max_matches,
+ StringList &matches, void *baton) {
+ IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton;
+ if (editline_reader)
+ return editline_reader->m_delegate.IOHandlerComplete(
+ *editline_reader, current_line, cursor, last_char, skip_first_n_matches,
+ max_matches, matches);
+ return 0;
}
#endif
-const char *
-IOHandlerEditline::GetPrompt ()
-{
+const char *IOHandlerEditline::GetPrompt() {
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- {
- return m_editline_ap->GetPrompt ();
- }
- else
- {
+ if (m_editline_ap) {
+ return m_editline_ap->GetPrompt();
+ } else {
#endif
- if (m_prompt.empty())
- return nullptr;
+ if (m_prompt.empty())
+ return nullptr;
#ifndef LLDB_DISABLE_LIBEDIT
- }
+ }
#endif
- return m_prompt.c_str();
+ return m_prompt.c_str();
}
-bool
-IOHandlerEditline::SetPrompt (const char *p)
-{
- if (p && p[0])
- m_prompt = p;
- else
- m_prompt.clear();
+bool IOHandlerEditline::SetPrompt(llvm::StringRef prompt) {
+ m_prompt = prompt;
+
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- m_editline_ap->SetPrompt(m_prompt.empty() ? nullptr : m_prompt.c_str());
+ if (m_editline_ap)
+ m_editline_ap->SetPrompt(m_prompt.empty() ? nullptr : m_prompt.c_str());
#endif
- return true;
+ return true;
}
-const char *
-IOHandlerEditline::GetContinuationPrompt ()
-{
- return (m_continuation_prompt.empty() ? nullptr : m_continuation_prompt.c_str());
+const char *IOHandlerEditline::GetContinuationPrompt() {
+ return (m_continuation_prompt.empty() ? nullptr
+ : m_continuation_prompt.c_str());
}
-void
-IOHandlerEditline::SetContinuationPrompt (const char *p)
-{
- if (p && p[0])
- m_continuation_prompt = p;
- else
- m_continuation_prompt.clear();
+void IOHandlerEditline::SetContinuationPrompt(llvm::StringRef prompt) {
+ m_continuation_prompt = prompt;
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- m_editline_ap->SetContinuationPrompt(m_continuation_prompt.empty() ? nullptr : m_continuation_prompt.c_str());
+ if (m_editline_ap)
+ m_editline_ap->SetContinuationPrompt(m_continuation_prompt.empty()
+ ? nullptr
+ : m_continuation_prompt.c_str());
#endif
}
-void
-IOHandlerEditline::SetBaseLineNumber (uint32_t line)
-{
- m_base_line_number = line;
+void IOHandlerEditline::SetBaseLineNumber(uint32_t line) {
+ m_base_line_number = line;
}
-uint32_t
-IOHandlerEditline::GetCurrentLineIndex () const
-{
+uint32_t IOHandlerEditline::GetCurrentLineIndex() const {
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- return m_editline_ap->GetCurrentLine();
+ if (m_editline_ap)
+ return m_editline_ap->GetCurrentLine();
#endif
- return m_curr_line_idx;
+ return m_curr_line_idx;
}
-bool
-IOHandlerEditline::GetLines (StringList &lines, bool &interrupted)
-{
- m_current_lines_ptr = &lines;
-
- bool success = false;
+bool IOHandlerEditline::GetLines(StringList &lines, bool &interrupted) {
+ m_current_lines_ptr = &lines;
+
+ bool success = false;
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- {
- return m_editline_ap->GetLines (m_base_line_number, lines, interrupted);
- }
- else
- {
+ if (m_editline_ap) {
+ return m_editline_ap->GetLines(m_base_line_number, lines, interrupted);
+ } else {
#endif
- bool done = false;
- Error error;
-
- while (!done)
- {
- // Show line numbers if we are asked to
- std::string line;
- if (m_base_line_number > 0 && GetIsInteractive())
- {
- FILE *out = GetOutputFILE();
- if (out)
- ::fprintf(out, "%u%s", m_base_line_number + (uint32_t)lines.GetSize(), GetPrompt() == nullptr ? " " : "");
- }
-
- m_curr_line_idx = lines.GetSize();
-
- bool interrupted = false;
- if (GetLine(line, interrupted) && !interrupted)
- {
- lines.AppendString(line);
- done = m_delegate.IOHandlerIsInputComplete(*this, lines);
- }
- else
- {
- done = true;
- }
- }
- success = lines.GetSize() > 0;
-#ifndef LLDB_DISABLE_LIBEDIT
+ bool done = false;
+ Error error;
+
+ while (!done) {
+ // Show line numbers if we are asked to
+ std::string line;
+ if (m_base_line_number > 0 && GetIsInteractive()) {
+ FILE *out = GetOutputFILE();
+ if (out)
+ ::fprintf(out, "%u%s", m_base_line_number + (uint32_t)lines.GetSize(),
+ GetPrompt() == nullptr ? " " : "");
+ }
+
+ m_curr_line_idx = lines.GetSize();
+
+ bool interrupted = false;
+ if (GetLine(line, interrupted) && !interrupted) {
+ lines.AppendString(line);
+ done = m_delegate.IOHandlerIsInputComplete(*this, lines);
+ } else {
+ done = true;
+ }
}
+ success = lines.GetSize() > 0;
+#ifndef LLDB_DISABLE_LIBEDIT
+ }
#endif
- return success;
+ return success;
}
// Each IOHandler gets to run until it is done. It should read data
// from the "in" and place output into "out" and "err and return
// when done.
-void
-IOHandlerEditline::Run ()
-{
- std::string line;
- while (IsActive())
- {
- bool interrupted = false;
- if (m_multi_line)
- {
- StringList lines;
- if (GetLines (lines, interrupted))
- {
- if (interrupted)
- {
- m_done = m_interrupt_exits;
- m_delegate.IOHandlerInputInterrupted (*this, line);
-
- }
- else
- {
- line = lines.CopyList();
- m_delegate.IOHandlerInputComplete (*this, line);
- }
- }
- else
- {
- m_done = true;
- }
- }
+void IOHandlerEditline::Run() {
+ std::string line;
+ while (IsActive()) {
+ bool interrupted = false;
+ if (m_multi_line) {
+ StringList lines;
+ if (GetLines(lines, interrupted)) {
+ if (interrupted) {
+ m_done = m_interrupt_exits;
+ m_delegate.IOHandlerInputInterrupted(*this, line);
+
+ } else {
+ line = lines.CopyList();
+ m_delegate.IOHandlerInputComplete(*this, line);
+ }
+ } else {
+ m_done = true;
+ }
+ } else {
+ if (GetLine(line, interrupted)) {
+ if (interrupted)
+ m_delegate.IOHandlerInputInterrupted(*this, line);
else
- {
- if (GetLine(line, interrupted))
- {
- if (interrupted)
- m_delegate.IOHandlerInputInterrupted (*this, line);
- else
- m_delegate.IOHandlerInputComplete (*this, line);
- }
- else
- {
- m_done = true;
- }
- }
+ m_delegate.IOHandlerInputComplete(*this, line);
+ } else {
+ m_done = true;
+ }
}
+ }
}
-void
-IOHandlerEditline::Cancel ()
-{
+void IOHandlerEditline::Cancel() {
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- m_editline_ap->Cancel ();
+ if (m_editline_ap)
+ m_editline_ap->Cancel();
#endif
}
-bool
-IOHandlerEditline::Interrupt ()
-{
- // Let the delgate handle it first
- if (m_delegate.IOHandlerInterrupt(*this))
- return true;
+bool IOHandlerEditline::Interrupt() {
+ // Let the delgate handle it first
+ if (m_delegate.IOHandlerInterrupt(*this))
+ return true;
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- return m_editline_ap->Interrupt();
+ if (m_editline_ap)
+ return m_editline_ap->Interrupt();
#endif
- return false;
+ return false;
}
-void
-IOHandlerEditline::GotEOF()
-{
+void IOHandlerEditline::GotEOF() {
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- m_editline_ap->Interrupt();
+ if (m_editline_ap)
+ m_editline_ap->Interrupt();
#endif
}
-void
-IOHandlerEditline::PrintAsync (Stream *stream, const char *s, size_t len)
-{
+void IOHandlerEditline::PrintAsync(Stream *stream, const char *s, size_t len) {
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- m_editline_ap->PrintAsync(stream, s, len);
- else
+ if (m_editline_ap)
+ m_editline_ap->PrintAsync(stream, s, len);
+ else
#endif
- {
- const char *prompt = GetPrompt();
+ {
#ifdef _MSC_VER
- if (prompt)
- {
- // Back up over previous prompt using Windows API
- CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
- HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
- GetConsoleScreenBufferInfo(console_handle, &screen_buffer_info);
- COORD coord = screen_buffer_info.dwCursorPosition;
- coord.X -= strlen(prompt);
- if (coord.X < 0)
- coord.X = 0;
- SetConsoleCursorPosition(console_handle, coord);
- }
-#endif
- IOHandler::PrintAsync(stream, s, len);
- if (prompt)
- IOHandler::PrintAsync(GetOutputStreamFile().get(), prompt, strlen(prompt));
+ const char *prompt = GetPrompt();
+ if (prompt) {
+ // Back up over previous prompt using Windows API
+ CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
+ HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+ GetConsoleScreenBufferInfo(console_handle, &screen_buffer_info);
+ COORD coord = screen_buffer_info.dwCursorPosition;
+ coord.X -= strlen(prompt);
+ if (coord.X < 0)
+ coord.X = 0;
+ SetConsoleCursorPosition(console_handle, coord);
}
+#endif
+ IOHandler::PrintAsync(stream, s, len);
+#ifdef _MSC_VER
+ if (prompt)
+ IOHandler::PrintAsync(GetOutputStreamFile().get(), prompt,
+ strlen(prompt));
+#endif
+ }
}
// we may want curses to be disabled for some builds
// for instance, windows
#ifndef LLDB_DISABLE_CURSES
-#define KEY_RETURN 10
-#define KEY_ESCAPE 27
-
-namespace curses
-{
- class Menu;
- class MenuDelegate;
- class Window;
- class WindowDelegate;
- typedef std::shared_ptr<Menu> MenuSP;
- typedef std::shared_ptr<MenuDelegate> MenuDelegateSP;
- typedef std::shared_ptr<Window> WindowSP;
- typedef std::shared_ptr<WindowDelegate> WindowDelegateSP;
- typedef std::vector<MenuSP> Menus;
- typedef std::vector<WindowSP> Windows;
- typedef std::vector<WindowDelegateSP> WindowDelegates;
+#define KEY_RETURN 10
+#define KEY_ESCAPE 27
+
+namespace curses {
+class Menu;
+class MenuDelegate;
+class Window;
+class WindowDelegate;
+typedef std::shared_ptr<Menu> MenuSP;
+typedef std::shared_ptr<MenuDelegate> MenuDelegateSP;
+typedef std::shared_ptr<Window> WindowSP;
+typedef std::shared_ptr<WindowDelegate> WindowDelegateSP;
+typedef std::vector<MenuSP> Menus;
+typedef std::vector<WindowSP> Windows;
+typedef std::vector<WindowDelegateSP> WindowDelegates;
#if 0
type summary add -s "x=${var.x}, y=${var.y}" curses::Point
@@ -826,4754 +639,4029 @@ 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;
- int y;
-
- Point (int _x = 0, int _y = 0) :
- x(_x),
- y(_y)
- {
- }
+struct Point {
+ int x;
+ int y;
- void
- Clear ()
- {
- x = 0;
- y = 0;
- }
-
- Point &
- operator += (const Point &rhs)
- {
- x += rhs.x;
- y += rhs.y;
- return *this;
- }
-
- void
- Dump ()
- {
- 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;
- }
+ Point(int _x = 0, int _y = 0) : x(_x), y(_y) {}
- bool operator != (const Point &lhs, const Point &rhs)
- {
- return lhs.x != rhs.x || lhs.y != rhs.y;
- }
+ void Clear() {
+ x = 0;
+ y = 0;
+ }
- struct Size
- {
- int width;
- int height;
- Size (int w = 0, int h = 0) :
- width (w),
- height (h)
- {
- }
-
- void
- Clear ()
- {
- width = 0;
- height = 0;
- }
+ Point &operator+=(const Point &rhs) {
+ x += rhs.x;
+ y += rhs.y;
+ return *this;
+ }
- void
- Dump ()
- {
- 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;
+ void Dump() { 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;
+}
+
+struct Size {
+ int width;
+ int height;
+ Size(int w = 0, int h = 0) : width(w), height(h) {}
+
+ void Clear() {
+ width = 0;
+ height = 0;
+ }
+
+ void Dump() { 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;
+}
+
+struct Rect {
+ Point origin;
+ Size size;
+
+ Rect() : origin(), size() {}
+
+ Rect(const Point &p, const Size &s) : origin(p), size(s) {}
+
+ void Clear() {
+ origin.Clear();
+ size.Clear();
+ }
+
+ void Dump() {
+ printf("(x=%i, y=%i), w=%i, h=%i)\n", origin.x, origin.y, size.width,
+ size.height);
+ }
+
+ void Inset(int w, int h) {
+ if (size.width > w * 2)
+ size.width -= w * 2;
+ origin.x += w;
+
+ if (size.height > h * 2)
+ 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.
+ Rect MakeStatusBar() {
+ Rect status_bar;
+ if (size.height > 1) {
+ status_bar.origin.x = origin.x;
+ status_bar.origin.y = size.height;
+ status_bar.size.width = size.width;
+ status_bar.size.height = 1;
+ --size.height;
+ }
+ return status_bar;
+ }
+
+ // Return a menubar rectangle which is the first line of
+ // this rectangle. This rectangle will be modified to not
+ // include the menubar area.
+ Rect MakeMenuBar() {
+ Rect menubar;
+ if (size.height > 1) {
+ menubar.origin.x = origin.x;
+ menubar.origin.y = origin.y;
+ menubar.size.width = size.width;
+ menubar.size.height = 1;
+ ++origin.y;
+ --size.height;
}
+ return menubar;
+ }
+
+ void HorizontalSplitPercentage(float top_percentage, Rect &top,
+ Rect &bottom) const {
+ float top_height = top_percentage * size.height;
+ HorizontalSplit(top_height, top, bottom);
+ }
+
+ void HorizontalSplit(int top_height, Rect &top, Rect &bottom) const {
+ top = *this;
+ if (top_height < size.height) {
+ top.size.height = top_height;
+ bottom.origin.x = origin.x;
+ bottom.origin.y = origin.y + top.size.height;
+ bottom.size.width = size.width;
+ bottom.size.height = size.height - top.size.height;
+ } else {
+ bottom.Clear();
+ }
+ }
+
+ void VerticalSplitPercentage(float left_percentage, Rect &left,
+ Rect &right) const {
+ float left_width = left_percentage * size.width;
+ VerticalSplit(left_width, left, right);
+ }
+
+ void VerticalSplit(int left_width, Rect &left, Rect &right) const {
+ left = *this;
+ if (left_width < size.width) {
+ left.size.width = left_width;
+ right.origin.x = origin.x + left.size.width;
+ right.origin.y = origin.y;
+ right.size.width = size.width - left.size.width;
+ right.size.height = size.height;
+ } else {
+ right.Clear();
+ }
+ }
+};
- bool operator != (const Size &lhs, const Size &rhs)
- {
- return lhs.width != rhs.width || lhs.height != rhs.height;
+bool operator==(const Rect &lhs, const Rect &rhs) {
+ 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;
+}
+
+enum HandleCharResult {
+ eKeyNotHandled = 0,
+ eKeyHandled = 1,
+ eQuitApplication = 2
+};
+
+enum class MenuActionResult {
+ Handled,
+ NotHandled,
+ Quit // Exit all menus and quit
+};
+
+struct KeyHelp {
+ int ch;
+ const char *description;
+};
+
+class WindowDelegate {
+public:
+ virtual ~WindowDelegate() = default;
+
+ virtual bool WindowDelegateDraw(Window &window, bool force) {
+ return false; // Drawing not handled
+ }
+
+ virtual HandleCharResult WindowDelegateHandleChar(Window &window, int key) {
+ return eKeyNotHandled;
+ }
+
+ virtual const char *WindowDelegateGetHelpText() { return nullptr; }
+
+ virtual KeyHelp *WindowDelegateGetKeyHelp() { return nullptr; }
+};
+
+class HelpDialogDelegate : public WindowDelegate {
+public:
+ HelpDialogDelegate(const char *text, KeyHelp *key_help_array);
+
+ ~HelpDialogDelegate() override;
+
+ bool WindowDelegateDraw(Window &window, bool force) override;
+
+ HandleCharResult WindowDelegateHandleChar(Window &window, int key) override;
+
+ size_t GetNumLines() const { return m_text.GetSize(); }
+
+ size_t GetMaxLineLength() const { return m_text.GetMaxStringLength(); }
+
+protected:
+ StringList m_text;
+ int m_first_visible_line;
+};
+
+class Window {
+public:
+ Window(const char *name)
+ : m_name(name), m_window(nullptr), m_panel(nullptr), m_parent(nullptr),
+ m_subwindows(), m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX),
+ m_prev_active_window_idx(UINT32_MAX), m_delete(false),
+ m_needs_update(true), m_can_activate(true), m_is_subwin(false) {}
+
+ Window(const char *name, WINDOW *w, bool del = true)
+ : m_name(name), m_window(nullptr), m_panel(nullptr), m_parent(nullptr),
+ m_subwindows(), m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX),
+ m_prev_active_window_idx(UINT32_MAX), m_delete(del),
+ m_needs_update(true), m_can_activate(true), m_is_subwin(false) {
+ if (w)
+ Reset(w);
+ }
+
+ Window(const char *name, const Rect &bounds)
+ : m_name(name), m_window(nullptr), m_parent(nullptr), m_subwindows(),
+ m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX),
+ m_prev_active_window_idx(UINT32_MAX), m_delete(true),
+ m_needs_update(true), m_can_activate(true), m_is_subwin(false) {
+ Reset(::newwin(bounds.size.height, bounds.size.width, bounds.origin.y,
+ bounds.origin.y));
+ }
+
+ virtual ~Window() {
+ RemoveSubWindows();
+ Reset();
+ }
+
+ void Reset(WINDOW *w = nullptr, bool del = true) {
+ if (m_window == w)
+ return;
+
+ if (m_panel) {
+ ::del_panel(m_panel);
+ m_panel = nullptr;
+ }
+ if (m_window && m_delete) {
+ ::delwin(m_window);
+ m_window = nullptr;
+ m_delete = false;
}
+ if (w) {
+ m_window = w;
+ m_panel = ::new_panel(m_window);
+ m_delete = del;
+ }
+ }
+
+ void AttributeOn(attr_t attr) { ::wattron(m_window, attr); }
+ void AttributeOff(attr_t attr) { ::wattroff(m_window, attr); }
+ void Box(chtype v_char = ACS_VLINE, chtype h_char = ACS_HLINE) {
+ ::box(m_window, v_char, h_char);
+ }
+ void Clear() { ::wclear(m_window); }
+ void Erase() { ::werase(m_window); }
+ Rect GetBounds() {
+ return Rect(GetParentOrigin(), GetSize());
+ } // Get the rectangle in our parent window
+ int GetChar() { return ::wgetch(m_window); }
+ int GetCursorX() { return getcurx(m_window); }
+ int GetCursorY() { return getcury(m_window); }
+ Rect GetFrame() {
+ return Rect(Point(), GetSize());
+ } // Get our rectangle in our own coordinate system
+ Point GetParentOrigin() { return Point(GetParentX(), GetParentY()); }
+ Size GetSize() { return Size(GetWidth(), GetHeight()); }
+ int GetParentX() { return getparx(m_window); }
+ int GetParentY() { return getpary(m_window); }
+ int GetMaxX() { return getmaxx(m_window); }
+ int GetMaxY() { return getmaxy(m_window); }
+ int GetWidth() { return GetMaxX(); }
+ int GetHeight() { return GetMaxY(); }
+ void MoveCursor(int x, int y) { ::wmove(m_window, y, x); }
+ void MoveWindow(int x, int y) { MoveWindow(Point(x, y)); }
+ void Resize(int w, int h) { ::wresize(m_window, h, w); }
+ void Resize(const Size &size) {
+ ::wresize(m_window, size.height, size.width);
+ }
+ void PutChar(int ch) { ::waddch(m_window, ch); }
+ void PutCString(const char *s, int len = -1) { ::waddnstr(m_window, s, len); }
+ void Refresh() { ::wrefresh(m_window); }
+ void DeferredRefresh() {
+ // We are using panels, so we don't need to call this...
+ //::wnoutrefresh(m_window);
+ }
+ void SetBackground(int color_pair_idx) {
+ ::wbkgd(m_window, COLOR_PAIR(color_pair_idx));
+ }
+ void UnderlineOn() { AttributeOn(A_UNDERLINE); }
+ void UnderlineOff() { AttributeOff(A_UNDERLINE); }
+
+ void PutCStringTruncated(const char *s, int right_pad) {
+ int bytes_left = GetWidth() - GetCursorX();
+ if (bytes_left > right_pad) {
+ bytes_left -= right_pad;
+ ::waddnstr(m_window, s, bytes_left);
+ }
+ }
+
+ void MoveWindow(const Point &origin) {
+ const bool moving_window = origin != GetParentOrigin();
+ if (m_is_subwin && moving_window) {
+ // Can't move subwindows, must delete and re-create
+ Size size = GetSize();
+ Reset(::subwin(m_parent->m_window, size.height, size.width, origin.y,
+ origin.x),
+ true);
+ } else {
+ ::mvwin(m_window, origin.y, origin.x);
+ }
+ }
+
+ void SetBounds(const Rect &bounds) {
+ const bool moving_window = bounds.origin != GetParentOrigin();
+ if (m_is_subwin && moving_window) {
+ // Can't move subwindows, must delete and re-create
+ Reset(::subwin(m_parent->m_window, bounds.size.height, bounds.size.width,
+ bounds.origin.y, bounds.origin.x),
+ true);
+ } else {
+ if (moving_window)
+ MoveWindow(bounds.origin);
+ Resize(bounds.size);
+ }
+ }
+
+ void Printf(const char *format, ...) __attribute__((format(printf, 2, 3))) {
+ va_list args;
+ va_start(args, format);
+ vwprintw(m_window, format, args);
+ va_end(args);
+ }
+
+ void Touch() {
+ ::touchwin(m_window);
+ if (m_parent)
+ m_parent->Touch();
+ }
+
+ WindowSP CreateSubWindow(const char *name, const Rect &bounds,
+ bool make_active) {
+ WindowSP subwindow_sp;
+ if (m_window) {
+ subwindow_sp.reset(new Window(
+ name, ::subwin(m_window, bounds.size.height, bounds.size.width,
+ bounds.origin.y, bounds.origin.x),
+ true));
+ subwindow_sp->m_is_subwin = true;
+ } else {
+ subwindow_sp.reset(
+ new Window(name, ::newwin(bounds.size.height, bounds.size.width,
+ bounds.origin.y, bounds.origin.x),
+ true));
+ subwindow_sp->m_is_subwin = false;
+ }
+ subwindow_sp->m_parent = this;
+ if (make_active) {
+ m_prev_active_window_idx = m_curr_active_window_idx;
+ m_curr_active_window_idx = m_subwindows.size();
+ }
+ m_subwindows.push_back(subwindow_sp);
+ ::top_panel(subwindow_sp->m_panel);
+ m_needs_update = true;
+ return subwindow_sp;
+ }
+
+ bool RemoveSubWindow(Window *window) {
+ Windows::iterator pos, end = m_subwindows.end();
+ size_t i = 0;
+ for (pos = m_subwindows.begin(); pos != end; ++pos, ++i) {
+ if ((*pos).get() == window) {
+ if (m_prev_active_window_idx == i)
+ m_prev_active_window_idx = UINT32_MAX;
+ else if (m_prev_active_window_idx != UINT32_MAX &&
+ m_prev_active_window_idx > i)
+ --m_prev_active_window_idx;
+
+ if (m_curr_active_window_idx == i)
+ m_curr_active_window_idx = UINT32_MAX;
+ else if (m_curr_active_window_idx != UINT32_MAX &&
+ m_curr_active_window_idx > i)
+ --m_curr_active_window_idx;
+ window->Erase();
+ m_subwindows.erase(pos);
+ m_needs_update = true;
+ if (m_parent)
+ m_parent->Touch();
+ else
+ ::touchwin(stdscr);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ WindowSP FindSubWindow(const char *name) {
+ Windows::iterator pos, end = m_subwindows.end();
+ size_t i = 0;
+ for (pos = m_subwindows.begin(); pos != end; ++pos, ++i) {
+ if ((*pos)->m_name.compare(name) == 0)
+ return *pos;
+ }
+ return WindowSP();
+ }
+
+ void RemoveSubWindows() {
+ m_curr_active_window_idx = UINT32_MAX;
+ m_prev_active_window_idx = UINT32_MAX;
+ for (Windows::iterator pos = m_subwindows.begin();
+ pos != m_subwindows.end(); pos = m_subwindows.erase(pos)) {
+ (*pos)->Erase();
+ }
+ if (m_parent)
+ m_parent->Touch();
+ else
+ ::touchwin(stdscr);
+ }
- struct Rect
- {
- Point origin;
- Size size;
-
- Rect () :
- origin(),
- size()
- {
- }
-
- Rect (const Point &p, const Size &s) :
- origin (p),
- size (s)
- {
- }
-
- void
- Clear ()
- {
- origin.Clear();
- size.Clear();
- }
-
- void
- Dump ()
- {
- printf ("(x=%i, y=%i), w=%i, h=%i)\n", origin.x, origin.y, size.width, size.height);
- }
-
- void
- Inset (int w, int h)
- {
- if (size.width > w*2)
- size.width -= w*2;
- origin.x += w;
-
- if (size.height > h*2)
- size.height -= h*2;
- origin.y += h;
- }
+ WINDOW *get() { return m_window; }
- // 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.
- Rect
- MakeStatusBar ()
- {
- Rect status_bar;
- if (size.height > 1)
- {
- status_bar.origin.x = origin.x;
- status_bar.origin.y = size.height;
- status_bar.size.width = size.width;
- status_bar.size.height = 1;
- --size.height;
- }
- return status_bar;
- }
+ operator WINDOW *() { return m_window; }
- // Return a menubar rectangle which is the first line of
- // this rectangle. This rectangle will be modified to not
- // include the menubar area.
- Rect
- MakeMenuBar ()
- {
- Rect menubar;
- if (size.height > 1)
- {
- menubar.origin.x = origin.x;
- menubar.origin.y = origin.y;
- menubar.size.width = size.width;
- menubar.size.height = 1;
- ++origin.y;
- --size.height;
- }
- return menubar;
- }
+ //----------------------------------------------------------------------
+ // Window drawing utilities
+ //----------------------------------------------------------------------
+ void DrawTitleBox(const char *title, const char *bottom_message = nullptr) {
+ attr_t attr = 0;
+ if (IsActive())
+ attr = A_BOLD | COLOR_PAIR(2);
+ else
+ attr = 0;
+ if (attr)
+ AttributeOn(attr);
- void
- HorizontalSplitPercentage (float top_percentage, Rect &top, Rect &bottom) const
- {
- float top_height = top_percentage * size.height;
- HorizontalSplit (top_height, top, bottom);
- }
+ Box();
+ MoveCursor(3, 0);
- void
- HorizontalSplit (int top_height, Rect &top, Rect &bottom) const
- {
- top = *this;
- if (top_height < size.height)
- {
- top.size.height = top_height;
- bottom.origin.x = origin.x;
- bottom.origin.y = origin.y + top.size.height;
- bottom.size.width = size.width;
- bottom.size.height = size.height - top.size.height;
- }
- else
- {
- bottom.Clear();
- }
- }
-
- void
- VerticalSplitPercentage (float left_percentage, Rect &left, Rect &right) const
- {
- float left_width = left_percentage * size.width;
- VerticalSplit (left_width, left, right);
- }
+ if (title && title[0]) {
+ PutChar('<');
+ PutCString(title);
+ PutChar('>');
+ }
- void
- VerticalSplit (int left_width, Rect &left, Rect &right) const
- {
- left = *this;
- if (left_width < size.width)
- {
- left.size.width = left_width;
- right.origin.x = origin.x + left.size.width;
- right.origin.y = origin.y;
- right.size.width = size.width - left.size.width;
- right.size.height = size.height;
- }
- else
- {
- right.Clear();
+ if (bottom_message && bottom_message[0]) {
+ int bottom_message_length = strlen(bottom_message);
+ int x = GetWidth() - 3 - (bottom_message_length + 2);
+
+ if (x > 0) {
+ MoveCursor(x, GetHeight() - 1);
+ PutChar('[');
+ PutCString(bottom_message);
+ PutChar(']');
+ } else {
+ MoveCursor(1, GetHeight() - 1);
+ PutChar('[');
+ PutCStringTruncated(bottom_message, 1);
+ }
+ }
+ if (attr)
+ AttributeOff(attr);
+ }
+
+ virtual void Draw(bool force) {
+ if (m_delegate_sp && m_delegate_sp->WindowDelegateDraw(*this, force))
+ return;
+
+ for (auto &subwindow_sp : m_subwindows)
+ subwindow_sp->Draw(force);
+ }
+
+ bool CreateHelpSubwindow() {
+ if (m_delegate_sp) {
+ const char *text = m_delegate_sp->WindowDelegateGetHelpText();
+ KeyHelp *key_help = m_delegate_sp->WindowDelegateGetKeyHelp();
+ if ((text && text[0]) || key_help) {
+ std::auto_ptr<HelpDialogDelegate> help_delegate_ap(
+ new HelpDialogDelegate(text, key_help));
+ const size_t num_lines = help_delegate_ap->GetNumLines();
+ const size_t max_length = help_delegate_ap->GetMaxLineLength();
+ Rect bounds = GetBounds();
+ bounds.Inset(1, 1);
+ if (max_length + 4 < static_cast<size_t>(bounds.size.width)) {
+ bounds.origin.x += (bounds.size.width - max_length + 4) / 2;
+ bounds.size.width = max_length + 4;
+ } else {
+ if (bounds.size.width > 100) {
+ const int inset_w = bounds.size.width / 4;
+ bounds.origin.x += inset_w;
+ bounds.size.width -= 2 * inset_w;
+ }
+ }
+
+ if (num_lines + 2 < static_cast<size_t>(bounds.size.height)) {
+ bounds.origin.y += (bounds.size.height - num_lines + 2) / 2;
+ bounds.size.height = num_lines + 2;
+ } else {
+ if (bounds.size.height > 100) {
+ const int inset_h = bounds.size.height / 4;
+ bounds.origin.y += inset_h;
+ bounds.size.height -= 2 * inset_h;
+ }
+ }
+ WindowSP help_window_sp;
+ Window *parent_window = GetParent();
+ if (parent_window)
+ help_window_sp = parent_window->CreateSubWindow("Help", bounds, true);
+ else
+ help_window_sp = CreateSubWindow("Help", bounds, true);
+ help_window_sp->SetDelegate(
+ WindowDelegateSP(help_delegate_ap.release()));
+ return true;
+ }
+ }
+ return false;
+ }
+
+ virtual HandleCharResult HandleChar(int key) {
+ // Always check the active window first
+ HandleCharResult result = eKeyNotHandled;
+ WindowSP active_window_sp = GetActiveWindow();
+ if (active_window_sp) {
+ result = active_window_sp->HandleChar(key);
+ if (result != eKeyNotHandled)
+ return result;
+ }
+
+ if (m_delegate_sp) {
+ result = m_delegate_sp->WindowDelegateHandleChar(*this, key);
+ if (result != eKeyNotHandled)
+ return result;
+ }
+
+ // Then check for any windows that want any keys
+ // that weren't handled. This is typically only
+ // for a menubar.
+ // Make a copy of the subwindows in case any HandleChar()
+ // functions muck with the subwindows. If we don't do this,
+ // we can crash when iterating over the subwindows.
+ Windows subwindows(m_subwindows);
+ for (auto subwindow_sp : subwindows) {
+ if (!subwindow_sp->m_can_activate) {
+ HandleCharResult result = subwindow_sp->HandleChar(key);
+ if (result != eKeyNotHandled)
+ return result;
+ }
+ }
+
+ return eKeyNotHandled;
+ }
+
+ bool SetActiveWindow(Window *window) {
+ const size_t num_subwindows = m_subwindows.size();
+ for (size_t i = 0; i < num_subwindows; ++i) {
+ if (m_subwindows[i].get() == window) {
+ m_prev_active_window_idx = m_curr_active_window_idx;
+ ::top_panel(window->m_panel);
+ m_curr_active_window_idx = i;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ WindowSP GetActiveWindow() {
+ if (!m_subwindows.empty()) {
+ if (m_curr_active_window_idx >= m_subwindows.size()) {
+ if (m_prev_active_window_idx < m_subwindows.size()) {
+ m_curr_active_window_idx = m_prev_active_window_idx;
+ m_prev_active_window_idx = UINT32_MAX;
+ } else if (IsActive()) {
+ m_prev_active_window_idx = UINT32_MAX;
+ m_curr_active_window_idx = UINT32_MAX;
+
+ // Find first window that wants to be active if this window is active
+ const size_t num_subwindows = m_subwindows.size();
+ for (size_t i = 0; i < num_subwindows; ++i) {
+ if (m_subwindows[i]->GetCanBeActive()) {
+ m_curr_active_window_idx = i;
+ break;
}
+ }
}
- };
+ }
- bool operator == (const Rect &lhs, const Rect &rhs)
- {
- return lhs.origin == rhs.origin && lhs.size == rhs.size;
+ if (m_curr_active_window_idx < m_subwindows.size())
+ return m_subwindows[m_curr_active_window_idx];
}
+ return WindowSP();
+ }
- bool operator != (const Rect &lhs, const Rect &rhs)
- {
- return lhs.origin != rhs.origin || lhs.size != rhs.size;
- }
+ bool GetCanBeActive() const { return m_can_activate; }
- enum HandleCharResult
- {
- eKeyNotHandled = 0,
- eKeyHandled = 1,
- eQuitApplication = 2
- };
-
- enum class MenuActionResult
- {
- Handled,
- NotHandled,
- Quit // Exit all menus and quit
- };
+ void SetCanBeActive(bool b) { m_can_activate = b; }
- struct KeyHelp
- {
- int ch;
- const char *description;
- };
+ const WindowDelegateSP &GetDelegate() const { return m_delegate_sp; }
- class WindowDelegate
- {
- public:
- virtual
- ~WindowDelegate() = default;
-
- virtual bool
- WindowDelegateDraw (Window &window, bool force)
- {
- return false; // Drawing not handled
- }
-
- virtual HandleCharResult
- WindowDelegateHandleChar (Window &window, int key)
- {
- return eKeyNotHandled;
- }
-
- virtual const char *
- WindowDelegateGetHelpText ()
- {
- return nullptr;
- }
+ void SetDelegate(const WindowDelegateSP &delegate_sp) {
+ m_delegate_sp = delegate_sp;
+ }
+
+ Window *GetParent() const { return m_parent; }
- virtual KeyHelp *
- WindowDelegateGetKeyHelp ()
- {
- return nullptr;
+ bool IsActive() const {
+ if (m_parent)
+ return m_parent->GetActiveWindow().get() == this;
+ else
+ return true; // Top level window is always active
+ }
+
+ void SelectNextWindowAsActive() {
+ // Move active focus to next window
+ const size_t num_subwindows = m_subwindows.size();
+ if (m_curr_active_window_idx == UINT32_MAX) {
+ uint32_t idx = 0;
+ for (auto subwindow_sp : m_subwindows) {
+ if (subwindow_sp->GetCanBeActive()) {
+ m_curr_active_window_idx = idx;
+ break;
+ }
+ ++idx;
+ }
+ } else if (m_curr_active_window_idx + 1 < num_subwindows) {
+ bool handled = false;
+ m_prev_active_window_idx = m_curr_active_window_idx;
+ for (size_t idx = m_curr_active_window_idx + 1; idx < num_subwindows;
+ ++idx) {
+ if (m_subwindows[idx]->GetCanBeActive()) {
+ m_curr_active_window_idx = idx;
+ handled = true;
+ break;
+ }
+ }
+ if (!handled) {
+ for (size_t idx = 0; idx <= m_prev_active_window_idx; ++idx) {
+ if (m_subwindows[idx]->GetCanBeActive()) {
+ m_curr_active_window_idx = idx;
+ break;
+ }
}
- };
-
- class HelpDialogDelegate :
- public WindowDelegate
- {
- public:
- HelpDialogDelegate (const char *text, KeyHelp *key_help_array);
-
- ~HelpDialogDelegate() override;
-
- bool
- WindowDelegateDraw (Window &window, bool force) override;
-
- HandleCharResult
- WindowDelegateHandleChar (Window &window, int key) override;
-
- size_t
- GetNumLines() const
- {
- return m_text.GetSize();
+ }
+ } else {
+ m_prev_active_window_idx = m_curr_active_window_idx;
+ for (size_t idx = 0; idx < num_subwindows; ++idx) {
+ if (m_subwindows[idx]->GetCanBeActive()) {
+ m_curr_active_window_idx = idx;
+ break;
}
+ }
+ }
+ }
- size_t
- GetMaxLineLength () const
- {
- return m_text.GetMaxStringLength();
- }
+ const char *GetName() const { return m_name.c_str(); }
- protected:
- StringList m_text;
- int m_first_visible_line;
- };
+protected:
+ std::string m_name;
+ WINDOW *m_window;
+ PANEL *m_panel;
+ Window *m_parent;
+ Windows m_subwindows;
+ WindowDelegateSP m_delegate_sp;
+ uint32_t m_curr_active_window_idx;
+ uint32_t m_prev_active_window_idx;
+ bool m_delete;
+ bool m_needs_update;
+ bool m_can_activate;
+ bool m_is_subwin;
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(Window);
+};
- class Window
- {
- public:
- Window (const char *name) :
- m_name (name),
- m_window(nullptr),
- m_panel(nullptr),
- m_parent(nullptr),
- m_subwindows (),
- m_delegate_sp (),
- m_curr_active_window_idx (UINT32_MAX),
- m_prev_active_window_idx (UINT32_MAX),
- m_delete (false),
- m_needs_update (true),
- m_can_activate (true),
- m_is_subwin (false)
- {
- }
-
- Window (const char *name, WINDOW *w, bool del = true) :
- m_name (name),
- m_window(nullptr),
- m_panel(nullptr),
- m_parent(nullptr),
- m_subwindows (),
- m_delegate_sp (),
- m_curr_active_window_idx (UINT32_MAX),
- m_prev_active_window_idx (UINT32_MAX),
- m_delete (del),
- m_needs_update (true),
- m_can_activate (true),
- m_is_subwin (false)
- {
- if (w)
- Reset(w);
- }
-
- Window (const char *name, const Rect &bounds) :
- m_name (name),
- m_window(nullptr),
- m_parent(nullptr),
- m_subwindows (),
- m_delegate_sp (),
- m_curr_active_window_idx (UINT32_MAX),
- m_prev_active_window_idx (UINT32_MAX),
- m_delete (true),
- m_needs_update (true),
- m_can_activate (true),
- m_is_subwin (false)
- {
- Reset (::newwin (bounds.size.height, bounds.size.width, bounds.origin.y, bounds.origin.y));
- }
-
- virtual
- ~Window ()
- {
- RemoveSubWindows ();
- Reset ();
- }
-
- void
- Reset(WINDOW *w = nullptr, bool del = true)
- {
- if (m_window == w)
- return;
-
- if (m_panel)
- {
- ::del_panel (m_panel);
- m_panel = nullptr;
- }
- if (m_window && m_delete)
- {
- ::delwin (m_window);
- m_window = nullptr;
- m_delete = false;
- }
- if (w)
- {
- m_window = w;
- m_panel = ::new_panel (m_window);
- m_delete = del;
- }
- }
-
- void AttributeOn (attr_t attr) { ::wattron (m_window, attr); }
- void AttributeOff (attr_t attr) { ::wattroff (m_window, attr); }
- void Box (chtype v_char = ACS_VLINE, chtype h_char = ACS_HLINE) { ::box(m_window, v_char, h_char); }
- void Clear () { ::wclear (m_window); }
- void Erase () { ::werase (m_window); }
- Rect GetBounds () { return Rect (GetParentOrigin(), GetSize()); } // Get the rectangle in our parent window
- int GetChar () { return ::wgetch (m_window); }
- int GetCursorX () { return getcurx (m_window); }
- int GetCursorY () { return getcury (m_window); }
- Rect GetFrame () { return Rect (Point(), GetSize()); } // Get our rectangle in our own coordinate system
- Point GetParentOrigin() { return Point (GetParentX(), GetParentY()); }
- Size GetSize() { return Size (GetWidth(), GetHeight()); }
- int GetParentX () { return getparx (m_window); }
- int GetParentY () { return getpary (m_window); }
- int GetMaxX() { return getmaxx (m_window); }
- int GetMaxY() { return getmaxy (m_window); }
- int GetWidth() { return GetMaxX(); }
- int GetHeight() { return GetMaxY(); }
- void MoveCursor (int x, int y) { ::wmove (m_window, y, x); }
- void MoveWindow (int x, int y) { MoveWindow(Point(x,y)); }
- void Resize (int w, int h) { ::wresize(m_window, h, w); }
- void Resize (const Size &size) { ::wresize(m_window, size.height, size.width); }
- void PutChar (int ch) { ::waddch (m_window, ch); }
- void PutCString (const char *s, int len = -1) { ::waddnstr (m_window, s, len); }
- void Refresh () { ::wrefresh (m_window); }
- void DeferredRefresh ()
- {
- // We are using panels, so we don't need to call this...
- //::wnoutrefresh(m_window);
- }
- void SetBackground (int color_pair_idx) { ::wbkgd (m_window,COLOR_PAIR(color_pair_idx)); }
- void UnderlineOn () { AttributeOn(A_UNDERLINE); }
- void UnderlineOff () { AttributeOff(A_UNDERLINE); }
-
- void PutCStringTruncated (const char *s, int right_pad)
- {
- int bytes_left = GetWidth() - GetCursorX();
- if (bytes_left > right_pad)
- {
- bytes_left -= right_pad;
- ::waddnstr (m_window, s, bytes_left);
- }
- }
+class MenuDelegate {
+public:
+ virtual ~MenuDelegate() = default;
- void
- MoveWindow (const Point &origin)
- {
- const bool moving_window = origin != GetParentOrigin();
- if (m_is_subwin && moving_window)
- {
- // Can't move subwindows, must delete and re-create
- Size size = GetSize();
- Reset (::subwin (m_parent->m_window,
- size.height,
- size.width,
- origin.y,
- origin.x), true);
- }
- else
- {
- ::mvwin (m_window, origin.y, origin.x);
- }
- }
+ virtual MenuActionResult MenuDelegateAction(Menu &menu) = 0;
+};
- void
- SetBounds (const Rect &bounds)
- {
- const bool moving_window = bounds.origin != GetParentOrigin();
- if (m_is_subwin && moving_window)
- {
- // Can't move subwindows, must delete and re-create
- Reset (::subwin (m_parent->m_window,
- bounds.size.height,
- bounds.size.width,
- bounds.origin.y,
- bounds.origin.x), true);
- }
- else
- {
- if (moving_window)
- MoveWindow(bounds.origin);
- Resize (bounds.size);
- }
- }
+class Menu : public WindowDelegate {
+public:
+ enum class Type { Invalid, Bar, Item, Separator };
- void
- Printf (const char *format, ...) __attribute__ ((format (printf, 2, 3)))
- {
- va_list args;
- va_start (args, format);
- vwprintw(m_window, format, args);
- va_end (args);
- }
+ // Menubar or separator constructor
+ Menu(Type type);
- void
- Touch ()
- {
- ::touchwin (m_window);
- if (m_parent)
- m_parent->Touch();
- }
+ // Menuitem constructor
+ Menu(const char *name, const char *key_name, int key_value,
+ uint64_t identifier);
- WindowSP
- CreateSubWindow (const char *name, const Rect &bounds, bool make_active)
- {
- WindowSP subwindow_sp;
- if (m_window)
- {
- subwindow_sp.reset(new Window(name, ::subwin (m_window,
- bounds.size.height,
- bounds.size.width,
- bounds.origin.y,
- bounds.origin.x), true));
- subwindow_sp->m_is_subwin = true;
- }
- else
- {
- subwindow_sp.reset(new Window(name, ::newwin (bounds.size.height,
- bounds.size.width,
- bounds.origin.y,
- bounds.origin.x), true));
- subwindow_sp->m_is_subwin = false;
- }
- subwindow_sp->m_parent = this;
- if (make_active)
- {
- m_prev_active_window_idx = m_curr_active_window_idx;
- m_curr_active_window_idx = m_subwindows.size();
- }
- m_subwindows.push_back(subwindow_sp);
- ::top_panel (subwindow_sp->m_panel);
- m_needs_update = true;
- return subwindow_sp;
- }
-
- bool
- RemoveSubWindow (Window *window)
- {
- Windows::iterator pos, end = m_subwindows.end();
- size_t i = 0;
- for (pos = m_subwindows.begin(); pos != end; ++pos, ++i)
- {
- if ((*pos).get() == window)
- {
- if (m_prev_active_window_idx == i)
- m_prev_active_window_idx = UINT32_MAX;
- else if (m_prev_active_window_idx != UINT32_MAX && m_prev_active_window_idx > i)
- --m_prev_active_window_idx;
-
- if (m_curr_active_window_idx == i)
- m_curr_active_window_idx = UINT32_MAX;
- else if (m_curr_active_window_idx != UINT32_MAX && m_curr_active_window_idx > i)
- --m_curr_active_window_idx;
- window->Erase();
- m_subwindows.erase(pos);
- m_needs_update = true;
- if (m_parent)
- m_parent->Touch();
- else
- ::touchwin (stdscr);
- return true;
- }
- }
- return false;
- }
-
- WindowSP
- FindSubWindow (const char *name)
- {
- Windows::iterator pos, end = m_subwindows.end();
- size_t i = 0;
- for (pos = m_subwindows.begin(); pos != end; ++pos, ++i)
- {
- if ((*pos)->m_name.compare(name) == 0)
- return *pos;
- }
- return WindowSP();
- }
-
- void
- RemoveSubWindows ()
- {
- m_curr_active_window_idx = UINT32_MAX;
- m_prev_active_window_idx = UINT32_MAX;
- for (Windows::iterator pos = m_subwindows.begin();
- pos != m_subwindows.end();
- pos = m_subwindows.erase(pos))
- {
- (*pos)->Erase();
- }
- if (m_parent)
- m_parent->Touch();
- else
- ::touchwin (stdscr);
- }
+ ~Menu() override = default;
- WINDOW *
- get()
- {
- return m_window;
- }
+ const MenuDelegateSP &GetDelegate() const { return m_delegate_sp; }
- operator WINDOW *()
- {
- return m_window;
- }
-
- //----------------------------------------------------------------------
- // Window drawing utilities
- //----------------------------------------------------------------------
- void
- DrawTitleBox(const char *title, const char *bottom_message = nullptr)
- {
- attr_t attr = 0;
- if (IsActive())
- attr = A_BOLD | COLOR_PAIR(2);
- else
- attr = 0;
- if (attr)
- AttributeOn(attr);
-
- Box();
- MoveCursor(3, 0);
-
- if (title && title[0])
- {
- PutChar ('<');
- PutCString (title);
- PutChar ('>');
- }
-
- if (bottom_message && bottom_message[0])
- {
- int bottom_message_length = strlen(bottom_message);
- int x = GetWidth() - 3 - (bottom_message_length + 2);
-
- if (x > 0)
- {
- MoveCursor (x, GetHeight() - 1);
- PutChar ('[');
- PutCString(bottom_message);
- PutChar (']');
- }
- else
- {
- MoveCursor (1, GetHeight() - 1);
- PutChar ('[');
- PutCStringTruncated (bottom_message, 1);
- }
- }
- if (attr)
- AttributeOff(attr);
- }
+ void SetDelegate(const MenuDelegateSP &delegate_sp) {
+ m_delegate_sp = delegate_sp;
+ }
- virtual void
- Draw (bool force)
- {
- if (m_delegate_sp && m_delegate_sp->WindowDelegateDraw (*this, force))
- return;
+ void RecalculateNameLengths();
- for (auto &subwindow_sp : m_subwindows)
- subwindow_sp->Draw(force);
- }
+ void AddSubmenu(const MenuSP &menu_sp);
- bool
- CreateHelpSubwindow ()
- {
- if (m_delegate_sp)
- {
- const char *text = m_delegate_sp->WindowDelegateGetHelpText ();
- KeyHelp *key_help = m_delegate_sp->WindowDelegateGetKeyHelp ();
- if ((text && text[0]) || key_help)
- {
- std::auto_ptr<HelpDialogDelegate> help_delegate_ap(new HelpDialogDelegate(text, key_help));
- const size_t num_lines = help_delegate_ap->GetNumLines();
- const size_t max_length = help_delegate_ap->GetMaxLineLength();
- Rect bounds = GetBounds();
- bounds.Inset(1, 1);
- if (max_length + 4 < static_cast<size_t>(bounds.size.width))
- {
- bounds.origin.x += (bounds.size.width - max_length + 4)/2;
- bounds.size.width = max_length + 4;
- }
- else
- {
- if (bounds.size.width > 100)
- {
- const int inset_w = bounds.size.width / 4;
- bounds.origin.x += inset_w;
- bounds.size.width -= 2*inset_w;
- }
- }
-
- if (num_lines + 2 < static_cast<size_t>(bounds.size.height))
- {
- bounds.origin.y += (bounds.size.height - num_lines + 2)/2;
- bounds.size.height = num_lines + 2;
- }
- else
- {
- if (bounds.size.height > 100)
- {
- const int inset_h = bounds.size.height / 4;
- bounds.origin.y += inset_h;
- bounds.size.height -= 2*inset_h;
- }
- }
- WindowSP help_window_sp;
- Window *parent_window = GetParent();
- if (parent_window)
- help_window_sp = parent_window->CreateSubWindow("Help", bounds, true);
- else
- help_window_sp = CreateSubWindow("Help", bounds, true);
- help_window_sp->SetDelegate(WindowDelegateSP(help_delegate_ap.release()));
- return true;
- }
- }
- return false;
- }
+ int DrawAndRunMenu(Window &window);
- virtual HandleCharResult
- HandleChar (int key)
- {
- // Always check the active window first
- HandleCharResult result = eKeyNotHandled;
- WindowSP active_window_sp = GetActiveWindow ();
- if (active_window_sp)
- {
- result = active_window_sp->HandleChar (key);
- if (result != eKeyNotHandled)
- return result;
- }
-
- if (m_delegate_sp)
- {
- result = m_delegate_sp->WindowDelegateHandleChar (*this, key);
- if (result != eKeyNotHandled)
- return result;
- }
+ void DrawMenuTitle(Window &window, bool highlight);
- // Then check for any windows that want any keys
- // that weren't handled. This is typically only
- // for a menubar.
- // Make a copy of the subwindows in case any HandleChar()
- // functions muck with the subwindows. If we don't do this,
- // we can crash when iterating over the subwindows.
- Windows subwindows (m_subwindows);
- for (auto subwindow_sp : subwindows)
- {
- if (!subwindow_sp->m_can_activate)
- {
- HandleCharResult result = subwindow_sp->HandleChar(key);
- if (result != eKeyNotHandled)
- return result;
- }
- }
+ bool WindowDelegateDraw(Window &window, bool force) override;
- return eKeyNotHandled;
- }
+ HandleCharResult WindowDelegateHandleChar(Window &window, int key) override;
- bool
- SetActiveWindow (Window *window)
- {
- const size_t num_subwindows = m_subwindows.size();
- for (size_t i = 0; i < num_subwindows; ++i)
- {
- if (m_subwindows[i].get() == window)
- {
- m_prev_active_window_idx = m_curr_active_window_idx;
- ::top_panel (window->m_panel);
- m_curr_active_window_idx = i;
- return true;
- }
- }
- return false;
- }
+ MenuActionResult ActionPrivate(Menu &menu) {
+ MenuActionResult result = MenuActionResult::NotHandled;
+ if (m_delegate_sp) {
+ result = m_delegate_sp->MenuDelegateAction(menu);
+ if (result != MenuActionResult::NotHandled)
+ return result;
+ } else if (m_parent) {
+ result = m_parent->ActionPrivate(menu);
+ if (result != MenuActionResult::NotHandled)
+ return result;
+ }
+ return m_canned_result;
+ }
- WindowSP
- GetActiveWindow ()
- {
- if (!m_subwindows.empty())
- {
- if (m_curr_active_window_idx >= m_subwindows.size())
- {
- if (m_prev_active_window_idx < m_subwindows.size())
- {
- m_curr_active_window_idx = m_prev_active_window_idx;
- m_prev_active_window_idx = UINT32_MAX;
- }
- else if (IsActive())
- {
- m_prev_active_window_idx = UINT32_MAX;
- m_curr_active_window_idx = UINT32_MAX;
-
- // Find first window that wants to be active if this window is active
- const size_t num_subwindows = m_subwindows.size();
- for (size_t i = 0; i < num_subwindows; ++i)
- {
- if (m_subwindows[i]->GetCanBeActive())
- {
- m_curr_active_window_idx = i;
- break;
- }
- }
- }
- }
-
- if (m_curr_active_window_idx < m_subwindows.size())
- return m_subwindows[m_curr_active_window_idx];
- }
- return WindowSP();
- }
-
- bool
- GetCanBeActive () const
- {
- return m_can_activate;
- }
+ MenuActionResult Action() {
+ // Call the recursive action so it can try to handle it
+ // with the menu delegate, and if not, try our parent menu
+ return ActionPrivate(*this);
+ }
- void
- SetCanBeActive (bool b)
- {
- m_can_activate = b;
- }
-
- const WindowDelegateSP &
- GetDelegate () const
- {
- return m_delegate_sp;
- }
+ void SetCannedResult(MenuActionResult result) { m_canned_result = result; }
- void
- SetDelegate (const WindowDelegateSP &delegate_sp)
- {
- m_delegate_sp = delegate_sp;
- }
-
- Window *
- GetParent () const
- {
- return m_parent;
- }
-
- bool
- IsActive () const
- {
- if (m_parent)
- return m_parent->GetActiveWindow().get() == this;
- else
- return true; // Top level window is always active
- }
-
- void
- SelectNextWindowAsActive ()
- {
- // Move active focus to next window
- const size_t num_subwindows = m_subwindows.size();
- if (m_curr_active_window_idx == UINT32_MAX)
- {
- uint32_t idx = 0;
- for (auto subwindow_sp : m_subwindows)
- {
- if (subwindow_sp->GetCanBeActive())
- {
- m_curr_active_window_idx = idx;
- break;
- }
- ++idx;
- }
- }
- else if (m_curr_active_window_idx + 1 < num_subwindows)
- {
- bool handled = false;
- m_prev_active_window_idx = m_curr_active_window_idx;
- for (size_t idx=m_curr_active_window_idx + 1; idx<num_subwindows; ++idx)
- {
- if (m_subwindows[idx]->GetCanBeActive())
- {
- m_curr_active_window_idx = idx;
- handled = true;
- break;
- }
- }
- if (!handled)
- {
- for (size_t idx=0; idx<=m_prev_active_window_idx; ++idx)
- {
- if (m_subwindows[idx]->GetCanBeActive())
- {
- m_curr_active_window_idx = idx;
- break;
- }
- }
- }
- }
- else
- {
- m_prev_active_window_idx = m_curr_active_window_idx;
- for (size_t idx=0; idx<num_subwindows; ++idx)
- {
- if (m_subwindows[idx]->GetCanBeActive())
- {
- m_curr_active_window_idx = idx;
- break;
- }
- }
- }
- }
+ Menus &GetSubmenus() { return m_submenus; }
- const char *
- GetName () const
- {
- return m_name.c_str();
- }
+ const Menus &GetSubmenus() const { return m_submenus; }
- protected:
- std::string m_name;
- WINDOW *m_window;
- PANEL *m_panel;
- Window *m_parent;
- Windows m_subwindows;
- WindowDelegateSP m_delegate_sp;
- uint32_t m_curr_active_window_idx;
- uint32_t m_prev_active_window_idx;
- bool m_delete;
- bool m_needs_update;
- bool m_can_activate;
- bool m_is_subwin;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(Window);
- };
-
- class MenuDelegate
- {
- public:
- virtual ~MenuDelegate() = default;
+ int GetSelectedSubmenuIndex() const { return m_selected; }
- virtual MenuActionResult
- MenuDelegateAction (Menu &menu) = 0;
- };
+ void SetSelectedSubmenuIndex(int idx) { m_selected = idx; }
- class Menu : public WindowDelegate
- {
- public:
- enum class Type
- {
- Invalid,
- Bar,
- Item,
- Separator
- };
-
- // Menubar or separator constructor
- Menu (Type type);
-
- // Menuitem constructor
- Menu (const char *name,
- const char *key_name,
- int key_value,
- uint64_t identifier);
-
- ~Menu() override = default;
-
- const MenuDelegateSP &
- GetDelegate () const
- {
- return m_delegate_sp;
- }
-
- void
- SetDelegate (const MenuDelegateSP &delegate_sp)
- {
- m_delegate_sp = delegate_sp;
- }
-
- void
- RecalculateNameLengths();
-
- void
- AddSubmenu (const MenuSP &menu_sp);
-
- int
- DrawAndRunMenu (Window &window);
-
- void
- DrawMenuTitle (Window &window, bool highlight);
-
- bool
- WindowDelegateDraw (Window &window, bool force) override;
-
- HandleCharResult
- WindowDelegateHandleChar (Window &window, int key) override;
-
- MenuActionResult
- ActionPrivate (Menu &menu)
- {
- MenuActionResult result = MenuActionResult::NotHandled;
- if (m_delegate_sp)
- {
- result = m_delegate_sp->MenuDelegateAction (menu);
- if (result != MenuActionResult::NotHandled)
- return result;
- }
- else if (m_parent)
- {
- result = m_parent->ActionPrivate(menu);
- if (result != MenuActionResult::NotHandled)
- return result;
- }
- return m_canned_result;
- }
+ Type GetType() const { return m_type; }
- MenuActionResult
- Action ()
- {
- // Call the recursive action so it can try to handle it
- // with the menu delegate, and if not, try our parent menu
- return ActionPrivate (*this);
- }
-
- void
- SetCannedResult (MenuActionResult result)
- {
- m_canned_result = result;
- }
+ int GetStartingColumn() const { return m_start_col; }
- Menus &
- GetSubmenus()
- {
- return m_submenus;
- }
+ void SetStartingColumn(int col) { m_start_col = col; }
- const Menus &
- GetSubmenus() const
- {
- return m_submenus;
- }
+ int GetKeyValue() const { return m_key_value; }
- int
- GetSelectedSubmenuIndex () const
- {
- return m_selected;
- }
-
- void
- SetSelectedSubmenuIndex (int idx)
- {
- m_selected = idx;
- }
+ void SetKeyValue(int key_value) { m_key_value = key_value; }
- Type
- GetType () const
- {
- return m_type;
- }
-
- int
- GetStartingColumn() const
- {
- return m_start_col;
- }
+ std::string &GetName() { return m_name; }
- void
- SetStartingColumn(int col)
- {
- m_start_col = col;
- }
+ std::string &GetKeyName() { return m_key_name; }
- int
- GetKeyValue() const
- {
- return m_key_value;
- }
-
- void
- SetKeyValue(int key_value)
- {
- m_key_value = key_value;
- }
+ int GetDrawWidth() const {
+ return m_max_submenu_name_length + m_max_submenu_key_name_length + 8;
+ }
- std::string &
- GetName()
- {
- return m_name;
- }
+ uint64_t GetIdentifier() const { return m_identifier; }
- std::string &
- GetKeyName()
- {
- return m_key_name;
- }
+ void SetIdentifier(uint64_t identifier) { m_identifier = identifier; }
- int
- GetDrawWidth () const
- {
- return m_max_submenu_name_length + m_max_submenu_key_name_length + 8;
- }
+protected:
+ std::string m_name;
+ std::string m_key_name;
+ uint64_t m_identifier;
+ Type m_type;
+ int m_key_value;
+ int m_start_col;
+ int m_max_submenu_name_length;
+ int m_max_submenu_key_name_length;
+ int m_selected;
+ Menu *m_parent;
+ Menus m_submenus;
+ WindowSP m_menu_window_sp;
+ MenuActionResult m_canned_result;
+ MenuDelegateSP m_delegate_sp;
+};
- uint64_t
- GetIdentifier() const
- {
- return m_identifier;
- }
+// Menubar or separator constructor
+Menu::Menu(Type type)
+ : m_name(), m_key_name(), m_identifier(0), m_type(type), m_key_value(0),
+ m_start_col(0), m_max_submenu_name_length(0),
+ m_max_submenu_key_name_length(0), m_selected(0), m_parent(nullptr),
+ m_submenus(), m_canned_result(MenuActionResult::NotHandled),
+ m_delegate_sp() {}
+
+// Menuitem constructor
+Menu::Menu(const char *name, const char *key_name, int key_value,
+ uint64_t identifier)
+ : m_name(), m_key_name(), m_identifier(identifier), m_type(Type::Invalid),
+ m_key_value(key_value), m_start_col(0), m_max_submenu_name_length(0),
+ m_max_submenu_key_name_length(0), m_selected(0), m_parent(nullptr),
+ m_submenus(), m_canned_result(MenuActionResult::NotHandled),
+ m_delegate_sp() {
+ if (name && name[0]) {
+ m_name = name;
+ m_type = Type::Item;
+ if (key_name && key_name[0])
+ m_key_name = key_name;
+ } else {
+ m_type = Type::Separator;
+ }
+}
- void
- SetIdentifier (uint64_t identifier)
- {
- m_identifier = identifier;
- }
+void Menu::RecalculateNameLengths() {
+ m_max_submenu_name_length = 0;
+ m_max_submenu_key_name_length = 0;
+ Menus &submenus = GetSubmenus();
+ const size_t num_submenus = submenus.size();
+ for (size_t i = 0; i < num_submenus; ++i) {
+ Menu *submenu = submenus[i].get();
+ if (static_cast<size_t>(m_max_submenu_name_length) < submenu->m_name.size())
+ m_max_submenu_name_length = submenu->m_name.size();
+ if (static_cast<size_t>(m_max_submenu_key_name_length) <
+ submenu->m_key_name.size())
+ m_max_submenu_key_name_length = submenu->m_key_name.size();
+ }
+}
- protected:
- std::string m_name;
- std::string m_key_name;
- uint64_t m_identifier;
- Type m_type;
- int m_key_value;
- int m_start_col;
- int m_max_submenu_name_length;
- int m_max_submenu_key_name_length;
- int m_selected;
- Menu *m_parent;
- Menus m_submenus;
- WindowSP m_menu_window_sp;
- MenuActionResult m_canned_result;
- MenuDelegateSP m_delegate_sp;
- };
-
- // Menubar or separator constructor
- Menu::Menu (Type type) :
- m_name (),
- m_key_name (),
- m_identifier (0),
- m_type (type),
- m_key_value (0),
- m_start_col (0),
- m_max_submenu_name_length (0),
- m_max_submenu_key_name_length (0),
- m_selected (0),
- m_parent(nullptr),
- m_submenus (),
- m_canned_result (MenuActionResult::NotHandled),
- m_delegate_sp()
- {
+void Menu::AddSubmenu(const MenuSP &menu_sp) {
+ menu_sp->m_parent = this;
+ if (static_cast<size_t>(m_max_submenu_name_length) < menu_sp->m_name.size())
+ m_max_submenu_name_length = menu_sp->m_name.size();
+ if (static_cast<size_t>(m_max_submenu_key_name_length) <
+ menu_sp->m_key_name.size())
+ m_max_submenu_key_name_length = menu_sp->m_key_name.size();
+ m_submenus.push_back(menu_sp);
+}
+
+void Menu::DrawMenuTitle(Window &window, bool highlight) {
+ if (m_type == Type::Separator) {
+ window.MoveCursor(0, window.GetCursorY());
+ window.PutChar(ACS_LTEE);
+ int width = window.GetWidth();
+ if (width > 2) {
+ width -= 2;
+ for (int i = 0; i < width; ++i)
+ window.PutChar(ACS_HLINE);
+ }
+ window.PutChar(ACS_RTEE);
+ } else {
+ const int shortcut_key = m_key_value;
+ bool underlined_shortcut = false;
+ const attr_t hilgight_attr = A_REVERSE;
+ if (highlight)
+ window.AttributeOn(hilgight_attr);
+ if (isprint(shortcut_key)) {
+ size_t lower_pos = m_name.find(tolower(shortcut_key));
+ size_t upper_pos = m_name.find(toupper(shortcut_key));
+ const char *name = m_name.c_str();
+ size_t pos = std::min<size_t>(lower_pos, upper_pos);
+ if (pos != std::string::npos) {
+ underlined_shortcut = true;
+ if (pos > 0) {
+ window.PutCString(name, pos);
+ name += pos;
+ }
+ const attr_t shortcut_attr = A_UNDERLINE | A_BOLD;
+ window.AttributeOn(shortcut_attr);
+ window.PutChar(name[0]);
+ window.AttributeOff(shortcut_attr);
+ name++;
+ if (name[0])
+ window.PutCString(name);
+ }
}
- // Menuitem constructor
- Menu::Menu (const char *name,
- const char *key_name,
- int key_value,
- uint64_t identifier) :
- m_name (),
- m_key_name (),
- m_identifier (identifier),
- m_type (Type::Invalid),
- m_key_value (key_value),
- m_start_col (0),
- m_max_submenu_name_length (0),
- m_max_submenu_key_name_length (0),
- m_selected (0),
- m_parent(nullptr),
- m_submenus (),
- m_canned_result (MenuActionResult::NotHandled),
- m_delegate_sp()
- {
- if (name && name[0])
- {
- m_name = name;
- m_type = Type::Item;
- if (key_name && key_name[0])
- m_key_name = key_name;
- }
- else
- {
- m_type = Type::Separator;
- }
+ if (!underlined_shortcut) {
+ window.PutCString(m_name.c_str());
}
- void
- Menu::RecalculateNameLengths()
- {
- m_max_submenu_name_length = 0;
- m_max_submenu_key_name_length = 0;
- Menus &submenus = GetSubmenus();
- const size_t num_submenus = submenus.size();
- for (size_t i = 0; i < num_submenus; ++i)
- {
- Menu *submenu = submenus[i].get();
- if (static_cast<size_t>(m_max_submenu_name_length) < submenu->m_name.size())
- m_max_submenu_name_length = submenu->m_name.size();
- if (static_cast<size_t>(m_max_submenu_key_name_length) < submenu->m_key_name.size())
- m_max_submenu_key_name_length = submenu->m_key_name.size();
- }
+ if (highlight)
+ window.AttributeOff(hilgight_attr);
+
+ if (m_key_name.empty()) {
+ if (!underlined_shortcut && isprint(m_key_value)) {
+ window.AttributeOn(COLOR_PAIR(3));
+ window.Printf(" (%c)", m_key_value);
+ window.AttributeOff(COLOR_PAIR(3));
+ }
+ } else {
+ window.AttributeOn(COLOR_PAIR(3));
+ window.Printf(" (%s)", m_key_name.c_str());
+ window.AttributeOff(COLOR_PAIR(3));
}
+ }
+}
- void
- Menu::AddSubmenu (const MenuSP &menu_sp)
- {
- menu_sp->m_parent = this;
- if (static_cast<size_t>(m_max_submenu_name_length) < menu_sp->m_name.size())
- m_max_submenu_name_length = menu_sp->m_name.size();
- if (static_cast<size_t>(m_max_submenu_key_name_length) < menu_sp->m_key_name.size())
- m_max_submenu_key_name_length = menu_sp->m_key_name.size();
- m_submenus.push_back(menu_sp);
+bool Menu::WindowDelegateDraw(Window &window, bool force) {
+ Menus &submenus = GetSubmenus();
+ const size_t num_submenus = submenus.size();
+ const int selected_idx = GetSelectedSubmenuIndex();
+ Menu::Type menu_type = GetType();
+ switch (menu_type) {
+ case Menu::Type::Bar: {
+ window.SetBackground(2);
+ window.MoveCursor(0, 0);
+ for (size_t i = 0; i < num_submenus; ++i) {
+ Menu *menu = submenus[i].get();
+ if (i > 0)
+ window.PutChar(' ');
+ menu->SetStartingColumn(window.GetCursorX());
+ window.PutCString("| ");
+ menu->DrawMenuTitle(window, false);
}
+ window.PutCString(" |");
+ window.DeferredRefresh();
+ } break;
- void
- Menu::DrawMenuTitle (Window &window, bool highlight)
- {
- if (m_type == Type::Separator)
- {
- window.MoveCursor(0, window.GetCursorY());
- window.PutChar(ACS_LTEE);
- int width = window.GetWidth();
- if (width > 2)
- {
- width -= 2;
- for (int i = 0; i < width; ++i)
- window.PutChar(ACS_HLINE);
- }
- window.PutChar(ACS_RTEE);
- }
- else
- {
- const int shortcut_key = m_key_value;
- bool underlined_shortcut = false;
- const attr_t hilgight_attr = A_REVERSE;
- if (highlight)
- window.AttributeOn(hilgight_attr);
- if (isprint(shortcut_key))
- {
- size_t lower_pos = m_name.find(tolower(shortcut_key));
- size_t upper_pos = m_name.find(toupper(shortcut_key));
- const char *name = m_name.c_str();
- size_t pos = std::min<size_t>(lower_pos, upper_pos);
- if (pos != std::string::npos)
- {
- underlined_shortcut = true;
- if (pos > 0)
- {
- window.PutCString(name, pos);
- name += pos;
- }
- const attr_t shortcut_attr = A_UNDERLINE|A_BOLD;
- window.AttributeOn (shortcut_attr);
- window.PutChar(name[0]);
- window.AttributeOff(shortcut_attr);
- name++;
- if (name[0])
- window.PutCString(name);
- }
- }
-
- if (!underlined_shortcut)
- {
- window.PutCString(m_name.c_str());
- }
+ case Menu::Type::Item: {
+ int y = 1;
+ int x = 3;
+ // Draw the menu
+ int cursor_x = 0;
+ int cursor_y = 0;
+ window.Erase();
+ window.SetBackground(2);
+ window.Box();
+ for (size_t i = 0; i < num_submenus; ++i) {
+ const bool is_selected = (i == static_cast<size_t>(selected_idx));
+ window.MoveCursor(x, y + i);
+ if (is_selected) {
+ // Remember where we want the cursor to be
+ cursor_x = x - 1;
+ cursor_y = y + i;
+ }
+ submenus[i]->DrawMenuTitle(window, is_selected);
+ }
+ window.MoveCursor(cursor_x, cursor_y);
+ window.DeferredRefresh();
+ } break;
+
+ default:
+ case Menu::Type::Separator:
+ break;
+ }
+ return true; // Drawing handled...
+}
- if (highlight)
- window.AttributeOff(hilgight_attr);
+HandleCharResult Menu::WindowDelegateHandleChar(Window &window, int key) {
+ HandleCharResult result = eKeyNotHandled;
+
+ Menus &submenus = GetSubmenus();
+ const size_t num_submenus = submenus.size();
+ const int selected_idx = GetSelectedSubmenuIndex();
+ Menu::Type menu_type = GetType();
+ if (menu_type == Menu::Type::Bar) {
+ MenuSP run_menu_sp;
+ switch (key) {
+ case KEY_DOWN:
+ case KEY_UP:
+ // Show last menu or first menu
+ if (selected_idx < static_cast<int>(num_submenus))
+ run_menu_sp = submenus[selected_idx];
+ else if (!submenus.empty())
+ run_menu_sp = submenus.front();
+ result = eKeyHandled;
+ break;
+
+ case KEY_RIGHT:
+ ++m_selected;
+ if (m_selected >= static_cast<int>(num_submenus))
+ m_selected = 0;
+ if (m_selected < static_cast<int>(num_submenus))
+ run_menu_sp = submenus[m_selected];
+ else if (!submenus.empty())
+ run_menu_sp = submenus.front();
+ result = eKeyHandled;
+ break;
+
+ case KEY_LEFT:
+ --m_selected;
+ if (m_selected < 0)
+ m_selected = num_submenus - 1;
+ if (m_selected < static_cast<int>(num_submenus))
+ run_menu_sp = submenus[m_selected];
+ else if (!submenus.empty())
+ run_menu_sp = submenus.front();
+ result = eKeyHandled;
+ break;
+
+ default:
+ for (size_t i = 0; i < num_submenus; ++i) {
+ if (submenus[i]->GetKeyValue() == key) {
+ SetSelectedSubmenuIndex(i);
+ run_menu_sp = submenus[i];
+ result = eKeyHandled;
+ break;
+ }
+ }
+ break;
+ }
- if (m_key_name.empty())
- {
- if (!underlined_shortcut && isprint(m_key_value))
- {
- window.AttributeOn (COLOR_PAIR(3));
- window.Printf (" (%c)", m_key_value);
- window.AttributeOff (COLOR_PAIR(3));
- }
- }
- else
- {
- window.AttributeOn (COLOR_PAIR(3));
- window.Printf (" (%s)", m_key_name.c_str());
- window.AttributeOff (COLOR_PAIR(3));
- }
- }
+ if (run_menu_sp) {
+ // 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 calculated
+ if (run_menu_sp->Action() == MenuActionResult::Quit)
+ return eQuitApplication;
+
+ Rect menu_bounds;
+ menu_bounds.origin.x = run_menu_sp->GetStartingColumn();
+ menu_bounds.origin.y = 1;
+ menu_bounds.size.width = run_menu_sp->GetDrawWidth();
+ menu_bounds.size.height = run_menu_sp->GetSubmenus().size() + 2;
+ if (m_menu_window_sp)
+ window.GetParent()->RemoveSubWindow(m_menu_window_sp.get());
+
+ m_menu_window_sp = window.GetParent()->CreateSubWindow(
+ run_menu_sp->GetName().c_str(), menu_bounds, true);
+ m_menu_window_sp->SetDelegate(run_menu_sp);
}
-
- bool
- Menu::WindowDelegateDraw (Window &window, bool force)
- {
- Menus &submenus = GetSubmenus();
- const size_t num_submenus = submenus.size();
- const int selected_idx = GetSelectedSubmenuIndex();
- Menu::Type menu_type = GetType ();
- switch (menu_type)
- {
- case Menu::Type::Bar:
- {
- window.SetBackground(2);
- window.MoveCursor(0, 0);
- for (size_t i = 0; i < num_submenus; ++i)
- {
- Menu *menu = submenus[i].get();
- if (i > 0)
- window.PutChar(' ');
- menu->SetStartingColumn (window.GetCursorX());
- window.PutCString("| ");
- menu->DrawMenuTitle (window, false);
- }
- window.PutCString(" |");
- window.DeferredRefresh();
- }
+ } else if (menu_type == Menu::Type::Item) {
+ switch (key) {
+ case KEY_DOWN:
+ if (m_submenus.size() > 1) {
+ const int start_select = m_selected;
+ while (++m_selected != start_select) {
+ if (static_cast<size_t>(m_selected) >= num_submenus)
+ m_selected = 0;
+ if (m_submenus[m_selected]->GetType() == Type::Separator)
+ continue;
+ else
break;
-
- case Menu::Type::Item:
- {
- int y = 1;
- int x = 3;
- // Draw the menu
- int cursor_x = 0;
- int cursor_y = 0;
- window.Erase();
- window.SetBackground(2);
- window.Box();
- for (size_t i = 0; i < num_submenus; ++i)
- {
- const bool is_selected =
- (i == static_cast<size_t>(selected_idx));
- window.MoveCursor(x, y + i);
- if (is_selected)
- {
- // Remember where we want the cursor to be
- cursor_x = x-1;
- cursor_y = y+i;
- }
- submenus[i]->DrawMenuTitle (window, is_selected);
- }
- window.MoveCursor(cursor_x, cursor_y);
- window.DeferredRefresh();
- }
- break;
-
- default:
- case Menu::Type::Separator:
+ }
+ return eKeyHandled;
+ }
+ break;
+
+ case KEY_UP:
+ if (m_submenus.size() > 1) {
+ const int start_select = m_selected;
+ while (--m_selected != start_select) {
+ if (m_selected < static_cast<int>(0))
+ m_selected = num_submenus - 1;
+ if (m_submenus[m_selected]->GetType() == Type::Separator)
+ continue;
+ else
break;
}
- return true; // Drawing handled...
+ return eKeyHandled;
+ }
+ break;
+
+ case KEY_RETURN:
+ if (static_cast<size_t>(selected_idx) < num_submenus) {
+ if (submenus[selected_idx]->Action() == MenuActionResult::Quit)
+ return eQuitApplication;
+ window.GetParent()->RemoveSubWindow(&window);
+ return eKeyHandled;
+ }
+ break;
+
+ case KEY_ESCAPE: // Beware: pressing escape key has 1 to 2 second delay in
+ // case other chars are entered for escaped sequences
+ window.GetParent()->RemoveSubWindow(&window);
+ return eKeyHandled;
+
+ default:
+ for (size_t i = 0; i < num_submenus; ++i) {
+ Menu *menu = submenus[i].get();
+ if (menu->GetKeyValue() == key) {
+ SetSelectedSubmenuIndex(i);
+ window.GetParent()->RemoveSubWindow(&window);
+ if (menu->Action() == MenuActionResult::Quit)
+ return eQuitApplication;
+ return eKeyHandled;
+ }
+ }
+ break;
}
-
- HandleCharResult
- Menu::WindowDelegateHandleChar (Window &window, int key)
- {
- HandleCharResult result = eKeyNotHandled;
-
- Menus &submenus = GetSubmenus();
- const size_t num_submenus = submenus.size();
- const int selected_idx = GetSelectedSubmenuIndex();
- Menu::Type menu_type = GetType ();
- if (menu_type == Menu::Type::Bar)
- {
- MenuSP run_menu_sp;
- switch (key)
- {
- case KEY_DOWN:
- case KEY_UP:
- // Show last menu or first menu
- if (selected_idx < static_cast<int>(num_submenus))
- run_menu_sp = submenus[selected_idx];
- else if (!submenus.empty())
- run_menu_sp = submenus.front();
- result = eKeyHandled;
- break;
-
- case KEY_RIGHT:
- ++m_selected;
- if (m_selected >= static_cast<int>(num_submenus))
- m_selected = 0;
- if (m_selected < static_cast<int>(num_submenus))
- run_menu_sp = submenus[m_selected];
- else if (!submenus.empty())
- run_menu_sp = submenus.front();
- result = eKeyHandled;
- break;
-
- case KEY_LEFT:
- --m_selected;
- if (m_selected < 0)
- m_selected = num_submenus - 1;
- if (m_selected < static_cast<int>(num_submenus))
- run_menu_sp = submenus[m_selected];
- else if (!submenus.empty())
- run_menu_sp = submenus.front();
- result = eKeyHandled;
- break;
-
- default:
- for (size_t i = 0; i < num_submenus; ++i)
- {
- if (submenus[i]->GetKeyValue() == key)
- {
- SetSelectedSubmenuIndex(i);
- run_menu_sp = submenus[i];
- result = eKeyHandled;
- break;
- }
- }
- break;
- }
-
- if (run_menu_sp)
- {
- // 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 calculated
- if (run_menu_sp->Action() == MenuActionResult::Quit)
- return eQuitApplication;
-
- Rect menu_bounds;
- menu_bounds.origin.x = run_menu_sp->GetStartingColumn();
- menu_bounds.origin.y = 1;
- menu_bounds.size.width = run_menu_sp->GetDrawWidth();
- menu_bounds.size.height = run_menu_sp->GetSubmenus().size() + 2;
- if (m_menu_window_sp)
- window.GetParent()->RemoveSubWindow(m_menu_window_sp.get());
-
- m_menu_window_sp = window.GetParent()->CreateSubWindow (run_menu_sp->GetName().c_str(),
- menu_bounds,
- true);
- m_menu_window_sp->SetDelegate (run_menu_sp);
- }
- }
- else if (menu_type == Menu::Type::Item)
- {
- switch (key)
- {
- case KEY_DOWN:
- if (m_submenus.size() > 1)
- {
- const int start_select = m_selected;
- while (++m_selected != start_select)
- {
- if (static_cast<size_t>(m_selected) >= num_submenus)
- m_selected = 0;
- if (m_submenus[m_selected]->GetType() == Type::Separator)
- continue;
- else
- break;
- }
- return eKeyHandled;
- }
- break;
-
- case KEY_UP:
- if (m_submenus.size() > 1)
- {
- const int start_select = m_selected;
- while (--m_selected != start_select)
- {
- if (m_selected < static_cast<int>(0))
- m_selected = num_submenus - 1;
- if (m_submenus[m_selected]->GetType() == Type::Separator)
- continue;
- else
- break;
- }
- return eKeyHandled;
- }
- break;
-
- case KEY_RETURN:
- if (static_cast<size_t>(selected_idx) < num_submenus)
- {
- if (submenus[selected_idx]->Action() == MenuActionResult::Quit)
- return eQuitApplication;
- window.GetParent()->RemoveSubWindow(&window);
- return eKeyHandled;
- }
- break;
-
- case KEY_ESCAPE: // Beware: pressing escape key has 1 to 2 second delay in case other chars are entered for escaped sequences
- window.GetParent()->RemoveSubWindow(&window);
- return eKeyHandled;
-
- default:
- for (size_t i = 0; i < num_submenus; ++i)
- {
- Menu *menu = submenus[i].get();
- if (menu->GetKeyValue() == key)
- {
- SetSelectedSubmenuIndex(i);
- window.GetParent()->RemoveSubWindow(&window);
- if (menu->Action() == MenuActionResult::Quit)
- return eQuitApplication;
- return eKeyHandled;
- }
- }
- break;
- }
- }
- else if (menu_type == Menu::Type::Separator)
- {
- }
- return result;
+ } else if (menu_type == Menu::Type::Separator) {
+ }
+ return result;
+}
+
+class Application {
+public:
+ Application(FILE *in, FILE *out)
+ : m_window_sp(), m_screen(nullptr), m_in(in), m_out(out) {}
+
+ ~Application() {
+ m_window_delegates.clear();
+ m_window_sp.reset();
+ if (m_screen) {
+ ::delscreen(m_screen);
+ m_screen = nullptr;
}
+ }
- class Application
- {
- public:
- Application (FILE *in, FILE *out) :
- m_window_sp(),
- m_screen(nullptr),
- m_in (in),
- m_out (out)
- {
- }
-
- ~Application ()
- {
- m_window_delegates.clear();
- m_window_sp.reset();
- if (m_screen)
- {
- ::delscreen(m_screen);
- m_screen = nullptr;
- }
- }
-
- void
- Initialize ()
- {
- ::setlocale(LC_ALL, "");
- ::setlocale(LC_CTYPE, "");
+ void Initialize() {
+ ::setlocale(LC_ALL, "");
+ ::setlocale(LC_CTYPE, "");
#if 0
::initscr();
#else
- m_screen = ::newterm(nullptr, m_out, m_in);
+ m_screen = ::newterm(nullptr, m_out, m_in);
#endif
- ::start_color();
- ::curs_set(0);
- ::noecho();
- ::keypad(stdscr,TRUE);
- }
-
- void
- Terminate ()
- {
- ::endwin();
- }
-
- void
- Run (Debugger &debugger)
- {
- bool done = false;
- int delay_in_tenths_of_a_second = 1;
-
- // Alas the threading model in curses is a bit lame so we need to
- // resort to polling every 0.5 seconds. We could poll for stdin
- // ourselves and then pass the keys down but then we need to
- // translate all of the escape sequences ourselves. So we resort to
- // polling for input because we need to receive async process events
- // while in this loop.
-
- halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths of seconds seconds when calling Window::GetChar()
-
- ListenerSP listener_sp (Listener::MakeListener("lldb.IOHandler.curses.Application"));
- ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
- ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
- ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
- debugger.EnableForwardEvents (listener_sp);
-
- bool update = true;
+ ::start_color();
+ ::curs_set(0);
+ ::noecho();
+ ::keypad(stdscr, TRUE);
+ }
+
+ void Terminate() { ::endwin(); }
+
+ void Run(Debugger &debugger) {
+ bool done = false;
+ int delay_in_tenths_of_a_second = 1;
+
+ // Alas the threading model in curses is a bit lame so we need to
+ // resort to polling every 0.5 seconds. We could poll for stdin
+ // ourselves and then pass the keys down but then we need to
+ // translate all of the escape sequences ourselves. So we resort to
+ // polling for input because we need to receive async process events
+ // while in this loop.
+
+ halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths
+ // of seconds seconds when calling
+ // Window::GetChar()
+
+ ListenerSP listener_sp(
+ Listener::MakeListener("lldb.IOHandler.curses.Application"));
+ ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
+ ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
+ ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
+ debugger.EnableForwardEvents(listener_sp);
+
+ bool update = true;
#if defined(__APPLE__)
- std::deque<int> escape_chars;
+ std::deque<int> escape_chars;
#endif
-
- while (!done)
- {
- if (update)
- {
- m_window_sp->Draw(false);
- // All windows should be calling Window::DeferredRefresh() instead
- // of Window::Refresh() so we can do a single update and avoid
- // any screen blinking
- update_panels();
-
- // Cursor hiding isn't working on MacOSX, so hide it in the top left corner
- m_window_sp->MoveCursor(0, 0);
-
- doupdate();
- update = false;
- }
-
+
+ while (!done) {
+ if (update) {
+ m_window_sp->Draw(false);
+ // All windows should be calling Window::DeferredRefresh() instead
+ // of Window::Refresh() so we can do a single update and avoid
+ // any screen blinking
+ update_panels();
+
+ // Cursor hiding isn't working on MacOSX, so hide it in the top left
+ // corner
+ m_window_sp->MoveCursor(0, 0);
+
+ doupdate();
+ update = false;
+ }
+
#if defined(__APPLE__)
- // Terminal.app doesn't map its function keys correctly, F1-F4 default to:
- // \033OP, \033OQ, \033OR, \033OS, so lets take care of this here if possible
- int ch;
- if (escape_chars.empty())
- ch = m_window_sp->GetChar();
- else
- {
- ch = escape_chars.front();
- escape_chars.pop_front();
- }
- if (ch == KEY_ESCAPE)
- {
- int ch2 = m_window_sp->GetChar();
- if (ch2 == 'O')
- {
- int ch3 = m_window_sp->GetChar();
- switch (ch3)
- {
- case 'P': ch = KEY_F(1); break;
- case 'Q': ch = KEY_F(2); break;
- case 'R': ch = KEY_F(3); break;
- case 'S': ch = KEY_F(4); break;
- default:
- escape_chars.push_back(ch2);
- if (ch3 != -1)
- escape_chars.push_back(ch3);
- break;
- }
- }
- else if (ch2 != -1)
- escape_chars.push_back(ch2);
- }
+ // Terminal.app doesn't map its function keys correctly, F1-F4 default to:
+ // \033OP, \033OQ, \033OR, \033OS, so lets take care of this here if
+ // possible
+ int ch;
+ if (escape_chars.empty())
+ ch = m_window_sp->GetChar();
+ else {
+ ch = escape_chars.front();
+ escape_chars.pop_front();
+ }
+ if (ch == KEY_ESCAPE) {
+ int ch2 = m_window_sp->GetChar();
+ if (ch2 == 'O') {
+ int ch3 = m_window_sp->GetChar();
+ switch (ch3) {
+ case 'P':
+ ch = KEY_F(1);
+ break;
+ case 'Q':
+ ch = KEY_F(2);
+ break;
+ case 'R':
+ ch = KEY_F(3);
+ break;
+ case 'S':
+ ch = KEY_F(4);
+ break;
+ default:
+ escape_chars.push_back(ch2);
+ if (ch3 != -1)
+ escape_chars.push_back(ch3);
+ break;
+ }
+ } else if (ch2 != -1)
+ escape_chars.push_back(ch2);
+ }
#else
- int ch = m_window_sp->GetChar();
+ int ch = m_window_sp->GetChar();
#endif
- if (ch == -1)
- {
- if (feof(m_in) || ferror(m_in))
- {
- done = true;
- }
- else
- {
- // Just a timeout from using halfdelay(), check for events
- EventSP event_sp;
- while (listener_sp->PeekAtNextEvent())
- {
- listener_sp->GetNextEvent(event_sp);
-
- if (event_sp)
- {
- Broadcaster *broadcaster = event_sp->GetBroadcaster();
- if (broadcaster)
- {
- //uint32_t event_type = event_sp->GetType();
- ConstString broadcaster_class (broadcaster->GetBroadcasterClass());
- if (broadcaster_class == broadcaster_class_process)
- {
- debugger.GetCommandInterpreter().UpdateExecutionContext(nullptr);
- update = true;
- continue; // Don't get any key, just update our view
- }
- }
- }
- }
- }
- }
- else
- {
- HandleCharResult key_result = m_window_sp->HandleChar(ch);
- switch (key_result)
- {
- case eKeyHandled:
- debugger.GetCommandInterpreter().UpdateExecutionContext(nullptr);
- update = true;
- break;
- case eKeyNotHandled:
- break;
- case eQuitApplication:
- done = true;
- break;
- }
+ if (ch == -1) {
+ if (feof(m_in) || ferror(m_in)) {
+ done = true;
+ } else {
+ // Just a timeout from using halfdelay(), check for events
+ EventSP event_sp;
+ while (listener_sp->PeekAtNextEvent()) {
+ listener_sp->GetEvent(event_sp, std::chrono::seconds(0));
+
+ if (event_sp) {
+ Broadcaster *broadcaster = event_sp->GetBroadcaster();
+ if (broadcaster) {
+ // uint32_t event_type = event_sp->GetType();
+ ConstString broadcaster_class(
+ broadcaster->GetBroadcasterClass());
+ if (broadcaster_class == broadcaster_class_process) {
+ debugger.GetCommandInterpreter().UpdateExecutionContext(
+ nullptr);
+ update = true;
+ continue; // Don't get any key, just update our view
}
+ }
}
-
- debugger.CancelForwardEvents (listener_sp);
- }
-
- WindowSP &
- GetMainWindow ()
- {
- if (!m_window_sp)
- m_window_sp.reset (new Window ("main", stdscr, false));
- return m_window_sp;
- }
-
- WindowDelegates &
- GetWindowDelegates ()
- {
- return m_window_delegates;
- }
+ }
+ }
+ } else {
+ HandleCharResult key_result = m_window_sp->HandleChar(ch);
+ switch (key_result) {
+ case eKeyHandled:
+ debugger.GetCommandInterpreter().UpdateExecutionContext(nullptr);
+ update = true;
+ break;
+ case eKeyNotHandled:
+ break;
+ case eQuitApplication:
+ done = true;
+ break;
+ }
+ }
+ }
+
+ debugger.CancelForwardEvents(listener_sp);
+ }
+
+ WindowSP &GetMainWindow() {
+ if (!m_window_sp)
+ m_window_sp.reset(new Window("main", stdscr, false));
+ return m_window_sp;
+ }
- protected:
- WindowSP m_window_sp;
- WindowDelegates m_window_delegates;
- SCREEN *m_screen;
- FILE *m_in;
- FILE *m_out;
- };
+ WindowDelegates &GetWindowDelegates() { return m_window_delegates; }
+
+protected:
+ WindowSP m_window_sp;
+ WindowDelegates m_window_delegates;
+ SCREEN *m_screen;
+ FILE *m_in;
+ FILE *m_out;
+};
} // namespace curses
using namespace curses;
-struct Row
-{
- ValueObjectSP valobj;
- Row *parent;
- int row_idx;
- int x;
- int y;
- bool might_have_children;
- bool expanded;
- bool calculated_children;
- std::vector<Row> children;
-
- Row (const ValueObjectSP &v, Row *p) :
- valobj (v),
- parent (p),
- row_idx(0),
- x(1),
- y(1),
- might_have_children (v ? v->MightHaveChildren() : false),
- expanded (false),
- calculated_children (false),
- children()
- {
- }
-
- size_t
- GetDepth () const
- {
- if (parent)
- return 1 + parent->GetDepth();
- return 0;
- }
-
- void
- Expand()
- {
- expanded = true;
- if (!calculated_children)
- {
- calculated_children = true;
- if (valobj)
- {
- const size_t num_children = valobj->GetNumChildren();
- for (size_t i = 0; i < num_children; ++i)
- {
- children.push_back(Row (valobj->GetChildAtIndex(i, true), this));
- }
- }
- }
+struct Row {
+ ValueObjectManager value;
+ Row *parent;
+ // The process stop ID when the children were calculated.
+ uint32_t children_stop_id;
+ int row_idx;
+ int x;
+ int y;
+ bool might_have_children;
+ bool expanded;
+ bool calculated_children;
+ std::vector<Row> children;
+
+ Row(const ValueObjectSP &v, Row *p)
+ : value(v, lldb::eDynamicDontRunTarget, true), parent(p), row_idx(0),
+ x(1), y(1), might_have_children(v ? v->MightHaveChildren() : false),
+ expanded(false), calculated_children(false), children() {}
+
+ size_t GetDepth() const {
+ if (parent)
+ return 1 + parent->GetDepth();
+ return 0;
+ }
+
+ void Expand() {
+ expanded = true;
+ }
+
+ std::vector<Row> &GetChildren() {
+ ProcessSP process_sp = value.GetProcessSP();
+ auto stop_id = process_sp->GetStopID();
+ if (process_sp && stop_id != children_stop_id) {
+ children_stop_id = stop_id;
+ calculated_children = false;
}
-
- void
- Unexpand ()
- {
- expanded = false;
+ if (!calculated_children) {
+ children.clear();
+ calculated_children = true;
+ ValueObjectSP valobj = value.GetSP();
+ if (valobj) {
+ const size_t num_children = valobj->GetNumChildren();
+ for (size_t i = 0; i < num_children; ++i) {
+ children.push_back(Row(valobj->GetChildAtIndex(i, true), this));
+ }
+ }
}
-
- void
- DrawTree (Window &window)
- {
- if (parent)
- parent->DrawTreeForChild (window, this, 0);
-
- if (might_have_children)
- {
- // It we can get UTF8 characters to work we should try to use the "symbol"
- // UTF8 string below
-// const char *symbol = "";
-// if (row.expanded)
-// symbol = "\xe2\x96\xbd ";
-// else
-// symbol = "\xe2\x96\xb7 ";
-// window.PutCString (symbol);
-
- // The ACS_DARROW and ACS_RARROW don't look very nice they are just a
- // 'v' or '>' character...
-// if (expanded)
-// window.PutChar (ACS_DARROW);
-// else
-// window.PutChar (ACS_RARROW);
- // Since we can't find any good looking right arrow/down arrow
- // symbols, just use a diamond...
- window.PutChar (ACS_DIAMOND);
- window.PutChar (ACS_HLINE);
- }
+ return children;
+ }
+
+ void Unexpand() {
+ expanded = false;
+ calculated_children = false;
+ children.clear();
+ }
+
+ void DrawTree(Window &window) {
+ if (parent)
+ parent->DrawTreeForChild(window, this, 0);
+
+ if (might_have_children) {
+ // It we can get UTF8 characters to work we should try to use the "symbol"
+ // UTF8 string below
+ // const char *symbol = "";
+ // if (row.expanded)
+ // symbol = "\xe2\x96\xbd ";
+ // else
+ // symbol = "\xe2\x96\xb7 ";
+ // window.PutCString (symbol);
+
+ // The ACS_DARROW and ACS_RARROW don't look very nice they are just a
+ // 'v' or '>' character...
+ // if (expanded)
+ // window.PutChar (ACS_DARROW);
+ // else
+ // window.PutChar (ACS_RARROW);
+ // Since we can't find any good looking right arrow/down arrow
+ // symbols, just use a diamond...
+ window.PutChar(ACS_DIAMOND);
+ window.PutChar(ACS_HLINE);
}
-
- void
- DrawTreeForChild (Window &window, Row *child, uint32_t reverse_depth)
- {
- if (parent)
- parent->DrawTreeForChild (window, this, reverse_depth + 1);
-
- if (&children.back() == child)
- {
- // Last child
- if (reverse_depth == 0)
- {
- window.PutChar (ACS_LLCORNER);
- window.PutChar (ACS_HLINE);
- }
- else
- {
- window.PutChar (' ');
- window.PutChar (' ');
- }
- }
- else
- {
- if (reverse_depth == 0)
- {
- window.PutChar (ACS_LTEE);
- window.PutChar (ACS_HLINE);
- }
- else
- {
- window.PutChar (ACS_VLINE);
- window.PutChar (' ');
- }
- }
+ }
+
+ void DrawTreeForChild(Window &window, Row *child, uint32_t reverse_depth) {
+ if (parent)
+ parent->DrawTreeForChild(window, this, reverse_depth + 1);
+
+ if (&GetChildren().back() == child) {
+ // Last child
+ if (reverse_depth == 0) {
+ window.PutChar(ACS_LLCORNER);
+ window.PutChar(ACS_HLINE);
+ } else {
+ window.PutChar(' ');
+ window.PutChar(' ');
+ }
+ } else {
+ if (reverse_depth == 0) {
+ window.PutChar(ACS_LTEE);
+ window.PutChar(ACS_HLINE);
+ } else {
+ window.PutChar(ACS_VLINE);
+ window.PutChar(' ');
+ }
}
+ }
};
-struct DisplayOptions
-{
- bool show_types;
+struct DisplayOptions {
+ bool show_types;
};
class TreeItem;
-class TreeDelegate
-{
+class TreeDelegate {
public:
- TreeDelegate() = default;
- virtual ~TreeDelegate() = default;
+ TreeDelegate() = default;
+ 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
+ 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
-{
+class TreeItem {
public:
- TreeItem (TreeItem *parent, TreeDelegate &delegate, bool might_have_children) :
- m_parent (parent),
- m_delegate (delegate),
- m_user_data(nullptr),
- m_identifier (0),
- m_row_idx (-1),
- m_children (),
- m_might_have_children (might_have_children),
- m_is_expanded (false)
- {
+ TreeItem(TreeItem *parent, TreeDelegate &delegate, bool might_have_children)
+ : m_parent(parent), m_delegate(delegate), m_user_data(nullptr),
+ m_identifier(0), m_row_idx(-1), m_children(),
+ m_might_have_children(might_have_children), m_is_expanded(false) {}
+
+ TreeItem &operator=(const TreeItem &rhs) {
+ if (this != &rhs) {
+ m_parent = rhs.m_parent;
+ m_delegate = rhs.m_delegate;
+ m_user_data = rhs.m_user_data;
+ m_identifier = rhs.m_identifier;
+ m_row_idx = rhs.m_row_idx;
+ m_children = rhs.m_children;
+ m_might_have_children = rhs.m_might_have_children;
+ m_is_expanded = rhs.m_is_expanded;
}
+ return *this;
+ }
- TreeItem &
- operator=(const TreeItem &rhs)
- {
- if (this != &rhs)
- {
- m_parent = rhs.m_parent;
- m_delegate = rhs.m_delegate;
- m_user_data = rhs.m_user_data;
- m_identifier = rhs.m_identifier;
- m_row_idx = rhs.m_row_idx;
- m_children = rhs.m_children;
- m_might_have_children = rhs.m_might_have_children;
- m_is_expanded = rhs.m_is_expanded;
- }
- return *this;
- }
-
- size_t
- GetDepth () const
- {
- if (m_parent)
- return 1 + m_parent->GetDepth();
- return 0;
- }
-
- int
- GetRowIndex () const
- {
- return m_row_idx;
- }
-
- void
- ClearChildren ()
- {
- m_children.clear();
- }
-
- void
- Resize (size_t n, const TreeItem &t)
- {
- m_children.resize(n, t);
- }
-
- TreeItem &
- operator [](size_t i)
- {
- return m_children[i];
- }
+ size_t GetDepth() const {
+ if (m_parent)
+ return 1 + m_parent->GetDepth();
+ return 0;
+ }
- void
- SetRowIndex (int row_idx)
- {
- m_row_idx = row_idx;
- }
+ int GetRowIndex() const { return m_row_idx; }
- size_t
- GetNumChildren ()
- {
- m_delegate.TreeDelegateGenerateChildren (*this);
- return m_children.size();
- }
+ void ClearChildren() { m_children.clear(); }
- void
- ItemWasSelected ()
- {
- m_delegate.TreeDelegateItemSelected(*this);
- }
+ void Resize(size_t n, const TreeItem &t) { m_children.resize(n, t); }
- void
- CalculateRowIndexes (int &row_idx)
- {
- SetRowIndex(row_idx);
- ++row_idx;
-
- const bool expanded = IsExpanded();
-
- // The root item must calculate its children,
- // or we must calculate the number of children
- // if the item is expanded
- if (m_parent == nullptr || expanded)
- GetNumChildren();
-
- for (auto &item : m_children)
- {
- if (expanded)
- item.CalculateRowIndexes(row_idx);
- else
- item.SetRowIndex(-1);
- }
- }
+ TreeItem &operator[](size_t i) { return m_children[i]; }
- TreeItem *
- GetParent ()
- {
- return m_parent;
- }
+ void SetRowIndex(int row_idx) { m_row_idx = row_idx; }
- bool
- IsExpanded () const
- {
- return m_is_expanded;
- }
+ size_t GetNumChildren() {
+ m_delegate.TreeDelegateGenerateChildren(*this);
+ return m_children.size();
+ }
- void
- Expand()
- {
- m_is_expanded = true;
- }
-
- void
- Unexpand ()
- {
- m_is_expanded = false;
- }
-
- bool
- Draw (Window &window,
- const int first_visible_row,
- const uint32_t selected_row_idx,
- int &row_idx,
- int &num_rows_left)
- {
- if (num_rows_left <= 0)
- return false;
-
- if (m_row_idx >= first_visible_row)
- {
- window.MoveCursor(2, row_idx + 1);
-
- if (m_parent)
- m_parent->DrawTreeForChild (window, this, 0);
-
- if (m_might_have_children)
- {
- // It we can get UTF8 characters to work we should try to use the "symbol"
- // UTF8 string below
- // const char *symbol = "";
- // if (row.expanded)
- // symbol = "\xe2\x96\xbd ";
- // else
- // symbol = "\xe2\x96\xb7 ";
- // window.PutCString (symbol);
-
- // The ACS_DARROW and ACS_RARROW don't look very nice they are just a
- // 'v' or '>' character...
- // if (expanded)
- // window.PutChar (ACS_DARROW);
- // else
- // window.PutChar (ACS_RARROW);
- // Since we can't find any good looking right arrow/down arrow
- // symbols, just use a diamond...
- window.PutChar (ACS_DIAMOND);
- window.PutChar (ACS_HLINE);
- }
- bool highlight =
- (selected_row_idx == static_cast<size_t>(m_row_idx)) && window.IsActive();
+ void ItemWasSelected() { m_delegate.TreeDelegateItemSelected(*this); }
- if (highlight)
- window.AttributeOn(A_REVERSE);
+ void CalculateRowIndexes(int &row_idx) {
+ SetRowIndex(row_idx);
+ ++row_idx;
- m_delegate.TreeDelegateDrawTreeItem(*this, window);
+ const bool expanded = IsExpanded();
- if (highlight)
- window.AttributeOff(A_REVERSE);
- ++row_idx;
- --num_rows_left;
- }
+ // The root item must calculate its children,
+ // or we must calculate the number of children
+ // if the item is expanded
+ if (m_parent == nullptr || expanded)
+ GetNumChildren();
- if (num_rows_left <= 0)
- return false; // We are done drawing...
-
- if (IsExpanded())
- {
- for (auto &item : m_children)
- {
- // If we displayed all the rows and item.Draw() returns
- // false we are done drawing and can exit this for loop
- if (!item.Draw(window, first_visible_row, selected_row_idx, row_idx, num_rows_left))
- break;
- }
- }
- return num_rows_left >= 0; // Return true if not done drawing yet
+ for (auto &item : m_children) {
+ if (expanded)
+ item.CalculateRowIndexes(row_idx);
+ else
+ item.SetRowIndex(-1);
}
-
- void
- DrawTreeForChild (Window &window, TreeItem *child, uint32_t reverse_depth)
- {
- if (m_parent)
- m_parent->DrawTreeForChild (window, this, reverse_depth + 1);
-
- if (&m_children.back() == child)
- {
- // Last child
- if (reverse_depth == 0)
- {
- window.PutChar (ACS_LLCORNER);
- window.PutChar (ACS_HLINE);
- }
- else
- {
- window.PutChar (' ');
- window.PutChar (' ');
- }
- }
- else
- {
- if (reverse_depth == 0)
- {
- window.PutChar (ACS_LTEE);
- window.PutChar (ACS_HLINE);
- }
- else
- {
- window.PutChar (ACS_VLINE);
- window.PutChar (' ');
- }
- }
+ }
+
+ TreeItem *GetParent() { return m_parent; }
+
+ bool IsExpanded() const { return m_is_expanded; }
+
+ void Expand() { m_is_expanded = true; }
+
+ void Unexpand() { m_is_expanded = false; }
+
+ bool Draw(Window &window, const int first_visible_row,
+ const uint32_t selected_row_idx, int &row_idx, int &num_rows_left) {
+ if (num_rows_left <= 0)
+ return false;
+
+ if (m_row_idx >= first_visible_row) {
+ window.MoveCursor(2, row_idx + 1);
+
+ if (m_parent)
+ m_parent->DrawTreeForChild(window, this, 0);
+
+ if (m_might_have_children) {
+ // It we can get UTF8 characters to work we should try to use the
+ // "symbol"
+ // UTF8 string below
+ // const char *symbol = "";
+ // if (row.expanded)
+ // symbol = "\xe2\x96\xbd ";
+ // else
+ // symbol = "\xe2\x96\xb7 ";
+ // window.PutCString (symbol);
+
+ // The ACS_DARROW and ACS_RARROW don't look very nice they are just a
+ // 'v' or '>' character...
+ // if (expanded)
+ // window.PutChar (ACS_DARROW);
+ // else
+ // window.PutChar (ACS_RARROW);
+ // Since we can't find any good looking right arrow/down arrow
+ // symbols, just use a diamond...
+ window.PutChar(ACS_DIAMOND);
+ window.PutChar(ACS_HLINE);
+ }
+ bool highlight = (selected_row_idx == static_cast<size_t>(m_row_idx)) &&
+ window.IsActive();
+
+ if (highlight)
+ window.AttributeOn(A_REVERSE);
+
+ m_delegate.TreeDelegateDrawTreeItem(*this, window);
+
+ if (highlight)
+ window.AttributeOff(A_REVERSE);
+ ++row_idx;
+ --num_rows_left;
}
-
- TreeItem *
- GetItemForRowIndex (uint32_t row_idx)
- {
- if (static_cast<uint32_t>(m_row_idx) == row_idx)
- return this;
- if (m_children.empty())
- return nullptr;
- if (IsExpanded())
- {
- for (auto &item : m_children)
- {
- TreeItem *selected_item_ptr = item.GetItemForRowIndex(row_idx);
- if (selected_item_ptr)
- return selected_item_ptr;
- }
- }
- return nullptr;
+
+ if (num_rows_left <= 0)
+ return false; // We are done drawing...
+
+ if (IsExpanded()) {
+ for (auto &item : m_children) {
+ // If we displayed all the rows and item.Draw() returns
+ // false we are done drawing and can exit this for loop
+ if (!item.Draw(window, first_visible_row, selected_row_idx, row_idx,
+ num_rows_left))
+ break;
+ }
}
-
- void *
- GetUserData() const
- {
- return m_user_data;
+ return num_rows_left >= 0; // Return true if not done drawing yet
+ }
+
+ void DrawTreeForChild(Window &window, TreeItem *child,
+ uint32_t reverse_depth) {
+ if (m_parent)
+ m_parent->DrawTreeForChild(window, this, reverse_depth + 1);
+
+ if (&m_children.back() == child) {
+ // Last child
+ if (reverse_depth == 0) {
+ window.PutChar(ACS_LLCORNER);
+ window.PutChar(ACS_HLINE);
+ } else {
+ window.PutChar(' ');
+ window.PutChar(' ');
+ }
+ } else {
+ if (reverse_depth == 0) {
+ window.PutChar(ACS_LTEE);
+ window.PutChar(ACS_HLINE);
+ } else {
+ window.PutChar(ACS_VLINE);
+ window.PutChar(' ');
+ }
}
-
- void
- SetUserData (void *user_data)
- {
- m_user_data = user_data;
+ }
+
+ TreeItem *GetItemForRowIndex(uint32_t row_idx) {
+ if (static_cast<uint32_t>(m_row_idx) == row_idx)
+ return this;
+ if (m_children.empty())
+ return nullptr;
+ if (IsExpanded()) {
+ for (auto &item : m_children) {
+ TreeItem *selected_item_ptr = item.GetItemForRowIndex(row_idx);
+ if (selected_item_ptr)
+ return selected_item_ptr;
+ }
}
+ return nullptr;
+ }
- uint64_t
- GetIdentifier() const
- {
- return m_identifier;
- }
-
- void
- SetIdentifier (uint64_t identifier)
- {
- m_identifier = identifier;
- }
+ void *GetUserData() const { return m_user_data; }
- void
- SetMightHaveChildren (bool b)
- {
- m_might_have_children = b;
- }
+ void SetUserData(void *user_data) { m_user_data = user_data; }
+
+ uint64_t GetIdentifier() const { return m_identifier; }
+
+ void SetIdentifier(uint64_t identifier) { m_identifier = identifier; }
+
+ void SetMightHaveChildren(bool b) { m_might_have_children = b; }
protected:
- TreeItem *m_parent;
- TreeDelegate &m_delegate;
- void *m_user_data;
- uint64_t m_identifier;
- int m_row_idx; // Zero based visible row index, -1 if not visible or for the root item
- std::vector<TreeItem> m_children;
- bool m_might_have_children;
- bool m_is_expanded;
+ TreeItem *m_parent;
+ TreeDelegate &m_delegate;
+ void *m_user_data;
+ uint64_t m_identifier;
+ int m_row_idx; // Zero based visible row index, -1 if not visible or for the
+ // root item
+ std::vector<TreeItem> m_children;
+ bool m_might_have_children;
+ bool m_is_expanded;
};
-class TreeWindowDelegate : public WindowDelegate
-{
+class TreeWindowDelegate : public WindowDelegate {
public:
- TreeWindowDelegate (Debugger &debugger, const TreeDelegateSP &delegate_sp) :
- m_debugger (debugger),
- m_delegate_sp (delegate_sp),
- m_root(nullptr, *delegate_sp, true),
- m_selected_item(nullptr),
- m_num_rows (0),
- m_selected_row_idx (0),
- m_first_visible_row (0),
- m_min_x (0),
- m_min_y (0),
- m_max_x (0),
- m_max_y (0)
- {
- }
-
- int
- NumVisibleRows () const
- {
- return m_max_y - m_min_y;
+ TreeWindowDelegate(Debugger &debugger, const TreeDelegateSP &delegate_sp)
+ : m_debugger(debugger), m_delegate_sp(delegate_sp),
+ m_root(nullptr, *delegate_sp, true), m_selected_item(nullptr),
+ m_num_rows(0), m_selected_row_idx(0), m_first_visible_row(0),
+ m_min_x(0), m_min_y(0), m_max_x(0), m_max_y(0) {}
+
+ int NumVisibleRows() const { return m_max_y - m_min_y; }
+
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ ExecutionContext exe_ctx(
+ m_debugger.GetCommandInterpreter().GetExecutionContext());
+ Process *process = exe_ctx.GetProcessPtr();
+
+ bool display_content = false;
+ if (process) {
+ StateType state = process->GetState();
+ if (StateIsStoppedState(state, true)) {
+ // We are stopped, so it is ok to
+ display_content = true;
+ } else if (StateIsRunningState(state)) {
+ return true; // Don't do any updating when we are running
+ }
}
- bool
- WindowDelegateDraw (Window &window, bool force) override
- {
- ExecutionContext exe_ctx (m_debugger.GetCommandInterpreter().GetExecutionContext());
- Process *process = exe_ctx.GetProcessPtr();
-
- bool display_content = false;
- if (process)
- {
- StateType state = process->GetState();
- if (StateIsStoppedState(state, true))
- {
- // We are stopped, so it is ok to
- display_content = true;
- }
- else if (StateIsRunningState(state))
- {
- return true; // Don't do any updating when we are running
- }
- }
+ m_min_x = 2;
+ m_min_y = 1;
+ m_max_x = window.GetWidth() - 1;
+ m_max_y = window.GetHeight() - 1;
- m_min_x = 2;
- m_min_y = 1;
- m_max_x = window.GetWidth() - 1;
- m_max_y = window.GetHeight() - 1;
-
- window.Erase();
- window.DrawTitleBox (window.GetName());
-
- if (display_content)
- {
- const int num_visible_rows = NumVisibleRows();
- m_num_rows = 0;
- m_root.CalculateRowIndexes(m_num_rows);
-
- // If we unexpanded while having something selected our
- // total number of rows is less than the num visible rows,
- // then make sure we show all the rows by setting the first
- // visible row accordingly.
- if (m_first_visible_row > 0 && m_num_rows < num_visible_rows)
- m_first_visible_row = 0;
-
- // Make sure the selected row is always visible
- if (m_selected_row_idx < m_first_visible_row)
- m_first_visible_row = m_selected_row_idx;
- else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx)
- m_first_visible_row = m_selected_row_idx - num_visible_rows + 1;
-
- int row_idx = 0;
- int num_rows_left = num_visible_rows;
- m_root.Draw (window, m_first_visible_row, m_selected_row_idx, row_idx, num_rows_left);
- // Get the selected row
- m_selected_item = m_root.GetItemForRowIndex (m_selected_row_idx);
- }
- else
- {
- m_selected_item = nullptr;
- }
-
- window.DeferredRefresh();
+ window.Erase();
+ window.DrawTitleBox(window.GetName());
+
+ if (display_content) {
+ const int num_visible_rows = NumVisibleRows();
+ m_num_rows = 0;
+ m_root.CalculateRowIndexes(m_num_rows);
+
+ // If we unexpanded while having something selected our
+ // total number of rows is less than the num visible rows,
+ // then make sure we show all the rows by setting the first
+ // visible row accordingly.
+ if (m_first_visible_row > 0 && m_num_rows < num_visible_rows)
+ m_first_visible_row = 0;
- return true; // Drawing handled
+ // Make sure the selected row is always visible
+ if (m_selected_row_idx < m_first_visible_row)
+ m_first_visible_row = m_selected_row_idx;
+ else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx)
+ m_first_visible_row = m_selected_row_idx - num_visible_rows + 1;
+
+ int row_idx = 0;
+ int num_rows_left = num_visible_rows;
+ m_root.Draw(window, m_first_visible_row, m_selected_row_idx, row_idx,
+ num_rows_left);
+ // Get the selected row
+ m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
+ } else {
+ m_selected_item = nullptr;
}
- const char *
- WindowDelegateGetHelpText () override
- {
- return "Thread window keyboard shortcuts:";
- }
-
- KeyHelp *
- WindowDelegateGetKeyHelp () override
- {
- static curses::KeyHelp g_source_view_key_help[] = {
- { KEY_UP, "Select previous item" },
- { KEY_DOWN, "Select next item" },
- { KEY_RIGHT, "Expand the selected item" },
- { KEY_LEFT, "Unexpand the selected item or select parent if not expanded" },
- { KEY_PPAGE, "Page up" },
- { KEY_NPAGE, "Page down" },
- { 'h', "Show help dialog" },
- { ' ', "Toggle item expansion" },
- { ',', "Page up" },
- { '.', "Page down" },
- { '\0', nullptr }
- };
- return g_source_view_key_help;
- }
-
- HandleCharResult
- WindowDelegateHandleChar (Window &window, int c) override
- {
- switch(c)
- {
- case ',':
- case KEY_PPAGE:
- // Page up key
- if (m_first_visible_row > 0)
- {
- if (m_first_visible_row > m_max_y)
- m_first_visible_row -= m_max_y;
- else
- m_first_visible_row = 0;
- m_selected_row_idx = m_first_visible_row;
- m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
- if (m_selected_item)
- m_selected_item->ItemWasSelected ();
- }
- return eKeyHandled;
-
- case '.':
- case KEY_NPAGE:
- // Page down key
- if (m_num_rows > m_max_y)
- {
- if (m_first_visible_row + m_max_y < m_num_rows)
- {
- m_first_visible_row += m_max_y;
- m_selected_row_idx = m_first_visible_row;
- m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
- if (m_selected_item)
- m_selected_item->ItemWasSelected ();
- }
- }
- return eKeyHandled;
-
- case KEY_UP:
- if (m_selected_row_idx > 0)
- {
- --m_selected_row_idx;
- m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
- if (m_selected_item)
- m_selected_item->ItemWasSelected ();
- }
- return eKeyHandled;
-
- case KEY_DOWN:
- if (m_selected_row_idx + 1 < m_num_rows)
- {
- ++m_selected_row_idx;
- m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
- if (m_selected_item)
- m_selected_item->ItemWasSelected ();
- }
- return eKeyHandled;
-
- case KEY_RIGHT:
- if (m_selected_item)
- {
- if (!m_selected_item->IsExpanded())
- m_selected_item->Expand();
- }
- return eKeyHandled;
-
- case KEY_LEFT:
- if (m_selected_item)
- {
- if (m_selected_item->IsExpanded())
- m_selected_item->Unexpand();
- else if (m_selected_item->GetParent())
- {
- m_selected_row_idx = m_selected_item->GetParent()->GetRowIndex();
- m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
- if (m_selected_item)
- m_selected_item->ItemWasSelected ();
- }
- }
- return eKeyHandled;
-
- case ' ':
- // Toggle expansion state when SPACE is pressed
- if (m_selected_item)
- {
- if (m_selected_item->IsExpanded())
- m_selected_item->Unexpand();
- else
- m_selected_item->Expand();
- }
- return eKeyHandled;
-
- case 'h':
- window.CreateHelpSubwindow ();
- return eKeyHandled;
-
- default:
- break;
- }
- return eKeyNotHandled;
+ window.DeferredRefresh();
+
+ return true; // Drawing handled
+ }
+
+ const char *WindowDelegateGetHelpText() override {
+ return "Thread window keyboard shortcuts:";
+ }
+
+ KeyHelp *WindowDelegateGetKeyHelp() override {
+ static curses::KeyHelp g_source_view_key_help[] = {
+ {KEY_UP, "Select previous item"},
+ {KEY_DOWN, "Select next item"},
+ {KEY_RIGHT, "Expand the selected item"},
+ {KEY_LEFT,
+ "Unexpand the selected item or select parent if not expanded"},
+ {KEY_PPAGE, "Page up"},
+ {KEY_NPAGE, "Page down"},
+ {'h', "Show help dialog"},
+ {' ', "Toggle item expansion"},
+ {',', "Page up"},
+ {'.', "Page down"},
+ {'\0', nullptr}};
+ return g_source_view_key_help;
+ }
+
+ HandleCharResult WindowDelegateHandleChar(Window &window, int c) override {
+ switch (c) {
+ case ',':
+ case KEY_PPAGE:
+ // Page up key
+ if (m_first_visible_row > 0) {
+ if (m_first_visible_row > m_max_y)
+ m_first_visible_row -= m_max_y;
+ else
+ m_first_visible_row = 0;
+ m_selected_row_idx = m_first_visible_row;
+ m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
+ if (m_selected_item)
+ m_selected_item->ItemWasSelected();
+ }
+ return eKeyHandled;
+
+ case '.':
+ case KEY_NPAGE:
+ // Page down key
+ if (m_num_rows > m_max_y) {
+ if (m_first_visible_row + m_max_y < m_num_rows) {
+ m_first_visible_row += m_max_y;
+ m_selected_row_idx = m_first_visible_row;
+ m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
+ if (m_selected_item)
+ m_selected_item->ItemWasSelected();
+ }
+ }
+ return eKeyHandled;
+
+ case KEY_UP:
+ if (m_selected_row_idx > 0) {
+ --m_selected_row_idx;
+ m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
+ if (m_selected_item)
+ m_selected_item->ItemWasSelected();
+ }
+ return eKeyHandled;
+
+ case KEY_DOWN:
+ if (m_selected_row_idx + 1 < m_num_rows) {
+ ++m_selected_row_idx;
+ m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
+ if (m_selected_item)
+ m_selected_item->ItemWasSelected();
+ }
+ return eKeyHandled;
+
+ case KEY_RIGHT:
+ if (m_selected_item) {
+ if (!m_selected_item->IsExpanded())
+ m_selected_item->Expand();
+ }
+ return eKeyHandled;
+
+ case KEY_LEFT:
+ if (m_selected_item) {
+ if (m_selected_item->IsExpanded())
+ m_selected_item->Unexpand();
+ else if (m_selected_item->GetParent()) {
+ m_selected_row_idx = m_selected_item->GetParent()->GetRowIndex();
+ m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx);
+ if (m_selected_item)
+ m_selected_item->ItemWasSelected();
+ }
+ }
+ return eKeyHandled;
+
+ case ' ':
+ // Toggle expansion state when SPACE is pressed
+ if (m_selected_item) {
+ if (m_selected_item->IsExpanded())
+ m_selected_item->Unexpand();
+ else
+ m_selected_item->Expand();
+ }
+ return eKeyHandled;
+
+ case 'h':
+ window.CreateHelpSubwindow();
+ return eKeyHandled;
+
+ default:
+ break;
}
+ return eKeyNotHandled;
+ }
protected:
- Debugger &m_debugger;
- TreeDelegateSP m_delegate_sp;
- TreeItem m_root;
- TreeItem *m_selected_item;
- int m_num_rows;
- int m_selected_row_idx;
- int m_first_visible_row;
- int m_min_x;
- int m_min_y;
- int m_max_x;
- int m_max_y;
+ Debugger &m_debugger;
+ TreeDelegateSP m_delegate_sp;
+ TreeItem m_root;
+ TreeItem *m_selected_item;
+ int m_num_rows;
+ int m_selected_row_idx;
+ int m_first_visible_row;
+ int m_min_x;
+ int m_min_y;
+ int m_max_x;
+ int m_max_y;
};
-class FrameTreeDelegate : public TreeDelegate
-{
+class FrameTreeDelegate : public TreeDelegate {
public:
- FrameTreeDelegate () :
- TreeDelegate()
- {
- FormatEntity::Parse ("frame #${frame.index}: {${function.name}${function.pc-offset}}}",
- m_format);
+ FrameTreeDelegate() : TreeDelegate() {
+ FormatEntity::Parse(
+ "frame #${frame.index}: {${function.name}${function.pc-offset}}}",
+ m_format);
+ }
+
+ ~FrameTreeDelegate() override = default;
+
+ void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override {
+ Thread *thread = (Thread *)item.GetUserData();
+ if (thread) {
+ const uint64_t frame_idx = item.GetIdentifier();
+ StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_idx);
+ if (frame_sp) {
+ StreamString strm;
+ const SymbolContext &sc =
+ frame_sp->GetSymbolContext(eSymbolContextEverything);
+ ExecutionContext exe_ctx(frame_sp);
+ if (FormatEntity::Format(m_format, strm, &sc, &exe_ctx, nullptr,
+ nullptr, false, false)) {
+ int right_pad = 1;
+ window.PutCStringTruncated(strm.GetString().str().c_str(), right_pad);
+ }
+ }
}
+ }
+
+ void TreeDelegateGenerateChildren(TreeItem &item) override {
+ // No children for frames yet...
+ }
+
+ bool TreeDelegateItemSelected(TreeItem &item) override {
+ Thread *thread = (Thread *)item.GetUserData();
+ if (thread) {
+ thread->GetProcess()->GetThreadList().SetSelectedThreadByID(
+ thread->GetID());
+ const uint64_t frame_idx = item.GetIdentifier();
+ thread->SetSelectedFrameByIndex(frame_idx);
+ return true;
+ }
+ return false;
+ }
- ~FrameTreeDelegate() override = default;
+protected:
+ FormatEntity::Entry m_format;
+};
- void
- TreeDelegateDrawTreeItem (TreeItem &item, Window &window) override
- {
- Thread* thread = (Thread*)item.GetUserData();
- if (thread)
- {
- const uint64_t frame_idx = item.GetIdentifier();
- StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_idx);
- if (frame_sp)
- {
- StreamString strm;
- const SymbolContext &sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
- ExecutionContext exe_ctx (frame_sp);
- if (FormatEntity::Format(m_format, strm, &sc, &exe_ctx, nullptr, nullptr, false, false))
- {
- int right_pad = 1;
- window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
- }
- }
- }
+class ThreadTreeDelegate : public TreeDelegate {
+public:
+ ThreadTreeDelegate(Debugger &debugger)
+ : TreeDelegate(), m_debugger(debugger), m_tid(LLDB_INVALID_THREAD_ID),
+ m_stop_id(UINT32_MAX) {
+ FormatEntity::Parse("thread #${thread.index}: tid = ${thread.id}{, stop "
+ "reason = ${thread.stop-reason}}",
+ m_format);
+ }
+
+ ~ThreadTreeDelegate() override = default;
+
+ ProcessSP GetProcess() {
+ return m_debugger.GetCommandInterpreter()
+ .GetExecutionContext()
+ .GetProcessSP();
+ }
+
+ ThreadSP GetThread(const TreeItem &item) {
+ ProcessSP process_sp = GetProcess();
+ if (process_sp)
+ return process_sp->GetThreadList().FindThreadByID(item.GetIdentifier());
+ return ThreadSP();
+ }
+
+ void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override {
+ ThreadSP thread_sp = GetThread(item);
+ if (thread_sp) {
+ StreamString strm;
+ ExecutionContext exe_ctx(thread_sp);
+ if (FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr,
+ nullptr, false, false)) {
+ int right_pad = 1;
+ window.PutCStringTruncated(strm.GetString().str().c_str(), right_pad);
+ }
}
-
- void
- TreeDelegateGenerateChildren (TreeItem &item) override
- {
- // No children for frames yet...
+ }
+
+ void TreeDelegateGenerateChildren(TreeItem &item) override {
+ ProcessSP process_sp = GetProcess();
+ if (process_sp && process_sp->IsAlive()) {
+ StateType state = process_sp->GetState();
+ if (StateIsStoppedState(state, true)) {
+ ThreadSP thread_sp = GetThread(item);
+ if (thread_sp) {
+ if (m_stop_id == process_sp->GetStopID() &&
+ thread_sp->GetID() == m_tid)
+ return; // Children are already up to date
+ if (!m_frame_delegate_sp) {
+ // Always expand the thread item the first time we show it
+ m_frame_delegate_sp.reset(new FrameTreeDelegate());
+ }
+
+ m_stop_id = process_sp->GetStopID();
+ m_tid = thread_sp->GetID();
+
+ TreeItem t(&item, *m_frame_delegate_sp, false);
+ size_t num_frames = thread_sp->GetStackFrameCount();
+ item.Resize(num_frames, t);
+ for (size_t i = 0; i < num_frames; ++i) {
+ item[i].SetUserData(thread_sp.get());
+ item[i].SetIdentifier(i);
+ }
+ }
+ return;
+ }
}
-
- bool
- TreeDelegateItemSelected (TreeItem &item) override
- {
- Thread* thread = (Thread*)item.GetUserData();
- if (thread)
- {
- thread->GetProcess()->GetThreadList().SetSelectedThreadByID(thread->GetID());
- const uint64_t frame_idx = item.GetIdentifier();
- thread->SetSelectedFrameByIndex(frame_idx);
+ item.ClearChildren();
+ }
+
+ bool TreeDelegateItemSelected(TreeItem &item) override {
+ ProcessSP process_sp = GetProcess();
+ if (process_sp && process_sp->IsAlive()) {
+ StateType state = process_sp->GetState();
+ if (StateIsStoppedState(state, true)) {
+ ThreadSP thread_sp = GetThread(item);
+ if (thread_sp) {
+ ThreadList &thread_list = thread_sp->GetProcess()->GetThreadList();
+ std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex());
+ ThreadSP selected_thread_sp = thread_list.GetSelectedThread();
+ if (selected_thread_sp->GetID() != thread_sp->GetID()) {
+ thread_list.SetSelectedThreadByID(thread_sp->GetID());
return true;
+ }
}
- return false;
+ }
}
+ return false;
+ }
protected:
- FormatEntity::Entry m_format;
+ Debugger &m_debugger;
+ std::shared_ptr<FrameTreeDelegate> m_frame_delegate_sp;
+ lldb::user_id_t m_tid;
+ uint32_t m_stop_id;
+ FormatEntity::Entry m_format;
};
-class ThreadTreeDelegate : public TreeDelegate
-{
+class ThreadsTreeDelegate : public TreeDelegate {
public:
- ThreadTreeDelegate (Debugger &debugger) :
- TreeDelegate(),
- m_debugger (debugger),
- m_tid (LLDB_INVALID_THREAD_ID),
- m_stop_id (UINT32_MAX)
- {
- FormatEntity::Parse ("thread #${thread.index}: tid = ${thread.id}{, stop reason = ${thread.stop-reason}}",
- m_format);
+ ThreadsTreeDelegate(Debugger &debugger)
+ : TreeDelegate(), m_thread_delegate_sp(), m_debugger(debugger),
+ m_stop_id(UINT32_MAX) {
+ FormatEntity::Parse("process ${process.id}{, name = ${process.name}}",
+ m_format);
+ }
+
+ ~ThreadsTreeDelegate() override = default;
+
+ ProcessSP GetProcess() {
+ return m_debugger.GetCommandInterpreter()
+ .GetExecutionContext()
+ .GetProcessSP();
+ }
+
+ void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override {
+ ProcessSP process_sp = GetProcess();
+ if (process_sp && process_sp->IsAlive()) {
+ StreamString strm;
+ ExecutionContext exe_ctx(process_sp);
+ if (FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr,
+ nullptr, false, false)) {
+ int right_pad = 1;
+ window.PutCStringTruncated(strm.GetString().str().c_str(), right_pad);
+ }
}
-
- ~ThreadTreeDelegate() override = default;
-
- ProcessSP
- GetProcess ()
- {
- return m_debugger.GetCommandInterpreter().GetExecutionContext().GetProcessSP();
- }
-
- ThreadSP
- GetThread (const TreeItem &item)
- {
- ProcessSP process_sp = GetProcess ();
- if (process_sp)
- return process_sp->GetThreadList().FindThreadByID(item.GetIdentifier());
- return ThreadSP();
- }
-
- void
- TreeDelegateDrawTreeItem (TreeItem &item, Window &window) override
- {
- ThreadSP thread_sp = GetThread (item);
- if (thread_sp)
- {
- StreamString strm;
- ExecutionContext exe_ctx (thread_sp);
- if (FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr, nullptr, false, false))
- {
- int right_pad = 1;
- window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
- }
+ }
+
+ void TreeDelegateGenerateChildren(TreeItem &item) override {
+ ProcessSP process_sp = GetProcess();
+ if (process_sp && process_sp->IsAlive()) {
+ StateType state = process_sp->GetState();
+ if (StateIsStoppedState(state, true)) {
+ const uint32_t stop_id = process_sp->GetStopID();
+ if (m_stop_id == stop_id)
+ return; // Children are already up to date
+
+ m_stop_id = stop_id;
+
+ if (!m_thread_delegate_sp) {
+ // Always expand the thread item the first time we show it
+ // item.Expand();
+ m_thread_delegate_sp.reset(new ThreadTreeDelegate(m_debugger));
+ }
+
+ TreeItem t(&item, *m_thread_delegate_sp, false);
+ ThreadList &threads = process_sp->GetThreadList();
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
+ size_t num_threads = threads.GetSize();
+ item.Resize(num_threads, t);
+ for (size_t i = 0; i < num_threads; ++i) {
+ item[i].SetIdentifier(threads.GetThreadAtIndex(i)->GetID());
+ item[i].SetMightHaveChildren(true);
}
+ return;
+ }
}
+ item.ClearChildren();
+ }
- void
- TreeDelegateGenerateChildren (TreeItem &item) override
- {
- ProcessSP process_sp = GetProcess ();
- if (process_sp && process_sp->IsAlive())
- {
- StateType state = process_sp->GetState();
- if (StateIsStoppedState(state, true))
- {
- ThreadSP thread_sp = GetThread (item);
- if (thread_sp)
- {
- if (m_stop_id == process_sp->GetStopID() && thread_sp->GetID() == m_tid)
- return; // Children are already up to date
- if (!m_frame_delegate_sp)
- {
- // Always expand the thread item the first time we show it
- m_frame_delegate_sp.reset (new FrameTreeDelegate());
- }
-
- m_stop_id = process_sp->GetStopID();
- m_tid = thread_sp->GetID();
-
- TreeItem t (&item, *m_frame_delegate_sp, false);
- size_t num_frames = thread_sp->GetStackFrameCount();
- item.Resize (num_frames, t);
- for (size_t i = 0; i < num_frames; ++i)
- {
- item[i].SetUserData(thread_sp.get());
- item[i].SetIdentifier(i);
- }
- }
- return;
- }
- }
- item.ClearChildren();
- }
-
- bool
- TreeDelegateItemSelected (TreeItem &item) override
- {
- ProcessSP process_sp = GetProcess ();
- if (process_sp && process_sp->IsAlive())
- {
- StateType state = process_sp->GetState();
- if (StateIsStoppedState(state, true))
- {
- ThreadSP thread_sp = GetThread (item);
- if (thread_sp)
- {
- ThreadList &thread_list = thread_sp->GetProcess()->GetThreadList();
- std::lock_guard<std::recursive_mutex> guard(thread_list.GetMutex());
- ThreadSP selected_thread_sp = thread_list.GetSelectedThread();
- if (selected_thread_sp->GetID() != thread_sp->GetID())
- {
- thread_list.SetSelectedThreadByID(thread_sp->GetID());
- return true;
- }
- }
- }
- }
- return false;
- }
+ bool TreeDelegateItemSelected(TreeItem &item) override { return false; }
protected:
- Debugger &m_debugger;
- std::shared_ptr<FrameTreeDelegate> m_frame_delegate_sp;
- lldb::user_id_t m_tid;
- uint32_t m_stop_id;
- FormatEntity::Entry m_format;
+ std::shared_ptr<ThreadTreeDelegate> m_thread_delegate_sp;
+ Debugger &m_debugger;
+ uint32_t m_stop_id;
+ FormatEntity::Entry m_format;
};
-class ThreadsTreeDelegate : public TreeDelegate
-{
+class ValueObjectListDelegate : public WindowDelegate {
public:
- ThreadsTreeDelegate (Debugger &debugger) :
- TreeDelegate(),
- m_thread_delegate_sp (),
- m_debugger (debugger),
- m_stop_id (UINT32_MAX)
- {
- FormatEntity::Parse("process ${process.id}{, name = ${process.name}}",
- m_format);
- }
+ ValueObjectListDelegate()
+ : m_rows(), m_selected_row(nullptr),
+ m_selected_row_idx(0), m_first_visible_row(0), m_num_rows(0),
+ m_max_x(0), m_max_y(0) {}
+
+ ValueObjectListDelegate(ValueObjectList &valobj_list)
+ : m_rows(), m_selected_row(nullptr),
+ m_selected_row_idx(0), m_first_visible_row(0), m_num_rows(0),
+ m_max_x(0), m_max_y(0) {
+ SetValues(valobj_list);
+ }
+
+ ~ValueObjectListDelegate() override = default;
+
+ void SetValues(ValueObjectList &valobj_list) {
+ m_selected_row = nullptr;
+ m_selected_row_idx = 0;
+ m_first_visible_row = 0;
+ m_num_rows = 0;
+ m_rows.clear();
+ for (auto &valobj_sp : valobj_list.GetObjects())
+ m_rows.push_back(Row(valobj_sp, nullptr));
+ }
+
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ m_num_rows = 0;
+ m_min_x = 2;
+ m_min_y = 1;
+ m_max_x = window.GetWidth() - 1;
+ m_max_y = window.GetHeight() - 1;
- ~ThreadsTreeDelegate() override = default;
+ window.Erase();
+ window.DrawTitleBox(window.GetName());
+
+ const int num_visible_rows = NumVisibleRows();
+ const int num_rows = CalculateTotalNumberRows(m_rows);
+
+ // If we unexpanded while having something selected our
+ // total number of rows is less than the num visible rows,
+ // then make sure we show all the rows by setting the first
+ // visible row accordingly.
+ if (m_first_visible_row > 0 && num_rows < num_visible_rows)
+ m_first_visible_row = 0;
+
+ // Make sure the selected row is always visible
+ if (m_selected_row_idx < m_first_visible_row)
+ m_first_visible_row = m_selected_row_idx;
+ else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx)
+ m_first_visible_row = m_selected_row_idx - num_visible_rows + 1;
+
+ DisplayRows(window, m_rows, g_options);
+
+ window.DeferredRefresh();
+
+ // Get the selected row
+ m_selected_row = GetRowForRowIndex(m_selected_row_idx);
+ // Keep the cursor on the selected row so the highlight and the cursor
+ // are always on the same line
+ if (m_selected_row)
+ window.MoveCursor(m_selected_row->x, m_selected_row->y);
+
+ return true; // Drawing handled
+ }
+
+ KeyHelp *WindowDelegateGetKeyHelp() override {
+ static curses::KeyHelp g_source_view_key_help[] = {
+ {KEY_UP, "Select previous item"},
+ {KEY_DOWN, "Select next item"},
+ {KEY_RIGHT, "Expand selected item"},
+ {KEY_LEFT, "Unexpand selected item or select parent if not expanded"},
+ {KEY_PPAGE, "Page up"},
+ {KEY_NPAGE, "Page down"},
+ {'A', "Format as annotated address"},
+ {'b', "Format as binary"},
+ {'B', "Format as hex bytes with ASCII"},
+ {'c', "Format as character"},
+ {'d', "Format as a signed integer"},
+ {'D', "Format selected value using the default format for the type"},
+ {'f', "Format as float"},
+ {'h', "Show help dialog"},
+ {'i', "Format as instructions"},
+ {'o', "Format as octal"},
+ {'p', "Format as pointer"},
+ {'s', "Format as C string"},
+ {'t', "Toggle showing/hiding type names"},
+ {'u', "Format as an unsigned integer"},
+ {'x', "Format as hex"},
+ {'X', "Format as uppercase hex"},
+ {' ', "Toggle item expansion"},
+ {',', "Page up"},
+ {'.', "Page down"},
+ {'\0', nullptr}};
+ return g_source_view_key_help;
+ }
+
+ HandleCharResult WindowDelegateHandleChar(Window &window, int c) override {
+ switch (c) {
+ case 'x':
+ case 'X':
+ case 'o':
+ case 's':
+ case 'u':
+ case 'd':
+ case 'D':
+ case 'i':
+ case 'A':
+ case 'p':
+ case 'c':
+ case 'b':
+ case 'B':
+ case 'f':
+ // Change the format for the currently selected item
+ if (m_selected_row) {
+ auto valobj_sp = m_selected_row->value.GetSP();
+ if (valobj_sp)
+ valobj_sp->SetFormat(FormatForChar(c));
+ }
+ return eKeyHandled;
+
+ case 't':
+ // Toggle showing type names
+ g_options.show_types = !g_options.show_types;
+ return eKeyHandled;
+
+ case ',':
+ case KEY_PPAGE:
+ // Page up key
+ if (m_first_visible_row > 0) {
+ if (static_cast<int>(m_first_visible_row) > m_max_y)
+ m_first_visible_row -= m_max_y;
+ else
+ m_first_visible_row = 0;
+ m_selected_row_idx = m_first_visible_row;
+ }
+ return eKeyHandled;
+
+ case '.':
+ case KEY_NPAGE:
+ // Page down key
+ if (m_num_rows > static_cast<size_t>(m_max_y)) {
+ if (m_first_visible_row + m_max_y < m_num_rows) {
+ m_first_visible_row += m_max_y;
+ m_selected_row_idx = m_first_visible_row;
+ }
+ }
+ return eKeyHandled;
+
+ case KEY_UP:
+ 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;
+ return eKeyHandled;
+
+ case KEY_RIGHT:
+ if (m_selected_row) {
+ if (!m_selected_row->expanded)
+ m_selected_row->Expand();
+ }
+ return eKeyHandled;
+
+ case KEY_LEFT:
+ if (m_selected_row) {
+ if (m_selected_row->expanded)
+ m_selected_row->Unexpand();
+ else if (m_selected_row->parent)
+ m_selected_row_idx = m_selected_row->parent->row_idx;
+ }
+ return eKeyHandled;
+
+ case ' ':
+ // Toggle expansion state when SPACE is pressed
+ if (m_selected_row) {
+ if (m_selected_row->expanded)
+ m_selected_row->Unexpand();
+ else
+ m_selected_row->Expand();
+ }
+ return eKeyHandled;
- ProcessSP
- GetProcess ()
- {
- return m_debugger.GetCommandInterpreter().GetExecutionContext().GetProcessSP();
- }
+ case 'h':
+ window.CreateHelpSubwindow();
+ return eKeyHandled;
- void
- TreeDelegateDrawTreeItem (TreeItem &item, Window &window) override
- {
- ProcessSP process_sp = GetProcess ();
- if (process_sp && process_sp->IsAlive())
- {
- StreamString strm;
- ExecutionContext exe_ctx (process_sp);
- if (FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr, nullptr, false, false))
- {
- int right_pad = 1;
- window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
- }
- }
+ default:
+ break;
}
+ return eKeyNotHandled;
+ }
- void
- TreeDelegateGenerateChildren (TreeItem &item) override
- {
- ProcessSP process_sp = GetProcess ();
- if (process_sp && process_sp->IsAlive())
- {
- StateType state = process_sp->GetState();
- if (StateIsStoppedState(state, true))
- {
- const uint32_t stop_id = process_sp->GetStopID();
- if (m_stop_id == stop_id)
- return; // Children are already up to date
-
- m_stop_id = stop_id;
-
- if (!m_thread_delegate_sp)
- {
- // Always expand the thread item the first time we show it
- //item.Expand();
- m_thread_delegate_sp.reset (new ThreadTreeDelegate(m_debugger));
- }
-
- TreeItem t (&item, *m_thread_delegate_sp, false);
- ThreadList &threads = process_sp->GetThreadList();
- std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
- size_t num_threads = threads.GetSize();
- item.Resize (num_threads, t);
- for (size_t i = 0; i < num_threads; ++i)
- {
- item[i].SetIdentifier(threads.GetThreadAtIndex(i)->GetID());
- item[i].SetMightHaveChildren(true);
- }
- return;
- }
- }
- item.ClearChildren();
- }
-
- bool
- TreeDelegateItemSelected (TreeItem &item) override
- {
- return false;
- }
-
protected:
- std::shared_ptr<ThreadTreeDelegate> m_thread_delegate_sp;
- Debugger &m_debugger;
- uint32_t m_stop_id;
- FormatEntity::Entry m_format;
-};
-
-class ValueObjectListDelegate : public WindowDelegate
-{
-public:
- ValueObjectListDelegate () :
- m_valobj_list (),
- m_rows (),
- m_selected_row(nullptr),
- m_selected_row_idx (0),
- m_first_visible_row (0),
- m_num_rows (0),
- m_max_x (0),
- m_max_y (0)
- {
- }
-
- ValueObjectListDelegate (ValueObjectList &valobj_list) :
- m_valobj_list (valobj_list),
- m_rows (),
- m_selected_row(nullptr),
- m_selected_row_idx (0),
- m_first_visible_row (0),
- m_num_rows (0),
- m_max_x (0),
- m_max_y (0)
- {
- SetValues (valobj_list);
+ std::vector<Row> m_rows;
+ Row *m_selected_row;
+ uint32_t m_selected_row_idx;
+ uint32_t m_first_visible_row;
+ uint32_t m_num_rows;
+ int m_min_x;
+ int m_min_y;
+ int m_max_x;
+ int m_max_y;
+
+ static Format FormatForChar(int c) {
+ switch (c) {
+ case 'x':
+ return eFormatHex;
+ case 'X':
+ return eFormatHexUppercase;
+ case 'o':
+ return eFormatOctal;
+ case 's':
+ return eFormatCString;
+ case 'u':
+ return eFormatUnsigned;
+ case 'd':
+ return eFormatDecimal;
+ case 'D':
+ return eFormatDefault;
+ case 'i':
+ return eFormatInstruction;
+ case 'A':
+ return eFormatAddressInfo;
+ case 'p':
+ return eFormatPointer;
+ case 'c':
+ return eFormatChar;
+ case 'b':
+ return eFormatBinary;
+ case 'B':
+ return eFormatBytesWithASCII;
+ case 'f':
+ return eFormatFloat;
}
+ return eFormatDefault;
+ }
- ~ValueObjectListDelegate() override = default;
+ bool DisplayRowObject(Window &window, Row &row, DisplayOptions &options,
+ bool highlight, bool last_child) {
+ ValueObject *valobj = row.value.GetSP().get();
- void
- SetValues (ValueObjectList &valobj_list)
- {
- m_selected_row = nullptr;
- m_selected_row_idx = 0;
- m_first_visible_row = 0;
- m_num_rows = 0;
- m_rows.clear();
- m_valobj_list = valobj_list;
- const size_t num_values = m_valobj_list.GetSize();
- for (size_t i = 0; i < num_values; ++i)
- m_rows.push_back(Row(m_valobj_list.GetValueObjectAtIndex(i), nullptr));
- }
-
- bool
- WindowDelegateDraw (Window &window, bool force) override
- {
- m_num_rows = 0;
- m_min_x = 2;
- m_min_y = 1;
- m_max_x = window.GetWidth() - 1;
- m_max_y = window.GetHeight() - 1;
-
- window.Erase();
- window.DrawTitleBox (window.GetName());
-
- const int num_visible_rows = NumVisibleRows();
- const int num_rows = CalculateTotalNumberRows (m_rows);
-
- // If we unexpanded while having something selected our
- // total number of rows is less than the num visible rows,
- // then make sure we show all the rows by setting the first
- // visible row accordingly.
- if (m_first_visible_row > 0 && num_rows < num_visible_rows)
- m_first_visible_row = 0;
-
- // Make sure the selected row is always visible
- if (m_selected_row_idx < m_first_visible_row)
- m_first_visible_row = m_selected_row_idx;
- else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx)
- m_first_visible_row = m_selected_row_idx - num_visible_rows + 1;
-
- DisplayRows (window, m_rows, g_options);
-
- window.DeferredRefresh();
-
- // Get the selected row
- m_selected_row = GetRowForRowIndex (m_selected_row_idx);
- // Keep the cursor on the selected row so the highlight and the cursor
- // are always on the same line
- if (m_selected_row)
- window.MoveCursor (m_selected_row->x,
- m_selected_row->y);
-
- return true; // Drawing handled
- }
-
- KeyHelp *
- WindowDelegateGetKeyHelp () override
- {
- static curses::KeyHelp g_source_view_key_help[] = {
- { KEY_UP, "Select previous item" },
- { KEY_DOWN, "Select next item" },
- { KEY_RIGHT, "Expand selected item" },
- { KEY_LEFT, "Unexpand selected item or select parent if not expanded" },
- { KEY_PPAGE, "Page up" },
- { KEY_NPAGE, "Page down" },
- { 'A', "Format as annotated address" },
- { 'b', "Format as binary" },
- { 'B', "Format as hex bytes with ASCII" },
- { 'c', "Format as character" },
- { 'd', "Format as a signed integer" },
- { 'D', "Format selected value using the default format for the type" },
- { 'f', "Format as float" },
- { 'h', "Show help dialog" },
- { 'i', "Format as instructions" },
- { 'o', "Format as octal" },
- { 'p', "Format as pointer" },
- { 's', "Format as C string" },
- { 't', "Toggle showing/hiding type names" },
- { 'u', "Format as an unsigned integer" },
- { 'x', "Format as hex" },
- { 'X', "Format as uppercase hex" },
- { ' ', "Toggle item expansion" },
- { ',', "Page up" },
- { '.', "Page down" },
- { '\0', nullptr }
- };
- return g_source_view_key_help;
- }
+ if (valobj == nullptr)
+ return false;
- HandleCharResult
- WindowDelegateHandleChar (Window &window, int c) override
- {
- switch(c)
- {
- case 'x':
- case 'X':
- case 'o':
- case 's':
- case 'u':
- case 'd':
- case 'D':
- case 'i':
- case 'A':
- case 'p':
- case 'c':
- case 'b':
- case 'B':
- case 'f':
- // Change the format for the currently selected item
- if (m_selected_row)
- m_selected_row->valobj->SetFormat (FormatForChar (c));
- return eKeyHandled;
-
- case 't':
- // Toggle showing type names
- g_options.show_types = !g_options.show_types;
- return eKeyHandled;
-
- case ',':
- case KEY_PPAGE:
- // Page up key
- if (m_first_visible_row > 0)
- {
- if (static_cast<int>(m_first_visible_row) > m_max_y)
- m_first_visible_row -= m_max_y;
- else
- m_first_visible_row = 0;
- m_selected_row_idx = m_first_visible_row;
- }
- return eKeyHandled;
-
- case '.':
- case KEY_NPAGE:
- // Page down key
- if (m_num_rows > static_cast<size_t>(m_max_y))
- {
- if (m_first_visible_row + m_max_y < m_num_rows)
- {
- m_first_visible_row += m_max_y;
- m_selected_row_idx = m_first_visible_row;
- }
- }
- return eKeyHandled;
-
- case KEY_UP:
- 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;
- return eKeyHandled;
-
- case KEY_RIGHT:
- if (m_selected_row)
- {
- if (!m_selected_row->expanded)
- m_selected_row->Expand();
- }
- return eKeyHandled;
-
- case KEY_LEFT:
- if (m_selected_row)
- {
- if (m_selected_row->expanded)
- m_selected_row->Unexpand();
- else if (m_selected_row->parent)
- m_selected_row_idx = m_selected_row->parent->row_idx;
- }
- return eKeyHandled;
-
- case ' ':
- // Toggle expansion state when SPACE is pressed
- if (m_selected_row)
- {
- if (m_selected_row->expanded)
- m_selected_row->Unexpand();
- else
- m_selected_row->Expand();
- }
- return eKeyHandled;
-
- case 'h':
- window.CreateHelpSubwindow ();
- return eKeyHandled;
+ const char *type_name =
+ options.show_types ? valobj->GetTypeName().GetCString() : nullptr;
+ const char *name = valobj->GetName().GetCString();
+ const char *value = valobj->GetValueAsCString();
+ const char *summary = valobj->GetSummaryAsCString();
- default:
- break;
- }
- return eKeyNotHandled;
- }
-
-protected:
- ValueObjectList m_valobj_list;
- std::vector<Row> m_rows;
- Row *m_selected_row;
- uint32_t m_selected_row_idx;
- uint32_t m_first_visible_row;
- uint32_t m_num_rows;
- int m_min_x;
- int m_min_y;
- int m_max_x;
- int m_max_y;
-
- static Format
- FormatForChar (int c)
- {
- switch (c)
- {
- case 'x': return eFormatHex;
- case 'X': return eFormatHexUppercase;
- case 'o': return eFormatOctal;
- case 's': return eFormatCString;
- case 'u': return eFormatUnsigned;
- case 'd': return eFormatDecimal;
- case 'D': return eFormatDefault;
- case 'i': return eFormatInstruction;
- case 'A': return eFormatAddressInfo;
- case 'p': return eFormatPointer;
- case 'c': return eFormatChar;
- case 'b': return eFormatBinary;
- case 'B': return eFormatBytesWithASCII;
- case 'f': return eFormatFloat;
- }
- return eFormatDefault;
- }
-
- bool
- DisplayRowObject (Window &window,
- Row &row,
- DisplayOptions &options,
- bool highlight,
- bool last_child)
- {
- ValueObject *valobj = row.valobj.get();
-
- if (valobj == nullptr)
- return false;
-
- const char *type_name = options.show_types ? valobj->GetTypeName().GetCString() : nullptr;
- const char *name = valobj->GetName().GetCString();
- const char *value = valobj->GetValueAsCString ();
- const char *summary = valobj->GetSummaryAsCString ();
-
- window.MoveCursor (row.x, row.y);
-
- row.DrawTree (window);
-
- if (highlight)
- window.AttributeOn(A_REVERSE);
-
- if (type_name && type_name[0])
- window.Printf ("(%s) ", type_name);
-
- if (name && name[0])
- window.PutCString(name);
-
- attr_t changd_attr = 0;
- if (valobj->GetValueDidChange())
- changd_attr = COLOR_PAIR(5) | A_BOLD;
-
- if (value && value[0])
- {
- window.PutCString(" = ");
- if (changd_attr)
- window.AttributeOn(changd_attr);
- window.PutCString (value);
- if (changd_attr)
- window.AttributeOff(changd_attr);
- }
-
- if (summary && summary[0])
- {
- window.PutChar(' ');
- if (changd_attr)
- window.AttributeOn(changd_attr);
- window.PutCString(summary);
- if (changd_attr)
- window.AttributeOff(changd_attr);
- }
-
- if (highlight)
- window.AttributeOff (A_REVERSE);
-
- return true;
- }
+ window.MoveCursor(row.x, row.y);
- void
- DisplayRows (Window &window,
- std::vector<Row> &rows,
- DisplayOptions &options)
- {
- // > 0x25B7
- // \/ 0x25BD
-
- bool window_is_active = window.IsActive();
- for (auto &row : rows)
- {
- const bool last_child = row.parent && &rows[rows.size()-1] == &row;
- // Save the row index in each Row structure
- row.row_idx = m_num_rows;
- if ((m_num_rows >= m_first_visible_row) &&
- ((m_num_rows - m_first_visible_row) < static_cast<size_t>(NumVisibleRows())))
- {
- row.x = m_min_x;
- row.y = m_num_rows - m_first_visible_row + 1;
- if (DisplayRowObject (window,
- row,
- options,
- window_is_active && m_num_rows == m_selected_row_idx,
- last_child))
- {
- ++m_num_rows;
- }
- else
- {
- row.x = 0;
- row.y = 0;
- }
- }
- else
- {
- row.x = 0;
- row.y = 0;
- ++m_num_rows;
- }
-
- if (row.expanded && !row.children.empty())
- {
- DisplayRows (window,
- row.children,
- options);
- }
- }
+ row.DrawTree(window);
+
+ if (highlight)
+ window.AttributeOn(A_REVERSE);
+
+ if (type_name && type_name[0])
+ window.Printf("(%s) ", type_name);
+
+ if (name && name[0])
+ window.PutCString(name);
+
+ attr_t changd_attr = 0;
+ if (valobj->GetValueDidChange())
+ changd_attr = COLOR_PAIR(5) | A_BOLD;
+
+ if (value && value[0]) {
+ window.PutCString(" = ");
+ if (changd_attr)
+ window.AttributeOn(changd_attr);
+ window.PutCString(value);
+ if (changd_attr)
+ window.AttributeOff(changd_attr);
}
-
- int
- CalculateTotalNumberRows (const std::vector<Row> &rows)
- {
- int row_count = 0;
- for (const auto &row : rows)
- {
- ++row_count;
- if (row.expanded)
- row_count += CalculateTotalNumberRows(row.children);
- }
- return row_count;
+
+ if (summary && summary[0]) {
+ window.PutChar(' ');
+ if (changd_attr)
+ window.AttributeOn(changd_attr);
+ window.PutCString(summary);
+ if (changd_attr)
+ window.AttributeOff(changd_attr);
}
- static Row *
- GetRowForRowIndexImpl (std::vector<Row> &rows, size_t &row_index)
- {
- for (auto &row : rows)
- {
- if (row_index == 0)
- return &row;
- else
- {
- --row_index;
- if (row.expanded && !row.children.empty())
- {
- Row *result = GetRowForRowIndexImpl (row.children, row_index);
- if (result)
- return result;
- }
- }
- }
- return nullptr;
+ if (highlight)
+ window.AttributeOff(A_REVERSE);
+
+ return true;
+ }
+
+ void DisplayRows(Window &window, std::vector<Row> &rows,
+ DisplayOptions &options) {
+ // > 0x25B7
+ // \/ 0x25BD
+
+ bool window_is_active = window.IsActive();
+ for (auto &row : rows) {
+ const bool last_child = row.parent && &rows[rows.size() - 1] == &row;
+ // Save the row index in each Row structure
+ row.row_idx = m_num_rows;
+ if ((m_num_rows >= m_first_visible_row) &&
+ ((m_num_rows - m_first_visible_row) <
+ static_cast<size_t>(NumVisibleRows()))) {
+ row.x = m_min_x;
+ row.y = m_num_rows - m_first_visible_row + 1;
+ if (DisplayRowObject(window, row, options,
+ window_is_active &&
+ m_num_rows == m_selected_row_idx,
+ last_child)) {
+ ++m_num_rows;
+ } else {
+ row.x = 0;
+ row.y = 0;
+ }
+ } else {
+ row.x = 0;
+ row.y = 0;
+ ++m_num_rows;
+ }
+
+ auto &children = row.GetChildren();
+ if (row.expanded && !children.empty()) {
+ DisplayRows(window, children, options);
+ }
}
-
- Row *
- GetRowForRowIndex (size_t row_index)
- {
- return GetRowForRowIndexImpl (m_rows, row_index);
+ }
+
+ int CalculateTotalNumberRows(std::vector<Row> &rows) {
+ int row_count = 0;
+ for (auto &row : rows) {
+ ++row_count;
+ if (row.expanded)
+ row_count += CalculateTotalNumberRows(row.GetChildren());
}
-
- int
- NumVisibleRows () const
- {
- return m_max_y - m_min_y;
+ return row_count;
+ }
+
+ static Row *GetRowForRowIndexImpl(std::vector<Row> &rows, size_t &row_index) {
+ for (auto &row : rows) {
+ if (row_index == 0)
+ return &row;
+ else {
+ --row_index;
+ auto &children = row.GetChildren();
+ if (row.expanded && !children.empty()) {
+ Row *result = GetRowForRowIndexImpl(children, row_index);
+ if (result)
+ return result;
+ }
+ }
}
+ return nullptr;
+ }
+
+ Row *GetRowForRowIndex(size_t row_index) {
+ return GetRowForRowIndexImpl(m_rows, row_index);
+ }
- static DisplayOptions g_options;
+ int NumVisibleRows() const { return m_max_y - m_min_y; }
+
+ static DisplayOptions g_options;
};
-class FrameVariablesWindowDelegate : public ValueObjectListDelegate
-{
+class FrameVariablesWindowDelegate : public ValueObjectListDelegate {
public:
- FrameVariablesWindowDelegate (Debugger &debugger) :
- ValueObjectListDelegate (),
- m_debugger (debugger),
- m_frame_block(nullptr)
- {
+ FrameVariablesWindowDelegate(Debugger &debugger)
+ : ValueObjectListDelegate(), m_debugger(debugger),
+ m_frame_block(nullptr) {}
+
+ ~FrameVariablesWindowDelegate() override = default;
+
+ const char *WindowDelegateGetHelpText() override {
+ return "Frame variable window keyboard shortcuts:";
+ }
+
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ ExecutionContext exe_ctx(
+ m_debugger.GetCommandInterpreter().GetExecutionContext());
+ Process *process = exe_ctx.GetProcessPtr();
+ Block *frame_block = nullptr;
+ StackFrame *frame = nullptr;
+
+ if (process) {
+ StateType state = process->GetState();
+ if (StateIsStoppedState(state, true)) {
+ frame = exe_ctx.GetFramePtr();
+ if (frame)
+ frame_block = frame->GetFrameBlock();
+ } else if (StateIsRunningState(state)) {
+ return true; // Don't do any updating when we are running
+ }
}
- ~FrameVariablesWindowDelegate() override = default;
-
- const char *
- WindowDelegateGetHelpText () override
- {
- return "Frame variable window keyboard shortcuts:";
- }
-
- bool
- WindowDelegateDraw (Window &window, bool force) override
- {
- ExecutionContext exe_ctx (m_debugger.GetCommandInterpreter().GetExecutionContext());
- Process *process = exe_ctx.GetProcessPtr();
- Block *frame_block = nullptr;
- StackFrame *frame = nullptr;
-
- if (process)
- {
- StateType state = process->GetState();
- if (StateIsStoppedState(state, true))
- {
- frame = exe_ctx.GetFramePtr();
- if (frame)
- frame_block = frame->GetFrameBlock ();
- }
- else if (StateIsRunningState(state))
- {
- return true; // Don't do any updating when we are running
+ ValueObjectList local_values;
+ if (frame_block) {
+ // Only update the variables if they have changed
+ if (m_frame_block != frame_block) {
+ m_frame_block = frame_block;
+
+ VariableList *locals = frame->GetVariableList(true);
+ if (locals) {
+ const DynamicValueType use_dynamic = eDynamicDontRunTarget;
+ const size_t num_locals = locals->GetSize();
+ for (size_t i = 0; i < num_locals; ++i) {
+ ValueObjectSP value_sp = frame->GetValueObjectForFrameVariable(
+ locals->GetVariableAtIndex(i), use_dynamic);
+ if (value_sp) {
+ ValueObjectSP synthetic_value_sp = value_sp->GetSyntheticValue();
+ if (synthetic_value_sp)
+ local_values.Append(synthetic_value_sp);
+ else
+ local_values.Append(value_sp);
}
- }
-
- ValueObjectList local_values;
- if (frame_block)
- {
- // Only update the variables if they have changed
- if (m_frame_block != frame_block)
- {
- m_frame_block = frame_block;
-
- VariableList *locals = frame->GetVariableList(true);
- if (locals)
- {
- const DynamicValueType use_dynamic = eDynamicDontRunTarget;
- const size_t num_locals = locals->GetSize();
- for (size_t i = 0; i < num_locals; ++i)
- {
- ValueObjectSP value_sp = frame->GetValueObjectForFrameVariable (locals->GetVariableAtIndex(i), use_dynamic);
- if (value_sp)
- {
- ValueObjectSP synthetic_value_sp = value_sp->GetSyntheticValue();
- if (synthetic_value_sp)
- local_values.Append(synthetic_value_sp);
- else
- local_values.Append(value_sp);
- }
- }
- // Update the values
- SetValues(local_values);
- }
- }
- }
- else
- {
- m_frame_block = nullptr;
- // Update the values with an empty list if there is no frame
- SetValues(local_values);
- }
-
- return ValueObjectListDelegate::WindowDelegateDraw (window, force);
+ }
+ // Update the values
+ SetValues(local_values);
+ }
+ }
+ } else {
+ m_frame_block = nullptr;
+ // Update the values with an empty list if there is no frame
+ SetValues(local_values);
}
+ return ValueObjectListDelegate::WindowDelegateDraw(window, force);
+ }
+
protected:
- Debugger &m_debugger;
- Block *m_frame_block;
+ Debugger &m_debugger;
+ Block *m_frame_block;
};
-class RegistersWindowDelegate : public ValueObjectListDelegate
-{
+class RegistersWindowDelegate : public ValueObjectListDelegate {
public:
- RegistersWindowDelegate (Debugger &debugger) :
- ValueObjectListDelegate (),
- m_debugger (debugger)
- {
+ RegistersWindowDelegate(Debugger &debugger)
+ : ValueObjectListDelegate(), m_debugger(debugger) {}
+
+ ~RegistersWindowDelegate() override = default;
+
+ const char *WindowDelegateGetHelpText() override {
+ return "Register window keyboard shortcuts:";
+ }
+
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ ExecutionContext exe_ctx(
+ m_debugger.GetCommandInterpreter().GetExecutionContext());
+ StackFrame *frame = exe_ctx.GetFramePtr();
+
+ ValueObjectList value_list;
+ if (frame) {
+ if (frame->GetStackID() != m_stack_id) {
+ m_stack_id = frame->GetStackID();
+ RegisterContextSP reg_ctx(frame->GetRegisterContext());
+ if (reg_ctx) {
+ const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
+ for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx) {
+ value_list.Append(
+ ValueObjectRegisterSet::Create(frame, reg_ctx, set_idx));
+ }
+ }
+ SetValues(value_list);
+ }
+ } else {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive())
+ return true; // Don't do any updating if we are running
+ else {
+ // Update the values with an empty list if there
+ // is no process or the process isn't alive anymore
+ SetValues(value_list);
+ }
}
+ return ValueObjectListDelegate::WindowDelegateDraw(window, force);
+ }
- ~RegistersWindowDelegate() override = default;
-
- const char *
- WindowDelegateGetHelpText () override
- {
- return "Register window keyboard shortcuts:";
- }
-
- bool
- WindowDelegateDraw (Window &window, bool force) override
- {
- ExecutionContext exe_ctx (m_debugger.GetCommandInterpreter().GetExecutionContext());
- StackFrame *frame = exe_ctx.GetFramePtr();
-
- ValueObjectList value_list;
- if (frame)
- {
- if (frame->GetStackID() != m_stack_id)
- {
- m_stack_id = frame->GetStackID();
- RegisterContextSP reg_ctx (frame->GetRegisterContext());
- if (reg_ctx)
- {
- const uint32_t num_sets = reg_ctx->GetRegisterSetCount();
- for (uint32_t set_idx = 0; set_idx < num_sets; ++set_idx)
- {
- value_list.Append(ValueObjectRegisterSet::Create (frame, reg_ctx, set_idx));
- }
- }
- SetValues(value_list);
- }
- }
- else
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive())
- return true; // Don't do any updating if we are running
- else
- {
- // Update the values with an empty list if there
- // is no process or the process isn't alive anymore
- SetValues(value_list);
- }
- }
- return ValueObjectListDelegate::WindowDelegateDraw (window, force);
- }
-
protected:
- Debugger &m_debugger;
- StackID m_stack_id;
+ Debugger &m_debugger;
+ StackID m_stack_id;
};
-static const char *
-CursesKeyToCString (int ch)
-{
- static char g_desc[32];
- if (ch >= KEY_F0 && ch < KEY_F0 + 64)
- {
- snprintf(g_desc, sizeof(g_desc), "F%u", ch - KEY_F0);
- return g_desc;
- }
- switch (ch)
- {
- case KEY_DOWN: return "down";
- case KEY_UP: return "up";
- case KEY_LEFT: return "left";
- case KEY_RIGHT: return "right";
- case KEY_HOME: return "home";
- case KEY_BACKSPACE: return "backspace";
- case KEY_DL: return "delete-line";
- case KEY_IL: return "insert-line";
- case KEY_DC: return "delete-char";
- case KEY_IC: return "insert-char";
- case KEY_CLEAR: return "clear";
- case KEY_EOS: return "clear-to-eos";
- case KEY_EOL: return "clear-to-eol";
- case KEY_SF: return "scroll-forward";
- case KEY_SR: return "scroll-backward";
- case KEY_NPAGE: return "page-down";
- case KEY_PPAGE: return "page-up";
- case KEY_STAB: return "set-tab";
- case KEY_CTAB: return "clear-tab";
- case KEY_CATAB: return "clear-all-tabs";
- case KEY_ENTER: return "enter";
- case KEY_PRINT: return "print";
- case KEY_LL: return "lower-left key";
- case KEY_A1: return "upper left of keypad";
- case KEY_A3: return "upper right of keypad";
- case KEY_B2: return "center of keypad";
- case KEY_C1: return "lower left of keypad";
- case KEY_C3: return "lower right of keypad";
- case KEY_BTAB: return "back-tab key";
- case KEY_BEG: return "begin key";
- case KEY_CANCEL: return "cancel key";
- case KEY_CLOSE: return "close key";
- case KEY_COMMAND: return "command key";
- case KEY_COPY: return "copy key";
- case KEY_CREATE: return "create key";
- case KEY_END: return "end key";
- case KEY_EXIT: return "exit key";
- case KEY_FIND: return "find key";
- case KEY_HELP: return "help key";
- case KEY_MARK: return "mark key";
- case KEY_MESSAGE: return "message key";
- case KEY_MOVE: return "move key";
- case KEY_NEXT: return "next key";
- case KEY_OPEN: return "open key";
- case KEY_OPTIONS: return "options key";
- case KEY_PREVIOUS: return "previous key";
- case KEY_REDO: return "redo key";
- case KEY_REFERENCE: return "reference key";
- case KEY_REFRESH: return "refresh key";
- case KEY_REPLACE: return "replace key";
- case KEY_RESTART: return "restart key";
- case KEY_RESUME: return "resume key";
- case KEY_SAVE: return "save key";
- case KEY_SBEG: return "shifted begin key";
- case KEY_SCANCEL: return "shifted cancel key";
- case KEY_SCOMMAND: return "shifted command key";
- case KEY_SCOPY: return "shifted copy key";
- case KEY_SCREATE: return "shifted create key";
- case KEY_SDC: return "shifted delete-character key";
- case KEY_SDL: return "shifted delete-line key";
- case KEY_SELECT: return "select key";
- case KEY_SEND: return "shifted end key";
- case KEY_SEOL: return "shifted clear-to-end-of-line key";
- case KEY_SEXIT: return "shifted exit key";
- case KEY_SFIND: return "shifted find key";
- case KEY_SHELP: return "shifted help key";
- case KEY_SHOME: return "shifted home key";
- case KEY_SIC: return "shifted insert-character key";
- case KEY_SLEFT: return "shifted left-arrow key";
- case KEY_SMESSAGE: return "shifted message key";
- case KEY_SMOVE: return "shifted move key";
- case KEY_SNEXT: return "shifted next key";
- case KEY_SOPTIONS: return "shifted options key";
- case KEY_SPREVIOUS: return "shifted previous key";
- case KEY_SPRINT: return "shifted print key";
- case KEY_SREDO: return "shifted redo key";
- case KEY_SREPLACE: return "shifted replace key";
- case KEY_SRIGHT: return "shifted right-arrow key";
- case KEY_SRSUME: return "shifted resume key";
- case KEY_SSAVE: return "shifted save key";
- case KEY_SSUSPEND: return "shifted suspend key";
- case KEY_SUNDO: return "shifted undo key";
- case KEY_SUSPEND: return "suspend key";
- case KEY_UNDO: return "undo key";
- case KEY_MOUSE: return "Mouse event has occurred";
- case KEY_RESIZE: return "Terminal resize event";
+static const char *CursesKeyToCString(int ch) {
+ static char g_desc[32];
+ if (ch >= KEY_F0 && ch < KEY_F0 + 64) {
+ snprintf(g_desc, sizeof(g_desc), "F%u", ch - KEY_F0);
+ return g_desc;
+ }
+ switch (ch) {
+ case KEY_DOWN:
+ return "down";
+ case KEY_UP:
+ return "up";
+ case KEY_LEFT:
+ return "left";
+ case KEY_RIGHT:
+ return "right";
+ case KEY_HOME:
+ return "home";
+ case KEY_BACKSPACE:
+ return "backspace";
+ case KEY_DL:
+ return "delete-line";
+ case KEY_IL:
+ return "insert-line";
+ case KEY_DC:
+ return "delete-char";
+ case KEY_IC:
+ return "insert-char";
+ case KEY_CLEAR:
+ return "clear";
+ case KEY_EOS:
+ return "clear-to-eos";
+ case KEY_EOL:
+ return "clear-to-eol";
+ case KEY_SF:
+ return "scroll-forward";
+ case KEY_SR:
+ return "scroll-backward";
+ case KEY_NPAGE:
+ return "page-down";
+ case KEY_PPAGE:
+ return "page-up";
+ case KEY_STAB:
+ return "set-tab";
+ case KEY_CTAB:
+ return "clear-tab";
+ case KEY_CATAB:
+ return "clear-all-tabs";
+ case KEY_ENTER:
+ return "enter";
+ case KEY_PRINT:
+ return "print";
+ case KEY_LL:
+ return "lower-left key";
+ case KEY_A1:
+ return "upper left of keypad";
+ case KEY_A3:
+ return "upper right of keypad";
+ case KEY_B2:
+ return "center of keypad";
+ case KEY_C1:
+ return "lower left of keypad";
+ case KEY_C3:
+ return "lower right of keypad";
+ case KEY_BTAB:
+ return "back-tab key";
+ case KEY_BEG:
+ return "begin key";
+ case KEY_CANCEL:
+ return "cancel key";
+ case KEY_CLOSE:
+ return "close key";
+ case KEY_COMMAND:
+ return "command key";
+ case KEY_COPY:
+ return "copy key";
+ case KEY_CREATE:
+ return "create key";
+ case KEY_END:
+ return "end key";
+ case KEY_EXIT:
+ return "exit key";
+ case KEY_FIND:
+ return "find key";
+ case KEY_HELP:
+ return "help key";
+ case KEY_MARK:
+ return "mark key";
+ case KEY_MESSAGE:
+ return "message key";
+ case KEY_MOVE:
+ return "move key";
+ case KEY_NEXT:
+ return "next key";
+ case KEY_OPEN:
+ return "open key";
+ case KEY_OPTIONS:
+ return "options key";
+ case KEY_PREVIOUS:
+ return "previous key";
+ case KEY_REDO:
+ return "redo key";
+ case KEY_REFERENCE:
+ return "reference key";
+ case KEY_REFRESH:
+ return "refresh key";
+ case KEY_REPLACE:
+ return "replace key";
+ case KEY_RESTART:
+ return "restart key";
+ case KEY_RESUME:
+ return "resume key";
+ case KEY_SAVE:
+ return "save key";
+ case KEY_SBEG:
+ return "shifted begin key";
+ case KEY_SCANCEL:
+ return "shifted cancel key";
+ case KEY_SCOMMAND:
+ return "shifted command key";
+ case KEY_SCOPY:
+ return "shifted copy key";
+ case KEY_SCREATE:
+ return "shifted create key";
+ case KEY_SDC:
+ return "shifted delete-character key";
+ case KEY_SDL:
+ return "shifted delete-line key";
+ case KEY_SELECT:
+ return "select key";
+ case KEY_SEND:
+ return "shifted end key";
+ case KEY_SEOL:
+ return "shifted clear-to-end-of-line key";
+ case KEY_SEXIT:
+ return "shifted exit key";
+ case KEY_SFIND:
+ return "shifted find key";
+ case KEY_SHELP:
+ return "shifted help key";
+ case KEY_SHOME:
+ return "shifted home key";
+ case KEY_SIC:
+ return "shifted insert-character key";
+ case KEY_SLEFT:
+ return "shifted left-arrow key";
+ case KEY_SMESSAGE:
+ return "shifted message key";
+ case KEY_SMOVE:
+ return "shifted move key";
+ case KEY_SNEXT:
+ return "shifted next key";
+ case KEY_SOPTIONS:
+ return "shifted options key";
+ case KEY_SPREVIOUS:
+ return "shifted previous key";
+ case KEY_SPRINT:
+ return "shifted print key";
+ case KEY_SREDO:
+ return "shifted redo key";
+ case KEY_SREPLACE:
+ return "shifted replace key";
+ case KEY_SRIGHT:
+ return "shifted right-arrow key";
+ case KEY_SRSUME:
+ return "shifted resume key";
+ case KEY_SSAVE:
+ return "shifted save key";
+ case KEY_SSUSPEND:
+ return "shifted suspend key";
+ case KEY_SUNDO:
+ return "shifted undo key";
+ case KEY_SUSPEND:
+ return "suspend key";
+ 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";
+ case KEY_EVENT:
+ return "We were interrupted by an event";
#endif
- case KEY_RETURN: return "return";
- case ' ': return "space";
- case '\t': return "tab";
- case KEY_ESCAPE: return "escape";
- default:
- if (isprint(ch))
- snprintf(g_desc, sizeof(g_desc), "%c", ch);
- else
- snprintf(g_desc, sizeof(g_desc), "\\x%2.2x", ch);
- return g_desc;
- }
- return nullptr;
+ case KEY_RETURN:
+ return "return";
+ case ' ':
+ return "space";
+ case '\t':
+ return "tab";
+ case KEY_ESCAPE:
+ return "escape";
+ default:
+ if (isprint(ch))
+ snprintf(g_desc, sizeof(g_desc), "%c", ch);
+ else
+ snprintf(g_desc, sizeof(g_desc), "\\x%2.2x", ch);
+ return g_desc;
+ }
+ return nullptr;
}
-HelpDialogDelegate::HelpDialogDelegate (const char *text, KeyHelp *key_help_array) :
- m_text (),
- m_first_visible_line (0)
-{
- if (text && text[0])
- {
- m_text.SplitIntoLines(text);
- m_text.AppendString("");
- }
- if (key_help_array)
- {
- for (KeyHelp *key = key_help_array; key->ch; ++key)
- {
- StreamString key_description;
- key_description.Printf("%10s - %s", CursesKeyToCString(key->ch), key->description);
- m_text.AppendString(std::move(key_description.GetString()));
- }
+HelpDialogDelegate::HelpDialogDelegate(const char *text,
+ KeyHelp *key_help_array)
+ : m_text(), m_first_visible_line(0) {
+ if (text && text[0]) {
+ m_text.SplitIntoLines(text);
+ m_text.AppendString("");
+ }
+ if (key_help_array) {
+ for (KeyHelp *key = key_help_array; key->ch; ++key) {
+ StreamString key_description;
+ key_description.Printf("%10s - %s", CursesKeyToCString(key->ch),
+ key->description);
+ m_text.AppendString(key_description.GetString());
}
+ }
}
HelpDialogDelegate::~HelpDialogDelegate() = default;
-
-bool
-HelpDialogDelegate::WindowDelegateDraw (Window &window, bool force)
-{
- window.Erase();
- const int window_height = window.GetHeight();
- int x = 2;
- int y = 1;
- const int min_y = y;
- const int max_y = window_height - 1 - y;
- const size_t num_visible_lines = max_y - min_y + 1;
- const size_t num_lines = m_text.GetSize();
- const char *bottom_message;
- if (num_lines <= num_visible_lines)
- bottom_message = "Press any key to exit";
- else
- bottom_message = "Use arrows to scroll, any other key to exit";
- window.DrawTitleBox(window.GetName(), bottom_message);
- while (y <= max_y)
- {
- window.MoveCursor(x, y);
- window.PutCStringTruncated(m_text.GetStringAtIndex(m_first_visible_line + y - min_y), 1);
- ++y;
- }
- return true;
-}
-
-HandleCharResult
-HelpDialogDelegate::WindowDelegateHandleChar (Window &window, int key)
-{
- bool done = false;
- const size_t num_lines = m_text.GetSize();
- const size_t num_visible_lines = window.GetHeight() - 2;
-
- if (num_lines <= num_visible_lines)
- {
- done = true;
- // If we have all lines visible and don't need scrolling, then any
- // key press will cause us to exit
- }
- else
- {
- switch (key)
- {
- case KEY_UP:
- if (m_first_visible_line > 0)
- --m_first_visible_line;
- break;
- case KEY_DOWN:
- if (m_first_visible_line + num_visible_lines < num_lines)
- ++m_first_visible_line;
- break;
-
- case KEY_PPAGE:
- case ',':
- if (m_first_visible_line > 0)
- {
- if (static_cast<size_t>(m_first_visible_line) >= num_visible_lines)
- m_first_visible_line -= num_visible_lines;
- else
- m_first_visible_line = 0;
- }
- break;
-
- case KEY_NPAGE:
- case '.':
- if (m_first_visible_line + num_visible_lines < num_lines)
- {
- m_first_visible_line += num_visible_lines;
- if (static_cast<size_t>(m_first_visible_line) > num_lines)
- m_first_visible_line = num_lines - num_visible_lines;
- }
- break;
+bool HelpDialogDelegate::WindowDelegateDraw(Window &window, bool force) {
+ window.Erase();
+ const int window_height = window.GetHeight();
+ int x = 2;
+ int y = 1;
+ const int min_y = y;
+ const int max_y = window_height - 1 - y;
+ const size_t num_visible_lines = max_y - min_y + 1;
+ const size_t num_lines = m_text.GetSize();
+ const char *bottom_message;
+ if (num_lines <= num_visible_lines)
+ bottom_message = "Press any key to exit";
+ else
+ bottom_message = "Use arrows to scroll, any other key to exit";
+ window.DrawTitleBox(window.GetName(), bottom_message);
+ while (y <= max_y) {
+ window.MoveCursor(x, y);
+ window.PutCStringTruncated(
+ m_text.GetStringAtIndex(m_first_visible_line + y - min_y), 1);
+ ++y;
+ }
+ return true;
+}
- default:
- done = true;
- break;
- }
+HandleCharResult HelpDialogDelegate::WindowDelegateHandleChar(Window &window,
+ int key) {
+ bool done = false;
+ const size_t num_lines = m_text.GetSize();
+ const size_t num_visible_lines = window.GetHeight() - 2;
+
+ if (num_lines <= num_visible_lines) {
+ done = true;
+ // If we have all lines visible and don't need scrolling, then any
+ // key press will cause us to exit
+ } else {
+ switch (key) {
+ case KEY_UP:
+ if (m_first_visible_line > 0)
+ --m_first_visible_line;
+ break;
+
+ case KEY_DOWN:
+ if (m_first_visible_line + num_visible_lines < num_lines)
+ ++m_first_visible_line;
+ break;
+
+ case KEY_PPAGE:
+ case ',':
+ if (m_first_visible_line > 0) {
+ if (static_cast<size_t>(m_first_visible_line) >= num_visible_lines)
+ m_first_visible_line -= num_visible_lines;
+ else
+ m_first_visible_line = 0;
+ }
+ break;
+
+ case KEY_NPAGE:
+ case '.':
+ if (m_first_visible_line + num_visible_lines < num_lines) {
+ m_first_visible_line += num_visible_lines;
+ if (static_cast<size_t>(m_first_visible_line) > num_lines)
+ m_first_visible_line = num_lines - num_visible_lines;
+ }
+ break;
+
+ default:
+ done = true;
+ break;
}
- if (done)
- window.GetParent()->RemoveSubWindow(&window);
- return eKeyHandled;
+ }
+ if (done)
+ window.GetParent()->RemoveSubWindow(&window);
+ return eKeyHandled;
}
-class ApplicationDelegate :
- public WindowDelegate,
- public MenuDelegate
-{
+class ApplicationDelegate : public WindowDelegate, public MenuDelegate {
public:
- enum {
- eMenuID_LLDB = 1,
- eMenuID_LLDBAbout,
- eMenuID_LLDBExit,
-
- eMenuID_Target,
- eMenuID_TargetCreate,
- eMenuID_TargetDelete,
-
- eMenuID_Process,
- eMenuID_ProcessAttach,
- eMenuID_ProcessDetach,
- eMenuID_ProcessLaunch,
- eMenuID_ProcessContinue,
- eMenuID_ProcessHalt,
- eMenuID_ProcessKill,
-
- eMenuID_Thread,
- eMenuID_ThreadStepIn,
- eMenuID_ThreadStepOver,
- eMenuID_ThreadStepOut,
-
- eMenuID_View,
- eMenuID_ViewBacktrace,
- eMenuID_ViewRegisters,
- eMenuID_ViewSource,
- eMenuID_ViewVariables,
-
- eMenuID_Help,
- eMenuID_HelpGUIHelp
- };
-
- ApplicationDelegate (Application &app, Debugger &debugger) :
- WindowDelegate (),
- MenuDelegate (),
- m_app (app),
- m_debugger (debugger)
- {
+ enum {
+ eMenuID_LLDB = 1,
+ eMenuID_LLDBAbout,
+ eMenuID_LLDBExit,
+
+ eMenuID_Target,
+ eMenuID_TargetCreate,
+ eMenuID_TargetDelete,
+
+ eMenuID_Process,
+ eMenuID_ProcessAttach,
+ eMenuID_ProcessDetach,
+ eMenuID_ProcessLaunch,
+ eMenuID_ProcessContinue,
+ eMenuID_ProcessHalt,
+ eMenuID_ProcessKill,
+
+ eMenuID_Thread,
+ eMenuID_ThreadStepIn,
+ eMenuID_ThreadStepOver,
+ eMenuID_ThreadStepOut,
+
+ eMenuID_View,
+ eMenuID_ViewBacktrace,
+ eMenuID_ViewRegisters,
+ eMenuID_ViewSource,
+ eMenuID_ViewVariables,
+
+ eMenuID_Help,
+ eMenuID_HelpGUIHelp
+ };
+
+ ApplicationDelegate(Application &app, Debugger &debugger)
+ : WindowDelegate(), MenuDelegate(), m_app(app), m_debugger(debugger) {}
+
+ ~ApplicationDelegate() override = default;
+
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ return false; // Drawing not handled, let standard window drawing happen
+ }
+
+ HandleCharResult WindowDelegateHandleChar(Window &window, int key) override {
+ switch (key) {
+ case '\t':
+ window.SelectNextWindowAsActive();
+ return eKeyHandled;
+
+ case 'h':
+ window.CreateHelpSubwindow();
+ return eKeyHandled;
+
+ case KEY_ESCAPE:
+ return eQuitApplication;
+
+ default:
+ break;
+ }
+ return eKeyNotHandled;
+ }
+
+ const char *WindowDelegateGetHelpText() override {
+ return "Welcome to the LLDB curses GUI.\n\n"
+ "Press the TAB key to change the selected view.\n"
+ "Each view has its own keyboard shortcuts, press 'h' to open a "
+ "dialog to display them.\n\n"
+ "Common key bindings for all views:";
+ }
+
+ KeyHelp *WindowDelegateGetKeyHelp() override {
+ static curses::KeyHelp g_source_view_key_help[] = {
+ {'\t', "Select next view"},
+ {'h', "Show help dialog with view specific key bindings"},
+ {',', "Page up"},
+ {'.', "Page down"},
+ {KEY_UP, "Select previous"},
+ {KEY_DOWN, "Select next"},
+ {KEY_LEFT, "Unexpand or select parent"},
+ {KEY_RIGHT, "Expand"},
+ {KEY_PPAGE, "Page up"},
+ {KEY_NPAGE, "Page down"},
+ {'\0', nullptr}};
+ return g_source_view_key_help;
+ }
+
+ MenuActionResult MenuDelegateAction(Menu &menu) override {
+ switch (menu.GetIdentifier()) {
+ case eMenuID_ThreadStepIn: {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasThreadScope()) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive() &&
+ StateIsStoppedState(process->GetState(), true))
+ exe_ctx.GetThreadRef().StepIn(true);
+ }
}
+ return MenuActionResult::Handled;
- ~ApplicationDelegate() override = default;
+ case eMenuID_ThreadStepOut: {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasThreadScope()) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive() &&
+ StateIsStoppedState(process->GetState(), true))
+ exe_ctx.GetThreadRef().StepOut();
+ }
+ }
+ return MenuActionResult::Handled;
- bool
- WindowDelegateDraw (Window &window, bool force) override
- {
- return false; // Drawing not handled, let standard window drawing happen
+ case eMenuID_ThreadStepOver: {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasThreadScope()) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive() &&
+ StateIsStoppedState(process->GetState(), true))
+ exe_ctx.GetThreadRef().StepOver(true);
+ }
}
-
- HandleCharResult
- WindowDelegateHandleChar (Window &window, int key) override
- {
- switch (key)
- {
- case '\t':
- window.SelectNextWindowAsActive();
- return eKeyHandled;
+ return MenuActionResult::Handled;
- case 'h':
- window.CreateHelpSubwindow();
- return eKeyHandled;
+ case eMenuID_ProcessContinue: {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasProcessScope()) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive() &&
+ StateIsStoppedState(process->GetState(), true))
+ process->Resume();
+ }
+ }
+ return MenuActionResult::Handled;
- case KEY_ESCAPE:
- return eQuitApplication;
+ case eMenuID_ProcessKill: {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasProcessScope()) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive())
+ process->Destroy(false);
+ }
+ }
+ return MenuActionResult::Handled;
- default:
- break;
- }
- return eKeyNotHandled;
+ case eMenuID_ProcessHalt: {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasProcessScope()) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive())
+ process->Halt();
+ }
}
+ return MenuActionResult::Handled;
- const char *
- WindowDelegateGetHelpText () override
- {
- return "Welcome to the LLDB curses GUI.\n\n"
- "Press the TAB key to change the selected view.\n"
- "Each view has its own keyboard shortcuts, press 'h' to open a dialog to display them.\n\n"
- "Common key bindings for all views:";
+ case eMenuID_ProcessDetach: {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasProcessScope()) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive())
+ process->Detach(false);
+ }
}
-
- KeyHelp *
- WindowDelegateGetKeyHelp () override
- {
- static curses::KeyHelp g_source_view_key_help[] = {
- { '\t', "Select next view" },
- { 'h', "Show help dialog with view specific key bindings" },
- { ',', "Page up" },
- { '.', "Page down" },
- { KEY_UP, "Select previous" },
- { KEY_DOWN, "Select next" },
- { KEY_LEFT, "Unexpand or select parent" },
- { KEY_RIGHT, "Expand" },
- { KEY_PPAGE, "Page up" },
- { KEY_NPAGE, "Page down" },
- { '\0', nullptr }
- };
- return g_source_view_key_help;
+ return MenuActionResult::Handled;
+
+ case eMenuID_Process: {
+ // Populate the menu with all of the threads if the process is stopped
+ // when
+ // the Process menu gets selected and is about to display its submenu.
+ Menus &submenus = menu.GetSubmenus();
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsAlive() &&
+ StateIsStoppedState(process->GetState(), true)) {
+ if (submenus.size() == 7)
+ menu.AddSubmenu(MenuSP(new Menu(Menu::Type::Separator)));
+ else if (submenus.size() > 8)
+ submenus.erase(submenus.begin() + 8, submenus.end());
+
+ ThreadList &threads = process->GetThreadList();
+ std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
+ size_t num_threads = threads.GetSize();
+ for (size_t i = 0; i < num_threads; ++i) {
+ ThreadSP thread_sp = threads.GetThreadAtIndex(i);
+ char menu_char = '\0';
+ if (i < 9)
+ menu_char = '1' + i;
+ StreamString thread_menu_title;
+ thread_menu_title.Printf("Thread %u", thread_sp->GetIndexID());
+ const char *thread_name = thread_sp->GetName();
+ if (thread_name && thread_name[0])
+ thread_menu_title.Printf(" %s", thread_name);
+ else {
+ const char *queue_name = thread_sp->GetQueueName();
+ if (queue_name && queue_name[0])
+ thread_menu_title.Printf(" %s", queue_name);
+ }
+ menu.AddSubmenu(
+ MenuSP(new Menu(thread_menu_title.GetString().str().c_str(),
+ nullptr, menu_char, thread_sp->GetID())));
+ }
+ } else if (submenus.size() > 7) {
+ // Remove the separator and any other thread submenu items
+ // that were previously added
+ submenus.erase(submenus.begin() + 7, submenus.end());
+ }
+ // Since we are adding and removing items we need to recalculate the name
+ // lengths
+ menu.RecalculateNameLengths();
}
-
- MenuActionResult
- MenuDelegateAction (Menu &menu) override
- {
- switch (menu.GetIdentifier())
- {
- case eMenuID_ThreadStepIn:
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasThreadScope())
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
- exe_ctx.GetThreadRef().StepIn(true);
- }
- }
- return MenuActionResult::Handled;
-
- case eMenuID_ThreadStepOut:
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasThreadScope())
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
- exe_ctx.GetThreadRef().StepOut();
- }
- }
- return MenuActionResult::Handled;
-
- case eMenuID_ThreadStepOver:
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasThreadScope())
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
- exe_ctx.GetThreadRef().StepOver(true);
- }
- }
- return MenuActionResult::Handled;
-
- case eMenuID_ProcessContinue:
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope())
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
- process->Resume();
- }
- }
- return MenuActionResult::Handled;
-
- case eMenuID_ProcessKill:
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope())
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive())
- process->Destroy(false);
- }
- }
- return MenuActionResult::Handled;
-
- case eMenuID_ProcessHalt:
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope())
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive())
- process->Halt();
- }
- }
- return MenuActionResult::Handled;
-
- case eMenuID_ProcessDetach:
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope())
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive())
- process->Detach(false);
- }
- }
- return MenuActionResult::Handled;
-
- case eMenuID_Process:
- {
- // Populate the menu with all of the threads if the process is stopped when
- // the Process menu gets selected and is about to display its submenu.
- Menus &submenus = menu.GetSubmenus();
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsAlive() && StateIsStoppedState (process->GetState(), true))
- {
- if (submenus.size() == 7)
- menu.AddSubmenu (MenuSP (new Menu(Menu::Type::Separator)));
- else if (submenus.size() > 8)
- submenus.erase (submenus.begin() + 8, submenus.end());
-
- ThreadList &threads = process->GetThreadList();
- std::lock_guard<std::recursive_mutex> guard(threads.GetMutex());
- size_t num_threads = threads.GetSize();
- for (size_t i = 0; i < num_threads; ++i)
- {
- ThreadSP thread_sp = threads.GetThreadAtIndex(i);
- char menu_char = '\0';
- if (i < 9)
- menu_char = '1' + i;
- StreamString thread_menu_title;
- thread_menu_title.Printf("Thread %u", thread_sp->GetIndexID());
- const char *thread_name = thread_sp->GetName();
- if (thread_name && thread_name[0])
- thread_menu_title.Printf (" %s", thread_name);
- else
- {
- const char *queue_name = thread_sp->GetQueueName();
- if (queue_name && queue_name[0])
- thread_menu_title.Printf (" %s", queue_name);
- }
- menu.AddSubmenu(MenuSP(new Menu(thread_menu_title.GetString().c_str(), nullptr, menu_char, thread_sp->GetID())));
- }
- }
- else if (submenus.size() > 7)
- {
- // Remove the separator and any other thread submenu items
- // that were previously added
- submenus.erase (submenus.begin() + 7, submenus.end());
- }
- // Since we are adding and removing items we need to recalculate the name lengths
- menu.RecalculateNameLengths();
- }
- return MenuActionResult::Handled;
-
- case eMenuID_ViewVariables:
- {
- WindowSP main_window_sp = m_app.GetMainWindow();
- WindowSP source_window_sp = main_window_sp->FindSubWindow("Source");
- WindowSP variables_window_sp = main_window_sp->FindSubWindow("Variables");
- WindowSP registers_window_sp = main_window_sp->FindSubWindow("Registers");
- const Rect source_bounds = source_window_sp->GetBounds();
-
- if (variables_window_sp)
- {
- const Rect variables_bounds = variables_window_sp->GetBounds();
-
- main_window_sp->RemoveSubWindow(variables_window_sp.get());
-
- if (registers_window_sp)
- {
- // We have a registers window, so give all the area back to the registers window
- Rect registers_bounds = variables_bounds;
- registers_bounds.size.width = source_bounds.size.width;
- registers_window_sp->SetBounds(registers_bounds);
- }
- else
- {
- // We have no registers window showing so give the bottom
- // area back to the source view
- source_window_sp->Resize (source_bounds.size.width,
- source_bounds.size.height + variables_bounds.size.height);
- }
- }
- else
- {
- Rect new_variables_rect;
- if (registers_window_sp)
- {
- // We have a registers window so split the area of the registers
- // window into two columns where the left hand side will be the
- // variables and the right hand side will be the registers
- const Rect variables_bounds = registers_window_sp->GetBounds();
- Rect new_registers_rect;
- variables_bounds.VerticalSplitPercentage (0.50, new_variables_rect, new_registers_rect);
- registers_window_sp->SetBounds (new_registers_rect);
- }
- else
- {
- // No variables window, grab the bottom part of the source window
- Rect new_source_rect;
- source_bounds.HorizontalSplitPercentage (0.70, new_source_rect, new_variables_rect);
- source_window_sp->SetBounds (new_source_rect);
- }
- WindowSP new_window_sp = main_window_sp->CreateSubWindow ("Variables",
- new_variables_rect,
- false);
- new_window_sp->SetDelegate (WindowDelegateSP(new FrameVariablesWindowDelegate(m_debugger)));
- }
- touchwin(stdscr);
- }
- return MenuActionResult::Handled;
-
- case eMenuID_ViewRegisters:
- {
- WindowSP main_window_sp = m_app.GetMainWindow();
- WindowSP source_window_sp = main_window_sp->FindSubWindow("Source");
- WindowSP variables_window_sp = main_window_sp->FindSubWindow("Variables");
- WindowSP registers_window_sp = main_window_sp->FindSubWindow("Registers");
- const Rect source_bounds = source_window_sp->GetBounds();
-
- if (registers_window_sp)
- {
- if (variables_window_sp)
- {
- const Rect variables_bounds = variables_window_sp->GetBounds();
-
- // We have a variables window, so give all the area back to the variables window
- variables_window_sp->Resize (variables_bounds.size.width + registers_window_sp->GetWidth(),
- variables_bounds.size.height);
- }
- else
- {
- // We have no variables window showing so give the bottom
- // area back to the source view
- source_window_sp->Resize (source_bounds.size.width,
- source_bounds.size.height + registers_window_sp->GetHeight());
- }
- main_window_sp->RemoveSubWindow(registers_window_sp.get());
- }
- else
- {
- Rect new_regs_rect;
- if (variables_window_sp)
- {
- // We have a variables window, split it into two columns
- // where the left hand side will be the variables and the
- // right hand side will be the registers
- const Rect variables_bounds = variables_window_sp->GetBounds();
- Rect new_vars_rect;
- variables_bounds.VerticalSplitPercentage (0.50, new_vars_rect, new_regs_rect);
- variables_window_sp->SetBounds (new_vars_rect);
- }
- else
- {
- // No registers window, grab the bottom part of the source window
- Rect new_source_rect;
- source_bounds.HorizontalSplitPercentage (0.70, new_source_rect, new_regs_rect);
- source_window_sp->SetBounds (new_source_rect);
- }
- WindowSP new_window_sp = main_window_sp->CreateSubWindow ("Registers",
- new_regs_rect,
- false);
- new_window_sp->SetDelegate (WindowDelegateSP(new RegistersWindowDelegate(m_debugger)));
- }
- touchwin(stdscr);
- }
- return MenuActionResult::Handled;
-
- case eMenuID_HelpGUIHelp:
- m_app.GetMainWindow ()->CreateHelpSubwindow();
- return MenuActionResult::Handled;
-
- default:
- break;
- }
-
- return MenuActionResult::NotHandled;
+ return MenuActionResult::Handled;
+
+ case eMenuID_ViewVariables: {
+ WindowSP main_window_sp = m_app.GetMainWindow();
+ WindowSP source_window_sp = main_window_sp->FindSubWindow("Source");
+ WindowSP variables_window_sp = main_window_sp->FindSubWindow("Variables");
+ WindowSP registers_window_sp = main_window_sp->FindSubWindow("Registers");
+ const Rect source_bounds = source_window_sp->GetBounds();
+
+ if (variables_window_sp) {
+ const Rect variables_bounds = variables_window_sp->GetBounds();
+
+ main_window_sp->RemoveSubWindow(variables_window_sp.get());
+
+ if (registers_window_sp) {
+ // We have a registers window, so give all the area back to the
+ // registers window
+ Rect registers_bounds = variables_bounds;
+ registers_bounds.size.width = source_bounds.size.width;
+ registers_window_sp->SetBounds(registers_bounds);
+ } else {
+ // We have no registers window showing so give the bottom
+ // area back to the source view
+ source_window_sp->Resize(source_bounds.size.width,
+ source_bounds.size.height +
+ variables_bounds.size.height);
+ }
+ } else {
+ Rect new_variables_rect;
+ if (registers_window_sp) {
+ // We have a registers window so split the area of the registers
+ // window into two columns where the left hand side will be the
+ // variables and the right hand side will be the registers
+ const Rect variables_bounds = registers_window_sp->GetBounds();
+ Rect new_registers_rect;
+ variables_bounds.VerticalSplitPercentage(0.50, new_variables_rect,
+ new_registers_rect);
+ registers_window_sp->SetBounds(new_registers_rect);
+ } else {
+ // No variables window, grab the bottom part of the source window
+ Rect new_source_rect;
+ source_bounds.HorizontalSplitPercentage(0.70, new_source_rect,
+ new_variables_rect);
+ source_window_sp->SetBounds(new_source_rect);
+ }
+ WindowSP new_window_sp = main_window_sp->CreateSubWindow(
+ "Variables", new_variables_rect, false);
+ new_window_sp->SetDelegate(
+ WindowDelegateSP(new FrameVariablesWindowDelegate(m_debugger)));
+ }
+ touchwin(stdscr);
}
-protected:
- Application &m_app;
- Debugger &m_debugger;
-};
-
-class StatusBarWindowDelegate : public WindowDelegate
-{
-public:
- StatusBarWindowDelegate (Debugger &debugger) :
- m_debugger (debugger)
- {
- FormatEntity::Parse("Thread: ${thread.id%tid}",
- m_format);
+ return MenuActionResult::Handled;
+
+ case eMenuID_ViewRegisters: {
+ WindowSP main_window_sp = m_app.GetMainWindow();
+ WindowSP source_window_sp = main_window_sp->FindSubWindow("Source");
+ WindowSP variables_window_sp = main_window_sp->FindSubWindow("Variables");
+ WindowSP registers_window_sp = main_window_sp->FindSubWindow("Registers");
+ const Rect source_bounds = source_window_sp->GetBounds();
+
+ if (registers_window_sp) {
+ if (variables_window_sp) {
+ const Rect variables_bounds = variables_window_sp->GetBounds();
+
+ // We have a variables window, so give all the area back to the
+ // variables window
+ variables_window_sp->Resize(variables_bounds.size.width +
+ registers_window_sp->GetWidth(),
+ variables_bounds.size.height);
+ } else {
+ // We have no variables window showing so give the bottom
+ // area back to the source view
+ source_window_sp->Resize(source_bounds.size.width,
+ source_bounds.size.height +
+ registers_window_sp->GetHeight());
+ }
+ main_window_sp->RemoveSubWindow(registers_window_sp.get());
+ } else {
+ Rect new_regs_rect;
+ if (variables_window_sp) {
+ // We have a variables window, split it into two columns
+ // where the left hand side will be the variables and the
+ // right hand side will be the registers
+ const Rect variables_bounds = variables_window_sp->GetBounds();
+ Rect new_vars_rect;
+ variables_bounds.VerticalSplitPercentage(0.50, new_vars_rect,
+ new_regs_rect);
+ variables_window_sp->SetBounds(new_vars_rect);
+ } else {
+ // No registers window, grab the bottom part of the source window
+ Rect new_source_rect;
+ source_bounds.HorizontalSplitPercentage(0.70, new_source_rect,
+ new_regs_rect);
+ source_window_sp->SetBounds(new_source_rect);
+ }
+ WindowSP new_window_sp =
+ main_window_sp->CreateSubWindow("Registers", new_regs_rect, false);
+ new_window_sp->SetDelegate(
+ WindowDelegateSP(new RegistersWindowDelegate(m_debugger)));
+ }
+ touchwin(stdscr);
}
+ return MenuActionResult::Handled;
- ~StatusBarWindowDelegate() override = default;
-
- bool
- WindowDelegateDraw (Window &window, bool force) override
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = exe_ctx.GetThreadPtr();
- StackFrame *frame = exe_ctx.GetFramePtr();
- window.Erase();
- window.SetBackground(2);
- window.MoveCursor (0, 0);
- if (process)
- {
- const StateType state = process->GetState();
- window.Printf ("Process: %5" PRIu64 " %10s", process->GetID(), StateAsCString(state));
-
- if (StateIsStoppedState(state, true))
- {
- StreamString strm;
- if (thread && FormatEntity::Format(m_format, strm, nullptr, &exe_ctx, nullptr, nullptr, false, false))
- {
- window.MoveCursor (40, 0);
- window.PutCStringTruncated(strm.GetString().c_str(), 1);
- }
+ case eMenuID_HelpGUIHelp:
+ m_app.GetMainWindow()->CreateHelpSubwindow();
+ return MenuActionResult::Handled;
- window.MoveCursor (60, 0);
- if (frame)
- window.Printf ("Frame: %3u PC = 0x%16.16" PRIx64, frame->GetFrameIndex(), frame->GetFrameCodeAddress().GetOpcodeLoadAddress (exe_ctx.GetTargetPtr()));
- }
- else if (state == eStateExited)
- {
- const char *exit_desc = process->GetExitDescription();
- const int exit_status = process->GetExitStatus();
- if (exit_desc && exit_desc[0])
- window.Printf (" with status = %i (%s)", exit_status, exit_desc);
- else
- window.Printf (" with status = %i", exit_status);
- }
- }
- window.DeferredRefresh();
- return true;
+ default:
+ break;
}
+ return MenuActionResult::NotHandled;
+ }
+
protected:
- Debugger &m_debugger;
- FormatEntity::Entry m_format;
+ Application &m_app;
+ Debugger &m_debugger;
};
-class SourceFileWindowDelegate : public WindowDelegate
-{
+class StatusBarWindowDelegate : public WindowDelegate {
public:
- SourceFileWindowDelegate (Debugger &debugger) :
- WindowDelegate (),
- m_debugger (debugger),
- m_sc (),
- m_file_sp (),
- m_disassembly_scope(nullptr),
- m_disassembly_sp (),
- m_disassembly_range (),
- m_title (),
- m_line_width (4),
- m_selected_line (0),
- m_pc_line (0),
- m_stop_id (0),
- m_frame_idx (UINT32_MAX),
- m_first_visible_line (0),
- m_min_x (0),
- m_min_y (0),
- m_max_x (0),
- m_max_y (0)
- {
- }
-
- ~SourceFileWindowDelegate() override = default;
-
- void
- Update (const SymbolContext &sc)
- {
- m_sc = sc;
- }
-
- uint32_t
- NumVisibleLines () const
- {
- return m_max_y - m_min_y;
+ StatusBarWindowDelegate(Debugger &debugger) : m_debugger(debugger) {
+ FormatEntity::Parse("Thread: ${thread.id%tid}", m_format);
+ }
+
+ ~StatusBarWindowDelegate() override = default;
+
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = exe_ctx.GetThreadPtr();
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ window.Erase();
+ window.SetBackground(2);
+ window.MoveCursor(0, 0);
+ if (process) {
+ const StateType state = process->GetState();
+ window.Printf("Process: %5" PRIu64 " %10s", process->GetID(),
+ StateAsCString(state));
+
+ if (StateIsStoppedState(state, true)) {
+ StreamString strm;
+ if (thread && FormatEntity::Format(m_format, strm, nullptr, &exe_ctx,
+ nullptr, nullptr, false, false)) {
+ window.MoveCursor(40, 0);
+ window.PutCStringTruncated(strm.GetString().str().c_str(), 1);
+ }
+
+ window.MoveCursor(60, 0);
+ if (frame)
+ window.Printf("Frame: %3u PC = 0x%16.16" PRIx64,
+ frame->GetFrameIndex(),
+ frame->GetFrameCodeAddress().GetOpcodeLoadAddress(
+ exe_ctx.GetTargetPtr()));
+ } else if (state == eStateExited) {
+ const char *exit_desc = process->GetExitDescription();
+ const int exit_status = process->GetExitStatus();
+ if (exit_desc && exit_desc[0])
+ window.Printf(" with status = %i (%s)", exit_status, exit_desc);
+ else
+ window.Printf(" with status = %i", exit_status);
+ }
}
+ window.DeferredRefresh();
+ return true;
+ }
- const char *
- WindowDelegateGetHelpText () override
- {
- return "Source/Disassembly window keyboard shortcuts:";
- }
+protected:
+ Debugger &m_debugger;
+ FormatEntity::Entry m_format;
+};
- KeyHelp *
- WindowDelegateGetKeyHelp () override
- {
- static curses::KeyHelp g_source_view_key_help[] = {
- { KEY_RETURN, "Run to selected line with one shot breakpoint" },
- { KEY_UP, "Select previous source line" },
- { KEY_DOWN, "Select next source line" },
- { KEY_PPAGE, "Page up" },
- { KEY_NPAGE, "Page down" },
- { 'b', "Set breakpoint on selected source/disassembly line" },
- { 'c', "Continue process" },
- { 'd', "Detach and resume process" },
- { 'D', "Detach with process suspended" },
- { 'h', "Show help dialog" },
- { 'k', "Kill process" },
- { 'n', "Step over (source line)" },
- { 'N', "Step over (single instruction)" },
- { 'o', "Step out" },
- { 's', "Step in (source line)" },
- { 'S', "Step in (single instruction)" },
- { ',', "Page up" },
- { '.', "Page down" },
- { '\0', nullptr }
- };
- return g_source_view_key_help;
+class SourceFileWindowDelegate : public WindowDelegate {
+public:
+ SourceFileWindowDelegate(Debugger &debugger)
+ : WindowDelegate(), m_debugger(debugger), m_sc(), m_file_sp(),
+ m_disassembly_scope(nullptr), m_disassembly_sp(), m_disassembly_range(),
+ m_title(), m_line_width(4), m_selected_line(0), m_pc_line(0),
+ m_stop_id(0), m_frame_idx(UINT32_MAX), m_first_visible_line(0),
+ m_min_x(0), m_min_y(0), m_max_x(0), m_max_y(0) {}
+
+ ~SourceFileWindowDelegate() override = default;
+
+ void Update(const SymbolContext &sc) { m_sc = sc; }
+
+ uint32_t NumVisibleLines() const { return m_max_y - m_min_y; }
+
+ const char *WindowDelegateGetHelpText() override {
+ return "Source/Disassembly window keyboard shortcuts:";
+ }
+
+ KeyHelp *WindowDelegateGetKeyHelp() override {
+ static curses::KeyHelp g_source_view_key_help[] = {
+ {KEY_RETURN, "Run to selected line with one shot breakpoint"},
+ {KEY_UP, "Select previous source line"},
+ {KEY_DOWN, "Select next source line"},
+ {KEY_PPAGE, "Page up"},
+ {KEY_NPAGE, "Page down"},
+ {'b', "Set breakpoint on selected source/disassembly line"},
+ {'c', "Continue process"},
+ {'d', "Detach and resume process"},
+ {'D', "Detach with process suspended"},
+ {'h', "Show help dialog"},
+ {'k', "Kill process"},
+ {'n', "Step over (source line)"},
+ {'N', "Step over (single instruction)"},
+ {'o', "Step out"},
+ {'s', "Step in (source line)"},
+ {'S', "Step in (single instruction)"},
+ {',', "Page up"},
+ {'.', "Page down"},
+ {'\0', nullptr}};
+ return g_source_view_key_help;
+ }
+
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ Process *process = exe_ctx.GetProcessPtr();
+ Thread *thread = nullptr;
+
+ bool update_location = false;
+ if (process) {
+ StateType state = process->GetState();
+ if (StateIsStoppedState(state, true)) {
+ // We are stopped, so it is ok to
+ update_location = true;
+ }
}
- bool
- WindowDelegateDraw (Window &window, bool force) override
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- Process *process = exe_ctx.GetProcessPtr();
- Thread *thread = nullptr;
-
- bool update_location = false;
- if (process)
- {
- StateType state = process->GetState();
- if (StateIsStoppedState(state, true))
- {
- // We are stopped, so it is ok to
- update_location = true;
+ m_min_x = 1;
+ m_min_y = 2;
+ m_max_x = window.GetMaxX() - 1;
+ m_max_y = window.GetMaxY() - 1;
+
+ const uint32_t num_visible_lines = NumVisibleLines();
+ StackFrameSP frame_sp;
+ bool set_selected_line_to_pc = false;
+
+ if (update_location) {
+ const bool process_alive = process ? process->IsAlive() : false;
+ bool thread_changed = false;
+ if (process_alive) {
+ thread = exe_ctx.GetThreadPtr();
+ if (thread) {
+ frame_sp = thread->GetSelectedFrame();
+ auto tid = thread->GetID();
+ thread_changed = tid != m_tid;
+ m_tid = tid;
+ } else {
+ if (m_tid != LLDB_INVALID_THREAD_ID) {
+ thread_changed = true;
+ m_tid = LLDB_INVALID_THREAD_ID;
+ }
+ }
+ }
+ const uint32_t stop_id = process ? process->GetStopID() : 0;
+ const bool stop_id_changed = stop_id != m_stop_id;
+ bool frame_changed = false;
+ m_stop_id = stop_id;
+ m_title.Clear();
+ if (frame_sp) {
+ m_sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
+ if (m_sc.module_sp) {
+ m_title.Printf(
+ "%s", m_sc.module_sp->GetFileSpec().GetFilename().GetCString());
+ ConstString func_name = m_sc.GetFunctionName();
+ if (func_name)
+ m_title.Printf("`%s", func_name.GetCString());
+ }
+ const uint32_t frame_idx = frame_sp->GetFrameIndex();
+ frame_changed = frame_idx != m_frame_idx;
+ m_frame_idx = frame_idx;
+ } else {
+ m_sc.Clear(true);
+ frame_changed = m_frame_idx != UINT32_MAX;
+ m_frame_idx = UINT32_MAX;
+ }
+
+ const bool context_changed =
+ thread_changed || frame_changed || stop_id_changed;
+
+ if (process_alive) {
+ if (m_sc.line_entry.IsValid()) {
+ m_pc_line = m_sc.line_entry.line;
+ if (m_pc_line != UINT32_MAX)
+ --m_pc_line; // Convert to zero based line number...
+ // Update the selected line if the stop ID changed...
+ if (context_changed)
+ m_selected_line = m_pc_line;
+
+ if (m_file_sp && m_file_sp->FileSpecMatches(m_sc.line_entry.file)) {
+ // Same file, nothing to do, we should either have the
+ // lines or not (source file missing)
+ if (m_selected_line >= static_cast<size_t>(m_first_visible_line)) {
+ if (m_selected_line >= m_first_visible_line + num_visible_lines)
+ m_first_visible_line = m_selected_line - 10;
+ } else {
+ if (m_selected_line > 10)
+ m_first_visible_line = m_selected_line - 10;
+ else
+ m_first_visible_line = 0;
}
- }
-
- m_min_x = 1;
- m_min_y = 2;
- m_max_x = window.GetMaxX()-1;
- m_max_y = window.GetMaxY()-1;
-
- const uint32_t num_visible_lines = NumVisibleLines();
- StackFrameSP frame_sp;
- bool set_selected_line_to_pc = false;
-
- if (update_location)
- {
- const bool process_alive = process ? process->IsAlive() : false;
- bool thread_changed = false;
- if (process_alive)
- {
- thread = exe_ctx.GetThreadPtr();
- if (thread)
- {
- frame_sp = thread->GetSelectedFrame();
- auto tid = thread->GetID();
- thread_changed = tid != m_tid;
- m_tid = tid;
- }
- else
- {
- if (m_tid != LLDB_INVALID_THREAD_ID)
- {
- thread_changed = true;
- m_tid = LLDB_INVALID_THREAD_ID;
- }
- }
+ } else {
+ // File changed, set selected line to the line with the PC
+ m_selected_line = m_pc_line;
+ m_file_sp =
+ m_debugger.GetSourceManager().GetFile(m_sc.line_entry.file);
+ if (m_file_sp) {
+ const size_t num_lines = m_file_sp->GetNumLines();
+ int m_line_width = 1;
+ for (size_t n = num_lines; n >= 10; n = n / 10)
+ ++m_line_width;
+
+ snprintf(m_line_format, sizeof(m_line_format), " %%%iu ",
+ m_line_width);
+ if (num_lines < num_visible_lines ||
+ m_selected_line < num_visible_lines)
+ m_first_visible_line = 0;
+ else
+ m_first_visible_line = m_selected_line - 10;
}
- const uint32_t stop_id = process ? process->GetStopID() : 0;
- const bool stop_id_changed = stop_id != m_stop_id;
- bool frame_changed = false;
- m_stop_id = stop_id;
- m_title.Clear();
- if (frame_sp)
- {
- m_sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
- if (m_sc.module_sp)
- {
- m_title.Printf("%s", m_sc.module_sp->GetFileSpec().GetFilename().GetCString());
- ConstString func_name = m_sc.GetFunctionName();
- if (func_name)
- m_title.Printf("`%s", func_name.GetCString());
- }
- const uint32_t frame_idx = frame_sp->GetFrameIndex();
- frame_changed = frame_idx != m_frame_idx;
- m_frame_idx = frame_idx;
+ }
+ } else {
+ m_file_sp.reset();
+ }
+
+ if (!m_file_sp || m_file_sp->GetNumLines() == 0) {
+ // Show disassembly
+ bool prefer_file_cache = false;
+ if (m_sc.function) {
+ if (m_disassembly_scope != m_sc.function) {
+ m_disassembly_scope = m_sc.function;
+ m_disassembly_sp = m_sc.function->GetInstructions(
+ exe_ctx, nullptr, prefer_file_cache);
+ if (m_disassembly_sp) {
+ set_selected_line_to_pc = true;
+ m_disassembly_range = m_sc.function->GetAddressRange();
+ } else {
+ m_disassembly_range.Clear();
+ }
+ } else {
+ set_selected_line_to_pc = context_changed;
}
- else
- {
- m_sc.Clear(true);
- frame_changed = m_frame_idx != UINT32_MAX;
- m_frame_idx = UINT32_MAX;
+ } else if (m_sc.symbol) {
+ if (m_disassembly_scope != m_sc.symbol) {
+ m_disassembly_scope = m_sc.symbol;
+ m_disassembly_sp = m_sc.symbol->GetInstructions(
+ exe_ctx, nullptr, prefer_file_cache);
+ if (m_disassembly_sp) {
+ set_selected_line_to_pc = true;
+ m_disassembly_range.GetBaseAddress() =
+ m_sc.symbol->GetAddress();
+ m_disassembly_range.SetByteSize(m_sc.symbol->GetByteSize());
+ } else {
+ m_disassembly_range.Clear();
+ }
+ } else {
+ set_selected_line_to_pc = context_changed;
}
+ }
+ }
+ } else {
+ m_pc_line = UINT32_MAX;
+ }
+ }
- const bool context_changed = thread_changed || frame_changed || stop_id_changed;
-
- if (process_alive)
- {
- if (m_sc.line_entry.IsValid())
- {
- m_pc_line = m_sc.line_entry.line;
- if (m_pc_line != UINT32_MAX)
- --m_pc_line; // Convert to zero based line number...
- // Update the selected line if the stop ID changed...
- if (context_changed)
- m_selected_line = m_pc_line;
-
- if (m_file_sp && m_file_sp->FileSpecMatches(m_sc.line_entry.file))
- {
- // Same file, nothing to do, we should either have the
- // lines or not (source file missing)
- if (m_selected_line >= static_cast<size_t>(m_first_visible_line))
- {
- if (m_selected_line >= m_first_visible_line + num_visible_lines)
- m_first_visible_line = m_selected_line - 10;
- }
- else
- {
- if (m_selected_line > 10)
- m_first_visible_line = m_selected_line - 10;
- else
- m_first_visible_line = 0;
- }
- }
- else
- {
- // File changed, set selected line to the line with the PC
- m_selected_line = m_pc_line;
- m_file_sp = m_debugger.GetSourceManager().GetFile(m_sc.line_entry.file);
- if (m_file_sp)
- {
- const size_t num_lines = m_file_sp->GetNumLines();
- int m_line_width = 1;
- for (size_t n = num_lines; n >= 10; n = n / 10)
- ++m_line_width;
-
- snprintf (m_line_format, sizeof(m_line_format), " %%%iu ", m_line_width);
- if (num_lines < num_visible_lines || m_selected_line < num_visible_lines)
- m_first_visible_line = 0;
- else
- m_first_visible_line = m_selected_line - 10;
- }
- }
- }
- else
- {
- m_file_sp.reset();
- }
+ const int window_width = window.GetWidth();
+ window.Erase();
+ window.DrawTitleBox("Sources");
+ if (!m_title.GetString().empty()) {
+ window.AttributeOn(A_REVERSE);
+ window.MoveCursor(1, 1);
+ window.PutChar(' ');
+ window.PutCStringTruncated(m_title.GetString().str().c_str(), 1);
+ int x = window.GetCursorX();
+ if (x < window_width - 1) {
+ window.Printf("%*s", window_width - x - 1, "");
+ }
+ window.AttributeOff(A_REVERSE);
+ }
- if (!m_file_sp || m_file_sp->GetNumLines() == 0)
- {
- // Show disassembly
- bool prefer_file_cache = false;
- if (m_sc.function)
- {
- if (m_disassembly_scope != m_sc.function)
- {
- m_disassembly_scope = m_sc.function;
- m_disassembly_sp = m_sc.function->GetInstructions(exe_ctx, nullptr, prefer_file_cache);
- if (m_disassembly_sp)
- {
- set_selected_line_to_pc = true;
- m_disassembly_range = m_sc.function->GetAddressRange();
- }
- else
- {
- m_disassembly_range.Clear();
- }
- }
- else
- {
- set_selected_line_to_pc = context_changed;
- }
- }
- else if (m_sc.symbol)
- {
- if (m_disassembly_scope != m_sc.symbol)
- {
- m_disassembly_scope = m_sc.symbol;
- m_disassembly_sp = m_sc.symbol->GetInstructions(exe_ctx, nullptr, prefer_file_cache);
- if (m_disassembly_sp)
- {
- set_selected_line_to_pc = true;
- m_disassembly_range.GetBaseAddress() = m_sc.symbol->GetAddress();
- m_disassembly_range.SetByteSize(m_sc.symbol->GetByteSize());
- }
- else
- {
- m_disassembly_range.Clear();
- }
- }
- else
- {
- set_selected_line_to_pc = context_changed;
- }
- }
- }
+ Target *target = exe_ctx.GetTargetPtr();
+ const size_t num_source_lines = GetNumSourceLines();
+ if (num_source_lines > 0) {
+ // Display source
+ BreakpointLines bp_lines;
+ if (target) {
+ BreakpointList &bp_list = target->GetBreakpointList();
+ const size_t num_bps = bp_list.GetSize();
+ for (size_t bp_idx = 0; bp_idx < num_bps; ++bp_idx) {
+ BreakpointSP bp_sp = bp_list.GetBreakpointAtIndex(bp_idx);
+ const size_t num_bps_locs = bp_sp->GetNumLocations();
+ for (size_t bp_loc_idx = 0; bp_loc_idx < num_bps_locs; ++bp_loc_idx) {
+ BreakpointLocationSP bp_loc_sp =
+ bp_sp->GetLocationAtIndex(bp_loc_idx);
+ LineEntry bp_loc_line_entry;
+ if (bp_loc_sp->GetAddress().CalculateSymbolContextLineEntry(
+ bp_loc_line_entry)) {
+ if (m_file_sp->GetFileSpec() == bp_loc_line_entry.file) {
+ bp_lines.insert(bp_loc_line_entry.line);
+ }
}
- else
- {
- m_pc_line = UINT32_MAX;
- }
- }
-
- const int window_width = window.GetWidth();
- window.Erase();
- window.DrawTitleBox ("Sources");
- if (!m_title.GetString().empty())
- {
- window.AttributeOn(A_REVERSE);
- window.MoveCursor(1, 1);
+ }
+ }
+ }
+
+ const attr_t selected_highlight_attr = A_REVERSE;
+ const attr_t pc_highlight_attr = COLOR_PAIR(1);
+
+ for (size_t i = 0; i < num_visible_lines; ++i) {
+ const uint32_t curr_line = m_first_visible_line + i;
+ if (curr_line < num_source_lines) {
+ const int line_y = m_min_y + i;
+ window.MoveCursor(1, line_y);
+ const bool is_pc_line = curr_line == m_pc_line;
+ const bool line_is_selected = m_selected_line == curr_line;
+ // Highlight the line as the PC line first, then if the selected line
+ // isn't the same as the PC line, highlight it differently
+ attr_t highlight_attr = 0;
+ attr_t bp_attr = 0;
+ if (is_pc_line)
+ highlight_attr = pc_highlight_attr;
+ else if (line_is_selected)
+ highlight_attr = selected_highlight_attr;
+
+ if (bp_lines.find(curr_line + 1) != bp_lines.end())
+ bp_attr = COLOR_PAIR(2);
+
+ if (bp_attr)
+ window.AttributeOn(bp_attr);
+
+ window.Printf(m_line_format, curr_line + 1);
+
+ if (bp_attr)
+ window.AttributeOff(bp_attr);
+
+ window.PutChar(ACS_VLINE);
+ // Mark the line with the PC with a diamond
+ if (is_pc_line)
+ window.PutChar(ACS_DIAMOND);
+ else
window.PutChar(' ');
- window.PutCStringTruncated(m_title.GetString().c_str(), 1);
- int x = window.GetCursorX();
- if (x < window_width - 1)
- {
- window.Printf ("%*s", window_width - x - 1, "");
- }
- window.AttributeOff(A_REVERSE);
- }
- Target *target = exe_ctx.GetTargetPtr();
- const size_t num_source_lines = GetNumSourceLines();
- if (num_source_lines > 0)
- {
- // Display source
- BreakpointLines bp_lines;
- if (target)
- {
- BreakpointList &bp_list = target->GetBreakpointList();
- const size_t num_bps = bp_list.GetSize();
- for (size_t bp_idx=0; bp_idx<num_bps; ++bp_idx)
- {
- BreakpointSP bp_sp = bp_list.GetBreakpointAtIndex(bp_idx);
- const size_t num_bps_locs = bp_sp->GetNumLocations();
- for (size_t bp_loc_idx=0; bp_loc_idx<num_bps_locs; ++bp_loc_idx)
- {
- BreakpointLocationSP bp_loc_sp = bp_sp->GetLocationAtIndex(bp_loc_idx);
- LineEntry bp_loc_line_entry;
- if (bp_loc_sp->GetAddress().CalculateSymbolContextLineEntry (bp_loc_line_entry))
- {
- if (m_file_sp->GetFileSpec() == bp_loc_line_entry.file)
- {
- bp_lines.insert(bp_loc_line_entry.line);
- }
- }
- }
- }
+ if (highlight_attr)
+ window.AttributeOn(highlight_attr);
+ const uint32_t line_len =
+ m_file_sp->GetLineLength(curr_line + 1, false);
+ if (line_len > 0)
+ window.PutCString(m_file_sp->PeekLineData(curr_line + 1), line_len);
+
+ if (is_pc_line && frame_sp &&
+ frame_sp->GetConcreteFrameIndex() == 0) {
+ StopInfoSP stop_info_sp;
+ if (thread)
+ stop_info_sp = thread->GetStopInfo();
+ if (stop_info_sp) {
+ const char *stop_description = stop_info_sp->GetDescription();
+ if (stop_description && stop_description[0]) {
+ size_t stop_description_len = strlen(stop_description);
+ int desc_x = window_width - stop_description_len - 16;
+ window.Printf("%*s", desc_x - window.GetCursorX(), "");
+ // window.MoveCursor(window_width - stop_description_len - 15,
+ // line_y);
+ window.Printf("<<< Thread %u: %s ", thread->GetIndexID(),
+ stop_description);
+ }
+ } else {
+ window.Printf("%*s", window_width - window.GetCursorX() - 1, "");
}
-
- const attr_t selected_highlight_attr = A_REVERSE;
- const attr_t pc_highlight_attr = COLOR_PAIR(1);
-
- for (size_t i = 0; i < num_visible_lines; ++i)
- {
- const uint32_t curr_line = m_first_visible_line + i;
- if (curr_line < num_source_lines)
- {
- const int line_y = m_min_y+i;
- window.MoveCursor(1, line_y);
- const bool is_pc_line = curr_line == m_pc_line;
- const bool line_is_selected = m_selected_line == curr_line;
- // Highlight the line as the PC line first, then if the selected line
- // isn't the same as the PC line, highlight it differently
- attr_t highlight_attr = 0;
- attr_t bp_attr = 0;
- if (is_pc_line)
- highlight_attr = pc_highlight_attr;
- else if (line_is_selected)
- highlight_attr = selected_highlight_attr;
-
- if (bp_lines.find(curr_line+1) != bp_lines.end())
- bp_attr = COLOR_PAIR(2);
-
- if (bp_attr)
- window.AttributeOn(bp_attr);
-
- window.Printf (m_line_format, curr_line + 1);
-
- if (bp_attr)
- window.AttributeOff(bp_attr);
-
- window.PutChar(ACS_VLINE);
- // Mark the line with the PC with a diamond
- if (is_pc_line)
- window.PutChar(ACS_DIAMOND);
- else
- window.PutChar(' ');
-
- if (highlight_attr)
- window.AttributeOn(highlight_attr);
- const uint32_t line_len = m_file_sp->GetLineLength(curr_line + 1, false);
- if (line_len > 0)
- window.PutCString(m_file_sp->PeekLineData(curr_line + 1), line_len);
-
- if (is_pc_line && frame_sp && frame_sp->GetConcreteFrameIndex() == 0)
- {
- StopInfoSP stop_info_sp;
- if (thread)
- stop_info_sp = thread->GetStopInfo();
- if (stop_info_sp)
- {
- const char *stop_description = stop_info_sp->GetDescription();
- if (stop_description && stop_description[0])
- {
- size_t stop_description_len = strlen(stop_description);
- int desc_x = window_width - stop_description_len - 16;
- window.Printf ("%*s", desc_x - window.GetCursorX(), "");
- //window.MoveCursor(window_width - stop_description_len - 15, line_y);
- window.Printf ("<<< Thread %u: %s ", thread->GetIndexID(), stop_description);
- }
- }
- else
- {
- window.Printf ("%*s", window_width - window.GetCursorX() - 1, "");
- }
- }
- if (highlight_attr)
- window.AttributeOff(highlight_attr);
- }
- else
- {
- break;
- }
+ }
+ if (highlight_attr)
+ window.AttributeOff(highlight_attr);
+ } else {
+ break;
+ }
+ }
+ } else {
+ size_t num_disassembly_lines = GetNumDisassemblyLines();
+ if (num_disassembly_lines > 0) {
+ // Display disassembly
+ BreakpointAddrs bp_file_addrs;
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ BreakpointList &bp_list = target->GetBreakpointList();
+ const size_t num_bps = bp_list.GetSize();
+ for (size_t bp_idx = 0; bp_idx < num_bps; ++bp_idx) {
+ BreakpointSP bp_sp = bp_list.GetBreakpointAtIndex(bp_idx);
+ const size_t num_bps_locs = bp_sp->GetNumLocations();
+ for (size_t bp_loc_idx = 0; bp_loc_idx < num_bps_locs;
+ ++bp_loc_idx) {
+ BreakpointLocationSP bp_loc_sp =
+ bp_sp->GetLocationAtIndex(bp_loc_idx);
+ LineEntry bp_loc_line_entry;
+ const lldb::addr_t file_addr =
+ bp_loc_sp->GetAddress().GetFileAddress();
+ if (file_addr != LLDB_INVALID_ADDRESS) {
+ if (m_disassembly_range.ContainsFileAddress(file_addr))
+ bp_file_addrs.insert(file_addr);
+ }
}
+ }
}
- else
- {
- size_t num_disassembly_lines = GetNumDisassemblyLines();
- if (num_disassembly_lines > 0)
- {
- // Display disassembly
- BreakpointAddrs bp_file_addrs;
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- BreakpointList &bp_list = target->GetBreakpointList();
- const size_t num_bps = bp_list.GetSize();
- for (size_t bp_idx=0; bp_idx<num_bps; ++bp_idx)
- {
- BreakpointSP bp_sp = bp_list.GetBreakpointAtIndex(bp_idx);
- const size_t num_bps_locs = bp_sp->GetNumLocations();
- for (size_t bp_loc_idx=0; bp_loc_idx<num_bps_locs; ++bp_loc_idx)
- {
- BreakpointLocationSP bp_loc_sp = bp_sp->GetLocationAtIndex(bp_loc_idx);
- LineEntry bp_loc_line_entry;
- const lldb::addr_t file_addr = bp_loc_sp->GetAddress().GetFileAddress();
- if (file_addr != LLDB_INVALID_ADDRESS)
- {
- if (m_disassembly_range.ContainsFileAddress(file_addr))
- bp_file_addrs.insert(file_addr);
- }
- }
- }
- }
- const attr_t selected_highlight_attr = A_REVERSE;
- const attr_t pc_highlight_attr = COLOR_PAIR(1);
+ const attr_t selected_highlight_attr = A_REVERSE;
+ const attr_t pc_highlight_attr = COLOR_PAIR(1);
- StreamString strm;
+ StreamString strm;
- InstructionList &insts = m_disassembly_sp->GetInstructionList();
- Address pc_address;
+ InstructionList &insts = m_disassembly_sp->GetInstructionList();
+ Address pc_address;
- if (frame_sp)
- pc_address = frame_sp->GetFrameCodeAddress();
- const uint32_t pc_idx = pc_address.IsValid() ? insts.GetIndexOfInstructionAtAddress (pc_address) : UINT32_MAX;
- if (set_selected_line_to_pc)
- {
- m_selected_line = pc_idx;
- }
+ if (frame_sp)
+ pc_address = frame_sp->GetFrameCodeAddress();
+ const uint32_t pc_idx =
+ pc_address.IsValid()
+ ? insts.GetIndexOfInstructionAtAddress(pc_address)
+ : UINT32_MAX;
+ if (set_selected_line_to_pc) {
+ m_selected_line = pc_idx;
+ }
- const uint32_t non_visible_pc_offset = (num_visible_lines / 5);
- if (static_cast<size_t>(m_first_visible_line) >= num_disassembly_lines)
- m_first_visible_line = 0;
+ const uint32_t non_visible_pc_offset = (num_visible_lines / 5);
+ if (static_cast<size_t>(m_first_visible_line) >= num_disassembly_lines)
+ m_first_visible_line = 0;
- if (pc_idx < num_disassembly_lines)
- {
- if (pc_idx < static_cast<uint32_t>(m_first_visible_line) ||
- pc_idx >= m_first_visible_line + num_visible_lines)
- m_first_visible_line = pc_idx - non_visible_pc_offset;
- }
+ if (pc_idx < num_disassembly_lines) {
+ if (pc_idx < static_cast<uint32_t>(m_first_visible_line) ||
+ pc_idx >= m_first_visible_line + num_visible_lines)
+ m_first_visible_line = pc_idx - non_visible_pc_offset;
+ }
- for (size_t i = 0; i < num_visible_lines; ++i)
- {
- const uint32_t inst_idx = m_first_visible_line + i;
- Instruction *inst = insts.GetInstructionAtIndex(inst_idx).get();
- if (!inst)
- break;
-
- const int line_y = m_min_y+i;
- window.MoveCursor(1, line_y);
- const bool is_pc_line = frame_sp && inst_idx == pc_idx;
- const bool line_is_selected = m_selected_line == inst_idx;
- // Highlight the line as the PC line first, then if the selected line
- // isn't the same as the PC line, highlight it differently
- attr_t highlight_attr = 0;
- attr_t bp_attr = 0;
- if (is_pc_line)
- highlight_attr = pc_highlight_attr;
- else if (line_is_selected)
- highlight_attr = selected_highlight_attr;
-
- if (bp_file_addrs.find(inst->GetAddress().GetFileAddress()) != bp_file_addrs.end())
- bp_attr = COLOR_PAIR(2);
-
- if (bp_attr)
- window.AttributeOn(bp_attr);
-
- window.Printf (" 0x%16.16llx ",
- static_cast<unsigned long long>(inst->GetAddress().GetLoadAddress(target)));
-
- if (bp_attr)
- window.AttributeOff(bp_attr);
-
- window.PutChar(ACS_VLINE);
- // Mark the line with the PC with a diamond
- if (is_pc_line)
- window.PutChar(ACS_DIAMOND);
- else
- window.PutChar(' ');
-
- if (highlight_attr)
- window.AttributeOn(highlight_attr);
-
- const char *mnemonic = inst->GetMnemonic(&exe_ctx);
- const char *operands = inst->GetOperands(&exe_ctx);
- const char *comment = inst->GetComment(&exe_ctx);
-
- if (mnemonic != nullptr && mnemonic[0] == '\0')
- mnemonic = nullptr;
- if (operands != nullptr && operands[0] == '\0')
- operands = nullptr;
- if (comment != nullptr && comment[0] == '\0')
- comment = nullptr;
-
- strm.Clear();
-
- if (mnemonic != nullptr && operands != nullptr && comment != nullptr)
- strm.Printf ("%-8s %-25s ; %s", mnemonic, operands, comment);
- else if (mnemonic != nullptr && operands != nullptr)
- strm.Printf ("%-8s %s", mnemonic, operands);
- else if (mnemonic != nullptr)
- strm.Printf ("%s", mnemonic);
-
- int right_pad = 1;
- window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
-
- if (is_pc_line && frame_sp && frame_sp->GetConcreteFrameIndex() == 0)
- {
- StopInfoSP stop_info_sp;
- if (thread)
- stop_info_sp = thread->GetStopInfo();
- if (stop_info_sp)
- {
- const char *stop_description = stop_info_sp->GetDescription();
- if (stop_description && stop_description[0])
- {
- size_t stop_description_len = strlen(stop_description);
- int desc_x = window_width - stop_description_len - 16;
- window.Printf ("%*s", desc_x - window.GetCursorX(), "");
- //window.MoveCursor(window_width - stop_description_len - 15, line_y);
- window.Printf ("<<< Thread %u: %s ", thread->GetIndexID(), stop_description);
- }
- }
- else
- {
- window.Printf ("%*s", window_width - window.GetCursorX() - 1, "");
- }
- }
- if (highlight_attr)
- window.AttributeOff(highlight_attr);
- }
+ for (size_t i = 0; i < num_visible_lines; ++i) {
+ const uint32_t inst_idx = m_first_visible_line + i;
+ Instruction *inst = insts.GetInstructionAtIndex(inst_idx).get();
+ if (!inst)
+ break;
+
+ const int line_y = m_min_y + i;
+ window.MoveCursor(1, line_y);
+ const bool is_pc_line = frame_sp && inst_idx == pc_idx;
+ const bool line_is_selected = m_selected_line == inst_idx;
+ // Highlight the line as the PC line first, then if the selected line
+ // isn't the same as the PC line, highlight it differently
+ attr_t highlight_attr = 0;
+ attr_t bp_attr = 0;
+ if (is_pc_line)
+ highlight_attr = pc_highlight_attr;
+ else if (line_is_selected)
+ highlight_attr = selected_highlight_attr;
+
+ if (bp_file_addrs.find(inst->GetAddress().GetFileAddress()) !=
+ bp_file_addrs.end())
+ bp_attr = COLOR_PAIR(2);
+
+ if (bp_attr)
+ window.AttributeOn(bp_attr);
+
+ window.Printf(" 0x%16.16llx ",
+ static_cast<unsigned long long>(
+ inst->GetAddress().GetLoadAddress(target)));
+
+ if (bp_attr)
+ window.AttributeOff(bp_attr);
+
+ window.PutChar(ACS_VLINE);
+ // Mark the line with the PC with a diamond
+ if (is_pc_line)
+ window.PutChar(ACS_DIAMOND);
+ else
+ window.PutChar(' ');
+
+ if (highlight_attr)
+ window.AttributeOn(highlight_attr);
+
+ const char *mnemonic = inst->GetMnemonic(&exe_ctx);
+ const char *operands = inst->GetOperands(&exe_ctx);
+ const char *comment = inst->GetComment(&exe_ctx);
+
+ if (mnemonic != nullptr && mnemonic[0] == '\0')
+ mnemonic = nullptr;
+ if (operands != nullptr && operands[0] == '\0')
+ operands = nullptr;
+ if (comment != nullptr && comment[0] == '\0')
+ comment = nullptr;
+
+ strm.Clear();
+
+ if (mnemonic != nullptr && operands != nullptr && comment != nullptr)
+ strm.Printf("%-8s %-25s ; %s", mnemonic, operands, comment);
+ else if (mnemonic != nullptr && operands != nullptr)
+ strm.Printf("%-8s %s", mnemonic, operands);
+ else if (mnemonic != nullptr)
+ strm.Printf("%s", mnemonic);
+
+ int right_pad = 1;
+ window.PutCStringTruncated(strm.GetData(), right_pad);
+
+ if (is_pc_line && frame_sp &&
+ frame_sp->GetConcreteFrameIndex() == 0) {
+ StopInfoSP stop_info_sp;
+ if (thread)
+ stop_info_sp = thread->GetStopInfo();
+ if (stop_info_sp) {
+ const char *stop_description = stop_info_sp->GetDescription();
+ if (stop_description && stop_description[0]) {
+ size_t stop_description_len = strlen(stop_description);
+ int desc_x = window_width - stop_description_len - 16;
+ window.Printf("%*s", desc_x - window.GetCursorX(), "");
+ // window.MoveCursor(window_width - stop_description_len - 15,
+ // line_y);
+ window.Printf("<<< Thread %u: %s ", thread->GetIndexID(),
+ stop_description);
+ }
+ } else {
+ window.Printf("%*s", window_width - window.GetCursorX() - 1, "");
}
+ }
+ if (highlight_attr)
+ window.AttributeOff(highlight_attr);
}
- window.DeferredRefresh();
- return true; // Drawing handled
+ }
}
+ window.DeferredRefresh();
+ return true; // Drawing handled
+ }
+
+ size_t GetNumLines() {
+ size_t num_lines = GetNumSourceLines();
+ if (num_lines == 0)
+ num_lines = GetNumDisassemblyLines();
+ return num_lines;
+ }
+
+ size_t GetNumSourceLines() const {
+ if (m_file_sp)
+ return m_file_sp->GetNumLines();
+ return 0;
+ }
- size_t
- GetNumLines ()
- {
- size_t num_lines = GetNumSourceLines();
- if (num_lines == 0)
- num_lines = GetNumDisassemblyLines();
- return num_lines;
+ size_t GetNumDisassemblyLines() const {
+ if (m_disassembly_sp)
+ return m_disassembly_sp->GetInstructionList().GetSize();
+ return 0;
+ }
+
+ HandleCharResult WindowDelegateHandleChar(Window &window, int c) override {
+ const uint32_t num_visible_lines = NumVisibleLines();
+ const size_t num_lines = GetNumLines();
+
+ switch (c) {
+ case ',':
+ case KEY_PPAGE:
+ // Page up key
+ if (static_cast<uint32_t>(m_first_visible_line) > num_visible_lines)
+ m_first_visible_line -= num_visible_lines;
+ else
+ m_first_visible_line = 0;
+ m_selected_line = m_first_visible_line;
+ return eKeyHandled;
+
+ case '.':
+ case KEY_NPAGE:
+ // Page down key
+ {
+ if (m_first_visible_line + num_visible_lines < num_lines)
+ m_first_visible_line += num_visible_lines;
+ else if (num_lines < num_visible_lines)
+ m_first_visible_line = 0;
+ else
+ m_first_visible_line = num_lines - num_visible_lines;
+ m_selected_line = m_first_visible_line;
+ }
+ return eKeyHandled;
+
+ case KEY_UP:
+ if (m_selected_line > 0) {
+ m_selected_line--;
+ if (static_cast<size_t>(m_first_visible_line) > m_selected_line)
+ m_first_visible_line = m_selected_line;
+ }
+ return eKeyHandled;
+
+ case KEY_DOWN:
+ if (m_selected_line + 1 < num_lines) {
+ m_selected_line++;
+ if (m_first_visible_line + num_visible_lines < m_selected_line)
+ m_first_visible_line++;
+ }
+ return eKeyHandled;
+
+ case '\r':
+ case '\n':
+ case KEY_ENTER:
+ // Set a breakpoint and run to the line using a one shot breakpoint
+ if (GetNumSourceLines() > 0) {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasProcessScope() && exe_ctx.GetProcessRef().IsAlive()) {
+ BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(
+ nullptr, // Don't limit the breakpoint to certain modules
+ m_file_sp->GetFileSpec(), // Source file
+ m_selected_line +
+ 1, // Source line number (m_selected_line is zero based)
+ 0, // No offset
+ eLazyBoolCalculate, // Check inlines using global setting
+ eLazyBoolCalculate, // Skip prologue using global setting,
+ false, // internal
+ false, // request_hardware
+ eLazyBoolCalculate); // move_to_nearest_code
+ // Make breakpoint one shot
+ bp_sp->GetOptions()->SetOneShot(true);
+ exe_ctx.GetProcessRef().Resume();
+ }
+ } else if (m_selected_line < GetNumDisassemblyLines()) {
+ const Instruction *inst = m_disassembly_sp->GetInstructionList()
+ .GetInstructionAtIndex(m_selected_line)
+ .get();
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasTargetScope()) {
+ Address addr = inst->GetAddress();
+ BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(
+ addr, // lldb_private::Address
+ false, // internal
+ false); // request_hardware
+ // Make breakpoint one shot
+ bp_sp->GetOptions()->SetOneShot(true);
+ exe_ctx.GetProcessRef().Resume();
+ }
+ }
+ return eKeyHandled;
+
+ case 'b': // 'b' == toggle breakpoint on currently selected line
+ if (m_selected_line < GetNumSourceLines()) {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasTargetScope()) {
+ BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(
+ nullptr, // Don't limit the breakpoint to certain modules
+ m_file_sp->GetFileSpec(), // Source file
+ m_selected_line +
+ 1, // Source line number (m_selected_line is zero based)
+ 0, // No offset
+ eLazyBoolCalculate, // Check inlines using global setting
+ eLazyBoolCalculate, // Skip prologue using global setting,
+ false, // internal
+ false, // request_hardware
+ eLazyBoolCalculate); // move_to_nearest_code
+ }
+ } else if (m_selected_line < GetNumDisassemblyLines()) {
+ const Instruction *inst = m_disassembly_sp->GetInstructionList()
+ .GetInstructionAtIndex(m_selected_line)
+ .get();
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasTargetScope()) {
+ Address addr = inst->GetAddress();
+ BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(
+ addr, // lldb_private::Address
+ false, // internal
+ false); // request_hardware
+ }
+ }
+ return eKeyHandled;
+
+ case 'd': // 'd' == detach and let run
+ case 'D': // 'D' == detach and keep stopped
+ {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasProcessScope())
+ exe_ctx.GetProcessRef().Detach(c == 'D');
}
-
- size_t
- GetNumSourceLines () const
- {
- if (m_file_sp)
- return m_file_sp->GetNumLines();
- return 0;
+ return eKeyHandled;
+
+ case 'k':
+ // 'k' == kill
+ {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasProcessScope())
+ exe_ctx.GetProcessRef().Destroy(false);
+ }
+ return eKeyHandled;
+
+ case 'c':
+ // 'c' == continue
+ {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasProcessScope())
+ exe_ctx.GetProcessRef().Resume();
+ }
+ return eKeyHandled;
+
+ case 'o':
+ // 'o' == step out
+ {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasThreadScope() &&
+ StateIsStoppedState(exe_ctx.GetProcessRef().GetState(), true)) {
+ exe_ctx.GetThreadRef().StepOut();
+ }
+ }
+ return eKeyHandled;
+
+ case 'n': // 'n' == step over
+ case 'N': // 'N' == step over instruction
+ {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasThreadScope() &&
+ StateIsStoppedState(exe_ctx.GetProcessRef().GetState(), true)) {
+ bool source_step = (c == 'n');
+ exe_ctx.GetThreadRef().StepOver(source_step);
+ }
}
-
- size_t
- GetNumDisassemblyLines () const
- {
- if (m_disassembly_sp)
- return m_disassembly_sp->GetInstructionList().GetSize();
- return 0;
+ return eKeyHandled;
+
+ case 's': // 's' == step into
+ case 'S': // 'S' == step into instruction
+ {
+ ExecutionContext exe_ctx =
+ m_debugger.GetCommandInterpreter().GetExecutionContext();
+ if (exe_ctx.HasThreadScope() &&
+ StateIsStoppedState(exe_ctx.GetProcessRef().GetState(), true)) {
+ bool source_step = (c == 's');
+ exe_ctx.GetThreadRef().StepIn(source_step);
+ }
}
+ return eKeyHandled;
- HandleCharResult
- WindowDelegateHandleChar (Window &window, int c) override
- {
- const uint32_t num_visible_lines = NumVisibleLines();
- const size_t num_lines = GetNumLines ();
-
- switch (c)
- {
- case ',':
- case KEY_PPAGE:
- // Page up key
- if (static_cast<uint32_t>(m_first_visible_line) > num_visible_lines)
- m_first_visible_line -= num_visible_lines;
- else
- m_first_visible_line = 0;
- m_selected_line = m_first_visible_line;
- return eKeyHandled;
-
- case '.':
- case KEY_NPAGE:
- // Page down key
- {
- if (m_first_visible_line + num_visible_lines < num_lines)
- m_first_visible_line += num_visible_lines;
- else if (num_lines < num_visible_lines)
- m_first_visible_line = 0;
- else
- m_first_visible_line = num_lines - num_visible_lines;
- m_selected_line = m_first_visible_line;
- }
- return eKeyHandled;
-
- case KEY_UP:
- if (m_selected_line > 0)
- {
- m_selected_line--;
- if (static_cast<size_t>(m_first_visible_line) > m_selected_line)
- m_first_visible_line = m_selected_line;
- }
- return eKeyHandled;
-
- case KEY_DOWN:
- if (m_selected_line + 1 < num_lines)
- {
- m_selected_line++;
- if (m_first_visible_line + num_visible_lines < m_selected_line)
- m_first_visible_line++;
- }
- return eKeyHandled;
-
- case '\r':
- case '\n':
- case KEY_ENTER:
- // Set a breakpoint and run to the line using a one shot breakpoint
- if (GetNumSourceLines() > 0)
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope() && exe_ctx.GetProcessRef().IsAlive())
- {
- BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(nullptr, // Don't limit the breakpoint to certain modules
- m_file_sp->GetFileSpec(), // Source file
- m_selected_line + 1, // Source line number (m_selected_line is zero based)
- 0, // No offset
- eLazyBoolCalculate, // Check inlines using global setting
- eLazyBoolCalculate, // Skip prologue using global setting,
- false, // internal
- false, // request_hardware
- eLazyBoolCalculate); // move_to_nearest_code
- // Make breakpoint one shot
- bp_sp->GetOptions()->SetOneShot(true);
- exe_ctx.GetProcessRef().Resume();
- }
- }
- else if (m_selected_line < GetNumDisassemblyLines())
- {
- const Instruction *inst = m_disassembly_sp->GetInstructionList().GetInstructionAtIndex(m_selected_line).get();
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasTargetScope())
- {
- Address addr = inst->GetAddress();
- BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint (addr, // lldb_private::Address
- false, // internal
- false); // request_hardware
- // Make breakpoint one shot
- bp_sp->GetOptions()->SetOneShot(true);
- exe_ctx.GetProcessRef().Resume();
- }
- }
- return eKeyHandled;
-
- case 'b': // 'b' == toggle breakpoint on currently selected line
- if (m_selected_line < GetNumSourceLines())
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasTargetScope())
- {
- BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint(nullptr, // Don't limit the breakpoint to certain modules
- m_file_sp->GetFileSpec(), // Source file
- m_selected_line + 1, // Source line number (m_selected_line is zero based)
- 0, // No offset
- eLazyBoolCalculate, // Check inlines using global setting
- eLazyBoolCalculate, // Skip prologue using global setting,
- false, // internal
- false, // request_hardware
- eLazyBoolCalculate); // move_to_nearest_code
- }
- }
- else if (m_selected_line < GetNumDisassemblyLines())
- {
- const Instruction *inst = m_disassembly_sp->GetInstructionList().GetInstructionAtIndex(m_selected_line).get();
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasTargetScope())
- {
- Address addr = inst->GetAddress();
- BreakpointSP bp_sp = exe_ctx.GetTargetRef().CreateBreakpoint (addr, // lldb_private::Address
- false, // internal
- false); // request_hardware
- }
- }
- return eKeyHandled;
-
- case 'd': // 'd' == detach and let run
- case 'D': // 'D' == detach and keep stopped
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope())
- exe_ctx.GetProcessRef().Detach(c == 'D');
- }
- return eKeyHandled;
-
- case 'k':
- // 'k' == kill
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope())
- exe_ctx.GetProcessRef().Destroy(false);
- }
- return eKeyHandled;
-
- case 'c':
- // 'c' == continue
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasProcessScope())
- exe_ctx.GetProcessRef().Resume();
- }
- return eKeyHandled;
-
- case 'o':
- // 'o' == step out
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasThreadScope() && StateIsStoppedState (exe_ctx.GetProcessRef().GetState(), true))
- {
- exe_ctx.GetThreadRef().StepOut();
- }
- }
- return eKeyHandled;
-
- case 'n': // 'n' == step over
- case 'N': // 'N' == step over instruction
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasThreadScope() && StateIsStoppedState (exe_ctx.GetProcessRef().GetState(), true))
- {
- bool source_step = (c == 'n');
- exe_ctx.GetThreadRef().StepOver(source_step);
- }
- }
- return eKeyHandled;
-
- case 's': // 's' == step into
- case 'S': // 'S' == step into instruction
- {
- ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext();
- if (exe_ctx.HasThreadScope() && StateIsStoppedState (exe_ctx.GetProcessRef().GetState(), true))
- {
- bool source_step = (c == 's');
- exe_ctx.GetThreadRef().StepIn(source_step);
- }
- }
- return eKeyHandled;
-
- case 'h':
- window.CreateHelpSubwindow ();
- return eKeyHandled;
+ case 'h':
+ window.CreateHelpSubwindow();
+ return eKeyHandled;
- default:
- break;
- }
- return eKeyNotHandled;
+ default:
+ break;
}
+ return eKeyNotHandled;
+ }
protected:
- typedef std::set<uint32_t> BreakpointLines;
- typedef std::set<lldb::addr_t> BreakpointAddrs;
-
- Debugger &m_debugger;
- SymbolContext m_sc;
- SourceManager::FileSP m_file_sp;
- SymbolContextScope *m_disassembly_scope;
- lldb::DisassemblerSP m_disassembly_sp;
- AddressRange m_disassembly_range;
- StreamString m_title;
- lldb::user_id_t m_tid;
- char m_line_format[8];
- int m_line_width;
- uint32_t m_selected_line; // The selected line
- uint32_t m_pc_line; // The line with the PC
- uint32_t m_stop_id;
- uint32_t m_frame_idx;
- int m_first_visible_line;
- int m_min_x;
- int m_min_y;
- int m_max_x;
- int m_max_y;
+ typedef std::set<uint32_t> BreakpointLines;
+ typedef std::set<lldb::addr_t> BreakpointAddrs;
+
+ Debugger &m_debugger;
+ SymbolContext m_sc;
+ SourceManager::FileSP m_file_sp;
+ SymbolContextScope *m_disassembly_scope;
+ lldb::DisassemblerSP m_disassembly_sp;
+ AddressRange m_disassembly_range;
+ StreamString m_title;
+ lldb::user_id_t m_tid;
+ char m_line_format[8];
+ int m_line_width;
+ uint32_t m_selected_line; // The selected line
+ uint32_t m_pc_line; // The line with the PC
+ uint32_t m_stop_id;
+ uint32_t m_frame_idx;
+ int m_first_visible_line;
+ int m_min_x;
+ int m_min_y;
+ int m_max_x;
+ int m_max_y;
};
-DisplayOptions ValueObjectListDelegate::g_options = { true };
-
-IOHandlerCursesGUI::IOHandlerCursesGUI (Debugger &debugger) :
- IOHandler (debugger, IOHandler::Type::Curses)
-{
-}
-
-void
-IOHandlerCursesGUI::Activate ()
-{
- IOHandler::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));
-
- MenuDelegateSP app_menu_delegate_sp = std::static_pointer_cast<MenuDelegate>(app_delegate_sp);
- MenuSP lldb_menu_sp(new Menu("LLDB" , "F1", KEY_F(1), ApplicationDelegate::eMenuID_LLDB));
- MenuSP exit_menuitem_sp(new Menu("Exit", nullptr, 'x', ApplicationDelegate::eMenuID_LLDBExit));
- exit_menuitem_sp->SetCannedResult(MenuActionResult::Quit);
- lldb_menu_sp->AddSubmenu (MenuSP (new Menu("About LLDB", nullptr, 'a', ApplicationDelegate::eMenuID_LLDBAbout)));
- lldb_menu_sp->AddSubmenu (MenuSP (new Menu(Menu::Type::Separator)));
- lldb_menu_sp->AddSubmenu (exit_menuitem_sp);
-
- MenuSP target_menu_sp(new Menu("Target" ,"F2", KEY_F(2), ApplicationDelegate::eMenuID_Target));
- target_menu_sp->AddSubmenu (MenuSP (new Menu("Create", nullptr, 'c', ApplicationDelegate::eMenuID_TargetCreate)));
- target_menu_sp->AddSubmenu (MenuSP (new Menu("Delete", nullptr, 'd', ApplicationDelegate::eMenuID_TargetDelete)));
-
- MenuSP process_menu_sp(new Menu("Process", "F3", KEY_F(3), ApplicationDelegate::eMenuID_Process));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Attach" , nullptr, 'a', ApplicationDelegate::eMenuID_ProcessAttach)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Detach" , nullptr, 'd', ApplicationDelegate::eMenuID_ProcessDetach)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Launch" , nullptr, 'l', ApplicationDelegate::eMenuID_ProcessLaunch)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu(Menu::Type::Separator)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Continue", nullptr, 'c', ApplicationDelegate::eMenuID_ProcessContinue)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Halt" , nullptr, 'h', ApplicationDelegate::eMenuID_ProcessHalt)));
- process_menu_sp->AddSubmenu (MenuSP (new Menu("Kill" , nullptr, 'k', ApplicationDelegate::eMenuID_ProcessKill)));
-
- MenuSP thread_menu_sp(new Menu("Thread", "F4", KEY_F(4), ApplicationDelegate::eMenuID_Thread));
- thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step In" , nullptr, 'i', ApplicationDelegate::eMenuID_ThreadStepIn)));
- thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step Over", nullptr, 'v', ApplicationDelegate::eMenuID_ThreadStepOver)));
- thread_menu_sp->AddSubmenu (MenuSP (new Menu("Step Out" , nullptr, 'o', ApplicationDelegate::eMenuID_ThreadStepOut)));
-
- MenuSP view_menu_sp(new Menu("View", "F5", KEY_F(5), ApplicationDelegate::eMenuID_View));
- view_menu_sp->AddSubmenu (MenuSP (new Menu("Backtrace", nullptr, 'b', ApplicationDelegate::eMenuID_ViewBacktrace)));
- view_menu_sp->AddSubmenu (MenuSP (new Menu("Registers", nullptr, 'r', ApplicationDelegate::eMenuID_ViewRegisters)));
- view_menu_sp->AddSubmenu (MenuSP (new Menu("Source" , nullptr, 's', ApplicationDelegate::eMenuID_ViewSource)));
- view_menu_sp->AddSubmenu (MenuSP (new Menu("Variables", nullptr, 'v', ApplicationDelegate::eMenuID_ViewVariables)));
-
- MenuSP help_menu_sp(new Menu("Help", "F6", KEY_F(6), ApplicationDelegate::eMenuID_Help));
- help_menu_sp->AddSubmenu (MenuSP (new Menu("GUI Help", nullptr, 'g', ApplicationDelegate::eMenuID_HelpGUIHelp)));
-
- m_app_ap->Initialize();
- WindowSP &main_window_sp = m_app_ap->GetMainWindow();
-
- MenuSP menubar_sp(new Menu(Menu::Type::Bar));
- menubar_sp->AddSubmenu (lldb_menu_sp);
- menubar_sp->AddSubmenu (target_menu_sp);
- menubar_sp->AddSubmenu (process_menu_sp);
- menubar_sp->AddSubmenu (thread_menu_sp);
- menubar_sp->AddSubmenu (view_menu_sp);
- menubar_sp->AddSubmenu (help_menu_sp);
- menubar_sp->SetDelegate(app_menu_delegate_sp);
-
- Rect content_bounds = main_window_sp->GetFrame();
- Rect menubar_bounds = content_bounds.MakeMenuBar();
- Rect status_bounds = content_bounds.MakeStatusBar();
- Rect source_bounds;
- Rect variables_bounds;
- Rect threads_bounds;
- Rect source_variables_bounds;
- content_bounds.VerticalSplitPercentage(0.80, source_variables_bounds, threads_bounds);
- source_variables_bounds.HorizontalSplitPercentage(0.70, source_bounds, variables_bounds);
-
- WindowSP menubar_window_sp = main_window_sp->CreateSubWindow("Menubar", menubar_bounds, false);
- // Let the menubar get keys if the active window doesn't handle the
- // keys that are typed so it can respond to menubar key presses.
- menubar_window_sp->SetCanBeActive(false); // Don't let the menubar become the active window
- menubar_window_sp->SetDelegate(menubar_sp);
-
- WindowSP source_window_sp (main_window_sp->CreateSubWindow("Source",
- source_bounds,
- true));
- WindowSP variables_window_sp (main_window_sp->CreateSubWindow("Variables",
- variables_bounds,
- false));
- WindowSP threads_window_sp (main_window_sp->CreateSubWindow("Threads",
- threads_bounds,
- false));
- WindowSP status_window_sp (main_window_sp->CreateSubWindow("Status",
- status_bounds,
- false));
- status_window_sp->SetCanBeActive(false); // Don't let the status bar become the active window
- main_window_sp->SetDelegate (std::static_pointer_cast<WindowDelegate>(app_delegate_sp));
- source_window_sp->SetDelegate (WindowDelegateSP(new SourceFileWindowDelegate(m_debugger)));
- variables_window_sp->SetDelegate (WindowDelegateSP(new FrameVariablesWindowDelegate(m_debugger)));
- TreeDelegateSP thread_delegate_sp (new ThreadsTreeDelegate(m_debugger));
- threads_window_sp->SetDelegate (WindowDelegateSP(new TreeWindowDelegate(m_debugger, thread_delegate_sp)));
- status_window_sp->SetDelegate (WindowDelegateSP(new StatusBarWindowDelegate(m_debugger)));
-
- // Show the main help window once the first time the curses GUI is launched
- static bool g_showed_help = false;
- if (!g_showed_help)
- {
- g_showed_help = true;
- main_window_sp->CreateHelpSubwindow();
- }
-
- init_pair (1, COLOR_WHITE , COLOR_BLUE );
- init_pair (2, COLOR_BLACK , COLOR_WHITE );
- init_pair (3, COLOR_MAGENTA , COLOR_WHITE );
- init_pair (4, COLOR_MAGENTA , COLOR_BLACK );
- init_pair (5, COLOR_RED , COLOR_BLACK );
+DisplayOptions ValueObjectListDelegate::g_options = {true};
+
+IOHandlerCursesGUI::IOHandlerCursesGUI(Debugger &debugger)
+ : IOHandler(debugger, IOHandler::Type::Curses) {}
+
+void IOHandlerCursesGUI::Activate() {
+ IOHandler::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));
+
+ MenuDelegateSP app_menu_delegate_sp =
+ std::static_pointer_cast<MenuDelegate>(app_delegate_sp);
+ MenuSP lldb_menu_sp(
+ new Menu("LLDB", "F1", KEY_F(1), ApplicationDelegate::eMenuID_LLDB));
+ MenuSP exit_menuitem_sp(
+ new Menu("Exit", nullptr, 'x', ApplicationDelegate::eMenuID_LLDBExit));
+ exit_menuitem_sp->SetCannedResult(MenuActionResult::Quit);
+ lldb_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "About LLDB", nullptr, 'a', ApplicationDelegate::eMenuID_LLDBAbout)));
+ lldb_menu_sp->AddSubmenu(MenuSP(new Menu(Menu::Type::Separator)));
+ lldb_menu_sp->AddSubmenu(exit_menuitem_sp);
+
+ MenuSP target_menu_sp(new Menu("Target", "F2", KEY_F(2),
+ ApplicationDelegate::eMenuID_Target));
+ target_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Create", nullptr, 'c', ApplicationDelegate::eMenuID_TargetCreate)));
+ target_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Delete", nullptr, 'd', ApplicationDelegate::eMenuID_TargetDelete)));
+
+ MenuSP process_menu_sp(new Menu("Process", "F3", KEY_F(3),
+ ApplicationDelegate::eMenuID_Process));
+ process_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Attach", nullptr, 'a', ApplicationDelegate::eMenuID_ProcessAttach)));
+ process_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Detach", nullptr, 'd', ApplicationDelegate::eMenuID_ProcessDetach)));
+ process_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Launch", nullptr, 'l', ApplicationDelegate::eMenuID_ProcessLaunch)));
+ process_menu_sp->AddSubmenu(MenuSP(new Menu(Menu::Type::Separator)));
+ process_menu_sp->AddSubmenu(
+ MenuSP(new Menu("Continue", nullptr, 'c',
+ ApplicationDelegate::eMenuID_ProcessContinue)));
+ process_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Halt", nullptr, 'h', ApplicationDelegate::eMenuID_ProcessHalt)));
+ process_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Kill", nullptr, 'k', ApplicationDelegate::eMenuID_ProcessKill)));
+
+ MenuSP thread_menu_sp(new Menu("Thread", "F4", KEY_F(4),
+ ApplicationDelegate::eMenuID_Thread));
+ thread_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Step In", nullptr, 'i', ApplicationDelegate::eMenuID_ThreadStepIn)));
+ thread_menu_sp->AddSubmenu(
+ MenuSP(new Menu("Step Over", nullptr, 'v',
+ ApplicationDelegate::eMenuID_ThreadStepOver)));
+ thread_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Step Out", nullptr, 'o', ApplicationDelegate::eMenuID_ThreadStepOut)));
+
+ MenuSP view_menu_sp(
+ new Menu("View", "F5", KEY_F(5), ApplicationDelegate::eMenuID_View));
+ view_menu_sp->AddSubmenu(
+ MenuSP(new Menu("Backtrace", nullptr, 'b',
+ ApplicationDelegate::eMenuID_ViewBacktrace)));
+ view_menu_sp->AddSubmenu(
+ MenuSP(new Menu("Registers", nullptr, 'r',
+ ApplicationDelegate::eMenuID_ViewRegisters)));
+ view_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "Source", nullptr, 's', ApplicationDelegate::eMenuID_ViewSource)));
+ view_menu_sp->AddSubmenu(
+ MenuSP(new Menu("Variables", nullptr, 'v',
+ ApplicationDelegate::eMenuID_ViewVariables)));
+
+ MenuSP help_menu_sp(
+ new Menu("Help", "F6", KEY_F(6), ApplicationDelegate::eMenuID_Help));
+ help_menu_sp->AddSubmenu(MenuSP(new Menu(
+ "GUI Help", nullptr, 'g', ApplicationDelegate::eMenuID_HelpGUIHelp)));
+
+ m_app_ap->Initialize();
+ WindowSP &main_window_sp = m_app_ap->GetMainWindow();
+
+ MenuSP menubar_sp(new Menu(Menu::Type::Bar));
+ menubar_sp->AddSubmenu(lldb_menu_sp);
+ menubar_sp->AddSubmenu(target_menu_sp);
+ menubar_sp->AddSubmenu(process_menu_sp);
+ menubar_sp->AddSubmenu(thread_menu_sp);
+ menubar_sp->AddSubmenu(view_menu_sp);
+ menubar_sp->AddSubmenu(help_menu_sp);
+ menubar_sp->SetDelegate(app_menu_delegate_sp);
+
+ Rect content_bounds = main_window_sp->GetFrame();
+ Rect menubar_bounds = content_bounds.MakeMenuBar();
+ Rect status_bounds = content_bounds.MakeStatusBar();
+ Rect source_bounds;
+ Rect variables_bounds;
+ Rect threads_bounds;
+ Rect source_variables_bounds;
+ content_bounds.VerticalSplitPercentage(0.80, source_variables_bounds,
+ threads_bounds);
+ source_variables_bounds.HorizontalSplitPercentage(0.70, source_bounds,
+ variables_bounds);
+
+ WindowSP menubar_window_sp =
+ main_window_sp->CreateSubWindow("Menubar", menubar_bounds, false);
+ // Let the menubar get keys if the active window doesn't handle the
+ // keys that are typed so it can respond to menubar key presses.
+ menubar_window_sp->SetCanBeActive(
+ false); // Don't let the menubar become the active window
+ menubar_window_sp->SetDelegate(menubar_sp);
+
+ WindowSP source_window_sp(
+ main_window_sp->CreateSubWindow("Source", source_bounds, true));
+ WindowSP variables_window_sp(
+ main_window_sp->CreateSubWindow("Variables", variables_bounds, false));
+ WindowSP threads_window_sp(
+ main_window_sp->CreateSubWindow("Threads", threads_bounds, false));
+ WindowSP status_window_sp(
+ main_window_sp->CreateSubWindow("Status", status_bounds, false));
+ status_window_sp->SetCanBeActive(
+ false); // Don't let the status bar become the active window
+ main_window_sp->SetDelegate(
+ std::static_pointer_cast<WindowDelegate>(app_delegate_sp));
+ source_window_sp->SetDelegate(
+ WindowDelegateSP(new SourceFileWindowDelegate(m_debugger)));
+ variables_window_sp->SetDelegate(
+ WindowDelegateSP(new FrameVariablesWindowDelegate(m_debugger)));
+ TreeDelegateSP thread_delegate_sp(new ThreadsTreeDelegate(m_debugger));
+ threads_window_sp->SetDelegate(WindowDelegateSP(
+ new TreeWindowDelegate(m_debugger, thread_delegate_sp)));
+ status_window_sp->SetDelegate(
+ WindowDelegateSP(new StatusBarWindowDelegate(m_debugger)));
+
+ // Show the main help window once the first time the curses GUI is launched
+ static bool g_showed_help = false;
+ if (!g_showed_help) {
+ g_showed_help = true;
+ main_window_sp->CreateHelpSubwindow();
}
-}
-void
-IOHandlerCursesGUI::Deactivate ()
-{
- m_app_ap->Terminate();
+ init_pair(1, COLOR_WHITE, COLOR_BLUE);
+ init_pair(2, COLOR_BLACK, COLOR_WHITE);
+ init_pair(3, COLOR_MAGENTA, COLOR_WHITE);
+ init_pair(4, COLOR_MAGENTA, COLOR_BLACK);
+ init_pair(5, COLOR_RED, COLOR_BLACK);
+ }
}
-void
-IOHandlerCursesGUI::Run ()
-{
- m_app_ap->Run(m_debugger);
- SetIsDone(true);
+void IOHandlerCursesGUI::Deactivate() { m_app_ap->Terminate(); }
+
+void IOHandlerCursesGUI::Run() {
+ m_app_ap->Run(m_debugger);
+ SetIsDone(true);
}
IOHandlerCursesGUI::~IOHandlerCursesGUI() = default;
-void
-IOHandlerCursesGUI::Cancel ()
-{
-}
+void IOHandlerCursesGUI::Cancel() {}
-bool
-IOHandlerCursesGUI::Interrupt ()
-{
- return false;
-}
+bool IOHandlerCursesGUI::Interrupt() { return false; }
-void
-IOHandlerCursesGUI::GotEOF()
-{
-}
+void IOHandlerCursesGUI::GotEOF() {}
#endif // LLDB_DISABLE_CURSES
diff --git a/source/Core/Listener.cpp b/source/Core/Listener.cpp
index 15a698784681..3adb677f53d1 100644
--- a/source/Core/Listener.cpp
+++ b/source/Core/Listener.cpp
@@ -16,523 +16,460 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Broadcaster.h"
+#include "lldb/Core/Event.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Core/Event.h"
-#include "lldb/Host/TimeValue.h"
using namespace lldb;
using namespace lldb_private;
-namespace
-{
- class BroadcasterManagerWPMatcher
- {
- public:
- BroadcasterManagerWPMatcher (BroadcasterManagerSP manager_sp) : m_manager_sp(manager_sp) {}
- bool operator() (const BroadcasterManagerWP input_wp) const
- {
- BroadcasterManagerSP input_sp = input_wp.lock();
- return (input_sp && input_sp == m_manager_sp);
- }
-
- BroadcasterManagerSP m_manager_sp;
- };
+namespace {
+class BroadcasterManagerWPMatcher {
+public:
+ BroadcasterManagerWPMatcher(BroadcasterManagerSP manager_sp)
+ : m_manager_sp(manager_sp) {}
+ bool operator()(const BroadcasterManagerWP input_wp) const {
+ BroadcasterManagerSP input_sp = input_wp.lock();
+ return (input_sp && input_sp == m_manager_sp);
+ }
+
+ BroadcasterManagerSP m_manager_sp;
+};
} // anonymous namespace
Listener::Listener(const char *name)
- : m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(), m_events_mutex(Mutex::eMutexTypeNormal)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- if (log != nullptr)
- log->Printf ("%p Listener::Listener('%s')",
- static_cast<void*>(this), m_name.c_str());
+ : m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(),
+ m_events_mutex() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log != nullptr)
+ log->Printf("%p Listener::Listener('%s')", static_cast<void *>(this),
+ m_name.c_str());
}
-Listener::~Listener()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+Listener::~Listener() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
- Clear();
+ Clear();
- if (log)
- log->Printf("%p Listener::%s('%s')", static_cast<void *>(this), __FUNCTION__, m_name.c_str());
+ if (log)
+ log->Printf("%p Listener::%s('%s')", static_cast<void *>(this),
+ __FUNCTION__, m_name.c_str());
}
-void
-Listener::Clear()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- broadcaster_collection::iterator pos, end = m_broadcasters.end();
- for (pos = m_broadcasters.begin(); pos != end; ++pos)
- {
- Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock());
- if (broadcaster_sp)
- broadcaster_sp->RemoveListener (this, pos->second.event_mask);
- }
- m_broadcasters.clear();
-
- Mutex::Locker event_locker(m_events_mutex);
- m_events.clear();
- size_t num_managers = m_broadcaster_managers.size();
-
- for (size_t i = 0; i < num_managers; i++)
- {
- BroadcasterManagerSP manager_sp(m_broadcaster_managers[i].lock());
- if (manager_sp)
- manager_sp->RemoveListener(this);
- }
-
- if (log)
- log->Printf("%p Listener::%s('%s')", static_cast<void *>(this), __FUNCTION__, m_name.c_str());
+void Listener::Clear() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ broadcaster_collection::iterator pos, end = m_broadcasters.end();
+ for (pos = m_broadcasters.begin(); pos != end; ++pos) {
+ Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock());
+ if (broadcaster_sp)
+ broadcaster_sp->RemoveListener(this, pos->second.event_mask);
+ }
+ m_broadcasters.clear();
+
+ std::lock_guard<std::mutex> events_guard(m_events_mutex);
+ m_events.clear();
+ size_t num_managers = m_broadcaster_managers.size();
+
+ for (size_t i = 0; i < num_managers; i++) {
+ BroadcasterManagerSP manager_sp(m_broadcaster_managers[i].lock());
+ if (manager_sp)
+ manager_sp->RemoveListener(this);
+ }
+
+ if (log)
+ log->Printf("%p Listener::%s('%s')", static_cast<void *>(this),
+ __FUNCTION__, m_name.c_str());
}
-uint32_t
-Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
-{
- if (broadcaster)
+uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
+ uint32_t event_mask) {
+ if (broadcaster) {
+ // Scope for "locker"
+ // Tell the broadcaster to add this object as a listener
{
- // Scope for "locker"
- // Tell the broadcaster to add this object as a listener
- {
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
- m_broadcasters.insert(std::make_pair(impl_wp, BroadcasterInfo(event_mask)));
- }
-
- uint32_t acquired_mask = broadcaster->AddListener (this->shared_from_this(), event_mask);
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
+ m_broadcasters.insert(
+ std::make_pair(impl_wp, BroadcasterInfo(event_mask)));
+ }
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log != nullptr)
- log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
- static_cast<void*>(this),
- static_cast<void*>(broadcaster), event_mask,
- acquired_mask, m_name.c_str());
+ uint32_t acquired_mask =
+ broadcaster->AddListener(this->shared_from_this(), event_mask);
- return acquired_mask;
- }
- return 0;
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log != nullptr)
+ log->Printf("%p Listener::StartListeningForEvents (broadcaster = %p, "
+ "mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
+ static_cast<void *>(this), static_cast<void *>(broadcaster),
+ event_mask, acquired_mask, m_name.c_str());
+
+ return acquired_mask;
+ }
+ return 0;
}
-uint32_t
-Listener::StartListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask, HandleBroadcastCallback callback, void *callback_user_data)
-{
- if (broadcaster)
+uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
+ uint32_t event_mask,
+ HandleBroadcastCallback callback,
+ void *callback_user_data) {
+ if (broadcaster) {
+ // Scope for "locker"
+ // Tell the broadcaster to add this object as a listener
{
- // Scope for "locker"
- // Tell the broadcaster to add this object as a listener
- {
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
- m_broadcasters.insert(std::make_pair(impl_wp,
- BroadcasterInfo(event_mask, callback, callback_user_data)));
- }
-
- uint32_t acquired_mask = broadcaster->AddListener (this->shared_from_this(), event_mask);
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log != nullptr)
- {
- void **pointer = reinterpret_cast<void**>(&callback);
- log->Printf ("%p Listener::StartListeningForEvents (broadcaster = %p, mask = 0x%8.8x, callback = %p, user_data = %p) acquired_mask = 0x%8.8x for %s",
- static_cast<void*>(this),
- static_cast<void*>(broadcaster), event_mask, *pointer,
- static_cast<void*>(callback_user_data), acquired_mask,
- m_name.c_str());
- }
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
+ m_broadcasters.insert(std::make_pair(
+ impl_wp, BroadcasterInfo(event_mask, callback, callback_user_data)));
+ }
- return acquired_mask;
+ uint32_t acquired_mask =
+ broadcaster->AddListener(this->shared_from_this(), event_mask);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log != nullptr) {
+ void **pointer = reinterpret_cast<void **>(&callback);
+ log->Printf("%p Listener::StartListeningForEvents (broadcaster = %p, "
+ "mask = 0x%8.8x, callback = %p, user_data = %p) "
+ "acquired_mask = 0x%8.8x for %s",
+ static_cast<void *>(this), static_cast<void *>(broadcaster),
+ event_mask, *pointer, static_cast<void *>(callback_user_data),
+ acquired_mask, m_name.c_str());
}
- return 0;
+
+ return acquired_mask;
+ }
+ return 0;
}
-bool
-Listener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
-{
- if (broadcaster)
+bool Listener::StopListeningForEvents(Broadcaster *broadcaster,
+ uint32_t event_mask) {
+ if (broadcaster) {
+ // Scope for "locker"
{
- // Scope for "locker"
- {
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- m_broadcasters.erase (broadcaster->GetBroadcasterImpl());
- }
- // Remove the broadcaster from our set of broadcasters
- return broadcaster->RemoveListener (this->shared_from_this(), event_mask);
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ m_broadcasters.erase(broadcaster->GetBroadcasterImpl());
}
+ // Remove the broadcaster from our set of broadcasters
+ return broadcaster->RemoveListener(this->shared_from_this(), event_mask);
+ }
- return false;
+ return false;
}
// Called when a Broadcaster is in its destructor. We need to remove all
// knowledge of this broadcaster and any events that it may have queued up
-void
-Listener::BroadcasterWillDestruct (Broadcaster *broadcaster)
-{
- // Scope for "broadcasters_locker"
- {
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- m_broadcasters.erase (broadcaster->GetBroadcasterImpl());
- }
-
- // Scope for "event_locker"
- {
- Mutex::Locker event_locker(m_events_mutex);
- // Remove all events for this broadcaster object.
- event_collection::iterator pos = m_events.begin();
- while (pos != m_events.end())
- {
- if ((*pos)->GetBroadcaster() == broadcaster)
- pos = m_events.erase(pos);
- else
- ++pos;
- }
+void Listener::BroadcasterWillDestruct(Broadcaster *broadcaster) {
+ // Scope for "broadcasters_locker"
+ {
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ m_broadcasters.erase(broadcaster->GetBroadcasterImpl());
+ }
+
+ // Scope for "event_locker"
+ {
+ std::lock_guard<std::mutex> events_guard(m_events_mutex);
+ // Remove all events for this broadcaster object.
+ event_collection::iterator pos = m_events.begin();
+ while (pos != m_events.end()) {
+ if ((*pos)->GetBroadcaster() == broadcaster)
+ pos = m_events.erase(pos);
+ else
+ ++pos;
}
+ }
}
-void
-Listener::BroadcasterManagerWillDestruct (BroadcasterManagerSP manager_sp)
-{
- // Just need to remove this broadcast manager from the list of managers:
- broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
- BroadcasterManagerWP manager_wp;
-
- BroadcasterManagerWPMatcher matcher(manager_sp);
- iter = std::find_if<broadcaster_manager_collection::iterator, BroadcasterManagerWPMatcher>(m_broadcaster_managers.begin(), end_iter, matcher);
- if (iter != end_iter)
- m_broadcaster_managers.erase (iter);
+void Listener::BroadcasterManagerWillDestruct(BroadcasterManagerSP manager_sp) {
+ // Just need to remove this broadcast manager from the list of managers:
+ broadcaster_manager_collection::iterator iter,
+ end_iter = m_broadcaster_managers.end();
+ BroadcasterManagerWP manager_wp;
+
+ BroadcasterManagerWPMatcher matcher(manager_sp);
+ iter = std::find_if<broadcaster_manager_collection::iterator,
+ BroadcasterManagerWPMatcher>(
+ m_broadcaster_managers.begin(), end_iter, matcher);
+ if (iter != end_iter)
+ m_broadcaster_managers.erase(iter);
}
-void
-Listener::AddEvent (EventSP &event_sp)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log != nullptr)
- log->Printf ("%p Listener('%s')::AddEvent (event_sp = {%p})",
- static_cast<void*>(this), m_name.c_str(),
- static_cast<void*>(event_sp.get()));
+void Listener::AddEvent(EventSP &event_sp) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log != nullptr)
+ log->Printf("%p Listener('%s')::AddEvent (event_sp = {%p})",
+ static_cast<void *>(this), m_name.c_str(),
+ static_cast<void *>(event_sp.get()));
- Mutex::Locker locker(m_events_mutex);
- m_events.push_back (event_sp);
- m_events_condition.Broadcast();
+ std::lock_guard<std::mutex> guard(m_events_mutex);
+ m_events.push_back(event_sp);
+ m_events_condition.notify_all();
}
-class EventBroadcasterMatches
-{
+class EventBroadcasterMatches {
public:
- EventBroadcasterMatches (Broadcaster *broadcaster) :
- m_broadcaster (broadcaster)
- {
- }
+ EventBroadcasterMatches(Broadcaster *broadcaster)
+ : m_broadcaster(broadcaster) {}
- bool operator() (const EventSP &event_sp) const
- {
- return event_sp->BroadcasterIs(m_broadcaster);
- }
+ bool operator()(const EventSP &event_sp) const {
+ return event_sp->BroadcasterIs(m_broadcaster);
+ }
private:
- Broadcaster *m_broadcaster;
+ Broadcaster *m_broadcaster;
};
-class EventMatcher
-{
+class EventMatcher {
public:
- EventMatcher (Broadcaster *broadcaster, const ConstString *broadcaster_names, uint32_t num_broadcaster_names, uint32_t event_type_mask) :
- m_broadcaster (broadcaster),
- m_broadcaster_names (broadcaster_names),
- m_num_broadcaster_names (num_broadcaster_names),
- m_event_type_mask (event_type_mask)
- {
- }
-
- bool operator() (const EventSP &event_sp) const
- {
- if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster))
- return false;
-
- if (m_broadcaster_names)
- {
- bool found_source = false;
- const ConstString &event_broadcaster_name = event_sp->GetBroadcaster()->GetBroadcasterName();
- for (uint32_t i = 0; i < m_num_broadcaster_names; ++i)
- {
- if (m_broadcaster_names[i] == event_broadcaster_name)
- {
- found_source = true;
- break;
- }
- }
- if (!found_source)
- return false;
+ EventMatcher(Broadcaster *broadcaster, const ConstString *broadcaster_names,
+ uint32_t num_broadcaster_names, uint32_t event_type_mask)
+ : m_broadcaster(broadcaster), m_broadcaster_names(broadcaster_names),
+ m_num_broadcaster_names(num_broadcaster_names),
+ m_event_type_mask(event_type_mask) {}
+
+ bool operator()(const EventSP &event_sp) const {
+ if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster))
+ return false;
+
+ if (m_broadcaster_names) {
+ bool found_source = false;
+ const ConstString &event_broadcaster_name =
+ event_sp->GetBroadcaster()->GetBroadcasterName();
+ for (uint32_t i = 0; i < m_num_broadcaster_names; ++i) {
+ if (m_broadcaster_names[i] == event_broadcaster_name) {
+ found_source = true;
+ break;
}
-
- if (m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType())
- return true;
+ }
+ if (!found_source)
return false;
}
+ if (m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType())
+ return true;
+ return false;
+ }
+
private:
- Broadcaster *m_broadcaster;
- const ConstString *m_broadcaster_names;
- const uint32_t m_num_broadcaster_names;
- const uint32_t m_event_type_mask;
+ Broadcaster *m_broadcaster;
+ const ConstString *m_broadcaster_names;
+ const uint32_t m_num_broadcaster_names;
+ const uint32_t m_event_type_mask;
};
-bool
-Listener::FindNextEventInternal
-(
- Mutex::Locker& lock,
- Broadcaster *broadcaster, // nullptr for any broadcaster
+bool Listener::FindNextEventInternal(
+ std::unique_lock<std::mutex> &lock,
+ Broadcaster *broadcaster, // nullptr for any broadcaster
const ConstString *broadcaster_names, // nullptr for any event
- uint32_t num_broadcaster_names,
- uint32_t event_type_mask,
- EventSP &event_sp,
- bool remove)
-{
- // NOTE: callers of this function must lock m_events_mutex using a Mutex::Locker
- // and pass the locker as the first argument. m_events_mutex is no longer recursive.
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
-
- if (m_events.empty())
- return false;
+ uint32_t num_broadcaster_names, uint32_t event_type_mask, EventSP &event_sp,
+ bool remove) {
+ // NOTE: callers of this function must lock m_events_mutex using a
+ // Mutex::Locker
+ // and pass the locker as the first argument. m_events_mutex is no longer
+ // recursive.
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+
+ if (m_events.empty())
+ return false;
- Listener::event_collection::iterator pos = m_events.end();
+ Listener::event_collection::iterator pos = m_events.end();
- if (broadcaster == nullptr && broadcaster_names == nullptr && event_type_mask == 0)
- {
- pos = m_events.begin();
- }
- else
- {
- pos = std::find_if (m_events.begin(), m_events.end(), EventMatcher (broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask));
- }
+ if (broadcaster == nullptr && broadcaster_names == nullptr &&
+ event_type_mask == 0) {
+ pos = m_events.begin();
+ } else {
+ pos = std::find_if(m_events.begin(), m_events.end(),
+ EventMatcher(broadcaster, broadcaster_names,
+ num_broadcaster_names, event_type_mask));
+ }
- if (pos != m_events.end())
- {
- event_sp = *pos;
-
- if (log != nullptr)
- log->Printf ("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, broadcaster_names=%p[%u], event_type_mask=0x%8.8x, remove=%i) event %p",
- static_cast<void*>(this), GetName(),
- static_cast<void*>(broadcaster),
- static_cast<const void*>(broadcaster_names),
- num_broadcaster_names, event_type_mask, remove,
- static_cast<void*>(event_sp.get()));
-
- if (remove)
- {
- m_events.erase(pos);
- // Unlock the event queue here. We've removed this event and are about to return
- // it so it should be okay to get the next event off the queue here - and it might
- // be useful to do that in the "DoOnRemoval".
- lock.Unlock();
- event_sp->DoOnRemoval();
- }
- return true;
+ if (pos != m_events.end()) {
+ event_sp = *pos;
+
+ if (log != nullptr)
+ log->Printf("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, "
+ "broadcaster_names=%p[%u], event_type_mask=0x%8.8x, "
+ "remove=%i) event %p",
+ static_cast<void *>(this), GetName(),
+ static_cast<void *>(broadcaster),
+ static_cast<const void *>(broadcaster_names),
+ num_broadcaster_names, event_type_mask, remove,
+ static_cast<void *>(event_sp.get()));
+
+ if (remove) {
+ m_events.erase(pos);
+ // Unlock the event queue here. We've removed this event and are about to
+ // return
+ // it so it should be okay to get the next event off the queue here - and
+ // it might
+ // be useful to do that in the "DoOnRemoval".
+ lock.unlock();
+ event_sp->DoOnRemoval();
}
+ return true;
+ }
- event_sp.reset();
- return false;
+ event_sp.reset();
+ return false;
}
-Event *
-Listener::PeekAtNextEvent ()
-{
- Mutex::Locker lock(m_events_mutex);
- EventSP event_sp;
- if (FindNextEventInternal(lock, nullptr, nullptr, 0, 0, event_sp, false))
- return event_sp.get();
- return nullptr;
+Event *Listener::PeekAtNextEvent() {
+ std::unique_lock<std::mutex> guard(m_events_mutex);
+ EventSP event_sp;
+ if (FindNextEventInternal(guard, nullptr, nullptr, 0, 0, event_sp, false))
+ return event_sp.get();
+ return nullptr;
}
-Event *
-Listener::PeekAtNextEventForBroadcaster (Broadcaster *broadcaster)
-{
- Mutex::Locker lock(m_events_mutex);
- EventSP event_sp;
- if (FindNextEventInternal(lock, broadcaster, nullptr, 0, 0, event_sp, false))
- return event_sp.get();
- return nullptr;
+Event *Listener::PeekAtNextEventForBroadcaster(Broadcaster *broadcaster) {
+ std::unique_lock<std::mutex> guard(m_events_mutex);
+ EventSP event_sp;
+ if (FindNextEventInternal(guard, broadcaster, nullptr, 0, 0, event_sp, false))
+ return event_sp.get();
+ return nullptr;
}
Event *
-Listener::PeekAtNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask)
-{
- Mutex::Locker lock(m_events_mutex);
- EventSP event_sp;
- if (FindNextEventInternal(lock, broadcaster, nullptr, 0, event_type_mask, event_sp, false))
- return event_sp.get();
- return nullptr;
-}
-
-bool
-Listener::GetNextEventInternal(Broadcaster *broadcaster, // nullptr for any broadcaster
- const ConstString *broadcaster_names, // nullptr for any event
- uint32_t num_broadcaster_names,
- uint32_t event_type_mask,
- EventSP &event_sp)
-{
- Mutex::Locker lock(m_events_mutex);
- return FindNextEventInternal (lock, broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true);
-}
-
-bool
-Listener::GetNextEvent (EventSP &event_sp)
-{
- return GetNextEventInternal(nullptr, nullptr, 0, 0, event_sp);
-}
-
-bool
-Listener::GetNextEventForBroadcaster (Broadcaster *broadcaster, EventSP &event_sp)
-{
- return GetNextEventInternal(broadcaster, nullptr, 0, 0, event_sp);
-}
-
-bool
-Listener::GetNextEventForBroadcasterWithType (Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp)
-{
- return GetNextEventInternal(broadcaster, nullptr, 0, event_type_mask, event_sp);
+Listener::PeekAtNextEventForBroadcasterWithType(Broadcaster *broadcaster,
+ uint32_t event_type_mask) {
+ std::unique_lock<std::mutex> guard(m_events_mutex);
+ EventSP event_sp;
+ if (FindNextEventInternal(guard, broadcaster, nullptr, 0, event_type_mask,
+ event_sp, false))
+ return event_sp.get();
+ return nullptr;
}
-bool
-Listener::WaitForEventsInternal(const TimeValue *timeout,
- Broadcaster *broadcaster, // nullptr for any broadcaster
- const ConstString *broadcaster_names, // nullptr for any event
- uint32_t num_broadcaster_names,
- uint32_t event_type_mask,
- EventSP &event_sp)
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log != nullptr)
- log->Printf ("%p Listener::WaitForEventsInternal (timeout = { %p }) for %s",
- static_cast<void*>(this), static_cast<const void*>(timeout),
- m_name.c_str());
-
- Mutex::Locker lock(m_events_mutex);
-
- while (true)
- {
- if (FindNextEventInternal (lock, broadcaster, broadcaster_names, num_broadcaster_names, event_type_mask, event_sp, true))
- {
- return true;
- }
- else
- {
- bool timed_out = false;
- if (m_events_condition.Wait(m_events_mutex, timeout, &timed_out) != 0)
- {
- if (timed_out)
- {
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
- if (log != nullptr)
- log->Printf ("%p Listener::WaitForEventsInternal() timed out for %s",
- static_cast<void*>(this), m_name.c_str());
- }
- else
- {
- log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EVENTS);
- if (log != nullptr)
- log->Printf ("%p Listener::WaitForEventsInternal() unknown error for %s",
- static_cast<void*>(this), m_name.c_str());
- }
- return false;
- }
- }
+bool Listener::GetEventInternal(
+ const Timeout<std::micro> &timeout,
+ Broadcaster *broadcaster, // nullptr for any broadcaster
+ const ConstString *broadcaster_names, // nullptr for any event
+ uint32_t num_broadcaster_names, uint32_t event_type_mask,
+ EventSP &event_sp) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log != nullptr)
+ log->Printf("%p Listener::GetEventInternal (timeout = %llu us) for %s",
+ static_cast<void *>(this), static_cast<unsigned long long>(
+ timeout ? timeout->count() : -1),
+ m_name.c_str());
+
+ std::unique_lock<std::mutex> lock(m_events_mutex);
+
+ while (true) {
+ if (FindNextEventInternal(lock, broadcaster, broadcaster_names,
+ num_broadcaster_names, event_type_mask, event_sp,
+ true)) {
+ return true;
+ } else {
+ std::cv_status result = std::cv_status::no_timeout;
+ if (!timeout)
+ m_events_condition.wait(lock);
+ else
+ result = m_events_condition.wait_for(lock, *timeout);
+
+ if (result == std::cv_status::timeout) {
+ log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
+ if (log)
+ log->Printf("%p Listener::GetEventInternal() timed out for %s",
+ static_cast<void *>(this), m_name.c_str());
+ return false;
+ } else if (result != std::cv_status::no_timeout) {
+ log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
+ if (log)
+ log->Printf("%p Listener::GetEventInternal() unknown error for %s",
+ static_cast<void *>(this), m_name.c_str());
+ return false;
+ }
}
+ }
- return false;
+ return false;
}
-bool
-Listener::WaitForEventForBroadcasterWithType(const TimeValue *timeout,
- Broadcaster *broadcaster,
- uint32_t event_type_mask,
- EventSP &event_sp)
-{
- return WaitForEventsInternal(timeout, broadcaster, nullptr, 0, event_type_mask, event_sp);
+bool Listener::GetEventForBroadcasterWithType(
+ Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp,
+ const Timeout<std::micro> &timeout) {
+ return GetEventInternal(timeout, broadcaster, nullptr, 0, event_type_mask,
+ event_sp);
}
-bool
-Listener::WaitForEventForBroadcaster(const TimeValue *timeout,
- Broadcaster *broadcaster,
- EventSP &event_sp)
-{
- return WaitForEventsInternal(timeout, broadcaster, nullptr, 0, 0, event_sp);
+bool Listener::GetEventForBroadcaster(Broadcaster *broadcaster,
+ EventSP &event_sp,
+ const Timeout<std::micro> &timeout) {
+ return GetEventInternal(timeout, broadcaster, nullptr, 0, 0, event_sp);
}
-bool
-Listener::WaitForEvent (const TimeValue *timeout, EventSP &event_sp)
-{
- return WaitForEventsInternal(timeout, nullptr, nullptr, 0, 0, event_sp);
+bool Listener::GetEvent(EventSP &event_sp, const Timeout<std::micro> &timeout) {
+ return GetEventInternal(timeout, nullptr, nullptr, 0, 0, event_sp);
}
-size_t
-Listener::HandleBroadcastEvent (EventSP &event_sp)
-{
- size_t num_handled = 0;
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- Broadcaster *broadcaster = event_sp->GetBroadcaster();
- if (!broadcaster)
- return 0;
- broadcaster_collection::iterator pos;
- broadcaster_collection::iterator end = m_broadcasters.end();
- Broadcaster::BroadcasterImplSP broadcaster_impl_sp(broadcaster->GetBroadcasterImpl());
- for (pos = m_broadcasters.find (broadcaster_impl_sp);
- pos != end && pos->first.lock() == broadcaster_impl_sp;
- ++pos)
- {
- BroadcasterInfo info = pos->second;
- if (event_sp->GetType () & info.event_mask)
- {
- if (info.callback != nullptr)
- {
- info.callback (event_sp, info.callback_user_data);
- ++num_handled;
- }
- }
+size_t Listener::HandleBroadcastEvent(EventSP &event_sp) {
+ size_t num_handled = 0;
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ Broadcaster *broadcaster = event_sp->GetBroadcaster();
+ if (!broadcaster)
+ return 0;
+ broadcaster_collection::iterator pos;
+ broadcaster_collection::iterator end = m_broadcasters.end();
+ Broadcaster::BroadcasterImplSP broadcaster_impl_sp(
+ broadcaster->GetBroadcasterImpl());
+ for (pos = m_broadcasters.find(broadcaster_impl_sp);
+ pos != end && pos->first.lock() == broadcaster_impl_sp; ++pos) {
+ BroadcasterInfo info = pos->second;
+ if (event_sp->GetType() & info.event_mask) {
+ if (info.callback != nullptr) {
+ info.callback(event_sp, info.callback_user_data);
+ ++num_handled;
+ }
}
- return num_handled;
+ }
+ return num_handled;
}
uint32_t
-Listener::StartListeningForEventSpec (BroadcasterManagerSP manager_sp,
- const BroadcastEventSpec &event_spec)
-{
- if (!manager_sp)
- return 0;
-
- // The BroadcasterManager mutex must be locked before m_broadcasters_mutex
- // to avoid violating the lock hierarchy (manager before broadcasters).
- std::lock_guard<std::recursive_mutex> manager_guard(manager_sp->m_manager_mutex);
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
-
- uint32_t bits_acquired = manager_sp->RegisterListenerForEvents(this->shared_from_this(), event_spec);
- if (bits_acquired)
- {
- broadcaster_manager_collection::iterator iter, end_iter = m_broadcaster_managers.end();
- BroadcasterManagerWP manager_wp(manager_sp);
- BroadcasterManagerWPMatcher matcher(manager_sp);
- iter = std::find_if<broadcaster_manager_collection::iterator, BroadcasterManagerWPMatcher>(m_broadcaster_managers.begin(), end_iter, matcher);
- if (iter == end_iter)
- m_broadcaster_managers.push_back(manager_wp);
- }
-
- return bits_acquired;
+Listener::StartListeningForEventSpec(BroadcasterManagerSP manager_sp,
+ const BroadcastEventSpec &event_spec) {
+ if (!manager_sp)
+ return 0;
+
+ // The BroadcasterManager mutex must be locked before m_broadcasters_mutex
+ // to avoid violating the lock hierarchy (manager before broadcasters).
+ std::lock_guard<std::recursive_mutex> manager_guard(
+ manager_sp->m_manager_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+
+ uint32_t bits_acquired = manager_sp->RegisterListenerForEvents(
+ this->shared_from_this(), event_spec);
+ if (bits_acquired) {
+ broadcaster_manager_collection::iterator iter,
+ end_iter = m_broadcaster_managers.end();
+ BroadcasterManagerWP manager_wp(manager_sp);
+ BroadcasterManagerWPMatcher matcher(manager_sp);
+ iter = std::find_if<broadcaster_manager_collection::iterator,
+ BroadcasterManagerWPMatcher>(
+ m_broadcaster_managers.begin(), end_iter, matcher);
+ if (iter == end_iter)
+ m_broadcaster_managers.push_back(manager_wp);
+ }
+
+ return bits_acquired;
}
-
-bool
-Listener::StopListeningForEventSpec (BroadcasterManagerSP manager_sp,
- const BroadcastEventSpec &event_spec)
-{
- if (!manager_sp)
- return false;
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- return manager_sp->UnregisterListenerForEvents (this->shared_from_this(), event_spec);
+bool Listener::StopListeningForEventSpec(BroadcasterManagerSP manager_sp,
+ const BroadcastEventSpec &event_spec) {
+ if (!manager_sp)
+ return false;
+
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ return manager_sp->UnregisterListenerForEvents(this->shared_from_this(),
+ event_spec);
}
-
-ListenerSP
-Listener::MakeListener(const char *name)
-{
- return ListenerSP(new Listener(name));
+
+ListenerSP Listener::MakeListener(const char *name) {
+ return ListenerSP(new Listener(name));
}
diff --git a/source/Core/Log.cpp b/source/Core/Log.cpp
index a292df3ed525..b62df3c1fe97 100644
--- a/source/Core/Log.cpp
+++ b/source/Core/Log.cpp
@@ -7,20 +7,6 @@
//
//===----------------------------------------------------------------------===//
-// C Includes
-// C++ Includes
-#include <cstdarg>
-#include <cstdio>
-#include <cstdlib>
-#include <map>
-#include <mutex>
-#include <string>
-
-// Other libraries and framework includes
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Signals.h"
-
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/PluginManager.h"
@@ -28,69 +14,53 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/ThisThread.h"
-#include "lldb/Host/TimeValue.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Utility/NameMatches.h"
+// Other libraries and framework includes
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Chrono.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
+
+// C Includes
+// C++ Includes
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <map>
+#include <mutex>
+#include <string>
+
using namespace lldb;
using namespace lldb_private;
-Log::Log () :
- m_stream_sp(),
- m_options(0),
- m_mask_bits(0)
-{
-}
+Log::Log() : m_stream_sp(), m_options(0), m_mask_bits(0) {}
-Log::Log (const StreamSP &stream_sp) :
- m_stream_sp(stream_sp),
- m_options(0),
- m_mask_bits(0)
-{
-}
+Log::Log(const StreamSP &stream_sp)
+ : m_stream_sp(stream_sp), m_options(0), m_mask_bits(0) {}
Log::~Log() = default;
-Flags &
-Log::GetOptions()
-{
- return m_options;
-}
+Flags &Log::GetOptions() { return m_options; }
-const Flags &
-Log::GetOptions() const
-{
- return m_options;
-}
+const Flags &Log::GetOptions() const { return m_options; }
-Flags &
-Log::GetMask()
-{
- return m_mask_bits;
-}
+Flags &Log::GetMask() { return m_mask_bits; }
-const Flags &
-Log::GetMask() const
-{
- return m_mask_bits;
-}
+const Flags &Log::GetMask() const { return m_mask_bits; }
-void
-Log::PutCString(const char *cstr)
-{
- Printf("%s", cstr);
-}
+void Log::PutCString(const char *cstr) { Printf("%s", cstr); }
+void Log::PutString(llvm::StringRef str) { PutCString(str.str().c_str()); }
//----------------------------------------------------------------------
// Simple variable argument logging with flags.
//----------------------------------------------------------------------
-void
-Log::Printf(const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- VAPrintf(format, args);
- va_end(args);
+void Log::Printf(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ VAPrintf(format, args);
+ va_end(args);
}
//----------------------------------------------------------------------
@@ -98,459 +68,332 @@ Log::Printf(const char *format, ...)
// a callback registered, then we call the logging callback. If we have
// a valid file handle, we also log to the file.
//----------------------------------------------------------------------
-void
-Log::VAPrintf(const char *format, va_list args)
-{
- // Make a copy of our stream shared pointer in case someone disables our
- // log while we are logging and releases the stream
- StreamSP stream_sp(m_stream_sp);
- if (stream_sp)
- {
- static uint32_t g_sequence_id = 0;
- StreamString header;
-
- // Add a sequence ID if requested
- if (m_options.Test (LLDB_LOG_OPTION_PREPEND_SEQUENCE))
- header.Printf ("%u ", ++g_sequence_id);
-
- // Timestamp if requested
- if (m_options.Test (LLDB_LOG_OPTION_PREPEND_TIMESTAMP))
- {
- TimeValue now = TimeValue::Now();
- header.Printf ("%9d.%09.9d ", now.seconds(), now.nanoseconds());
- }
-
- // Add the process and thread if requested
- if (m_options.Test (LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
- header.Printf ("[%4.4x/%4.4" PRIx64 "]: ", getpid(), Host::GetCurrentThreadID());
-
- // Add the thread name if requested
- if (m_options.Test (LLDB_LOG_OPTION_PREPEND_THREAD_NAME))
- {
- llvm::SmallString<32> thread_name;
- ThisThread::GetName(thread_name);
- if (!thread_name.empty())
- header.Printf ("%s ", thread_name.c_str());
- }
-
- header.PrintfVarArg (format, args);
- header.PutCString("\n");
-
- if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE))
- {
- std::string back_trace;
- llvm::raw_string_ostream stream(back_trace);
- llvm::sys::PrintStackTrace(stream);
- stream.flush();
- header.PutCString(back_trace.c_str());
- }
-
- if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE))
- {
- static std::recursive_mutex g_LogThreadedMutex;
- std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex);
- stream_sp->PutCString(header.GetString().c_str());
- stream_sp->Flush();
- }
- else
- {
- stream_sp->PutCString(header.GetString().c_str());
- stream_sp->Flush();
- }
+void Log::VAPrintf(const char *format, va_list args) {
+ // Make a copy of our stream shared pointer in case someone disables our
+ // log while we are logging and releases the stream
+ StreamSP stream_sp(m_stream_sp);
+ if (stream_sp) {
+ static uint32_t g_sequence_id = 0;
+ StreamString header;
+
+ // Add a sequence ID if requested
+ if (m_options.Test(LLDB_LOG_OPTION_PREPEND_SEQUENCE))
+ header.Printf("%u ", ++g_sequence_id);
+
+ // Timestamp if requested
+ if (m_options.Test(LLDB_LOG_OPTION_PREPEND_TIMESTAMP)) {
+ auto now = std::chrono::duration<double>(
+ std::chrono::system_clock::now().time_since_epoch());
+ header.Printf("%.9f ", now.count());
}
-}
-//----------------------------------------------------------------------
-// Print debug strings if and only if the global debug option is set to
-// a non-zero value.
-//----------------------------------------------------------------------
-void
-Log::Debug(const char *format, ...)
-{
- if (!GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
- return;
-
- va_list args;
- va_start(args, format);
- VAPrintf(format, args);
- va_end(args);
+ // Add the process and thread if requested
+ if (m_options.Test(LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD))
+ header.Printf("[%4.4x/%4.4" PRIx64 "]: ", getpid(),
+ Host::GetCurrentThreadID());
+
+ // Add the thread name if requested
+ if (m_options.Test(LLDB_LOG_OPTION_PREPEND_THREAD_NAME)) {
+ llvm::SmallString<32> thread_name;
+ ThisThread::GetName(thread_name);
+ if (!thread_name.empty())
+ header.Printf("%s ", thread_name.c_str());
+ }
+
+ header.PrintfVarArg(format, args);
+ header.PutCString("\n");
+
+ if (m_options.Test(LLDB_LOG_OPTION_BACKTRACE)) {
+ std::string back_trace;
+ llvm::raw_string_ostream stream(back_trace);
+ llvm::sys::PrintStackTrace(stream);
+ stream.flush();
+ header.PutCString(back_trace);
+ }
+
+ if (m_options.Test(LLDB_LOG_OPTION_THREADSAFE)) {
+ static std::recursive_mutex g_LogThreadedMutex;
+ std::lock_guard<std::recursive_mutex> guard(g_LogThreadedMutex);
+ stream_sp->PutCString(header.GetString());
+ stream_sp->Flush();
+ } else {
+ stream_sp->PutCString(header.GetString());
+ stream_sp->Flush();
+ }
+ }
}
//----------------------------------------------------------------------
// Print debug strings if and only if the global debug option is set to
// a non-zero value.
//----------------------------------------------------------------------
-void
-Log::DebugVerbose(const char *format, ...)
-{
- if (!GetOptions().AllSet(LLDB_LOG_OPTION_DEBUG | LLDB_LOG_OPTION_VERBOSE))
- return;
-
- va_list args;
- va_start(args, format);
- VAPrintf(format, args);
- va_end(args);
+void Log::Debug(const char *format, ...) {
+ if (!GetOptions().Test(LLDB_LOG_OPTION_DEBUG))
+ return;
+
+ va_list args;
+ va_start(args, format);
+ VAPrintf(format, args);
+ va_end(args);
}
//----------------------------------------------------------------------
// Log only if all of the bits are set
//----------------------------------------------------------------------
-void
-Log::LogIf(uint32_t bits, const char *format, ...)
-{
- if (!m_options.AllSet(bits))
- return;
-
- va_list args;
- va_start(args, format);
- VAPrintf(format, args);
- va_end(args);
+void Log::LogIf(uint32_t bits, const char *format, ...) {
+ if (!m_options.AllSet(bits))
+ return;
+
+ va_list args;
+ va_start(args, format);
+ VAPrintf(format, args);
+ va_end(args);
}
//----------------------------------------------------------------------
// Printing of errors that are not fatal.
//----------------------------------------------------------------------
-void
-Log::Error(const char *format, ...)
-{
- va_list args;
- va_start(args, format);
- VAError(format, args);
- va_end(args);
+void Log::Error(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ VAError(format, args);
+ va_end(args);
}
-void
-Log::VAError(const char *format, va_list args)
-{
- char *arg_msg = nullptr;
- ::vasprintf(&arg_msg, format, args);
-
- if (arg_msg == nullptr)
- return;
+void Log::VAError(const char *format, va_list args) {
+ char *arg_msg = nullptr;
+ ::vasprintf(&arg_msg, format, args);
- Printf("error: %s", arg_msg);
- free(arg_msg);
-}
+ if (arg_msg == nullptr)
+ return;
-//----------------------------------------------------------------------
-// Printing of errors that ARE fatal. Exit with ERR exit code
-// immediately.
-//----------------------------------------------------------------------
-void
-Log::FatalError(int err, const char *format, ...)
-{
- char *arg_msg = nullptr;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg != nullptr)
- {
- Printf("error: %s", arg_msg);
- ::free(arg_msg);
- }
- ::exit(err);
+ Printf("error: %s", arg_msg);
+ free(arg_msg);
}
//----------------------------------------------------------------------
// Printing of warnings that are not fatal only if verbose mode is
// enabled.
//----------------------------------------------------------------------
-void
-Log::Verbose(const char *format, ...)
-{
- if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
- return;
-
- va_list args;
- va_start(args, format);
- VAPrintf(format, args);
- va_end(args);
-}
+void Log::Verbose(const char *format, ...) {
+ if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
+ return;
-//----------------------------------------------------------------------
-// Printing of warnings that are not fatal only if verbose mode is
-// enabled.
-//----------------------------------------------------------------------
-void
-Log::WarningVerbose(const char *format, ...)
-{
- if (!m_options.Test(LLDB_LOG_OPTION_VERBOSE))
- return;
-
- char *arg_msg = nullptr;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg == nullptr)
- return;
-
- Printf("warning: %s", arg_msg);
- free(arg_msg);
+ va_list args;
+ va_start(args, format);
+ VAPrintf(format, args);
+ va_end(args);
}
//----------------------------------------------------------------------
// Printing of warnings that are not fatal.
//----------------------------------------------------------------------
-void
-Log::Warning(const char *format, ...)
-{
- char *arg_msg = nullptr;
- va_list args;
- va_start(args, format);
- ::vasprintf(&arg_msg, format, args);
- va_end(args);
-
- if (arg_msg == nullptr)
- return;
-
- Printf("warning: %s", arg_msg);
- free(arg_msg);
+void Log::Warning(const char *format, ...) {
+ char *arg_msg = nullptr;
+ va_list args;
+ va_start(args, format);
+ ::vasprintf(&arg_msg, format, args);
+ va_end(args);
+
+ if (arg_msg == nullptr)
+ return;
+
+ Printf("warning: %s", arg_msg);
+ free(arg_msg);
}
-typedef std::map <ConstString, Log::Callbacks> CallbackMap;
+typedef std::map<ConstString, Log::Callbacks> CallbackMap;
typedef CallbackMap::iterator CallbackMapIter;
-typedef std::map <ConstString, LogChannelSP> LogChannelMap;
+typedef std::map<ConstString, LogChannelSP> LogChannelMap;
typedef LogChannelMap::iterator LogChannelMapIter;
// Surround our callback map with a singleton function so we don't have any
// global initializers.
-static CallbackMap &
-GetCallbackMap ()
-{
- static CallbackMap g_callback_map;
- return g_callback_map;
-}
-
-static LogChannelMap &
-GetChannelMap ()
-{
- static LogChannelMap g_channel_map;
- return g_channel_map;
-}
-
-void
-Log::RegisterLogChannel (const ConstString &channel, const Log::Callbacks &log_callbacks)
-{
- GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
-}
-
-bool
-Log::UnregisterLogChannel (const ConstString &channel)
-{
- return GetCallbackMap().erase(channel) != 0;
-}
-
-bool
-Log::GetLogChannelCallbacks (const ConstString &channel, Log::Callbacks &log_callbacks)
-{
- CallbackMap &callback_map = GetCallbackMap ();
- CallbackMapIter pos = callback_map.find(channel);
- if (pos != callback_map.end())
- {
- log_callbacks = pos->second;
- return true;
+static CallbackMap &GetCallbackMap() {
+ static CallbackMap g_callback_map;
+ return g_callback_map;
+}
+
+static LogChannelMap &GetChannelMap() {
+ static LogChannelMap g_channel_map;
+ return g_channel_map;
+}
+
+void Log::RegisterLogChannel(const ConstString &channel,
+ const Log::Callbacks &log_callbacks) {
+ GetCallbackMap().insert(std::make_pair(channel, log_callbacks));
+}
+
+bool Log::UnregisterLogChannel(const ConstString &channel) {
+ return GetCallbackMap().erase(channel) != 0;
+}
+
+bool Log::GetLogChannelCallbacks(const ConstString &channel,
+ Log::Callbacks &log_callbacks) {
+ CallbackMap &callback_map = GetCallbackMap();
+ CallbackMapIter pos = callback_map.find(channel);
+ if (pos != callback_map.end()) {
+ log_callbacks = pos->second;
+ return true;
+ }
+ ::memset(&log_callbacks, 0, sizeof(log_callbacks));
+ return false;
+}
+
+bool Log::EnableLogChannel(lldb::StreamSP &log_stream_sp, uint32_t log_options,
+ const char *channel, const char **categories,
+ Stream &error_stream) {
+ Log::Callbacks log_callbacks;
+ if (Log::GetLogChannelCallbacks(ConstString(channel), log_callbacks)) {
+ log_callbacks.enable(log_stream_sp, log_options, categories, &error_stream);
+ return true;
+ }
+
+ LogChannelSP log_channel_sp(LogChannel::FindPlugin(channel));
+ if (log_channel_sp) {
+ if (log_channel_sp->Enable(log_stream_sp, log_options, &error_stream,
+ categories)) {
+ return true;
+ } else {
+ error_stream.Printf("Invalid log channel '%s'.\n", channel);
+ return false;
}
- ::memset (&log_callbacks, 0, sizeof(log_callbacks));
+ } else {
+ error_stream.Printf("Invalid log channel '%s'.\n", channel);
return false;
-}
-
-bool
-Log::EnableLogChannel(lldb::StreamSP &log_stream_sp,
- uint32_t log_options,
- const char *channel,
- const char **categories,
- Stream &error_stream)
-{
- Log::Callbacks log_callbacks;
- if (Log::GetLogChannelCallbacks (ConstString(channel), log_callbacks))
- {
- log_callbacks.enable (log_stream_sp, log_options, categories, &error_stream);
- return true;
- }
-
- LogChannelSP log_channel_sp (LogChannel::FindPlugin (channel));
+ }
+}
+
+void Log::EnableAllLogChannels(StreamSP &log_stream_sp, uint32_t log_options,
+ const char **categories, Stream *feedback_strm) {
+ CallbackMap &callback_map = GetCallbackMap();
+ CallbackMapIter pos, end = callback_map.end();
+
+ for (pos = callback_map.begin(); pos != end; ++pos)
+ pos->second.enable(log_stream_sp, log_options, categories, feedback_strm);
+
+ LogChannelMap &channel_map = GetChannelMap();
+ LogChannelMapIter channel_pos, channel_end = channel_map.end();
+ for (channel_pos = channel_map.begin(); channel_pos != channel_end;
+ ++channel_pos) {
+ channel_pos->second->Enable(log_stream_sp, log_options, feedback_strm,
+ categories);
+ }
+}
+
+void Log::AutoCompleteChannelName(const char *channel_name,
+ StringList &matches) {
+ LogChannelMap &map = GetChannelMap();
+ LogChannelMapIter pos, end = map.end();
+ for (pos = map.begin(); pos != end; ++pos) {
+ const char *pos_channel_name = pos->first.GetCString();
+ if (channel_name && channel_name[0]) {
+ if (NameMatches(channel_name, eNameMatchStartsWith, pos_channel_name)) {
+ matches.AppendString(pos_channel_name);
+ }
+ } else
+ matches.AppendString(pos_channel_name);
+ }
+}
+
+void Log::DisableAllLogChannels(Stream *feedback_strm) {
+ CallbackMap &callback_map = GetCallbackMap();
+ CallbackMapIter pos, end = callback_map.end();
+ const char *categories[] = {"all", nullptr};
+
+ for (pos = callback_map.begin(); pos != end; ++pos)
+ pos->second.disable(categories, feedback_strm);
+
+ LogChannelMap &channel_map = GetChannelMap();
+ LogChannelMapIter channel_pos, channel_end = channel_map.end();
+ for (channel_pos = channel_map.begin(); channel_pos != channel_end;
+ ++channel_pos)
+ channel_pos->second->Disable(categories, feedback_strm);
+}
+
+void Log::Initialize() {
+ Log::Callbacks log_callbacks = {DisableLog, EnableLog, ListLogCategories};
+ Log::RegisterLogChannel(ConstString("lldb"), log_callbacks);
+}
+
+void Log::Terminate() { DisableAllLogChannels(nullptr); }
+
+void Log::ListAllLogChannels(Stream *strm) {
+ CallbackMap &callback_map = GetCallbackMap();
+ LogChannelMap &channel_map = GetChannelMap();
+
+ if (callback_map.empty() && channel_map.empty()) {
+ strm->PutCString("No logging channels are currently registered.\n");
+ return;
+ }
+
+ CallbackMapIter pos, end = callback_map.end();
+ for (pos = callback_map.begin(); pos != end; ++pos)
+ pos->second.list_categories(strm);
+
+ uint32_t idx = 0;
+ const char *name;
+ for (idx = 0;
+ (name = PluginManager::GetLogChannelCreateNameAtIndex(idx)) != nullptr;
+ ++idx) {
+ LogChannelSP log_channel_sp(LogChannel::FindPlugin(name));
if (log_channel_sp)
- {
- if (log_channel_sp->Enable (log_stream_sp, log_options, &error_stream, categories))
- {
- return true;
- }
- else
- {
- error_stream.Printf ("Invalid log channel '%s'.\n", channel);
- return false;
- }
- }
- else
- {
- error_stream.Printf ("Invalid log channel '%s'.\n", channel);
- return false;
- }
+ log_channel_sp->ListCategories(strm);
+ }
}
-void
-Log::EnableAllLogChannels(StreamSP &log_stream_sp,
- uint32_t log_options,
- const char **categories,
- Stream *feedback_strm)
-{
- CallbackMap &callback_map = GetCallbackMap ();
- CallbackMapIter pos, end = callback_map.end();
-
- for (pos = callback_map.begin(); pos != end; ++pos)
- pos->second.enable (log_stream_sp, log_options, categories, feedback_strm);
-
- LogChannelMap &channel_map = GetChannelMap ();
- LogChannelMapIter channel_pos, channel_end = channel_map.end();
- for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
- {
- channel_pos->second->Enable (log_stream_sp, log_options, feedback_strm, categories);
- }
-}
-
-void
-Log::AutoCompleteChannelName (const char *channel_name, StringList &matches)
-{
- LogChannelMap &map = GetChannelMap ();
- LogChannelMapIter pos, end = map.end();
- for (pos = map.begin(); pos != end; ++pos)
- {
- const char *pos_channel_name = pos->first.GetCString();
- if (channel_name && channel_name[0])
- {
- if (NameMatches (channel_name, eNameMatchStartsWith, pos_channel_name))
- {
- matches.AppendString(pos_channel_name);
- }
- }
- else
- matches.AppendString(pos_channel_name);
- }
-}
-
-void
-Log::DisableAllLogChannels (Stream *feedback_strm)
-{
- CallbackMap &callback_map = GetCallbackMap ();
- CallbackMapIter pos, end = callback_map.end();
- const char *categories[] = {"all", nullptr};
-
- for (pos = callback_map.begin(); pos != end; ++pos)
- pos->second.disable (categories, feedback_strm);
-
- LogChannelMap &channel_map = GetChannelMap ();
- LogChannelMapIter channel_pos, channel_end = channel_map.end();
- for (channel_pos = channel_map.begin(); channel_pos != channel_end; ++channel_pos)
- channel_pos->second->Disable (categories, feedback_strm);
-}
-
-void
-Log::Initialize()
-{
- Log::Callbacks log_callbacks = { DisableLog, EnableLog, ListLogCategories };
- Log::RegisterLogChannel (ConstString("lldb"), log_callbacks);
-}
-
-void
-Log::Terminate ()
-{
- DisableAllLogChannels(nullptr);
-}
+bool Log::GetVerbose() const {
+ // FIXME: This has to be centralized between the stream and the log...
+ if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
+ return true;
-void
-Log::ListAllLogChannels (Stream *strm)
-{
- CallbackMap &callback_map = GetCallbackMap ();
- LogChannelMap &channel_map = GetChannelMap ();
-
- if (callback_map.empty() && channel_map.empty())
- {
- strm->PutCString ("No logging channels are currently registered.\n");
- return;
- }
-
- CallbackMapIter pos, end = callback_map.end();
- for (pos = callback_map.begin(); pos != end; ++pos)
- pos->second.list_categories (strm);
-
- uint32_t idx = 0;
- const char *name;
- for (idx = 0; (name = PluginManager::GetLogChannelCreateNameAtIndex (idx)) != nullptr; ++idx)
- {
- LogChannelSP log_channel_sp(LogChannel::FindPlugin (name));
- if (log_channel_sp)
- log_channel_sp->ListCategories (strm);
- }
-}
-
-bool
-Log::GetVerbose() const
-{
- // FIXME: This has to be centralized between the stream and the log...
- if (m_options.Test(LLDB_LOG_OPTION_VERBOSE))
- return true;
-
- // Make a copy of our stream shared pointer in case someone disables our
- // log while we are logging and releases the stream
- StreamSP stream_sp(m_stream_sp);
- if (stream_sp)
- return stream_sp->GetVerbose();
- return false;
+ // Make a copy of our stream shared pointer in case someone disables our
+ // log while we are logging and releases the stream
+ StreamSP stream_sp(m_stream_sp);
+ if (stream_sp)
+ return stream_sp->GetVerbose();
+ return false;
}
//------------------------------------------------------------------
// Returns true if the debug flag bit is set in this stream.
//------------------------------------------------------------------
-bool
-Log::GetDebug() const
-{
- // Make a copy of our stream shared pointer in case someone disables our
- // log while we are logging and releases the stream
- StreamSP stream_sp(m_stream_sp);
- if (stream_sp)
- return stream_sp->GetDebug();
- return false;
-}
-
-LogChannelSP
-LogChannel::FindPlugin (const char *plugin_name)
-{
- LogChannelSP log_channel_sp;
- LogChannelMap &channel_map = GetChannelMap ();
- ConstString log_channel_name (plugin_name);
- LogChannelMapIter pos = channel_map.find (log_channel_name);
- if (pos == channel_map.end())
- {
- ConstString const_plugin_name (plugin_name);
- LogChannelCreateInstance create_callback = PluginManager::GetLogChannelCreateCallbackForPluginName (const_plugin_name);
- if (create_callback)
- {
- log_channel_sp.reset(create_callback());
- if (log_channel_sp)
- {
- // Cache the one and only loaded instance of each log channel
- // plug-in after it has been loaded once.
- channel_map[log_channel_name] = log_channel_sp;
- }
- }
- }
- else
- {
- // We have already loaded an instance of this log channel class,
- // so just return the cached instance.
- log_channel_sp = pos->second;
+bool Log::GetDebug() const {
+ // Make a copy of our stream shared pointer in case someone disables our
+ // log while we are logging and releases the stream
+ StreamSP stream_sp(m_stream_sp);
+ if (stream_sp)
+ return stream_sp->GetDebug();
+ return false;
+}
+
+LogChannelSP LogChannel::FindPlugin(const char *plugin_name) {
+ LogChannelSP log_channel_sp;
+ LogChannelMap &channel_map = GetChannelMap();
+ ConstString log_channel_name(plugin_name);
+ LogChannelMapIter pos = channel_map.find(log_channel_name);
+ if (pos == channel_map.end()) {
+ ConstString const_plugin_name(plugin_name);
+ LogChannelCreateInstance create_callback =
+ PluginManager::GetLogChannelCreateCallbackForPluginName(
+ const_plugin_name);
+ if (create_callback) {
+ log_channel_sp.reset(create_callback());
+ if (log_channel_sp) {
+ // Cache the one and only loaded instance of each log channel
+ // plug-in after it has been loaded once.
+ channel_map[log_channel_name] = log_channel_sp;
+ }
}
- return log_channel_sp;
+ } else {
+ // We have already loaded an instance of this log channel class,
+ // so just return the cached instance.
+ log_channel_sp = pos->second;
+ }
+ return log_channel_sp;
}
-LogChannel::LogChannel () :
- m_log_ap ()
-{
-}
+LogChannel::LogChannel() : m_log_ap() {}
LogChannel::~LogChannel() = default;
diff --git a/source/Core/Logging.cpp b/source/Core/Logging.cpp
index 9eb4f6676a4d..4d63b60eeccd 100644
--- a/source/Core/Logging.cpp
+++ b/source/Core/Logging.cpp
@@ -1,4 +1,4 @@
-//===-- lldb-log.cpp --------------------------------------------*- C++ -*-===//
+//===-- Logging.cpp ---------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,14 +11,14 @@
// C Includes
// C++ Includes
-#include <cstring>
#include <atomic>
+#include <cstring>
// Other libraries and framework includes
// Project includes
-#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/Args.h"
using namespace lldb;
using namespace lldb_private;
@@ -28,254 +28,295 @@ using namespace lldb_private;
// that will construct the static g_lob_sp the first time this function is
// called.
-static std::atomic<bool> g_log_enabled {false};
-static Log * g_log = nullptr;
+static std::atomic<bool> g_log_enabled{false};
+static Log *g_log = nullptr;
-static Log *
-GetLog ()
-{
- if (!g_log_enabled)
- return nullptr;
- return g_log;
+static Log *GetLog() {
+ if (!g_log_enabled)
+ return nullptr;
+ return g_log;
}
-uint32_t
-lldb_private::GetLogMask ()
-{
- Log *log(GetLog ());
- if (log)
- return log->GetMask().Get();
- return 0;
+uint32_t lldb_private::GetLogMask() {
+ Log *log(GetLog());
+ if (log)
+ return log->GetMask().Get();
+ return 0;
}
-bool
-lldb_private::IsLogVerbose ()
-{
- uint32_t mask = GetLogMask();
- return (mask & LIBLLDB_LOG_VERBOSE);
+bool lldb_private::IsLogVerbose() {
+ uint32_t mask = GetLogMask();
+ return (mask & LIBLLDB_LOG_VERBOSE);
}
-Log *
-lldb_private::GetLogIfAllCategoriesSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log && mask)
- {
- uint32_t log_mask = log->GetMask().Get();
- if ((log_mask & mask) != mask)
- return nullptr;
- }
- return log;
+Log *lldb_private::GetLogIfAllCategoriesSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log && mask) {
+ uint32_t log_mask = log->GetMask().Get();
+ if ((log_mask & mask) != mask)
+ return nullptr;
+ }
+ return log;
}
-void
-lldb_private::LogIfAllCategoriesSet (uint32_t mask, const char *format, ...)
-{
- Log *log(GetLogIfAllCategoriesSet (mask));
- if (log)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+void lldb_private::LogIfAllCategoriesSet(uint32_t mask, const char *format,
+ ...) {
+ Log *log(GetLogIfAllCategoriesSet(mask));
+ if (log) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
+ }
}
-void
-lldb_private::LogIfAnyCategoriesSet (uint32_t mask, const char *format, ...)
-{
- Log *log(GetLogIfAnyCategoriesSet (mask));
- if (log != nullptr)
- {
- va_list args;
- va_start (args, format);
- log->VAPrintf (format, args);
- va_end (args);
- }
+void lldb_private::LogIfAnyCategoriesSet(uint32_t mask, const char *format,
+ ...) {
+ Log *log(GetLogIfAnyCategoriesSet(mask));
+ if (log != nullptr) {
+ va_list args;
+ va_start(args, format);
+ log->VAPrintf(format, args);
+ va_end(args);
+ }
}
-Log *
-lldb_private::GetLogIfAnyCategoriesSet (uint32_t mask)
-{
- Log *log(GetLog ());
- if (log != nullptr && mask && (mask & log->GetMask().Get()))
- return log;
- return nullptr;
+Log *lldb_private::GetLogIfAnyCategoriesSet(uint32_t mask) {
+ Log *log(GetLog());
+ if (log != nullptr && mask && (mask & log->GetMask().Get()))
+ return log;
+ return nullptr;
}
-void
-lldb_private::DisableLog (const char **categories, Stream *feedback_strm)
-{
- Log *log(GetLog ());
+void lldb_private::DisableLog(const char **categories, Stream *feedback_strm) {
+ Log *log(GetLog());
- if (log != nullptr)
- {
- uint32_t flag_bits = 0;
- if (categories[0] != nullptr)
- {
- flag_bits = log->GetMask().Get();
- for (size_t i = 0; categories[i] != nullptr; ++i)
- {
- const char *arg = categories[i];
+ if (log != nullptr) {
+ uint32_t flag_bits = 0;
+ if (categories && categories[0]) {
+ flag_bits = log->GetMask().Get();
+ for (size_t i = 0; categories[i] != nullptr; ++i) {
+ const char *arg = categories[i];
- if (0 == ::strcasecmp(arg, "all")) flag_bits &= ~LIBLLDB_LOG_ALL;
- else if (0 == ::strcasecmp(arg, "api")) flag_bits &= ~LIBLLDB_LOG_API;
- else if (0 == ::strncasecmp(arg, "break", 5)) flag_bits &= ~LIBLLDB_LOG_BREAKPOINTS;
- else if (0 == ::strcasecmp(arg, "commands")) flag_bits &= ~LIBLLDB_LOG_COMMANDS;
- else if (0 == ::strcasecmp(arg, "default")) flag_bits &= ~LIBLLDB_LOG_DEFAULT;
- else if (0 == ::strcasecmp(arg, "dyld")) flag_bits &= ~LIBLLDB_LOG_DYNAMIC_LOADER;
- else if (0 == ::strncasecmp(arg, "event", 5)) flag_bits &= ~LIBLLDB_LOG_EVENTS;
- else if (0 == ::strncasecmp(arg, "expr", 4)) flag_bits &= ~LIBLLDB_LOG_EXPRESSIONS;
- else if (0 == ::strncasecmp(arg, "object", 6)) flag_bits &= ~LIBLLDB_LOG_OBJECT;
- else if (0 == ::strcasecmp(arg, "process")) flag_bits &= ~LIBLLDB_LOG_PROCESS;
- else if (0 == ::strcasecmp(arg, "platform")) flag_bits &= ~LIBLLDB_LOG_PLATFORM;
- else if (0 == ::strcasecmp(arg, "script")) flag_bits &= ~LIBLLDB_LOG_SCRIPT;
- else if (0 == ::strcasecmp(arg, "state")) flag_bits &= ~LIBLLDB_LOG_STATE;
- else if (0 == ::strcasecmp(arg, "step")) flag_bits &= ~LIBLLDB_LOG_STEP;
- else if (0 == ::strcasecmp(arg, "thread")) flag_bits &= ~LIBLLDB_LOG_THREAD;
- else if (0 == ::strcasecmp(arg, "target")) flag_bits &= ~LIBLLDB_LOG_TARGET;
- else if (0 == ::strcasecmp(arg, "verbose")) flag_bits &= ~LIBLLDB_LOG_VERBOSE;
- else if (0 == ::strncasecmp(arg, "watch", 5)) flag_bits &= ~LIBLLDB_LOG_WATCHPOINTS;
- else if (0 == ::strncasecmp(arg, "temp", 4)) flag_bits &= ~LIBLLDB_LOG_TEMPORARY;
- else if (0 == ::strncasecmp(arg, "comm", 4)) flag_bits &= ~LIBLLDB_LOG_COMMUNICATION;
- else if (0 == ::strncasecmp(arg, "conn", 4)) flag_bits &= ~LIBLLDB_LOG_CONNECTION;
- else if (0 == ::strncasecmp(arg, "host", 4)) flag_bits &= ~LIBLLDB_LOG_HOST;
- else if (0 == ::strncasecmp(arg, "unwind", 6)) flag_bits &= ~LIBLLDB_LOG_UNWIND;
- else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits &= ~LIBLLDB_LOG_TYPES;
- else if (0 == ::strncasecmp(arg, "symbol", 6)) flag_bits &= ~LIBLLDB_LOG_SYMBOLS;
- else if (0 == ::strcasecmp(arg, "system-runtime")) flag_bits &= ~LIBLLDB_LOG_SYSTEM_RUNTIME;
- else if (0 == ::strncasecmp(arg, "module", 6)) flag_bits &= ~LIBLLDB_LOG_MODULES;
- else if (0 == ::strncasecmp(arg, "mmap", 4)) flag_bits &= ~LIBLLDB_LOG_MMAP;
- 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 if (0 == ::strncasecmp(arg, "demangle", 8)) flag_bits &= ~LIBLLDB_LOG_DEMANGLE;
- else
- {
- feedback_strm->Printf ("error: unrecognized log category '%s'\n", arg);
- ListLogCategories (feedback_strm);
- return;
- }
- }
- }
- log->GetMask().Reset (flag_bits);
- if (flag_bits == 0)
- {
- log->SetStream(lldb::StreamSP());
- g_log_enabled = false;
+ if (0 == ::strcasecmp(arg, "all"))
+ flag_bits &= ~LIBLLDB_LOG_ALL;
+ else if (0 == ::strcasecmp(arg, "api"))
+ flag_bits &= ~LIBLLDB_LOG_API;
+ else if (0 == ::strncasecmp(arg, "break", 5))
+ flag_bits &= ~LIBLLDB_LOG_BREAKPOINTS;
+ else if (0 == ::strcasecmp(arg, "commands"))
+ flag_bits &= ~LIBLLDB_LOG_COMMANDS;
+ else if (0 == ::strcasecmp(arg, "default"))
+ flag_bits &= ~LIBLLDB_LOG_DEFAULT;
+ else if (0 == ::strcasecmp(arg, "dyld"))
+ flag_bits &= ~LIBLLDB_LOG_DYNAMIC_LOADER;
+ else if (0 == ::strncasecmp(arg, "event", 5))
+ flag_bits &= ~LIBLLDB_LOG_EVENTS;
+ else if (0 == ::strncasecmp(arg, "expr", 4))
+ flag_bits &= ~LIBLLDB_LOG_EXPRESSIONS;
+ else if (0 == ::strncasecmp(arg, "object", 6))
+ flag_bits &= ~LIBLLDB_LOG_OBJECT;
+ else if (0 == ::strcasecmp(arg, "process"))
+ flag_bits &= ~LIBLLDB_LOG_PROCESS;
+ else if (0 == ::strcasecmp(arg, "platform"))
+ flag_bits &= ~LIBLLDB_LOG_PLATFORM;
+ else if (0 == ::strcasecmp(arg, "script"))
+ flag_bits &= ~LIBLLDB_LOG_SCRIPT;
+ else if (0 == ::strcasecmp(arg, "state"))
+ flag_bits &= ~LIBLLDB_LOG_STATE;
+ else if (0 == ::strcasecmp(arg, "step"))
+ flag_bits &= ~LIBLLDB_LOG_STEP;
+ else if (0 == ::strcasecmp(arg, "thread"))
+ flag_bits &= ~LIBLLDB_LOG_THREAD;
+ else if (0 == ::strcasecmp(arg, "target"))
+ flag_bits &= ~LIBLLDB_LOG_TARGET;
+ else if (0 == ::strcasecmp(arg, "verbose"))
+ flag_bits &= ~LIBLLDB_LOG_VERBOSE;
+ else if (0 == ::strncasecmp(arg, "watch", 5))
+ flag_bits &= ~LIBLLDB_LOG_WATCHPOINTS;
+ else if (0 == ::strncasecmp(arg, "temp", 4))
+ flag_bits &= ~LIBLLDB_LOG_TEMPORARY;
+ else if (0 == ::strncasecmp(arg, "comm", 4))
+ flag_bits &= ~LIBLLDB_LOG_COMMUNICATION;
+ else if (0 == ::strncasecmp(arg, "conn", 4))
+ flag_bits &= ~LIBLLDB_LOG_CONNECTION;
+ else if (0 == ::strncasecmp(arg, "host", 4))
+ flag_bits &= ~LIBLLDB_LOG_HOST;
+ else if (0 == ::strncasecmp(arg, "unwind", 6))
+ flag_bits &= ~LIBLLDB_LOG_UNWIND;
+ else if (0 == ::strncasecmp(arg, "types", 5))
+ flag_bits &= ~LIBLLDB_LOG_TYPES;
+ else if (0 == ::strncasecmp(arg, "symbol", 6))
+ flag_bits &= ~LIBLLDB_LOG_SYMBOLS;
+ else if (0 == ::strcasecmp(arg, "system-runtime"))
+ flag_bits &= ~LIBLLDB_LOG_SYSTEM_RUNTIME;
+ else if (0 == ::strncasecmp(arg, "module", 6))
+ flag_bits &= ~LIBLLDB_LOG_MODULES;
+ else if (0 == ::strncasecmp(arg, "mmap", 4))
+ flag_bits &= ~LIBLLDB_LOG_MMAP;
+ 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 if (0 == ::strncasecmp(arg, "demangle", 8))
+ flag_bits &= ~LIBLLDB_LOG_DEMANGLE;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n",
+ arg);
+ ListLogCategories(feedback_strm);
+ return;
}
+ }
+ }
+ log->GetMask().Reset(flag_bits);
+ if (flag_bits == 0) {
+ log->SetStream(lldb::StreamSP());
+ g_log_enabled = false;
}
+ }
}
-Log *
-lldb_private::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
-{
- // Try see if there already is a log - that way we can reuse its settings.
- // We could reuse the log in toto, but we don't know that the stream is the same.
- uint32_t flag_bits;
- if (g_log != nullptr)
- flag_bits = g_log->GetMask().Get();
- else
- flag_bits = 0;
-
- // Now make a new log with this stream if one was provided
- if (log_stream_sp)
- {
- if (g_log != nullptr)
- g_log->SetStream(log_stream_sp);
- else
- g_log = new Log(log_stream_sp);
- }
+Log *lldb_private::EnableLog(StreamSP &log_stream_sp, uint32_t log_options,
+ const char **categories, Stream *feedback_strm) {
+ // Try see if there already is a log - that way we can reuse its settings.
+ // We could reuse the log in toto, but we don't know that the stream is the
+ // same.
+ uint32_t flag_bits;
+ if (g_log != nullptr)
+ flag_bits = g_log->GetMask().Get();
+ else
+ flag_bits = 0;
+ // Now make a new log with this stream if one was provided
+ if (log_stream_sp) {
if (g_log != nullptr)
- {
- for (size_t i = 0; categories[i] != nullptr; ++i)
- {
- const char *arg = categories[i];
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
+ }
- if (0 == ::strcasecmp(arg, "all")) flag_bits |= LIBLLDB_LOG_ALL;
- else if (0 == ::strcasecmp(arg, "api")) flag_bits |= LIBLLDB_LOG_API;
- else if (0 == ::strncasecmp(arg, "break", 5)) flag_bits |= LIBLLDB_LOG_BREAKPOINTS;
- else if (0 == ::strcasecmp(arg, "commands")) flag_bits |= LIBLLDB_LOG_COMMANDS;
- else if (0 == ::strncasecmp(arg, "commu", 5)) flag_bits |= LIBLLDB_LOG_COMMUNICATION;
- else if (0 == ::strncasecmp(arg, "conn", 4)) flag_bits |= LIBLLDB_LOG_CONNECTION;
- else if (0 == ::strcasecmp(arg, "default")) flag_bits |= LIBLLDB_LOG_DEFAULT;
- else if (0 == ::strcasecmp(arg, "dyld")) flag_bits |= LIBLLDB_LOG_DYNAMIC_LOADER;
- else if (0 == ::strncasecmp(arg, "event", 5)) flag_bits |= LIBLLDB_LOG_EVENTS;
- else if (0 == ::strncasecmp(arg, "expr", 4)) flag_bits |= LIBLLDB_LOG_EXPRESSIONS;
- else if (0 == ::strncasecmp(arg, "host", 4)) flag_bits |= LIBLLDB_LOG_HOST;
- else if (0 == ::strncasecmp(arg, "mmap", 4)) flag_bits |= LIBLLDB_LOG_MMAP;
- else if (0 == ::strncasecmp(arg, "module", 6)) flag_bits |= LIBLLDB_LOG_MODULES;
- else if (0 == ::strncasecmp(arg, "object", 6)) flag_bits |= LIBLLDB_LOG_OBJECT;
- else if (0 == ::strcasecmp(arg, "os")) flag_bits |= LIBLLDB_LOG_OS;
- else if (0 == ::strcasecmp(arg, "platform")) flag_bits |= LIBLLDB_LOG_PLATFORM;
- else if (0 == ::strcasecmp(arg, "process")) flag_bits |= LIBLLDB_LOG_PROCESS;
- else if (0 == ::strcasecmp(arg, "script")) flag_bits |= LIBLLDB_LOG_SCRIPT;
- else if (0 == ::strcasecmp(arg, "state")) flag_bits |= LIBLLDB_LOG_STATE;
- else if (0 == ::strcasecmp(arg, "step")) flag_bits |= LIBLLDB_LOG_STEP;
- else if (0 == ::strncasecmp(arg, "symbol", 6)) flag_bits |= LIBLLDB_LOG_SYMBOLS;
- else if (0 == ::strcasecmp(arg, "system-runtime")) flag_bits |= LIBLLDB_LOG_SYSTEM_RUNTIME;
- else if (0 == ::strcasecmp(arg, "target")) flag_bits |= LIBLLDB_LOG_TARGET;
- else if (0 == ::strncasecmp(arg, "temp", 4)) flag_bits |= LIBLLDB_LOG_TEMPORARY;
- else if (0 == ::strcasecmp(arg, "thread")) flag_bits |= LIBLLDB_LOG_THREAD;
- else if (0 == ::strncasecmp(arg, "types", 5)) flag_bits |= LIBLLDB_LOG_TYPES;
- else if (0 == ::strncasecmp(arg, "unwind", 6)) flag_bits |= LIBLLDB_LOG_UNWIND;
- else if (0 == ::strcasecmp(arg, "verbose")) flag_bits |= LIBLLDB_LOG_VERBOSE;
- 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 if (0 == ::strncasecmp(arg, "demangle", 8)) flag_bits |= LIBLLDB_LOG_DEMANGLE;
- else
- {
- feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
- ListLogCategories (feedback_strm);
- return g_log;
- }
- }
+ if (g_log != nullptr) {
+ for (size_t i = 0; categories[i] != nullptr; ++i) {
+ const char *arg = categories[i];
- g_log->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
+ if (0 == ::strcasecmp(arg, "all"))
+ flag_bits |= LIBLLDB_LOG_ALL;
+ else if (0 == ::strcasecmp(arg, "api"))
+ flag_bits |= LIBLLDB_LOG_API;
+ else if (0 == ::strncasecmp(arg, "break", 5))
+ flag_bits |= LIBLLDB_LOG_BREAKPOINTS;
+ else if (0 == ::strcasecmp(arg, "commands"))
+ flag_bits |= LIBLLDB_LOG_COMMANDS;
+ else if (0 == ::strncasecmp(arg, "commu", 5))
+ flag_bits |= LIBLLDB_LOG_COMMUNICATION;
+ else if (0 == ::strncasecmp(arg, "conn", 4))
+ flag_bits |= LIBLLDB_LOG_CONNECTION;
+ else if (0 == ::strcasecmp(arg, "default"))
+ flag_bits |= LIBLLDB_LOG_DEFAULT;
+ else if (0 == ::strcasecmp(arg, "dyld"))
+ flag_bits |= LIBLLDB_LOG_DYNAMIC_LOADER;
+ else if (0 == ::strncasecmp(arg, "event", 5))
+ flag_bits |= LIBLLDB_LOG_EVENTS;
+ else if (0 == ::strncasecmp(arg, "expr", 4))
+ flag_bits |= LIBLLDB_LOG_EXPRESSIONS;
+ else if (0 == ::strncasecmp(arg, "host", 4))
+ flag_bits |= LIBLLDB_LOG_HOST;
+ else if (0 == ::strncasecmp(arg, "mmap", 4))
+ flag_bits |= LIBLLDB_LOG_MMAP;
+ else if (0 == ::strncasecmp(arg, "module", 6))
+ flag_bits |= LIBLLDB_LOG_MODULES;
+ else if (0 == ::strncasecmp(arg, "object", 6))
+ flag_bits |= LIBLLDB_LOG_OBJECT;
+ else if (0 == ::strcasecmp(arg, "os"))
+ flag_bits |= LIBLLDB_LOG_OS;
+ else if (0 == ::strcasecmp(arg, "platform"))
+ flag_bits |= LIBLLDB_LOG_PLATFORM;
+ else if (0 == ::strcasecmp(arg, "process"))
+ flag_bits |= LIBLLDB_LOG_PROCESS;
+ else if (0 == ::strcasecmp(arg, "script"))
+ flag_bits |= LIBLLDB_LOG_SCRIPT;
+ else if (0 == ::strcasecmp(arg, "state"))
+ flag_bits |= LIBLLDB_LOG_STATE;
+ else if (0 == ::strcasecmp(arg, "step"))
+ flag_bits |= LIBLLDB_LOG_STEP;
+ else if (0 == ::strncasecmp(arg, "symbol", 6))
+ flag_bits |= LIBLLDB_LOG_SYMBOLS;
+ else if (0 == ::strcasecmp(arg, "system-runtime"))
+ flag_bits |= LIBLLDB_LOG_SYSTEM_RUNTIME;
+ else if (0 == ::strcasecmp(arg, "target"))
+ flag_bits |= LIBLLDB_LOG_TARGET;
+ else if (0 == ::strncasecmp(arg, "temp", 4))
+ flag_bits |= LIBLLDB_LOG_TEMPORARY;
+ else if (0 == ::strcasecmp(arg, "thread"))
+ flag_bits |= LIBLLDB_LOG_THREAD;
+ else if (0 == ::strncasecmp(arg, "types", 5))
+ flag_bits |= LIBLLDB_LOG_TYPES;
+ else if (0 == ::strncasecmp(arg, "unwind", 6))
+ flag_bits |= LIBLLDB_LOG_UNWIND;
+ else if (0 == ::strcasecmp(arg, "verbose"))
+ flag_bits |= LIBLLDB_LOG_VERBOSE;
+ 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 if (0 == ::strncasecmp(arg, "demangle", 8))
+ flag_bits |= LIBLLDB_LOG_DEMANGLE;
+ else {
+ feedback_strm->Printf("error: unrecognized log category '%s'\n", arg);
+ ListLogCategories(feedback_strm);
+ return g_log;
+ }
}
- g_log_enabled = true;
- return g_log;
+
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ }
+ g_log_enabled = true;
+ return g_log;
}
-void
-lldb_private::ListLogCategories (Stream *strm)
-{
- strm->Printf("Logging categories for 'lldb':\n"
- " all - turn on all available logging categories\n"
- " api - enable logging of API calls and return values\n"
- " break - log breakpoints\n"
- " commands - log command argument parsing\n"
- " communication - log communication activities\n"
- " connection - log connection details\n"
- " default - enable the default set of logging categories for liblldb\n"
- " demangle - log mangled names to catch demangler crashes\n"
- " 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"
- " mmap - log mmap related activities\n"
- " module - log module activities such as when modules are created, destroyed, replaced, and more\n"
- " object - log object construction/destruction for important objects\n"
- " os - log OperatingSystem plugin related activities\n"
- " platform - log platform events and activities\n"
- " process - log process events and activities\n"
- " script - log events about the script interpreter\n"
- " state - log private and public process state changes\n"
- " step - log step related activities\n"
- " symbol - log symbol related issues and warnings\n"
- " system-runtime - log system runtime events\n"
- " target - log target events and activities\n"
- " thread - log thread events and activities\n"
- " types - log type system related activities\n"
- " unwind - log stack unwind activities\n"
- " verbose - enable verbose logging\n"
- " watch - log watchpoint related activities\n");
+void lldb_private::ListLogCategories(Stream *strm) {
+ strm->Printf(
+ "Logging categories for 'lldb':\n"
+ " all - turn on all available logging categories\n"
+ " api - enable logging of API calls and return values\n"
+ " break - log breakpoints\n"
+ " commands - log command argument parsing\n"
+ " communication - log communication activities\n"
+ " connection - log connection details\n"
+ " default - enable the default set of logging categories for liblldb\n"
+ " demangle - log mangled names to catch demangler crashes\n"
+ " 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"
+ " mmap - log mmap related activities\n"
+ " module - log module activities such as when modules are created, "
+ "destroyed, replaced, and more\n"
+ " object - log object construction/destruction for important objects\n"
+ " os - log OperatingSystem plugin related activities\n"
+ " platform - log platform events and activities\n"
+ " process - log process events and activities\n"
+ " script - log events about the script interpreter\n"
+ " state - log private and public process state changes\n"
+ " step - log step related activities\n"
+ " symbol - log symbol related issues and warnings\n"
+ " system-runtime - log system runtime events\n"
+ " target - log target events and activities\n"
+ " thread - log thread events and activities\n"
+ " types - log type system related activities\n"
+ " unwind - log stack unwind activities\n"
+ " verbose - enable verbose logging\n"
+ " watch - log watchpoint related activities\n");
}
diff --git a/source/Core/Mangled.cpp b/source/Core/Mangled.cpp
index 543b34e337a2..c2c63b665639 100644
--- a/source/Core/Mangled.cpp
+++ b/source/Core/Mangled.cpp
@@ -7,32 +7,27 @@
//
//===----------------------------------------------------------------------===//
-
// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
#include <cstddef>
-#if defined(_MSC_VER)
+#if defined(_WIN32)
#include "lldb/Host/windows/windows.h"
-#include <Dbghelp.h>
+#include <dbghelp.h>
#pragma comment(lib, "dbghelp.lib")
-#define LLDB_USE_BUILTIN_DEMANGLER
-#elif defined (__FreeBSD__)
-#define LLDB_USE_BUILTIN_DEMANGLER
-#else
-#include <cxxabi.h>
#endif
#ifdef LLDB_USE_BUILTIN_DEMANGLER
-
// Provide a fast-path demangler implemented in FastDemangle.cpp until it can
// replace the existing C++ demangler with a complete implementation
+#include "llvm/Demangle/Demangle.h"
#include "lldb/Core/FastDemangle.h"
-#include "lldb/Core/CxaDemangle.h"
-
+#else
+#include <cxxabi.h>
#endif
-
#include "llvm/ADT/DenseMap.h"
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "lldb/Core/ConstString.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Logging.h"
@@ -40,119 +35,114 @@
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/Timer.h"
-#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include <ctype.h>
-#include <string.h>
#include <stdlib.h>
-
+#include <string.h>
using namespace lldb_private;
-static inline Mangled::ManglingScheme
-cstring_mangling_scheme(const char *s)
-{
- if (s)
- {
- if (s[0] == '?')
- return Mangled::eManglingSchemeMSVC;
- if (s[0] == '_' && s[1] == 'Z')
- return Mangled::eManglingSchemeItanium;
- }
- return Mangled::eManglingSchemeNone;
+static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) {
+ if (s) {
+ if (s[0] == '?')
+ return Mangled::eManglingSchemeMSVC;
+ if (s[0] == '_' && s[1] == 'Z')
+ return Mangled::eManglingSchemeItanium;
+ }
+ return Mangled::eManglingSchemeNone;
}
-static inline bool
-cstring_is_mangled(const char *s)
-{
- return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
+static inline bool cstring_is_mangled(const char *s) {
+ return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
}
static const ConstString &
-get_demangled_name_without_arguments (ConstString mangled, ConstString demangled)
-{
- // This pair is <mangled name, demangled name without function arguments>
- static std::pair<ConstString, ConstString> g_most_recent_mangled_to_name_sans_args;
-
- // Need to have the mangled & demangled names we're currently examining as statics
- // so we can return a const ref to them at the end of the func if we don't have
- // anything better.
- static ConstString g_last_mangled;
- static ConstString g_last_demangled;
-
- if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled)
+get_demangled_name_without_arguments(ConstString mangled,
+ ConstString demangled) {
+ // This pair is <mangled name, demangled name without function arguments>
+ static std::pair<ConstString, ConstString>
+ g_most_recent_mangled_to_name_sans_args;
+
+ // Need to have the mangled & demangled names we're currently examining as
+ // statics
+ // so we can return a const ref to them at the end of the func if we don't
+ // have
+ // anything better.
+ static ConstString g_last_mangled;
+ static ConstString g_last_demangled;
+
+ if (mangled && g_most_recent_mangled_to_name_sans_args.first == mangled) {
+ return g_most_recent_mangled_to_name_sans_args.second;
+ }
+
+ g_last_demangled = demangled;
+ g_last_mangled = mangled;
+
+ const char *mangled_name_cstr = mangled.GetCString();
+
+ if (demangled && mangled_name_cstr && mangled_name_cstr[0]) {
+ if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
+ (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure,
+ // typeinfo structure, and typeinfo
+ // mangled_name
+ 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)
{
+ CPlusPlusLanguage::MethodName cxx_method(demangled);
+ if (!cxx_method.GetBasename().empty()) {
+ 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;
+ g_most_recent_mangled_to_name_sans_args.second = result;
return g_most_recent_mangled_to_name_sans_args.second;
+ }
}
+ }
- g_last_demangled = demangled;
- g_last_mangled = mangled;
-
- const char *mangled_name_cstr = mangled.GetCString();
-
- if (demangled && mangled_name_cstr && mangled_name_cstr[0])
- {
- if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' &&
- (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, typeinfo structure, and typeinfo mangled_name
- 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)
- {
- CPlusPlusLanguage::MethodName cxx_method (demangled);
- if (!cxx_method.GetBasename().empty())
- {
- 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;
- g_most_recent_mangled_to_name_sans_args.second = result;
- return g_most_recent_mangled_to_name_sans_args.second;
- }
- }
- }
-
- if (demangled)
- return g_last_demangled;
- return g_last_mangled;
+ if (demangled)
+ return g_last_demangled;
+ return g_last_mangled;
}
#pragma mark Mangled
//----------------------------------------------------------------------
// Default constructor
//----------------------------------------------------------------------
-Mangled::Mangled () :
- m_mangled(),
- m_demangled()
-{
-}
+Mangled::Mangled() : m_mangled(), m_demangled() {}
//----------------------------------------------------------------------
// Constructor with an optional string and a boolean indicating if it is
// the mangled version.
//----------------------------------------------------------------------
-Mangled::Mangled (const ConstString &s, bool mangled) :
- m_mangled(),
- m_demangled()
-{
- if (s)
- SetValue(s, mangled);
+Mangled::Mangled(const ConstString &s, bool mangled)
+ : m_mangled(), m_demangled() {
+ if (s)
+ SetValue(s, mangled);
+}
+
+Mangled::Mangled(llvm::StringRef name, bool is_mangled) {
+ if (!name.empty())
+ SetValue(ConstString(name), is_mangled);
}
-Mangled::Mangled (const ConstString &s) :
- m_mangled(),
- m_demangled()
-{
- if (s)
- SetValue(s);
+Mangled::Mangled(const ConstString &s) : m_mangled(), m_demangled() {
+ if (s)
+ SetValue(s);
+}
+
+Mangled::Mangled(llvm::StringRef name) {
+ if (!name.empty())
+ SetValue(ConstString(name));
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-Mangled::~Mangled ()
-{
-}
+Mangled::~Mangled() {}
//----------------------------------------------------------------------
// Convert to pointer operator. This allows code to check any Mangled
@@ -162,9 +152,8 @@ Mangled::~Mangled ()
// if (mangled)
// { ...
//----------------------------------------------------------------------
-Mangled::operator void* () const
-{
- return (m_mangled) ? const_cast<Mangled*>(this) : NULL;
+Mangled::operator void *() const {
+ return (m_mangled) ? const_cast<Mangled *>(this) : NULL;
}
//----------------------------------------------------------------------
@@ -175,83 +164,58 @@ Mangled::operator void* () const
// if (!file_spec)
// { ...
//----------------------------------------------------------------------
-bool
-Mangled::operator! () const
-{
- return !m_mangled;
-}
+bool Mangled::operator!() const { return !m_mangled; }
//----------------------------------------------------------------------
// Clear the mangled and demangled values.
//----------------------------------------------------------------------
-void
-Mangled::Clear ()
-{
- m_mangled.Clear();
- m_demangled.Clear();
+void Mangled::Clear() {
+ m_mangled.Clear();
+ m_demangled.Clear();
}
-
//----------------------------------------------------------------------
// Compare the string values.
//----------------------------------------------------------------------
-int
-Mangled::Compare (const Mangled& a, const Mangled& b)
-{
- return ConstString::Compare(a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
+int Mangled::Compare(const Mangled &a, const Mangled &b) {
+ return ConstString::Compare(
+ a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled),
+ a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled));
}
-
-
//----------------------------------------------------------------------
// Set the string value in this objects. If "mangled" is true, then
// the mangled named is set with the new value in "s", else the
// demangled name is set.
//----------------------------------------------------------------------
-void
-Mangled::SetValue (const ConstString &s, bool mangled)
-{
- if (s)
- {
- if (mangled)
- {
- m_demangled.Clear();
- m_mangled = s;
- }
- else
- {
- m_demangled = s;
- m_mangled.Clear();
- }
- }
- else
- {
- m_demangled.Clear();
- m_mangled.Clear();
+void Mangled::SetValue(const ConstString &s, bool mangled) {
+ if (s) {
+ if (mangled) {
+ m_demangled.Clear();
+ m_mangled = s;
+ } else {
+ m_demangled = s;
+ m_mangled.Clear();
}
+ } else {
+ m_demangled.Clear();
+ m_mangled.Clear();
+ }
}
-void
-Mangled::SetValue (const ConstString &name)
-{
- if (name)
- {
- if (cstring_is_mangled(name.GetCString()))
- {
- m_demangled.Clear();
- m_mangled = name;
- }
- else
- {
- m_demangled = name;
- m_mangled.Clear();
- }
- }
- else
- {
- m_demangled.Clear();
- m_mangled.Clear();
+void Mangled::SetValue(const ConstString &name) {
+ if (name) {
+ if (cstring_is_mangled(name.GetCString())) {
+ m_demangled.Clear();
+ m_mangled = name;
+ } else {
+ m_demangled = name;
+ m_mangled.Clear();
}
+ } else {
+ m_demangled.Clear();
+ m_mangled.Clear();
+ }
}
//----------------------------------------------------------------------
@@ -261,180 +225,166 @@ Mangled::SetValue (const ConstString &name)
// new string value is supplied to this object, or until the end of the
// object's lifetime.
//----------------------------------------------------------------------
-const ConstString&
-Mangled::GetDemangledName (lldb::LanguageType language) const
-{
- // Check to make sure we have a valid mangled name and that we
- // haven't already decoded our mangled name.
- if (m_mangled && !m_demangled)
- {
- // We need to generate and cache the demangled name.
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "Mangled::GetDemangledName (m_mangled = %s)",
- m_mangled.GetCString());
-
- Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_DEMANGLE);
-
- // Don't bother running anything that isn't mangled
- const char *mangled_name = m_mangled.GetCString();
- ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
- if (mangling_scheme != eManglingSchemeNone &&
- !m_mangled.GetMangledCounterpart(m_demangled))
- {
- // We didn't already mangle this name, demangle it and if all goes well
- // add it to our map.
- char *demangled_name = nullptr;
- switch (mangling_scheme)
- {
- case eManglingSchemeMSVC:
- {
+const ConstString &
+Mangled::GetDemangledName(lldb::LanguageType language) const {
+ // Check to make sure we have a valid mangled name and that we
+ // haven't already decoded our mangled name.
+ if (m_mangled && !m_demangled) {
+ // We need to generate and cache the demangled name.
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "Mangled::GetDemangledName (m_mangled = %s)",
+ m_mangled.GetCString());
+
+ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE);
+
+ // Don't bother running anything that isn't mangled
+ const char *mangled_name = m_mangled.GetCString();
+ ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
+ if (mangling_scheme != eManglingSchemeNone &&
+ !m_mangled.GetMangledCounterpart(m_demangled)) {
+ // We didn't already mangle this name, demangle it and if all goes well
+ // add it to our map.
+ char *demangled_name = nullptr;
+ switch (mangling_scheme) {
+ case eManglingSchemeMSVC: {
#if defined(_MSC_VER)
- if (log)
- log->Printf("demangle msvc: %s", mangled_name);
- const size_t demangled_length = 2048;
- demangled_name = static_cast<char *>(::malloc(demangled_length));
- ::ZeroMemory(demangled_name, demangled_length);
- DWORD result = ::UnDecorateSymbolName(mangled_name, demangled_name, demangled_length,
- UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected keywords
- UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc keywords
- UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
- UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
- UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
- );
- if (log)
- {
- if (demangled_name && demangled_name[0])
- log->Printf("demangled msvc: %s -> \"%s\"", mangled_name, demangled_name);
- else
- log->Printf("demangled msvc: %s -> error: 0x%" PRIx64, mangled_name, result);
- }
-
- if (result == 0)
- {
- free(demangled_name);
- demangled_name = nullptr;
- }
+ if (log)
+ log->Printf("demangle msvc: %s", mangled_name);
+ const size_t demangled_length = 2048;
+ demangled_name = static_cast<char *>(::malloc(demangled_length));
+ ::ZeroMemory(demangled_name, demangled_length);
+ DWORD result = ::UnDecorateSymbolName(
+ mangled_name, demangled_name, demangled_length,
+ UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected
+ // keywords
+ UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall,
+ // etc keywords
+ UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
+ UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc
+ // specifiers
+ UNDNAME_NO_MS_KEYWORDS // Strip all MS extension keywords
+ );
+ if (log) {
+ if (demangled_name && demangled_name[0])
+ log->Printf("demangled msvc: %s -> \"%s\"", mangled_name,
+ demangled_name);
+ else
+ log->Printf("demangled msvc: %s -> error: 0x%lu", mangled_name,
+ result);
+ }
+
+ if (result == 0) {
+ free(demangled_name);
+ demangled_name = nullptr;
+ }
#endif
- break;
- }
- case eManglingSchemeItanium:
- {
+ break;
+ }
+ case eManglingSchemeItanium: {
#ifdef LLDB_USE_BUILTIN_DEMANGLER
- if (log)
- log->Printf("demangle itanium: %s", mangled_name);
- // Try to use the fast-path demangler first for the
- // performance win, falling back to the full demangler only
- // when necessary
- demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
- if (!demangled_name)
- demangled_name = __cxa_demangle(mangled_name, NULL, NULL, NULL);
+ if (log)
+ log->Printf("demangle itanium: %s", mangled_name);
+ // Try to use the fast-path demangler first for the
+ // performance win, falling back to the full demangler only
+ // when necessary
+ demangled_name = FastDemangle(mangled_name, m_mangled.GetLength());
+ if (!demangled_name)
+ demangled_name =
+ llvm::itaniumDemangle(mangled_name, NULL, NULL, NULL);
#else
- demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
+ demangled_name = abi::__cxa_demangle(mangled_name, NULL, NULL, NULL);
#endif
- if (log)
- {
- if (demangled_name)
- log->Printf("demangled itanium: %s -> \"%s\"", mangled_name, demangled_name);
- else
- log->Printf("demangled itanium: %s -> error: failed to demangle", mangled_name);
- }
- break;
- }
- case eManglingSchemeNone:
- break;
- }
- if (demangled_name)
- {
- m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
- free(demangled_name);
- }
- }
- if (!m_demangled)
- {
- // Set the demangled string to the empty string to indicate we
- // tried to parse it once and failed.
- m_demangled.SetCString("");
+ if (log) {
+ if (demangled_name)
+ log->Printf("demangled itanium: %s -> \"%s\"", mangled_name,
+ demangled_name);
+ else
+ log->Printf("demangled itanium: %s -> error: failed to demangle",
+ mangled_name);
}
+ break;
+ }
+ case eManglingSchemeNone:
+ break;
+ }
+ if (demangled_name) {
+ m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled);
+ free(demangled_name);
+ }
}
+ if (!m_demangled) {
+ // Set the demangled string to the empty string to indicate we
+ // tried to parse it once and failed.
+ m_demangled.SetCString("");
+ }
+ }
- return m_demangled;
+ return m_demangled;
}
-
ConstString
-Mangled::GetDisplayDemangledName (lldb::LanguageType language) const
-{
- return GetDemangledName(language);
+Mangled::GetDisplayDemangledName(lldb::LanguageType language) const {
+ return GetDemangledName(language);
}
-bool
-Mangled::NameMatches (const RegularExpression& regex, lldb::LanguageType language) const
-{
- if (m_mangled && regex.Execute (m_mangled.AsCString()))
- return true;
+bool Mangled::NameMatches(const RegularExpression &regex,
+ lldb::LanguageType language) const {
+ if (m_mangled && regex.Execute(m_mangled.AsCString()))
+ return true;
- ConstString demangled = GetDemangledName(language);
- if (demangled && regex.Execute (demangled.AsCString()))
- return true;
- return false;
+ ConstString demangled = GetDemangledName(language);
+ if (demangled && regex.Execute(demangled.AsCString()))
+ return true;
+ return false;
}
//----------------------------------------------------------------------
// Get the demangled name if there is one, else return the mangled name.
//----------------------------------------------------------------------
-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)
- {
- return get_demangled_name_without_arguments (m_mangled, demangled);
- }
- if (preference == ePreferDemangled)
- {
- // Call the accessor to make sure we get a demangled name in case
- // it hasn't been demangled yet...
- if (demangled)
- return demangled;
- return m_mangled;
- }
- return demangled;
+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) {
+ return get_demangled_name_without_arguments(m_mangled, demangled);
+ }
+ if (preference == ePreferDemangled) {
+ // Call the accessor to make sure we get a demangled name in case
+ // it hasn't been demangled yet...
+ if (demangled)
+ return demangled;
+ return m_mangled;
+ }
+ return demangled;
}
//----------------------------------------------------------------------
// Dump a Mangled object to stream "s". We don't force our
// demangled name to be computed currently (we don't use the accessor).
//----------------------------------------------------------------------
-void
-Mangled::Dump (Stream *s) const
-{
- if (m_mangled)
- {
- *s << ", mangled = " << m_mangled;
- }
- if (m_demangled)
- {
- const char * demangled = m_demangled.AsCString();
- s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
- }
+void Mangled::Dump(Stream *s) const {
+ if (m_mangled) {
+ *s << ", mangled = " << m_mangled;
+ }
+ if (m_demangled) {
+ const char *demangled = m_demangled.AsCString();
+ s->Printf(", demangled = %s", demangled[0] ? demangled : "<error>");
+ }
}
//----------------------------------------------------------------------
// Dumps a debug version of this string with extra object and state
// information to stream "s".
//----------------------------------------------------------------------
-void
-Mangled::DumpDebug (Stream *s) const
-{
- s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void*) * 2),
- static_cast<const void*>(this));
- m_mangled.DumpDebug(s);
- s->Printf(", demangled = ");
- m_demangled.DumpDebug(s);
+void Mangled::DumpDebug(Stream *s) const {
+ s->Printf("%*p: Mangled mangled = ", static_cast<int>(sizeof(void *) * 2),
+ static_cast<const void *>(this));
+ m_mangled.DumpDebug(s);
+ s->Printf(", demangled = ");
+ m_demangled.DumpDebug(s);
}
//----------------------------------------------------------------------
@@ -442,10 +392,8 @@ Mangled::DumpDebug (Stream *s) const
// includes the size of the objects it owns, and not the strings that
// it references because they are shared strings.
//----------------------------------------------------------------------
-size_t
-Mangled::MemorySize () const
-{
- return m_mangled.MemorySize() + m_demangled.MemorySize();
+size_t Mangled::MemorySize() const {
+ return m_mangled.MemorySize() + m_demangled.MemorySize();
}
//----------------------------------------------------------------------
@@ -456,37 +404,32 @@ Mangled::MemorySize () const
// different ways of mangling names from a given language, likewise the
// compilation units within those targets.
//----------------------------------------------------------------------
-lldb::LanguageType
-Mangled::GuessLanguage () const
-{
- ConstString mangled = GetMangledName();
- if (mangled)
- {
- if (GetDemangledName(lldb::eLanguageTypeUnknown))
- {
- 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;
- }
+lldb::LanguageType Mangled::GuessLanguage() const {
+ ConstString mangled = GetMangledName();
+ if (mangled) {
+ if (GetDemangledName(lldb::eLanguageTypeUnknown)) {
+ 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;
}
//----------------------------------------------------------------------
// Dump OBJ to the supplied stream S.
//----------------------------------------------------------------------
-Stream&
-operator << (Stream& s, const Mangled& obj)
-{
- if (obj.GetMangledName())
- s << "mangled = '" << obj.GetMangledName() << "'";
-
- const ConstString& demangled = obj.GetDemangledName(lldb::eLanguageTypeUnknown);
- if (demangled)
- s << ", demangled = '" << demangled << '\'';
- else
- s << ", demangled = <error>";
- return s;
+Stream &operator<<(Stream &s, const Mangled &obj) {
+ if (obj.GetMangledName())
+ s << "mangled = '" << obj.GetMangledName() << "'";
+
+ const ConstString &demangled =
+ obj.GetDemangledName(lldb::eLanguageTypeUnknown);
+ if (demangled)
+ s << ", demangled = '" << demangled << '\'';
+ else
+ s << ", demangled = <error>";
+ return s;
}
diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp
index 5fe39abda183..220773b5ad40 100644
--- a/source/Core/Module.cpp
+++ b/source/Core/Module.cpp
@@ -12,14 +12,16 @@
// C Includes
// C++ Includes
// Other libraries and framework includes
-#include "llvm/Support/raw_os_ostream.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_os_ostream.h"
// Project includes
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+#include "Plugins/Language/ObjC/ObjCLanguage.h"
#include "lldb/Core/AddressResolverFileLine.h"
-#include "lldb/Core/Error.h"
#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
@@ -28,6 +30,7 @@
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -37,14 +40,12 @@
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolFile.h"
#include "lldb/Symbol/SymbolVendor.h"
+#include "lldb/Symbol/TypeMap.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 "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
-#include "Plugins/Language/ObjC/ObjCLanguage.h"
-#include "lldb/Symbol/TypeMap.h"
#include "Plugins/ObjectFile/JIT/ObjectFileJIT.h"
@@ -56,51 +57,49 @@ using namespace lldb_private;
// will track all module objects that are still alive
typedef std::vector<Module *> ModuleCollection;
-static ModuleCollection &
-GetModuleCollection()
-{
- // This module collection needs to live past any module, so we could either make it a
- // shared pointer in each module or just leak is. Since it is only an empty vector by
- // the time all the modules have gone away, we just leak it for now. If we decide this
- // is a big problem we can introduce a Finalize method that will tear everything down in
- // a predictable order.
-
- static ModuleCollection *g_module_collection = nullptr;
- if (g_module_collection == nullptr)
- g_module_collection = new ModuleCollection();
-
- return *g_module_collection;
-}
-
-std::recursive_mutex &
-Module::GetAllocationModuleCollectionMutex()
-{
- // NOTE: The mutex below must be leaked since the global module list in
- // the ModuleList class will get torn at some point, and we can't know
- // if it will tear itself down before the "g_module_collection_mutex" below
- // will. So we leak a Mutex object below to safeguard against that
-
- static std::recursive_mutex *g_module_collection_mutex = nullptr;
- if (g_module_collection_mutex == nullptr)
- g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak
- return *g_module_collection_mutex;
-}
-
-size_t
-Module::GetNumberAllocatedModules ()
-{
- std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
- return GetModuleCollection().size();
-}
-
-Module *
-Module::GetAllocatedModuleAtIndex (size_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
- ModuleCollection &modules = GetModuleCollection();
- if (idx < modules.size())
- return modules[idx];
- return nullptr;
+static ModuleCollection &GetModuleCollection() {
+ // This module collection needs to live past any module, so we could either
+ // make it a
+ // shared pointer in each module or just leak is. Since it is only an empty
+ // vector by
+ // the time all the modules have gone away, we just leak it for now. If we
+ // decide this
+ // is a big problem we can introduce a Finalize method that will tear
+ // everything down in
+ // a predictable order.
+
+ static ModuleCollection *g_module_collection = nullptr;
+ if (g_module_collection == nullptr)
+ g_module_collection = new ModuleCollection();
+
+ return *g_module_collection;
+}
+
+std::recursive_mutex &Module::GetAllocationModuleCollectionMutex() {
+ // NOTE: The mutex below must be leaked since the global module list in
+ // the ModuleList class will get torn at some point, and we can't know
+ // if it will tear itself down before the "g_module_collection_mutex" below
+ // will. So we leak a Mutex object below to safeguard against that
+
+ static std::recursive_mutex *g_module_collection_mutex = nullptr;
+ if (g_module_collection_mutex == nullptr)
+ g_module_collection_mutex = new std::recursive_mutex; // NOTE: known leak
+ return *g_module_collection_mutex;
+}
+
+size_t Module::GetNumberAllocatedModules() {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetAllocationModuleCollectionMutex());
+ return GetModuleCollection().size();
+}
+
+Module *Module::GetAllocatedModuleAtIndex(size_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetAllocationModuleCollectionMutex());
+ ModuleCollection &modules = GetModuleCollection();
+ if (idx < modules.size())
+ return modules[idx];
+ return nullptr;
}
#if 0
@@ -121,7 +120,7 @@ namespace lldb {
Mutex::Locker locker (Module::GetAllocationModuleCollectionMutex());
ModuleCollection &modules = GetModuleCollection();
const size_t count = modules.size();
- printf ("%s: %" PRIu64 " modules:\n", __PRETTY_FUNCTION__, (uint64_t)count);
+ printf ("%s: %" PRIu64 " modules:\n", LLVM_PRETTY_FUNCTION, (uint64_t)count);
for (size_t i = 0; i < count; ++i)
{
@@ -141,1779 +140,1531 @@ namespace lldb {
#endif
Module::Module(const ModuleSpec &module_spec)
- : m_mutex(),
- m_mod_time(),
- m_arch(),
- m_uuid(),
- m_file(),
- m_platform_file(),
- m_remote_install_file(),
- m_symfile_spec(),
- m_object_name(),
- m_object_offset(),
- m_object_mod_time(),
- m_objfile_sp(),
- m_symfile_ap(),
- 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_file_has_changed(false),
- m_first_file_changed_log(false)
-{
- // Scope for locker below...
- {
- std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
- GetModuleCollection().push_back(this);
- }
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES));
- if (log != nullptr)
- log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this),
- module_spec.GetArchitecture().GetArchitectureName(), module_spec.GetFileSpec().GetPath().c_str(),
- module_spec.GetObjectName().IsEmpty() ? "" : "(",
- module_spec.GetObjectName().IsEmpty() ? "" : module_spec.GetObjectName().AsCString(""),
- module_spec.GetObjectName().IsEmpty() ? "" : ")");
-
- // First extract all module specifications from the file using the local
- // file path. If there are no specifications, then don't fill anything in
- ModuleSpecList modules_specs;
- if (ObjectFile::GetModuleSpecifications(module_spec.GetFileSpec(), 0, 0, modules_specs) == 0)
- return;
-
- // Now make sure that one of the module specifications matches what we just
- // extract. We might have a module specification that specifies a file "/usr/lib/dyld"
- // with UUID XXX, but we might have a local version of "/usr/lib/dyld" that has
- // UUID YYY and we don't want those to match. If they don't match, just don't
- // fill any ivars in so we don't accidentally grab the wrong file later since
- // they don't match...
- ModuleSpec matching_module_spec;
- if (modules_specs.FindMatchingModuleSpec(module_spec, matching_module_spec) == 0)
- return;
-
- if (module_spec.GetFileSpec())
- m_mod_time = module_spec.GetFileSpec().GetModificationTime();
- else if (matching_module_spec.GetFileSpec())
- m_mod_time = matching_module_spec.GetFileSpec().GetModificationTime();
-
- // Copy the architecture from the actual spec if we got one back, else use the one that was specified
- if (matching_module_spec.GetArchitecture().IsValid())
- m_arch = matching_module_spec.GetArchitecture();
- else if (module_spec.GetArchitecture().IsValid())
- m_arch = module_spec.GetArchitecture();
-
- // Copy the file spec over and use the specified one (if there was one) so we
- // don't use a path that might have gotten resolved a path in 'matching_module_spec'
- if (module_spec.GetFileSpec())
- m_file = module_spec.GetFileSpec();
- else if (matching_module_spec.GetFileSpec())
- m_file = matching_module_spec.GetFileSpec();
-
- // Copy the platform file spec over
- if (module_spec.GetPlatformFileSpec())
- m_platform_file = module_spec.GetPlatformFileSpec();
- else if (matching_module_spec.GetPlatformFileSpec())
- m_platform_file = matching_module_spec.GetPlatformFileSpec();
-
- // Copy the symbol file spec over
- if (module_spec.GetSymbolFileSpec())
- m_symfile_spec = module_spec.GetSymbolFileSpec();
- else if (matching_module_spec.GetSymbolFileSpec())
- m_symfile_spec = matching_module_spec.GetSymbolFileSpec();
-
- // Copy the object name over
- if (matching_module_spec.GetObjectName())
- m_object_name = matching_module_spec.GetObjectName();
- else
- m_object_name = module_spec.GetObjectName();
-
- // Always trust the object offset (file offset) and object modification
- // time (for mod time in a BSD static archive) of from the matching
- // module specification
- m_object_offset = matching_module_spec.GetObjectOffset();
- m_object_mod_time = matching_module_spec.GetObjectModificationTime();
-}
-
-Module::Module(const FileSpec &file_spec, const ArchSpec &arch, const ConstString *object_name,
- lldb::offset_t object_offset, const TimeValue *object_mod_time_ptr)
- : m_mutex(),
- m_mod_time(file_spec.GetModificationTime()),
- m_arch(arch),
- m_uuid(),
- m_file(file_spec),
- m_platform_file(),
- m_remote_install_file(),
- m_symfile_spec(),
- m_object_name(),
- m_object_offset(object_offset),
- m_object_mod_time(),
- m_objfile_sp(),
- m_symfile_ap(),
- 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_file_has_changed(false),
- m_first_file_changed_log(false)
-{
- // Scope for locker below...
- {
- std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
- GetModuleCollection().push_back(this);
- }
-
- if (object_name)
- m_object_name = *object_name;
+ : m_object_offset(0), m_file_has_changed(false),
+ m_first_file_changed_log(false) {
+ // Scope for locker below...
+ {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetAllocationModuleCollectionMutex());
+ GetModuleCollection().push_back(this);
+ }
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
+ LIBLLDB_LOG_MODULES));
+ if (log != nullptr)
+ log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this),
+ module_spec.GetArchitecture().GetArchitectureName(),
+ module_spec.GetFileSpec().GetPath().c_str(),
+ module_spec.GetObjectName().IsEmpty() ? "" : "(",
+ module_spec.GetObjectName().IsEmpty()
+ ? ""
+ : module_spec.GetObjectName().AsCString(""),
+ module_spec.GetObjectName().IsEmpty() ? "" : ")");
+
+ // First extract all module specifications from the file using the local
+ // file path. If there are no specifications, then don't fill anything in
+ ModuleSpecList modules_specs;
+ if (ObjectFile::GetModuleSpecifications(module_spec.GetFileSpec(), 0, 0,
+ modules_specs) == 0)
+ return;
+
+ // Now make sure that one of the module specifications matches what we just
+ // extract. We might have a module specification that specifies a file
+ // "/usr/lib/dyld"
+ // with UUID XXX, but we might have a local version of "/usr/lib/dyld" that
+ // has
+ // UUID YYY and we don't want those to match. If they don't match, just don't
+ // fill any ivars in so we don't accidentally grab the wrong file later since
+ // they don't match...
+ ModuleSpec matching_module_spec;
+ if (modules_specs.FindMatchingModuleSpec(module_spec, matching_module_spec) ==
+ 0)
+ return;
+
+ if (module_spec.GetFileSpec())
+ m_mod_time = FileSystem::GetModificationTime(module_spec.GetFileSpec());
+ else if (matching_module_spec.GetFileSpec())
+ m_mod_time =
+ FileSystem::GetModificationTime(matching_module_spec.GetFileSpec());
+
+ // Copy the architecture from the actual spec if we got one back, else use the
+ // one that was specified
+ if (matching_module_spec.GetArchitecture().IsValid())
+ m_arch = matching_module_spec.GetArchitecture();
+ else if (module_spec.GetArchitecture().IsValid())
+ m_arch = module_spec.GetArchitecture();
+
+ // Copy the file spec over and use the specified one (if there was one) so we
+ // don't use a path that might have gotten resolved a path in
+ // 'matching_module_spec'
+ if (module_spec.GetFileSpec())
+ m_file = module_spec.GetFileSpec();
+ else if (matching_module_spec.GetFileSpec())
+ m_file = matching_module_spec.GetFileSpec();
+
+ // Copy the platform file spec over
+ if (module_spec.GetPlatformFileSpec())
+ m_platform_file = module_spec.GetPlatformFileSpec();
+ else if (matching_module_spec.GetPlatformFileSpec())
+ m_platform_file = matching_module_spec.GetPlatformFileSpec();
+
+ // Copy the symbol file spec over
+ if (module_spec.GetSymbolFileSpec())
+ m_symfile_spec = module_spec.GetSymbolFileSpec();
+ else if (matching_module_spec.GetSymbolFileSpec())
+ m_symfile_spec = matching_module_spec.GetSymbolFileSpec();
+
+ // Copy the object name over
+ if (matching_module_spec.GetObjectName())
+ m_object_name = matching_module_spec.GetObjectName();
+ else
+ m_object_name = module_spec.GetObjectName();
+
+ // Always trust the object offset (file offset) and object modification
+ // time (for mod time in a BSD static archive) of from the matching
+ // module specification
+ m_object_offset = matching_module_spec.GetObjectOffset();
+ m_object_mod_time = matching_module_spec.GetObjectModificationTime();
+}
+
+Module::Module(const FileSpec &file_spec, const ArchSpec &arch,
+ const ConstString *object_name, lldb::offset_t object_offset,
+ const llvm::sys::TimePoint<> &object_mod_time)
+ : m_mod_time(FileSystem::GetModificationTime(file_spec)), m_arch(arch),
+ m_file(file_spec), m_object_offset(object_offset),
+ m_object_mod_time(object_mod_time), m_file_has_changed(false),
+ m_first_file_changed_log(false) {
+ // Scope for locker below...
+ {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetAllocationModuleCollectionMutex());
+ GetModuleCollection().push_back(this);
+ }
- if (object_mod_time_ptr)
- m_object_mod_time = *object_mod_time_ptr;
+ if (object_name)
+ m_object_name = *object_name;
- Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES));
- if (log != nullptr)
- log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this), m_arch.GetArchitectureName(),
- m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
- m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")");
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
+ LIBLLDB_LOG_MODULES));
+ if (log != nullptr)
+ log->Printf("%p Module::Module((%s) '%s%s%s%s')", static_cast<void *>(this),
+ m_arch.GetArchitectureName(), m_file.GetPath().c_str(),
+ m_object_name.IsEmpty() ? "" : "(",
+ m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
+ m_object_name.IsEmpty() ? "" : ")");
}
Module::Module()
- : m_mutex(),
- m_mod_time(),
- m_arch(),
- m_uuid(),
- m_file(),
- m_platform_file(),
- m_remote_install_file(),
- m_symfile_spec(),
- m_object_name(),
- m_object_offset(0),
- m_object_mod_time(),
- m_objfile_sp(),
- m_symfile_ap(),
- 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_file_has_changed(false),
- m_first_file_changed_log(false)
-{
- std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
- GetModuleCollection().push_back(this);
-}
-
-Module::~Module()
-{
- // Lock our module down while we tear everything down to make sure
- // we don't get any access to the module while it is being destroyed
+ : m_object_offset(0), m_file_has_changed(false),
+ m_first_file_changed_log(false) {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetAllocationModuleCollectionMutex());
+ GetModuleCollection().push_back(this);
+}
+
+Module::~Module() {
+ // Lock our module down while we tear everything down to make sure
+ // we don't get any access to the module while it is being destroyed
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ // Scope for locker below...
+ {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetAllocationModuleCollectionMutex());
+ ModuleCollection &modules = GetModuleCollection();
+ ModuleCollection::iterator end = modules.end();
+ ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
+ assert(pos != end);
+ modules.erase(pos);
+ }
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT |
+ LIBLLDB_LOG_MODULES));
+ if (log != nullptr)
+ log->Printf("%p Module::~Module((%s) '%s%s%s%s')",
+ static_cast<void *>(this), m_arch.GetArchitectureName(),
+ m_file.GetPath().c_str(), m_object_name.IsEmpty() ? "" : "(",
+ m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
+ m_object_name.IsEmpty() ? "" : ")");
+ // Release any auto pointers before we start tearing down our member
+ // variables since the object file and symbol files might need to make
+ // function calls back into this module object. The ordering is important
+ // here because symbol files can require the module object file. So we tear
+ // down the symbol file first, then the object file.
+ m_sections_ap.reset();
+ m_symfile_ap.reset();
+ m_objfile_sp.reset();
+}
+
+ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp,
+ lldb::addr_t header_addr, Error &error,
+ size_t size_to_read) {
+ if (m_objfile_sp) {
+ error.SetErrorString("object file already exists");
+ } else {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- // Scope for locker below...
- {
- std::lock_guard<std::recursive_mutex> guard(GetAllocationModuleCollectionMutex());
- ModuleCollection &modules = GetModuleCollection();
- ModuleCollection::iterator end = modules.end();
- ModuleCollection::iterator pos = std::find(modules.begin(), end, this);
- assert (pos != end);
- modules.erase(pos);
- }
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT|LIBLLDB_LOG_MODULES));
- if (log != nullptr)
- log->Printf ("%p Module::~Module((%s) '%s%s%s%s')",
- static_cast<void*>(this),
- m_arch.GetArchitectureName(),
- m_file.GetPath().c_str(),
- m_object_name.IsEmpty() ? "" : "(",
- m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""),
- m_object_name.IsEmpty() ? "" : ")");
- // Release any auto pointers before we start tearing down our member
- // variables since the object file and symbol files might need to make
- // function calls back into this module object. The ordering is important
- // here because symbol files can require the module object file. So we tear
- // down the symbol file first, then the object file.
- m_sections_ap.reset();
- m_symfile_ap.reset();
- m_objfile_sp.reset();
-}
-
-ObjectFile *
-Module::GetMemoryObjectFile (const lldb::ProcessSP &process_sp, lldb::addr_t header_addr, Error &error, size_t size_to_read)
-{
- if (m_objfile_sp)
- {
- error.SetErrorString ("object file already exists");
- }
- else
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (process_sp)
- {
- m_did_load_objfile = true;
- std::unique_ptr<DataBufferHeap> data_ap (new DataBufferHeap (size_to_read, 0));
- Error readmem_error;
- const size_t bytes_read = process_sp->ReadMemory (header_addr,
- data_ap->GetBytes(),
- data_ap->GetByteSize(),
- readmem_error);
- if (bytes_read == size_to_read)
- {
- DataBufferSP data_sp(data_ap.release());
- m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp, header_addr, data_sp);
- if (m_objfile_sp)
- {
- StreamString s;
- s.Printf("0x%16.16" PRIx64, header_addr);
- m_object_name.SetCString (s.GetData());
-
- // 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.
- m_objfile_sp->GetArchitecture (m_arch);
- }
- else
- {
- error.SetErrorString ("unable to find suitable object file plug-in");
- }
- }
- else
- {
- error.SetErrorStringWithFormat ("unable to read header from memory: %s", readmem_error.AsCString());
- }
- }
- else
- {
- error.SetErrorString ("invalid process");
+ if (process_sp) {
+ m_did_load_objfile = true;
+ std::unique_ptr<DataBufferHeap> data_ap(
+ new DataBufferHeap(size_to_read, 0));
+ Error readmem_error;
+ const size_t bytes_read =
+ process_sp->ReadMemory(header_addr, data_ap->GetBytes(),
+ data_ap->GetByteSize(), readmem_error);
+ if (bytes_read == size_to_read) {
+ DataBufferSP data_sp(data_ap.release());
+ m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp,
+ header_addr, data_sp);
+ if (m_objfile_sp) {
+ StreamString s;
+ s.Printf("0x%16.16" PRIx64, header_addr);
+ m_object_name.SetString(s.GetString());
+
+ // 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.
+ m_objfile_sp->GetArchitecture(m_arch);
+ } else {
+ error.SetErrorString("unable to find suitable object file plug-in");
}
+ } else {
+ error.SetErrorStringWithFormat("unable to read header from memory: %s",
+ readmem_error.AsCString());
+ }
+ } else {
+ error.SetErrorString("invalid process");
}
- return m_objfile_sp.get();
+ }
+ return m_objfile_sp.get();
}
-const lldb_private::UUID&
-Module::GetUUID()
-{
- if (!m_did_parse_uuid.load())
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (!m_did_parse_uuid.load())
- {
- ObjectFile * obj_file = GetObjectFile ();
+const lldb_private::UUID &Module::GetUUID() {
+ if (!m_did_parse_uuid.load()) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_did_parse_uuid.load()) {
+ ObjectFile *obj_file = GetObjectFile();
- if (obj_file != nullptr)
- {
- obj_file->GetUUID(&m_uuid);
- m_did_parse_uuid = true;
- }
- }
+ if (obj_file != nullptr) {
+ obj_file->GetUUID(&m_uuid);
+ m_did_parse_uuid = true;
+ }
}
- return m_uuid;
+ }
+ return m_uuid;
}
-TypeSystem *
-Module::GetTypeSystemForLanguage (LanguageType language)
-{
- return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
+TypeSystem *Module::GetTypeSystemForLanguage(LanguageType language) {
+ return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
}
-void
-Module::ParseAllDebugSymbols()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- size_t num_comp_units = GetNumCompileUnits();
- if (num_comp_units == 0)
- return;
+void Module::ParseAllDebugSymbols() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ size_t num_comp_units = GetNumCompileUnits();
+ if (num_comp_units == 0)
+ return;
- SymbolContext sc;
- sc.module_sp = shared_from_this();
- SymbolVendor *symbols = GetSymbolVendor ();
+ SymbolContext sc;
+ sc.module_sp = shared_from_this();
+ SymbolVendor *symbols = GetSymbolVendor();
- for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++)
- {
- sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
- if (sc.comp_unit)
- {
- sc.function = nullptr;
- symbols->ParseVariablesForContext(sc);
+ for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) {
+ sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get();
+ if (sc.comp_unit) {
+ sc.function = nullptr;
+ symbols->ParseVariablesForContext(sc);
- symbols->ParseCompileUnitFunctions(sc);
+ symbols->ParseCompileUnitFunctions(sc);
- for (size_t func_idx = 0; (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != nullptr; ++func_idx)
- {
- symbols->ParseFunctionBlocks(sc);
+ for (size_t func_idx = 0;
+ (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) !=
+ nullptr;
+ ++func_idx) {
+ symbols->ParseFunctionBlocks(sc);
- // Parse the variables for this function and all its blocks
- symbols->ParseVariablesForContext(sc);
- }
+ // Parse the variables for this function and all its blocks
+ symbols->ParseVariablesForContext(sc);
+ }
- // Parse all types for this compile unit
- sc.function = nullptr;
- symbols->ParseTypes(sc);
- }
+ // Parse all types for this compile unit
+ sc.function = nullptr;
+ symbols->ParseTypes(sc);
}
+ }
}
-void
-Module::CalculateSymbolContext(SymbolContext* sc)
-{
- sc->module_sp = shared_from_this();
+void Module::CalculateSymbolContext(SymbolContext *sc) {
+ sc->module_sp = shared_from_this();
}
-ModuleSP
-Module::CalculateSymbolContextModule ()
-{
- return shared_from_this();
-}
+ModuleSP Module::CalculateSymbolContextModule() { return shared_from_this(); }
-void
-Module::DumpSymbolContext(Stream *s)
-{
- s->Printf(", Module{%p}", static_cast<void*>(this));
+void Module::DumpSymbolContext(Stream *s) {
+ s->Printf(", Module{%p}", static_cast<void *>(this));
}
-size_t
-Module::GetNumCompileUnits()
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- Timer scoped_timer(__PRETTY_FUNCTION__,
- "Module::GetNumCompileUnits (module = %p)",
- static_cast<void*>(this));
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- return symbols->GetNumCompileUnits();
- return 0;
+size_t Module::GetNumCompileUnits() {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "Module::GetNumCompileUnits (module = %p)",
+ static_cast<void *>(this));
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ return symbols->GetNumCompileUnits();
+ return 0;
}
-CompUnitSP
-Module::GetCompileUnitAtIndex (size_t index)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- size_t num_comp_units = GetNumCompileUnits ();
- CompUnitSP cu_sp;
+CompUnitSP Module::GetCompileUnitAtIndex(size_t index) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ size_t num_comp_units = GetNumCompileUnits();
+ CompUnitSP cu_sp;
- if (index < num_comp_units)
- {
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- cu_sp = symbols->GetCompileUnitAtIndex(index);
+ if (index < num_comp_units) {
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ cu_sp = symbols->GetCompileUnitAtIndex(index);
+ }
+ return cu_sp;
+}
+
+bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")",
+ vm_addr);
+ SectionList *section_list = GetSectionList();
+ if (section_list)
+ return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
+ return false;
+}
+
+uint32_t Module::ResolveSymbolContextForAddress(
+ const Address &so_addr, uint32_t resolve_scope, SymbolContext &sc,
+ bool resolve_tail_call_address) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ uint32_t resolved_flags = 0;
+
+ // Clear the result symbol context in case we don't find anything, but don't
+ // clear the target
+ sc.Clear(false);
+
+ // Get the section from the section/offset address.
+ SectionSP section_sp(so_addr.GetSection());
+
+ // Make sure the section matches this module before we try and match anything
+ if (section_sp && section_sp->GetModule().get() == this) {
+ // If the section offset based address resolved itself, then this
+ // is the right module.
+ sc.module_sp = shared_from_this();
+ resolved_flags |= eSymbolContextModule;
+
+ SymbolVendor *sym_vendor = GetSymbolVendor();
+ if (!sym_vendor)
+ return resolved_flags;
+
+ // Resolve the compile unit, function, block, line table or line
+ // entry if requested.
+ if (resolve_scope & eSymbolContextCompUnit ||
+ resolve_scope & eSymbolContextFunction ||
+ resolve_scope & eSymbolContextBlock ||
+ resolve_scope & eSymbolContextLineEntry ||
+ resolve_scope & eSymbolContextVariable) {
+ resolved_flags |=
+ sym_vendor->ResolveSymbolContext(so_addr, resolve_scope, sc);
}
- return cu_sp;
-}
-
-bool
-Module::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- Timer scoped_timer(__PRETTY_FUNCTION__, "Module::ResolveFileAddress (vm_addr = 0x%" PRIx64 ")", vm_addr);
- SectionList *section_list = GetSectionList();
- if (section_list)
- return so_addr.ResolveAddressUsingFileSections(vm_addr, section_list);
- return false;
-}
-
-uint32_t
-Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc,
- bool resolve_tail_call_address)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- uint32_t resolved_flags = 0;
- // Clear the result symbol context in case we don't find anything, but don't clear the target
- sc.Clear(false);
-
- // Get the section from the section/offset address.
- SectionSP section_sp (so_addr.GetSection());
-
- // Make sure the section matches this module before we try and match anything
- if (section_sp && section_sp->GetModule().get() == this)
- {
- // If the section offset based address resolved itself, then this
- // is the right module.
- sc.module_sp = shared_from_this();
- resolved_flags |= eSymbolContextModule;
-
- SymbolVendor* sym_vendor = GetSymbolVendor();
- if (!sym_vendor)
- return resolved_flags;
-
- // Resolve the compile unit, function, block, line table or line
- // entry if requested.
- if (resolve_scope & eSymbolContextCompUnit ||
- resolve_scope & eSymbolContextFunction ||
- resolve_scope & eSymbolContextBlock ||
- resolve_scope & eSymbolContextLineEntry ||
- resolve_scope & eSymbolContextVariable )
- {
- resolved_flags |= sym_vendor->ResolveSymbolContext (so_addr, resolve_scope, sc);
+ // Resolve the symbol if requested, but don't re-look it up if we've already
+ // found it.
+ if (resolve_scope & eSymbolContextSymbol &&
+ !(resolved_flags & eSymbolContextSymbol)) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab && so_addr.IsSectionOffset()) {
+ Symbol *matching_symbol = nullptr;
+
+ symtab->ForEachSymbolContainingFileAddress(
+ so_addr.GetFileAddress(),
+ [&matching_symbol](Symbol *symbol) -> bool {
+ if (symbol->GetType() != eSymbolTypeInvalid) {
+ matching_symbol = symbol;
+ return false; // Stop iterating
+ }
+ return true; // Keep iterating
+ });
+ sc.symbol = matching_symbol;
+ if (!sc.symbol && resolve_scope & eSymbolContextFunction &&
+ !(resolved_flags & eSymbolContextFunction)) {
+ bool verify_unique = false; // No need to check again since
+ // ResolveSymbolContext failed to find a
+ // symbol at this address.
+ if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
+ sc.symbol =
+ obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
}
- // Resolve the symbol if requested, but don't re-look it up if we've already found it.
- if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol))
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab && so_addr.IsSectionOffset())
- {
- Symbol *matching_symbol = nullptr;
-
- symtab->ForEachSymbolContainingFileAddress(so_addr.GetFileAddress(),
- [&matching_symbol](Symbol *symbol) -> bool {
- if (symbol->GetType() != eSymbolTypeInvalid)
- {
- matching_symbol = symbol;
- return false; // Stop iterating
- }
- return true; // Keep iterating
- });
- sc.symbol = matching_symbol;
- if (!sc.symbol &&
- resolve_scope & eSymbolContextFunction && !(resolved_flags & eSymbolContextFunction))
- {
- bool verify_unique = false; // No need to check again since ResolveSymbolContext failed to find a symbol at this address.
- if (ObjectFile *obj_file = sc.module_sp->GetObjectFile())
- sc.symbol = obj_file->ResolveSymbolForAddress(so_addr, verify_unique);
- }
-
- if (sc.symbol)
- {
- if (sc.symbol->IsSynthetic())
- {
- // We have a synthetic symbol so lets check if the object file
- // from the symbol file in the symbol vendor is different than
- // the object file for the module, and if so search its symbol
- // table to see if we can come up with a better symbol. For example
- // dSYM files on MacOSX have an unstripped symbol table inside of
- // them.
- ObjectFile *symtab_objfile = symtab->GetObjectFile();
- if (symtab_objfile && symtab_objfile->IsStripped())
- {
- SymbolFile *symfile = sym_vendor->GetSymbolFile();
- if (symfile)
- {
- ObjectFile *symfile_objfile = symfile->GetObjectFile();
- if (symfile_objfile != symtab_objfile)
- {
- Symtab *symfile_symtab = symfile_objfile->GetSymtab();
- if (symfile_symtab)
- {
- Symbol *symbol = symfile_symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
- if (symbol && !symbol->IsSynthetic())
- {
- sc.symbol = symbol;
- }
- }
- }
- }
- }
+ if (sc.symbol) {
+ if (sc.symbol->IsSynthetic()) {
+ // We have a synthetic symbol so lets check if the object file
+ // from the symbol file in the symbol vendor is different than
+ // the object file for the module, and if so search its symbol
+ // table to see if we can come up with a better symbol. For example
+ // dSYM files on MacOSX have an unstripped symbol table inside of
+ // them.
+ ObjectFile *symtab_objfile = symtab->GetObjectFile();
+ if (symtab_objfile && symtab_objfile->IsStripped()) {
+ SymbolFile *symfile = sym_vendor->GetSymbolFile();
+ if (symfile) {
+ ObjectFile *symfile_objfile = symfile->GetObjectFile();
+ if (symfile_objfile != symtab_objfile) {
+ Symtab *symfile_symtab = symfile_objfile->GetSymtab();
+ if (symfile_symtab) {
+ Symbol *symbol =
+ symfile_symtab->FindSymbolContainingFileAddress(
+ so_addr.GetFileAddress());
+ if (symbol && !symbol->IsSynthetic()) {
+ sc.symbol = symbol;
}
- resolved_flags |= eSymbolContextSymbol;
+ }
}
+ }
}
+ }
+ resolved_flags |= eSymbolContextSymbol;
}
+ }
+ }
- // For function symbols, so_addr may be off by one. This is a convention consistent
- // with FDE row indices in eh_frame sections, but requires extra logic here to permit
- // symbol lookup for disassembly and unwind.
- if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol) &&
- resolve_tail_call_address && so_addr.IsSectionOffset())
- {
- Address previous_addr = so_addr;
- previous_addr.Slide(-1);
-
- bool do_resolve_tail_call_address = false; // prevent recursion
- const uint32_t flags = ResolveSymbolContextForAddress(previous_addr, resolve_scope, sc,
- do_resolve_tail_call_address);
- if (flags & eSymbolContextSymbol)
- {
- AddressRange addr_range;
- if (sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, addr_range))
- {
- if (addr_range.GetBaseAddress().GetSection() == so_addr.GetSection())
- {
- // If the requested address is one past the address range of a function (i.e. a tail call),
- // or the decremented address is the start of a function (i.e. some forms of trampoline),
- // indicate that the symbol has been resolved.
- if (so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() ||
- so_addr.GetOffset() == addr_range.GetBaseAddress().GetOffset() + addr_range.GetByteSize())
- {
- resolved_flags |= flags;
- }
- }
- else
- {
- sc.symbol = nullptr; // Don't trust the symbol if the sections didn't match.
- }
- }
+ // For function symbols, so_addr may be off by one. This is a convention
+ // consistent
+ // with FDE row indices in eh_frame sections, but requires extra logic here
+ // to permit
+ // symbol lookup for disassembly and unwind.
+ if (resolve_scope & eSymbolContextSymbol &&
+ !(resolved_flags & eSymbolContextSymbol) && resolve_tail_call_address &&
+ so_addr.IsSectionOffset()) {
+ Address previous_addr = so_addr;
+ previous_addr.Slide(-1);
+
+ bool do_resolve_tail_call_address = false; // prevent recursion
+ const uint32_t flags = ResolveSymbolContextForAddress(
+ previous_addr, resolve_scope, sc, do_resolve_tail_call_address);
+ if (flags & eSymbolContextSymbol) {
+ AddressRange addr_range;
+ if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
+ false, addr_range)) {
+ if (addr_range.GetBaseAddress().GetSection() ==
+ so_addr.GetSection()) {
+ // If the requested address is one past the address range of a
+ // function (i.e. a tail call),
+ // or the decremented address is the start of a function (i.e. some
+ // forms of trampoline),
+ // indicate that the symbol has been resolved.
+ if (so_addr.GetOffset() ==
+ addr_range.GetBaseAddress().GetOffset() ||
+ so_addr.GetOffset() ==
+ addr_range.GetBaseAddress().GetOffset() +
+ addr_range.GetByteSize()) {
+ resolved_flags |= flags;
}
+ } else {
+ sc.symbol =
+ nullptr; // Don't trust the symbol if the sections didn't match.
+ }
}
+ }
}
- return resolved_flags;
-}
-
-uint32_t
-Module::ResolveSymbolContextForFilePath
-(
- const char *file_path,
- uint32_t line,
- bool check_inlines,
- uint32_t resolve_scope,
- SymbolContextList& sc_list
-)
-{
- FileSpec file_spec(file_path, false);
- return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
-}
-
-uint32_t
-Module::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- Timer scoped_timer(__PRETTY_FUNCTION__,
- "Module::ResolveSymbolContextForFilePath (%s:%u, check_inlines = %s, resolve_scope = 0x%8.8x)",
- file_spec.GetPath().c_str(),
- line,
- check_inlines ? "yes" : "no",
- resolve_scope);
-
- const uint32_t initial_count = sc_list.GetSize();
-
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list);
-
- return sc_list.GetSize() - initial_count;
-}
-
-size_t
-Module::FindGlobalVariables (const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- bool append,
- size_t max_matches,
- VariableList& variables)
-{
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- return symbols->FindGlobalVariables(name, parent_decl_ctx, append, max_matches, variables);
- return 0;
-}
-
-size_t
-Module::FindGlobalVariables (const RegularExpression& regex,
- bool append,
- size_t max_matches,
- VariableList& variables)
-{
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- return symbols->FindGlobalVariables(regex, append, max_matches, variables);
- return 0;
-}
-
-size_t
-Module::FindCompileUnits (const FileSpec &path,
- bool append,
- SymbolContextList &sc_list)
-{
- if (!append)
- sc_list.Clear();
-
- const size_t start_size = sc_list.GetSize();
- const size_t num_compile_units = GetNumCompileUnits();
- SymbolContext sc;
- sc.module_sp = shared_from_this();
- const bool compare_directory = (bool)path.GetDirectory();
- for (size_t i = 0; i < num_compile_units; ++i)
- {
- sc.comp_unit = GetCompileUnitAtIndex(i).get();
- if (sc.comp_unit)
- {
- if (FileSpec::Equal (*sc.comp_unit, path, compare_directory))
- sc_list.Append(sc);
- }
+ }
+ return resolved_flags;
+}
+
+uint32_t Module::ResolveSymbolContextForFilePath(const char *file_path,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList &sc_list) {
+ FileSpec file_spec(file_path, false);
+ return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
+ resolve_scope, sc_list);
+}
+
+uint32_t Module::ResolveSymbolContextsForFileSpec(const FileSpec &file_spec,
+ uint32_t line,
+ bool check_inlines,
+ uint32_t resolve_scope,
+ SymbolContextList &sc_list) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "Module::ResolveSymbolContextForFilePath (%s:%u, "
+ "check_inlines = %s, resolve_scope = 0x%8.8x)",
+ file_spec.GetPath().c_str(), line,
+ check_inlines ? "yes" : "no", resolve_scope);
+
+ const uint32_t initial_count = sc_list.GetSize();
+
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ symbols->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope,
+ sc_list);
+
+ return sc_list.GetSize() - initial_count;
+}
+
+size_t Module::FindGlobalVariables(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ bool append, size_t max_matches,
+ VariableList &variables) {
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ return symbols->FindGlobalVariables(name, parent_decl_ctx, append,
+ max_matches, variables);
+ return 0;
+}
+
+size_t Module::FindGlobalVariables(const RegularExpression &regex, bool append,
+ size_t max_matches,
+ VariableList &variables) {
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ return symbols->FindGlobalVariables(regex, append, max_matches, variables);
+ return 0;
+}
+
+size_t Module::FindCompileUnits(const FileSpec &path, bool append,
+ SymbolContextList &sc_list) {
+ if (!append)
+ sc_list.Clear();
+
+ const size_t start_size = sc_list.GetSize();
+ const size_t num_compile_units = GetNumCompileUnits();
+ SymbolContext sc;
+ sc.module_sp = shared_from_this();
+ const bool compare_directory = (bool)path.GetDirectory();
+ for (size_t i = 0; i < num_compile_units; ++i) {
+ sc.comp_unit = GetCompileUnitAtIndex(i).get();
+ if (sc.comp_unit) {
+ if (FileSpec::Equal(*sc.comp_unit, path, compare_directory))
+ sc_list.Append(sc);
}
- return sc_list.GetSize() - start_size;
-}
-
-Module::LookupInfo::LookupInfo(const ConstString &name, uint32_t name_type_mask, lldb::LanguageType language) :
- m_name(name),
- m_lookup_name(),
- m_language(language),
- m_name_type_mask(0),
- m_match_name_after_lookup(false)
-{
- const char *name_cstr = name.GetCString();
- llvm::StringRef basename;
- llvm::StringRef context;
-
- if (name_type_mask & eFunctionNameTypeAuto)
- {
- if (CPlusPlusLanguage::IsCPPMangledName (name_cstr))
- m_name_type_mask = eFunctionNameTypeFull;
- else if ((language == eLanguageTypeUnknown ||
- Language::LanguageIsObjC(language)) &&
- ObjCLanguage::IsPossibleObjCMethodName (name_cstr))
- m_name_type_mask = eFunctionNameTypeFull;
- else if (Language::LanguageIsC(language))
- {
- m_name_type_mask = eFunctionNameTypeFull;
- }
+ }
+ return sc_list.GetSize() - start_size;
+}
+
+Module::LookupInfo::LookupInfo(const ConstString &name, uint32_t name_type_mask,
+ lldb::LanguageType language)
+ : m_name(name), m_lookup_name(), m_language(language), m_name_type_mask(0),
+ m_match_name_after_lookup(false) {
+ const char *name_cstr = name.GetCString();
+ llvm::StringRef basename;
+ llvm::StringRef context;
+
+ if (name_type_mask & eFunctionNameTypeAuto) {
+ if (CPlusPlusLanguage::IsCPPMangledName(name_cstr))
+ m_name_type_mask = eFunctionNameTypeFull;
+ else if ((language == eLanguageTypeUnknown ||
+ Language::LanguageIsObjC(language)) &&
+ ObjCLanguage::IsPossibleObjCMethodName(name_cstr))
+ m_name_type_mask = eFunctionNameTypeFull;
+ else if (Language::LanguageIsC(language)) {
+ m_name_type_mask = eFunctionNameTypeFull;
+ } else {
+ if ((language == eLanguageTypeUnknown ||
+ Language::LanguageIsObjC(language)) &&
+ ObjCLanguage::IsPossibleObjCSelector(name_cstr))
+ m_name_type_mask |= eFunctionNameTypeSelector;
+
+ CPlusPlusLanguage::MethodName cpp_method(name);
+ basename = cpp_method.GetBasename();
+ if (basename.empty()) {
+ if (CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
+ basename))
+ m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
else
- {
- if ((language == eLanguageTypeUnknown ||
- Language::LanguageIsObjC(language)) &&
- ObjCLanguage::IsPossibleObjCSelector(name_cstr))
- m_name_type_mask |= eFunctionNameTypeSelector;
-
- CPlusPlusLanguage::MethodName cpp_method (name);
- basename = cpp_method.GetBasename();
- if (basename.empty())
- {
- if (CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename))
- m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
- else
- m_name_type_mask |= eFunctionNameTypeFull;
- }
- else
- {
- m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
- }
- }
+ m_name_type_mask |= eFunctionNameTypeFull;
+ } else {
+ m_name_type_mask |= (eFunctionNameTypeMethod | eFunctionNameTypeBase);
+ }
}
- else
- {
- m_name_type_mask = name_type_mask;
- if (name_type_mask & eFunctionNameTypeMethod || name_type_mask & eFunctionNameTypeBase)
- {
- // 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.
- CPlusPlusLanguage::MethodName cpp_method (name);
- if (cpp_method.IsValid())
- {
- basename = cpp_method.GetBasename();
-
- if (!cpp_method.GetQualifiers().empty())
- {
- // There is a "const" or other qualifier following the end of the function parens,
- // this can't be a eFunctionNameTypeBase
- m_name_type_mask &= ~(eFunctionNameTypeBase);
- if (m_name_type_mask == eFunctionNameTypeNone)
- return;
- }
- }
- else
- {
- // 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.
- CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename);
- }
- }
-
- if (name_type_mask & eFunctionNameTypeSelector)
- {
- if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr))
- {
- m_name_type_mask &= ~(eFunctionNameTypeSelector);
- if (m_name_type_mask == eFunctionNameTypeNone)
- return;
- }
- }
-
- // Still try and get a basename in case someone specifies a name type mask of
- // eFunctionNameTypeFull and a name like "A::func"
- if (basename.empty())
- {
- if (name_type_mask & eFunctionNameTypeFull)
- {
- CPlusPlusLanguage::MethodName cpp_method (name);
- basename = cpp_method.GetBasename();
- if (basename.empty())
- CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename);
- }
+ } else {
+ m_name_type_mask = name_type_mask;
+ if (name_type_mask & eFunctionNameTypeMethod ||
+ name_type_mask & eFunctionNameTypeBase) {
+ // 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.
+ CPlusPlusLanguage::MethodName cpp_method(name);
+ if (cpp_method.IsValid()) {
+ basename = cpp_method.GetBasename();
+
+ if (!cpp_method.GetQualifiers().empty()) {
+ // There is a "const" or other qualifier following the end of the
+ // function parens,
+ // this can't be a eFunctionNameTypeBase
+ m_name_type_mask &= ~(eFunctionNameTypeBase);
+ if (m_name_type_mask == eFunctionNameTypeNone)
+ return;
}
+ } else {
+ // 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.
+ CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
+ basename);
+ }
}
- if (!basename.empty())
- {
- // The name supplied was a partial C++ path like "a::count". In this case we want to do a
- // lookup on the basename "count" and then make sure any matching results contain "a::count"
- // so that it would match "b::a::count" and "a::count". This is why we set "match_name_after_lookup"
- // to true
- m_lookup_name.SetString(basename);
- m_match_name_after_lookup = true;
- }
- else
- {
- // The name is already correct, just use the exact name as supplied, and we won't need
- // to check if any matches contain "name"
- m_lookup_name = name;
- m_match_name_after_lookup = false;
+ if (name_type_mask & eFunctionNameTypeSelector) {
+ if (!ObjCLanguage::IsPossibleObjCSelector(name_cstr)) {
+ m_name_type_mask &= ~(eFunctionNameTypeSelector);
+ if (m_name_type_mask == eFunctionNameTypeNone)
+ return;
+ }
}
-}
-
-void
-Module::LookupInfo::Prune(SymbolContextList &sc_list, size_t start_idx) const
-{
- if (m_match_name_after_lookup && m_name)
- {
- SymbolContext sc;
- size_t i = start_idx;
- while (i < sc_list.GetSize())
- {
- if (!sc_list.GetContextAtIndex(i, sc))
- break;
- ConstString full_name(sc.GetFunctionName());
- if (full_name && ::strstr(full_name.GetCString(), m_name.GetCString()) == nullptr)
- {
- sc_list.RemoveContextAtIndex(i);
- }
- else
- {
- ++i;
- }
- }
+ // Still try and get a basename in case someone specifies a name type mask
+ // of
+ // eFunctionNameTypeFull and a name like "A::func"
+ if (basename.empty()) {
+ if (name_type_mask & eFunctionNameTypeFull) {
+ CPlusPlusLanguage::MethodName cpp_method(name);
+ basename = cpp_method.GetBasename();
+ if (basename.empty())
+ CPlusPlusLanguage::ExtractContextAndIdentifier(name_cstr, context,
+ basename);
+ }
}
-
- // If we have only full name matches we might have tried to set breakpoint on "func"
- // and specified eFunctionNameTypeFull, but we might have found "a::func()",
- // "a::b::func()", "c::func()", "func()" and "func". Only "func()" and "func" should
- // end up matching.
- if (m_name_type_mask == eFunctionNameTypeFull)
- {
- SymbolContext sc;
- size_t i = start_idx;
- while (i < sc_list.GetSize())
- {
- if (!sc_list.GetContextAtIndex(i, sc))
- break;
- ConstString full_name(sc.GetFunctionName());
- CPlusPlusLanguage::MethodName cpp_method(full_name);
- if (cpp_method.IsValid())
- {
- if (cpp_method.GetContext().empty())
- {
- if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0)
- {
- sc_list.RemoveContextAtIndex(i);
- continue;
- }
- }
- else
- {
- std::string qualified_name = cpp_method.GetScopeQualifiedName();
- if (qualified_name.compare(m_name.GetCString()) != 0)
- {
- sc_list.RemoveContextAtIndex(i);
- continue;
- }
- }
- }
- ++i;
+ }
+
+ if (!basename.empty()) {
+ // The name supplied was a partial C++ path like "a::count". In this case we
+ // want to do a
+ // lookup on the basename "count" and then make sure any matching results
+ // contain "a::count"
+ // so that it would match "b::a::count" and "a::count". This is why we set
+ // "match_name_after_lookup"
+ // to true
+ m_lookup_name.SetString(basename);
+ m_match_name_after_lookup = true;
+ } else {
+ // The name is already correct, just use the exact name as supplied, and we
+ // won't need
+ // to check if any matches contain "name"
+ m_lookup_name = name;
+ m_match_name_after_lookup = false;
+ }
+}
+
+void Module::LookupInfo::Prune(SymbolContextList &sc_list,
+ size_t start_idx) const {
+ if (m_match_name_after_lookup && m_name) {
+ SymbolContext sc;
+ size_t i = start_idx;
+ while (i < sc_list.GetSize()) {
+ if (!sc_list.GetContextAtIndex(i, sc))
+ break;
+ ConstString full_name(sc.GetFunctionName());
+ if (full_name &&
+ ::strstr(full_name.GetCString(), m_name.GetCString()) == nullptr) {
+ sc_list.RemoveContextAtIndex(i);
+ } else {
+ ++i;
+ }
+ }
+ }
+
+ // If we have only full name matches we might have tried to set breakpoint on
+ // "func"
+ // and specified eFunctionNameTypeFull, but we might have found "a::func()",
+ // "a::b::func()", "c::func()", "func()" and "func". Only "func()" and "func"
+ // should
+ // end up matching.
+ if (m_name_type_mask == eFunctionNameTypeFull) {
+ SymbolContext sc;
+ size_t i = start_idx;
+ while (i < sc_list.GetSize()) {
+ if (!sc_list.GetContextAtIndex(i, sc))
+ break;
+ ConstString full_name(sc.GetFunctionName());
+ CPlusPlusLanguage::MethodName cpp_method(full_name);
+ if (cpp_method.IsValid()) {
+ if (cpp_method.GetContext().empty()) {
+ if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) {
+ sc_list.RemoveContextAtIndex(i);
+ continue;
+ }
+ } else {
+ std::string qualified_name = cpp_method.GetScopeQualifiedName();
+ if (qualified_name.compare(m_name.GetCString()) != 0) {
+ sc_list.RemoveContextAtIndex(i);
+ continue;
+ }
}
+ }
+ ++i;
}
+ }
}
+size_t Module::FindFunctions(const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx,
+ uint32_t name_type_mask, bool include_symbols,
+ bool include_inlines, bool append,
+ SymbolContextList &sc_list) {
+ if (!append)
+ sc_list.Clear();
-size_t
-Module::FindFunctions (const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- uint32_t name_type_mask,
- bool include_symbols,
- bool include_inlines,
- bool append,
- SymbolContextList& sc_list)
-{
- if (!append)
- sc_list.Clear();
-
- const size_t old_size = sc_list.GetSize();
+ const size_t old_size = sc_list.GetSize();
- // Find all the functions (not symbols, but debug information functions...
- SymbolVendor *symbols = GetSymbolVendor ();
-
- if (name_type_mask & eFunctionNameTypeAuto)
- {
- LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
+ // Find all the functions (not symbols, but debug information functions...
+ SymbolVendor *symbols = GetSymbolVendor();
- if (symbols)
- {
- symbols->FindFunctions(lookup_info.GetLookupName(),
- parent_decl_ctx,
- lookup_info.GetNameTypeMask(),
- include_inlines,
- append,
- sc_list);
-
- // Now check our symbol table for symbols that are code symbols if requested
- if (include_symbols)
- {
- Symtab *symtab = symbols->GetSymtab();
- if (symtab)
- symtab->FindFunctionSymbols(lookup_info.GetLookupName(), lookup_info.GetNameTypeMask(), sc_list);
- }
- }
+ if (name_type_mask & eFunctionNameTypeAuto) {
+ LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
- const size_t new_size = sc_list.GetSize();
+ if (symbols) {
+ symbols->FindFunctions(lookup_info.GetLookupName(), parent_decl_ctx,
+ lookup_info.GetNameTypeMask(), include_inlines,
+ append, sc_list);
- if (old_size < new_size)
- lookup_info.Prune (sc_list, old_size);
- }
- else
- {
- if (symbols)
- {
- 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)
- {
- Symtab *symtab = symbols->GetSymtab();
- if (symtab)
- symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
- }
- }
- }
-
- return sc_list.GetSize() - old_size;
-}
-
-size_t
-Module::FindFunctions (const RegularExpression& regex,
- bool include_symbols,
- bool include_inlines,
- bool append,
- SymbolContextList& sc_list)
-{
- if (!append)
- sc_list.Clear();
-
- const size_t start_size = sc_list.GetSize();
-
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- {
- symbols->FindFunctions(regex, include_inlines, append, sc_list);
-
- // Now check our symbol table for symbols that are code symbols if requested
- if (include_symbols)
- {
- Symtab *symtab = symbols->GetSymtab();
- if (symtab)
- {
- std::vector<uint32_t> symbol_indexes;
- symtab->AppendSymbolIndexesMatchingRegExAndType (regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
- const size_t num_matches = symbol_indexes.size();
- if (num_matches)
- {
- SymbolContext sc(this);
- const size_t end_functions_added_index = sc_list.GetSize();
- size_t num_functions_added_to_sc_list = end_functions_added_index - start_size;
- if (num_functions_added_to_sc_list == 0)
- {
- // No functions were added, just symbols, so we can just append them
- for (size_t i = 0; i < num_matches; ++i)
- {
- sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
- SymbolType sym_type = sc.symbol->GetType();
- if (sc.symbol && (sym_type == eSymbolTypeCode ||
- sym_type == eSymbolTypeResolver))
- sc_list.Append(sc);
- }
- }
- else
- {
- typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
- FileAddrToIndexMap file_addr_to_index;
- for (size_t i = start_size; i < end_functions_added_index; ++i)
- {
- const SymbolContext &sc = sc_list[i];
- if (sc.block)
- continue;
- file_addr_to_index[sc.function->GetAddressRange().GetBaseAddress().GetFileAddress()] = i;
- }
-
- FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
- // Functions were added so we need to merge symbols into any
- // existing function symbol contexts
- for (size_t i = start_size; i < num_matches; ++i)
- {
- sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
- SymbolType sym_type = sc.symbol->GetType();
- if (sc.symbol && sc.symbol->ValueIsAddress() && (sym_type == eSymbolTypeCode || sym_type == eSymbolTypeResolver))
- {
- FileAddrToIndexMap::const_iterator pos = file_addr_to_index.find(sc.symbol->GetAddressRef().GetFileAddress());
- if (pos == end)
- sc_list.Append(sc);
- else
- sc_list[pos->second].symbol = sc.symbol;
- }
- }
- }
- }
- }
- }
+ // Now check our symbol table for symbols that are code symbols if
+ // requested
+ if (include_symbols) {
+ Symtab *symtab = symbols->GetSymtab();
+ if (symtab)
+ symtab->FindFunctionSymbols(lookup_info.GetLookupName(),
+ lookup_info.GetNameTypeMask(), sc_list);
+ }
}
- return sc_list.GetSize() - start_size;
-}
-void
-Module::FindAddressesForLine (const lldb::TargetSP target_sp,
- const FileSpec &file, uint32_t line,
- Function *function,
- std::vector<Address> &output_local, std::vector<Address> &output_extern)
-{
- SearchFilterByModule filter(target_sp, m_file);
- AddressResolverFileLine resolver(file, line, true);
- resolver.ResolveAddress (filter);
+ const size_t new_size = sc_list.GetSize();
- for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++)
- {
- Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();
- Function *f = addr.CalculateSymbolContextFunction();
- if (f && f == function)
- output_local.push_back (addr);
- else
- output_extern.push_back (addr);
- }
-}
+ if (old_size < new_size)
+ lookup_info.Prune(sc_list, old_size);
+ } else {
+ if (symbols) {
+ symbols->FindFunctions(name, parent_decl_ctx, name_type_mask,
+ include_inlines, append, sc_list);
-size_t
-Module::FindTypes_Impl (const SymbolContext& sc,
- const ConstString &name,
- const CompilerDeclContext *parent_decl_ctx,
- bool append,
- size_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap& types)
-{
- Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
- if (!sc.module_sp || sc.module_sp.get() == this)
- {
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- return symbols->FindTypes(sc, name, parent_decl_ctx, append, max_matches, searched_symbol_files, types);
+ // Now check our symbol table for symbols that are code symbols if
+ // requested
+ if (include_symbols) {
+ Symtab *symtab = symbols->GetSymtab();
+ if (symtab)
+ symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
+ }
}
- return 0;
-}
-
-size_t
-Module::FindTypesInNamespace (const SymbolContext& sc,
- const ConstString &type_name,
- const CompilerDeclContext *parent_decl_ctx,
- size_t max_matches,
- TypeList& type_list)
-{
- const bool append = true;
- TypeMap types_map;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- size_t num_types = FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches, searched_symbol_files, types_map);
- if (num_types > 0)
- sc.SortTypeList(types_map, type_list);
- return num_types;
-}
-
-lldb::TypeSP
-Module::FindFirstType (const SymbolContext& sc,
- const ConstString &name,
- bool exact_match)
-{
- TypeList type_list;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- const size_t num_matches = FindTypes (sc, name, exact_match, 1, searched_symbol_files, type_list);
- if (num_matches)
- return type_list.GetTypeAtIndex(0);
- return TypeSP();
-}
-
-size_t
-Module::FindTypes (const SymbolContext& sc,
- const ConstString &name,
- bool exact_match,
- size_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeList& types)
-{
- size_t num_matches = 0;
- const char *type_name_cstr = name.GetCString();
- std::string type_scope;
- 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
- // from the root namespace and implies and exact match. The typenames we
- // get back from clang do not start with "::" so we need to strip this off
- // in order to get the qualified names to match
+ }
+
+ return sc_list.GetSize() - old_size;
+}
+
+size_t Module::FindFunctions(const RegularExpression &regex,
+ bool include_symbols, bool include_inlines,
+ bool append, SymbolContextList &sc_list) {
+ if (!append)
+ sc_list.Clear();
+
+ const size_t start_size = sc_list.GetSize();
+
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols) {
+ symbols->FindFunctions(regex, include_inlines, append, sc_list);
+
+ // Now check our symbol table for symbols that are code symbols if requested
+ if (include_symbols) {
+ Symtab *symtab = symbols->GetSymtab();
+ if (symtab) {
+ std::vector<uint32_t> symbol_indexes;
+ symtab->AppendSymbolIndexesMatchingRegExAndType(
+ regex, eSymbolTypeAny, Symtab::eDebugAny, Symtab::eVisibilityAny,
+ symbol_indexes);
+ const size_t num_matches = symbol_indexes.size();
+ if (num_matches) {
+ SymbolContext sc(this);
+ const size_t end_functions_added_index = sc_list.GetSize();
+ size_t num_functions_added_to_sc_list =
+ end_functions_added_index - start_size;
+ if (num_functions_added_to_sc_list == 0) {
+ // No functions were added, just symbols, so we can just append them
+ for (size_t i = 0; i < num_matches; ++i) {
+ sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
+ SymbolType sym_type = sc.symbol->GetType();
+ if (sc.symbol && (sym_type == eSymbolTypeCode ||
+ sym_type == eSymbolTypeResolver))
+ sc_list.Append(sc);
+ }
+ } else {
+ typedef std::map<lldb::addr_t, uint32_t> FileAddrToIndexMap;
+ FileAddrToIndexMap file_addr_to_index;
+ for (size_t i = start_size; i < end_functions_added_index; ++i) {
+ const SymbolContext &sc = sc_list[i];
+ if (sc.block)
+ continue;
+ file_addr_to_index[sc.function->GetAddressRange()
+ .GetBaseAddress()
+ .GetFileAddress()] = i;
+ }
- if (type_scope.size() >= 2 && type_scope[0] == ':' && type_scope[1] == ':')
- {
- type_scope.erase(0,2);
- exact_match = true;
- }
- ConstString type_basename_const_str (type_basename.c_str());
- if (FindTypes_Impl(sc, type_basename_const_str, nullptr, append, max_matches, searched_symbol_files, typesmap))
- {
- typesmap.RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match);
- num_matches = typesmap.GetSize();
+ FileAddrToIndexMap::const_iterator end = file_addr_to_index.end();
+ // Functions were added so we need to merge symbols into any
+ // existing function symbol contexts
+ for (size_t i = start_size; i < num_matches; ++i) {
+ sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
+ SymbolType sym_type = sc.symbol->GetType();
+ if (sc.symbol && sc.symbol->ValueIsAddress() &&
+ (sym_type == eSymbolTypeCode ||
+ sym_type == eSymbolTypeResolver)) {
+ FileAddrToIndexMap::const_iterator pos =
+ file_addr_to_index.find(
+ sc.symbol->GetAddressRef().GetFileAddress());
+ if (pos == end)
+ sc_list.Append(sc);
+ else
+ sc_list[pos->second].symbol = sc.symbol;
+ }
+ }
+ }
}
+ }
}
+ }
+ return sc_list.GetSize() - start_size;
+}
+
+void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
+ const FileSpec &file, uint32_t line,
+ Function *function,
+ std::vector<Address> &output_local,
+ std::vector<Address> &output_extern) {
+ SearchFilterByModule filter(target_sp, m_file);
+ AddressResolverFileLine resolver(file, line, true);
+ resolver.ResolveAddress(filter);
+
+ for (size_t n = 0; n < resolver.GetNumberOfAddresses(); n++) {
+ Address addr = resolver.GetAddressRangeAtIndex(n).GetBaseAddress();
+ Function *f = addr.CalculateSymbolContextFunction();
+ if (f && f == function)
+ output_local.push_back(addr);
else
- {
- // The type is not in a namespace/class scope, just search for it by basename
- if (type_class != eTypeClassAny)
- {
- // 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), nullptr, append, max_matches, searched_symbol_files, typesmap);
- typesmap.RemoveMismatchedTypes (type_class);
- num_matches = typesmap.GetSize();
- }
- else
- {
- num_matches = FindTypes_Impl(sc, name, nullptr, append, max_matches, searched_symbol_files, typesmap);
- }
+ output_extern.push_back(addr);
+ }
+}
+
+size_t Module::FindTypes_Impl(
+ const SymbolContext &sc, const ConstString &name,
+ const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ TypeMap &types) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION);
+ if (!sc.module_sp || sc.module_sp.get() == this) {
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ return symbols->FindTypes(sc, name, parent_decl_ctx, append, max_matches,
+ searched_symbol_files, types);
+ }
+ return 0;
+}
+
+size_t Module::FindTypesInNamespace(const SymbolContext &sc,
+ const ConstString &type_name,
+ const CompilerDeclContext *parent_decl_ctx,
+ size_t max_matches, TypeList &type_list) {
+ const bool append = true;
+ TypeMap types_map;
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ size_t num_types =
+ FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches,
+ searched_symbol_files, types_map);
+ if (num_types > 0)
+ sc.SortTypeList(types_map, type_list);
+ return num_types;
+}
+
+lldb::TypeSP Module::FindFirstType(const SymbolContext &sc,
+ const ConstString &name, bool exact_match) {
+ TypeList type_list;
+ llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
+ const size_t num_matches =
+ FindTypes(sc, name, exact_match, 1, searched_symbol_files, type_list);
+ if (num_matches)
+ return type_list.GetTypeAtIndex(0);
+ return TypeSP();
+}
+
+size_t Module::FindTypes(
+ const SymbolContext &sc, const ConstString &name, bool exact_match,
+ size_t max_matches,
+ llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
+ TypeList &types) {
+ size_t num_matches = 0;
+ const char *type_name_cstr = name.GetCString();
+ std::string type_scope;
+ 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
+ // from the root namespace and implies and exact match. The typenames we
+ // get back from clang do not start with "::" so we need to strip this off
+ // in order to get the qualified names to match
+
+ if (type_scope.size() >= 2 && type_scope[0] == ':' &&
+ type_scope[1] == ':') {
+ type_scope.erase(0, 2);
+ exact_match = true;
}
- if (num_matches > 0)
- sc.SortTypeList(typesmap, types);
- return num_matches;
-}
-
-SymbolVendor*
-Module::GetSymbolVendor (bool can_create, lldb_private::Stream *feedback_strm)
-{
- if (!m_did_load_symbol_vendor.load())
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (!m_did_load_symbol_vendor.load() && can_create)
- {
- ObjectFile *obj_file = GetObjectFile ();
- if (obj_file != nullptr)
- {
- Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
- m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
- m_did_load_symbol_vendor = true;
- }
- }
+ ConstString type_basename_const_str(type_basename.c_str());
+ if (FindTypes_Impl(sc, type_basename_const_str, nullptr, append,
+ max_matches, searched_symbol_files, typesmap)) {
+ typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
+ exact_match);
+ num_matches = typesmap.GetSize();
}
- return m_symfile_ap.get();
-}
-
-void
-Module::SetFileSpecAndObjectName (const FileSpec &file, const ConstString &object_name)
-{
- // Container objects whose paths do not specify a file directly can call
- // this function to correct the file and object names.
- m_file = file;
- m_mod_time = file.GetModificationTime();
- m_object_name = object_name;
-}
-
-const ArchSpec&
-Module::GetArchitecture () const
-{
- return m_arch;
-}
-
-std::string
-Module::GetSpecificationDescription () const
-{
- std::string spec(GetFileSpec().GetPath());
- if (m_object_name)
- {
- spec += '(';
- spec += m_object_name.GetCString();
- spec += ')';
+ } else {
+ // The type is not in a namespace/class scope, just search for it by
+ // basename
+ if (type_class != eTypeClassAny) {
+ // 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), nullptr, append,
+ max_matches, searched_symbol_files, typesmap);
+ typesmap.RemoveMismatchedTypes(type_class);
+ num_matches = typesmap.GetSize();
+ } else {
+ num_matches = FindTypes_Impl(sc, name, nullptr, append, max_matches,
+ searched_symbol_files, typesmap);
}
- return spec;
+ }
+ if (num_matches > 0)
+ sc.SortTypeList(typesmap, types);
+ return num_matches;
}
-void
-Module::GetDescription (Stream *s, lldb::DescriptionLevel level)
-{
+SymbolVendor *Module::GetSymbolVendor(bool can_create,
+ lldb_private::Stream *feedback_strm) {
+ if (!m_did_load_symbol_vendor.load()) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
-
- if (level >= eDescriptionLevelFull)
- {
- if (m_arch.IsValid())
- s->Printf("(%s) ", m_arch.GetArchitectureName());
+ if (!m_did_load_symbol_vendor.load() && can_create) {
+ ObjectFile *obj_file = GetObjectFile();
+ if (obj_file != nullptr) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION);
+ m_symfile_ap.reset(
+ SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
+ m_did_load_symbol_vendor = true;
+ }
}
-
- if (level == eDescriptionLevelBrief)
- {
- const char *filename = m_file.GetFilename().GetCString();
- if (filename)
- s->PutCString (filename);
- }
- else
- {
- char path[PATH_MAX];
- if (m_file.GetPath(path, sizeof(path)))
- s->PutCString(path);
- }
-
- const char *object_name = m_object_name.GetCString();
- if (object_name)
- s->Printf("(%s)", object_name);
-}
-
-void
-Module::ReportError (const char *format, ...)
-{
- if (format && format[0])
- {
- StreamString strm;
- strm.PutCString("error: ");
- GetDescription(&strm, lldb::eDescriptionLevelBrief);
- strm.PutChar (' ');
- va_list args;
- va_start (args, format);
- strm.PrintfVarArg(format, args);
- va_end (args);
-
- const int format_len = strlen(format);
- if (format_len > 0)
- {
- const char last_char = format[format_len-1];
- if (last_char != '\n' || last_char != '\r')
- strm.EOL();
- }
- Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str());
+ }
+ return m_symfile_ap.get();
+}
+
+void Module::SetFileSpecAndObjectName(const FileSpec &file,
+ const ConstString &object_name) {
+ // Container objects whose paths do not specify a file directly can call
+ // this function to correct the file and object names.
+ m_file = file;
+ m_mod_time = FileSystem::GetModificationTime(file);
+ m_object_name = object_name;
+}
+
+const ArchSpec &Module::GetArchitecture() const { return m_arch; }
+
+std::string Module::GetSpecificationDescription() const {
+ std::string spec(GetFileSpec().GetPath());
+ if (m_object_name) {
+ spec += '(';
+ spec += m_object_name.GetCString();
+ spec += ')';
+ }
+ return spec;
+}
+
+void Module::GetDescription(Stream *s, lldb::DescriptionLevel level) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+
+ if (level >= eDescriptionLevelFull) {
+ if (m_arch.IsValid())
+ s->Printf("(%s) ", m_arch.GetArchitectureName());
+ }
+
+ if (level == eDescriptionLevelBrief) {
+ const char *filename = m_file.GetFilename().GetCString();
+ if (filename)
+ s->PutCString(filename);
+ } else {
+ char path[PATH_MAX];
+ if (m_file.GetPath(path, sizeof(path)))
+ s->PutCString(path);
+ }
+
+ const char *object_name = m_object_name.GetCString();
+ if (object_name)
+ s->Printf("(%s)", object_name);
+}
+
+void Module::ReportError(const char *format, ...) {
+ if (format && format[0]) {
+ StreamString strm;
+ strm.PutCString("error: ");
+ GetDescription(&strm, lldb::eDescriptionLevelBrief);
+ strm.PutChar(' ');
+ va_list args;
+ va_start(args, format);
+ strm.PrintfVarArg(format, args);
+ va_end(args);
+
+ const int format_len = strlen(format);
+ if (format_len > 0) {
+ const char last_char = format[format_len - 1];
+ if (last_char != '\n' || last_char != '\r')
+ strm.EOL();
}
+ Host::SystemLog(Host::eSystemLogError, "%s", strm.GetData());
+ }
}
-bool
-Module::FileHasChanged () const
-{
- if (!m_file_has_changed)
- m_file_has_changed = (m_file.GetModificationTime() != m_mod_time);
- return m_file_has_changed;
-}
-
-void
-Module::ReportErrorIfModifyDetected (const char *format, ...)
-{
- if (!m_first_file_changed_log)
- {
- if (FileHasChanged ())
- {
- m_first_file_changed_log = true;
- if (format)
- {
- StreamString strm;
- strm.PutCString("error: the object file ");
- GetDescription(&strm, lldb::eDescriptionLevelFull);
- strm.PutCString (" has been modified\n");
-
- va_list args;
- va_start (args, format);
- strm.PrintfVarArg(format, args);
- va_end (args);
-
- const int format_len = strlen(format);
- if (format_len > 0)
- {
- const char last_char = format[format_len-1];
- if (last_char != '\n' || last_char != '\r')
- strm.EOL();
- }
- strm.PutCString("The debug session should be aborted as the original debug information has been overwritten.\n");
- Host::SystemLog (Host::eSystemLogError, "%s", strm.GetString().c_str());
- }
- }
- }
+bool Module::FileHasChanged() const {
+ if (!m_file_has_changed)
+ m_file_has_changed =
+ (FileSystem::GetModificationTime(m_file) != m_mod_time);
+ return m_file_has_changed;
}
-void
-Module::ReportWarning (const char *format, ...)
-{
- if (format && format[0])
- {
+void Module::ReportErrorIfModifyDetected(const char *format, ...) {
+ if (!m_first_file_changed_log) {
+ if (FileHasChanged()) {
+ m_first_file_changed_log = true;
+ if (format) {
StreamString strm;
- strm.PutCString("warning: ");
+ strm.PutCString("error: the object file ");
GetDescription(&strm, lldb::eDescriptionLevelFull);
- strm.PutChar (' ');
-
+ strm.PutCString(" has been modified\n");
+
va_list args;
- va_start (args, format);
+ va_start(args, format);
strm.PrintfVarArg(format, args);
- va_end (args);
-
+ va_end(args);
+
const int format_len = strlen(format);
- if (format_len > 0)
- {
- const char last_char = format[format_len-1];
- if (last_char != '\n' || last_char != '\r')
- strm.EOL();
+ if (format_len > 0) {
+ const char last_char = format[format_len - 1];
+ if (last_char != '\n' || last_char != '\r')
+ strm.EOL();
}
- Host::SystemLog (Host::eSystemLogWarning, "%s", strm.GetString().c_str());
+ strm.PutCString("The debug session should be aborted as the original "
+ "debug information has been overwritten.\n");
+ Host::SystemLog(Host::eSystemLogError, "%s", strm.GetData());
+ }
}
-}
-
-void
-Module::LogMessage (Log *log, const char *format, ...)
-{
- if (log != nullptr)
- {
- StreamString log_message;
- GetDescription(&log_message, lldb::eDescriptionLevelFull);
- log_message.PutCString (": ");
- va_list args;
- va_start (args, format);
- log_message.PrintfVarArg (format, args);
- va_end (args);
- log->PutCString(log_message.GetString().c_str());
+ }
+}
+
+void Module::ReportWarning(const char *format, ...) {
+ if (format && format[0]) {
+ StreamString strm;
+ strm.PutCString("warning: ");
+ GetDescription(&strm, lldb::eDescriptionLevelFull);
+ strm.PutChar(' ');
+
+ va_list args;
+ va_start(args, format);
+ strm.PrintfVarArg(format, args);
+ va_end(args);
+
+ const int format_len = strlen(format);
+ if (format_len > 0) {
+ const char last_char = format[format_len - 1];
+ if (last_char != '\n' || last_char != '\r')
+ strm.EOL();
}
-}
-
-void
-Module::LogMessageVerboseBacktrace (Log *log, const char *format, ...)
-{
- if (log != nullptr)
- {
- StreamString log_message;
- GetDescription(&log_message, lldb::eDescriptionLevelFull);
- log_message.PutCString (": ");
- va_list args;
- va_start (args, format);
- log_message.PrintfVarArg (format, args);
- va_end (args);
- if (log->GetVerbose())
- {
- std::string back_trace;
- llvm::raw_string_ostream stream(back_trace);
- llvm::sys::PrintStackTrace(stream);
- log_message.PutCString(back_trace.c_str());
- }
- log->PutCString(log_message.GetString().c_str());
+ Host::SystemLog(Host::eSystemLogWarning, "%s", strm.GetData());
+ }
+}
+
+void Module::LogMessage(Log *log, const char *format, ...) {
+ if (log != nullptr) {
+ StreamString log_message;
+ GetDescription(&log_message, lldb::eDescriptionLevelFull);
+ log_message.PutCString(": ");
+ va_list args;
+ va_start(args, format);
+ log_message.PrintfVarArg(format, args);
+ va_end(args);
+ log->PutCString(log_message.GetData());
+ }
+}
+
+void Module::LogMessageVerboseBacktrace(Log *log, const char *format, ...) {
+ if (log != nullptr) {
+ StreamString log_message;
+ GetDescription(&log_message, lldb::eDescriptionLevelFull);
+ log_message.PutCString(": ");
+ va_list args;
+ va_start(args, format);
+ log_message.PrintfVarArg(format, args);
+ va_end(args);
+ if (log->GetVerbose()) {
+ std::string back_trace;
+ llvm::raw_string_ostream stream(back_trace);
+ llvm::sys::PrintStackTrace(stream);
+ log_message.PutCString(back_trace);
}
+ log->PutCString(log_message.GetData());
+ }
}
-void
-Module::Dump(Stream *s)
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- //s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
- s->Indent();
- s->Printf("Module %s%s%s%s\n",
- m_file.GetPath().c_str(),
- m_object_name ? "(" : "",
- m_object_name ? m_object_name.GetCString() : "",
- m_object_name ? ")" : "");
-
- s->IndentMore();
-
- ObjectFile *objfile = GetObjectFile ();
- if (objfile)
- objfile->Dump(s);
+void Module::Dump(Stream *s) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+ s->Indent();
+ s->Printf("Module %s%s%s%s\n", m_file.GetPath().c_str(),
+ m_object_name ? "(" : "",
+ m_object_name ? m_object_name.GetCString() : "",
+ m_object_name ? ")" : "");
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- symbols->Dump(s);
+ s->IndentMore();
- s->IndentLess();
-}
+ ObjectFile *objfile = GetObjectFile();
+ if (objfile)
+ objfile->Dump(s);
-TypeList*
-Module::GetTypeList ()
-{
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- return &symbols->GetTypeList();
- return nullptr;
-}
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ symbols->Dump(s);
-const ConstString &
-Module::GetObjectName() const
-{
- return m_object_name;
+ s->IndentLess();
}
-ObjectFile *
-Module::GetObjectFile()
-{
- if (!m_did_load_objfile.load())
- {
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- if (!m_did_load_objfile.load())
- {
- 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)
- {
- 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());
- }
- }
- }
- }
- return m_objfile_sp.get();
+TypeList *Module::GetTypeList() {
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ return &symbols->GetTypeList();
+ return nullptr;
}
-SectionList *
-Module::GetSectionList()
-{
- // Populate m_unified_sections_ap with sections from objfile.
- if (!m_sections_ap)
- {
- ObjectFile *obj_file = GetObjectFile();
- if (obj_file != nullptr)
- obj_file->CreateSections(*GetUnifiedSectionList());
- }
- return m_sections_ap.get();
-}
-
-void
-Module::SectionFileAddressesChanged ()
-{
- ObjectFile *obj_file = GetObjectFile ();
- if (obj_file)
- obj_file->SectionFileAddressesChanged ();
- SymbolVendor* sym_vendor = GetSymbolVendor();
- if (sym_vendor != nullptr)
- sym_vendor->SectionFileAddressesChanged ();
-}
-
-SectionList *
-Module::GetUnifiedSectionList()
-{
- // Populate m_unified_sections_ap with sections from objfile.
- if (!m_sections_ap)
- m_sections_ap.reset(new SectionList());
- return m_sections_ap.get();
-}
-
-const Symbol *
-Module::FindFirstSymbolWithNameAndType (const ConstString &name, SymbolType symbol_type)
-{
- Timer scoped_timer(__PRETTY_FUNCTION__,
- "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
- name.AsCString(),
- symbol_type);
- SymbolVendor* sym_vendor = GetSymbolVendor();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- return symtab->FindFirstSymbolWithNameAndType (name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
- }
- return nullptr;
-}
-void
-Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
-{
- // No need to protect this call using m_mutex all other method calls are
- // already thread safe.
+const ConstString &Module::GetObjectName() const { return m_object_name; }
- size_t num_indices = symbol_indexes.size();
- if (num_indices > 0)
- {
- SymbolContext sc;
- CalculateSymbolContext (&sc);
- for (size_t i = 0; i < num_indices; i++)
- {
- sc.symbol = symtab->SymbolAtIndex (symbol_indexes[i]);
- if (sc.symbol)
- sc_list.Append (sc);
+ObjectFile *Module::GetObjectFile() {
+ if (!m_did_load_objfile.load()) {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ if (!m_did_load_objfile.load()) {
+ Timer scoped_timer(LLVM_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) {
+ 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());
}
+ }
}
+ }
+ return m_objfile_sp.get();
}
-size_t
-Module::FindFunctionSymbols (const ConstString &name,
- uint32_t name_type_mask,
- SymbolContextList& sc_list)
-{
- Timer scoped_timer(__PRETTY_FUNCTION__,
- "Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
- name.AsCString(),
- name_type_mask);
- SymbolVendor* sym_vendor = GetSymbolVendor();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- return symtab->FindFunctionSymbols (name, name_type_mask, sc_list);
+SectionList *Module::GetSectionList() {
+ // Populate m_unified_sections_ap with sections from objfile.
+ if (!m_sections_ap) {
+ ObjectFile *obj_file = GetObjectFile();
+ if (obj_file != nullptr)
+ obj_file->CreateSections(*GetUnifiedSectionList());
+ }
+ return m_sections_ap.get();
+}
+
+void Module::SectionFileAddressesChanged() {
+ ObjectFile *obj_file = GetObjectFile();
+ if (obj_file)
+ obj_file->SectionFileAddressesChanged();
+ SymbolVendor *sym_vendor = GetSymbolVendor();
+ if (sym_vendor != nullptr)
+ sym_vendor->SectionFileAddressesChanged();
+}
+
+SectionList *Module::GetUnifiedSectionList() {
+ // Populate m_unified_sections_ap with sections from objfile.
+ if (!m_sections_ap)
+ m_sections_ap.reset(new SectionList());
+ return m_sections_ap.get();
+}
+
+const Symbol *Module::FindFirstSymbolWithNameAndType(const ConstString &name,
+ SymbolType symbol_type) {
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION,
+ "Module::FindFirstSymbolWithNameAndType (name = %s, type = %i)",
+ name.AsCString(), symbol_type);
+ SymbolVendor *sym_vendor = GetSymbolVendor();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab)
+ return symtab->FindFirstSymbolWithNameAndType(
+ name, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny);
+ }
+ return nullptr;
+}
+void Module::SymbolIndicesToSymbolContextList(
+ Symtab *symtab, std::vector<uint32_t> &symbol_indexes,
+ SymbolContextList &sc_list) {
+ // No need to protect this call using m_mutex all other method calls are
+ // already thread safe.
+
+ size_t num_indices = symbol_indexes.size();
+ if (num_indices > 0) {
+ SymbolContext sc;
+ CalculateSymbolContext(&sc);
+ for (size_t i = 0; i < num_indices; i++) {
+ sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
+ if (sc.symbol)
+ sc_list.Append(sc);
}
- return 0;
-}
-
-size_t
-Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
-{
- // No need to protect this call using m_mutex all other method calls are
- // already thread safe.
-
- Timer scoped_timer(__PRETTY_FUNCTION__,
- "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
- name.AsCString(),
- symbol_type);
- const size_t initial_size = sc_list.GetSize();
- SymbolVendor* sym_vendor = GetSymbolVendor();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- {
- std::vector<uint32_t> symbol_indexes;
- symtab->FindAllSymbolsWithNameAndType (name, symbol_type, symbol_indexes);
- SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
- }
+ }
+}
+
+size_t Module::FindFunctionSymbols(const ConstString &name,
+ uint32_t name_type_mask,
+ SymbolContextList &sc_list) {
+ Timer scoped_timer(LLVM_PRETTY_FUNCTION,
+ "Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
+ name.AsCString(), name_type_mask);
+ SymbolVendor *sym_vendor = GetSymbolVendor();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab)
+ return symtab->FindFunctionSymbols(name, name_type_mask, sc_list);
+ }
+ return 0;
+}
+
+size_t Module::FindSymbolsWithNameAndType(const ConstString &name,
+ SymbolType symbol_type,
+ SymbolContextList &sc_list) {
+ // No need to protect this call using m_mutex all other method calls are
+ // already thread safe.
+
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION,
+ "Module::FindSymbolsWithNameAndType (name = %s, type = %i)",
+ name.AsCString(), symbol_type);
+ const size_t initial_size = sc_list.GetSize();
+ SymbolVendor *sym_vendor = GetSymbolVendor();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab) {
+ std::vector<uint32_t> symbol_indexes;
+ symtab->FindAllSymbolsWithNameAndType(name, symbol_type, symbol_indexes);
+ SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
}
- return sc_list.GetSize() - initial_size;
-}
-
-size_t
-Module::FindSymbolsMatchingRegExAndType (const RegularExpression &regex, SymbolType symbol_type, SymbolContextList &sc_list)
-{
- // No need to protect this call using m_mutex all other method calls are
- // already thread safe.
-
- Timer scoped_timer(__PRETTY_FUNCTION__,
- "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
- regex.GetText(),
- symbol_type);
- const size_t initial_size = sc_list.GetSize();
- SymbolVendor* sym_vendor = GetSymbolVendor();
- if (sym_vendor)
- {
- Symtab *symtab = sym_vendor->GetSymtab();
- if (symtab)
- {
- std::vector<uint32_t> symbol_indexes;
- symtab->FindAllSymbolsMatchingRexExAndType (regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny, symbol_indexes);
- SymbolIndicesToSymbolContextList (symtab, symbol_indexes, sc_list);
- }
+ }
+ return sc_list.GetSize() - initial_size;
+}
+
+size_t Module::FindSymbolsMatchingRegExAndType(const RegularExpression &regex,
+ SymbolType symbol_type,
+ SymbolContextList &sc_list) {
+ // No need to protect this call using m_mutex all other method calls are
+ // already thread safe.
+
+ Timer scoped_timer(
+ LLVM_PRETTY_FUNCTION,
+ "Module::FindSymbolsMatchingRegExAndType (regex = %s, type = %i)",
+ regex.GetText().str().c_str(), symbol_type);
+ const size_t initial_size = sc_list.GetSize();
+ SymbolVendor *sym_vendor = GetSymbolVendor();
+ if (sym_vendor) {
+ Symtab *symtab = sym_vendor->GetSymtab();
+ if (symtab) {
+ std::vector<uint32_t> symbol_indexes;
+ symtab->FindAllSymbolsMatchingRexExAndType(
+ regex, symbol_type, Symtab::eDebugAny, Symtab::eVisibilityAny,
+ symbol_indexes);
+ SymbolIndicesToSymbolContextList(symtab, symbol_indexes, sc_list);
}
- return sc_list.GetSize() - initial_size;
+ }
+ return sc_list.GetSize() - initial_size;
}
-void
-Module::SetSymbolFileFileSpec (const FileSpec &file)
-{
- if (!file.Exists())
- return;
- if (m_symfile_ap)
- {
- // Remove any sections in the unified section list that come from the current symbol vendor.
- SectionList *section_list = GetSectionList();
- SymbolFile *symbol_file = m_symfile_ap->GetSymbolFile();
- if (section_list && symbol_file)
- {
- ObjectFile *obj_file = symbol_file->GetObjectFile();
- // Make sure we have an object file and that the symbol vendor's objfile isn't
- // the same as the module's objfile before we remove any sections for it...
- if (obj_file)
- {
- // Check to make sure we aren't trying to specify the file we already have
- if (obj_file->GetFileSpec() == file)
- {
- // We are being told to add the exact same file that we already have
- // 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
- // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to check this
-
- if (file.IsDirectory())
- {
- std::string new_path(file.GetPath());
- std::string old_path(obj_file->GetFileSpec().GetPath());
- if (old_path.find(new_path) == 0)
- {
- // We specified the same bundle as the symbol file that we already have
- return;
- }
- }
-
- if (obj_file != m_objfile_sp.get())
- {
- size_t num_sections = section_list->GetNumSections (0);
- for (size_t idx = num_sections; idx > 0; --idx)
- {
- lldb::SectionSP section_sp (section_list->GetSectionAtIndex (idx - 1));
- if (section_sp->GetObjectFile() == obj_file)
- {
- section_list->DeleteSection (idx - 1);
- }
- }
- }
- }
+void Module::SetSymbolFileFileSpec(const FileSpec &file) {
+ if (!file.Exists())
+ return;
+ if (m_symfile_ap) {
+ // Remove any sections in the unified section list that come from the
+ // current symbol vendor.
+ SectionList *section_list = GetSectionList();
+ SymbolFile *symbol_file = m_symfile_ap->GetSymbolFile();
+ if (section_list && symbol_file) {
+ ObjectFile *obj_file = symbol_file->GetObjectFile();
+ // Make sure we have an object file and that the symbol vendor's objfile
+ // isn't
+ // the same as the module's objfile before we remove any sections for
+ // it...
+ if (obj_file) {
+ // Check to make sure we aren't trying to specify the file we already
+ // have
+ if (obj_file->GetFileSpec() == file) {
+ // We are being told to add the exact same file that we already have
+ // we don't have to do anything.
+ return;
}
- // Keep all old symbol files around in case there are any lingering type references in
- // any SBValue objects that might have been handed out.
- m_old_symfiles.push_back(std::move(m_symfile_ap));
- }
- m_symfile_spec = file;
- m_symfile_ap.reset();
- m_did_load_symbol_vendor = false;
-}
-bool
-Module::IsExecutable ()
-{
- if (GetObjectFile() == nullptr)
- return false;
- else
- return GetObjectFile()->IsExecutable();
-}
+ // 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
+ // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to
+ // check this
+
+ if (file.IsDirectory()) {
+ std::string new_path(file.GetPath());
+ std::string old_path(obj_file->GetFileSpec().GetPath());
+ if (old_path.find(new_path) == 0) {
+ // We specified the same bundle as the symbol file that we already
+ // have
+ return;
+ }
+ }
-bool
-Module::IsLoadedInTarget (Target *target)
-{
- ObjectFile *obj_file = GetObjectFile();
- if (obj_file)
- {
- SectionList *sections = GetSectionList();
- if (sections != nullptr)
- {
- size_t num_sections = sections->GetSize();
- for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++)
- {
- SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
- if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS)
- {
- return true;
- }
+ if (obj_file != m_objfile_sp.get()) {
+ size_t num_sections = section_list->GetNumSections(0);
+ for (size_t idx = num_sections; idx > 0; --idx) {
+ lldb::SectionSP section_sp(
+ section_list->GetSectionAtIndex(idx - 1));
+ if (section_sp->GetObjectFile() == obj_file) {
+ section_list->DeleteSection(idx - 1);
}
+ }
}
+ }
}
+ // Keep all old symbol files around in case there are any lingering type
+ // references in
+ // any SBValue objects that might have been handed out.
+ m_old_symfiles.push_back(std::move(m_symfile_ap));
+ }
+ m_symfile_spec = file;
+ m_symfile_ap.reset();
+ m_did_load_symbol_vendor = false;
+}
+
+bool Module::IsExecutable() {
+ if (GetObjectFile() == nullptr)
return false;
+ else
+ return GetObjectFile()->IsExecutable();
+}
+
+bool Module::IsLoadedInTarget(Target *target) {
+ ObjectFile *obj_file = GetObjectFile();
+ if (obj_file) {
+ SectionList *sections = GetSectionList();
+ if (sections != nullptr) {
+ size_t num_sections = sections->GetSize();
+ for (size_t sect_idx = 0; sect_idx < num_sections; sect_idx++) {
+ SectionSP section_sp = sections->GetSectionAtIndex(sect_idx);
+ if (section_sp->GetLoadBaseAddress(target) != LLDB_INVALID_ADDRESS) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
}
-bool
-Module::LoadScriptingResourceInTarget (Target *target, Error& error, Stream* feedback_stream)
-{
- if (!target)
- {
- error.SetErrorString("invalid destination Target");
- return false;
- }
-
- LoadScriptFromSymFile should_load = target->TargetProperties::GetLoadScriptFromSymbolFile();
-
- if (should_load == eLoadScriptFromSymFileFalse)
- return false;
-
- Debugger &debugger = target->GetDebugger();
- const ScriptLanguage script_language = debugger.GetScriptLanguage();
- if (script_language != eScriptLanguageNone)
- {
-
- PlatformSP platform_sp(target->GetPlatform());
-
- if (!platform_sp)
- {
- error.SetErrorString("invalid Platform");
- return false;
- }
+bool Module::LoadScriptingResourceInTarget(Target *target, Error &error,
+ Stream *feedback_stream) {
+ if (!target) {
+ error.SetErrorString("invalid destination Target");
+ return false;
+ }
- FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources (target,
- *this,
- feedback_stream);
+ LoadScriptFromSymFile should_load =
+ target->TargetProperties::GetLoadScriptFromSymbolFile();
- const uint32_t num_specs = file_specs.GetSize();
- if (num_specs)
- {
- ScriptInterpreter *script_interpreter = debugger.GetCommandInterpreter().GetScriptInterpreter();
- if (script_interpreter)
- {
- for (uint32_t i = 0; i < num_specs; ++i)
- {
- FileSpec scripting_fspec (file_specs.GetFileSpecAtIndex(i));
- if (scripting_fspec && scripting_fspec.Exists())
- {
- if (should_load == eLoadScriptFromSymFileWarn)
- {
- if (feedback_stream)
- feedback_stream->Printf("warning: '%s' contains a debug script. To run this script in "
- "this debug session:\n\n command script import \"%s\"\n\n"
- "To run all discovered debug scripts in this session:\n\n"
- " settings set target.load-script-from-symbol-file true\n",
- GetFileSpec().GetFileNameStrippingExtension().GetCString(),
- scripting_fspec.GetPath().c_str());
- return false;
- }
- StreamString scripting_stream;
- scripting_fspec.Dump(&scripting_stream);
- const bool can_reload = true;
- const bool init_lldb_globals = false;
- bool did_load = script_interpreter->LoadScriptingModule(scripting_stream.GetData(),
- can_reload,
- init_lldb_globals,
- error);
- if (!did_load)
- return false;
- }
- }
- }
- else
- {
- error.SetErrorString("invalid ScriptInterpreter");
- return false;
+ if (should_load == eLoadScriptFromSymFileFalse)
+ return false;
+
+ Debugger &debugger = target->GetDebugger();
+ const ScriptLanguage script_language = debugger.GetScriptLanguage();
+ if (script_language != eScriptLanguageNone) {
+
+ PlatformSP platform_sp(target->GetPlatform());
+
+ if (!platform_sp) {
+ error.SetErrorString("invalid Platform");
+ return false;
+ }
+
+ FileSpecList file_specs = platform_sp->LocateExecutableScriptingResources(
+ target, *this, feedback_stream);
+
+ const uint32_t num_specs = file_specs.GetSize();
+ if (num_specs) {
+ ScriptInterpreter *script_interpreter =
+ debugger.GetCommandInterpreter().GetScriptInterpreter();
+ if (script_interpreter) {
+ for (uint32_t i = 0; i < num_specs; ++i) {
+ FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i));
+ if (scripting_fspec && scripting_fspec.Exists()) {
+ if (should_load == eLoadScriptFromSymFileWarn) {
+ if (feedback_stream)
+ feedback_stream->Printf(
+ "warning: '%s' contains a debug script. To run this script "
+ "in "
+ "this debug session:\n\n command script import "
+ "\"%s\"\n\n"
+ "To run all discovered debug scripts in this session:\n\n"
+ " settings set target.load-script-from-symbol-file "
+ "true\n",
+ GetFileSpec().GetFileNameStrippingExtension().GetCString(),
+ scripting_fspec.GetPath().c_str());
+ return false;
}
+ StreamString scripting_stream;
+ scripting_fspec.Dump(&scripting_stream);
+ const bool can_reload = true;
+ const bool init_lldb_globals = false;
+ bool did_load = script_interpreter->LoadScriptingModule(
+ scripting_stream.GetData(), can_reload, init_lldb_globals,
+ error);
+ if (!did_load)
+ return false;
+ }
}
+ } else {
+ error.SetErrorString("invalid ScriptInterpreter");
+ return false;
+ }
}
- return true;
+ }
+ return true;
}
-bool
-Module::SetArchitecture (const ArchSpec &new_arch)
-{
- if (!m_arch.IsValid())
- {
- m_arch = new_arch;
- return true;
- }
- return m_arch.IsCompatibleMatch(new_arch);
+bool Module::SetArchitecture(const ArchSpec &new_arch) {
+ if (!m_arch.IsValid()) {
+ m_arch = new_arch;
+ return true;
+ }
+ return m_arch.IsCompatibleMatch(new_arch);
}
-bool
-Module::SetLoadAddress (Target &target, lldb::addr_t value, bool value_is_offset, bool &changed)
-{
- ObjectFile *object_file = GetObjectFile();
- if (object_file != nullptr)
- {
- changed = object_file->SetLoadAddress(target, value, value_is_offset);
- return true;
- }
- else
- {
- changed = false;
- }
- return false;
+bool Module::SetLoadAddress(Target &target, lldb::addr_t value,
+ bool value_is_offset, bool &changed) {
+ ObjectFile *object_file = GetObjectFile();
+ if (object_file != nullptr) {
+ changed = object_file->SetLoadAddress(target, value, value_is_offset);
+ return true;
+ } else {
+ changed = false;
+ }
+ return false;
}
+bool Module::MatchesModuleSpec(const ModuleSpec &module_ref) {
+ const UUID &uuid = module_ref.GetUUID();
-bool
-Module::MatchesModuleSpec (const ModuleSpec &module_ref)
-{
- const UUID &uuid = module_ref.GetUUID();
-
- if (uuid.IsValid())
- {
- // If the UUID matches, then nothing more needs to match...
- return (uuid == GetUUID());
- }
-
- const FileSpec &file_spec = module_ref.GetFileSpec();
- if (file_spec)
- {
- if (!FileSpec::Equal (file_spec, m_file, (bool)file_spec.GetDirectory()) &&
- !FileSpec::Equal (file_spec, m_platform_file, (bool)file_spec.GetDirectory()))
- return false;
- }
+ if (uuid.IsValid()) {
+ // If the UUID matches, then nothing more needs to match...
+ return (uuid == GetUUID());
+ }
- const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
- if (platform_file_spec)
- {
- if (!FileSpec::Equal (platform_file_spec, GetPlatformFileSpec (), (bool)platform_file_spec.GetDirectory()))
- return false;
- }
-
- const ArchSpec &arch = module_ref.GetArchitecture();
- if (arch.IsValid())
- {
- if (!m_arch.IsCompatibleMatch(arch))
- return false;
- }
-
- const ConstString &object_name = module_ref.GetObjectName();
- if (object_name)
- {
- if (object_name != GetObjectName())
- return false;
- }
- return true;
+ const FileSpec &file_spec = module_ref.GetFileSpec();
+ if (file_spec) {
+ if (!FileSpec::Equal(file_spec, m_file, (bool)file_spec.GetDirectory()) &&
+ !FileSpec::Equal(file_spec, m_platform_file,
+ (bool)file_spec.GetDirectory()))
+ return false;
+ }
+
+ const FileSpec &platform_file_spec = module_ref.GetPlatformFileSpec();
+ if (platform_file_spec) {
+ if (!FileSpec::Equal(platform_file_spec, GetPlatformFileSpec(),
+ (bool)platform_file_spec.GetDirectory()))
+ return false;
+ }
+
+ const ArchSpec &arch = module_ref.GetArchitecture();
+ if (arch.IsValid()) {
+ if (!m_arch.IsCompatibleMatch(arch))
+ return false;
+ }
+
+ const ConstString &object_name = module_ref.GetObjectName();
+ if (object_name) {
+ if (object_name != GetObjectName())
+ return false;
+ }
+ return true;
}
-bool
-Module::FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- return m_source_mappings.FindFile (orig_spec, new_spec);
+bool Module::FindSourceFile(const FileSpec &orig_spec,
+ FileSpec &new_spec) const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_source_mappings.FindFile(orig_spec, new_spec);
}
-bool
-Module::RemapSourceFile (const char *path, std::string &new_path) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_mutex);
- return m_source_mappings.RemapPath(path, new_path);
+bool Module::RemapSourceFile(llvm::StringRef path,
+ std::string &new_path) const {
+ std::lock_guard<std::recursive_mutex> guard(m_mutex);
+ return m_source_mappings.RemapPath(path, new_path);
}
-uint32_t
-Module::GetVersion (uint32_t *versions, uint32_t num_versions)
-{
- ObjectFile *obj_file = GetObjectFile();
- if (obj_file)
- return obj_file->GetVersion (versions, num_versions);
-
- if (versions != nullptr && num_versions != 0)
- {
- for (uint32_t i = 0; i < num_versions; ++i)
- versions[i] = LLDB_INVALID_MODULE_VERSION;
- }
- return 0;
+uint32_t Module::GetVersion(uint32_t *versions, uint32_t num_versions) {
+ ObjectFile *obj_file = GetObjectFile();
+ if (obj_file)
+ return obj_file->GetVersion(versions, num_versions);
+
+ if (versions != nullptr && num_versions != 0) {
+ for (uint32_t i = 0; i < num_versions; ++i)
+ versions[i] = LLDB_INVALID_MODULE_VERSION;
+ }
+ return 0;
}
ModuleSP
-Module::CreateJITModule (const lldb::ObjectFileJITDelegateSP &delegate_sp)
-{
- if (delegate_sp)
- {
- // Must create a module and place it into a shared pointer before
- // we can create an object file since it has a std::weak_ptr back
- // to the module, so we need to control the creation carefully in
- // this static function
- ModuleSP module_sp(new Module());
- module_sp->m_objfile_sp.reset (new ObjectFileJIT (module_sp, delegate_sp));
- if (module_sp->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.
- module_sp->m_objfile_sp->GetArchitecture (module_sp->m_arch);
- }
- return module_sp;
+Module::CreateJITModule(const lldb::ObjectFileJITDelegateSP &delegate_sp) {
+ if (delegate_sp) {
+ // Must create a module and place it into a shared pointer before
+ // we can create an object file since it has a std::weak_ptr back
+ // to the module, so we need to control the creation carefully in
+ // this static function
+ ModuleSP module_sp(new Module());
+ module_sp->m_objfile_sp.reset(new ObjectFileJIT(module_sp, delegate_sp));
+ if (module_sp->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.
+ module_sp->m_objfile_sp->GetArchitecture(module_sp->m_arch);
}
- return ModuleSP();
+ return module_sp;
+ }
+ return ModuleSP();
}
-bool
-Module::GetIsDynamicLinkEditor()
-{
- ObjectFile * obj_file = GetObjectFile ();
+bool Module::GetIsDynamicLinkEditor() {
+ ObjectFile *obj_file = GetObjectFile();
- if (obj_file)
- return obj_file->GetIsDynamicLinkEditor();
+ if (obj_file)
+ return obj_file->GetIsDynamicLinkEditor();
- return false;
+ return false;
}
diff --git a/source/Core/ModuleChild.cpp b/source/Core/ModuleChild.cpp
index 9637fc3aedda..86495742754d 100644
--- a/source/Core/ModuleChild.cpp
+++ b/source/Core/ModuleChild.cpp
@@ -11,36 +11,22 @@
using namespace lldb_private;
-ModuleChild::ModuleChild (const lldb::ModuleSP &module_sp) :
- m_module_wp (module_sp)
-{
-}
+ModuleChild::ModuleChild(const lldb::ModuleSP &module_sp)
+ : m_module_wp(module_sp) {}
-ModuleChild::ModuleChild (const ModuleChild& rhs) :
- m_module_wp(rhs.m_module_wp)
-{
-}
+ModuleChild::ModuleChild(const ModuleChild &rhs)
+ : m_module_wp(rhs.m_module_wp) {}
-ModuleChild::~ModuleChild()
-{
-}
+ModuleChild::~ModuleChild() {}
-const ModuleChild&
-ModuleChild::operator= (const ModuleChild& rhs)
-{
- if (this != &rhs)
- m_module_wp = rhs.m_module_wp;
- return *this;
+const ModuleChild &ModuleChild::operator=(const ModuleChild &rhs) {
+ if (this != &rhs)
+ m_module_wp = rhs.m_module_wp;
+ return *this;
}
-lldb::ModuleSP
-ModuleChild::GetModule () const
-{
- return m_module_wp.lock();
-}
+lldb::ModuleSP ModuleChild::GetModule() const { return m_module_wp.lock(); }
-void
-ModuleChild::SetModule (const lldb::ModuleSP &module_sp)
-{
- m_module_wp = module_sp;
+void ModuleChild::SetModule(const lldb::ModuleSP &module_sp) {
+ m_module_wp = module_sp;
}
diff --git a/source/Core/ModuleList.cpp b/source/Core/ModuleList.cpp
index bfd53e7d1c2c..b980e15c0b37 100644
--- a/source/Core/ModuleList.cpp
+++ b/source/Core/ModuleList.cpp
@@ -19,6 +19,7 @@
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -28,1131 +29,934 @@
using namespace lldb;
using namespace lldb_private;
-ModuleList::ModuleList() : m_modules(), m_modules_mutex(), m_notifier(nullptr)
-{
+ModuleList::ModuleList()
+ : m_modules(), m_modules_mutex(), m_notifier(nullptr) {}
+
+ModuleList::ModuleList(const ModuleList &rhs)
+ : m_modules(), m_modules_mutex(), m_notifier(nullptr) {
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
+ m_modules = rhs.m_modules;
+}
+
+ModuleList::ModuleList(ModuleList::Notifier *notifier)
+ : m_modules(), m_modules_mutex(), m_notifier(notifier) {}
+
+const ModuleList &ModuleList::operator=(const ModuleList &rhs) {
+ if (this != &rhs) {
+ // That's probably me nit-picking, but in theoretical situation:
+ //
+ // * that two threads A B and
+ // * two ModuleList's x y do opposite assignments ie.:
+ //
+ // in thread A: | in thread B:
+ // x = y; | y = x;
+ //
+ // This establishes correct(same) lock taking order and thus
+ // avoids priority inversion.
+ if (uintptr_t(this) > uintptr_t(&rhs)) {
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
+ m_modules = rhs.m_modules;
+ } else {
+ std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
+ std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
+ m_modules = rhs.m_modules;
+ }
+ }
+ return *this;
}
-ModuleList::ModuleList(const ModuleList &rhs) : m_modules(), m_modules_mutex(), m_notifier(nullptr)
-{
- std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
- std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
- m_modules = rhs.m_modules;
-}
-
-ModuleList::ModuleList(ModuleList::Notifier *notifier) : m_modules(), m_modules_mutex(), m_notifier(notifier)
-{
-}
+ModuleList::~ModuleList() = default;
-const ModuleList&
-ModuleList::operator= (const ModuleList& rhs)
-{
- if (this != &rhs)
- {
- // That's probably me nit-picking, but in theoretical situation:
- //
- // * that two threads A B and
- // * two ModuleList's x y do opposite assignments ie.:
- //
- // in thread A: | in thread B:
- // x = y; | y = x;
- //
- // This establishes correct(same) lock taking order and thus
- // avoids priority inversion.
- if (uintptr_t(this) > uintptr_t(&rhs))
- {
- std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
- std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
- m_modules = rhs.m_modules;
- }
- else
- {
- std::lock_guard<std::recursive_mutex> lhs_guard(m_modules_mutex);
- std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_modules_mutex);
- m_modules = rhs.m_modules;
- }
- }
- return *this;
+void ModuleList::AppendImpl(const ModuleSP &module_sp, bool use_notifier) {
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ m_modules.push_back(module_sp);
+ if (use_notifier && m_notifier)
+ m_notifier->ModuleAdded(*this, module_sp);
+ }
}
-ModuleList::~ModuleList() = default;
+void ModuleList::Append(const ModuleSP &module_sp) { AppendImpl(module_sp); }
-void
-ModuleList::AppendImpl (const ModuleSP &module_sp, bool use_notifier)
-{
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- m_modules.push_back(module_sp);
- if (use_notifier && m_notifier)
- m_notifier->ModuleAdded(*this, module_sp);
- }
-}
+void ModuleList::ReplaceEquivalent(const ModuleSP &module_sp) {
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
-void
-ModuleList::Append (const ModuleSP &module_sp)
-{
- AppendImpl (module_sp);
-}
+ // First remove any equivalent modules. Equivalent modules are modules
+ // whose path, platform path and architecture match.
+ ModuleSpec equivalent_module_spec(module_sp->GetFileSpec(),
+ module_sp->GetArchitecture());
+ equivalent_module_spec.GetPlatformFileSpec() =
+ module_sp->GetPlatformFileSpec();
-void
-ModuleList::ReplaceEquivalent (const ModuleSP &module_sp)
-{
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
-
- // First remove any equivalent modules. Equivalent modules are modules
- // whose path, platform path and architecture match.
- ModuleSpec equivalent_module_spec (module_sp->GetFileSpec(), module_sp->GetArchitecture());
- equivalent_module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
-
- size_t idx = 0;
- while (idx < m_modules.size())
- {
- ModuleSP module_sp (m_modules[idx]);
- if (module_sp->MatchesModuleSpec (equivalent_module_spec))
- RemoveImpl(m_modules.begin() + idx);
- else
- ++idx;
- }
- // Now add the new module to the list
- Append(module_sp);
+ size_t idx = 0;
+ while (idx < m_modules.size()) {
+ ModuleSP module_sp(m_modules[idx]);
+ if (module_sp->MatchesModuleSpec(equivalent_module_spec))
+ RemoveImpl(m_modules.begin() + idx);
+ else
+ ++idx;
}
+ // Now add the new module to the list
+ Append(module_sp);
+ }
}
-bool
-ModuleList::AppendIfNeeded (const ModuleSP &module_sp)
-{
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if (pos->get() == module_sp.get())
- return false; // Already in the list
- }
- // Only push module_sp on the list if it wasn't already in there.
- Append(module_sp);
- return true;
+bool ModuleList::AppendIfNeeded(const ModuleSP &module_sp) {
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if (pos->get() == module_sp.get())
+ return false; // Already in the list
}
- return false;
+ // Only push module_sp on the list if it wasn't already in there.
+ Append(module_sp);
+ return true;
+ }
+ return false;
}
-void
-ModuleList::Append (const ModuleList& module_list)
-{
- for (auto pos : module_list.m_modules)
- Append(pos);
+void ModuleList::Append(const ModuleList &module_list) {
+ for (auto pos : module_list.m_modules)
+ Append(pos);
}
-bool
-ModuleList::AppendIfNeeded (const ModuleList& module_list)
-{
- bool any_in = false;
- for (auto pos : module_list.m_modules)
- {
- if (AppendIfNeeded(pos))
- any_in = true;
- }
- return any_in;
+bool ModuleList::AppendIfNeeded(const ModuleList &module_list) {
+ bool any_in = false;
+ for (auto pos : module_list.m_modules) {
+ if (AppendIfNeeded(pos))
+ any_in = true;
+ }
+ return any_in;
}
-bool
-ModuleList::RemoveImpl (const ModuleSP &module_sp, bool use_notifier)
-{
- if (module_sp)
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if (pos->get() == module_sp.get())
- {
- m_modules.erase (pos);
- if (use_notifier && m_notifier)
- m_notifier->ModuleRemoved(*this, module_sp);
- return true;
- }
- }
+bool ModuleList::RemoveImpl(const ModuleSP &module_sp, bool use_notifier) {
+ if (module_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if (pos->get() == module_sp.get()) {
+ m_modules.erase(pos);
+ if (use_notifier && m_notifier)
+ m_notifier->ModuleRemoved(*this, module_sp);
+ return true;
+ }
}
- return false;
+ }
+ return false;
}
ModuleList::collection::iterator
-ModuleList::RemoveImpl (ModuleList::collection::iterator pos, bool use_notifier)
-{
- ModuleSP module_sp(*pos);
- collection::iterator retval = m_modules.erase(pos);
- if (use_notifier && m_notifier)
- m_notifier->ModuleRemoved(*this, module_sp);
- return retval;
+ModuleList::RemoveImpl(ModuleList::collection::iterator pos,
+ bool use_notifier) {
+ ModuleSP module_sp(*pos);
+ collection::iterator retval = m_modules.erase(pos);
+ if (use_notifier && m_notifier)
+ m_notifier->ModuleRemoved(*this, module_sp);
+ return retval;
}
-bool
-ModuleList::Remove (const ModuleSP &module_sp)
-{
- return RemoveImpl (module_sp);
+bool ModuleList::Remove(const ModuleSP &module_sp) {
+ return RemoveImpl(module_sp);
}
-bool
-ModuleList::ReplaceModule (const lldb::ModuleSP &old_module_sp, const lldb::ModuleSP &new_module_sp)
-{
- if (!RemoveImpl(old_module_sp, false))
- return false;
- AppendImpl (new_module_sp, false);
- if (m_notifier)
- m_notifier->ModuleUpdated(*this, old_module_sp,new_module_sp);
- return true;
-}
-
-bool
-ModuleList::RemoveIfOrphaned (const Module *module_ptr)
-{
- if (module_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if (pos->get() == module_ptr)
- {
- if (pos->unique())
- {
- pos = RemoveImpl(pos);
- return true;
- }
- else
- return false;
- }
- }
- }
+bool ModuleList::ReplaceModule(const lldb::ModuleSP &old_module_sp,
+ const lldb::ModuleSP &new_module_sp) {
+ if (!RemoveImpl(old_module_sp, false))
return false;
+ AppendImpl(new_module_sp, false);
+ if (m_notifier)
+ m_notifier->ModuleUpdated(*this, old_module_sp, new_module_sp);
+ return true;
}
-size_t
-ModuleList::RemoveOrphans (bool mandatory)
-{
- std::unique_lock<std::recursive_mutex> lock(m_modules_mutex, std::defer_lock);
-
- if (mandatory)
- {
- lock.lock();
- }
- else
- {
- // Not mandatory, remove orphans if we can get the mutex
- if (!lock.try_lock())
- return 0;
- }
- collection::iterator pos = m_modules.begin();
- size_t remove_count = 0;
- while (pos != m_modules.end())
- {
- if (pos->unique())
- {
- pos = RemoveImpl(pos);
- ++remove_count;
- }
- else
- {
- ++pos;
- }
- }
- return remove_count;
-}
-
-size_t
-ModuleList::Remove (ModuleList &module_list)
-{
+bool ModuleList::RemoveIfOrphaned(const Module *module_ptr) {
+ if (module_ptr) {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- size_t num_removed = 0;
- collection::iterator pos, end = module_list.m_modules.end();
- for (pos = module_list.m_modules.begin(); pos != end; ++pos)
- {
- if (Remove (*pos))
- ++num_removed;
+ collection::iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if (pos->get() == module_ptr) {
+ if (pos->unique()) {
+ pos = RemoveImpl(pos);
+ return true;
+ } else
+ return false;
+ }
}
- return num_removed;
+ }
+ return false;
}
+size_t ModuleList::RemoveOrphans(bool mandatory) {
+ std::unique_lock<std::recursive_mutex> lock(m_modules_mutex, std::defer_lock);
-void
-ModuleList::Clear()
-{
- ClearImpl();
+ if (mandatory) {
+ lock.lock();
+ } else {
+ // Not mandatory, remove orphans if we can get the mutex
+ if (!lock.try_lock())
+ return 0;
+ }
+ collection::iterator pos = m_modules.begin();
+ size_t remove_count = 0;
+ while (pos != m_modules.end()) {
+ if (pos->unique()) {
+ pos = RemoveImpl(pos);
+ ++remove_count;
+ } else {
+ ++pos;
+ }
+ }
+ return remove_count;
}
-void
-ModuleList::Destroy()
-{
- ClearImpl();
+size_t ModuleList::Remove(ModuleList &module_list) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ size_t num_removed = 0;
+ collection::iterator pos, end = module_list.m_modules.end();
+ for (pos = module_list.m_modules.begin(); pos != end; ++pos) {
+ if (Remove(*pos))
+ ++num_removed;
+ }
+ return num_removed;
}
-void
-ModuleList::ClearImpl (bool use_notifier)
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- if (use_notifier && m_notifier)
- m_notifier->WillClearList(*this);
- m_modules.clear();
-}
+void ModuleList::Clear() { ClearImpl(); }
-Module*
-ModuleList::GetModulePointerAtIndex (size_t idx) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- return GetModulePointerAtIndexUnlocked(idx);
-}
+void ModuleList::Destroy() { ClearImpl(); }
-Module*
-ModuleList::GetModulePointerAtIndexUnlocked (size_t idx) const
-{
- if (idx < m_modules.size())
- return m_modules[idx].get();
- return nullptr;
+void ModuleList::ClearImpl(bool use_notifier) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ if (use_notifier && m_notifier)
+ m_notifier->WillClearList(*this);
+ m_modules.clear();
}
-ModuleSP
-ModuleList::GetModuleAtIndex(size_t idx) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- return GetModuleAtIndexUnlocked(idx);
+Module *ModuleList::GetModulePointerAtIndex(size_t idx) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ return GetModulePointerAtIndexUnlocked(idx);
}
-ModuleSP
-ModuleList::GetModuleAtIndexUnlocked(size_t idx) const
-{
- ModuleSP module_sp;
- if (idx < m_modules.size())
- module_sp = m_modules[idx];
- return module_sp;
+Module *ModuleList::GetModulePointerAtIndexUnlocked(size_t idx) const {
+ if (idx < m_modules.size())
+ return m_modules[idx].get();
+ return nullptr;
}
-size_t
-ModuleList::FindFunctions (const ConstString &name,
- uint32_t name_type_mask,
- bool include_symbols,
- bool include_inlines,
- bool append,
- SymbolContextList &sc_list) const
-{
- if (!append)
- sc_list.Clear();
-
- const size_t old_size = sc_list.GetSize();
-
- if (name_type_mask & eFunctionNameTypeAuto)
- {
- Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
-
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindFunctions(lookup_info.GetLookupName(),
- nullptr,
- lookup_info.GetNameTypeMask(),
- include_symbols,
- include_inlines,
- true,
- sc_list);
- }
-
- const size_t new_size = sc_list.GetSize();
-
- if (old_size < new_size)
- lookup_info.Prune (sc_list, old_size);
- }
- else
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindFunctions(name, nullptr, name_type_mask, include_symbols, include_inlines, true, sc_list);
- }
- }
- return sc_list.GetSize() - old_size;
+ModuleSP ModuleList::GetModuleAtIndex(size_t idx) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ return GetModuleAtIndexUnlocked(idx);
}
-size_t
-ModuleList::FindFunctionSymbols (const ConstString &name,
- uint32_t name_type_mask,
- SymbolContextList& sc_list)
-{
- const size_t old_size = sc_list.GetSize();
-
- if (name_type_mask & eFunctionNameTypeAuto)
- {
- Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
-
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindFunctionSymbols (lookup_info.GetLookupName(),
- lookup_info.GetNameTypeMask(),
- sc_list);
- }
+ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const {
+ ModuleSP module_sp;
+ if (idx < m_modules.size())
+ module_sp = m_modules[idx];
+ return module_sp;
+}
+size_t ModuleList::FindFunctions(const ConstString &name,
+ uint32_t name_type_mask, bool include_symbols,
+ bool include_inlines, bool append,
+ SymbolContextList &sc_list) const {
+ if (!append)
+ sc_list.Clear();
- const size_t new_size = sc_list.GetSize();
+ const size_t old_size = sc_list.GetSize();
- if (old_size < new_size)
- lookup_info.Prune (sc_list, old_size);
- }
- else
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindFunctionSymbols (name, name_type_mask, sc_list);
- }
- }
-
- return sc_list.GetSize() - old_size;
-}
-
-size_t
-ModuleList::FindFunctions(const RegularExpression &name,
- bool include_symbols,
- bool include_inlines,
- bool append,
- SymbolContextList& sc_list)
-{
- const size_t old_size = sc_list.GetSize();
+ if (name_type_mask & eFunctionNameTypeAuto) {
+ Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindFunctions (name, include_symbols, include_inlines, append, sc_list);
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindFunctions(lookup_info.GetLookupName(), nullptr,
+ lookup_info.GetNameTypeMask(), include_symbols,
+ include_inlines, true, sc_list);
}
- return sc_list.GetSize() - old_size;
-}
-
-size_t
-ModuleList::FindCompileUnits (const FileSpec &path,
- bool append,
- SymbolContextList &sc_list) const
-{
- if (!append)
- sc_list.Clear();
+ const size_t new_size = sc_list.GetSize();
+ if (old_size < new_size)
+ lookup_info.Prune(sc_list, old_size);
+ } else {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindCompileUnits (path, true, sc_list);
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindFunctions(name, nullptr, name_type_mask, include_symbols,
+ include_inlines, true, sc_list);
}
-
- return sc_list.GetSize();
+ }
+ return sc_list.GetSize() - old_size;
}
-size_t
-ModuleList::FindGlobalVariables (const ConstString &name,
- bool append,
- size_t max_matches,
- VariableList& variable_list) const
-{
- size_t initial_size = variable_list.GetSize();
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindGlobalVariables(name, nullptr, append, max_matches, variable_list);
- }
- return variable_list.GetSize() - initial_size;
-}
+size_t ModuleList::FindFunctionSymbols(const ConstString &name,
+ uint32_t name_type_mask,
+ SymbolContextList &sc_list) {
+ const size_t old_size = sc_list.GetSize();
+
+ if (name_type_mask & eFunctionNameTypeAuto) {
+ Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown);
-size_t
-ModuleList::FindGlobalVariables (const RegularExpression& regex,
- bool append,
- size_t max_matches,
- VariableList& variable_list) const
-{
- size_t initial_size = variable_list.GetSize();
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindGlobalVariables (regex, append, max_matches, variable_list);
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindFunctionSymbols(lookup_info.GetLookupName(),
+ lookup_info.GetNameTypeMask(), sc_list);
}
- return variable_list.GetSize() - initial_size;
-}
-size_t
-ModuleList::FindSymbolsWithNameAndType (const ConstString &name,
- SymbolType symbol_type,
- SymbolContextList &sc_list,
- bool append) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- if (!append)
- sc_list.Clear();
- size_t initial_size = sc_list.GetSize();
-
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- (*pos)->FindSymbolsWithNameAndType (name, symbol_type, sc_list);
- return sc_list.GetSize() - initial_size;
-}
+ const size_t new_size = sc_list.GetSize();
-size_t
-ModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression &regex,
- lldb::SymbolType symbol_type,
- SymbolContextList &sc_list,
- bool append) const
-{
+ if (old_size < new_size)
+ lookup_info.Prune(sc_list, old_size);
+ } else {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- if (!append)
- sc_list.Clear();
- size_t initial_size = sc_list.GetSize();
-
collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- (*pos)->FindSymbolsMatchingRegExAndType (regex, symbol_type, sc_list);
- return sc_list.GetSize() - initial_size;
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindFunctionSymbols(name, name_type_mask, sc_list);
+ }
+ }
+
+ return sc_list.GetSize() - old_size;
+}
+
+size_t ModuleList::FindFunctions(const RegularExpression &name,
+ bool include_symbols, bool include_inlines,
+ bool append, SymbolContextList &sc_list) {
+ const size_t old_size = sc_list.GetSize();
+
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindFunctions(name, include_symbols, include_inlines, append,
+ sc_list);
+ }
+
+ return sc_list.GetSize() - old_size;
+}
+
+size_t ModuleList::FindCompileUnits(const FileSpec &path, bool append,
+ SymbolContextList &sc_list) const {
+ if (!append)
+ sc_list.Clear();
+
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindCompileUnits(path, true, sc_list);
+ }
+
+ return sc_list.GetSize();
+}
+
+size_t ModuleList::FindGlobalVariables(const ConstString &name, bool append,
+ size_t max_matches,
+ VariableList &variable_list) const {
+ size_t initial_size = variable_list.GetSize();
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindGlobalVariables(name, nullptr, append, max_matches,
+ variable_list);
+ }
+ return variable_list.GetSize() - initial_size;
+}
+
+size_t ModuleList::FindGlobalVariables(const RegularExpression &regex,
+ bool append, size_t max_matches,
+ VariableList &variable_list) const {
+ size_t initial_size = variable_list.GetSize();
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindGlobalVariables(regex, append, max_matches, variable_list);
+ }
+ return variable_list.GetSize() - initial_size;
+}
+
+size_t ModuleList::FindSymbolsWithNameAndType(const ConstString &name,
+ SymbolType symbol_type,
+ SymbolContextList &sc_list,
+ bool append) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ if (!append)
+ sc_list.Clear();
+ size_t initial_size = sc_list.GetSize();
+
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos)
+ (*pos)->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
+ return sc_list.GetSize() - initial_size;
+}
+
+size_t ModuleList::FindSymbolsMatchingRegExAndType(
+ const RegularExpression &regex, lldb::SymbolType symbol_type,
+ SymbolContextList &sc_list, bool append) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ if (!append)
+ sc_list.Clear();
+ size_t initial_size = sc_list.GetSize();
+
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos)
+ (*pos)->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list);
+ return sc_list.GetSize() - initial_size;
+}
+
+size_t ModuleList::FindModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) const {
+ size_t existing_matches = matching_module_list.GetSize();
+
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ ModuleSP module_sp(*pos);
+ if (module_sp->MatchesModuleSpec(module_spec))
+ matching_module_list.Append(module_sp);
+ }
+ return matching_module_list.GetSize() - existing_matches;
}
-size_t
-ModuleList::FindModules (const ModuleSpec &module_spec, ModuleList& matching_module_list) const
-{
- size_t existing_matches = matching_module_list.GetSize();
+ModuleSP ModuleList::FindModule(const Module *module_ptr) const {
+ ModuleSP module_sp;
+ // Scope for "locker"
+ {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- ModuleSP module_sp(*pos);
- if (module_sp->MatchesModuleSpec (module_spec))
- matching_module_list.Append(module_sp);
- }
- return matching_module_list.GetSize() - existing_matches;
-}
-ModuleSP
-ModuleList::FindModule (const Module *module_ptr) const
-{
- ModuleSP module_sp;
-
- // Scope for "locker"
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
-
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if ((*pos).get() == module_ptr)
- {
- module_sp = (*pos);
- break;
- }
- }
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if ((*pos).get() == module_ptr) {
+ module_sp = (*pos);
+ break;
+ }
}
- return module_sp;
+ }
+ return module_sp;
}
-ModuleSP
-ModuleList::FindModule (const UUID &uuid) const
-{
- ModuleSP module_sp;
-
- if (uuid.IsValid())
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
-
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if ((*pos)->GetUUID() == uuid)
- {
- module_sp = (*pos);
- break;
- }
- }
- }
- return module_sp;
-}
+ModuleSP ModuleList::FindModule(const UUID &uuid) const {
+ ModuleSP module_sp;
-size_t
-ModuleList::FindTypes (const SymbolContext& sc, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeList& types) const
-{
+ if (uuid.IsValid()) {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
-
- size_t total_matches = 0;
collection::const_iterator pos, end = m_modules.end();
- if (sc.module_sp)
- {
- // The symbol context "sc" contains a module so we want to search that
- // one first if it is in our list...
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if (sc.module_sp.get() == (*pos).get())
- {
- total_matches += (*pos)->FindTypes (sc, name, name_is_fully_qualified, max_matches, searched_symbol_files, types);
-
- if (total_matches >= max_matches)
- break;
- }
- }
- }
-
- if (total_matches < max_matches)
- {
- SymbolContext world_sc;
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- // 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 comparison will always be true (valid_module_ptr != nullptr).
- if (sc.module_sp.get() != (*pos).get())
- total_matches += (*pos)->FindTypes (world_sc, name, name_is_fully_qualified, max_matches, searched_symbol_files, types);
-
- if (total_matches >= max_matches)
- break;
- }
- }
-
- return total_matches;
-}
-bool
-ModuleList::FindSourceFile (const FileSpec &orig_spec, FileSpec &new_spec) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if ((*pos)->FindSourceFile (orig_spec, new_spec))
- return true;
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if ((*pos)->GetUUID() == uuid) {
+ module_sp = (*pos);
+ break;
+ }
}
- return false;
-}
-
-void
-ModuleList::FindAddressesForLine (const lldb::TargetSP target_sp,
- const FileSpec &file, uint32_t line,
- Function *function,
- std::vector<Address> &output_local, std::vector<Address> &output_extern)
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->FindAddressesForLine(target_sp, file, line, function, output_local, output_extern);
- }
-}
-
-ModuleSP
-ModuleList::FindFirstModule (const ModuleSpec &module_spec) const
-{
- ModuleSP module_sp;
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- ModuleSP module_sp(*pos);
- if (module_sp->MatchesModuleSpec (module_spec))
- return module_sp;
- }
- return module_sp;
-
+ }
+ return module_sp;
}
size_t
-ModuleList::GetSize() const
-{
- size_t size = 0;
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- size = m_modules.size();
- }
- return size;
+ModuleList::FindTypes(const SymbolContext &sc, const ConstString &name,
+ bool name_is_fully_qualified, size_t max_matches,
+ llvm::DenseSet<SymbolFile *> &searched_symbol_files,
+ TypeList &types) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+
+ size_t total_matches = 0;
+ collection::const_iterator pos, end = m_modules.end();
+ if (sc.module_sp) {
+ // The symbol context "sc" contains a module so we want to search that
+ // one first if it is in our list...
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if (sc.module_sp.get() == (*pos).get()) {
+ total_matches +=
+ (*pos)->FindTypes(sc, name, name_is_fully_qualified, max_matches,
+ searched_symbol_files, types);
+
+ if (total_matches >= max_matches)
+ break;
+ }
+ }
+ }
+
+ if (total_matches < max_matches) {
+ SymbolContext world_sc;
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ // 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 comparison will always be true (valid_module_ptr != nullptr).
+ if (sc.module_sp.get() != (*pos).get())
+ total_matches +=
+ (*pos)->FindTypes(world_sc, name, name_is_fully_qualified,
+ max_matches, searched_symbol_files, types);
+
+ if (total_matches >= max_matches)
+ break;
+ }
+ }
+
+ return total_matches;
+}
+
+bool ModuleList::FindSourceFile(const FileSpec &orig_spec,
+ FileSpec &new_spec) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if ((*pos)->FindSourceFile(orig_spec, new_spec))
+ return true;
+ }
+ return false;
+}
+
+void ModuleList::FindAddressesForLine(const lldb::TargetSP target_sp,
+ const FileSpec &file, uint32_t line,
+ Function *function,
+ std::vector<Address> &output_local,
+ std::vector<Address> &output_extern) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->FindAddressesForLine(target_sp, file, line, function, output_local,
+ output_extern);
+ }
+}
+
+ModuleSP ModuleList::FindFirstModule(const ModuleSpec &module_spec) const {
+ ModuleSP module_sp;
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ ModuleSP module_sp(*pos);
+ if (module_sp->MatchesModuleSpec(module_spec))
+ return module_sp;
+ }
+ return module_sp;
}
-void
-ModuleList::Dump(Stream *s) const
-{
- // s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
- // s.Indent();
- // s << "ModuleList\n";
-
+size_t ModuleList::GetSize() const {
+ size_t size = 0;
+ {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->Dump(s);
- }
+ size = m_modules.size();
+ }
+ return size;
}
-void
-ModuleList::LogUUIDAndPaths (Log *log, const char *prefix_cstr)
-{
- if (log != nullptr)
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, begin = m_modules.begin(), end = m_modules.end();
- for (pos = begin; pos != end; ++pos)
- {
- Module *module = pos->get();
- const FileSpec &module_file_spec = module->GetFileSpec();
- log->Printf ("%s[%u] %s (%s) \"%s\"",
- prefix_cstr ? prefix_cstr : "",
- (uint32_t)std::distance (begin, pos),
- module->GetUUID().GetAsString().c_str(),
- module->GetArchitecture().GetArchitectureName(),
- module_file_spec.GetPath().c_str());
- }
- }
+void ModuleList::Dump(Stream *s) const {
+ // s.Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+ // s.Indent();
+ // s << "ModuleList\n";
+
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->Dump(s);
+ }
}
-bool
-ModuleList::ResolveFileAddress (lldb::addr_t vm_addr, Address& so_addr) const
-{
+void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) {
+ if (log != nullptr) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, begin = m_modules.begin(),
+ end = m_modules.end();
+ for (pos = begin; pos != end; ++pos) {
+ Module *module = pos->get();
+ const FileSpec &module_file_spec = module->GetFileSpec();
+ log->Printf("%s[%u] %s (%s) \"%s\"", prefix_cstr ? prefix_cstr : "",
+ (uint32_t)std::distance(begin, pos),
+ module->GetUUID().GetAsString().c_str(),
+ module->GetArchitecture().GetArchitectureName(),
+ module_file_spec.GetPath().c_str());
+ }
+ }
+}
+
+bool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr,
+ Address &so_addr) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if ((*pos)->ResolveFileAddress(vm_addr, so_addr))
+ return true;
+ }
+
+ return false;
+}
+
+uint32_t ModuleList::ResolveSymbolContextForAddress(const Address &so_addr,
+ uint32_t resolve_scope,
+ SymbolContext &sc) const {
+ // The address is already section offset so it has a module
+ uint32_t resolved_flags = 0;
+ ModuleSP module_sp(so_addr.GetModule());
+ if (module_sp) {
+ resolved_flags =
+ module_sp->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
+ } else {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if ((*pos)->ResolveFileAddress (vm_addr, so_addr))
- return true;
- }
-
- return false;
-}
-
-uint32_t
-ModuleList::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc) const
-{
- // The address is already section offset so it has a module
- uint32_t resolved_flags = 0;
- ModuleSP module_sp (so_addr.GetModule());
- if (module_sp)
- {
- resolved_flags = module_sp->ResolveSymbolContextForAddress (so_addr,
- resolve_scope,
- sc);
- }
- else
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- resolved_flags = (*pos)->ResolveSymbolContextForAddress (so_addr,
- resolve_scope,
- sc);
- if (resolved_flags != 0)
- break;
- }
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ resolved_flags =
+ (*pos)->ResolveSymbolContextForAddress(so_addr, resolve_scope, sc);
+ if (resolved_flags != 0)
+ break;
}
+ }
- return resolved_flags;
+ return resolved_flags;
}
-uint32_t
-ModuleList::ResolveSymbolContextForFilePath(const char *file_path,
- uint32_t line,
- bool check_inlines,
- uint32_t resolve_scope,
- SymbolContextList& sc_list) const
-{
- FileSpec file_spec(file_path, false);
- return ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
+uint32_t ModuleList::ResolveSymbolContextForFilePath(
+ const char *file_path, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, SymbolContextList &sc_list) const {
+ FileSpec file_spec(file_path, false);
+ return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
+ resolve_scope, sc_list);
}
-uint32_t
-ModuleList::ResolveSymbolContextsForFileSpec (const FileSpec &file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- (*pos)->ResolveSymbolContextsForFileSpec (file_spec, line, check_inlines, resolve_scope, sc_list);
- }
+uint32_t ModuleList::ResolveSymbolContextsForFileSpec(
+ const FileSpec &file_spec, uint32_t line, bool check_inlines,
+ uint32_t resolve_scope, SymbolContextList &sc_list) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos, end = m_modules.end();
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ (*pos)->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
+ resolve_scope, sc_list);
+ }
- return sc_list.GetSize();
+ return sc_list.GetSize();
}
-size_t
-ModuleList::GetIndexForModule (const Module *module) const
-{
- if (module)
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos;
- collection::const_iterator begin = m_modules.begin();
- collection::const_iterator end = m_modules.end();
- for (pos = begin; pos != end; ++pos)
- {
- if ((*pos).get() == module)
- return std::distance (begin, pos);
+size_t ModuleList::GetIndexForModule(const Module *module) const {
+ if (module) {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ collection::const_iterator pos;
+ collection::const_iterator begin = m_modules.begin();
+ collection::const_iterator end = m_modules.end();
+ for (pos = begin; pos != end; ++pos) {
+ if ((*pos).get() == module)
+ return std::distance(begin, pos);
+ }
+ }
+ return LLDB_INVALID_INDEX32;
+}
+
+static ModuleList &GetSharedModuleList() {
+ static ModuleList *g_shared_module_list = nullptr;
+ static std::once_flag g_once_flag;
+ std::call_once(g_once_flag, []() {
+ // NOTE: Intentionally leak the module list so a program doesn't have to
+ // cleanup all modules and object files as it exits. This just wastes time
+ // doing a bunch of cleanup that isn't required.
+ if (g_shared_module_list == nullptr)
+ g_shared_module_list = new ModuleList(); // <--- Intentional leak!!!
+ });
+ return *g_shared_module_list;
+}
+
+bool ModuleList::ModuleIsInCache(const Module *module_ptr) {
+ if (module_ptr) {
+ ModuleList &shared_module_list = GetSharedModuleList();
+ return shared_module_list.FindModule(module_ptr).get() != nullptr;
+ }
+ return false;
+}
+
+size_t ModuleList::FindSharedModules(const ModuleSpec &module_spec,
+ ModuleList &matching_module_list) {
+ return GetSharedModuleList().FindModules(module_spec, matching_module_list);
+}
+
+size_t ModuleList::RemoveOrphanSharedModules(bool mandatory) {
+ return GetSharedModuleList().RemoveOrphans(mandatory);
+}
+
+Error ModuleList::GetSharedModule(const ModuleSpec &module_spec,
+ ModuleSP &module_sp,
+ const FileSpecList *module_search_paths_ptr,
+ ModuleSP *old_module_sp_ptr,
+ bool *did_create_ptr, bool always_create) {
+ ModuleList &shared_module_list = GetSharedModuleList();
+ std::lock_guard<std::recursive_mutex> guard(
+ shared_module_list.m_modules_mutex);
+ char path[PATH_MAX];
+
+ Error error;
+
+ module_sp.reset();
+
+ if (did_create_ptr)
+ *did_create_ptr = false;
+ if (old_module_sp_ptr)
+ old_module_sp_ptr->reset();
+
+ const UUID *uuid_ptr = module_spec.GetUUIDPtr();
+ const FileSpec &module_file_spec = module_spec.GetFileSpec();
+ const ArchSpec &arch = module_spec.GetArchitecture();
+
+ // Make sure no one else can try and get or create a module while this
+ // function is actively working on it by doing an extra lock on the
+ // global mutex list.
+ if (!always_create) {
+ ModuleList matching_module_list;
+ const size_t num_matching_modules =
+ shared_module_list.FindModules(module_spec, matching_module_list);
+ if (num_matching_modules > 0) {
+ for (size_t module_idx = 0; module_idx < num_matching_modules;
+ ++module_idx) {
+ module_sp = matching_module_list.GetModuleAtIndex(module_idx);
+
+ // Make sure the file for the module hasn't been modified
+ if (module_sp->FileHasChanged()) {
+ if (old_module_sp_ptr && !*old_module_sp_ptr)
+ *old_module_sp_ptr = module_sp;
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_MODULES));
+ if (log != nullptr)
+ log->Printf("module changed: %p, removing from global module list",
+ static_cast<void *>(module_sp.get()));
+
+ shared_module_list.Remove(module_sp);
+ module_sp.reset();
+ } else {
+ // The module matches and the module was not modified from
+ // when it was last loaded.
+ return error;
}
+ }
}
- return LLDB_INVALID_INDEX32;
-}
+ }
-static ModuleList &
-GetSharedModuleList ()
-{
- static ModuleList *g_shared_module_list = nullptr;
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, [](){
- // NOTE: Intentionally leak the module list so a program doesn't have to
- // cleanup all modules and object files as it exits. This just wastes time
- // doing a bunch of cleanup that isn't required.
- if (g_shared_module_list == nullptr)
- g_shared_module_list = new ModuleList(); // <--- Intentional leak!!!
- });
- return *g_shared_module_list;
-}
-
-bool
-ModuleList::ModuleIsInCache (const Module *module_ptr)
-{
- if (module_ptr)
- {
- ModuleList &shared_module_list = GetSharedModuleList ();
- return shared_module_list.FindModule(module_ptr).get() != nullptr;
- }
- return false;
-}
-
-size_t
-ModuleList::FindSharedModules (const ModuleSpec &module_spec, ModuleList &matching_module_list)
-{
- return GetSharedModuleList ().FindModules (module_spec, matching_module_list);
-}
-
-size_t
-ModuleList::RemoveOrphanSharedModules (bool mandatory)
-{
- return GetSharedModuleList ().RemoveOrphans(mandatory);
-}
-
-Error
-ModuleList::GetSharedModule(const ModuleSpec &module_spec,
- ModuleSP &module_sp,
- const FileSpecList *module_search_paths_ptr,
- ModuleSP *old_module_sp_ptr,
- bool *did_create_ptr,
- bool always_create)
-{
- ModuleList &shared_module_list = GetSharedModuleList ();
- std::lock_guard<std::recursive_mutex> guard(shared_module_list.m_modules_mutex);
- char path[PATH_MAX];
-
- Error error;
-
- module_sp.reset();
-
- if (did_create_ptr)
- *did_create_ptr = false;
- if (old_module_sp_ptr)
- old_module_sp_ptr->reset();
-
- const UUID *uuid_ptr = module_spec.GetUUIDPtr();
- const FileSpec &module_file_spec = module_spec.GetFileSpec();
- const ArchSpec &arch = module_spec.GetArchitecture();
+ if (module_sp)
+ return error;
- // Make sure no one else can try and get or create a module while this
- // function is actively working on it by doing an extra lock on the
- // global mutex list.
- if (!always_create)
- {
- ModuleList matching_module_list;
- const size_t num_matching_modules = shared_module_list.FindModules (module_spec, matching_module_list);
- if (num_matching_modules > 0)
- {
- for (size_t module_idx = 0; module_idx < num_matching_modules; ++module_idx)
- {
- module_sp = matching_module_list.GetModuleAtIndex(module_idx);
-
- // Make sure the file for the module hasn't been modified
- if (module_sp->FileHasChanged())
- {
- if (old_module_sp_ptr && !*old_module_sp_ptr)
- *old_module_sp_ptr = module_sp;
-
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_MODULES));
- if (log != nullptr)
- log->Printf("module changed: %p, removing from global module list",
- static_cast<void*>(module_sp.get()));
-
- shared_module_list.Remove (module_sp);
- module_sp.reset();
- }
- else
- {
- // The module matches and the module was not modified from
- // when it was last loaded.
- return error;
- }
- }
+ module_sp.reset(new Module(module_spec));
+ // Make sure there are a module and an object file since we can specify
+ // a valid file path with an architecture that might not be in that file.
+ // By getting the object file we can guarantee that the architecture matches
+ if (module_sp->GetObjectFile()) {
+ // 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 (module_sp->GetObjectFile() &&
+ module_sp->GetObjectFile()->GetType() ==
+ ObjectFile::eTypeStubLibrary) {
+ module_sp.reset();
+ } else {
+ if (did_create_ptr) {
+ *did_create_ptr = true;
}
- }
- if (module_sp)
+ shared_module_list.ReplaceEquivalent(module_sp);
return error;
-
- module_sp.reset (new Module (module_spec));
- // Make sure there are a module and an object file since we can specify
- // a valid file path with an architecture that might not be in that file.
- // By getting the object file we can guarantee that the architecture matches
- if (module_sp->GetObjectFile())
- {
+ }
+ }
+ } else {
+ module_sp.reset();
+ }
+
+ if (module_search_paths_ptr) {
+ const auto num_directories = module_search_paths_ptr->GetSize();
+ for (size_t idx = 0; idx < num_directories; ++idx) {
+ auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
+ if (!search_path_spec.ResolvePath())
+ continue;
+ if (!search_path_spec.Exists() || !search_path_spec.IsDirectory())
+ continue;
+ search_path_spec.AppendPathComponent(
+ module_spec.GetFileSpec().GetFilename().AsCString());
+ if (!search_path_spec.Exists())
+ continue;
+
+ auto resolved_module_spec(module_spec);
+ resolved_module_spec.GetFileSpec() = search_path_spec;
+ module_sp.reset(new Module(resolved_module_spec));
+ if (module_sp->GetObjectFile()) {
// 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())
- {
+ if (uuid_ptr && *uuid_ptr != module_sp->GetUUID()) {
+ module_sp.reset();
+ } else {
+ 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
- {
- 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;
- }
- }
- }
- else
- {
+ } else {
module_sp.reset();
- }
-
- if (module_search_paths_ptr)
- {
- const auto num_directories = module_search_paths_ptr->GetSize();
- for (size_t idx = 0; idx < num_directories; ++idx)
- {
- auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx);
- if (!search_path_spec.ResolvePath())
- continue;
- if (!search_path_spec.Exists() || !search_path_spec.IsDirectory())
- continue;
- search_path_spec.AppendPathComponent(module_spec.GetFileSpec().GetFilename().AsCString());
- if (!search_path_spec.Exists())
- continue;
-
- auto resolved_module_spec(module_spec);
- resolved_module_spec.GetFileSpec() = search_path_spec;
- module_sp.reset (new Module (resolved_module_spec));
- if (module_sp->GetObjectFile())
- {
- // 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 (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();
- }
+ }
+ }
+ }
+
+ // Either the file didn't exist where at the path, or no path was given, so
+ // we now have to use more extreme measures to try and find the appropriate
+ // module.
+
+ // 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.
+ 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 (located_binary_modulespec.GetFileSpec() != module_file_spec) {
+ if (!located_binary_modulespec.GetFileSpec().Exists()) {
+ 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 (located_binary_modulespec.GetFileSpec().Exists()) {
+ std::string uuid_str;
+ if (uuid_ptr && uuid_ptr->IsValid())
+ uuid_str = uuid_ptr->GetAsString();
+
+ if (arch.IsValid()) {
+ if (!uuid_str.empty())
+ error.SetErrorStringWithFormat(
+ "'%s' does not contain the %s architecture and UUID %s", path,
+ arch.GetArchitectureName(), uuid_str.c_str());
+ else
+ error.SetErrorStringWithFormat(
+ "'%s' does not contain the %s architecture.", path,
+ arch.GetArchitectureName());
}
+ } else {
+ error.SetErrorStringWithFormat("'%s' does not exist", path);
+ }
+ if (error.Fail())
+ module_sp.reset();
+ return error;
}
- // Either the file didn't exist where at the path, or no path was given, so
- // we now have to use more extreme measures to try and find the appropriate
- // module.
-
- // 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.
- 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 (located_binary_modulespec.GetFileSpec() != module_file_spec)
- {
- if (!located_binary_modulespec.GetFileSpec().Exists())
- {
- 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 (located_binary_modulespec.GetFileSpec().Exists())
- {
- std::string uuid_str;
- if (uuid_ptr && uuid_ptr->IsValid())
- uuid_str = uuid_ptr->GetAsString();
-
- if (arch.IsValid())
- {
- if (!uuid_str.empty())
- error.SetErrorStringWithFormat("'%s' does not contain the %s architecture and UUID %s", path, arch.GetArchitectureName(), uuid_str.c_str());
- else
- error.SetErrorStringWithFormat("'%s' does not contain the %s architecture.", path, arch.GetArchitectureName());
- }
- }
- else
- {
- error.SetErrorStringWithFormat("'%s' does not exist", path);
- }
- if (error.Fail())
- module_sp.reset();
- return error;
+ // Make sure no one else can try and get or create a module while this
+ // 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() =
+ 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) {
+ module_sp = matching_module_list.GetModuleAtIndex(0);
+
+ // If we didn't have a UUID in mind when looking for the object file,
+ // then we should make sure the modification time hasn't changed!
+ if (platform_module_spec.GetUUIDPtr() == nullptr) {
+ auto file_spec_mod_time = FileSystem::GetModificationTime(
+ located_binary_modulespec.GetFileSpec());
+ if (file_spec_mod_time != llvm::sys::TimePoint<>()) {
+ if (file_spec_mod_time != module_sp->GetModificationTime()) {
+ if (old_module_sp_ptr)
+ *old_module_sp_ptr = module_sp;
+ shared_module_list.Remove(module_sp);
+ module_sp.reset();
+ }
}
-
- // Make sure no one else can try and get or create a module while this
- // 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() = 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)
- {
- module_sp = matching_module_list.GetModuleAtIndex(0);
-
- // If we didn't have a UUID in mind when looking for the object file,
- // then we should make sure the modification time hasn't changed!
- if (platform_module_spec.GetUUIDPtr() == nullptr)
- {
- TimeValue file_spec_mod_time(located_binary_modulespec.GetFileSpec().GetModificationTime());
- if (file_spec_mod_time.IsValid())
- {
- if (file_spec_mod_time != module_sp->GetModificationTime())
- {
- if (old_module_sp_ptr)
- *old_module_sp_ptr = module_sp;
- shared_module_list.Remove (module_sp);
- module_sp.reset();
- }
- }
- }
+ }
+ }
+
+ if (!module_sp) {
+ module_sp.reset(new Module(platform_module_spec));
+ // Make sure there are a module and an object file since we can specify
+ // a valid file path with an architecture that might not be in that file.
+ // By getting the object file we can guarantee that the architecture
+ // matches
+ if (module_sp && module_sp->GetObjectFile()) {
+ 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);
}
-
- if (!module_sp)
- {
- module_sp.reset (new Module (platform_module_spec));
- // Make sure there are a module and an object file since we can specify
- // a valid file path with an architecture that might not be in that file.
- // By getting the object file we can guarantee that the architecture matches
- if (module_sp && module_sp->GetObjectFile())
- {
- 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);
- }
- }
- else
- {
- located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
-
- if (located_binary_modulespec.GetFileSpec())
- {
- if (arch.IsValid())
- error.SetErrorStringWithFormat("unable to open %s architecture in '%s'", arch.GetArchitectureName(), path);
- else
- error.SetErrorStringWithFormat("unable to open '%s'", path);
- }
- else
- {
- std::string uuid_str;
- if (uuid_ptr && uuid_ptr->IsValid())
- uuid_str = uuid_ptr->GetAsString();
-
- if (!uuid_str.empty())
- error.SetErrorStringWithFormat("cannot locate a module for UUID '%s'", uuid_str.c_str());
- else
- error.SetErrorStringWithFormat("cannot locate a module");
- }
- }
+ } else {
+ located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path));
+
+ if (located_binary_modulespec.GetFileSpec()) {
+ if (arch.IsValid())
+ error.SetErrorStringWithFormat(
+ "unable to open %s architecture in '%s'",
+ arch.GetArchitectureName(), path);
+ else
+ error.SetErrorStringWithFormat("unable to open '%s'", path);
+ } else {
+ std::string uuid_str;
+ if (uuid_ptr && uuid_ptr->IsValid())
+ uuid_str = uuid_ptr->GetAsString();
+
+ if (!uuid_str.empty())
+ error.SetErrorStringWithFormat(
+ "cannot locate a module for UUID '%s'", uuid_str.c_str());
+ else
+ error.SetErrorStringWithFormat("cannot locate a module");
}
+ }
}
+ }
- return error;
+ return error;
}
-bool
-ModuleList::RemoveSharedModule (lldb::ModuleSP &module_sp)
-{
- return GetSharedModuleList ().Remove (module_sp);
+bool ModuleList::RemoveSharedModule(lldb::ModuleSP &module_sp) {
+ return GetSharedModuleList().Remove(module_sp);
}
-bool
-ModuleList::RemoveSharedModuleIfOrphaned (const Module *module_ptr)
-{
- return GetSharedModuleList ().RemoveIfOrphaned (module_ptr);
+bool ModuleList::RemoveSharedModuleIfOrphaned(const Module *module_ptr) {
+ return GetSharedModuleList().RemoveIfOrphaned(module_ptr);
}
-bool
-ModuleList::LoadScriptingResourcesInTarget (Target *target,
- std::list<Error>& errors,
- Stream *feedback_stream,
- bool continue_on_error)
-{
- if (!target)
- return false;
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- for (auto module : m_modules)
- {
- Error error;
- if (module)
- {
- if (!module->LoadScriptingResourceInTarget(target, error, feedback_stream))
- {
- if (error.Fail() && error.AsCString())
- {
- error.SetErrorStringWithFormat("unable to load scripting data for module %s - error reported was %s",
- module->GetFileSpec().GetFileNameStrippingExtension().GetCString(),
- error.AsCString());
- errors.push_back(error);
-
- if (!continue_on_error)
- return false;
- }
- }
+bool ModuleList::LoadScriptingResourcesInTarget(Target *target,
+ std::list<Error> &errors,
+ Stream *feedback_stream,
+ bool continue_on_error) {
+ if (!target)
+ return false;
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ for (auto module : m_modules) {
+ Error error;
+ if (module) {
+ if (!module->LoadScriptingResourceInTarget(target, error,
+ feedback_stream)) {
+ if (error.Fail() && error.AsCString()) {
+ error.SetErrorStringWithFormat("unable to load scripting data for "
+ "module %s - error reported was %s",
+ module->GetFileSpec()
+ .GetFileNameStrippingExtension()
+ .GetCString(),
+ error.AsCString());
+ errors.push_back(error);
+
+ if (!continue_on_error)
+ return false;
}
+ }
}
- return errors.empty();
+ }
+ return errors.empty();
}
-void
-ModuleList::ForEach (std::function <bool (const ModuleSP &module_sp)> const &callback) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- for (const auto &module : m_modules)
- {
- // If the callback returns false, then stop iterating and break out
- if (!callback (module))
- break;
- }
+void ModuleList::ForEach(
+ std::function<bool(const ModuleSP &module_sp)> const &callback) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ for (const auto &module : m_modules) {
+ // If the callback returns false, then stop iterating and break out
+ if (!callback(module))
+ break;
+ }
}
diff --git a/source/Core/Opcode.cpp b/source/Core/Opcode.cpp
index e36727eaa313..11b913841ecb 100644
--- a/source/Core/Opcode.cpp
+++ b/source/Core/Opcode.cpp
@@ -24,136 +24,119 @@
using namespace lldb;
using namespace lldb_private;
-int
-Opcode::Dump (Stream *s, uint32_t min_byte_width)
-{
- int bytes_written = 0;
- switch (m_type)
- {
- case Opcode::eTypeInvalid:
- bytes_written = s->PutCString ("<invalid>");
- break;
- case Opcode::eType8:
- bytes_written = s->Printf ("0x%2.2x", m_data.inst8);
- break;
- case Opcode::eType16:
- bytes_written = s->Printf ("0x%4.4x", m_data.inst16);
- break;
- case Opcode::eType16_2:
- case Opcode::eType32:
- bytes_written = s->Printf ("0x%8.8x", m_data.inst32);
- break;
+int Opcode::Dump(Stream *s, uint32_t min_byte_width) {
+ int bytes_written = 0;
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ bytes_written = s->PutCString("<invalid>");
+ break;
+ case Opcode::eType8:
+ bytes_written = s->Printf("0x%2.2x", m_data.inst8);
+ break;
+ case Opcode::eType16:
+ bytes_written = s->Printf("0x%4.4x", m_data.inst16);
+ break;
+ case Opcode::eType16_2:
+ case Opcode::eType32:
+ bytes_written = s->Printf("0x%8.8x", m_data.inst32);
+ break;
- case Opcode::eType64:
- bytes_written = s->Printf ("0x%16.16" PRIx64, m_data.inst64);
- break;
+ case Opcode::eType64:
+ bytes_written = s->Printf("0x%16.16" PRIx64, m_data.inst64);
+ break;
- case Opcode::eTypeBytes:
- for (uint32_t i = 0; i < m_data.inst.length; ++i)
- {
- if (i > 0)
- bytes_written += s->PutChar (' ');
- bytes_written += s->Printf ("%2.2x", m_data.inst.bytes[i]);
- }
- break;
+ case Opcode::eTypeBytes:
+ for (uint32_t i = 0; i < m_data.inst.length; ++i) {
+ if (i > 0)
+ bytes_written += s->PutChar(' ');
+ bytes_written += s->Printf("%2.2x", m_data.inst.bytes[i]);
}
+ break;
+ }
- // Add spaces to make sure bytes dispay comes out even in case opcodes
- // aren't all the same size
- if (static_cast<uint32_t>(bytes_written) < min_byte_width)
- bytes_written = s->Printf ("%*s", min_byte_width - bytes_written, "");
- return bytes_written;
+ // Add spaces to make sure bytes dispay comes out even in case opcodes
+ // aren't all the same size
+ if (static_cast<uint32_t>(bytes_written) < min_byte_width)
+ bytes_written = s->Printf("%*s", min_byte_width - bytes_written, "");
+ return bytes_written;
}
-lldb::ByteOrder
-Opcode::GetDataByteOrder () const
-{
- if (m_byte_order != eByteOrderInvalid)
- {
- return m_byte_order;
- }
- switch (m_type)
- {
- case Opcode::eTypeInvalid: break;
- case Opcode::eType8:
- case Opcode::eType16:
- case Opcode::eType16_2:
- case Opcode::eType32:
- case Opcode::eType64: return endian::InlHostByteOrder();
- case Opcode::eTypeBytes:
- break;
- }
- return eByteOrderInvalid;
+lldb::ByteOrder Opcode::GetDataByteOrder() const {
+ if (m_byte_order != eByteOrderInvalid) {
+ return m_byte_order;
+ }
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ case Opcode::eType16:
+ case Opcode::eType16_2:
+ case Opcode::eType32:
+ case Opcode::eType64:
+ return endian::InlHostByteOrder();
+ case Opcode::eTypeBytes:
+ break;
+ }
+ return eByteOrderInvalid;
}
-uint32_t
-Opcode::GetData (DataExtractor &data) const
-{
- uint32_t byte_size = GetByteSize ();
- uint8_t swap_buf[8];
- const void *buf = nullptr;
+uint32_t Opcode::GetData(DataExtractor &data) const {
+ uint32_t byte_size = GetByteSize();
+ uint8_t swap_buf[8];
+ const void *buf = nullptr;
- if (byte_size > 0)
- {
- if (!GetEndianSwap())
- {
- if (m_type == Opcode::eType16_2)
- {
- // 32 bit thumb instruction, we need to sizzle this a bit
- swap_buf[0] = m_data.inst.bytes[2];
- swap_buf[1] = m_data.inst.bytes[3];
- swap_buf[2] = m_data.inst.bytes[0];
- swap_buf[3] = m_data.inst.bytes[1];
- buf = swap_buf;
- }
- else
- {
- buf = GetOpcodeDataBytes();
- }
- }
- else
- {
- switch (m_type)
- {
- case Opcode::eTypeInvalid:
- break;
- case Opcode::eType8:
- buf = GetOpcodeDataBytes();
- break;
- case Opcode::eType16:
- *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16);
- buf = swap_buf;
- break;
- case Opcode::eType16_2:
- swap_buf[0] = m_data.inst.bytes[1];
- swap_buf[1] = m_data.inst.bytes[0];
- swap_buf[2] = m_data.inst.bytes[3];
- swap_buf[3] = m_data.inst.bytes[2];
- buf = swap_buf;
- break;
- case Opcode::eType32:
- *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32);
- buf = swap_buf;
- break;
- case Opcode::eType64:
- *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64);
- buf = swap_buf;
- break;
- case Opcode::eTypeBytes:
- buf = GetOpcodeDataBytes();
- break;
- }
- }
+ if (byte_size > 0) {
+ if (!GetEndianSwap()) {
+ if (m_type == Opcode::eType16_2) {
+ // 32 bit thumb instruction, we need to sizzle this a bit
+ swap_buf[0] = m_data.inst.bytes[2];
+ swap_buf[1] = m_data.inst.bytes[3];
+ swap_buf[2] = m_data.inst.bytes[0];
+ swap_buf[3] = m_data.inst.bytes[1];
+ buf = swap_buf;
+ } else {
+ buf = GetOpcodeDataBytes();
+ }
+ } else {
+ switch (m_type) {
+ case Opcode::eTypeInvalid:
+ break;
+ case Opcode::eType8:
+ buf = GetOpcodeDataBytes();
+ break;
+ case Opcode::eType16:
+ *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16);
+ buf = swap_buf;
+ break;
+ case Opcode::eType16_2:
+ swap_buf[0] = m_data.inst.bytes[1];
+ swap_buf[1] = m_data.inst.bytes[0];
+ swap_buf[2] = m_data.inst.bytes[3];
+ swap_buf[3] = m_data.inst.bytes[2];
+ buf = swap_buf;
+ break;
+ case Opcode::eType32:
+ *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32);
+ buf = swap_buf;
+ break;
+ case Opcode::eType64:
+ *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64);
+ buf = swap_buf;
+ break;
+ case Opcode::eTypeBytes:
+ buf = GetOpcodeDataBytes();
+ break;
+ }
}
- if (buf != nullptr)
- {
- DataBufferSP buffer_sp;
+ }
+ if (buf != nullptr) {
+ DataBufferSP buffer_sp;
- buffer_sp.reset (new DataBufferHeap (buf, byte_size));
- data.SetByteOrder(GetDataByteOrder());
- data.SetData (buffer_sp);
- return byte_size;
- }
- data.Clear();
- return 0;
+ buffer_sp.reset(new DataBufferHeap(buf, byte_size));
+ data.SetByteOrder(GetDataByteOrder());
+ data.SetData(buffer_sp);
+ return byte_size;
+ }
+ data.Clear();
+ return 0;
}
diff --git a/source/Core/PluginManager.cpp b/source/Core/PluginManager.cpp
index 500b08b73e9e..b7b6b9a54efe 100644
--- a/source/Core/PluginManager.cpp
+++ b/source/Core/PluginManager.cpp
@@ -31,3021 +31,2608 @@
using namespace lldb;
using namespace lldb_private;
-enum PluginAction
-{
- ePluginRegisterInstance,
- ePluginUnregisterInstance,
- ePluginGetInstanceAtIndex
+enum PluginAction {
+ ePluginRegisterInstance,
+ ePluginUnregisterInstance,
+ ePluginGetInstanceAtIndex
};
typedef bool (*PluginInitCallback)();
typedef void (*PluginTermCallback)();
-struct PluginInfo
-{
- PluginInfo()
- : plugin_init_callback(nullptr), plugin_term_callback(nullptr)
- {
- }
+struct PluginInfo {
+ PluginInfo() : plugin_init_callback(nullptr), plugin_term_callback(nullptr) {}
- llvm::sys::DynamicLibrary library;
- PluginInitCallback plugin_init_callback;
- PluginTermCallback plugin_term_callback;
+ llvm::sys::DynamicLibrary library;
+ PluginInitCallback plugin_init_callback;
+ PluginTermCallback plugin_term_callback;
};
typedef std::map<FileSpec, PluginInfo> PluginTerminateMap;
-static std::recursive_mutex &
-GetPluginMapMutex()
-{
- static std::recursive_mutex g_plugin_map_mutex;
- return g_plugin_map_mutex;
-}
-
-static PluginTerminateMap &
-GetPluginMap ()
-{
- static PluginTerminateMap g_plugin_map;
- return g_plugin_map;
-}
-
-static bool
-PluginIsLoaded (const FileSpec &plugin_file_spec)
-{
- std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
- PluginTerminateMap &plugin_map = GetPluginMap ();
- return plugin_map.find (plugin_file_spec) != plugin_map.end();
-}
-
-static void
-SetPluginInfo (const FileSpec &plugin_file_spec, const PluginInfo &plugin_info)
-{
- std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
- PluginTerminateMap &plugin_map = GetPluginMap ();
- assert (plugin_map.find (plugin_file_spec) == plugin_map.end());
- plugin_map[plugin_file_spec] = plugin_info;
-}
-
-template <typename FPtrTy>
-static FPtrTy
-CastToFPtr (void *VPtr)
-{
- return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
-}
-
-static FileSpec::EnumerateDirectoryResult
-LoadPluginCallback(void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
-// PluginManager *plugin_manager = (PluginManager *)baton;
- Error error;
-
- // If we have a regular file, a symbolic link or unknown file type, try
- // and process the file. We must handle unknown as sometimes the directory
- // enumeration might be enumerating a file system that doesn't have correct
- // file type information.
- if (file_type == FileSpec::eFileTypeRegular ||
- file_type == FileSpec::eFileTypeSymbolicLink ||
- file_type == FileSpec::eFileTypeUnknown )
- {
- FileSpec plugin_file_spec (file_spec);
- plugin_file_spec.ResolvePath();
-
- if (PluginIsLoaded (plugin_file_spec))
- return FileSpec::eEnumerateDirectoryResultNext;
- else
- {
- PluginInfo plugin_info;
-
- std::string pluginLoadError;
- plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary (plugin_file_spec.GetPath().c_str(), &pluginLoadError);
- if (plugin_info.library.isValid())
- {
- bool success = false;
- plugin_info.plugin_init_callback =
- CastToFPtr<PluginInitCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
- if (plugin_info.plugin_init_callback)
- {
- // Call the plug-in "bool LLDBPluginInitialize(void)" function
- success = plugin_info.plugin_init_callback();
- }
-
- if (success)
- {
- // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
- plugin_info.plugin_term_callback =
- CastToFPtr<PluginTermCallback>(plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
- }
- else
- {
- // The initialize function returned FALSE which means the plug-in might not be
- // compatible, or might be too new or too old, or might not want to run on this
- // machine. Set it to a default-constructed instance to invalidate it.
- plugin_info = PluginInfo();
- }
-
- // Regardless of success or failure, cache the plug-in load
- // in our plug-in info so we don't try to load it again and
- // again.
- SetPluginInfo (plugin_file_spec, plugin_info);
-
- return FileSpec::eEnumerateDirectoryResultNext;
- }
+static std::recursive_mutex &GetPluginMapMutex() {
+ static std::recursive_mutex g_plugin_map_mutex;
+ return g_plugin_map_mutex;
+}
+
+static PluginTerminateMap &GetPluginMap() {
+ static PluginTerminateMap g_plugin_map;
+ return g_plugin_map;
+}
+
+static bool PluginIsLoaded(const FileSpec &plugin_file_spec) {
+ std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
+ PluginTerminateMap &plugin_map = GetPluginMap();
+ return plugin_map.find(plugin_file_spec) != plugin_map.end();
+}
+
+static void SetPluginInfo(const FileSpec &plugin_file_spec,
+ const PluginInfo &plugin_info) {
+ std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
+ PluginTerminateMap &plugin_map = GetPluginMap();
+ assert(plugin_map.find(plugin_file_spec) == plugin_map.end());
+ plugin_map[plugin_file_spec] = plugin_info;
+}
+
+template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
+ return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
+}
+
+static FileSpec::EnumerateDirectoryResult
+LoadPluginCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &file_spec) {
+ // PluginManager *plugin_manager = (PluginManager *)baton;
+ Error error;
+
+ // If we have a regular file, a symbolic link or unknown file type, try
+ // and process the file. We must handle unknown as sometimes the directory
+ // enumeration might be enumerating a file system that doesn't have correct
+ // file type information.
+ if (file_type == FileSpec::eFileTypeRegular ||
+ file_type == FileSpec::eFileTypeSymbolicLink ||
+ file_type == FileSpec::eFileTypeUnknown) {
+ FileSpec plugin_file_spec(file_spec);
+ plugin_file_spec.ResolvePath();
+
+ if (PluginIsLoaded(plugin_file_spec))
+ return FileSpec::eEnumerateDirectoryResultNext;
+ else {
+ PluginInfo plugin_info;
+
+ std::string pluginLoadError;
+ plugin_info.library = llvm::sys::DynamicLibrary::getPermanentLibrary(
+ plugin_file_spec.GetPath().c_str(), &pluginLoadError);
+ if (plugin_info.library.isValid()) {
+ bool success = false;
+ plugin_info.plugin_init_callback = CastToFPtr<PluginInitCallback>(
+ plugin_info.library.getAddressOfSymbol("LLDBPluginInitialize"));
+ if (plugin_info.plugin_init_callback) {
+ // Call the plug-in "bool LLDBPluginInitialize(void)" function
+ success = plugin_info.plugin_init_callback();
}
+
+ if (success) {
+ // It is ok for the "LLDBPluginTerminate" symbol to be nullptr
+ plugin_info.plugin_term_callback = CastToFPtr<PluginTermCallback>(
+ plugin_info.library.getAddressOfSymbol("LLDBPluginTerminate"));
+ } else {
+ // The initialize function returned FALSE which means the plug-in
+ // might not be
+ // compatible, or might be too new or too old, or might not want to
+ // run on this
+ // machine. Set it to a default-constructed instance to invalidate
+ // it.
+ plugin_info = PluginInfo();
+ }
+
+ // Regardless of success or failure, cache the plug-in load
+ // in our plug-in info so we don't try to load it again and
+ // again.
+ SetPluginInfo(plugin_file_spec, plugin_info);
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+ }
}
-
- if (file_type == FileSpec::eFileTypeUnknown ||
- file_type == FileSpec::eFileTypeDirectory ||
- file_type == FileSpec::eFileTypeSymbolicLink )
- {
- // Try and recurse into anything that a directory or symbolic link.
- // We must also do this for unknown as sometimes the directory enumeration
- // might be enumerating a file system that doesn't have correct file type
- // information.
- return FileSpec::eEnumerateDirectoryResultEnter;
- }
+ }
+
+ if (file_type == FileSpec::eFileTypeUnknown ||
+ file_type == FileSpec::eFileTypeDirectory ||
+ file_type == FileSpec::eFileTypeSymbolicLink) {
+ // Try and recurse into anything that a directory or symbolic link.
+ // We must also do this for unknown as sometimes the directory enumeration
+ // might be enumerating a file system that doesn't have correct file type
+ // information.
+ return FileSpec::eEnumerateDirectoryResultEnter;
+ }
- return FileSpec::eEnumerateDirectoryResultNext;
+ return FileSpec::eEnumerateDirectoryResultNext;
}
-void
-PluginManager::Initialize ()
-{
+void PluginManager::Initialize() {
#if 1
- FileSpec dir_spec;
- const bool find_directories = true;
- const bool find_files = true;
- const bool find_other = true;
- char dir_path[PATH_MAX];
- if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
- {
- if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
- {
- FileSpec::EnumerateDirectory(dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- nullptr);
- }
- }
-
- if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
- {
- if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
- {
- FileSpec::EnumerateDirectory(dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- nullptr);
- }
- }
+ FileSpec dir_spec;
+ const bool find_directories = true;
+ const bool find_files = true;
+ const bool find_other = true;
+ char dir_path[PATH_MAX];
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
+ FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
+ find_other, LoadPluginCallback, nullptr);
+ }
+ }
+
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
+ FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
+ find_other, LoadPluginCallback, nullptr);
+ }
+ }
#endif
}
-void
-PluginManager::Terminate ()
-{
- std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
- PluginTerminateMap &plugin_map = GetPluginMap ();
-
- PluginTerminateMap::const_iterator pos, end = plugin_map.end();
- for (pos = plugin_map.begin(); pos != end; ++pos)
- {
- // Call the plug-in "void LLDBPluginTerminate (void)" function if there
- // is one (if the symbol was not nullptr).
- if (pos->second.library.isValid())
- {
- if (pos->second.plugin_term_callback)
- pos->second.plugin_term_callback();
- }
+void PluginManager::Terminate() {
+ std::lock_guard<std::recursive_mutex> guard(GetPluginMapMutex());
+ PluginTerminateMap &plugin_map = GetPluginMap();
+
+ PluginTerminateMap::const_iterator pos, end = plugin_map.end();
+ for (pos = plugin_map.begin(); pos != end; ++pos) {
+ // Call the plug-in "void LLDBPluginTerminate (void)" function if there
+ // is one (if the symbol was not nullptr).
+ if (pos->second.library.isValid()) {
+ if (pos->second.plugin_term_callback)
+ pos->second.plugin_term_callback();
}
- plugin_map.clear();
+ }
+ plugin_map.clear();
}
#pragma mark ABI
-struct ABIInstance
-{
- ABIInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
+struct ABIInstance {
+ ABIInstance() : name(), description(), create_callback(nullptr) {}
- ConstString name;
- std::string description;
- ABICreateInstance create_callback;
+ ConstString name;
+ std::string description;
+ ABICreateInstance create_callback;
};
typedef std::vector<ABIInstance> ABIInstances;
-static std::recursive_mutex &
-GetABIInstancesMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static ABIInstances &
-GetABIInstances ()
-{
- static ABIInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- ABICreateInstance create_callback)
-{
- if (create_callback)
- {
- ABIInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
- GetABIInstances ().push_back (instance);
+static std::recursive_mutex &GetABIInstancesMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
+}
+
+static ABIInstances &GetABIInstances() {
+ static ABIInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ ABICreateInstance create_callback) {
+ if (create_callback) {
+ ABIInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
+ GetABIInstances().push_back(instance);
+ return true;
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
+ ABIInstances &instances = GetABIInstances();
+
+ ABIInstances::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;
+ }
+ return false;
}
-bool
-PluginManager::UnregisterPlugin (ABICreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
- ABIInstances &instances = GetABIInstances ();
-
- ABIInstances::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;
+ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
+ ABIInstances &instances = GetABIInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
ABICreateInstance
-PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
-{
+PluginManager::GetABICreateCallbackForPluginName(const ConstString &name) {
+ if (name) {
std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
- ABIInstances &instances = GetABIInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
-}
+ ABIInstances &instances = GetABIInstances();
-ABICreateInstance
-PluginManager::GetABICreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
- ABIInstances &instances = GetABIInstances ();
-
- ABIInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+ ABIInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark Disassembler
-struct DisassemblerInstance
-{
- DisassemblerInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
+struct DisassemblerInstance {
+ DisassemblerInstance() : name(), description(), create_callback(nullptr) {}
- ConstString name;
- std::string description;
- DisassemblerCreateInstance create_callback;
+ ConstString name;
+ std::string description;
+ DisassemblerCreateInstance create_callback;
};
typedef std::vector<DisassemblerInstance> DisassemblerInstances;
-static std::recursive_mutex &
-GetDisassemblerMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static DisassemblerInstances &
-GetDisassemblerInstances ()
-{
- static DisassemblerInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- DisassemblerCreateInstance create_callback)
-{
- if (create_callback)
- {
- DisassemblerInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
- GetDisassemblerInstances ().push_back (instance);
- return true;
- }
- return false;
+static std::recursive_mutex &GetDisassemblerMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (DisassemblerCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
- DisassemblerInstances &instances = GetDisassemblerInstances ();
-
- DisassemblerInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static DisassemblerInstances &GetDisassemblerInstances() {
+ static DisassemblerInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ DisassemblerCreateInstance create_callback) {
+ if (create_callback) {
+ DisassemblerInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
+ GetDisassemblerInstances().push_back(instance);
+ return true;
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ DisassemblerCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
+ DisassemblerInstances &instances = GetDisassemblerInstances();
+
+ DisassemblerInstances::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;
+ }
+ return false;
}
DisassemblerCreateInstance
-PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
- DisassemblerInstances &instances = GetDisassemblerInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
+ DisassemblerInstances &instances = GetDisassemblerInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
DisassemblerCreateInstance
-PluginManager::GetDisassemblerCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
- DisassemblerInstances &instances = GetDisassemblerInstances ();
-
- DisassemblerInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetDisassemblerCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex());
+ DisassemblerInstances &instances = GetDisassemblerInstances();
+
+ DisassemblerInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark DynamicLoader
-struct DynamicLoaderInstance
-{
- DynamicLoaderInstance() :
- name(),
- description(),
- create_callback(nullptr),
- debugger_init_callback(nullptr)
- {
- }
+struct DynamicLoaderInstance {
+ DynamicLoaderInstance()
+ : name(), description(), create_callback(nullptr),
+ debugger_init_callback(nullptr) {}
- ConstString name;
- std::string description;
- DynamicLoaderCreateInstance create_callback;
- DebuggerInitializeCallback debugger_init_callback;
+ ConstString name;
+ std::string description;
+ DynamicLoaderCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances;
-static std::recursive_mutex &
-GetDynamicLoaderMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static DynamicLoaderInstances &
-GetDynamicLoaderInstances ()
-{
- static DynamicLoaderInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- DynamicLoaderCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback)
-{
- if (create_callback)
- {
- DynamicLoaderInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.debugger_init_callback = debugger_init_callback;
- std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
- GetDynamicLoaderInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetDynamicLoaderMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (DynamicLoaderCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
- DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
-
- DynamicLoaderInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static DynamicLoaderInstances &GetDynamicLoaderInstances() {
+ static DynamicLoaderInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ DynamicLoaderCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback) {
+ if (create_callback) {
+ DynamicLoaderInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
+ GetDynamicLoaderInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ DynamicLoaderCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
+ DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
+
+ DynamicLoaderInstances::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;
+ }
+ return false;
}
DynamicLoaderCreateInstance
-PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
- DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
+ DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
DynamicLoaderCreateInstance
-PluginManager::GetDynamicLoaderCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
- DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
-
- DynamicLoaderInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetDynamicLoaderCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
+ DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
+
+ DynamicLoaderInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark JITLoader
-struct JITLoaderInstance
-{
- JITLoaderInstance() :
- name(),
- description(),
- create_callback(nullptr),
- debugger_init_callback(nullptr)
- {
- }
+struct JITLoaderInstance {
+ JITLoaderInstance()
+ : name(), description(), create_callback(nullptr),
+ debugger_init_callback(nullptr) {}
- ConstString name;
- std::string description;
- JITLoaderCreateInstance create_callback;
- DebuggerInitializeCallback debugger_init_callback;
+ ConstString name;
+ std::string description;
+ JITLoaderCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<JITLoaderInstance> JITLoaderInstances;
-static std::recursive_mutex &
-GetJITLoaderMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static JITLoaderInstances &
-GetJITLoaderInstances ()
-{
- static JITLoaderInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- JITLoaderCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback)
-{
- if (create_callback)
- {
- JITLoaderInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.debugger_init_callback = debugger_init_callback;
- std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
- GetJITLoaderInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetJITLoaderMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (JITLoaderCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
- JITLoaderInstances &instances = GetJITLoaderInstances ();
-
- JITLoaderInstances::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;
+static JITLoaderInstances &GetJITLoaderInstances() {
+ static JITLoaderInstances g_instances;
+ return g_instances;
}
-JITLoaderCreateInstance
-PluginManager::GetJITLoaderCreateCallbackAtIndex (uint32_t idx)
-{
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ JITLoaderCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback) {
+ if (create_callback) {
+ JITLoaderInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
- JITLoaderInstances &instances = GetJITLoaderInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ GetJITLoaderInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
+ JITLoaderInstances &instances = GetJITLoaderInstances();
+
+ JITLoaderInstances::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;
}
JITLoaderCreateInstance
-PluginManager::GetJITLoaderCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
- JITLoaderInstances &instances = GetJITLoaderInstances ();
-
- JITLoaderInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
+ JITLoaderInstances &instances = GetJITLoaderInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
+}
+
+JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
+ JITLoaderInstances &instances = GetJITLoaderInstances();
+
+ JITLoaderInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark EmulateInstruction
-struct EmulateInstructionInstance
-{
- EmulateInstructionInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- EmulateInstructionCreateInstance create_callback;
+struct EmulateInstructionInstance {
+ EmulateInstructionInstance()
+ : name(), description(), create_callback(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ EmulateInstructionCreateInstance create_callback;
};
typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances;
-static std::recursive_mutex &
-GetEmulateInstructionMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static EmulateInstructionInstances &
-GetEmulateInstructionInstances ()
-{
- static EmulateInstructionInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- EmulateInstructionCreateInstance create_callback)
-{
- if (create_callback)
- {
- EmulateInstructionInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
- GetEmulateInstructionInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetEmulateInstructionMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (EmulateInstructionCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
- EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
-
- EmulateInstructionInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static EmulateInstructionInstances &GetEmulateInstructionInstances() {
+ static EmulateInstructionInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ EmulateInstructionCreateInstance create_callback) {
+ if (create_callback) {
+ EmulateInstructionInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
+ GetEmulateInstructionInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ EmulateInstructionCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
+ EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
+
+ EmulateInstructionInstances::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;
+ }
+ return false;
}
EmulateInstructionCreateInstance
-PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
- EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
+ EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
EmulateInstructionCreateInstance
-PluginManager::GetEmulateInstructionCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
- EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
-
- EmulateInstructionInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetEmulateInstructionCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex());
+ EmulateInstructionInstances &instances = GetEmulateInstructionInstances();
+
+ EmulateInstructionInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark OperatingSystem
-struct OperatingSystemInstance
-{
- OperatingSystemInstance () :
- name (),
- description (),
- create_callback (nullptr),
- debugger_init_callback (nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- OperatingSystemCreateInstance create_callback;
- DebuggerInitializeCallback debugger_init_callback;
+struct OperatingSystemInstance {
+ 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;
-static std::recursive_mutex &
-GetOperatingSystemMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static OperatingSystemInstances &
-GetOperatingSystemInstances ()
-{
- static OperatingSystemInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name, const char *description,
- OperatingSystemCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback)
-{
- if (create_callback)
- {
- OperatingSystemInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.debugger_init_callback = debugger_init_callback;
- std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
- GetOperatingSystemInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetOperatingSystemMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (OperatingSystemCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
- OperatingSystemInstances &instances = GetOperatingSystemInstances ();
-
- OperatingSystemInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static OperatingSystemInstances &GetOperatingSystemInstances() {
+ static OperatingSystemInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ OperatingSystemCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback) {
+ if (create_callback) {
+ OperatingSystemInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
+ GetOperatingSystemInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ OperatingSystemCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
+ OperatingSystemInstances &instances = GetOperatingSystemInstances();
+
+ OperatingSystemInstances::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;
+ }
+ return false;
}
OperatingSystemCreateInstance
-PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
- OperatingSystemInstances &instances = GetOperatingSystemInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
+ OperatingSystemInstances &instances = GetOperatingSystemInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
OperatingSystemCreateInstance
-PluginManager::GetOperatingSystemCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
- OperatingSystemInstances &instances = GetOperatingSystemInstances ();
-
- OperatingSystemInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetOperatingSystemCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
+ OperatingSystemInstances &instances = GetOperatingSystemInstances();
+
+ OperatingSystemInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark Language
-struct LanguageInstance
-{
- LanguageInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- LanguageCreateInstance create_callback;
+struct LanguageInstance {
+ LanguageInstance() : name(), description(), create_callback(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ LanguageCreateInstance create_callback;
};
typedef std::vector<LanguageInstance> LanguageInstances;
-static std::recursive_mutex &
-GetLanguageMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- 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;
- std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
- GetLanguageInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetLanguageMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (LanguageCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(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;
- }
- }
+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;
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
+ GetLanguageInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(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;
+ }
+ return false;
}
LanguageCreateInstance
-PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
- LanguageInstances &instances = GetLanguageInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex());
+ LanguageInstances &instances = GetLanguageInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
LanguageCreateInstance
-PluginManager::GetLanguageCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(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;
- }
+PluginManager::GetLanguageCreateCallbackForPluginName(const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(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 nullptr;
+ }
+ return nullptr;
}
#pragma mark LanguageRuntime
-struct LanguageRuntimeInstance
-{
- LanguageRuntimeInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
+struct LanguageRuntimeInstance {
+ LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {}
- ConstString name;
- std::string description;
- LanguageRuntimeCreateInstance create_callback;
- LanguageRuntimeGetCommandObject command_callback;
+ ConstString name;
+ std::string description;
+ LanguageRuntimeCreateInstance create_callback;
+ LanguageRuntimeGetCommandObject command_callback;
};
typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances;
-static std::recursive_mutex &
-GetLanguageRuntimeMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static LanguageRuntimeInstances &
-GetLanguageRuntimeInstances ()
-{
- static LanguageRuntimeInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- LanguageRuntimeCreateInstance create_callback,
- LanguageRuntimeGetCommandObject command_callback)
-{
- if (create_callback)
- {
- LanguageRuntimeInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.command_callback = command_callback;
- std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
- GetLanguageRuntimeInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetLanguageRuntimeMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (LanguageRuntimeCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
- LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
-
- LanguageRuntimeInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static LanguageRuntimeInstances &GetLanguageRuntimeInstances() {
+ static LanguageRuntimeInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ LanguageRuntimeCreateInstance create_callback,
+ LanguageRuntimeGetCommandObject command_callback) {
+ if (create_callback) {
+ LanguageRuntimeInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.command_callback = command_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
+ GetLanguageRuntimeInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ LanguageRuntimeCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
+ LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
+
+ LanguageRuntimeInstances::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;
+ }
+ return false;
}
LanguageRuntimeCreateInstance
-PluginManager::GetLanguageRuntimeCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
- LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
+ LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
LanguageRuntimeGetCommandObject
-PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
- LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
- if (idx < instances.size())
- return instances[idx].command_callback;
- return nullptr;
+PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
+ LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
+ if (idx < instances.size())
+ return instances[idx].command_callback;
+ return nullptr;
}
LanguageRuntimeCreateInstance
-PluginManager::GetLanguageRuntimeCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
- LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances ();
-
- LanguageRuntimeInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetLanguageRuntimeCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex());
+ LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances();
+
+ LanguageRuntimeInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark SystemRuntime
-struct SystemRuntimeInstance
-{
- SystemRuntimeInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
+struct SystemRuntimeInstance {
+ SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {}
- ConstString name;
- std::string description;
- SystemRuntimeCreateInstance create_callback;
+ ConstString name;
+ std::string description;
+ SystemRuntimeCreateInstance create_callback;
};
typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances;
-static std::recursive_mutex &
-GetSystemRuntimeMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static SystemRuntimeInstances &
-GetSystemRuntimeInstances ()
-{
- static SystemRuntimeInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- SystemRuntimeCreateInstance create_callback)
-{
- if (create_callback)
- {
- SystemRuntimeInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
- GetSystemRuntimeInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetSystemRuntimeMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (SystemRuntimeCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
- SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
-
- SystemRuntimeInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static SystemRuntimeInstances &GetSystemRuntimeInstances() {
+ static SystemRuntimeInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ SystemRuntimeCreateInstance create_callback) {
+ if (create_callback) {
+ SystemRuntimeInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
+ GetSystemRuntimeInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ SystemRuntimeCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
+ SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
+
+ SystemRuntimeInstances::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;
+ }
+ return false;
}
SystemRuntimeCreateInstance
-PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
- SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
+ SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
SystemRuntimeCreateInstance
-PluginManager::GetSystemRuntimeCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
- SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
-
- SystemRuntimeInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetSystemRuntimeCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex());
+ SystemRuntimeInstances &instances = GetSystemRuntimeInstances();
+
+ SystemRuntimeInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark ObjectFile
-struct ObjectFileInstance
-{
- ObjectFileInstance() :
- name(),
- description(),
- create_callback(nullptr),
- create_memory_callback(nullptr),
- get_module_specifications(nullptr),
- save_core(nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- ObjectFileCreateInstance create_callback;
- ObjectFileCreateMemoryInstance create_memory_callback;
- ObjectFileGetModuleSpecifications get_module_specifications;
- ObjectFileSaveCore save_core;
+struct ObjectFileInstance {
+ ObjectFileInstance()
+ : name(), description(), create_callback(nullptr),
+ create_memory_callback(nullptr), get_module_specifications(nullptr),
+ save_core(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ ObjectFileCreateInstance create_callback;
+ ObjectFileCreateMemoryInstance create_memory_callback;
+ ObjectFileGetModuleSpecifications get_module_specifications;
+ ObjectFileSaveCore save_core;
};
typedef std::vector<ObjectFileInstance> ObjectFileInstances;
-static std::recursive_mutex &
-GetObjectFileMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static ObjectFileInstances &
-GetObjectFileInstances ()
-{
- static ObjectFileInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin (const ConstString &name,
- const char *description,
- ObjectFileCreateInstance create_callback,
- ObjectFileCreateMemoryInstance create_memory_callback,
- ObjectFileGetModuleSpecifications get_module_specifications,
- ObjectFileSaveCore save_core)
-{
- if (create_callback)
- {
- ObjectFileInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.create_memory_callback = create_memory_callback;
- instance.save_core = save_core;
- instance.get_module_specifications = get_module_specifications;
- std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
- GetObjectFileInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetObjectFileMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (ObjectFileCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
- ObjectFileInstances &instances = GetObjectFileInstances ();
-
- ObjectFileInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static ObjectFileInstances &GetObjectFileInstances() {
+ static ObjectFileInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ ObjectFileCreateInstance create_callback,
+ ObjectFileCreateMemoryInstance create_memory_callback,
+ ObjectFileGetModuleSpecifications get_module_specifications,
+ ObjectFileSaveCore save_core) {
+ if (create_callback) {
+ ObjectFileInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.create_memory_callback = create_memory_callback;
+ instance.save_core = save_core;
+ instance.get_module_specifications = get_module_specifications;
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
+ GetObjectFileInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
+ ObjectFileInstances &instances = GetObjectFileInstances();
+
+ ObjectFileInstances::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;
+ }
+ return false;
}
ObjectFileCreateInstance
-PluginManager::GetObjectFileCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
- ObjectFileInstances &instances = GetObjectFileInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
+ ObjectFileInstances &instances = GetObjectFileInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
ObjectFileCreateMemoryInstance
-PluginManager::GetObjectFileCreateMemoryCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
- ObjectFileInstances &instances = GetObjectFileInstances ();
- if (idx < instances.size())
- return instances[idx].create_memory_callback;
- return nullptr;
+PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
+ ObjectFileInstances &instances = GetObjectFileInstances();
+ if (idx < instances.size())
+ return instances[idx].create_memory_callback;
+ return nullptr;
}
ObjectFileGetModuleSpecifications
-PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
- ObjectFileInstances &instances = GetObjectFileInstances ();
- if (idx < instances.size())
- return instances[idx].get_module_specifications;
- return nullptr;
+PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
+ uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
+ ObjectFileInstances &instances = GetObjectFileInstances();
+ if (idx < instances.size())
+ return instances[idx].get_module_specifications;
+ return nullptr;
}
ObjectFileCreateInstance
-PluginManager::GetObjectFileCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
- ObjectFileInstances &instances = GetObjectFileInstances ();
-
- ObjectFileInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
- }
- return nullptr;
-}
+PluginManager::GetObjectFileCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
+ ObjectFileInstances &instances = GetObjectFileInstances();
-ObjectFileCreateMemoryInstance
-PluginManager::GetObjectFileCreateMemoryCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
- ObjectFileInstances &instances = GetObjectFileInstances ();
-
- ObjectFileInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_memory_callback;
- }
+ ObjectFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
-Error
-PluginManager::SaveCore (const lldb::ProcessSP &process_sp, const FileSpec &outfile)
-{
- Error error;
+ObjectFileCreateMemoryInstance
+PluginManager::GetObjectFileCreateMemoryCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
- ObjectFileInstances &instances = GetObjectFileInstances ();
-
+ ObjectFileInstances &instances = GetObjectFileInstances();
+
ObjectFileInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->save_core && pos->save_core (process_sp, outfile, error))
- return error;
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_memory_callback;
}
- error.SetErrorString("no ObjectFile plugins were able to save a core for this process");
- return error;
+ }
+ return nullptr;
+}
+
+Error PluginManager::SaveCore(const lldb::ProcessSP &process_sp,
+ const FileSpec &outfile) {
+ Error error;
+ std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex());
+ ObjectFileInstances &instances = GetObjectFileInstances();
+
+ ObjectFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (pos->save_core && pos->save_core(process_sp, outfile, error))
+ return error;
+ }
+ error.SetErrorString(
+ "no ObjectFile plugins were able to save a core for this process");
+ return error;
}
#pragma mark ObjectContainer
-struct ObjectContainerInstance
-{
- ObjectContainerInstance() :
- name(),
- description(),
- create_callback(nullptr),
- get_module_specifications(nullptr)
- {
- }
+struct ObjectContainerInstance {
+ ObjectContainerInstance()
+ : name(), description(), create_callback(nullptr),
+ get_module_specifications(nullptr) {}
- ConstString name;
- std::string description;
- ObjectContainerCreateInstance create_callback;
- ObjectFileGetModuleSpecifications get_module_specifications;
+ ConstString name;
+ std::string description;
+ ObjectContainerCreateInstance create_callback;
+ ObjectFileGetModuleSpecifications get_module_specifications;
};
typedef std::vector<ObjectContainerInstance> ObjectContainerInstances;
-static std::recursive_mutex &
-GetObjectContainerMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static ObjectContainerInstances &
-GetObjectContainerInstances ()
-{
- static ObjectContainerInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin (const ConstString &name,
- const char *description,
- ObjectContainerCreateInstance create_callback,
- ObjectFileGetModuleSpecifications get_module_specifications)
-{
- if (create_callback)
- {
- ObjectContainerInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.get_module_specifications = get_module_specifications;
- std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
- GetObjectContainerInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetObjectContainerMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (ObjectContainerCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
- ObjectContainerInstances &instances = GetObjectContainerInstances ();
-
- ObjectContainerInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static ObjectContainerInstances &GetObjectContainerInstances() {
+ static ObjectContainerInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ ObjectContainerCreateInstance create_callback,
+ ObjectFileGetModuleSpecifications get_module_specifications) {
+ if (create_callback) {
+ ObjectContainerInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.get_module_specifications = get_module_specifications;
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
+ GetObjectContainerInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ ObjectContainerCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
+ ObjectContainerInstances &instances = GetObjectContainerInstances();
+
+ ObjectContainerInstances::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;
+ }
+ return false;
}
ObjectContainerCreateInstance
-PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
- ObjectContainerInstances &instances = GetObjectContainerInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
+ ObjectContainerInstances &instances = GetObjectContainerInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
ObjectContainerCreateInstance
-PluginManager::GetObjectContainerCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
- ObjectContainerInstances &instances = GetObjectContainerInstances ();
-
- ObjectContainerInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetObjectContainerCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
+ ObjectContainerInstances &instances = GetObjectContainerInstances();
+
+ ObjectContainerInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
ObjectFileGetModuleSpecifications
-PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
- ObjectContainerInstances &instances = GetObjectContainerInstances ();
- if (idx < instances.size())
- return instances[idx].get_module_specifications;
- return nullptr;
+PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(
+ uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex());
+ ObjectContainerInstances &instances = GetObjectContainerInstances();
+ if (idx < instances.size())
+ return instances[idx].get_module_specifications;
+ return nullptr;
}
#pragma mark LogChannel
-struct LogInstance
-{
- LogInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
+struct LogInstance {
+ LogInstance() : name(), description(), create_callback(nullptr) {}
- ConstString name;
- std::string description;
- LogChannelCreateInstance create_callback;
+ ConstString name;
+ std::string description;
+ LogChannelCreateInstance create_callback;
};
typedef std::vector<LogInstance> LogInstances;
-static std::recursive_mutex &
-GetLogMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static LogInstances &
-GetLogInstances ()
-{
- static LogInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- LogChannelCreateInstance create_callback)
-{
- if (create_callback)
- {
- LogInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- GetLogInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetLogMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (LogChannelCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- LogInstances &instances = GetLogInstances ();
-
- LogInstances::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;
+static LogInstances &GetLogInstances() {
+ static LogInstances g_instances;
+ return g_instances;
}
-const char *
-PluginManager::GetLogChannelCreateNameAtIndex (uint32_t idx)
-{
+bool PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ LogChannelCreateInstance create_callback) {
+ if (create_callback) {
+ LogInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- LogInstances &instances = GetLogInstances ();
- if (idx < instances.size())
- return instances[idx].name.GetCString();
- return nullptr;
+ GetLogInstances().push_back(instance);
+ }
+ return false;
}
-LogChannelCreateInstance
-PluginManager::GetLogChannelCreateCallbackAtIndex (uint32_t idx)
-{
+bool PluginManager::UnregisterPlugin(LogChannelCreateInstance create_callback) {
+ if (create_callback) {
std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- LogInstances &instances = GetLogInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ LogInstances &instances = GetLogInstances();
+
+ LogInstances::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;
+}
+
+const char *PluginManager::GetLogChannelCreateNameAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
+ LogInstances &instances = GetLogInstances();
+ if (idx < instances.size())
+ return instances[idx].name.GetCString();
+ return nullptr;
}
LogChannelCreateInstance
-PluginManager::GetLogChannelCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
- LogInstances &instances = GetLogInstances ();
-
- LogInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetLogChannelCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
+ LogInstances &instances = GetLogInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
+}
+
+LogChannelCreateInstance
+PluginManager::GetLogChannelCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> gard(GetLogMutex());
+ LogInstances &instances = GetLogInstances();
+
+ LogInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark Platform
-struct PlatformInstance
-{
- PlatformInstance() :
- name(),
- description(),
- create_callback(nullptr),
- debugger_init_callback(nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- PlatformCreateInstance create_callback;
- DebuggerInitializeCallback debugger_init_callback;
+struct PlatformInstance {
+ PlatformInstance()
+ : name(), description(), create_callback(nullptr),
+ debugger_init_callback(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ PlatformCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<PlatformInstance> PlatformInstances;
-static std::recursive_mutex &
-GetPlatformInstancesMutex()
-{
- static std::recursive_mutex g_platform_instances_mutex;
- return g_platform_instances_mutex;
-}
-
-static PlatformInstances &
-GetPlatformInstances ()
-{
- static PlatformInstances g_platform_instances;
- return g_platform_instances;
-}
-
-bool
-PluginManager::RegisterPlugin (const ConstString &name,
- const char *description,
- PlatformCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
-
- PlatformInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.debugger_init_callback = debugger_init_callback;
- GetPlatformInstances ().push_back (instance);
- return true;
- }
- return false;
+static std::recursive_mutex &GetPlatformInstancesMutex() {
+ static std::recursive_mutex g_platform_instances_mutex;
+ return g_platform_instances_mutex;
}
-const char *
-PluginManager::GetPlatformPluginNameAtIndex (uint32_t idx)
-{
+static PlatformInstances &GetPlatformInstances() {
+ static PlatformInstances g_platform_instances;
+ return g_platform_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ PlatformCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback) {
+ if (create_callback) {
std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
- PlatformInstances &instances = GetPlatformInstances ();
- if (idx < instances.size())
- return instances[idx].name.GetCString();
- return nullptr;
+
+ PlatformInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
+ GetPlatformInstances().push_back(instance);
+ return true;
+ }
+ return false;
+}
+
+const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+ PlatformInstances &instances = GetPlatformInstances();
+ if (idx < instances.size())
+ return instances[idx].name.GetCString();
+ return nullptr;
}
-const char *
-PluginManager::GetPlatformPluginDescriptionAtIndex (uint32_t idx)
-{
+const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+ PlatformInstances &instances = GetPlatformInstances();
+ if (idx < instances.size())
+ return instances[idx].description.c_str();
+ return nullptr;
+}
+
+bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) {
+ if (create_callback) {
std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
- PlatformInstances &instances = GetPlatformInstances ();
- if (idx < instances.size())
- return instances[idx].description.c_str();
- return nullptr;
-}
-
-bool
-PluginManager::UnregisterPlugin (PlatformCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
- PlatformInstances &instances = GetPlatformInstances ();
-
- PlatformInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+ PlatformInstances &instances = GetPlatformInstances();
+
+ PlatformInstances::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;
+ }
+ return false;
}
PlatformCreateInstance
-PluginManager::GetPlatformCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
- PlatformInstances &instances = GetPlatformInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+ PlatformInstances &instances = GetPlatformInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
PlatformCreateInstance
-PluginManager::GetPlatformCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
- PlatformInstances &instances = GetPlatformInstances ();
-
- PlatformInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetPlatformCreateCallbackForPluginName(const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+ PlatformInstances &instances = GetPlatformInstances();
+
+ PlatformInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
-size_t
-PluginManager::AutoCompletePlatformName (const char *name, StringList &matches)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
- PlatformInstances &instances = GetPlatformInstances ();
- llvm::StringRef name_sref(name);
-
- PlatformInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- llvm::StringRef plugin_name (pos->name.GetCString());
- if (plugin_name.startswith(name_sref))
- matches.AppendString (plugin_name.data());
- }
- }
+size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
+ StringList &matches) {
+ if (name.empty())
return matches.GetSize();
+
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+ PlatformInstances &instances = GetPlatformInstances();
+ llvm::StringRef name_sref(name);
+
+ PlatformInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ llvm::StringRef plugin_name(pos->name.GetCString());
+ if (plugin_name.startswith(name_sref))
+ matches.AppendString(plugin_name.data());
+ }
+ return matches.GetSize();
}
#pragma mark Process
-struct ProcessInstance
-{
- ProcessInstance() :
- name(),
- description(),
- create_callback(nullptr),
- debugger_init_callback(nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- ProcessCreateInstance create_callback;
- DebuggerInitializeCallback debugger_init_callback;
+struct ProcessInstance {
+ ProcessInstance()
+ : name(), description(), create_callback(nullptr),
+ debugger_init_callback(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ ProcessCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<ProcessInstance> ProcessInstances;
-static std::recursive_mutex &
-GetProcessMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static ProcessInstances &
-GetProcessInstances ()
-{
- static ProcessInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin (const ConstString &name,
- const char *description,
- ProcessCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback)
-{
- if (create_callback)
- {
- ProcessInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.debugger_init_callback = debugger_init_callback;
- std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
- GetProcessInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetProcessMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
+}
+
+static ProcessInstances &GetProcessInstances() {
+ static ProcessInstances g_instances;
+ return g_instances;
}
-const char *
-PluginManager::GetProcessPluginNameAtIndex (uint32_t idx)
-{
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ ProcessCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback) {
+ if (create_callback) {
+ ProcessInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
- ProcessInstances &instances = GetProcessInstances ();
- if (idx < instances.size())
- return instances[idx].name.GetCString();
- return nullptr;
+ GetProcessInstances().push_back(instance);
+ }
+ return false;
+}
+
+const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
+ ProcessInstances &instances = GetProcessInstances();
+ if (idx < instances.size())
+ return instances[idx].name.GetCString();
+ return nullptr;
}
-const char *
-PluginManager::GetProcessPluginDescriptionAtIndex (uint32_t idx)
-{
+const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
+ ProcessInstances &instances = GetProcessInstances();
+ if (idx < instances.size())
+ return instances[idx].description.c_str();
+ return nullptr;
+}
+
+bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) {
+ if (create_callback) {
std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
- ProcessInstances &instances = GetProcessInstances ();
- if (idx < instances.size())
- return instances[idx].description.c_str();
- return nullptr;
-}
-
-bool
-PluginManager::UnregisterPlugin (ProcessCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
- ProcessInstances &instances = GetProcessInstances ();
-
- ProcessInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+ ProcessInstances &instances = GetProcessInstances();
+
+ ProcessInstances::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;
+ }
+ return false;
}
ProcessCreateInstance
-PluginManager::GetProcessCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
- ProcessInstances &instances = GetProcessInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
+ ProcessInstances &instances = GetProcessInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
ProcessCreateInstance
-PluginManager::GetProcessCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
- ProcessInstances &instances = GetProcessInstances ();
-
- ProcessInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetProcessCreateCallbackForPluginName(const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
+ ProcessInstances &instances = GetProcessInstances();
+
+ ProcessInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark ScriptInterpreter
-struct ScriptInterpreterInstance
-{
- ScriptInterpreterInstance()
- : name()
- , language(lldb::eScriptLanguageNone)
- , description()
- , create_callback(nullptr)
- {
- }
+struct ScriptInterpreterInstance {
+ ScriptInterpreterInstance()
+ : name(), language(lldb::eScriptLanguageNone), description(),
+ create_callback(nullptr) {}
- ConstString name;
- lldb::ScriptLanguage language;
- std::string description;
- ScriptInterpreterCreateInstance create_callback;
+ ConstString name;
+ lldb::ScriptLanguage language;
+ std::string description;
+ ScriptInterpreterCreateInstance create_callback;
};
typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances;
-static std::recursive_mutex &
-GetScriptInterpreterMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
+static std::recursive_mutex &GetScriptInterpreterMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-static ScriptInterpreterInstances &
-GetScriptInterpreterInstances()
-{
- static ScriptInterpreterInstances g_instances;
- return g_instances;
+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;
- std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
- GetScriptInterpreterInstances().push_back(instance);
+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;
+ std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
+ GetScriptInterpreterInstances().push_back(instance);
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ ScriptInterpreterCreateInstance create_callback) {
+ if (!create_callback)
return false;
+ std::lock_guard<std::recursive_mutex> guard(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;
}
-bool
-PluginManager::UnregisterPlugin(ScriptInterpreterCreateInstance create_callback)
-{
- if (!create_callback)
- return false;
- std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
- ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
+ScriptInterpreterCreateInstance
+PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(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) {
+ std::lock_guard<std::recursive_mutex> guard(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 -
+#pragma mark StructuredDataPlugin
+
+// -----------------------------------------------------------------------------
+// StructuredDataPlugin
+// -----------------------------------------------------------------------------
+
+struct StructuredDataPluginInstance {
+ StructuredDataPluginInstance()
+ : name(), description(), create_callback(nullptr),
+ debugger_init_callback(nullptr), filter_callback(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ StructuredDataPluginCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
+ StructuredDataFilterLaunchInfo filter_callback;
+};
+
+typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
- ScriptInterpreterInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++pos)
- {
- if (pos->create_callback != create_callback)
- continue;
+static std::recursive_mutex &GetStructuredDataPluginMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
+}
+static StructuredDataPluginInstances &GetStructuredDataPluginInstances() {
+ static StructuredDataPluginInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ StructuredDataPluginCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback,
+ StructuredDataFilterLaunchInfo filter_callback) {
+ if (create_callback) {
+ StructuredDataPluginInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
+ instance.filter_callback = filter_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
+ GetStructuredDataPluginInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ StructuredDataPluginCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
+ StructuredDataPluginInstances &instances =
+ GetStructuredDataPluginInstances();
+
+ StructuredDataPluginInstances::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;
+ }
+ return false;
}
-ScriptInterpreterCreateInstance
-PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex());
- ScriptInterpreterInstances &instances = GetScriptInterpreterInstances();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+StructuredDataPluginCreateInstance
+PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
+ StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
-lldb::ScriptInterpreterSP
-PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, CommandInterpreter &interpreter)
-{
- std::lock_guard<std::recursive_mutex> guard(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;
+StructuredDataPluginCreateInstance
+PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
+ StructuredDataPluginInstances &instances =
+ GetStructuredDataPluginInstances();
- if (script_lang == pos->language)
- return pos->create_callback(interpreter);
+ StructuredDataPluginInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
+ }
+ return nullptr;
+}
- // If we didn't find one, return the ScriptInterpreter for the null language.
- assert(none_instance != nullptr);
- return none_instance(interpreter);
+StructuredDataFilterLaunchInfo
+PluginManager::GetStructuredDataFilterCallbackAtIndex(
+ uint32_t idx, bool &iteration_complete) {
+ std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
+ StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances();
+ if (idx < instances.size()) {
+ iteration_complete = false;
+ return instances[idx].filter_callback;
+ } else {
+ iteration_complete = true;
+ }
+ return nullptr;
}
#pragma mark SymbolFile
-struct SymbolFileInstance
-{
- SymbolFileInstance() :
- name(),
- description(),
- create_callback(nullptr),
- debugger_init_callback(nullptr)
- {
- }
+struct SymbolFileInstance {
+ SymbolFileInstance()
+ : name(), description(), create_callback(nullptr),
+ debugger_init_callback(nullptr) {}
- ConstString name;
- std::string description;
- SymbolFileCreateInstance create_callback;
- DebuggerInitializeCallback debugger_init_callback;
+ ConstString name;
+ std::string description;
+ SymbolFileCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
};
typedef std::vector<SymbolFileInstance> SymbolFileInstances;
-static std::recursive_mutex &
-GetSymbolFileMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static SymbolFileInstances &
-GetSymbolFileInstances ()
-{
- static SymbolFileInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- SymbolFileCreateInstance create_callback,
- DebuggerInitializeCallback debugger_init_callback)
-{
- if (create_callback)
- {
- SymbolFileInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.debugger_init_callback = debugger_init_callback;
- std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
- GetSymbolFileInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetSymbolFileMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (SymbolFileCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
- SymbolFileInstances &instances = GetSymbolFileInstances ();
-
- SymbolFileInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static SymbolFileInstances &GetSymbolFileInstances() {
+ static SymbolFileInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ SymbolFileCreateInstance create_callback,
+ DebuggerInitializeCallback debugger_init_callback) {
+ if (create_callback) {
+ SymbolFileInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.debugger_init_callback = debugger_init_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
+ GetSymbolFileInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
+ SymbolFileInstances &instances = GetSymbolFileInstances();
+
+ SymbolFileInstances::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;
+ }
+ return false;
}
SymbolFileCreateInstance
-PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
- SymbolFileInstances &instances = GetSymbolFileInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
+ SymbolFileInstances &instances = GetSymbolFileInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
SymbolFileCreateInstance
-PluginManager::GetSymbolFileCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
- SymbolFileInstances &instances = GetSymbolFileInstances ();
-
- SymbolFileInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetSymbolFileCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
+ SymbolFileInstances &instances = GetSymbolFileInstances();
+
+ SymbolFileInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark SymbolVendor
-struct SymbolVendorInstance
-{
- SymbolVendorInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
+struct SymbolVendorInstance {
+ SymbolVendorInstance() : name(), description(), create_callback(nullptr) {}
- ConstString name;
- std::string description;
- SymbolVendorCreateInstance create_callback;
+ ConstString name;
+ std::string description;
+ SymbolVendorCreateInstance create_callback;
};
typedef std::vector<SymbolVendorInstance> SymbolVendorInstances;
-static std::recursive_mutex &
-GetSymbolVendorMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static SymbolVendorInstances &
-GetSymbolVendorInstances ()
-{
- static SymbolVendorInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- SymbolVendorCreateInstance create_callback)
-{
- if (create_callback)
- {
- SymbolVendorInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
- GetSymbolVendorInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetSymbolVendorMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (SymbolVendorCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
- SymbolVendorInstances &instances = GetSymbolVendorInstances ();
-
- SymbolVendorInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static SymbolVendorInstances &GetSymbolVendorInstances() {
+ static SymbolVendorInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(const ConstString &name,
+ const char *description,
+ SymbolVendorCreateInstance create_callback) {
+ if (create_callback) {
+ SymbolVendorInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
+ GetSymbolVendorInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ SymbolVendorCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
+ SymbolVendorInstances &instances = GetSymbolVendorInstances();
+
+ SymbolVendorInstances::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;
+ }
+ return false;
}
SymbolVendorCreateInstance
-PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
- SymbolVendorInstances &instances = GetSymbolVendorInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
+ SymbolVendorInstances &instances = GetSymbolVendorInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
SymbolVendorCreateInstance
-PluginManager::GetSymbolVendorCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
- SymbolVendorInstances &instances = GetSymbolVendorInstances ();
-
- SymbolVendorInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetSymbolVendorCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex());
+ SymbolVendorInstances &instances = GetSymbolVendorInstances();
+
+ SymbolVendorInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark UnwindAssembly
-struct UnwindAssemblyInstance
-{
- UnwindAssemblyInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
+struct UnwindAssemblyInstance {
+ UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {}
- ConstString name;
- std::string description;
- UnwindAssemblyCreateInstance create_callback;
+ ConstString name;
+ std::string description;
+ UnwindAssemblyCreateInstance create_callback;
};
typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances;
-static std::recursive_mutex &
-GetUnwindAssemblyMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static UnwindAssemblyInstances &
-GetUnwindAssemblyInstances ()
-{
- static UnwindAssemblyInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- UnwindAssemblyCreateInstance create_callback)
-{
- if (create_callback)
- {
- UnwindAssemblyInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
- GetUnwindAssemblyInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetUnwindAssemblyMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (UnwindAssemblyCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
- UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
-
- UnwindAssemblyInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static UnwindAssemblyInstances &GetUnwindAssemblyInstances() {
+ static UnwindAssemblyInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ UnwindAssemblyCreateInstance create_callback) {
+ if (create_callback) {
+ UnwindAssemblyInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
+ GetUnwindAssemblyInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ UnwindAssemblyCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
+ UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
+
+ UnwindAssemblyInstances::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;
+ }
+ return false;
}
UnwindAssemblyCreateInstance
-PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
- UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
+ UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
UnwindAssemblyCreateInstance
-PluginManager::GetUnwindAssemblyCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
- UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
-
- UnwindAssemblyInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetUnwindAssemblyCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex());
+ UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances();
+
+ UnwindAssemblyInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark MemoryHistory
-struct MemoryHistoryInstance
-{
- MemoryHistoryInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- MemoryHistoryCreateInstance create_callback;
+struct MemoryHistoryInstance {
+ MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ MemoryHistoryCreateInstance create_callback;
};
typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances;
-static std::recursive_mutex &
-GetMemoryHistoryMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static MemoryHistoryInstances &
-GetMemoryHistoryInstances ()
-{
- static MemoryHistoryInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- MemoryHistoryCreateInstance create_callback)
-{
- if (create_callback)
- {
- MemoryHistoryInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
- GetMemoryHistoryInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetMemoryHistoryMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (MemoryHistoryCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
- MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
-
- MemoryHistoryInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static MemoryHistoryInstances &GetMemoryHistoryInstances() {
+ static MemoryHistoryInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ MemoryHistoryCreateInstance create_callback) {
+ if (create_callback) {
+ MemoryHistoryInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
+ GetMemoryHistoryInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ MemoryHistoryCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
+ MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
+
+ MemoryHistoryInstances::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;
+ }
+ return false;
}
MemoryHistoryCreateInstance
-PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
- MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
+ MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
MemoryHistoryCreateInstance
-PluginManager::GetMemoryHistoryCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
- MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
-
- MemoryHistoryInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetMemoryHistoryCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex());
+ MemoryHistoryInstances &instances = GetMemoryHistoryInstances();
+
+ MemoryHistoryInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark InstrumentationRuntime
-struct InstrumentationRuntimeInstance
-{
- InstrumentationRuntimeInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- InstrumentationRuntimeCreateInstance create_callback;
- InstrumentationRuntimeGetType get_type_callback;
+struct InstrumentationRuntimeInstance {
+ InstrumentationRuntimeInstance()
+ : name(), description(), create_callback(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ InstrumentationRuntimeCreateInstance create_callback;
+ InstrumentationRuntimeGetType get_type_callback;
};
-typedef std::vector<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances;
-
-static std::recursive_mutex &
-GetInstrumentationRuntimeMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
-}
-
-static InstrumentationRuntimeInstances &
-GetInstrumentationRuntimeInstances ()
-{
- static InstrumentationRuntimeInstances g_instances;
- return g_instances;
-}
-
-bool
-PluginManager::RegisterPlugin(const ConstString &name,
- const char *description,
- InstrumentationRuntimeCreateInstance create_callback,
- InstrumentationRuntimeGetType get_type_callback)
-{
- if (create_callback)
- {
- InstrumentationRuntimeInstance instance;
- assert ((bool)name);
- instance.name = name;
- if (description && description[0])
- instance.description = description;
- instance.create_callback = create_callback;
- instance.get_type_callback = get_type_callback;
- std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
- GetInstrumentationRuntimeInstances ().push_back (instance);
- }
- return false;
+typedef std::vector<InstrumentationRuntimeInstance>
+ InstrumentationRuntimeInstances;
+
+static std::recursive_mutex &GetInstrumentationRuntimeMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (InstrumentationRuntimeCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
- InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
-
- InstrumentationRuntimeInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->create_callback == create_callback)
- {
- instances.erase(pos);
- return true;
- }
- }
+static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() {
+ static InstrumentationRuntimeInstances g_instances;
+ return g_instances;
+}
+
+bool PluginManager::RegisterPlugin(
+ const ConstString &name, const char *description,
+ InstrumentationRuntimeCreateInstance create_callback,
+ InstrumentationRuntimeGetType get_type_callback) {
+ if (create_callback) {
+ InstrumentationRuntimeInstance instance;
+ assert((bool)name);
+ instance.name = name;
+ if (description && description[0])
+ instance.description = description;
+ instance.create_callback = create_callback;
+ instance.get_type_callback = get_type_callback;
+ std::lock_guard<std::recursive_mutex> guard(
+ GetInstrumentationRuntimeMutex());
+ GetInstrumentationRuntimeInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(
+ InstrumentationRuntimeCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetInstrumentationRuntimeMutex());
+ InstrumentationRuntimeInstances &instances =
+ GetInstrumentationRuntimeInstances();
+
+ InstrumentationRuntimeInstances::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;
+ }
+ return false;
}
InstrumentationRuntimeGetType
-PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
- InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
- if (idx < instances.size())
- return instances[idx].get_type_callback;
- return nullptr;
+PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
+ InstrumentationRuntimeInstances &instances =
+ GetInstrumentationRuntimeInstances();
+ if (idx < instances.size())
+ return instances[idx].get_type_callback;
+ return nullptr;
}
InstrumentationRuntimeCreateInstance
-PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
- InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
+ InstrumentationRuntimeInstances &instances =
+ GetInstrumentationRuntimeInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
InstrumentationRuntimeCreateInstance
-PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex());
- InstrumentationRuntimeInstances &instances = GetInstrumentationRuntimeInstances ();
-
- InstrumentationRuntimeInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (name == pos->name)
- return pos->create_callback;
- }
+PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(
+ GetInstrumentationRuntimeMutex());
+ InstrumentationRuntimeInstances &instances =
+ GetInstrumentationRuntimeInstances();
+
+ InstrumentationRuntimeInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- return nullptr;
+ }
+ return nullptr;
}
#pragma mark TypeSystem
-struct TypeSystemInstance
-{
- TypeSystemInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
+struct TypeSystemInstance {
+ TypeSystemInstance() : name(), description(), create_callback(nullptr) {}
- ConstString name;
- std::string description;
- TypeSystemCreateInstance create_callback;
- TypeSystemEnumerateSupportedLanguages enumerate_callback;
+ ConstString name;
+ std::string description;
+ TypeSystemCreateInstance create_callback;
+ TypeSystemEnumerateSupportedLanguages enumerate_callback;
};
typedef std::vector<TypeSystemInstance> TypeSystemInstances;
-static std::recursive_mutex &
-GetTypeSystemMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- 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;
- std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
- GetTypeSystemInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetTypeSystemMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (TypeSystemCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(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;
- }
- }
+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;
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
+ GetTypeSystemInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) {
+ if (create_callback) {
+ std::lock_guard<std::recursive_mutex> guard(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;
+ }
+ return false;
}
TypeSystemCreateInstance
-PluginManager::GetTypeSystemCreateCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
- TypeSystemInstances &instances = GetTypeSystemInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
+ TypeSystemInstances &instances = GetTypeSystemInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
TypeSystemCreateInstance
-PluginManager::GetTypeSystemCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(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;
- }
+PluginManager::GetTypeSystemCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(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 nullptr;
+ }
+ return nullptr;
}
TypeSystemEnumerateSupportedLanguages
-PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
- TypeSystemInstances &instances = GetTypeSystemInstances ();
- if (idx < instances.size())
- return instances[idx].enumerate_callback;
- return nullptr;
+PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
+ uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
+ TypeSystemInstances &instances = GetTypeSystemInstances();
+ if (idx < instances.size())
+ return instances[idx].enumerate_callback;
+ return nullptr;
}
TypeSystemEnumerateSupportedLanguages
-PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(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;
- }
+PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(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 nullptr;
+ }
+ return nullptr;
}
#pragma mark REPL
-struct REPLInstance
-{
- REPLInstance() :
- name(),
- description(),
- create_callback(nullptr)
- {
- }
-
- ConstString name;
- std::string description;
- REPLCreateInstance create_callback;
- REPLEnumerateSupportedLanguages enumerate_languages_callback;
+struct REPLInstance {
+ REPLInstance() : name(), description(), create_callback(nullptr) {}
+
+ ConstString name;
+ std::string description;
+ REPLCreateInstance create_callback;
+ REPLEnumerateSupportedLanguages enumerate_languages_callback;
};
typedef std::vector<REPLInstance> REPLInstances;
-static std::recursive_mutex &
-GetREPLMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- 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;
- std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
- GetREPLInstances ().push_back (instance);
- }
- return false;
+static std::recursive_mutex &GetREPLMutex() {
+ static std::recursive_mutex g_instances_mutex;
+ return g_instances_mutex;
}
-bool
-PluginManager::UnregisterPlugin (REPLCreateInstance create_callback)
-{
- if (create_callback)
- {
- std::lock_guard<std::recursive_mutex> guard(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;
+static REPLInstances &GetREPLInstances() {
+ static REPLInstances g_instances;
+ return g_instances;
}
-REPLCreateInstance
-PluginManager::GetREPLCreateCallbackAtIndex (uint32_t idx)
-{
+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;
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
+ GetREPLInstances().push_back(instance);
+ }
+ return false;
+}
+
+bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) {
+ if (create_callback) {
std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
- REPLInstances &instances = GetREPLInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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) {
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
+ REPLInstances &instances = GetREPLInstances();
+ if (idx < instances.size())
+ return instances[idx].create_callback;
+ return nullptr;
}
REPLCreateInstance
-PluginManager::GetREPLCreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(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;
- }
+PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(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 nullptr;
+ }
+ return nullptr;
}
REPLEnumerateSupportedLanguages
-PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
-{
- std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
- REPLInstances &instances = GetREPLInstances ();
- if (idx < instances.size())
- return instances[idx].enumerate_languages_callback;
- return nullptr;
+PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
+ std::lock_guard<std::recursive_mutex> guard(GetREPLMutex());
+ REPLInstances &instances = GetREPLInstances();
+ if (idx < instances.size())
+ return instances[idx].enumerate_languages_callback;
+ return nullptr;
}
REPLEnumerateSupportedLanguages
-PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(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;
- }
+PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
+ std::lock_guard<std::recursive_mutex> guard(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 nullptr;
+ }
+ return nullptr;
}
#pragma mark PluginManager
-void
-PluginManager::DebuggerInitialize (Debugger &debugger)
-{
- // Initialize the DynamicLoader plugins
- {
- std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
- DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
-
- DynamicLoaderInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->debugger_init_callback)
- pos->debugger_init_callback (debugger);
- }
+void PluginManager::DebuggerInitialize(Debugger &debugger) {
+ // Initialize the DynamicLoader plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex());
+ DynamicLoaderInstances &instances = GetDynamicLoaderInstances();
+
+ DynamicLoaderInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (pos->debugger_init_callback)
+ pos->debugger_init_callback(debugger);
}
+ }
- // Initialize the JITLoader plugins
- {
- std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
- JITLoaderInstances &instances = GetJITLoaderInstances ();
-
- JITLoaderInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->debugger_init_callback)
- pos->debugger_init_callback (debugger);
- }
+ // Initialize the JITLoader plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
+ JITLoaderInstances &instances = GetJITLoaderInstances();
+
+ JITLoaderInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (pos->debugger_init_callback)
+ pos->debugger_init_callback(debugger);
}
+ }
- // Initialize the Platform plugins
- {
- std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
- PlatformInstances &instances = GetPlatformInstances ();
-
- PlatformInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->debugger_init_callback)
- pos->debugger_init_callback (debugger);
- }
+ // Initialize the Platform plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+ PlatformInstances &instances = GetPlatformInstances();
+
+ PlatformInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (pos->debugger_init_callback)
+ pos->debugger_init_callback(debugger);
}
+ }
- // Initialize the Process plugins
- {
- std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
- ProcessInstances &instances = GetProcessInstances();
-
- ProcessInstances::iterator pos, end = instances.end();
- for (pos = instances.begin(); pos != end; ++ pos)
- {
- if (pos->debugger_init_callback)
- pos->debugger_init_callback (debugger);
- }
+ // Initialize the Process plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetProcessMutex());
+ ProcessInstances &instances = GetProcessInstances();
+
+ ProcessInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (pos->debugger_init_callback)
+ pos->debugger_init_callback(debugger);
}
+ }
- // Initialize the SymbolFile plugins
- {
- std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
- for (auto& sym_file: GetSymbolFileInstances())
- {
- if (sym_file.debugger_init_callback)
- sym_file.debugger_init_callback (debugger);
- }
+ // Initialize the SymbolFile plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex());
+ for (auto &sym_file : GetSymbolFileInstances()) {
+ if (sym_file.debugger_init_callback)
+ sym_file.debugger_init_callback(debugger);
}
+ }
- // Initialize the OperatingSystem plugins
- {
- std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
- for (auto &os : GetOperatingSystemInstances())
- {
- if (os.debugger_init_callback)
- os.debugger_init_callback(debugger);
- }
+ // Initialize the OperatingSystem plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex());
+ for (auto &os : GetOperatingSystemInstances()) {
+ if (os.debugger_init_callback)
+ os.debugger_init_callback(debugger);
+ }
+ }
+
+ // Initialize the StructuredDataPlugin plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
+ for (auto &plugin : GetStructuredDataPluginInstances()) {
+ if (plugin.debugger_init_callback)
+ plugin.debugger_init_callback(debugger);
}
+ }
}
// This is the preferred new way to register plugin specific settings. e.g.
-// This will put a plugin's settings under e.g. "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
-static lldb::OptionValuePropertiesSP
-GetDebuggerPropertyForPlugins (Debugger &debugger,
- const ConstString &plugin_type_name,
- const ConstString &plugin_type_desc,
- bool can_create)
-{
- lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
- if (parent_properties_sp)
- {
- static ConstString g_property_name("plugin");
-
- OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty(nullptr, g_property_name);
- if (!plugin_properties_sp && can_create)
- {
- plugin_properties_sp.reset (new OptionValueProperties (g_property_name));
- parent_properties_sp->AppendProperty (g_property_name,
- ConstString("Settings specify to plugins."),
- true,
- plugin_properties_sp);
- }
-
- if (plugin_properties_sp)
- {
- lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
- if (!plugin_type_properties_sp && can_create)
- {
- plugin_type_properties_sp.reset (new OptionValueProperties (plugin_type_name));
- plugin_properties_sp->AppendProperty (plugin_type_name,
- plugin_type_desc,
- true,
- plugin_type_properties_sp);
- }
- return plugin_type_properties_sp;
- }
+// This will put a plugin's settings under e.g.
+// "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME".
+static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPlugins(
+ Debugger &debugger, const ConstString &plugin_type_name,
+ const ConstString &plugin_type_desc, bool can_create) {
+ lldb::OptionValuePropertiesSP parent_properties_sp(
+ debugger.GetValueProperties());
+ if (parent_properties_sp) {
+ static ConstString g_property_name("plugin");
+
+ OptionValuePropertiesSP plugin_properties_sp =
+ parent_properties_sp->GetSubProperty(nullptr, g_property_name);
+ if (!plugin_properties_sp && can_create) {
+ plugin_properties_sp.reset(new OptionValueProperties(g_property_name));
+ parent_properties_sp->AppendProperty(
+ g_property_name, ConstString("Settings specify to plugins."), true,
+ plugin_properties_sp);
}
- return lldb::OptionValuePropertiesSP();
+
+ if (plugin_properties_sp) {
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp =
+ plugin_properties_sp->GetSubProperty(nullptr, plugin_type_name);
+ if (!plugin_type_properties_sp && can_create) {
+ plugin_type_properties_sp.reset(
+ new OptionValueProperties(plugin_type_name));
+ plugin_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
+ true, plugin_type_properties_sp);
+ }
+ return plugin_type_properties_sp;
+ }
+ }
+ return lldb::OptionValuePropertiesSP();
}
// This is deprecated way to register plugin specific settings. e.g.
// "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME"
// and Platform generic settings would be under "platform.SETTINGNAME".
-static lldb::OptionValuePropertiesSP
-GetDebuggerPropertyForPluginsOldStyle (Debugger &debugger,
- const ConstString &plugin_type_name,
- const ConstString &plugin_type_desc,
- bool can_create)
-{
- static ConstString g_property_name("plugin");
- lldb::OptionValuePropertiesSP parent_properties_sp (debugger.GetValueProperties());
- if (parent_properties_sp)
- {
- OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
- if (!plugin_properties_sp && can_create)
- {
- plugin_properties_sp.reset (new OptionValueProperties (plugin_type_name));
- parent_properties_sp->AppendProperty (plugin_type_name,
- plugin_type_desc,
- true,
- plugin_properties_sp);
- }
-
- if (plugin_properties_sp)
- {
- lldb::OptionValuePropertiesSP plugin_type_properties_sp = plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
- if (!plugin_type_properties_sp && can_create)
- {
- plugin_type_properties_sp.reset (new OptionValueProperties (g_property_name));
- plugin_properties_sp->AppendProperty (g_property_name,
- ConstString("Settings specific to plugins"),
- true,
- plugin_type_properties_sp);
- }
- return plugin_type_properties_sp;
- }
- }
- return lldb::OptionValuePropertiesSP();
+static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle(
+ Debugger &debugger, const ConstString &plugin_type_name,
+ const ConstString &plugin_type_desc, bool can_create) {
+ static ConstString g_property_name("plugin");
+ lldb::OptionValuePropertiesSP parent_properties_sp(
+ debugger.GetValueProperties());
+ if (parent_properties_sp) {
+ OptionValuePropertiesSP plugin_properties_sp =
+ parent_properties_sp->GetSubProperty(nullptr, plugin_type_name);
+ if (!plugin_properties_sp && can_create) {
+ plugin_properties_sp.reset(new OptionValueProperties(plugin_type_name));
+ parent_properties_sp->AppendProperty(plugin_type_name, plugin_type_desc,
+ true, plugin_properties_sp);
+ }
+
+ if (plugin_properties_sp) {
+ lldb::OptionValuePropertiesSP plugin_type_properties_sp =
+ plugin_properties_sp->GetSubProperty(nullptr, g_property_name);
+ if (!plugin_type_properties_sp && can_create) {
+ plugin_type_properties_sp.reset(
+ new OptionValueProperties(g_property_name));
+ plugin_properties_sp->AppendProperty(
+ g_property_name, ConstString("Settings specific to plugins"), true,
+ plugin_type_properties_sp);
+ }
+ return plugin_type_properties_sp;
+ }
+ }
+ return lldb::OptionValuePropertiesSP();
}
namespace {
typedef lldb::OptionValuePropertiesSP
-GetDebuggerPropertyForPluginsPtr (Debugger&, const ConstString&, const ConstString&, bool can_create);
+GetDebuggerPropertyForPluginsPtr(Debugger &, const ConstString &,
+ const ConstString &, bool can_create);
lldb::OptionValuePropertiesSP
-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 (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 (nullptr, setting_name);
- return properties_sp;
-}
-
-bool
-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 (get_debugger_property (
- debugger, plugin_type_name, plugin_type_desc, true));
- if (plugin_type_properties_sp)
- {
- plugin_type_properties_sp->AppendProperty (properties_sp->GetName(),
- description,
- is_global_property,
- properties_sp);
- return true;
- }
+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(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(nullptr, setting_name);
+ return properties_sp;
+}
+
+bool 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(
+ get_debugger_property(debugger, plugin_type_name, plugin_type_desc,
+ 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 false;
}
-const char* kDynamicLoaderPluginName("dynamic-loader");
-const char* kPlatformPluginName("platform");
-const char* kProcessPluginName("process");
-const char* kSymbolFilePluginName("symbol-file");
-const char* kJITLoaderPluginName("jit-loader");
+const char *kDynamicLoaderPluginName("dynamic-loader");
+const char *kPlatformPluginName("platform");
+const char *kProcessPluginName("process");
+const char *kSymbolFilePluginName("symbol-file");
+const char *kJITLoaderPluginName("jit-loader");
+const char *kStructuredDataPluginName("structured-data");
} // anonymous namespace
-lldb::OptionValuePropertiesSP
-PluginManager::GetSettingForDynamicLoaderPlugin (Debugger &debugger,
- const ConstString &setting_name)
-{
- return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName));
-}
-
-bool
-PluginManager::CreateSettingForDynamicLoaderPlugin (Debugger &debugger,
- const lldb::OptionValuePropertiesSP &properties_sp,
- const ConstString &description,
- bool is_global_property)
-{
- return CreateSettingForPlugin(debugger,
- ConstString(kDynamicLoaderPluginName),
- ConstString("Settings for dynamic loader plug-ins"),
- properties_sp,
- description,
- is_global_property);
+lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(
+ Debugger &debugger, const ConstString &setting_name) {
+ return GetSettingForPlugin(debugger, setting_name,
+ ConstString(kDynamicLoaderPluginName));
+}
+
+bool PluginManager::CreateSettingForDynamicLoaderPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ const ConstString &description, bool is_global_property) {
+ 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);
+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)
-{
- return GetSettingForPlugin(debugger, setting_name, ConstString(kProcessPluginName));
+PluginManager::GetSettingForProcessPlugin(Debugger &debugger,
+ const ConstString &setting_name) {
+ return GetSettingForPlugin(debugger, setting_name,
+ ConstString(kProcessPluginName));
}
-bool
-PluginManager::CreateSettingForProcessPlugin (Debugger &debugger,
- const lldb::OptionValuePropertiesSP &properties_sp,
- const ConstString &description,
- bool is_global_property)
-{
- return CreateSettingForPlugin(debugger,
- ConstString(kProcessPluginName),
- ConstString("Settings for process plug-ins"),
- properties_sp,
- description,
- is_global_property);
+bool PluginManager::CreateSettingForProcessPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ 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);
+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);
+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 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(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(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);
- return true;
- }
- }
- return false;
+ 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);
+ return true;
+ }
+ }
+ return false;
+}
+
+lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(
+ Debugger &debugger, const ConstString &setting_name) {
+ return GetSettingForPlugin(debugger, setting_name,
+ ConstString(kStructuredDataPluginName));
+}
+
+bool PluginManager::CreateSettingForStructuredDataPlugin(
+ Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp,
+ const ConstString &description, bool is_global_property) {
+ return CreateSettingForPlugin(
+ debugger, ConstString(kStructuredDataPluginName),
+ ConstString("Settings for structured data plug-ins"), properties_sp,
+ description, is_global_property);
}
diff --git a/source/Core/RegisterValue.cpp b/source/Core/RegisterValue.cpp
index d739dd6b5902..2bc0b9dd4743 100644
--- a/source/Core/RegisterValue.cpp
+++ b/source/Core/RegisterValue.cpp
@@ -23,635 +23,599 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Interpreter/Args.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/Args.h"
using namespace lldb;
using namespace lldb_private;
-bool
-RegisterValue::Dump (Stream *s,
- const RegisterInfo *reg_info,
- bool prefix_with_name,
- bool prefix_with_alt_name,
- Format format,
- uint32_t reg_name_right_align_at) const
-{
- DataExtractor data;
- if (GetData (data))
- {
- bool name_printed = false;
- // For simplicity, alignment of the register name printing applies only
- // in the most common case where:
- //
- // prefix_with_name^prefix_with_alt_name is true
- //
- StreamString format_string;
- if (reg_name_right_align_at && (prefix_with_name^prefix_with_alt_name))
- format_string.Printf("%%%us", reg_name_right_align_at);
- else
- format_string.Printf("%%s");
- const char *fmt = format_string.GetData();
- if (prefix_with_name)
- {
- if (reg_info->name)
- {
- s->Printf (fmt, reg_info->name);
- name_printed = true;
- }
- else if (reg_info->alt_name)
- {
- s->Printf (fmt, reg_info->alt_name);
- prefix_with_alt_name = false;
- name_printed = true;
- }
- }
- if (prefix_with_alt_name)
- {
- if (name_printed)
- s->PutChar ('/');
- if (reg_info->alt_name)
- {
- s->Printf (fmt, reg_info->alt_name);
- name_printed = true;
- }
- else if (!name_printed)
- {
- // No alternate name but we were asked to display a name, so show the main name
- s->Printf (fmt, reg_info->name);
- name_printed = true;
- }
- }
- if (name_printed)
- s->PutCString (" = ");
-
- if (format == eFormatDefault)
- format = reg_info->format;
-
- data.Dump (s,
- 0, // Offset in "data"
- format, // Format to use when dumping
- reg_info->byte_size, // item_byte_size
- 1, // item_count
- UINT32_MAX, // num_per_line
- LLDB_INVALID_ADDRESS, // base_addr
- 0, // item_bit_size
- 0); // item_bit_offset
- return true;
- }
- return false;
+bool RegisterValue::Dump(Stream *s, const RegisterInfo *reg_info,
+ bool prefix_with_name, bool prefix_with_alt_name,
+ Format format,
+ uint32_t reg_name_right_align_at) const {
+ DataExtractor data;
+ if (GetData(data)) {
+ bool name_printed = false;
+ // For simplicity, alignment of the register name printing applies only
+ // in the most common case where:
+ //
+ // prefix_with_name^prefix_with_alt_name is true
+ //
+ StreamString format_string;
+ if (reg_name_right_align_at && (prefix_with_name ^ prefix_with_alt_name))
+ format_string.Printf("%%%us", reg_name_right_align_at);
+ else
+ format_string.Printf("%%s");
+ std::string fmt = format_string.GetString();
+ if (prefix_with_name) {
+ if (reg_info->name) {
+ s->Printf(fmt.c_str(), reg_info->name);
+ name_printed = true;
+ } else if (reg_info->alt_name) {
+ s->Printf(fmt.c_str(), reg_info->alt_name);
+ prefix_with_alt_name = false;
+ name_printed = true;
+ }
+ }
+ if (prefix_with_alt_name) {
+ if (name_printed)
+ s->PutChar('/');
+ if (reg_info->alt_name) {
+ s->Printf(fmt.c_str(), reg_info->alt_name);
+ name_printed = true;
+ } else if (!name_printed) {
+ // No alternate name but we were asked to display a name, so show the
+ // main name
+ s->Printf(fmt.c_str(), reg_info->name);
+ name_printed = true;
+ }
+ }
+ if (name_printed)
+ s->PutCString(" = ");
+
+ if (format == eFormatDefault)
+ format = reg_info->format;
+
+ data.Dump(s,
+ 0, // Offset in "data"
+ format, // Format to use when dumping
+ reg_info->byte_size, // item_byte_size
+ 1, // item_count
+ UINT32_MAX, // num_per_line
+ LLDB_INVALID_ADDRESS, // base_addr
+ 0, // item_bit_size
+ 0); // item_bit_offset
+ return true;
+ }
+ return false;
}
-bool
-RegisterValue::GetData (DataExtractor &data) const
-{
- return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
+bool RegisterValue::GetData(DataExtractor &data) const {
+ return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
}
-uint32_t
-RegisterValue::GetAsMemoryData (const RegisterInfo *reg_info,
- void *dst,
- uint32_t dst_len,
- lldb::ByteOrder dst_byte_order,
- Error &error) const
-{
- if (reg_info == nullptr)
- {
- error.SetErrorString ("invalid register info argument.");
- return 0;
- }
-
- // ReadRegister should have already been called on this object prior to
- // calling this.
- if (GetType() == eTypeInvalid)
- {
- // No value has been read into this object...
- error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name);
- return 0;
- }
-
- if (dst_len > kMaxRegisterByteSize)
- {
- error.SetErrorString ("destination is too big");
- return 0;
- }
-
- const uint32_t src_len = reg_info->byte_size;
-
- // Extract the register data into a data extractor
- DataExtractor reg_data;
- if (!GetData(reg_data))
- {
- error.SetErrorString ("invalid register value to copy into");
- return 0;
- }
-
- // Prepare a memory buffer that contains some or all of the register value
- const uint32_t bytes_copied = reg_data.CopyByteOrderedData (0, // src offset
- src_len, // src length
- dst, // dst buffer
- dst_len, // dst length
- dst_byte_order); // dst byte order
- if (bytes_copied == 0)
- error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name);
-
- return bytes_copied;
+uint32_t RegisterValue::GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
+ uint32_t dst_len,
+ lldb::ByteOrder dst_byte_order,
+ Error &error) const {
+ if (reg_info == nullptr) {
+ error.SetErrorString("invalid register info argument.");
+ return 0;
+ }
+
+ // ReadRegister should have already been called on this object prior to
+ // calling this.
+ if (GetType() == eTypeInvalid) {
+ // No value has been read into this object...
+ error.SetErrorStringWithFormat(
+ "invalid register value type for register %s", reg_info->name);
+ return 0;
+ }
+
+ if (dst_len > kMaxRegisterByteSize) {
+ error.SetErrorString("destination is too big");
+ return 0;
+ }
+
+ const uint32_t src_len = reg_info->byte_size;
+
+ // Extract the register data into a data extractor
+ DataExtractor reg_data;
+ if (!GetData(reg_data)) {
+ error.SetErrorString("invalid register value to copy into");
+ return 0;
+ }
+
+ // Prepare a memory buffer that contains some or all of the register value
+ const uint32_t bytes_copied =
+ reg_data.CopyByteOrderedData(0, // src offset
+ src_len, // src length
+ dst, // dst buffer
+ dst_len, // dst length
+ dst_byte_order); // dst byte order
+ if (bytes_copied == 0)
+ error.SetErrorStringWithFormat(
+ "failed to copy data for register write of %s", reg_info->name);
+
+ return bytes_copied;
}
-uint32_t
-RegisterValue::SetFromMemoryData (const RegisterInfo *reg_info,
- const void *src,
- uint32_t src_len,
- lldb::ByteOrder src_byte_order,
- Error &error)
-{
- if (reg_info == nullptr)
- {
- error.SetErrorString ("invalid register info argument.");
- return 0;
- }
-
- // Moving from addr into a register
- //
- // Case 1: src_len == dst_len
- //
- // |AABBCCDD| Address contents
- // |AABBCCDD| Register contents
- //
- // Case 2: src_len > dst_len
- //
- // Error! (The register should always be big enough to hold the data)
- //
- // Case 3: src_len < dst_len
- //
- // |AABB| Address contents
- // |AABB0000| Register contents [on little-endian hardware]
- // |0000AABB| Register contents [on big-endian hardware]
- if (src_len > kMaxRegisterByteSize)
- {
- error.SetErrorStringWithFormat ("register buffer is too small to receive %u bytes of data.", src_len);
- return 0;
- }
-
- const uint32_t dst_len = reg_info->byte_size;
-
- if (src_len > dst_len)
- {
- error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len);
- return 0;
- }
+uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo *reg_info,
+ const void *src, uint32_t src_len,
+ lldb::ByteOrder src_byte_order,
+ Error &error) {
+ if (reg_info == nullptr) {
+ error.SetErrorString("invalid register info argument.");
+ return 0;
+ }
- // Use a data extractor to correctly copy and pad the bytes read into the
- // register value
- DataExtractor src_data (src, src_len, src_byte_order, 4);
+ // Moving from addr into a register
+ //
+ // Case 1: src_len == dst_len
+ //
+ // |AABBCCDD| Address contents
+ // |AABBCCDD| Register contents
+ //
+ // Case 2: src_len > dst_len
+ //
+ // Error! (The register should always be big enough to hold the data)
+ //
+ // Case 3: src_len < dst_len
+ //
+ // |AABB| Address contents
+ // |AABB0000| Register contents [on little-endian hardware]
+ // |0000AABB| Register contents [on big-endian hardware]
+ if (src_len > kMaxRegisterByteSize) {
+ error.SetErrorStringWithFormat(
+ "register buffer is too small to receive %u bytes of data.", src_len);
+ return 0;
+ }
+
+ const uint32_t dst_len = reg_info->byte_size;
+
+ if (src_len > dst_len) {
+ error.SetErrorStringWithFormat(
+ "%u bytes is too big to store in register %s (%u bytes)", src_len,
+ reg_info->name, dst_len);
+ return 0;
+ }
- error = SetValueFromData(reg_info, src_data, 0, true);
- if (error.Fail())
- return 0;
+ // Use a data extractor to correctly copy and pad the bytes read into the
+ // register value
+ DataExtractor src_data(src, src_len, src_byte_order, 4);
- // If SetValueFromData succeeded, we must have copied all of src_len
- return src_len;
+ error = SetValueFromData(reg_info, src_data, 0, true);
+ if (error.Fail())
+ return 0;
+
+ // If SetValueFromData succeeded, we must have copied all of src_len
+ return src_len;
}
-bool
-RegisterValue::GetScalarValue (Scalar &scalar) const
-{
- switch (m_type)
- {
- case eTypeInvalid: break;
- case eTypeBytes:
- {
- switch (buffer.length)
- {
- default: break;
- 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 16:
- case 32:
- if (buffer.length % sizeof(uint64_t) == 0)
- {
- const auto length_in_bits = buffer.length * 8;
- const auto length_in_uint64 = buffer.length / sizeof(uint64_t);
- scalar = llvm::APInt(length_in_bits, llvm::ArrayRef<uint64_t>((const uint64_t *)buffer.bytes, length_in_uint64));
- return true;
- }
- break;
- }
- }
- break;
- case eTypeUInt8:
- case eTypeUInt16:
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble: scalar = m_scalar; return true;
+bool RegisterValue::GetScalarValue(Scalar &scalar) const {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ 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 16:
+ case 32:
+ if (buffer.length % sizeof(uint64_t) == 0) {
+ const auto length_in_bits = buffer.length * 8;
+ const auto length_in_uint64 = buffer.length / sizeof(uint64_t);
+ scalar =
+ llvm::APInt(length_in_bits,
+ llvm::ArrayRef<uint64_t>((const uint64_t *)buffer.bytes,
+ length_in_uint64));
+ return true;
+ }
+ break;
}
- return false;
+ } break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ scalar = m_scalar;
+ return true;
+ }
+ return false;
}
-void
-RegisterValue::Clear()
-{
- m_type = eTypeInvalid;
-}
+void RegisterValue::Clear() { m_type = eTypeInvalid; }
-RegisterValue::Type
-RegisterValue::SetType (const RegisterInfo *reg_info)
-{
- // To change the type, we simply copy the data in again, using the new format
- RegisterValue copy;
- DataExtractor copy_data;
- if (copy.CopyValue(*this) && copy.GetData(copy_data))
- SetValueFromData(reg_info, copy_data, 0, true);
+RegisterValue::Type RegisterValue::SetType(const RegisterInfo *reg_info) {
+ // To change the type, we simply copy the data in again, using the new format
+ RegisterValue copy;
+ DataExtractor copy_data;
+ if (copy.CopyValue(*this) && copy.GetData(copy_data))
+ SetValueFromData(reg_info, copy_data, 0, true);
- return m_type;
+ return m_type;
}
-Error
-RegisterValue::SetValueFromData (const RegisterInfo *reg_info, DataExtractor &src, lldb::offset_t src_offset, bool partial_data_ok)
-{
- Error error;
-
- if (src.GetByteSize() == 0)
- {
- error.SetErrorString ("empty data.");
- return error;
- }
+Error RegisterValue::SetValueFromData(const RegisterInfo *reg_info,
+ DataExtractor &src,
+ lldb::offset_t src_offset,
+ bool partial_data_ok) {
+ Error error;
- if (reg_info->byte_size == 0)
- {
- error.SetErrorString ("invalid register info.");
- return error;
- }
+ if (src.GetByteSize() == 0) {
+ error.SetErrorString("empty data.");
+ return error;
+ }
- uint32_t src_len = src.GetByteSize() - src_offset;
-
- if (!partial_data_ok && (src_len < reg_info->byte_size))
- {
- error.SetErrorString ("not enough data.");
- return error;
- }
-
- // Cap the data length if there is more than enough bytes for this register
- // value
- if (src_len > reg_info->byte_size)
- src_len = reg_info->byte_size;
+ if (reg_info->byte_size == 0) {
+ error.SetErrorString("invalid register info.");
+ return error;
+ }
- // Zero out the value in case we get partial data...
- memset (buffer.bytes, 0, sizeof (buffer.bytes));
+ uint32_t src_len = src.GetByteSize() - src_offset;
- type128 int128;
+ if (!partial_data_ok && (src_len < reg_info->byte_size)) {
+ error.SetErrorString("not enough data.");
+ return error;
+ }
- m_type = eTypeInvalid;
- switch (reg_info->encoding)
- {
- case eEncodingInvalid:
- break;
- case eEncodingUint:
- case eEncodingSint:
- if (reg_info->byte_size == 1)
- SetUInt8(src.GetMaxU32(&src_offset, src_len));
- else if (reg_info->byte_size <= 2)
- SetUInt16(src.GetMaxU32(&src_offset, src_len));
- else if (reg_info->byte_size <= 4)
- SetUInt32(src.GetMaxU32(&src_offset, src_len));
- else if (reg_info->byte_size <= 8)
- SetUInt64(src.GetMaxU64(&src_offset, src_len));
- else if (reg_info->byte_size <= 16)
- {
- uint64_t data1 = src.GetU64 (&src_offset);
- uint64_t data2 = src.GetU64 (&src_offset);
- if (src.GetByteSize() == eByteOrderBig)
- {
- int128.x[0] = data1;
- int128.x[1] = data2;
- }
- else
- {
- int128.x[0] = data2;
- int128.x[1] = data1;
- }
- SetUInt128 (llvm::APInt(128, 2, int128.x));
- }
- break;
- case eEncodingIEEE754:
- if (reg_info->byte_size == sizeof(float))
- SetFloat(src.GetFloat(&src_offset));
- else if (reg_info->byte_size == sizeof(double))
- SetDouble(src.GetDouble(&src_offset));
- else if (reg_info->byte_size == sizeof(long double))
- SetLongDouble(src.GetLongDouble(&src_offset));
- break;
- case eEncodingVector:
- {
- m_type = eTypeBytes;
- 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
- buffer.bytes, // dst buffer
- buffer.length, // dst length
- buffer.byte_order) == 0)// dst byte order
- {
- error.SetErrorStringWithFormat("failed to copy data for register write of %s", reg_info->name);
- return error;
- }
- }
+ // Cap the data length if there is more than enough bytes for this register
+ // value
+ if (src_len > reg_info->byte_size)
+ src_len = reg_info->byte_size;
+
+ // Zero out the value in case we get partial data...
+ memset(buffer.bytes, 0, sizeof(buffer.bytes));
+
+ type128 int128;
+
+ m_type = eTypeInvalid;
+ switch (reg_info->encoding) {
+ case eEncodingInvalid:
+ break;
+ case eEncodingUint:
+ case eEncodingSint:
+ if (reg_info->byte_size == 1)
+ SetUInt8(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 2)
+ SetUInt16(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 4)
+ SetUInt32(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 8)
+ SetUInt64(src.GetMaxU64(&src_offset, src_len));
+ else if (reg_info->byte_size <= 16) {
+ uint64_t data1 = src.GetU64(&src_offset);
+ uint64_t data2 = src.GetU64(&src_offset);
+ if (src.GetByteSize() == eByteOrderBig) {
+ int128.x[0] = data1;
+ int128.x[1] = data2;
+ } else {
+ int128.x[0] = data2;
+ int128.x[1] = data1;
+ }
+ SetUInt128(llvm::APInt(128, 2, int128.x));
+ }
+ break;
+ case eEncodingIEEE754:
+ if (reg_info->byte_size == sizeof(float))
+ SetFloat(src.GetFloat(&src_offset));
+ else if (reg_info->byte_size == sizeof(double))
+ SetDouble(src.GetDouble(&src_offset));
+ else if (reg_info->byte_size == sizeof(long double))
+ SetLongDouble(src.GetLongDouble(&src_offset));
+ break;
+ case eEncodingVector: {
+ m_type = eTypeBytes;
+ 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
+ buffer.bytes, // dst buffer
+ buffer.length, // dst length
+ buffer.byte_order) == 0) // dst byte order
+ {
+ error.SetErrorStringWithFormat(
+ "failed to copy data for register write of %s", reg_info->name);
+ return error;
}
+ }
+ }
- if (m_type == eTypeInvalid)
- error.SetErrorStringWithFormat("invalid register value type for register %s", reg_info->name);
- return error;
+ if (m_type == eTypeInvalid)
+ error.SetErrorStringWithFormat(
+ "invalid register value type for register %s", reg_info->name);
+ return error;
}
-static inline void StripSpaces(llvm::StringRef &Str)
-{
- while (!Str.empty() && isspace(Str[0]))
- Str = Str.substr(1);
- while (!Str.empty() && isspace(Str.back()))
- Str = Str.substr(0, Str.size()-1);
-}
+// Helper function for RegisterValue::SetValueFromString()
+static bool ParseVectorEncoding(const RegisterInfo *reg_info,
+ llvm::StringRef vector_str,
+ const uint32_t byte_size,
+ RegisterValue *reg_value) {
+ // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
+ // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
+ vector_str = vector_str.trim();
+ vector_str.consume_front("{");
+ vector_str.consume_back("}");
+ vector_str = vector_str.trim();
+
+ char Sep = ' ';
+
+ // The first split should give us:
+ // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
+ // 0x2a 0x3e').
+ llvm::StringRef car;
+ llvm::StringRef cdr = vector_str;
+ std::tie(car, cdr) = vector_str.split(Sep);
+ std::vector<uint8_t> bytes;
+ unsigned byte = 0;
+
+ // Using radix auto-sensing by passing 0 as the radix.
+ // Keep on processing the vector elements as long as the parsing succeeds and
+ // the vector size is < byte_size.
+ while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
+ bytes.push_back(byte);
+ std::tie(car, cdr) = cdr.split(Sep);
+ }
-static inline void LStrip(llvm::StringRef &Str, char c)
-{
- if (!Str.empty() && Str.front() == c)
- Str = Str.substr(1);
-}
+ // Check for vector of exact byte_size elements.
+ if (bytes.size() != byte_size)
+ return false;
-static inline void RStrip(llvm::StringRef &Str, char c)
-{
- if (!Str.empty() && Str.back() == c)
- Str = Str.substr(0, Str.size()-1);
+ reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
+ return true;
}
-// Helper function for RegisterValue::SetValueFromCString()
-static bool
-ParseVectorEncoding(const RegisterInfo *reg_info, const char *vector_str, const uint32_t byte_size, RegisterValue *reg_value)
-{
- // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
- llvm::StringRef Str(vector_str);
- StripSpaces(Str);
- LStrip(Str, '{');
- RStrip(Str, '}');
- StripSpaces(Str);
-
- char Sep = ' ';
-
- // The first split should give us:
- // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f 0x2a 0x3e').
- std::pair<llvm::StringRef, llvm::StringRef> Pair = Str.split(Sep);
- std::vector<uint8_t> bytes;
- unsigned byte = 0;
-
- // Using radix auto-sensing by passing 0 as the radix.
- // Keep on processing the vector elements as long as the parsing succeeds and the vector size is < byte_size.
- while (!Pair.first.getAsInteger(0, byte) && bytes.size() < byte_size) {
- bytes.push_back(byte);
- Pair = Pair.second.split(Sep);
+Error RegisterValue::SetValueFromString(const RegisterInfo *reg_info,
+ llvm::StringRef value_str) {
+ Error error;
+ if (reg_info == nullptr) {
+ error.SetErrorString("Invalid register info argument.");
+ return error;
+ }
+
+ m_type = eTypeInvalid;
+ if (value_str.empty()) {
+ error.SetErrorString("Invalid c-string value string.");
+ return error;
+ }
+ const uint32_t byte_size = reg_info->byte_size;
+
+ uint64_t uval64;
+ int64_t ival64;
+ float flt_val;
+ double dbl_val;
+ long double ldbl_val;
+ switch (reg_info->encoding) {
+ case eEncodingInvalid:
+ error.SetErrorString("Invalid encoding.");
+ break;
+
+ case eEncodingUint:
+ if (byte_size > sizeof(uint64_t)) {
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %u", byte_size);
+ break;
+ }
+ if (value_str.getAsInteger(0, uval64)) {
+ error.SetErrorStringWithFormat(
+ "'%s' is not a valid unsigned integer string value",
+ value_str.str().c_str());
+ break;
}
- // Check for vector of exact byte_size elements.
- if (bytes.size() != byte_size)
- return false;
+ if (!Args::UInt64ValueIsValidForByteSize(uval64, byte_size)) {
+ error.SetErrorStringWithFormat(
+ "value 0x%" PRIx64
+ " is too large to fit in a %u byte unsigned integer value",
+ uval64, byte_size);
+ break;
+ }
- reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
- return true;
-}
+ if (!SetUInt(uval64, reg_info->byte_size)) {
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %u", byte_size);
+ break;
+ }
+ // TODO: Shouldn't we be setting m_type here?
+ break;
-Error
-RegisterValue::SetValueFromCString (const RegisterInfo *reg_info, const char *value_str)
-{
- Error error;
- if (reg_info == nullptr)
- {
- error.SetErrorString ("Invalid register info argument.");
- return error;
+ case eEncodingSint:
+ if (byte_size > sizeof(long long)) {
+ error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
+ byte_size);
+ break;
}
- if (value_str == nullptr || value_str[0] == '\0')
- {
- error.SetErrorString ("Invalid c-string value string.");
- return error;
+ if (value_str.getAsInteger(0, ival64)) {
+ error.SetErrorStringWithFormat(
+ "'%s' is not a valid signed integer string value",
+ value_str.str().c_str());
+ break;
}
- 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:
- error.SetErrorString ("Invalid encoding.");
- break;
-
- case eEncodingUint:
- if (byte_size <= sizeof (uint64_t))
- {
- uint64_t uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str);
- else if (!Args::UInt64ValueIsValidForByteSize (uval64, byte_size))
- error.SetErrorStringWithFormat ("value 0x%" PRIx64 " is too large to fit in a %u byte unsigned integer value", uval64, byte_size);
- else
- {
- if (!SetUInt (uval64, reg_info->byte_size))
- error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %u", byte_size);
- }
- }
- else
- {
- error.SetErrorStringWithFormat ("unsupported unsigned integer byte size: %u", byte_size);
- return error;
- }
- break;
-
- case eEncodingSint:
- if (byte_size <= sizeof (long long))
- {
- uint64_t sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str);
- else if (!Args::SInt64ValueIsValidForByteSize (sval64, byte_size))
- error.SetErrorStringWithFormat ("value 0x%" PRIx64 " is too large to fit in a %u byte signed integer value", sval64, byte_size);
- else
- {
- if (!SetUInt (sval64, reg_info->byte_size))
- error.SetErrorStringWithFormat ("unsupported signed integer byte size: %u", byte_size);
- }
- }
- else
- {
- error.SetErrorStringWithFormat ("unsupported signed integer byte size: %u", byte_size);
- return error;
- }
- break;
-
- case eEncodingIEEE754:
- if (byte_size == sizeof (float))
- {
- 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", &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", &ldbl_val) == 1)
- {
- m_scalar = ldbl_val;
- m_type = eTypeLongDouble;
- }
- else
- error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
- }
- else
- {
- error.SetErrorStringWithFormat ("unsupported float byte size: %u", byte_size);
- return error;
- }
- break;
-
- case eEncodingVector:
- if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
- error.SetErrorString ("unrecognized vector encoding string value.");
- break;
+
+ if (!Args::SInt64ValueIsValidForByteSize(ival64, byte_size)) {
+ error.SetErrorStringWithFormat(
+ "value 0x%" PRIx64
+ " is too large to fit in a %u byte signed integer value",
+ ival64, byte_size);
+ break;
}
- if (error.Fail())
- m_type = eTypeInvalid;
-
- return error;
-}
-bool
-RegisterValue::SignExtend (uint32_t sign_bitpos)
-{
- switch (m_type)
- {
- case eTypeInvalid:
- break;
-
- case eTypeUInt8:
- case eTypeUInt16:
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- return m_scalar.SignExtend(sign_bitpos);
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble:
- case eTypeBytes:
- break;
+ if (!SetUInt(ival64, reg_info->byte_size)) {
+ error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
+ byte_size);
+ break;
}
- return false;
-}
-bool
-RegisterValue::CopyValue (const RegisterValue &rhs)
-{
- m_type = rhs.m_type;
- switch (m_type)
- {
- case eTypeInvalid:
- return false;
- 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.buffer.length <= kMaxRegisterByteSize);
- ::memcpy (buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize);
- buffer.length = rhs.buffer.length;
- buffer.byte_order = rhs.buffer.byte_order;
- break;
+ // TODO: Shouldn't we be setting m_type here?
+ break;
+
+ case eEncodingIEEE754: {
+ std::string value_string = value_str;
+ if (byte_size == sizeof(float)) {
+ if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_string.c_str());
+ break;
+ }
+ m_scalar = flt_val;
+ m_type = eTypeFloat;
+ } else if (byte_size == sizeof(double)) {
+ if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_string.c_str());
+ break;
+ }
+ m_scalar = dbl_val;
+ m_type = eTypeDouble;
+ } else if (byte_size == sizeof(long double)) {
+ if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_string.c_str());
+ break;
+ }
+ m_scalar = ldbl_val;
+ m_type = eTypeLongDouble;
+ } else {
+ error.SetErrorStringWithFormat("unsupported float byte size: %u",
+ byte_size);
+ return error;
}
- return true;
+ break;
+ }
+ case eEncodingVector:
+ if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
+ error.SetErrorString("unrecognized vector encoding string value.");
+ break;
+ }
+
+ return error;
}
-uint16_t
-RegisterValue::GetAsUInt16 (uint16_t fail_value, bool *success_ptr) const
-{
- if (success_ptr)
- *success_ptr = true;
-
- switch (m_type)
- {
- default: break;
- case eTypeUInt8:
- case eTypeUInt16: return m_scalar.UShort(fail_value);
- case eTypeBytes:
- {
- switch (buffer.length)
- {
- default: break;
- case 1:
- case 2: return *(const uint16_t *)buffer.bytes;
- }
- }
- break;
+bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ return m_scalar.SignExtend(sign_bitpos);
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ case eTypeBytes:
+ break;
+ }
+ return false;
+}
+
+bool RegisterValue::CopyValue(const RegisterValue &rhs) {
+ m_type = rhs.m_type;
+ switch (m_type) {
+ case eTypeInvalid:
+ return false;
+ 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.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;
+}
+
+uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
+ bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+
+ switch (m_type) {
+ default:
+ break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ return m_scalar.UShort(fail_value);
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ case 1:
+ case 2:
+ return *(const uint16_t *)buffer.bytes;
}
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
+ } break;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
}
-uint32_t
-RegisterValue::GetAsUInt32 (uint32_t fail_value, bool *success_ptr) const
-{
- if (success_ptr)
- *success_ptr = true;
- switch (m_type)
- {
- default: break;
- case eTypeUInt8:
- case eTypeUInt16:
- case eTypeUInt32:
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble: return m_scalar.UInt(fail_value);
- case eTypeBytes:
- {
- switch (buffer.length)
- {
- default: break;
- case 1:
- case 2:
- case 4: return *(const uint32_t *)buffer.bytes;
- }
- }
- break;
+uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
+ bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.UInt(fail_value);
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ case 1:
+ case 2:
+ case 4:
+ return *(const uint32_t *)buffer.bytes;
}
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
+ } break;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
}
-uint64_t
-RegisterValue::GetAsUInt64 (uint64_t fail_value, bool *success_ptr) const
-{
+uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
+ bool *success_ptr) const {
if (success_ptr)
*success_ptr = true;
switch (m_type) {
@@ -685,353 +649,312 @@ RegisterValue::GetAsUInt64 (uint64_t fail_value, bool *success_ptr) const
return fail_value;
}
-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:
- case eTypeUInt16:
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble: return m_scalar.UInt128(fail_value);
- case eTypeBytes:
- {
- switch (buffer.length)
- {
- 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;
+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:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.UInt128(fail_value);
+ case eTypeBytes: {
+ switch (buffer.length) {
+ 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);
}
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
+ } break;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
}
-float
-RegisterValue::GetAsFloat (float fail_value, bool *success_ptr) const
-{
- if (success_ptr)
- *success_ptr = true;
- switch (m_type)
- {
- default: break;
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble:
- return m_scalar.Float(fail_value);
- }
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
+float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.Float(fail_value);
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
}
-double
-RegisterValue::GetAsDouble (double fail_value, bool *success_ptr) const
-{
- if (success_ptr)
- *success_ptr = true;
- switch (m_type)
- {
- default:
- break;
-
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble:
- return m_scalar.Double(fail_value);
- }
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
+double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.Double(fail_value);
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
}
-long double
-RegisterValue::GetAsLongDouble (long double fail_value, bool *success_ptr) const
-{
- if (success_ptr)
- *success_ptr = true;
- switch (m_type)
- {
- default:
- break;
-
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble:
- return m_scalar.LongDouble();
- }
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
+long double RegisterValue::GetAsLongDouble(long double fail_value,
+ bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.LongDouble();
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
}
-const void *
-RegisterValue::GetBytes () const
-{
- switch (m_type)
- {
- case eTypeInvalid: break;
- 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 nullptr;
+const void *RegisterValue::GetBytes() const {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+ 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 nullptr;
}
-uint32_t
-RegisterValue::GetByteSize () const
-{
- switch (m_type)
- {
- case eTypeInvalid: break;
- 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;
+uint32_t RegisterValue::GetByteSize() const {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+ 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;
}
-bool
-RegisterValue::SetUInt (uint64_t uint, uint32_t byte_size)
-{
- if (byte_size == 0)
- {
- SetUInt64 (uint);
- }
- else if (byte_size == 1)
- {
- SetUInt8 (uint);
- }
- else if (byte_size <= 2)
- {
- SetUInt16 (uint);
- }
- else if (byte_size <= 4)
- {
- SetUInt32 (uint);
- }
- else if (byte_size <= 8)
- {
- SetUInt64 (uint);
- }
- else if (byte_size <= 16)
- {
- SetUInt128 (llvm::APInt(128, uint));
- }
- else
- return false;
- return true;
+bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
+ if (byte_size == 0) {
+ SetUInt64(uint);
+ } else if (byte_size == 1) {
+ SetUInt8(uint);
+ } else if (byte_size <= 2) {
+ SetUInt16(uint);
+ } else if (byte_size <= 4) {
+ SetUInt32(uint);
+ } else if (byte_size <= 8) {
+ SetUInt64(uint);
+ } else if (byte_size <= 16) {
+ SetUInt128(llvm::APInt(128, uint));
+ } else
+ return false;
+ return true;
}
-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
- // 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 (buffer.bytes) && "Storing too many bytes in a RegisterValue.");
- m_type = eTypeBytes;
- buffer.length = length;
- memcpy (buffer.bytes, bytes, length);
- buffer.byte_order = byte_order;
- }
- else
- {
- m_type = eTypeInvalid;
- buffer.length = 0;
- }
+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
+ // 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(buffer.bytes) &&
+ "Storing too many bytes in a RegisterValue.");
+ m_type = eTypeBytes;
+ buffer.length = length;
+ memcpy(buffer.bytes, bytes, length);
+ buffer.byte_order = byte_order;
+ } else {
+ m_type = eTypeInvalid;
+ buffer.length = 0;
+ }
}
-bool
-RegisterValue::operator == (const RegisterValue &rhs) const
-{
- if (m_type == rhs.m_type)
- {
- switch (m_type)
- {
- case eTypeInvalid: return true;
- 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 (buffer.length != rhs.buffer.length)
- return false;
- else
- {
- uint8_t length = buffer.length;
- if (length > kMaxRegisterByteSize)
- length = kMaxRegisterByteSize;
- return memcmp (buffer.bytes, rhs.buffer.bytes, length) == 0;
- }
- break;
- }
+bool RegisterValue::operator==(const RegisterValue &rhs) const {
+ if (m_type == rhs.m_type) {
+ switch (m_type) {
+ case eTypeInvalid:
+ return true;
+ 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 (buffer.length != rhs.buffer.length)
+ return false;
+ else {
+ uint8_t length = buffer.length;
+ if (length > kMaxRegisterByteSize)
+ length = kMaxRegisterByteSize;
+ return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0;
+ }
+ break;
}
+ }
+ return false;
+}
+
+bool RegisterValue::operator!=(const RegisterValue &rhs) const {
+ if (m_type != rhs.m_type)
+ return true;
+ switch (m_type) {
+ case eTypeInvalid:
return false;
+ 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 (buffer.length != rhs.buffer.length) {
+ return true;
+ } else {
+ uint8_t length = buffer.length;
+ if (length > kMaxRegisterByteSize)
+ length = kMaxRegisterByteSize;
+ return memcmp(buffer.bytes, rhs.buffer.bytes, length) != 0;
+ }
+ break;
+ }
+ return true;
}
-bool
-RegisterValue::operator != (const RegisterValue &rhs) const
-{
- if (m_type != rhs.m_type)
+bool RegisterValue::ClearBit(uint32_t bit) {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ if (bit < (GetByteSize() * 8)) {
+ return m_scalar.ClearBit(bit);
+ }
+ break;
+
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ break;
+
+ case eTypeBytes:
+ if (buffer.byte_order == eByteOrderBig ||
+ buffer.byte_order == eByteOrderLittle) {
+ uint32_t byte_idx;
+ 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 < buffer.length) {
+ buffer.bytes[byte_idx] &= ~(1u << byte_bit);
return true;
- switch (m_type)
- {
- case eTypeInvalid: return false;
- 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 (buffer.length != rhs.buffer.length)
- {
- return true;
- }
- else
- {
- uint8_t length = buffer.length;
- if (length > kMaxRegisterByteSize)
- length = kMaxRegisterByteSize;
- return memcmp (buffer.bytes, rhs.buffer.bytes, length) != 0;
- }
- break;
+ }
}
- return true;
+ break;
+ }
+ return false;
}
-bool
-RegisterValue::ClearBit (uint32_t bit)
-{
- switch (m_type)
- {
- case eTypeInvalid:
- break;
-
- case eTypeUInt8:
- case eTypeUInt16:
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- if (bit < (GetByteSize() * 8))
- {
- return m_scalar.ClearBit(bit);
- }
- break;
-
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble:
- break;
-
- case eTypeBytes:
- if (buffer.byte_order == eByteOrderBig || buffer.byte_order == eByteOrderLittle)
- {
- uint32_t byte_idx;
- 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 < buffer.length)
- {
- buffer.bytes[byte_idx] &= ~(1u << byte_bit);
- return true;
- }
- }
- break;
+bool RegisterValue::SetBit(uint32_t bit) {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ if (bit < (GetByteSize() * 8)) {
+ return m_scalar.SetBit(bit);
}
- return false;
-}
+ break;
-bool
-RegisterValue::SetBit (uint32_t bit)
-{
- switch (m_type)
- {
- case eTypeInvalid:
- break;
-
- case eTypeUInt8:
- case eTypeUInt16:
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeUInt128:
- if (bit < (GetByteSize() * 8))
- {
- return m_scalar.SetBit(bit);
- }
- break;
-
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble:
- break;
-
- case eTypeBytes:
- if (buffer.byte_order == eByteOrderBig || buffer.byte_order == eByteOrderLittle)
- {
- uint32_t byte_idx;
- 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 < buffer.length)
- {
- buffer.bytes[byte_idx] |= (1u << byte_bit);
- return true;
- }
- }
- break;
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ break;
+
+ case eTypeBytes:
+ if (buffer.byte_order == eByteOrderBig ||
+ buffer.byte_order == eByteOrderLittle) {
+ uint32_t byte_idx;
+ 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 < buffer.length) {
+ buffer.bytes[byte_idx] |= (1u << byte_bit);
+ return true;
+ }
}
- return false;
+ break;
+ }
+ return false;
}
diff --git a/source/Core/RegularExpression.cpp b/source/Core/RegularExpression.cpp
index bdef3ced94d4..54e0231556db 100644
--- a/source/Core/RegularExpression.cpp
+++ b/source/Core/RegularExpression.cpp
@@ -25,46 +25,37 @@
// everywhere.
//----------------------------------------------------------------------
#if defined(REG_ENHANCED)
-#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED|REG_EXTENDED)
+#define DEFAULT_COMPILE_FLAGS (REG_ENHANCED | REG_EXTENDED)
#else
#define DEFAULT_COMPILE_FLAGS (REG_EXTENDED)
#endif
using namespace lldb_private;
-RegularExpression::RegularExpression() :
- m_re(),
- m_comp_err (1),
- m_preg()
-{
- memset(&m_preg, 0, sizeof(m_preg));
+RegularExpression::RegularExpression() : m_re(), m_comp_err(1), m_preg() {
+ memset(&m_preg, 0, sizeof(m_preg));
}
//----------------------------------------------------------------------
// Constructor that compiles "re" using "flags" and stores the
// resulting compiled regular expression into this object.
//----------------------------------------------------------------------
-RegularExpression::RegularExpression(const char* re) :
- m_re(),
- m_comp_err (1),
- m_preg()
-{
- memset(&m_preg,0,sizeof(m_preg));
- Compile(re);
+RegularExpression::RegularExpression(llvm::StringRef str)
+ : m_re(), m_comp_err(1), m_preg() {
+ memset(&m_preg, 0, sizeof(m_preg));
+ Compile(str);
}
-RegularExpression::RegularExpression(const RegularExpression &rhs)
-{
- memset(&m_preg,0,sizeof(m_preg));
- Compile(rhs.GetText());
+RegularExpression::RegularExpression(const RegularExpression &rhs) {
+ memset(&m_preg, 0, sizeof(m_preg));
+ Compile(rhs.GetText());
}
-const RegularExpression &
-RegularExpression::operator= (const RegularExpression &rhs)
-{
- if (&rhs != this)
- Compile (rhs.GetText());
- return *this;
+const RegularExpression &RegularExpression::
+operator=(const RegularExpression &rhs) {
+ if (&rhs != this)
+ Compile(rhs.GetText());
+ return *this;
}
//----------------------------------------------------------------------
@@ -73,10 +64,7 @@ RegularExpression::operator= (const RegularExpression &rhs)
// Any previously compiled regular expression contained in this
// object will be freed.
//----------------------------------------------------------------------
-RegularExpression::~RegularExpression()
-{
- Free();
-}
+RegularExpression::~RegularExpression() { Free(); }
//----------------------------------------------------------------------
// Compile a regular expression using the supplied regular
@@ -90,23 +78,18 @@ RegularExpression::~RegularExpression()
// True if the regular expression compiles successfully, false
// otherwise.
//----------------------------------------------------------------------
-bool
-RegularExpression::Compile(const char* re)
-{
- Free();
-
- if (re && re[0])
- {
- m_re = re;
- m_comp_err = ::regcomp (&m_preg, re, DEFAULT_COMPILE_FLAGS);
- }
- else
- {
- // No valid regular expression
- m_comp_err = 1;
- }
-
- return m_comp_err == 0;
+bool RegularExpression::Compile(llvm::StringRef str) {
+ Free();
+
+ if (!str.empty()) {
+ m_re = str;
+ m_comp_err = ::regcomp(&m_preg, m_re.c_str(), DEFAULT_COMPILE_FLAGS);
+ } else {
+ // No valid regular expression
+ m_comp_err = 1;
+ }
+
+ return m_comp_err == 0;
}
//----------------------------------------------------------------------
@@ -117,145 +100,109 @@ RegularExpression::Compile(const char* re)
// values that are present in "match_ptr". The regular expression
// will be executed using the "execute_flags".
//---------------------------------------------------------------------
-bool
-RegularExpression::Execute (const char* s, Match *match) const
-{
- int err = 1;
- if (s != nullptr && m_comp_err == 0)
- {
- if (match)
- {
- err = ::regexec (&m_preg,
- s,
- match->GetSize(),
- match->GetData(),
- 0);
- }
- else
- {
- err = ::regexec(&m_preg,
- s,
- 0,
- nullptr,
- 0);
- }
- }
-
- if (err != 0)
- {
- // The regular expression didn't compile, so clear the matches
- if (match)
- match->Clear();
- return false;
+bool RegularExpression::Execute(llvm::StringRef str, Match *match) const {
+ int err = 1;
+ if (m_comp_err == 0) {
+ // Argument to regexec must be null-terminated.
+ std::string reg_str = str;
+ if (match) {
+ err = ::regexec(&m_preg, reg_str.c_str(), match->GetSize(),
+ match->GetData(), 0);
+ } else {
+ err = ::regexec(&m_preg, reg_str.c_str(), 0, nullptr, 0);
}
- return true;
-}
+ }
-bool
-RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, std::string& match_str) const
-{
- llvm::StringRef match_str_ref;
- if (GetMatchAtIndex(s, idx, match_str_ref))
- {
- match_str = match_str_ref.str();
- return true;
- }
+ if (err != 0) {
+ // The regular expression didn't compile, so clear the matches
+ if (match)
+ match->Clear();
return false;
+ }
+ return true;
}
-bool
-RegularExpression::Match::GetMatchAtIndex (const char* s, uint32_t idx, llvm::StringRef& match_str) const
-{
- if (idx < m_matches.size())
- {
- if (m_matches[idx].rm_eo == -1 && m_matches[idx].rm_so == -1)
- return false;
+bool RegularExpression::Match::GetMatchAtIndex(llvm::StringRef s, uint32_t idx,
+ std::string &match_str) const {
+ llvm::StringRef match_str_ref;
+ if (GetMatchAtIndex(s, idx, match_str_ref)) {
+ match_str = match_str_ref.str();
+ return true;
+ }
+ return false;
+}
- if (m_matches[idx].rm_eo == m_matches[idx].rm_so)
- {
- // Matched the empty string...
- match_str = llvm::StringRef();
- return true;
- }
- else if (m_matches[idx].rm_eo > m_matches[idx].rm_so)
- {
- match_str = llvm::StringRef (s + m_matches[idx].rm_so, m_matches[idx].rm_eo - m_matches[idx].rm_so);
- return true;
- }
+bool RegularExpression::Match::GetMatchAtIndex(
+ llvm::StringRef s, uint32_t idx, llvm::StringRef &match_str) const {
+ if (idx < m_matches.size()) {
+ if (m_matches[idx].rm_eo == -1 && m_matches[idx].rm_so == -1)
+ return false;
+
+ if (m_matches[idx].rm_eo == m_matches[idx].rm_so) {
+ // Matched the empty string...
+ match_str = llvm::StringRef();
+ return true;
+ } else if (m_matches[idx].rm_eo > m_matches[idx].rm_so) {
+ match_str = s.substr(m_matches[idx].rm_so,
+ m_matches[idx].rm_eo - m_matches[idx].rm_so);
+ return true;
}
- return false;
+ }
+ return false;
}
-bool
-RegularExpression::Match::GetMatchSpanningIndices (const char* s, uint32_t idx1, uint32_t idx2, llvm::StringRef& match_str) const
-{
- if (idx1 < m_matches.size() && idx2 < m_matches.size())
- {
- if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo)
- {
- // Matched the empty string...
- match_str = llvm::StringRef();
- return true;
- }
- else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo)
- {
- match_str = llvm::StringRef (s + m_matches[idx1].rm_so, m_matches[idx2].rm_eo - m_matches[idx1].rm_so);
- return true;
- }
+bool RegularExpression::Match::GetMatchSpanningIndices(
+ llvm::StringRef s, uint32_t idx1, uint32_t idx2,
+ llvm::StringRef &match_str) const {
+ if (idx1 < m_matches.size() && idx2 < m_matches.size()) {
+ if (m_matches[idx1].rm_so == m_matches[idx2].rm_eo) {
+ // Matched the empty string...
+ match_str = llvm::StringRef();
+ return true;
+ } else if (m_matches[idx1].rm_so < m_matches[idx2].rm_eo) {
+ match_str = s.substr(m_matches[idx1].rm_so,
+ m_matches[idx2].rm_eo - m_matches[idx1].rm_so);
+ return true;
}
- return false;
+ }
+ return false;
}
//----------------------------------------------------------------------
// Returns true if the regular expression compiled and is ready
// for execution.
//----------------------------------------------------------------------
-bool
-RegularExpression::IsValid () const
-{
- return m_comp_err == 0;
-}
+bool RegularExpression::IsValid() const { return m_comp_err == 0; }
//----------------------------------------------------------------------
// Returns the text that was used to compile the current regular
// expression.
//----------------------------------------------------------------------
-const char*
-RegularExpression::GetText () const
-{
- return (m_re.empty() ? nullptr : m_re.c_str());
-}
+llvm::StringRef RegularExpression::GetText() const { return m_re; }
//----------------------------------------------------------------------
// Free any contained compiled regular expressions.
//----------------------------------------------------------------------
-void
-RegularExpression::Free()
-{
- if (m_comp_err == 0)
- {
- m_re.clear();
- regfree(&m_preg);
- // Set a compile error since we no longer have a valid regex
- m_comp_err = 1;
- }
+void RegularExpression::Free() {
+ if (m_comp_err == 0) {
+ m_re.clear();
+ regfree(&m_preg);
+ // Set a compile error since we no longer have a valid regex
+ m_comp_err = 1;
+ }
}
-size_t
-RegularExpression::GetErrorAsCString (char *err_str, size_t err_str_max_len) const
-{
- if (m_comp_err == 0)
- {
- if (err_str && err_str_max_len)
- *err_str = '\0';
- return 0;
- }
-
- return ::regerror (m_comp_err, &m_preg, err_str, err_str_max_len);
+size_t RegularExpression::GetErrorAsCString(char *err_str,
+ size_t err_str_max_len) const {
+ if (m_comp_err == 0) {
+ if (err_str && err_str_max_len)
+ *err_str = '\0';
+ return 0;
+ }
+
+ return ::regerror(m_comp_err, &m_preg, err_str, err_str_max_len);
}
-bool
-RegularExpression::operator < (const RegularExpression& rhs) const
-{
- return (m_re < rhs.m_re);
+bool 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 d3e9a7565046..2b99ec17b0a0 100644
--- a/source/Core/Scalar.cpp
+++ b/source/Core/Scalar.cpp
@@ -19,12 +19,12 @@
#include "llvm/ADT/SmallString.h"
// Project includes
-#include "lldb/Interpreter/Args.h"
+#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Core/DataExtractor.h"
#include "lldb/Host/Endian.h"
#include "lldb/Host/StringConvert.h"
+#include "lldb/Interpreter/Args.h"
#include "Plugins/Process/Utility/InstructionUtils.h"
@@ -35,63 +35,57 @@ using namespace lldb_private;
// Promote to max type currently follows the ANSI C rule for type
// promotion in expressions.
//----------------------------------------------------------------------
-static Scalar::Type
-PromoteToMaxType
-(
- const Scalar& lhs, // The const left hand side object
- const Scalar& rhs, // The const right hand side object
- Scalar& temp_value, // A modifiable temp value than can be used to hold either the promoted lhs or rhs object
- const Scalar* &promoted_lhs_ptr, // Pointer to the resulting possibly promoted value of lhs (at most one of lhs/rhs will get promoted)
- const Scalar* &promoted_rhs_ptr // Pointer to the resulting possibly promoted value of rhs (at most one of lhs/rhs will get promoted)
-)
-{
- Scalar result;
- // Initialize the promoted values for both the right and left hand side values
- // to be the objects themselves. If no promotion is needed (both right and left
- // have the same type), then the temp_value will not get used.
- promoted_lhs_ptr = &lhs;
- promoted_rhs_ptr = &rhs;
- // Extract the types of both the right and left hand side values
- Scalar::Type lhs_type = lhs.GetType();
- Scalar::Type rhs_type = rhs.GetType();
-
- if (lhs_type > rhs_type)
- {
- // Right hand side need to be promoted
- temp_value = rhs; // Copy right hand side into the temp value
- if (temp_value.Promote(lhs_type)) // Promote it
- promoted_rhs_ptr = &temp_value; // Update the pointer for the promoted right hand side
- }
- else if (lhs_type < rhs_type)
- {
- // Left hand side need to be promoted
- temp_value = lhs; // Copy left hand side value into the temp value
- if (temp_value.Promote(rhs_type)) // Promote it
- promoted_lhs_ptr = &temp_value; // Update the pointer for the promoted left hand side
- }
-
- // Make sure our type promotion worked as expected
- if (promoted_lhs_ptr->GetType() == promoted_rhs_ptr->GetType())
- return promoted_lhs_ptr->GetType(); // Return the resulting max type
-
- // Return the void type (zero) if we fail to promote either of the values.
- return Scalar::e_void;
-}
-
-Scalar::Scalar() :
- m_type(e_void),
- m_float((float)0)
-{
-}
-
-Scalar::Scalar(const Scalar& rhs) :
- m_type(rhs.m_type),
- m_integer(rhs.m_integer),
- m_float(rhs.m_float)
-{
-}
-
-//Scalar::Scalar(const RegisterValue& reg) :
+static Scalar::Type PromoteToMaxType(
+ const Scalar &lhs, // The const left hand side object
+ const Scalar &rhs, // The const right hand side object
+ Scalar &temp_value, // A modifiable temp value than can be used to hold
+ // either the promoted lhs or rhs object
+ const Scalar *&promoted_lhs_ptr, // Pointer to the resulting possibly
+ // promoted value of lhs (at most one of
+ // lhs/rhs will get promoted)
+ const Scalar *&promoted_rhs_ptr // Pointer to the resulting possibly
+ // promoted value of rhs (at most one of
+ // lhs/rhs will get promoted)
+ ) {
+ Scalar result;
+ // Initialize the promoted values for both the right and left hand side values
+ // to be the objects themselves. If no promotion is needed (both right and
+ // left
+ // have the same type), then the temp_value will not get used.
+ promoted_lhs_ptr = &lhs;
+ promoted_rhs_ptr = &rhs;
+ // Extract the types of both the right and left hand side values
+ Scalar::Type lhs_type = lhs.GetType();
+ Scalar::Type rhs_type = rhs.GetType();
+
+ if (lhs_type > rhs_type) {
+ // Right hand side need to be promoted
+ temp_value = rhs; // Copy right hand side into the temp value
+ if (temp_value.Promote(lhs_type)) // Promote it
+ promoted_rhs_ptr =
+ &temp_value; // Update the pointer for the promoted right hand side
+ } else if (lhs_type < rhs_type) {
+ // Left hand side need to be promoted
+ temp_value = lhs; // Copy left hand side value into the temp value
+ if (temp_value.Promote(rhs_type)) // Promote it
+ promoted_lhs_ptr =
+ &temp_value; // Update the pointer for the promoted left hand side
+ }
+
+ // Make sure our type promotion worked as expected
+ if (promoted_lhs_ptr->GetType() == promoted_rhs_ptr->GetType())
+ return promoted_lhs_ptr->GetType(); // Return the resulting max type
+
+ // Return the void type (zero) if we fail to promote either of the values.
+ return Scalar::e_void;
+}
+
+Scalar::Scalar() : m_type(e_void), m_float((float)0) {}
+
+Scalar::Scalar(const Scalar &rhs)
+ : m_type(rhs.m_type), m_integer(rhs.m_integer), m_float(rhs.m_float) {}
+
+// Scalar::Scalar(const RegisterValue& reg) :
// m_type(e_void),
// m_data()
//{
@@ -103,7 +97,8 @@ Scalar::Scalar(const Scalar& rhs) :
// case 1: m_type = e_uint; m_data.uint = reg.value.uint8; break;
// case 2: m_type = e_uint; m_data.uint = reg.value.uint16; break;
// case 4: m_type = e_uint; m_data.uint = reg.value.uint32; break;
-// case 8: m_type = e_ulonglong; m_data.ulonglong = reg.value.uint64; break;
+// case 8: m_type = e_ulonglong; m_data.ulonglong = reg.value.uint64;
+// break;
// break;
// }
// break;
@@ -114,7 +109,8 @@ Scalar::Scalar(const Scalar& rhs) :
// case 1: m_type = e_sint; m_data.sint = reg.value.sint8; break;
// case 2: m_type = e_sint; m_data.sint = reg.value.sint16; break;
// case 4: m_type = e_sint; m_data.sint = reg.value.sint32; break;
-// case 8: m_type = e_slonglong; m_data.slonglong = reg.value.sint64; break;
+// case 8: m_type = e_slonglong; m_data.slonglong = reg.value.sint64;
+// break;
// break;
// }
// break;
@@ -132,1385 +128,702 @@ Scalar::Scalar(const Scalar& rhs) :
// }
//}
-bool
-Scalar::GetData (DataExtractor &data, size_t limit_byte_size) const
-{
- size_t byte_size = GetByteSize();
- if (byte_size > 0)
- {
- const uint8_t *bytes = reinterpret_cast<const uint8_t *>(GetBytes());
-
- if (limit_byte_size < byte_size)
- {
- if (endian::InlHostByteOrder() == eByteOrderLittle)
- {
- // On little endian systems if we want fewer bytes from the
- // current type we just specify fewer bytes since the LSByte
- // is first...
- byte_size = limit_byte_size;
- }
- else if (endian::InlHostByteOrder() == eByteOrderBig)
- {
- // On big endian systems if we want fewer bytes from the
- // current type have to advance our initial byte pointer and
- // trim down the number of bytes since the MSByte is first
- bytes += byte_size - limit_byte_size;
- byte_size = limit_byte_size;
- }
- }
-
- data.SetData(bytes, byte_size, endian::InlHostByteOrder());
- return true;
- }
- data.Clear();
- return false;
-}
-
-const void *
-Scalar::GetBytes() const
-{
- const uint64_t *apint_words;
- const uint8_t *bytes;
- static float_t flt_val;
- static double_t dbl_val;
- static uint64_t swapped_words[4];
- 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:
- bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData());
- // getRawData always returns a pointer to an uint64_t. If we have a smaller type,
- // we need to update the pointer on big-endian systems.
- if (endian::InlHostByteOrder() == eByteOrderBig)
- {
- size_t byte_size = m_integer.getBitWidth() / 8;
- if (byte_size < 8)
- bytes += 8 - byte_size;
- }
- return bytes;
- case e_sint128:
- case e_uint128:
- apint_words = m_integer.getRawData();
- // getRawData always returns a pointer to an array of two uint64_t values,
- // where the least-significant word always comes first. On big-endian
- // systems we need to swap the two words.
- if (endian::InlHostByteOrder() == eByteOrderBig)
- {
- swapped_words[0] = apint_words[1];
- swapped_words[1] = apint_words[0];
- apint_words = swapped_words;
- }
- return reinterpret_cast<const void *>(apint_words);
- case e_sint256:
- case e_uint256:
- apint_words = m_integer.getRawData();
- // getRawData always returns a pointer to an array of four uint64_t values,
- // where the least-significant word always comes first. On big-endian
- // systems we need to swap the four words.
- if (endian::InlHostByteOrder() == eByteOrderBig)
- {
- swapped_words[0] = apint_words[3];
- swapped_words[1] = apint_words[2];
- swapped_words[2] = apint_words[1];
- swapped_words[3] = apint_words[0];
- apint_words = swapped_words;
- }
- return reinterpret_cast<const void *>(apint_words);
- case e_float:
- flt_val = m_float.convertToFloat();
- return reinterpret_cast<const void *>(&flt_val);
- case e_double:
- dbl_val = m_float.convertToDouble();
- return reinterpret_cast<const void *>(&dbl_val);
- case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- apint_words = ldbl_val.getRawData();
- // getRawData always returns a pointer to an array of two uint64_t values,
- // where the least-significant word always comes first. On big-endian
- // systems we need to swap the two words.
- if (endian::InlHostByteOrder() == eByteOrderBig)
- {
- swapped_words[0] = apint_words[1];
- swapped_words[1] = apint_words[0];
- apint_words = swapped_words;
- }
- return reinterpret_cast<const void *>(apint_words);
- }
- return nullptr;
-}
-
-size_t
-Scalar::GetByteSize() const
-{
- switch (m_type)
- {
- case e_void:
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- 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);
+bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const {
+ size_t byte_size = GetByteSize();
+ if (byte_size > 0) {
+ const uint8_t *bytes = reinterpret_cast<const uint8_t *>(GetBytes());
+
+ if (limit_byte_size < byte_size) {
+ if (endian::InlHostByteOrder() == eByteOrderLittle) {
+ // On little endian systems if we want fewer bytes from the
+ // current type we just specify fewer bytes since the LSByte
+ // is first...
+ byte_size = limit_byte_size;
+ } else if (endian::InlHostByteOrder() == eByteOrderBig) {
+ // On big endian systems if we want fewer bytes from the
+ // current type have to advance our initial byte pointer and
+ // trim down the number of bytes since the MSByte is first
+ bytes += byte_size - limit_byte_size;
+ byte_size = limit_byte_size;
+ }
}
- return 0;
-}
-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:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- return llvm::APInt::isSameValue(zero_int, m_integer);
- case e_float:
- case e_double:
- case e_long_double:
- return m_float.isZero();
+ data.SetData(bytes, byte_size, endian::InlHostByteOrder());
+ return true;
+ }
+ data.Clear();
+ return false;
+}
+
+const void *Scalar::GetBytes() const {
+ const uint64_t *apint_words;
+ const uint8_t *bytes;
+ static float_t flt_val;
+ static double_t dbl_val;
+ static uint64_t swapped_words[4];
+ 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:
+ bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData());
+ // getRawData always returns a pointer to an uint64_t. If we have a smaller
+ // type,
+ // we need to update the pointer on big-endian systems.
+ if (endian::InlHostByteOrder() == eByteOrderBig) {
+ size_t byte_size = m_integer.getBitWidth() / 8;
+ if (byte_size < 8)
+ bytes += 8 - byte_size;
}
- return false;
-}
-
-void
-Scalar::GetValue (Stream *s, bool show_type) const
-{
- if (show_type)
- s->Printf("(%s) ", GetTypeAsCString());
-
- switch (m_type)
- {
- case e_void:
- break;
- case e_sint:
- case e_ulong:
- case e_slonglong:
- case e_sint128:
- case e_sint256:
- s->Printf("%s",m_integer.toString(10,true).c_str());
- break;
- case e_uint:
- case e_slong:
- case e_ulonglong:
- case e_uint128:
- case e_uint256:
- s->Printf("%s",m_integer.toString(16,false).c_str());
- break;
- case e_float:
- case e_double:
- case e_long_double:
- llvm::SmallString<24> string;
- m_float.toString(string);
- s->Printf("%s", string.c_str());
- break;
+ return bytes;
+ case e_sint128:
+ case e_uint128:
+ apint_words = m_integer.getRawData();
+ // getRawData always returns a pointer to an array of two uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the two words.
+ if (endian::InlHostByteOrder() == eByteOrderBig) {
+ swapped_words[0] = apint_words[1];
+ swapped_words[1] = apint_words[0];
+ apint_words = swapped_words;
}
-}
-
-const char *
-Scalar::GetTypeAsCString() const
-{
- switch (m_type)
- {
- case e_void: return "void";
- case e_sint: return "int";
- case e_uint: return "unsigned int";
- case e_slong: return "long";
- case e_ulong: return "unsigned long";
- case e_slonglong: return "long long";
- case e_ulonglong: return "unsigned long long";
- case e_sint128: return "int128_t";
- case e_uint128: return "unsigned int128_t";
- case e_sint256: return "int256_t";
- case e_uint256: return "unsigned int256_t";
- case e_float: return "float";
- case e_double: return "double";
- case e_long_double: return "long double";
+ return reinterpret_cast<const void *>(apint_words);
+ case e_sint256:
+ case e_uint256:
+ apint_words = m_integer.getRawData();
+ // getRawData always returns a pointer to an array of four uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the four words.
+ if (endian::InlHostByteOrder() == eByteOrderBig) {
+ swapped_words[0] = apint_words[3];
+ swapped_words[1] = apint_words[2];
+ swapped_words[2] = apint_words[1];
+ swapped_words[3] = apint_words[0];
+ apint_words = swapped_words;
}
- return "<invalid Scalar type>";
-}
-
-Scalar&
-Scalar::operator=(const Scalar& rhs)
-{
- if (this != &rhs)
- {
- m_type = rhs.m_type;
- m_integer = llvm::APInt(rhs.m_integer);
- m_float = rhs.m_float;
+ return reinterpret_cast<const void *>(apint_words);
+ case e_float:
+ flt_val = m_float.convertToFloat();
+ return reinterpret_cast<const void *>(&flt_val);
+ case e_double:
+ dbl_val = m_float.convertToDouble();
+ return reinterpret_cast<const void *>(&dbl_val);
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ apint_words = ldbl_val.getRawData();
+ // getRawData always returns a pointer to an array of two uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the two words.
+ if (endian::InlHostByteOrder() == eByteOrderBig) {
+ swapped_words[0] = apint_words[1];
+ swapped_words[1] = apint_words[0];
+ apint_words = swapped_words;
}
- return *this;
-}
-
-Scalar&
-Scalar::operator= (const int v)
-{
- m_type = e_sint;
- m_integer = llvm::APInt(sizeof(int) * 8, v, true);
- return *this;
-}
-
-Scalar&
-Scalar::operator= (unsigned int v)
-{
- m_type = e_uint;
- m_integer = llvm::APInt(sizeof(int) * 8, v);
- return *this;
-}
-
-Scalar&
-Scalar::operator= (long v)
-{
- m_type = e_slong;
- m_integer = llvm::APInt(sizeof(long) * 8, v, true);
- return *this;
-}
-
-Scalar&
-Scalar::operator= (unsigned long v)
-{
- m_type = e_ulong;
- m_integer = llvm::APInt(sizeof(long) * 8, v);
- return *this;
-}
-
-Scalar&
-Scalar::operator= (long long v)
-{
- m_type = e_slonglong;
- m_integer = llvm::APInt(sizeof(long) * 8, v, true);
- return *this;
-}
-
-Scalar&
-Scalar::operator= (unsigned long long v)
-{
- m_type = e_ulonglong;
- m_integer = llvm::APInt(sizeof(long long) * 8, v);
- return *this;
-}
-
-Scalar&
-Scalar::operator= (float v)
-{
- m_type = e_float;
- m_float = llvm::APFloat(v);
- return *this;
-}
-
-Scalar&
-Scalar::operator= (double v)
-{
- m_type = e_double;
- m_float = llvm::APFloat(v);
- return *this;
-}
-
-Scalar&
-Scalar::operator= (long double v)
-{
- m_type = e_long_double;
- if(m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&v)->x));
+ return reinterpret_cast<const void *>(apint_words);
+ }
+ return nullptr;
+}
+
+size_t Scalar::GetByteSize() const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ 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;
+}
+
+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:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return llvm::APInt::isSameValue(zero_int, m_integer);
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.isZero();
+ }
+ return false;
+}
+
+void Scalar::GetValue(Stream *s, bool show_type) const {
+ if (show_type)
+ s->Printf("(%s) ", GetTypeAsCString());
+
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_slong:
+ case e_slonglong:
+ case e_sint128:
+ case e_sint256:
+ s->PutCString(m_integer.toString(10, true));
+ break;
+ case e_uint:
+ case e_ulong:
+ case e_ulonglong:
+ case e_uint128:
+ case e_uint256:
+ s->PutCString(m_integer.toString(10, false));
+ break;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ llvm::SmallString<24> string;
+ m_float.toString(string);
+ s->Printf("%s", string.c_str());
+ break;
+ }
+}
+
+const char *Scalar::GetTypeAsCString() const {
+ switch (m_type) {
+ case e_void:
+ return "void";
+ case e_sint:
+ return "int";
+ case e_uint:
+ return "unsigned int";
+ case e_slong:
+ return "long";
+ case e_ulong:
+ return "unsigned long";
+ case e_slonglong:
+ return "long long";
+ case e_ulonglong:
+ return "unsigned long long";
+ case e_sint128:
+ return "int128_t";
+ case e_uint128:
+ return "unsigned int128_t";
+ case e_sint256:
+ return "int256_t";
+ case e_uint256:
+ return "unsigned int256_t";
+ case e_float:
+ return "float";
+ case e_double:
+ return "double";
+ case e_long_double:
+ return "long double";
+ }
+ return "<invalid Scalar type>";
+}
+
+Scalar &Scalar::operator=(const Scalar &rhs) {
+ if (this != &rhs) {
+ m_type = rhs.m_type;
+ m_integer = llvm::APInt(rhs.m_integer);
+ m_float = rhs.m_float;
+ }
+ return *this;
+}
+
+Scalar &Scalar::operator=(const int v) {
+ m_type = e_sint;
+ m_integer = llvm::APInt(sizeof(int) * 8, v, true);
+ return *this;
+}
+
+Scalar &Scalar::operator=(unsigned int v) {
+ m_type = e_uint;
+ m_integer = llvm::APInt(sizeof(int) * 8, v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(long v) {
+ m_type = e_slong;
+ m_integer = llvm::APInt(sizeof(long) * 8, v, true);
+ return *this;
+}
+
+Scalar &Scalar::operator=(unsigned long v) {
+ m_type = e_ulong;
+ m_integer = llvm::APInt(sizeof(long) * 8, v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(long long v) {
+ m_type = e_slonglong;
+ m_integer = llvm::APInt(sizeof(long) * 8, v, true);
+ return *this;
+}
+
+Scalar &Scalar::operator=(unsigned long long v) {
+ m_type = e_ulonglong;
+ m_integer = llvm::APInt(sizeof(long long) * 8, v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(float v) {
+ m_type = e_float;
+ m_float = llvm::APFloat(v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(double v) {
+ m_type = e_double;
+ m_float = llvm::APFloat(v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(long double v) {
+ m_type = e_long_double;
+ if (m_ieee_quad)
+ m_float = llvm::APFloat(
+ llvm::APFloat::IEEEquad(),
+ llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((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_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;
- case 256:
- if(m_integer.isSignedIntN(BITWIDTH_INT256))
- m_type = e_sint256;
- else
- m_type = e_uint256;
- break;
- }
- return *this;
+ m_type = e_uint;
+ break;
+ case 64:
+ if (m_integer.isSignedIntN(sizeof(slonglong_t) * 8))
+ m_type = e_slonglong;
+ else
+ m_type = e_ulonglong;
+ break;
+ case 128:
+ if (m_integer.isSignedIntN(BITWIDTH_INT128))
+ m_type = e_sint128;
+ else
+ m_type = e_uint128;
+ break;
+ case 256:
+ if (m_integer.isSignedIntN(BITWIDTH_INT256))
+ m_type = e_sint256;
+ else
+ m_type = e_uint256;
+ break;
+ }
+ return *this;
}
Scalar::~Scalar() = default;
-bool
-Scalar::Promote(Scalar::Type type)
-{
- bool success = false;
- switch (m_type)
- {
- case e_void:
- break;
+bool Scalar::Promote(Scalar::Type type) {
+ bool success = false;
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ switch (type) {
+ case e_void:
+ break;
case e_sint:
- switch (type)
- {
- case e_void: break;
- case e_sint: success = true; break;
- case e_uint:
- m_integer = m_integer.sextOrTrunc(sizeof(uint_t) * 8);
- success = true;
- break;
-
- case e_slong:
- m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
- success = true;
- break;
-
- case e_ulong:
- m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8);
- success = true;
- break;
-
- case e_slonglong:
- m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_ulonglong:
- m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
- success = true;
- break;
-
- case e_sint128:
- case e_uint128:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_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;
-
+ success = true;
+ break;
case e_uint:
- switch (type)
- {
- case e_void:
- case e_sint: break;
- case e_uint: success = true; break;
- case e_slong:
- m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
- success = true;
- break;
-
- case e_ulong:
- m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8);
- success = true;
- break;
-
- case e_slonglong:
- m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_ulonglong:
- m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
- success = true;
- break;
-
- case e_sint128:
- case e_uint128:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_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;
+ m_integer = m_integer.sextOrTrunc(sizeof(uint_t) * 8);
+ success = true;
+ break;
case e_slong:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint: break;
- case e_slong: success = true; break;
- case e_ulong:
- m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8);
- success = true;
- break;
-
- case e_slonglong:
- m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_ulonglong:
- m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
- success = true;
- break;
-
- case e_sint128:
- case e_uint128:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_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;
+ m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
+ success = true;
+ break;
case e_ulong:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong: break;
- case e_ulong: success = true; break;
- case e_slonglong:
- m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_ulonglong:
- m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
- success = true;
- break;
-
- case e_sint128:
- case e_uint128:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_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;
+ m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8);
+ success = true;
+ break;
case e_slonglong:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong: break;
- case e_slonglong: success = true; break;
- case e_ulonglong:
- m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
- success = true;
- break;
-
- case e_sint128:
- case e_uint128:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_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;
+ m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
case e_ulonglong:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong: break;
- case e_ulonglong: success = true; break;
- case e_sint128:
- case e_uint128:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_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;
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
case e_sint128:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong: break;
- case e_sint128: success = true; break;
- case e_uint128:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
- success = true;
- break;
-
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_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_sint256:
- case e_uint256:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
- 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;
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
case e_sint256:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128: break;
- case e_sint256: success = true; break;
- case e_uint256:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- 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_uint256:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256: break;
- case e_uint256: success = true; break;
- case e_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;
-
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256: 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;
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
case e_double:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_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;
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
case e_long_double:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- case e_float:
- case e_double: break;
- case e_long_double: success = true; break;
- }
- break;
- }
-
- if (success)
- m_type = type;
- return success;
-}
-
-const char *
-Scalar::GetValueTypeAsCString (Scalar::Type type)
-{
- switch (type)
- {
- case e_void: return "void";
- case e_sint: return "int";
- case e_uint: return "unsigned int";
- case e_slong: return "long";
- case e_ulong: return "unsigned long";
- case e_slonglong: return "long long";
- case e_ulonglong: return "unsigned long long";
- case e_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";
- case e_sint256: return "int256_t";
- case e_uint256: return "uint256_t";
+ 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;
}
- return "???";
-}
-
-Scalar::Type
-Scalar::GetValueTypeForSignedIntegerWithByteSize (size_t byte_size)
-{
- if (byte_size <= sizeof(sint_t))
- return e_sint;
- if (byte_size <= sizeof(slong_t))
- return e_slong;
- if (byte_size <= sizeof(slonglong_t))
- return e_slonglong;
- return e_void;
-}
+ break;
-Scalar::Type
-Scalar::GetValueTypeForUnsignedIntegerWithByteSize (size_t byte_size)
-{
- if (byte_size <= sizeof(uint_t))
- return e_uint;
- if (byte_size <= sizeof(ulong_t))
- return e_ulong;
- if (byte_size <= sizeof(ulonglong_t))
- return e_ulonglong;
- return e_void;
-}
-
-Scalar::Type
-Scalar::GetValueTypeForFloatWithByteSize (size_t byte_size)
-{
- if (byte_size == sizeof(float_t))
- return e_float;
- if (byte_size == sizeof(double_t))
- return e_double;
- if (byte_size == sizeof(long_double_t))
- return e_long_double;
- return e_void;
-}
-
-bool
-Scalar::Cast(Scalar::Type type)
-{
- bool success = false;
- switch (m_type)
- {
+ case e_uint:
+ switch (type) {
case e_void:
- break;
-
case e_sint:
+ break;
case e_uint:
+ success = true;
+ break;
case e_slong:
+ m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
+ success = true;
+ break;
+
case e_ulong:
+ m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8);
+ success = true;
+ break;
+
case e_slonglong:
+ m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
+
case e_ulonglong:
+ m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
case e_sint128:
case e_uint128:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
case e_sint256:
case e_uint256:
- switch (type)
- {
- 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_sint256:
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_uint256:
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
- 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;
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
case e_float:
- switch (type)
- {
- case e_void: break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256: 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;
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
case e_double:
- switch (type)
- {
- case e_void: break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256: 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;
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
case e_long_double:
- switch (type)
- {
- case e_void: break;
- case e_sint:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8);
- success = true;
- break;
-
- case e_uint:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8);
- success = true;
- break;
-
- case e_slong:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
- success = true;
- break;
-
- case e_ulong:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
- success = true;
- break;
-
- case e_slonglong:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
- success = true;
- break;
-
- case e_ulonglong:
- 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_sint256:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
- success = true;
- break;
-
- case e_uint256:
- m_integer = m_float.bitcastToAPInt();
- m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
- 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;
- }
-
- if (success)
- m_type = type;
- return success;
-}
-
-bool
-Scalar::MakeSigned ()
-{
- bool success = false;
-
- switch (m_type)
- {
- case e_void: break;
- case e_sint: success = true; break;
- case e_uint: m_type = e_sint; success = true; break;
- case e_slong: success = true; break;
- 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_sint128; success = true; break;
- case e_sint256: success = true; break;
- case e_uint256: m_type = e_sint256; success = true; break;
- case e_float: success = true; break;
- case e_double: success = true; break;
- case e_long_double: success = true; break;
- }
-
- return success;
-}
-
-bool
-Scalar::MakeUnsigned ()
-{
- bool success = false;
-
- switch (m_type)
- {
- case e_void: break;
- case e_sint: success = true; break;
- case e_uint: m_type = e_uint; success = true; break;
- case e_slong: success = true; break;
- case e_ulong: m_type = e_ulong; success = true; break;
- case e_slonglong: success = true; break;
- case e_ulonglong: m_type = e_ulonglong; success = true; break;
- case e_sint128: success = true; break;
- case e_uint128: m_type = e_uint128; success = true; break;
- case e_sint256: success = true; break;
- case e_uint256: m_type = e_uint256; success = true; break;
- case e_float: success = true; break;
- case e_double: success = true; break;
- case e_long_double: success = true; break;
+ 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;
- return success;
-}
-
-signed char
-Scalar::SChar(char fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_slong:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
+ break;
case e_slong:
+ success = true;
+ break;
case e_ulong:
+ m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8);
+ success = true;
+ break;
+
case e_slonglong:
+ m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
+
case e_ulonglong:
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
case e_sint128:
case e_uint128:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
case e_sint256:
case e_uint256:
- return (schar_t)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- return (schar_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
case e_double:
- return (schar_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (schar_t)(ldbl_val.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-unsigned char
-Scalar::UChar(unsigned char fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_ulong:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
+ break;
case e_ulong:
+ success = true;
+ break;
case e_slonglong:
+ m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
+
case e_ulonglong:
+ m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
case e_sint128:
case e_uint128:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
case e_sint256:
case e_uint256:
- return (uchar_t)(m_integer.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- return (uchar_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
case e_double:
- return (uchar_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (uchar_t)(ldbl_val.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-short
-Scalar::SShort(short fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_slonglong:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
case e_ulong:
+ break;
case e_slonglong:
+ success = true;
+ break;
case e_ulonglong:
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
case e_sint128:
case e_uint128:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
case e_sint256:
case e_uint256:
- return (sshort_t)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue();
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- return (sshort_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
case e_double:
- return (sshort_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (sshort_t)(ldbl_val.sextOrTrunc(sizeof(sshort_t) * 8)).getSExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-unsigned short
-Scalar::UShort(unsigned short fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_ulonglong:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
case e_ulong:
case e_slonglong:
+ break;
case e_ulonglong:
+ success = true;
+ break;
case e_sint128:
case e_uint128:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
case e_sint256:
case e_uint256:
- return (ushort_t)(m_integer.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue();
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- return (ushort_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
case e_double:
- return (ushort_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (ushort_t)(ldbl_val.zextOrTrunc(sizeof(ushort_t) * 8)).getZExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-int
-Scalar::SInt(int fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_sint128:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
case e_ulong:
case e_slonglong:
case e_ulonglong:
+ break;
case e_sint128:
+ success = true;
+ break;
case e_uint128:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
case e_sint256:
case e_uint256:
- return (sint_t)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- return (sint_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
case e_double:
- return (sint_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (sint_t)(ldbl_val.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-unsigned int
-Scalar::UInt(unsigned int fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_uint128:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
@@ -1518,27 +831,39 @@ Scalar::UInt(unsigned int fail_value) const
case e_slonglong:
case e_ulonglong:
case e_sint128:
+ break;
case e_uint128:
+ success = true;
+ break;
case e_sint256:
case e_uint256:
- return (uint_t)(m_integer.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- return (uint_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
case e_double:
- return (uint_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (uint_t)(ldbl_val.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-long
-Scalar::SLong(long fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_sint256:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
@@ -1547,26 +872,38 @@ Scalar::SLong(long fail_value) const
case e_ulonglong:
case e_sint128:
case e_uint128:
+ break;
case e_sint256:
+ success = true;
+ break;
case e_uint256:
- return (slong_t)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- return (slong_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
case e_double:
- return (slong_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (slong_t)(ldbl_val.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-unsigned long
-Scalar::ULong(unsigned long fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_uint256:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
@@ -1576,25 +913,33 @@ Scalar::ULong(unsigned long fail_value) const
case e_sint128:
case e_uint128:
case e_sint256:
+ break;
case e_uint256:
- return (ulong_t)(m_integer.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
+ success = true;
+ break;
case e_float:
- return (ulong_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_integer.bitsToFloat());
+ success = true;
+ break;
+
case e_double:
- return (ulong_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_integer.bitsToDouble());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (ulong_t)(ldbl_val.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-long long
-Scalar::SLongLong(long long fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_float:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
@@ -1605,24 +950,30 @@ Scalar::SLongLong(long long fail_value) const
case e_uint128:
case e_sint256:
case e_uint256:
- return (slonglong_t)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue();
+ break;
case e_float:
- return (slonglong_t)m_float.convertToFloat();
+ success = true;
+ break;
case e_double:
- return (slonglong_t)m_float.convertToDouble();
+ m_float = llvm::APFloat((float_t)m_float.convertToFloat());
+ success = true;
+ break;
+
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (slonglong_t)(ldbl_val.sextOrTrunc(sizeof(slonglong_t) * 8)).getSExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-unsigned long long
-Scalar::ULongLong(unsigned long long fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_double:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
@@ -1633,49 +984,26 @@ Scalar::ULongLong(unsigned long long fail_value) const
case e_uint128:
case e_sint256:
case e_uint256:
- return (ulonglong_t)(m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue();
case e_float:
- return (ulonglong_t)m_float.convertToFloat();
+ break;
case e_double:
- return (ulonglong_t)m_float.convertToDouble();
+ success = true;
+ break;
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (ulonglong_t)(ldbl_val.zextOrTrunc(sizeof(ulonglong_t) * 8)).getZExtValue();
+ 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;
}
- return fail_value;
-}
+ break;
-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:
- case e_sint256:
- case e_uint256:
- return m_integer;
- case e_float:
- case e_double:
- case e_long_double:
- return m_float.bitcastToAPInt();
- }
- return fail_value;
-}
-
-llvm::APInt
-Scalar::UInt128(const llvm::APInt& fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_long_double:
+ switch (type) {
+ case e_void:
case e_sint:
case e_uint:
case e_slong:
@@ -1686,71 +1014,180 @@ Scalar::UInt128(const llvm::APInt& fail_value) const
case e_uint128:
case e_sint256:
case e_uint256:
- return m_integer;
case e_float:
case e_double:
+ break;
case e_long_double:
- return m_float.bitcastToAPInt();
+ success = true;
+ break;
}
- return fail_value;
+ break;
+ }
+
+ if (success)
+ m_type = type;
+ return success;
+}
+
+const char *Scalar::GetValueTypeAsCString(Scalar::Type type) {
+ switch (type) {
+ case e_void:
+ return "void";
+ case e_sint:
+ return "int";
+ case e_uint:
+ return "unsigned int";
+ case e_slong:
+ return "long";
+ case e_ulong:
+ return "unsigned long";
+ case e_slonglong:
+ return "long long";
+ case e_ulonglong:
+ return "unsigned long long";
+ case e_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";
+ case e_sint256:
+ return "int256_t";
+ case e_uint256:
+ return "uint256_t";
+ }
+ return "???";
+}
+
+Scalar::Type
+Scalar::GetValueTypeForSignedIntegerWithByteSize(size_t byte_size) {
+ if (byte_size <= sizeof(sint_t))
+ return e_sint;
+ if (byte_size <= sizeof(slong_t))
+ return e_slong;
+ if (byte_size <= sizeof(slonglong_t))
+ return e_slonglong;
+ return e_void;
}
-llvm::APInt
-Scalar::SInt256(llvm::APInt& fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+Scalar::Type
+Scalar::GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size) {
+ if (byte_size <= sizeof(uint_t))
+ return e_uint;
+ if (byte_size <= sizeof(ulong_t))
+ return e_ulong;
+ if (byte_size <= sizeof(ulonglong_t))
+ return e_ulonglong;
+ return e_void;
+}
+
+Scalar::Type Scalar::GetValueTypeForFloatWithByteSize(size_t byte_size) {
+ if (byte_size == sizeof(float_t))
+ return e_float;
+ if (byte_size == sizeof(double_t))
+ return e_double;
+ if (byte_size == sizeof(long_double_t))
+ return e_long_double;
+ return e_void;
+}
+
+bool Scalar::Cast(Scalar::Type type) {
+ bool success = false;
+ switch (m_type) {
+ case e_void:
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (type) {
+ 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_sint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_uint256:
- return m_integer;
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ 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:
- return m_float.bitcastToAPInt();
+ 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;
}
- return fail_value;
-}
+ break;
-llvm::APInt
-Scalar::UInt256(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:
- case e_sint256:
- case e_uint256:
- 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
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_float:
+ switch (type) {
+ case e_void:
+ break;
case e_sint:
case e_uint:
case e_slong:
@@ -1761,24 +1198,33 @@ Scalar::Float(float fail_value) const
case e_uint128:
case e_sint256:
case e_uint256:
- return m_integer.bitsToFloat();
+ m_integer = m_float.bitcastToAPInt();
+ success = true;
+ break;
case e_float:
- return m_float.convertToFloat();
+ m_float = llvm::APFloat(m_float.convertToFloat());
+ success = true;
+ break;
case e_double:
- return (float_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_float.convertToFloat());
+ success = true;
+ break;
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return ldbl_val.bitsToFloat();
+ 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;
}
- return fail_value;
-}
+ break;
-double
-Scalar::Double(double fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_double:
+ switch (type) {
+ case e_void:
+ break;
case e_sint:
case e_uint:
case e_slong:
@@ -1789,92 +1235,670 @@ Scalar::Double(double fail_value) const
case e_uint128:
case e_sint256:
case e_uint256:
- return m_integer.bitsToDouble();
+ m_integer = m_float.bitcastToAPInt();
+ success = true;
+ break;
case e_float:
- return (double_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_float.convertToDouble());
+ success = true;
+ break;
case e_double:
- return m_float.convertToDouble();
+ m_float = llvm::APFloat(m_float.convertToDouble());
+ success = true;
+ break;
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return ldbl_val.bitsToFloat();
+ 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;
}
- return fail_value;
-}
+ break;
-long double
-Scalar::LongDouble(long double fail_value) const
-{
- switch (m_type)
- {
- case e_void: break;
+ case e_long_double:
+ switch (type) {
+ case e_void:
+ break;
case e_sint:
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.sextOrTrunc(sizeof(sint_t) * 8);
+ success = true;
+ break;
+
case e_uint:
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.zextOrTrunc(sizeof(sint_t) * 8);
+ success = true;
+ break;
+
case e_slong:
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
+ success = true;
+ break;
+
case e_ulong:
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
+ success = true;
+ break;
+
case e_slonglong:
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
+
case e_ulonglong:
+ 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_sint256:
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_uint256:
- return (long_double_t)m_integer.bitsToDouble();
+ m_integer = m_float.bitcastToAPInt();
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
case e_float:
- return (long_double_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_float.convertToFloat());
+ success = true;
+ break;
case e_double:
- return (long_double_t)m_float.convertToDouble();
+ m_float = llvm::APFloat(m_float.convertToFloat());
+ success = true;
+ break;
case e_long_double:
- llvm::APInt ldbl_val = m_float.bitcastToAPInt();
- return (long_double_t)ldbl_val.bitsToDouble();
- }
- return fail_value;
-}
-
-Scalar&
-Scalar::operator+= (const Scalar& rhs)
-{
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (m_type)
- {
- case e_void: break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- 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;
- }
+ success = true;
+ break;
}
- return *this;
+ break;
+ }
+
+ if (success)
+ m_type = type;
+ return success;
}
-Scalar&
-Scalar::operator<<= (const Scalar& rhs)
-{
- switch (m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
+bool Scalar::MakeSigned() {
+ bool success = false;
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ success = true;
+ break;
+ case e_uint:
+ m_type = e_sint;
+ success = true;
+ break;
+ case e_slong:
+ success = true;
+ break;
+ 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_sint128;
+ success = true;
+ break;
+ case e_sint256:
+ success = true;
+ break;
+ case e_uint256:
+ m_type = e_sint256;
+ success = true;
+ break;
+ case e_float:
+ success = true;
+ break;
+ case e_double:
+ success = true;
+ break;
+ case e_long_double:
+ success = true;
+ break;
+ }
+
+ return success;
+}
+
+bool Scalar::MakeUnsigned() {
+ bool success = false;
+
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ success = true;
+ break;
+ case e_uint:
+ m_type = e_uint;
+ success = true;
+ break;
+ case e_slong:
+ success = true;
+ break;
+ case e_ulong:
+ m_type = e_ulong;
+ success = true;
+ break;
+ case e_slonglong:
+ success = true;
+ break;
+ case e_ulonglong:
+ m_type = e_ulonglong;
+ success = true;
+ break;
+ case e_sint128:
+ success = true;
+ break;
+ case e_uint128:
+ m_type = e_uint128;
+ success = true;
+ break;
+ case e_sint256:
+ success = true;
+ break;
+ case e_uint256:
+ m_type = e_uint256;
+ success = true;
+ break;
+ case e_float:
+ success = true;
+ break;
+ case e_double:
+ success = true;
+ break;
+ case e_long_double:
+ success = true;
+ break;
+ }
+
+ return success;
+}
+
+signed 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:
+ case e_sint256:
+ case e_uint256:
+ return (schar_t)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
+ 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.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
+ }
+ 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:
+ case e_sint256:
+ case e_uint256:
+ return (uchar_t)(m_integer.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
+ 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.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
+ }
+ 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:
+ case e_sint256:
+ case e_uint256:
+ return (sshort_t)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8))
+ .getSExtValue();
+ 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 (sshort_t)(ldbl_val.sextOrTrunc(sizeof(sshort_t) * 8))
+ .getSExtValue();
+ }
+ 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:
+ case e_sint256:
+ case e_uint256:
+ return (ushort_t)(m_integer.zextOrTrunc(sizeof(ushort_t) * 8))
+ .getZExtValue();
+ 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 (ushort_t)(ldbl_val.zextOrTrunc(sizeof(ushort_t) * 8))
+ .getZExtValue();
+ }
+ return fail_value;
+}
+
+int Scalar::SInt(int fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (sint_t)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
+ 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 (sint_t)(ldbl_val.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
+ }
+ return fail_value;
+}
+
+unsigned int Scalar::UInt(unsigned int fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (uint_t)(m_integer.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
+ 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 (uint_t)(ldbl_val.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
+ }
+ return fail_value;
+}
+
+long Scalar::SLong(long fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (slong_t)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
+ 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 (slong_t)(ldbl_val.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
+ }
+ return fail_value;
+}
+
+unsigned long Scalar::ULong(unsigned long fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (ulong_t)(m_integer.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
+ 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 (ulong_t)(ldbl_val.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
+ }
+ return fail_value;
+}
+
+long long Scalar::SLongLong(long long fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (slonglong_t)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8))
+ .getSExtValue();
+ 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 (slonglong_t)(ldbl_val.sextOrTrunc(sizeof(slonglong_t) * 8))
+ .getSExtValue();
+ }
+ return fail_value;
+}
+
+unsigned long long Scalar::ULongLong(unsigned long long fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (ulonglong_t)(m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8))
+ .getZExtValue();
+ 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 (ulonglong_t)(ldbl_val.zextOrTrunc(sizeof(ulonglong_t) * 8))
+ .getZExtValue();
+ }
+ 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:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
+ }
+ 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:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
+ }
+ return fail_value;
+}
+
+llvm::APInt Scalar::SInt256(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:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
+ }
+ return fail_value;
+}
+
+llvm::APInt Scalar::UInt256(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:
+ case e_sint256:
+ case e_uint256:
+ 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 {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ 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;
+}
+
+double Scalar::Double(double fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ 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;
+}
+
+long double Scalar::LongDouble(long double fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ 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;
+}
+
+Scalar &Scalar::operator+=(const Scalar &rhs) {
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (m_type) {
+ case e_void:
+ break;
case e_sint:
case e_uint:
case e_slong:
@@ -1885,92 +1909,45 @@ Scalar::operator<<= (const Scalar& rhs)
case e_uint128:
case e_sint256:
case e_uint256:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- m_integer = m_integer << rhs.m_integer;
- break;
- }
- break;
- }
- return *this;
-}
+ m_integer = a->m_integer + b->m_integer;
+ break;
-bool
-Scalar::ShiftRightLogical(const Scalar& rhs)
-{
- switch (m_type)
- {
- case e_void:
case e_float:
case e_double:
case e_long_double:
- m_type = e_void;
- break;
-
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.lshr(rhs.m_integer);
- break;
- }
- break;
+ m_float = a->m_float + b->m_float;
+ break;
}
- return m_type != e_void;
-}
-
-Scalar&
-Scalar::operator>>= (const Scalar& rhs)
-{
- switch (m_type)
- {
+ }
+ return *this;
+}
+
+Scalar &Scalar::operator<<=(const Scalar &rhs) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (rhs.m_type) {
case e_void:
case e_float:
case e_double:
case e_long_double:
- m_type = e_void;
- break;
-
+ m_type = e_void;
+ break;
case e_sint:
case e_uint:
case e_slong:
@@ -1981,44 +1958,40 @@ Scalar::operator>>= (const Scalar& rhs)
case e_uint128:
case e_sint256:
case e_uint256:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- m_integer = m_integer.ashr(rhs.m_integer);
- break;
- }
- break;
+ m_integer = m_integer << rhs.m_integer;
+ break;
}
- return *this;
-}
-
-Scalar&
-Scalar::operator&= (const Scalar& rhs)
-{
- switch (m_type)
- {
+ break;
+ }
+ return *this;
+}
+
+bool Scalar::ShiftRightLogical(const Scalar &rhs) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (rhs.m_type) {
case e_void:
case e_float:
case e_double:
case e_long_double:
- m_type = e_void;
- break;
-
+ m_type = e_void;
+ break;
case e_sint:
case e_uint:
case e_slong:
@@ -2029,69 +2002,40 @@ Scalar::operator&= (const Scalar& rhs)
case e_uint128:
case e_sint256:
case e_uint256:
- switch (rhs.m_type)
- {
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- m_type = e_void;
- break;
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- case e_sint128:
- case e_uint128:
- case e_sint256:
- case e_uint256:
- m_integer &= rhs.m_integer;
- break;
- }
- break;
+ m_integer = m_integer.lshr(rhs.m_integer);
+ break;
}
- return *this;
-}
-
-bool
-Scalar::AbsoluteValue()
-{
- switch (m_type)
- {
+ break;
+ }
+ return m_type != e_void;
+}
+
+Scalar &Scalar::operator>>=(const Scalar &rhs) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (rhs.m_type) {
case e_void:
- break;
-
- case e_sint:
- case e_slong:
- case e_slonglong:
- case e_sint128:
- case e_sint256:
- if (m_integer.isNegative())
- m_integer = -m_integer;
- return true;
-
- case e_uint:
- case e_ulong:
- case e_ulonglong: return true;
- case e_uint128:
- case e_uint256:
case e_float:
case e_double:
case e_long_double:
- m_float.clearSign();
- return true;
- }
- return false;
-}
-
-bool
-Scalar::UnaryNegate()
-{
- switch (m_type)
- {
- case e_void: break;
+ m_type = e_void;
+ break;
case e_sint:
case e_uint:
case e_slong:
@@ -2102,20 +2046,40 @@ Scalar::UnaryNegate()
case e_uint128:
case e_sint256:
case e_uint256:
- m_integer = -m_integer; return true;
+ m_integer = m_integer.ashr(rhs.m_integer);
+ break;
+ }
+ break;
+ }
+ return *this;
+}
+
+Scalar &Scalar::operator&=(const Scalar &rhs) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (rhs.m_type) {
+ case e_void:
case e_float:
case e_double:
case e_long_double:
- m_float.changeSign(); return true;
- }
- return false;
-}
-
-bool
-Scalar::OnesComplement()
-{
- switch (m_type)
- {
+ m_type = e_void;
+ break;
case e_sint:
case e_uint:
case e_slong:
@@ -2126,696 +2090,102 @@ Scalar::OnesComplement()
case e_uint128:
case e_sint256:
case e_uint256:
- m_integer = ~m_integer; return true;
-
- case e_void:
- case e_float:
- case e_double:
- case e_long_double:
- break;
- }
- return false;
-}
-
-const Scalar
-lldb_private::operator+ (const Scalar& lhs, const Scalar& rhs)
-{
- Scalar result;
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (result.m_type)
- {
- case Scalar::e_void: break;
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- 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;
-}
-
-const Scalar
-lldb_private::operator- (const Scalar& lhs, const Scalar& rhs)
-{
- Scalar result;
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (result.m_type)
- {
- case Scalar::e_void: break;
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- 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;
-}
-
-const Scalar
-lldb_private::operator/ (const Scalar& lhs, const Scalar& rhs)
-{
- Scalar result;
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (result.m_type)
- {
- case Scalar::e_void: break;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- if (b->m_integer != 0)
- {
- result.m_integer = a->m_integer.sdiv(b->m_integer);
- return result;
- }
- break;
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- if (b->m_integer != 0)
- {
- result.m_integer = a->m_integer.udiv(b->m_integer);
- return result;
- }
- break;
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- if (b->m_float.isZero())
- {
- result.m_float = a->m_float / b->m_float;
- return result;
- }
- break;
- }
- }
- // For division only, the only way it should make it here is if a promotion failed,
- // or if we are trying to do a divide by zero.
- result.m_type = Scalar::e_void;
- return result;
-}
-
-const Scalar
-lldb_private::operator* (const Scalar& lhs, const Scalar& rhs)
-{
- Scalar result;
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (result.m_type)
- {
- case Scalar::e_void: break;
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- 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;
- }
+ m_integer &= rhs.m_integer;
+ break;
}
- return result;
-}
-
-const Scalar
-lldb_private::operator& (const Scalar& lhs, const Scalar& rhs)
-{
- Scalar result;
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (result.m_type)
- {
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- result.m_integer = a->m_integer & b->m_integer; break;
- case Scalar::e_void:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- // No bitwise AND on floats, doubles of long doubles
- result.m_type = Scalar::e_void;
- break;
- }
- }
- return result;
-}
-
-const Scalar
-lldb_private::operator| (const Scalar& lhs, const Scalar& rhs)
-{
- Scalar result;
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (result.m_type)
- {
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- result.m_integer = a->m_integer | b->m_integer; break;
-
- case Scalar::e_void:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- // No bitwise AND on floats, doubles of long doubles
- result.m_type = Scalar::e_void;
- break;
- }
- }
- return result;
-}
-
-const Scalar
-lldb_private::operator% (const Scalar& lhs, const Scalar& rhs)
-{
- Scalar result;
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (result.m_type)
- {
- default: break;
- case Scalar::e_void: break;
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- if (b->m_integer != 0)
- {
- result.m_integer = a->m_integer.srem(b->m_integer);
- return result;
- }
- break;
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- if (b->m_integer != 0)
- {
- result.m_integer = a->m_integer.urem(b->m_integer);
- return result;
- }
- break;
- }
- }
- result.m_type = Scalar::e_void;
- return result;
-}
-
-const Scalar
-lldb_private::operator^ (const Scalar& lhs, const Scalar& rhs)
-{
- Scalar result;
- Scalar temp_value;
- const Scalar* a;
- const Scalar* b;
- if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) != Scalar::e_void)
- {
- switch (result.m_type)
- {
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- result.m_integer = a->m_integer ^ b->m_integer; break;
-
- case Scalar::e_void:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- // No bitwise AND on floats, doubles of long doubles
- result.m_type = Scalar::e_void;
- break;
- }
- }
- return result;
-}
-
-const Scalar
-lldb_private::operator<< (const Scalar& lhs, const Scalar &rhs)
-{
- Scalar result = lhs;
- result <<= rhs;
- return result;
-}
-
-const Scalar
-lldb_private::operator>> (const Scalar& lhs, const Scalar &rhs)
-{
- Scalar result = lhs;
- result >>= rhs;
- return result;
-}
-
-Error
-Scalar::SetValueFromCString (const char *value_str, Encoding encoding, size_t byte_size)
-{
- Error error;
- if (value_str == nullptr || value_str[0] == '\0')
- {
- error.SetErrorString ("Invalid c-string value string.");
- return error;
- }
- bool success = false;
- switch (encoding)
- {
- case eEncodingInvalid:
- error.SetErrorString ("Invalid encoding.");
- break;
-
- case eEncodingUint:
- if (byte_size <= sizeof (unsigned long long))
- {
- uint64_t uval64 = StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("'%s' is not a valid unsigned integer string value", value_str);
- else if (!UIntValueIsValidForSize (uval64, byte_size))
- error.SetErrorStringWithFormat("value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte unsigned integer value", uval64, (uint64_t)byte_size);
- else
- {
- m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize (byte_size);
- switch (m_type)
- {
- case e_uint: m_integer = llvm::APInt(sizeof(uint_t) * 8, uval64, false); break;
- case e_ulong: m_integer = llvm::APInt(sizeof(ulong_t) * 8, uval64, false); break;
- case e_ulonglong: m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, uval64, false); break;
- default:
- error.SetErrorStringWithFormat("unsupported unsigned integer byte size: %" PRIu64 "", (uint64_t)byte_size);
- break;
- }
- }
- }
- else
- {
- error.SetErrorStringWithFormat("unsupported unsigned integer byte size: %" PRIu64 "", (uint64_t)byte_size);
- return error;
- }
- break;
-
- case eEncodingSint:
- if (byte_size <= sizeof (long long))
- {
- uint64_t sval64 = StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
- if (!success)
- error.SetErrorStringWithFormat ("'%s' is not a valid signed integer string value", value_str);
- else if (!SIntValueIsValidForSize (sval64, byte_size))
- error.SetErrorStringWithFormat("value 0x%" PRIx64 " is too large to fit in a %" PRIu64 " byte signed integer value", sval64, (uint64_t)byte_size);
- else
- {
- m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize (byte_size);
- switch (m_type)
- {
- case e_sint: m_integer = llvm::APInt(sizeof(sint_t) * 8, sval64, true); break;
- case e_slong: m_integer = llvm::APInt(sizeof(slong_t) * 8, sval64, true); break;
- case e_slonglong: m_integer = llvm::APInt(sizeof(slonglong_t) * 8, sval64, true); break;
- default:
- error.SetErrorStringWithFormat("unsupported signed integer byte size: %" PRIu64 "", (uint64_t)byte_size);
- break;
- }
- }
- }
- else
- {
- error.SetErrorStringWithFormat("unsupported signed integer byte size: %" PRIu64 "", (uint64_t)byte_size);
- return error;
- }
- break;
-
- case eEncodingIEEE754:
- static float f_val;
- static double d_val;
- static long double l_val;
- if (byte_size == sizeof (float))
- {
- if (::sscanf (value_str, "%f", &f_val) == 1)
- {
- m_float = llvm::APFloat(f_val);
- m_type = e_float;
- }
- else
- error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
- }
- else if (byte_size == sizeof (double))
- {
- if (::sscanf (value_str, "%lf", &d_val) == 1)
- {
- m_float = llvm::APFloat(d_val);
- m_type = e_double;
- }
- else
- error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
- }
- else if (byte_size == sizeof (long double))
- {
- if (::sscanf (value_str, "%Lf", &l_val) == 1)
- {
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&l_val)->x));
- m_type = e_long_double;
- }
- else
- error.SetErrorStringWithFormat ("'%s' is not a valid float string value", value_str);
- }
- else
- {
- error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "", (uint64_t)byte_size);
- return error;
- }
- break;
-
- case eEncodingVector:
- error.SetErrorString ("vector encoding unsupported.");
- break;
- }
- if (error.Fail())
- m_type = e_void;
-
- return error;
-}
-
-Error
-Scalar::SetValueFromData (DataExtractor &data, lldb::Encoding encoding, size_t byte_size)
-{
- Error error;
-
- type128 int128;
- type256 int256;
- switch (encoding)
- {
- case lldb::eEncodingInvalid:
- error.SetErrorString ("invalid encoding");
- break;
- case lldb::eEncodingVector:
- error.SetErrorString ("vector encoding unsupported");
- break;
- case lldb::eEncodingUint:
- {
- lldb::offset_t offset = 0;
-
- 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 16:
- if (data.GetByteOrder() == eByteOrderBig)
- {
- int128.x[1] = (uint64_t)data.GetU64 (&offset);
- int128.x[0] = (uint64_t)data.GetU64 (&offset);
- }
- else
- {
- int128.x[0] = (uint64_t)data.GetU64 (&offset);
- int128.x[1] = (uint64_t)data.GetU64 (&offset);
- }
- operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
- break;
- case 32:
- if (data.GetByteOrder() == eByteOrderBig)
- {
- int256.x[3] = (uint64_t)data.GetU64 (&offset);
- int256.x[2] = (uint64_t)data.GetU64 (&offset);
- int256.x[1] = (uint64_t)data.GetU64 (&offset);
- int256.x[0] = (uint64_t)data.GetU64 (&offset);
- }
- else
- {
- int256.x[0] = (uint64_t)data.GetU64 (&offset);
- int256.x[1] = (uint64_t)data.GetU64 (&offset);
- int256.x[2] = (uint64_t)data.GetU64 (&offset);
- int256.x[3] = (uint64_t)data.GetU64 (&offset);
- }
- operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
- break;
- default:
- error.SetErrorStringWithFormat("unsupported unsigned integer byte size: %" PRIu64 "", (uint64_t)byte_size);
- break;
- }
- }
- break;
- case lldb::eEncodingSint:
- {
- lldb::offset_t offset = 0;
-
- switch (byte_size)
- {
- case 1: operator=((int8_t)data.GetU8(&offset)); break;
- 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);
- }
- else
- {
- int128.x[0] = (uint64_t)data.GetU64 (&offset);
- int128.x[1] = (uint64_t)data.GetU64 (&offset);
- }
- operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
- break;
- case 32:
- if (data.GetByteOrder() == eByteOrderBig)
- {
- int256.x[3] = (uint64_t)data.GetU64 (&offset);
- int256.x[2] = (uint64_t)data.GetU64 (&offset);
- int256.x[1] = (uint64_t)data.GetU64 (&offset);
- int256.x[0] = (uint64_t)data.GetU64 (&offset);
- }
- else
- {
- int256.x[0] = (uint64_t)data.GetU64 (&offset);
- int256.x[1] = (uint64_t)data.GetU64 (&offset);
- int256.x[2] = (uint64_t)data.GetU64 (&offset);
- int256.x[3] = (uint64_t)data.GetU64 (&offset);
- }
- operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
- break;
- default:
- error.SetErrorStringWithFormat("unsupported signed integer byte size: %" PRIu64 "", (uint64_t)byte_size);
- break;
- }
- }
- break;
- case lldb::eEncodingIEEE754:
- {
- lldb::offset_t offset = 0;
-
- if (byte_size == sizeof (float))
- operator=((float)data.GetFloat(&offset));
- else if (byte_size == sizeof (double))
- operator=((double)data.GetDouble(&offset));
- else if (byte_size == sizeof (long double))
- operator=((long double)data.GetLongDouble(&offset));
- else
- error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "", (uint64_t)byte_size);
- }
- break;
- }
-
- return error;
-}
-
-bool
-Scalar::SignExtend (uint32_t sign_bit_pos)
-{
- const uint32_t max_bit_pos = GetByteSize() * 8;
-
- if (sign_bit_pos < max_bit_pos)
- {
- switch (m_type)
- {
- case Scalar::e_void:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- return false;
-
- case Scalar::e_sint:
- case Scalar::e_uint:
- case Scalar::e_slong:
- case Scalar::e_ulong:
- case Scalar::e_slonglong:
- case Scalar::e_ulonglong:
- case Scalar::e_sint128:
- case Scalar::e_uint128:
- case Scalar::e_sint256:
- case Scalar::e_uint256:
- if (max_bit_pos == sign_bit_pos)
- return true;
- else if (sign_bit_pos < (max_bit_pos-1))
- {
- llvm::APInt sign_bit = llvm::APInt::getSignBit(sign_bit_pos + 1);
- llvm::APInt bitwize_and = m_integer & sign_bit;
- if (bitwize_and.getBoolValue())
- {
- const llvm::APInt mask = ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
- m_integer |= mask;
- }
- return true;
- }
- break;
- }
- }
- return false;
-}
-
-size_t
-Scalar::GetAsMemoryData (void *dst,
- size_t dst_len,
- lldb::ByteOrder dst_byte_order,
- Error &error) const
-{
- // Get a data extractor that points to the native scalar data
- DataExtractor data;
- if (!GetData(data))
- {
- error.SetErrorString ("invalid scalar value");
- return 0;
- }
-
- const size_t src_len = data.GetByteSize();
-
- // Prepare a memory buffer that contains some or all of the register value
- const size_t bytes_copied = data.CopyByteOrderedData (0, // src offset
- src_len, // src length
- dst, // dst buffer
- dst_len, // dst length
- dst_byte_order); // dst byte order
- if (bytes_copied == 0)
- error.SetErrorString ("failed to copy data");
-
- return bytes_copied;
-}
-
-bool
-Scalar::ExtractBitfield (uint32_t bit_size,
- uint32_t bit_offset)
-{
- if (bit_size == 0)
- return true;
+ break;
+ }
+ return *this;
+}
+
+bool Scalar::AbsoluteValue() {
+ switch (m_type) {
+ case e_void:
+ break;
+
+ case e_sint:
+ case e_slong:
+ case e_slonglong:
+ case e_sint128:
+ case e_sint256:
+ if (m_integer.isNegative())
+ m_integer = -m_integer;
+ return true;
- switch (m_type)
- {
- case Scalar::e_void:
- case Scalar::e_float:
- case Scalar::e_double:
- case Scalar::e_long_double:
- break;
-
- case Scalar::e_sint:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- m_integer = m_integer.ashr(bit_offset).sextOrTrunc(bit_size).sextOrSelf(8 * GetByteSize());
- return true;
-
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- m_integer = m_integer.lshr(bit_offset).zextOrTrunc(bit_size).zextOrSelf(8 * GetByteSize());
- return true;
- }
- return false;
-}
+ case e_uint:
+ case e_ulong:
+ case e_ulonglong:
+ return true;
+ case e_uint128:
+ case e_uint256:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_float.clearSign();
+ return true;
+ }
+ return false;
+}
+
+bool Scalar::UnaryNegate() {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = -m_integer;
+ return true;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_float.changeSign();
+ return true;
+ }
+ return false;
+}
+
+bool Scalar::OnesComplement() {
+ switch (m_type) {
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = ~m_integer;
+ return true;
-bool
-lldb_private::operator== (const Scalar& lhs, const Scalar& rhs)
-{
- // If either entry is void then we can just compare the types
- if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
- return lhs.m_type == rhs.m_type;
-
- 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 e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ break;
+ }
+ return false;
+}
+
+const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
+ break;
case Scalar::e_sint:
case Scalar::e_uint:
case Scalar::e_slong:
@@ -2826,31 +2196,28 @@ lldb_private::operator== (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_uint128:
case Scalar::e_sint256:
case Scalar::e_uint256:
- return a->m_integer == b->m_integer;
+ result.m_integer = a->m_integer + b->m_integer;
+ break;
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;
+ result.m_float = a->m_float + b->m_float;
+ break;
}
- return false;
-}
-
-bool
-lldb_private::operator!= (const Scalar& lhs, const Scalar& rhs)
-{
- // If either entry is void then we can just compare the types
- if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
- return lhs.m_type != rhs.m_type;
-
- 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;
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator-(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
+ break;
case Scalar::e_sint:
case Scalar::e_uint:
case Scalar::e_slong:
@@ -2861,202 +2228,849 @@ lldb_private::operator!= (const Scalar& lhs, const Scalar& rhs)
case Scalar::e_uint128:
case Scalar::e_sint256:
case Scalar::e_uint256:
- return a->m_integer != b->m_integer;
+ result.m_integer = a->m_integer - b->m_integer;
+ break;
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;
+ result.m_float = a->m_float - b->m_float;
+ break;
}
- return true;
-}
-
-bool
-lldb_private::operator< (const Scalar& lhs, const Scalar& rhs)
-{
- if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
- return false;
-
- 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;
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
+ break;
case Scalar::e_sint:
case Scalar::e_slong:
case Scalar::e_slonglong:
case Scalar::e_sint128:
case Scalar::e_sint256:
- return a->m_integer.slt(b->m_integer);
+ if (b->m_integer != 0) {
+ result.m_integer = a->m_integer.sdiv(b->m_integer);
+ return result;
+ }
+ break;
case Scalar::e_uint:
case Scalar::e_ulong:
case Scalar::e_ulonglong:
case Scalar::e_uint128:
case Scalar::e_uint256:
- return a->m_integer.ult(b->m_integer);
+ if (b->m_integer != 0) {
+ result.m_integer = a->m_integer.udiv(b->m_integer);
+ return result;
+ }
+ break;
case Scalar::e_float:
case Scalar::e_double:
case Scalar::e_long_double:
- result = a->m_float.compare(b->m_float);
- if(result == llvm::APFloat::cmpLessThan)
- return true;
+ if (b->m_float.isZero()) {
+ result.m_float = a->m_float / b->m_float;
+ return result;
+ }
+ break;
}
- return false;
-}
-
-bool
-lldb_private::operator<= (const Scalar& lhs, const Scalar& rhs)
-{
- if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
- return false;
+ }
+ // For division only, the only way it should make it here is if a promotion
+ // failed,
+ // or if we are trying to do a divide by zero.
+ result.m_type = Scalar::e_void;
+ return result;
+}
+
+const Scalar lldb_private::operator*(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
+ break;
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ 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;
+}
+
+const Scalar lldb_private::operator&(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ result.m_integer = a->m_integer & b->m_integer;
+ break;
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ // No bitwise AND on floats, doubles of long doubles
+ result.m_type = Scalar::e_void;
+ break;
+ }
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator|(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ result.m_integer = a->m_integer | b->m_integer;
+ break;
- 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_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ // No bitwise AND on floats, doubles of long doubles
+ result.m_type = Scalar::e_void;
+ break;
+ }
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator%(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ default:
+ break;
+ case Scalar::e_void:
+ break;
case Scalar::e_sint:
case Scalar::e_slong:
case Scalar::e_slonglong:
case Scalar::e_sint128:
case Scalar::e_sint256:
- return a->m_integer.sle(b->m_integer);
+ if (b->m_integer != 0) {
+ result.m_integer = a->m_integer.srem(b->m_integer);
+ return result;
+ }
+ break;
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ if (b->m_integer != 0) {
+ result.m_integer = a->m_integer.urem(b->m_integer);
+ return result;
+ }
+ break;
+ }
+ }
+ result.m_type = Scalar::e_void;
+ return result;
+}
+
+const Scalar lldb_private::operator^(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_sint:
case Scalar::e_uint:
+ case Scalar::e_slong:
case Scalar::e_ulong:
+ case Scalar::e_slonglong:
case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
case Scalar::e_uint128:
+ case Scalar::e_sint256:
case Scalar::e_uint256:
- return a->m_integer.ule(b->m_integer);
+ result.m_integer = a->m_integer ^ b->m_integer;
+ break;
+
+ case Scalar::e_void:
case Scalar::e_float:
case Scalar::e_double:
case Scalar::e_long_double:
- result = a->m_float.compare(b->m_float);
- if(result == llvm::APFloat::cmpLessThan || result == llvm::APFloat::cmpEqual)
- return true;
+ // No bitwise AND on floats, doubles of long doubles
+ result.m_type = Scalar::e_void;
+ break;
}
- return false;
+ }
+ return result;
}
-bool
-lldb_private::operator> (const Scalar& lhs, const Scalar& rhs)
-{
- if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
- return false;
-
- 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:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- return a->m_integer.sgt(b->m_integer);
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- 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;
+const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result = lhs;
+ result <<= rhs;
+ return result;
}
-bool
-lldb_private::operator>= (const Scalar& lhs, const Scalar& rhs)
-{
- if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
- return false;
-
- 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:
- case Scalar::e_slong:
- case Scalar::e_slonglong:
- case Scalar::e_sint128:
- case Scalar::e_sint256:
- return a->m_integer.sge(b->m_integer);
- case Scalar::e_uint:
- case Scalar::e_ulong:
- case Scalar::e_ulonglong:
- case Scalar::e_uint128:
- case Scalar::e_uint256:
- 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;
+const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result = lhs;
+ result >>= rhs;
+ return result;
}
-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:
- case e_sint256:
- case e_uint256: m_integer.clearBit(bit); return true;
- case e_float:
- case e_double:
- case e_long_double: break;
+Error Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
+ size_t byte_size) {
+ Error error;
+ if (value_str == nullptr || value_str[0] == '\0') {
+ error.SetErrorString("Invalid c-string value string.");
+ return error;
+ }
+ bool success = false;
+ switch (encoding) {
+ case eEncodingInvalid:
+ error.SetErrorString("Invalid encoding.");
+ break;
+
+ case eEncodingUint:
+ if (byte_size <= sizeof(unsigned long long)) {
+ uint64_t uval64 =
+ StringConvert::ToUInt64(value_str, UINT64_MAX, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "'%s' is not a valid unsigned integer string value", value_str);
+ else if (!UIntValueIsValidForSize(uval64, byte_size))
+ error.SetErrorStringWithFormat("value 0x%" PRIx64
+ " is too large to fit in a %" PRIu64
+ " byte unsigned integer value",
+ uval64, (uint64_t)byte_size);
+ else {
+ m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize(byte_size);
+ switch (m_type) {
+ case e_uint:
+ m_integer = llvm::APInt(sizeof(uint_t) * 8, uval64, false);
+ break;
+ case e_ulong:
+ m_integer = llvm::APInt(sizeof(ulong_t) * 8, uval64, false);
+ break;
+ case e_ulonglong:
+ m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, uval64, false);
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ break;
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ return error;
}
- return false;
+ break;
+
+ case eEncodingSint:
+ if (byte_size <= sizeof(long long)) {
+ uint64_t sval64 =
+ StringConvert::ToSInt64(value_str, INT64_MAX, 0, &success);
+ if (!success)
+ error.SetErrorStringWithFormat(
+ "'%s' is not a valid signed integer string value", value_str);
+ else if (!SIntValueIsValidForSize(sval64, byte_size))
+ error.SetErrorStringWithFormat("value 0x%" PRIx64
+ " is too large to fit in a %" PRIu64
+ " byte signed integer value",
+ sval64, (uint64_t)byte_size);
+ else {
+ m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize(byte_size);
+ switch (m_type) {
+ case e_sint:
+ m_integer = llvm::APInt(sizeof(sint_t) * 8, sval64, true);
+ break;
+ case e_slong:
+ m_integer = llvm::APInt(sizeof(slong_t) * 8, sval64, true);
+ break;
+ case e_slonglong:
+ m_integer = llvm::APInt(sizeof(slonglong_t) * 8, sval64, true);
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "unsupported signed integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ break;
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "unsupported signed integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ return error;
+ }
+ break;
+
+ case eEncodingIEEE754:
+ static float f_val;
+ static double d_val;
+ static long double l_val;
+ if (byte_size == sizeof(float)) {
+ if (::sscanf(value_str, "%f", &f_val) == 1) {
+ m_float = llvm::APFloat(f_val);
+ m_type = e_float;
+ } else
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_str);
+ } else if (byte_size == sizeof(double)) {
+ if (::sscanf(value_str, "%lf", &d_val) == 1) {
+ m_float = llvm::APFloat(d_val);
+ m_type = e_double;
+ } else
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_str);
+ } else if (byte_size == sizeof(long double)) {
+ if (::sscanf(value_str, "%Lf", &l_val) == 1) {
+ m_float =
+ llvm::APFloat(llvm::APFloat::x87DoubleExtended(),
+ llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
+ ((type128 *)&l_val)->x));
+ m_type = e_long_double;
+ } else
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_str);
+ } else {
+ error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ return error;
+ }
+ break;
+
+ case eEncodingVector:
+ error.SetErrorString("vector encoding unsupported.");
+ break;
+ }
+ if (error.Fail())
+ m_type = e_void;
+
+ return error;
+}
+
+Error Scalar::SetValueFromData(DataExtractor &data, lldb::Encoding encoding,
+ size_t byte_size) {
+ Error error;
+
+ type128 int128;
+ type256 int256;
+ switch (encoding) {
+ case lldb::eEncodingInvalid:
+ error.SetErrorString("invalid encoding");
+ break;
+ case lldb::eEncodingVector:
+ error.SetErrorString("vector encoding unsupported");
+ break;
+ case lldb::eEncodingUint: {
+ lldb::offset_t offset = 0;
+
+ 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 16:
+ if (data.GetByteOrder() == eByteOrderBig) {
+ int128.x[1] = (uint64_t)data.GetU64(&offset);
+ int128.x[0] = (uint64_t)data.GetU64(&offset);
+ } else {
+ int128.x[0] = (uint64_t)data.GetU64(&offset);
+ int128.x[1] = (uint64_t)data.GetU64(&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
+ break;
+ case 32:
+ if (data.GetByteOrder() == eByteOrderBig) {
+ int256.x[3] = (uint64_t)data.GetU64(&offset);
+ int256.x[2] = (uint64_t)data.GetU64(&offset);
+ int256.x[1] = (uint64_t)data.GetU64(&offset);
+ int256.x[0] = (uint64_t)data.GetU64(&offset);
+ } else {
+ int256.x[0] = (uint64_t)data.GetU64(&offset);
+ int256.x[1] = (uint64_t)data.GetU64(&offset);
+ int256.x[2] = (uint64_t)data.GetU64(&offset);
+ int256.x[3] = (uint64_t)data.GetU64(&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ break;
+ }
+ } break;
+ case lldb::eEncodingSint: {
+ lldb::offset_t offset = 0;
+
+ switch (byte_size) {
+ case 1:
+ operator=((int8_t)data.GetU8(&offset));
+ break;
+ 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);
+ } else {
+ int128.x[0] = (uint64_t)data.GetU64(&offset);
+ int128.x[1] = (uint64_t)data.GetU64(&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
+ break;
+ case 32:
+ if (data.GetByteOrder() == eByteOrderBig) {
+ int256.x[3] = (uint64_t)data.GetU64(&offset);
+ int256.x[2] = (uint64_t)data.GetU64(&offset);
+ int256.x[1] = (uint64_t)data.GetU64(&offset);
+ int256.x[0] = (uint64_t)data.GetU64(&offset);
+ } else {
+ int256.x[0] = (uint64_t)data.GetU64(&offset);
+ int256.x[1] = (uint64_t)data.GetU64(&offset);
+ int256.x[2] = (uint64_t)data.GetU64(&offset);
+ int256.x[3] = (uint64_t)data.GetU64(&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "unsupported signed integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ break;
+ }
+ } break;
+ case lldb::eEncodingIEEE754: {
+ lldb::offset_t offset = 0;
+
+ if (byte_size == sizeof(float))
+ operator=((float)data.GetFloat(&offset));
+ else if (byte_size == sizeof(double))
+ operator=((double)data.GetDouble(&offset));
+ else if (byte_size == sizeof(long double))
+ operator=((long double)data.GetLongDouble(&offset));
+ else
+ error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ } break;
+ }
+
+ return error;
}
-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:
- case e_sint256:
- case e_uint256: m_integer.setBit(bit); return true;
- case e_float:
- case e_double:
- case e_long_double: break;
+bool Scalar::SignExtend(uint32_t sign_bit_pos) {
+ const uint32_t max_bit_pos = GetByteSize() * 8;
+
+ if (sign_bit_pos < max_bit_pos) {
+ switch (m_type) {
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ return false;
+
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ if (max_bit_pos == sign_bit_pos)
+ return true;
+ else if (sign_bit_pos < (max_bit_pos - 1)) {
+ llvm::APInt sign_bit = llvm::APInt::getSignBit(sign_bit_pos + 1);
+ llvm::APInt bitwize_and = m_integer & sign_bit;
+ if (bitwize_and.getBoolValue()) {
+ const llvm::APInt mask =
+ ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
+ m_integer |= mask;
+ }
+ return true;
+ }
+ break;
}
- return false;
+ }
+ return false;
}
+size_t Scalar::GetAsMemoryData(void *dst, size_t dst_len,
+ lldb::ByteOrder dst_byte_order,
+ Error &error) const {
+ // Get a data extractor that points to the native scalar data
+ DataExtractor data;
+ if (!GetData(data)) {
+ error.SetErrorString("invalid scalar value");
+ return 0;
+ }
+
+ const size_t src_len = data.GetByteSize();
+
+ // Prepare a memory buffer that contains some or all of the register value
+ const size_t bytes_copied =
+ data.CopyByteOrderedData(0, // src offset
+ src_len, // src length
+ dst, // dst buffer
+ dst_len, // dst length
+ dst_byte_order); // dst byte order
+ if (bytes_copied == 0)
+ error.SetErrorString("failed to copy data");
+
+ return bytes_copied;
+}
+
+bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {
+ if (bit_size == 0)
+ return true;
+
+ switch (m_type) {
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ break;
+
+ case Scalar::e_sint:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ m_integer = m_integer.ashr(bit_offset)
+ .sextOrTrunc(bit_size)
+ .sextOrSelf(8 * GetByteSize());
+ return true;
+
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ m_integer = m_integer.lshr(bit_offset)
+ .zextOrTrunc(bit_size)
+ .zextOrSelf(8 * GetByteSize());
+ return true;
+ }
+ return false;
+}
+
+bool lldb_private::operator==(const Scalar &lhs, const Scalar &rhs) {
+ // If either entry is void then we can just compare the types
+ if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
+ return lhs.m_type == rhs.m_type;
+
+ 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:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ 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;
+}
+
+bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) {
+ // If either entry is void then we can just compare the types
+ if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
+ return lhs.m_type != rhs.m_type;
+
+ 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:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ 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;
+}
+
+bool lldb_private::operator<(const Scalar &lhs, const Scalar &rhs) {
+ if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
+ return false;
+
+ 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:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ return a->m_integer.slt(b->m_integer);
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ 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;
+}
+
+bool lldb_private::operator<=(const Scalar &lhs, const Scalar &rhs) {
+ if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
+ return false;
+
+ 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:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ return a->m_integer.sle(b->m_integer);
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ 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;
+}
+
+bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) {
+ if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
+ return false;
+
+ 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:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ return a->m_integer.sgt(b->m_integer);
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ 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;
+}
+
+bool lldb_private::operator>=(const Scalar &lhs, const Scalar &rhs) {
+ if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
+ return false;
+
+ 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:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ return a->m_integer.sge(b->m_integer);
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ 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:
+ case e_sint256:
+ case e_uint256:
+ 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:
+ case e_sint256:
+ case e_uint256:
+ m_integer.setBit(bit);
+ return true;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ break;
+ }
+ return false;
+}
diff --git a/source/Core/SearchFilter.cpp b/source/Core/SearchFilter.cpp
index 202a40ff414d..2dfb26910ee0 100644
--- a/source/Core/SearchFilter.cpp
+++ b/source/Core/SearchFilter.cpp
@@ -12,89 +12,169 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
#include "lldb/Core/SearchFilter.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Target/Target.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
-Searcher::Searcher() = default;
+const char *SearchFilter::g_ty_to_name[] = {"Unconstrained", "Exception",
+ "Module", "Modules",
+ "ModulesAndCU", "Unknown"};
-Searcher::~Searcher() = default;
+const char
+ *SearchFilter::g_option_names[SearchFilter::OptionNames::LastOptionName] = {
+ "ModuleList", "CUList"};
+
+const char *SearchFilter::FilterTyToName(enum FilterTy type) {
+ if (type > LastKnownFilterType)
+ return g_ty_to_name[UnknownFilter];
-void
-Searcher::GetDescription (Stream *s)
-{
+ return g_ty_to_name[type];
}
-SearchFilter::SearchFilter(const TargetSP &target_sp) :
- m_target_sp (target_sp)
-{
+SearchFilter::FilterTy SearchFilter::NameToFilterTy(const char *name) {
+ for (size_t i = 0; i <= LastKnownFilterType; i++) {
+ if (strcmp(name, g_ty_to_name[i]) == 0)
+ return (FilterTy)i;
+ }
+ return UnknownFilter;
}
-SearchFilter::SearchFilter(const SearchFilter& rhs) = default;
+Searcher::Searcher() = default;
-SearchFilter&
-SearchFilter::operator=(const SearchFilter& rhs) = default;
+Searcher::~Searcher() = default;
-SearchFilter::~SearchFilter() = default;
+void Searcher::GetDescription(Stream *s) {}
-bool
-SearchFilter::ModulePasses (const FileSpec &spec)
-{
- return true;
-}
+SearchFilter::SearchFilter(const TargetSP &target_sp, unsigned char filterType)
+ : m_target_sp(target_sp), SubclassID(filterType) {}
-bool
-SearchFilter::ModulePasses (const ModuleSP &module_sp)
-{
- return true;
-}
+SearchFilter::SearchFilter(const SearchFilter &rhs) = default;
-bool
-SearchFilter::AddressPasses (Address &address)
-{
- return true;
-}
+SearchFilter &SearchFilter::operator=(const SearchFilter &rhs) = default;
-bool
-SearchFilter::CompUnitPasses (FileSpec &fileSpec)
-{
- return true;
-}
+SearchFilter::~SearchFilter() = default;
-bool
-SearchFilter::CompUnitPasses (CompileUnit &compUnit)
-{
- return true;
+SearchFilterSP SearchFilter::CreateFromStructuredData(
+ Target &target, const StructuredData::Dictionary &filter_dict,
+ Error &error) {
+ SearchFilterSP result_sp;
+ if (!filter_dict.IsValid()) {
+ error.SetErrorString("Can't deserialize from an invalid data object.");
+ return result_sp;
+ }
+
+ std::string subclass_name;
+
+ bool success = filter_dict.GetValueForKeyAsString(
+ GetSerializationSubclassKey(), subclass_name);
+ if (!success) {
+ error.SetErrorStringWithFormat("Filter data missing subclass key");
+ return result_sp;
+ }
+
+ FilterTy filter_type = NameToFilterTy(subclass_name.c_str());
+ if (filter_type == UnknownFilter) {
+ error.SetErrorStringWithFormat("Unknown filter type: %s.",
+ subclass_name.c_str());
+ return result_sp;
+ }
+
+ StructuredData::Dictionary *subclass_options = nullptr;
+ success = filter_dict.GetValueForKeyAsDictionary(
+ GetSerializationSubclassOptionsKey(), subclass_options);
+ if (!success || !subclass_options || !subclass_options->IsValid()) {
+ error.SetErrorString("Filter data missing subclass options key.");
+ return result_sp;
+ }
+
+ switch (filter_type) {
+ case Unconstrained:
+ result_sp = SearchFilterForUnconstrainedSearches::CreateFromStructuredData(
+ target, *subclass_options, error);
+ break;
+ case ByModule:
+ result_sp = SearchFilterByModule::CreateFromStructuredData(
+ target, *subclass_options, error);
+ break;
+ case ByModules:
+ result_sp = SearchFilterByModuleList::CreateFromStructuredData(
+ target, *subclass_options, error);
+ break;
+ case ByModulesAndCU:
+ result_sp = SearchFilterByModuleListAndCU::CreateFromStructuredData(
+ target, *subclass_options, error);
+ break;
+ case Exception:
+ error.SetErrorString("Can't serialize exception breakpoints yet.");
+ break;
+ default:
+ llvm_unreachable("Should never get an uresolvable filter type.");
+ }
+
+ return result_sp;
+}
+
+bool SearchFilter::ModulePasses(const FileSpec &spec) { return true; }
+
+bool SearchFilter::ModulePasses(const ModuleSP &module_sp) { return true; }
+
+bool SearchFilter::AddressPasses(Address &address) { return true; }
+
+bool SearchFilter::CompUnitPasses(FileSpec &fileSpec) { return true; }
+
+bool SearchFilter::CompUnitPasses(CompileUnit &compUnit) { return true; }
+
+uint32_t SearchFilter::GetFilterRequiredItems() {
+ return (lldb::SymbolContextItem)0;
+}
+
+void SearchFilter::GetDescription(Stream *s) {}
+
+void SearchFilter::Dump(Stream *s) const {}
+
+lldb::SearchFilterSP SearchFilter::CopyForBreakpoint(Breakpoint &breakpoint) {
+ SearchFilterSP ret_sp = DoCopyForBreakpoint(breakpoint);
+ TargetSP target_sp = breakpoint.GetTargetSP();
+ ret_sp->SetTarget(target_sp);
+ return ret_sp;
}
-uint32_t
-SearchFilter::GetFilterRequiredItems()
-{
- return (lldb::SymbolContextItem) 0;
-}
+//----------------------------------------------------------------------
+// Helper functions for serialization.
+//----------------------------------------------------------------------
-void
-SearchFilter::GetDescription (Stream *s)
-{
-}
+StructuredData::DictionarySP
+SearchFilter::WrapOptionsDict(StructuredData::DictionarySP options_dict_sp) {
+ if (!options_dict_sp || !options_dict_sp->IsValid())
+ return StructuredData::DictionarySP();
+
+ StructuredData::DictionarySP type_dict_sp(new StructuredData::Dictionary());
+ type_dict_sp->AddStringItem(GetSerializationSubclassKey(), GetFilterName());
+ type_dict_sp->AddItem(GetSerializationSubclassOptionsKey(), options_dict_sp);
-void
-SearchFilter::Dump (Stream *s) const
-{
+ return type_dict_sp;
}
-lldb::SearchFilterSP
-SearchFilter::CopyForBreakpoint (Breakpoint &breakpoint)
-{
- SearchFilterSP ret_sp = DoCopyForBreakpoint (breakpoint);
- TargetSP target_sp = breakpoint.GetTargetSP();
- ret_sp->SetTarget(target_sp);
- return ret_sp;
+void SearchFilter::SerializeFileSpecList(
+ StructuredData::DictionarySP &options_dict_sp, OptionNames name,
+ FileSpecList &file_list) {
+ size_t num_modules = file_list.GetSize();
+
+ // Don't serialize empty lists.
+ if (num_modules == 0)
+ return;
+
+ StructuredData::ArraySP module_array_sp(new StructuredData::Array());
+ for (size_t i = 0; i < num_modules; i++) {
+ module_array_sp->AddItem(StructuredData::StringSP(
+ new StructuredData::String(file_list.GetFileSpecAtIndex(i).GetPath())));
+ }
+ options_dict_sp->AddItem(GetKey(name), module_array_sp);
}
//----------------------------------------------------------------------
@@ -102,191 +182,178 @@ SearchFilter::CopyForBreakpoint (Breakpoint &breakpoint)
// SymbolContext.
//----------------------------------------------------------------------
-void
-SearchFilter::Search (Searcher &searcher)
-{
- SymbolContext empty_sc;
+void SearchFilter::Search(Searcher &searcher) {
+ SymbolContext empty_sc;
- if (!m_target_sp)
- return;
- empty_sc.target_sp = m_target_sp;
+ if (!m_target_sp)
+ return;
+ empty_sc.target_sp = m_target_sp;
- if (searcher.GetDepth() == Searcher::eDepthTarget)
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
- else
- DoModuleIteration(empty_sc, searcher);
+ if (searcher.GetDepth() == Searcher::eDepthTarget)
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ else
+ DoModuleIteration(empty_sc, searcher);
}
-void
-SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules)
-{
- SymbolContext empty_sc;
+void SearchFilter::SearchInModuleList(Searcher &searcher, ModuleList &modules) {
+ SymbolContext empty_sc;
- if (!m_target_sp)
- return;
- empty_sc.target_sp = m_target_sp;
+ if (!m_target_sp)
+ return;
+ empty_sc.target_sp = m_target_sp;
- if (searcher.GetDepth() == Searcher::eDepthTarget)
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
- else
- {
- std::lock_guard<std::recursive_mutex> guard(modules.GetMutex());
- const size_t numModules = modules.GetSize();
-
- for (size_t i = 0; i < numModules; i++)
- {
- ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i));
- if (ModulePasses(module_sp))
- {
- if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop)
- return;
- }
- }
+ if (searcher.GetDepth() == Searcher::eDepthTarget)
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ else {
+ std::lock_guard<std::recursive_mutex> guard(modules.GetMutex());
+ const size_t numModules = modules.GetSize();
+
+ for (size_t i = 0; i < numModules; i++) {
+ ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i));
+ if (ModulePasses(module_sp)) {
+ if (DoModuleIteration(module_sp, searcher) ==
+ Searcher::eCallbackReturnStop)
+ return;
+ }
}
+ }
}
Searcher::CallbackReturn
-SearchFilter::DoModuleIteration (const lldb::ModuleSP& module_sp, Searcher &searcher)
-{
- SymbolContext matchingContext (m_target_sp, module_sp);
- return DoModuleIteration(matchingContext, searcher);
+SearchFilter::DoModuleIteration(const lldb::ModuleSP &module_sp,
+ Searcher &searcher) {
+ SymbolContext matchingContext(m_target_sp, module_sp);
+ return DoModuleIteration(matchingContext, searcher);
}
Searcher::CallbackReturn
-SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searcher)
-{
- if (searcher.GetDepth () >= Searcher::eDepthModule)
- {
- if (context.module_sp)
- {
- if (searcher.GetDepth () == Searcher::eDepthModule)
- {
- SymbolContext matchingContext(context.module_sp.get());
- searcher.SearchCallback(*this, matchingContext, nullptr, false);
- }
- else
- {
- return DoCUIteration(context.module_sp, context, searcher);
- }
- }
- else
- {
- const ModuleList &target_images = m_target_sp->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
-
- size_t n_modules = target_images.GetSize();
- for (size_t i = 0; i < n_modules; i++)
- {
- // If this is the last level supplied, then call the callback directly,
- // otherwise descend.
- ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked (i));
- if (!ModulePasses (module_sp))
- continue;
-
- if (searcher.GetDepth () == Searcher::eDepthModule)
- {
- SymbolContext matchingContext(m_target_sp, module_sp);
-
- Searcher::CallbackReturn shouldContinue = searcher.SearchCallback(*this, matchingContext, nullptr, false);
- if (shouldContinue == Searcher::eCallbackReturnStop
- || shouldContinue == Searcher::eCallbackReturnPop)
- return shouldContinue;
- }
- else
- {
- Searcher::CallbackReturn shouldContinue = DoCUIteration(module_sp, context, searcher);
- if (shouldContinue == Searcher::eCallbackReturnStop)
- return shouldContinue;
- else if (shouldContinue == Searcher::eCallbackReturnPop)
- continue;
- }
- }
+SearchFilter::DoModuleIteration(const SymbolContext &context,
+ Searcher &searcher) {
+ if (searcher.GetDepth() >= Searcher::eDepthModule) {
+ if (context.module_sp) {
+ if (searcher.GetDepth() == Searcher::eDepthModule) {
+ SymbolContext matchingContext(context.module_sp.get());
+ searcher.SearchCallback(*this, matchingContext, nullptr, false);
+ } else {
+ return DoCUIteration(context.module_sp, context, searcher);
+ }
+ } else {
+ const ModuleList &target_images = m_target_sp->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+
+ size_t n_modules = target_images.GetSize();
+ for (size_t i = 0; i < n_modules; i++) {
+ // If this is the last level supplied, then call the callback directly,
+ // otherwise descend.
+ ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked(i));
+ if (!ModulePasses(module_sp))
+ continue;
+
+ if (searcher.GetDepth() == Searcher::eDepthModule) {
+ SymbolContext matchingContext(m_target_sp, module_sp);
+
+ Searcher::CallbackReturn shouldContinue =
+ searcher.SearchCallback(*this, matchingContext, nullptr, false);
+ if (shouldContinue == Searcher::eCallbackReturnStop ||
+ shouldContinue == Searcher::eCallbackReturnPop)
+ return shouldContinue;
+ } else {
+ Searcher::CallbackReturn shouldContinue =
+ DoCUIteration(module_sp, context, searcher);
+ if (shouldContinue == Searcher::eCallbackReturnStop)
+ return shouldContinue;
+ else if (shouldContinue == Searcher::eCallbackReturnPop)
+ continue;
}
+ }
}
- return Searcher::eCallbackReturnContinue;
+ }
+ return Searcher::eCallbackReturnContinue;
}
Searcher::CallbackReturn
-SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher)
-{
- Searcher::CallbackReturn shouldContinue;
- if (context.comp_unit == nullptr)
- {
- const size_t num_comp_units = module_sp->GetNumCompileUnits();
- for (size_t i = 0; i < num_comp_units; i++)
- {
- CompUnitSP cu_sp (module_sp->GetCompileUnitAtIndex (i));
- if (cu_sp)
- {
- if (!CompUnitPasses (*(cu_sp.get())))
- continue;
-
- if (searcher.GetDepth () == Searcher::eDepthCompUnit)
- {
- SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
-
- shouldContinue = searcher.SearchCallback(*this, matchingContext, nullptr, false);
-
- if (shouldContinue == Searcher::eCallbackReturnPop)
- return Searcher::eCallbackReturnContinue;
- else if (shouldContinue == Searcher::eCallbackReturnStop)
- return shouldContinue;
- }
- else
- {
- // FIXME Descend to block.
- }
- }
+SearchFilter::DoCUIteration(const ModuleSP &module_sp,
+ const SymbolContext &context, Searcher &searcher) {
+ Searcher::CallbackReturn shouldContinue;
+ if (context.comp_unit == nullptr) {
+ const size_t num_comp_units = module_sp->GetNumCompileUnits();
+ for (size_t i = 0; i < num_comp_units; i++) {
+ CompUnitSP cu_sp(module_sp->GetCompileUnitAtIndex(i));
+ if (cu_sp) {
+ if (!CompUnitPasses(*(cu_sp.get())))
+ continue;
+
+ if (searcher.GetDepth() == Searcher::eDepthCompUnit) {
+ SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
+
+ shouldContinue =
+ searcher.SearchCallback(*this, matchingContext, nullptr, false);
+
+ if (shouldContinue == Searcher::eCallbackReturnPop)
+ return Searcher::eCallbackReturnContinue;
+ else if (shouldContinue == Searcher::eCallbackReturnStop)
+ return shouldContinue;
+ } else {
+ // FIXME Descend to block.
}
+ }
}
- else
- {
- if (CompUnitPasses(*context.comp_unit))
- {
- SymbolContext matchingContext (m_target_sp, module_sp, context.comp_unit);
- return searcher.SearchCallback(*this, matchingContext, nullptr, false);
- }
+ } else {
+ if (CompUnitPasses(*context.comp_unit)) {
+ SymbolContext matchingContext(m_target_sp, module_sp, context.comp_unit);
+ return searcher.SearchCallback(*this, matchingContext, nullptr, false);
}
- return Searcher::eCallbackReturnContinue;
+ }
+ return Searcher::eCallbackReturnContinue;
}
-Searcher::CallbackReturn
-SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &context, Searcher &searcher)
-{
- // FIXME: Implement...
- return Searcher::eCallbackReturnContinue;
+Searcher::CallbackReturn SearchFilter::DoFunctionIteration(
+ Function *function, const SymbolContext &context, Searcher &searcher) {
+ // FIXME: Implement...
+ return Searcher::eCallbackReturnContinue;
}
//----------------------------------------------------------------------
// SearchFilterForUnconstrainedSearches:
-// Selects a shared library matching a given file spec, consulting the targets "black list".
+// Selects a shared library matching a given file spec, consulting the targets
+// "black list".
//----------------------------------------------------------------------
+SearchFilterSP SearchFilterForUnconstrainedSearches::CreateFromStructuredData(
+ Target &target, const StructuredData::Dictionary &data_dict, Error &error) {
+ // No options for an unconstrained search.
+ return SearchFilterSP(
+ new SearchFilterForUnconstrainedSearches(target.shared_from_this()));
+}
-bool
-SearchFilterForUnconstrainedSearches::ModulePasses (const FileSpec &module_spec)
-{
- if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches (module_spec))
- return false;
- else
- return true;
+StructuredData::ObjectSP
+SearchFilterForUnconstrainedSearches::SerializeToStructuredData() {
+ // The options dictionary is an empty dictionary:
+ StructuredData::DictionarySP result_sp(new StructuredData::Dictionary());
+ return WrapOptionsDict(result_sp);
}
-bool
-SearchFilterForUnconstrainedSearches::ModulePasses (const lldb::ModuleSP &module_sp)
-{
- if (!module_sp)
- return true;
- else if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches (module_sp))
- return false;
- else
- return true;
+bool SearchFilterForUnconstrainedSearches::ModulePasses(
+ const FileSpec &module_spec) {
+ if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_spec))
+ return false;
+ else
+ return true;
}
-lldb::SearchFilterSP
-SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint (Breakpoint &breakpoint)
-{
- SearchFilterSP ret_sp(new SearchFilterForUnconstrainedSearches(*this));
- return ret_sp;
+bool SearchFilterForUnconstrainedSearches::ModulePasses(
+ const lldb::ModuleSP &module_sp) {
+ if (!module_sp)
+ return true;
+ else if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_sp))
+ return false;
+ else
+ return true;
+}
+
+lldb::SearchFilterSP SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint(
+ Breakpoint &breakpoint) {
+ SearchFilterSP ret_sp(new SearchFilterForUnconstrainedSearches(*this));
+ return ret_sp;
}
//----------------------------------------------------------------------
@@ -294,126 +361,136 @@ SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint (Breakpoint &breakpoin
// Selects a shared library matching a given file spec
//----------------------------------------------------------------------
-SearchFilterByModule::SearchFilterByModule (const lldb::TargetSP &target_sp, const FileSpec &module) :
- SearchFilter (target_sp),
- m_module_spec (module)
-{
-}
+SearchFilterByModule::SearchFilterByModule(const lldb::TargetSP &target_sp,
+ const FileSpec &module)
+ : SearchFilter(target_sp, FilterTy::ByModule), m_module_spec(module) {}
-SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) = default;
+SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule &rhs) =
+ default;
-SearchFilterByModule&
-SearchFilterByModule::operator=(const SearchFilterByModule& rhs)
-{
- m_target_sp = rhs.m_target_sp;
- m_module_spec = rhs.m_module_spec;
- return *this;
+SearchFilterByModule &SearchFilterByModule::
+operator=(const SearchFilterByModule &rhs) {
+ m_target_sp = rhs.m_target_sp;
+ m_module_spec = rhs.m_module_spec;
+ return *this;
}
SearchFilterByModule::~SearchFilterByModule() = default;
-bool
-SearchFilterByModule::ModulePasses (const ModuleSP &module_sp)
-{
- return (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false));
+bool SearchFilterByModule::ModulePasses(const ModuleSP &module_sp) {
+ return (module_sp &&
+ FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false));
}
-bool
-SearchFilterByModule::ModulePasses (const FileSpec &spec)
-{
- // Do a full match only if "spec" has a directory
- const bool full_match = (bool)spec.GetDirectory();
- return FileSpec::Equal(spec, m_module_spec, full_match);
+bool SearchFilterByModule::ModulePasses(const FileSpec &spec) {
+ // Do a full match only if "spec" has a directory
+ const bool full_match = (bool)spec.GetDirectory();
+ return FileSpec::Equal(spec, m_module_spec, full_match);
}
-bool
-SearchFilterByModule::AddressPasses (Address &address)
-{
- // FIXME: Not yet implemented
- return true;
+bool SearchFilterByModule::AddressPasses(Address &address) {
+ // FIXME: Not yet implemented
+ return true;
}
-bool
-SearchFilterByModule::CompUnitPasses (FileSpec &fileSpec)
-{
- return true;
-}
+bool SearchFilterByModule::CompUnitPasses(FileSpec &fileSpec) { return true; }
-bool
-SearchFilterByModule::CompUnitPasses (CompileUnit &compUnit)
-{
- return true;
+bool SearchFilterByModule::CompUnitPasses(CompileUnit &compUnit) {
+ return true;
}
-void
-SearchFilterByModule::Search (Searcher &searcher)
-{
- if (!m_target_sp)
- return;
-
- if (searcher.GetDepth() == Searcher::eDepthTarget)
- {
- SymbolContext empty_sc;
- empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
- }
+void SearchFilterByModule::Search(Searcher &searcher) {
+ if (!m_target_sp)
+ return;
- // If the module file spec is a full path, then we can just find the one
- // filespec that passes. Otherwise, we need to go through all modules and
- // find the ones that match the file name.
-
- const ModuleList &target_modules = m_target_sp->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
-
- const size_t num_modules = target_modules.GetSize ();
- for (size_t i = 0; i < num_modules; i++)
- {
- Module* module = target_modules.GetModulePointerAtIndexUnlocked(i);
- const bool full_match = (bool)m_module_spec.GetDirectory();
- if (FileSpec::Equal (m_module_spec, module->GetFileSpec(), full_match))
- {
- SymbolContext matchingContext(m_target_sp, module->shared_from_this());
- Searcher::CallbackReturn shouldContinue;
-
- shouldContinue = DoModuleIteration(matchingContext, searcher);
- if (shouldContinue == Searcher::eCallbackReturnStop)
- return;
- }
+ if (searcher.GetDepth() == Searcher::eDepthTarget) {
+ SymbolContext empty_sc;
+ empty_sc.target_sp = m_target_sp;
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ }
+
+ // If the module file spec is a full path, then we can just find the one
+ // filespec that passes. Otherwise, we need to go through all modules and
+ // find the ones that match the file name.
+
+ const ModuleList &target_modules = m_target_sp->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+
+ const size_t num_modules = target_modules.GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
+ const bool full_match = (bool)m_module_spec.GetDirectory();
+ if (FileSpec::Equal(m_module_spec, module->GetFileSpec(), full_match)) {
+ SymbolContext matchingContext(m_target_sp, module->shared_from_this());
+ Searcher::CallbackReturn shouldContinue;
+
+ shouldContinue = DoModuleIteration(matchingContext, searcher);
+ if (shouldContinue == Searcher::eCallbackReturnStop)
+ return;
}
+ }
}
-void
-SearchFilterByModule::GetDescription (Stream *s)
-{
- s->PutCString(", module = ");
- if (s->GetVerbose())
- {
- char buffer[2048];
- m_module_spec.GetPath(buffer, 2047);
- s->PutCString(buffer);
- }
- else
- {
- s->PutCString(m_module_spec.GetFilename().AsCString("<Unknown>"));
- }
+void SearchFilterByModule::GetDescription(Stream *s) {
+ s->PutCString(", module = ");
+ if (s->GetVerbose()) {
+ char buffer[2048];
+ m_module_spec.GetPath(buffer, 2047);
+ s->PutCString(buffer);
+ } else {
+ s->PutCString(m_module_spec.GetFilename().AsCString("<Unknown>"));
+ }
}
-uint32_t
-SearchFilterByModule::GetFilterRequiredItems()
-{
- return eSymbolContextModule;
+uint32_t SearchFilterByModule::GetFilterRequiredItems() {
+ return eSymbolContextModule;
}
-void
-SearchFilterByModule::Dump (Stream *s) const
-{
-}
+void SearchFilterByModule::Dump(Stream *s) const {}
lldb::SearchFilterSP
-SearchFilterByModule::DoCopyForBreakpoint (Breakpoint &breakpoint)
-{
- SearchFilterSP ret_sp(new SearchFilterByModule(*this));
- return ret_sp;
+SearchFilterByModule::DoCopyForBreakpoint(Breakpoint &breakpoint) {
+ SearchFilterSP ret_sp(new SearchFilterByModule(*this));
+ return ret_sp;
+}
+
+SearchFilterSP SearchFilterByModule::CreateFromStructuredData(
+ Target &target, const StructuredData::Dictionary &data_dict, Error &error) {
+ StructuredData::Array *modules_array;
+ bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
+ modules_array);
+ if (!success) {
+ error.SetErrorString("SFBM::CFSD: Could not find the module list key.");
+ return nullptr;
+ }
+
+ size_t num_modules = modules_array->GetSize();
+ if (num_modules > 1) {
+ error.SetErrorString(
+ "SFBM::CFSD: Only one modules allowed for SearchFilterByModule.");
+ return nullptr;
+ }
+
+ std::string module;
+ success = modules_array->GetItemAtIndexAsString(0, module);
+ if (!success) {
+ error.SetErrorString("SFBM::CFSD: filter module item not a string.");
+ return nullptr;
+ }
+ FileSpec module_spec(module, false);
+
+ return SearchFilterSP(
+ new SearchFilterByModule(target.shared_from_this(), module_spec));
+}
+
+StructuredData::ObjectSP SearchFilterByModule::SerializeToStructuredData() {
+ StructuredData::DictionarySP options_dict_sp(
+ new StructuredData::Dictionary());
+ StructuredData::ArraySP module_array_sp(new StructuredData::Array());
+ module_array_sp->AddItem(StructuredData::StringSP(
+ new StructuredData::String(m_module_spec.GetPath())));
+ options_dict_sp->AddItem(GetKey(OptionNames::ModList), module_array_sp);
+ return WrapOptionsDict(options_dict_sp);
}
//----------------------------------------------------------------------
@@ -421,160 +498,173 @@ SearchFilterByModule::DoCopyForBreakpoint (Breakpoint &breakpoint)
// Selects a shared library matching a given file spec
//----------------------------------------------------------------------
-SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp,
- const FileSpecList &module_list) :
- SearchFilter (target_sp),
- m_module_spec_list (module_list)
-{
-}
+SearchFilterByModuleList::SearchFilterByModuleList(
+ const lldb::TargetSP &target_sp, const FileSpecList &module_list)
+ : SearchFilter(target_sp, FilterTy::ByModules),
+ m_module_spec_list(module_list) {}
-SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) = default;
+SearchFilterByModuleList::SearchFilterByModuleList(
+ const lldb::TargetSP &target_sp, const FileSpecList &module_list,
+ enum FilterTy filter_ty)
+ : SearchFilter(target_sp, filter_ty), m_module_spec_list(module_list) {}
-SearchFilterByModuleList&
-SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs)
-{
- m_target_sp = rhs.m_target_sp;
- m_module_spec_list = rhs.m_module_spec_list;
- return *this;
+SearchFilterByModuleList::SearchFilterByModuleList(
+ const SearchFilterByModuleList &rhs) = default;
+
+SearchFilterByModuleList &SearchFilterByModuleList::
+operator=(const SearchFilterByModuleList &rhs) {
+ m_target_sp = rhs.m_target_sp;
+ m_module_spec_list = rhs.m_module_spec_list;
+ return *this;
}
SearchFilterByModuleList::~SearchFilterByModuleList() = default;
-bool
-SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
-{
- if (m_module_spec_list.GetSize() == 0)
- return true;
-
- if (module_sp &&
- m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
- return true;
- else
- return false;
-}
-
-bool
-SearchFilterByModuleList::ModulePasses (const FileSpec &spec)
-{
- if (m_module_spec_list.GetSize() == 0)
- return true;
-
- if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX)
- return true;
- else
- return false;
-}
-
-bool
-SearchFilterByModuleList::AddressPasses (Address &address)
-{
- // FIXME: Not yet implemented
+bool SearchFilterByModuleList::ModulePasses(const ModuleSP &module_sp) {
+ if (m_module_spec_list.GetSize() == 0)
return true;
-}
-bool
-SearchFilterByModuleList::CompUnitPasses (FileSpec &fileSpec)
-{
+ if (module_sp &&
+ m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) !=
+ UINT32_MAX)
return true;
+ else
+ return false;
}
-bool
-SearchFilterByModuleList::CompUnitPasses (CompileUnit &compUnit)
-{
+bool SearchFilterByModuleList::ModulePasses(const FileSpec &spec) {
+ if (m_module_spec_list.GetSize() == 0)
return true;
-}
-void
-SearchFilterByModuleList::Search (Searcher &searcher)
-{
- if (!m_target_sp)
- return;
+ if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX)
+ return true;
+ else
+ return false;
+}
- if (searcher.GetDepth() == Searcher::eDepthTarget)
- {
- SymbolContext empty_sc;
- empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
- }
+bool SearchFilterByModuleList::AddressPasses(Address &address) {
+ // FIXME: Not yet implemented
+ return true;
+}
- // If the module file spec is a full path, then we can just find the one
- // filespec that passes. Otherwise, we need to go through all modules and
- // find the ones that match the file name.
+bool SearchFilterByModuleList::CompUnitPasses(FileSpec &fileSpec) {
+ return true;
+}
- const ModuleList &target_modules = m_target_sp->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+bool SearchFilterByModuleList::CompUnitPasses(CompileUnit &compUnit) {
+ return true;
+}
- const size_t num_modules = target_modules.GetSize ();
- for (size_t i = 0; i < num_modules; i++)
- {
- Module* module = target_modules.GetModulePointerAtIndexUnlocked(i);
- if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) != UINT32_MAX)
- {
- SymbolContext matchingContext(m_target_sp, module->shared_from_this());
- Searcher::CallbackReturn shouldContinue;
+void SearchFilterByModuleList::Search(Searcher &searcher) {
+ if (!m_target_sp)
+ return;
- shouldContinue = DoModuleIteration(matchingContext, searcher);
- if (shouldContinue == Searcher::eCallbackReturnStop)
- return;
- }
+ if (searcher.GetDepth() == Searcher::eDepthTarget) {
+ SymbolContext empty_sc;
+ empty_sc.target_sp = m_target_sp;
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ }
+
+ // If the module file spec is a full path, then we can just find the one
+ // filespec that passes. Otherwise, we need to go through all modules and
+ // find the ones that match the file name.
+
+ const ModuleList &target_modules = m_target_sp->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
+
+ const size_t num_modules = target_modules.GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ Module *module = target_modules.GetModulePointerAtIndexUnlocked(i);
+ if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) !=
+ UINT32_MAX) {
+ SymbolContext matchingContext(m_target_sp, module->shared_from_this());
+ Searcher::CallbackReturn shouldContinue;
+
+ shouldContinue = DoModuleIteration(matchingContext, searcher);
+ if (shouldContinue == Searcher::eCallbackReturnStop)
+ return;
}
-}
-
-void
-SearchFilterByModuleList::GetDescription (Stream *s)
-{
- size_t num_modules = m_module_spec_list.GetSize();
- if (num_modules == 1)
- {
- s->Printf (", module = ");
- if (s->GetVerbose())
- {
- char buffer[2048];
- m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
- s->PutCString(buffer);
- }
- else
- {
- s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<Unknown>"));
- }
+ }
+}
+
+void SearchFilterByModuleList::GetDescription(Stream *s) {
+ size_t num_modules = m_module_spec_list.GetSize();
+ if (num_modules == 1) {
+ s->Printf(", module = ");
+ if (s->GetVerbose()) {
+ char buffer[2048];
+ m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
+ s->PutCString(buffer);
+ } else {
+ s->PutCString(
+ m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString(
+ "<Unknown>"));
}
- else
- {
- s->Printf(", modules(%" PRIu64 ") = ", (uint64_t)num_modules);
- for (size_t i = 0; i < num_modules; i++)
- {
- if (s->GetVerbose())
- {
- char buffer[2048];
- m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
- s->PutCString(buffer);
- }
- else
- {
- s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<Unknown>"));
- }
- if (i != num_modules - 1)
- s->PutCString (", ");
- }
+ } else {
+ s->Printf(", modules(%" PRIu64 ") = ", (uint64_t)num_modules);
+ for (size_t i = 0; i < num_modules; i++) {
+ if (s->GetVerbose()) {
+ char buffer[2048];
+ m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
+ s->PutCString(buffer);
+ } else {
+ s->PutCString(
+ m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString(
+ "<Unknown>"));
+ }
+ if (i != num_modules - 1)
+ s->PutCString(", ");
}
+ }
}
-uint32_t
-SearchFilterByModuleList::GetFilterRequiredItems()
-{
- return eSymbolContextModule;
+uint32_t SearchFilterByModuleList::GetFilterRequiredItems() {
+ return eSymbolContextModule;
}
-void
-SearchFilterByModuleList::Dump (Stream *s) const
-{
-}
+void SearchFilterByModuleList::Dump(Stream *s) const {}
lldb::SearchFilterSP
-SearchFilterByModuleList::DoCopyForBreakpoint (Breakpoint &breakpoint)
-{
- SearchFilterSP ret_sp(new SearchFilterByModuleList(*this));
- return ret_sp;
+SearchFilterByModuleList::DoCopyForBreakpoint(Breakpoint &breakpoint) {
+ SearchFilterSP ret_sp(new SearchFilterByModuleList(*this));
+ return ret_sp;
+}
+
+SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData(
+ Target &target, const StructuredData::Dictionary &data_dict, Error &error) {
+ StructuredData::Array *modules_array;
+ bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
+ modules_array);
+ FileSpecList modules;
+ if (success) {
+ size_t num_modules = modules_array->GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ std::string module;
+ success = modules_array->GetItemAtIndexAsString(i, module);
+ if (!success) {
+ error.SetErrorStringWithFormat(
+ "SFBM::CFSD: filter module item %zu not a string.", i);
+ return nullptr;
+ }
+ modules.Append(FileSpec(module, false));
+ }
+ }
+
+ return SearchFilterSP(
+ new SearchFilterByModuleList(target.shared_from_this(), modules));
+}
+
+void SearchFilterByModuleList::SerializeUnwrapped(
+ StructuredData::DictionarySP &options_dict_sp) {
+ SerializeFileSpecList(options_dict_sp, OptionNames::ModList,
+ m_module_spec_list);
+}
+
+StructuredData::ObjectSP SearchFilterByModuleList::SerializeToStructuredData() {
+ StructuredData::DictionarySP options_dict_sp(
+ new StructuredData::Dictionary());
+ SerializeUnwrapped(options_dict_sp);
+ return WrapOptionsDict(options_dict_sp);
}
//----------------------------------------------------------------------
@@ -582,174 +672,196 @@ SearchFilterByModuleList::DoCopyForBreakpoint (Breakpoint &breakpoint)
// Selects a shared library matching a given file spec
//----------------------------------------------------------------------
-SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU (const lldb::TargetSP &target_sp,
- const FileSpecList &module_list,
- const FileSpecList &cu_list) :
- SearchFilterByModuleList (target_sp, module_list),
- m_cu_spec_list (cu_list)
-{
-}
+SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(
+ const lldb::TargetSP &target_sp, const FileSpecList &module_list,
+ const FileSpecList &cu_list)
+ : SearchFilterByModuleList(target_sp, module_list,
+ FilterTy::ByModulesAndCU),
+ m_cu_spec_list(cu_list) {}
-SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU& rhs) = default;
+SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(
+ const SearchFilterByModuleListAndCU &rhs) = default;
-SearchFilterByModuleListAndCU&
-SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rhs)
-{
- if (&rhs != this)
- {
- m_target_sp = rhs.m_target_sp;
- m_module_spec_list = rhs.m_module_spec_list;
- m_cu_spec_list = rhs.m_cu_spec_list;
- }
- return *this;
+SearchFilterByModuleListAndCU &SearchFilterByModuleListAndCU::
+operator=(const SearchFilterByModuleListAndCU &rhs) {
+ if (&rhs != this) {
+ m_target_sp = rhs.m_target_sp;
+ m_module_spec_list = rhs.m_module_spec_list;
+ m_cu_spec_list = rhs.m_cu_spec_list;
+ }
+ return *this;
}
SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU() = default;
-bool
-SearchFilterByModuleListAndCU::AddressPasses (Address &address)
-{
- return true;
+lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData(
+ Target &target, const StructuredData::Dictionary &data_dict, Error &error) {
+ StructuredData::Array *modules_array = nullptr;
+ SearchFilterSP result_sp;
+ bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList),
+ modules_array);
+ FileSpecList modules;
+ if (success) {
+ size_t num_modules = modules_array->GetSize();
+ for (size_t i = 0; i < num_modules; i++) {
+ std::string module;
+ success = modules_array->GetItemAtIndexAsString(i, module);
+ if (!success) {
+ error.SetErrorStringWithFormat(
+ "SFBM::CFSD: filter module item %zu not a string.", i);
+ return result_sp;
+ }
+ modules.Append(FileSpec(module, false));
+ }
+ }
+
+ StructuredData::Array *cus_array = nullptr;
+ success =
+ data_dict.GetValueForKeyAsArray(GetKey(OptionNames::CUList), cus_array);
+ if (!success) {
+ error.SetErrorString("SFBM::CFSD: Could not find the CU list key.");
+ return result_sp;
+ }
+
+ size_t num_cus = cus_array->GetSize();
+ FileSpecList cus;
+ for (size_t i = 0; i < num_cus; i++) {
+ std::string cu;
+ success = cus_array->GetItemAtIndexAsString(i, cu);
+ if (!success) {
+ error.SetErrorStringWithFormat(
+ "SFBM::CFSD: filter cu item %zu not a string.", i);
+ return nullptr;
+ }
+ cus.Append(FileSpec(cu, false));
+ }
+
+ return SearchFilterSP(new SearchFilterByModuleListAndCU(
+ target.shared_from_this(), modules, cus));
}
-bool
-SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec)
-{
- return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
+StructuredData::ObjectSP
+SearchFilterByModuleListAndCU::SerializeToStructuredData() {
+ StructuredData::DictionarySP options_dict_sp(
+ new StructuredData::Dictionary());
+ SearchFilterByModuleList::SerializeUnwrapped(options_dict_sp);
+ SerializeFileSpecList(options_dict_sp, OptionNames::CUList, m_cu_spec_list);
+ return WrapOptionsDict(options_dict_sp);
}
-bool
-SearchFilterByModuleListAndCU::CompUnitPasses (CompileUnit &compUnit)
-{
- bool in_cu_list = m_cu_spec_list.FindFileIndex(0, compUnit, false) != UINT32_MAX;
- if (in_cu_list)
- {
- ModuleSP module_sp(compUnit.GetModule());
- if (module_sp)
- {
- bool module_passes = SearchFilterByModuleList::ModulePasses(module_sp);
- return module_passes;
- }
- else
- return true;
- }
- else
- return false;
+bool SearchFilterByModuleListAndCU::AddressPasses(Address &address) {
+ return true;
}
-void
-SearchFilterByModuleListAndCU::Search (Searcher &searcher)
-{
- if (!m_target_sp)
- return;
+bool SearchFilterByModuleListAndCU::CompUnitPasses(FileSpec &fileSpec) {
+ return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
+}
- if (searcher.GetDepth() == Searcher::eDepthTarget)
- {
- SymbolContext empty_sc;
- empty_sc.target_sp = m_target_sp;
- searcher.SearchCallback(*this, empty_sc, nullptr, false);
- }
+bool SearchFilterByModuleListAndCU::CompUnitPasses(CompileUnit &compUnit) {
+ bool in_cu_list =
+ m_cu_spec_list.FindFileIndex(0, compUnit, false) != UINT32_MAX;
+ if (in_cu_list) {
+ ModuleSP module_sp(compUnit.GetModule());
+ if (module_sp) {
+ bool module_passes = SearchFilterByModuleList::ModulePasses(module_sp);
+ return module_passes;
+ } else
+ return true;
+ } else
+ return false;
+}
- // If the module file spec is a full path, then we can just find the one
- // filespec that passes. Otherwise, we need to go through all modules and
- // find the ones that match the file name.
-
- ModuleList matching_modules;
- const ModuleList &target_images = m_target_sp->GetImages();
- std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
-
- const size_t num_modules = target_images.GetSize ();
- bool no_modules_in_filter = m_module_spec_list.GetSize() == 0;
- for (size_t i = 0; i < num_modules; i++)
- {
- lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i);
- if (no_modules_in_filter ||
- m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
- {
- SymbolContext matchingContext(m_target_sp, module_sp);
- Searcher::CallbackReturn shouldContinue;
-
- if (searcher.GetDepth() == Searcher::eDepthModule)
- {
- shouldContinue = DoModuleIteration(matchingContext, searcher);
- if (shouldContinue == Searcher::eCallbackReturnStop)
- return;
- }
- else
- {
- const size_t num_cu = module_sp->GetNumCompileUnits();
- for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++)
- {
- CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx);
- matchingContext.comp_unit = cu_sp.get();
- if (matchingContext.comp_unit)
- {
- if (m_cu_spec_list.FindFileIndex(0, *matchingContext.comp_unit, false) != UINT32_MAX)
- {
- shouldContinue = DoCUIteration(module_sp, matchingContext, searcher);
- if (shouldContinue == Searcher::eCallbackReturnStop)
- return;
- }
- }
- }
+void SearchFilterByModuleListAndCU::Search(Searcher &searcher) {
+ if (!m_target_sp)
+ return;
+
+ if (searcher.GetDepth() == Searcher::eDepthTarget) {
+ SymbolContext empty_sc;
+ empty_sc.target_sp = m_target_sp;
+ searcher.SearchCallback(*this, empty_sc, nullptr, false);
+ }
+
+ // If the module file spec is a full path, then we can just find the one
+ // filespec that passes. Otherwise, we need to go through all modules and
+ // find the ones that match the file name.
+
+ ModuleList matching_modules;
+ const ModuleList &target_images = m_target_sp->GetImages();
+ std::lock_guard<std::recursive_mutex> guard(target_images.GetMutex());
+
+ const size_t num_modules = target_images.GetSize();
+ bool no_modules_in_filter = m_module_spec_list.GetSize() == 0;
+ for (size_t i = 0; i < num_modules; i++) {
+ lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i);
+ if (no_modules_in_filter ||
+ m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) !=
+ UINT32_MAX) {
+ SymbolContext matchingContext(m_target_sp, module_sp);
+ Searcher::CallbackReturn shouldContinue;
+
+ if (searcher.GetDepth() == Searcher::eDepthModule) {
+ shouldContinue = DoModuleIteration(matchingContext, searcher);
+ if (shouldContinue == Searcher::eCallbackReturnStop)
+ return;
+ } else {
+ const size_t num_cu = module_sp->GetNumCompileUnits();
+ for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++) {
+ CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx);
+ matchingContext.comp_unit = cu_sp.get();
+ if (matchingContext.comp_unit) {
+ if (m_cu_spec_list.FindFileIndex(0, *matchingContext.comp_unit,
+ false) != UINT32_MAX) {
+ shouldContinue =
+ DoCUIteration(module_sp, matchingContext, searcher);
+ if (shouldContinue == Searcher::eCallbackReturnStop)
+ return;
}
+ }
}
+ }
}
-}
-
-void
-SearchFilterByModuleListAndCU::GetDescription (Stream *s)
-{
- size_t num_modules = m_module_spec_list.GetSize();
- if (num_modules == 1)
- {
- s->Printf (", module = ");
- if (s->GetVerbose())
- {
- char buffer[2048];
- m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
- s->PutCString(buffer);
- }
- else
- {
- s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<Unknown>"));
- }
+ }
+}
+
+void SearchFilterByModuleListAndCU::GetDescription(Stream *s) {
+ size_t num_modules = m_module_spec_list.GetSize();
+ if (num_modules == 1) {
+ s->Printf(", module = ");
+ if (s->GetVerbose()) {
+ char buffer[2048];
+ m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
+ s->PutCString(buffer);
+ } else {
+ s->PutCString(
+ m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString(
+ "<Unknown>"));
}
- else if (num_modules > 0)
- {
- s->Printf (", modules(%" PRIu64 ") = ", static_cast<uint64_t>(num_modules));
- for (size_t i = 0; i < num_modules; i++)
- {
- if (s->GetVerbose())
- {
- char buffer[2048];
- m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
- s->PutCString(buffer);
- }
- else
- {
- s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<Unknown>"));
- }
- if (i != num_modules - 1)
- s->PutCString (", ");
- }
+ } else if (num_modules > 0) {
+ s->Printf(", modules(%" PRIu64 ") = ", static_cast<uint64_t>(num_modules));
+ for (size_t i = 0; i < num_modules; i++) {
+ if (s->GetVerbose()) {
+ char buffer[2048];
+ m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
+ s->PutCString(buffer);
+ } else {
+ s->PutCString(
+ m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString(
+ "<Unknown>"));
+ }
+ if (i != num_modules - 1)
+ s->PutCString(", ");
}
+ }
}
-uint32_t
-SearchFilterByModuleListAndCU::GetFilterRequiredItems()
-{
- return eSymbolContextModule | eSymbolContextCompUnit;
+uint32_t SearchFilterByModuleListAndCU::GetFilterRequiredItems() {
+ return eSymbolContextModule | eSymbolContextCompUnit;
}
-void
-SearchFilterByModuleListAndCU::Dump (Stream *s) const
-{
-}
+void SearchFilterByModuleListAndCU::Dump(Stream *s) const {}
lldb::SearchFilterSP
-SearchFilterByModuleListAndCU::DoCopyForBreakpoint (Breakpoint &breakpoint)
-{
- SearchFilterSP ret_sp(new SearchFilterByModuleListAndCU(*this));
- return ret_sp;
+SearchFilterByModuleListAndCU::DoCopyForBreakpoint(Breakpoint &breakpoint) {
+ SearchFilterSP ret_sp(new SearchFilterByModuleListAndCU(*this));
+ return ret_sp;
}
diff --git a/source/Core/Section.cpp b/source/Core/Section.cpp
index 9622cb78970c..95bcdada5377 100644
--- a/source/Core/Section.cpp
+++ b/source/Core/Section.cpp
@@ -17,600 +17,491 @@
using namespace lldb;
using namespace lldb_private;
-Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file, user_id_t sect_id, const ConstString &name,
- SectionType sect_type, addr_t file_addr, addr_t byte_size, lldb::offset_t file_offset,
- lldb::offset_t file_size, uint32_t log2align, uint32_t flags, uint32_t target_byte_size /*=1*/)
- : ModuleChild(module_sp),
- UserID(sect_id),
- Flags(flags),
- m_obj_file(obj_file),
- m_type(sect_type),
- m_parent_wp(),
- m_name(name),
- m_file_addr(file_addr),
- m_byte_size(byte_size),
- m_file_offset(file_offset),
- m_file_size(file_size),
- m_log2align(log2align),
- m_children(),
- m_fake(false),
- m_encrypted(false),
- m_thread_specific(false),
- m_readable(false),
- m_writable(false),
- m_executable(false),
- m_target_byte_size(target_byte_size)
-{
-// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
-// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
-}
-
-Section::Section(const lldb::SectionSP &parent_section_sp, const ModuleSP &module_sp, ObjectFile *obj_file,
- user_id_t sect_id, const ConstString &name, SectionType sect_type, addr_t file_addr, addr_t byte_size,
- lldb::offset_t file_offset, lldb::offset_t file_size, uint32_t log2align, uint32_t flags,
+Section::Section(const ModuleSP &module_sp, ObjectFile *obj_file,
+ user_id_t sect_id, const ConstString &name,
+ SectionType sect_type, addr_t file_addr, addr_t byte_size,
+ lldb::offset_t file_offset, lldb::offset_t file_size,
+ uint32_t log2align, uint32_t flags,
uint32_t target_byte_size /*=1*/)
- : ModuleChild(module_sp),
- UserID(sect_id),
- Flags(flags),
- m_obj_file(obj_file),
- m_type(sect_type),
- m_parent_wp(),
- m_name(name),
- m_file_addr(file_addr),
- m_byte_size(byte_size),
- m_file_offset(file_offset),
- m_file_size(file_size),
- m_log2align(log2align),
- m_children(),
- m_fake(false),
- m_encrypted(false),
- m_thread_specific(false),
- m_readable(false),
- m_writable(false),
- m_executable(false),
- m_target_byte_size(target_byte_size)
-{
-// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
-// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
- if (parent_section_sp)
- m_parent_wp = parent_section_sp;
-}
-
-Section::~Section()
-{
-// printf ("Section::~Section(%p)\n", this);
-}
-
-addr_t
-Section::GetFileAddress () const
-{
- SectionSP parent_sp (GetParent ());
- if (parent_sp)
- {
- // This section has a parent which means m_file_addr is an offset into
- // the parent section, so the file address for this section is the file
- // address of the parent plus the offset
- return parent_sp->GetFileAddress() + m_file_addr;
- }
+ : ModuleChild(module_sp), UserID(sect_id), Flags(flags),
+ m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
+ m_file_addr(file_addr), m_byte_size(byte_size),
+ m_file_offset(file_offset), m_file_size(file_size),
+ m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
+ m_thread_specific(false), m_readable(false), m_writable(false),
+ m_executable(false), m_target_byte_size(target_byte_size) {
+ // printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ",
+ // addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 "
+ // - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
+ // this, module_sp.get(), sect_id, file_addr, file_addr +
+ // byte_size, file_offset, file_offset + file_size, flags,
+ // name.GetCString());
+}
+
+Section::Section(const lldb::SectionSP &parent_section_sp,
+ const ModuleSP &module_sp, ObjectFile *obj_file,
+ user_id_t sect_id, const ConstString &name,
+ SectionType sect_type, addr_t file_addr, addr_t byte_size,
+ lldb::offset_t file_offset, lldb::offset_t file_size,
+ uint32_t log2align, uint32_t flags,
+ uint32_t target_byte_size /*=1*/)
+ : ModuleChild(module_sp), UserID(sect_id), Flags(flags),
+ m_obj_file(obj_file), m_type(sect_type), m_parent_wp(), m_name(name),
+ m_file_addr(file_addr), m_byte_size(byte_size),
+ m_file_offset(file_offset), m_file_size(file_size),
+ m_log2align(log2align), m_children(), m_fake(false), m_encrypted(false),
+ m_thread_specific(false), m_readable(false), m_writable(false),
+ m_executable(false), m_target_byte_size(target_byte_size) {
+ // printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ",
+ // addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 "
+ // - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
+ // this, module_sp.get(), sect_id, file_addr, file_addr +
+ // byte_size, file_offset, file_offset + file_size, flags,
+ // parent_section_sp->GetName().GetCString(), name.GetCString());
+ if (parent_section_sp)
+ m_parent_wp = parent_section_sp;
+}
+
+Section::~Section() {
+ // printf ("Section::~Section(%p)\n", this);
+}
+
+addr_t Section::GetFileAddress() const {
+ SectionSP parent_sp(GetParent());
+ if (parent_sp) {
+ // This section has a parent which means m_file_addr is an offset into
+ // the parent section, so the file address for this section is the file
+ // address of the parent plus the offset
+ return parent_sp->GetFileAddress() + m_file_addr;
+ }
+ // This section has no parent, so m_file_addr is the file base address
+ return m_file_addr;
+}
+
+bool Section::SetFileAddress(lldb::addr_t file_addr) {
+ SectionSP parent_sp(GetParent());
+ if (parent_sp) {
+ if (m_file_addr >= file_addr)
+ return parent_sp->SetFileAddress(m_file_addr - file_addr);
+ return false;
+ } else {
// This section has no parent, so m_file_addr is the file base address
- return m_file_addr;
-}
-
-bool
-Section::SetFileAddress (lldb::addr_t file_addr)
-{
- SectionSP parent_sp (GetParent ());
- if (parent_sp)
- {
- if (m_file_addr >= file_addr)
- return parent_sp->SetFileAddress (m_file_addr - file_addr);
- return false;
- }
- else
- {
- // This section has no parent, so m_file_addr is the file base address
- m_file_addr = file_addr;
- return true;
- }
+ m_file_addr = file_addr;
+ return true;
+ }
}
-lldb::addr_t
-Section::GetOffset () const
-{
- // This section has a parent which means m_file_addr is an offset.
- SectionSP parent_sp (GetParent ());
- if (parent_sp)
- return m_file_addr;
-
- // This section has no parent, so there is no offset to be had
- return 0;
-}
+lldb::addr_t Section::GetOffset() const {
+ // This section has a parent which means m_file_addr is an offset.
+ SectionSP parent_sp(GetParent());
+ if (parent_sp)
+ return m_file_addr;
-addr_t
-Section::GetLoadBaseAddress (Target *target) const
-{
- addr_t load_base_addr = LLDB_INVALID_ADDRESS;
- SectionSP parent_sp (GetParent ());
- if (parent_sp)
- {
- load_base_addr = parent_sp->GetLoadBaseAddress (target);
- if (load_base_addr != LLDB_INVALID_ADDRESS)
- load_base_addr += GetOffset();
- }
- if (load_base_addr == LLDB_INVALID_ADDRESS)
- {
- load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
+ // This section has no parent, so there is no offset to be had
+ return 0;
+}
+
+addr_t Section::GetLoadBaseAddress(Target *target) const {
+ addr_t load_base_addr = LLDB_INVALID_ADDRESS;
+ SectionSP parent_sp(GetParent());
+ if (parent_sp) {
+ load_base_addr = parent_sp->GetLoadBaseAddress(target);
+ if (load_base_addr != LLDB_INVALID_ADDRESS)
+ load_base_addr += GetOffset();
+ }
+ if (load_base_addr == LLDB_INVALID_ADDRESS) {
+ load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress(
+ const_cast<Section *>(this)->shared_from_this());
+ }
+ return load_base_addr;
+}
+
+bool Section::ResolveContainedAddress(addr_t offset, Address &so_addr) const {
+ const size_t num_children = m_children.GetSize();
+ if (num_children > 0) {
+ for (size_t i = 0; i < num_children; i++) {
+ Section *child_section = m_children.GetSectionAtIndex(i).get();
+
+ addr_t child_offset = child_section->GetOffset();
+ if (child_offset <= offset &&
+ offset - child_offset < child_section->GetByteSize())
+ return child_section->ResolveContainedAddress(offset - child_offset,
+ so_addr);
}
- return load_base_addr;
-}
-
-bool
-Section::ResolveContainedAddress (addr_t offset, Address &so_addr) const
-{
- const size_t num_children = m_children.GetSize();
- if (num_children > 0)
- {
- for (size_t i=0; i<num_children; i++)
- {
- Section* child_section = m_children.GetSectionAtIndex (i).get();
-
- addr_t child_offset = child_section->GetOffset();
- if (child_offset <= offset && offset - child_offset < child_section->GetByteSize())
- return child_section->ResolveContainedAddress (offset - child_offset, so_addr);
- }
- }
- so_addr.SetOffset(offset);
- so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
-
+ }
+ so_addr.SetOffset(offset);
+ so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
+
#ifdef LLDB_CONFIGURATION_DEBUG
- // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
- assert(GetModule().get());
+ // For debug builds, ensure that there are no orphaned (i.e., moduleless)
+ // sections.
+ assert(GetModule().get());
#endif
- return true;
+ return true;
}
-bool
-Section::ContainsFileAddress (addr_t vm_addr) const
-{
- const addr_t file_addr = GetFileAddress();
- if (file_addr != LLDB_INVALID_ADDRESS)
- {
- if (file_addr <= vm_addr)
- {
- const addr_t offset = (vm_addr - file_addr) * m_target_byte_size;
- return offset < GetByteSize();
- }
+bool Section::ContainsFileAddress(addr_t vm_addr) const {
+ const addr_t file_addr = GetFileAddress();
+ if (file_addr != LLDB_INVALID_ADDRESS) {
+ if (file_addr <= vm_addr) {
+ const addr_t offset = (vm_addr - file_addr) * m_target_byte_size;
+ return offset < GetByteSize();
}
- return false;
+ }
+ return false;
}
-int
-Section::Compare (const Section& a, const Section& b)
-{
- if (&a == &b)
- return 0;
-
- const ModuleSP a_module_sp = a.GetModule();
- const ModuleSP b_module_sp = b.GetModule();
- if (a_module_sp == b_module_sp)
- {
- user_id_t a_sect_uid = a.GetID();
- user_id_t b_sect_uid = b.GetID();
- if (a_sect_uid < b_sect_uid)
- return -1;
- if (a_sect_uid > b_sect_uid)
- return 1;
- return 0;
- }
- else
- {
- // The modules are different, just compare the module pointers
- if (a_module_sp.get() < b_module_sp.get())
- return -1;
- else
- return 1; // We already know the modules aren't equal
- }
-}
-
-
-void
-Section::Dump (Stream *s, Target *target, uint32_t depth) const
-{
-// s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
- s->Indent();
- s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(), GetSectionTypeAsCString (m_type));
- bool resolved = true;
- addr_t addr = LLDB_INVALID_ADDRESS;
+int Section::Compare(const Section &a, const Section &b) {
+ if (&a == &b)
+ return 0;
- if (GetByteSize() == 0)
- s->Printf("%39s", "");
+ const ModuleSP a_module_sp = a.GetModule();
+ const ModuleSP b_module_sp = b.GetModule();
+ if (a_module_sp == b_module_sp) {
+ user_id_t a_sect_uid = a.GetID();
+ user_id_t b_sect_uid = b.GetID();
+ if (a_sect_uid < b_sect_uid)
+ return -1;
+ if (a_sect_uid > b_sect_uid)
+ return 1;
+ return 0;
+ } else {
+ // The modules are different, just compare the module pointers
+ if (a_module_sp.get() < b_module_sp.get())
+ return -1;
else
- {
- if (target)
- addr = GetLoadBaseAddress (target);
-
- if (addr == LLDB_INVALID_ADDRESS)
- {
- if (target)
- resolved = false;
- addr = GetFileAddress();
- }
-
- VMRange range(addr, addr + m_byte_size);
- range.Dump (s, 0);
+ return 1; // We already know the modules aren't equal
+ }
+}
+
+void Section::Dump(Stream *s, Target *target, uint32_t depth) const {
+ // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
+ s->Indent();
+ s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(),
+ GetSectionTypeAsCString(m_type));
+ bool resolved = true;
+ addr_t addr = LLDB_INVALID_ADDRESS;
+
+ if (GetByteSize() == 0)
+ s->Printf("%39s", "");
+ else {
+ if (target)
+ addr = GetLoadBaseAddress(target);
+
+ if (addr == LLDB_INVALID_ADDRESS) {
+ if (target)
+ resolved = false;
+ addr = GetFileAddress();
}
- s->Printf("%c %c%c%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", resolved ? ' ' : '*', m_readable ? 'r' : '-',
- m_writable ? 'w' : '-', m_executable ? 'x' : '-', m_file_offset, m_file_size, Get());
+ VMRange range(addr, addr + m_byte_size);
+ range.Dump(s, 0);
+ }
+
+ s->Printf("%c %c%c%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ",
+ resolved ? ' ' : '*', m_readable ? 'r' : '-',
+ m_writable ? 'w' : '-', m_executable ? 'x' : '-', m_file_offset,
+ m_file_size, Get());
- DumpName (s);
+ DumpName(s);
- s->EOL();
+ s->EOL();
- if (depth > 0)
- m_children.Dump(s, target, false, depth - 1);
+ if (depth > 0)
+ m_children.Dump(s, target, false, depth - 1);
}
-void
-Section::DumpName (Stream *s) const
-{
- SectionSP parent_sp (GetParent ());
- if (parent_sp)
- {
- parent_sp->DumpName (s);
- s->PutChar('.');
- }
- else
- {
- // The top most section prints the module basename
- const char * name = NULL;
- ModuleSP module_sp (GetModule());
- const FileSpec &file_spec = m_obj_file->GetFileSpec();
-
- if (m_obj_file)
- name = file_spec.GetFilename().AsCString();
- if ((!name || !name[0]) && module_sp)
- name = module_sp->GetFileSpec().GetFilename().AsCString();
- if (name && name[0])
- s->Printf("%s.", name);
- }
- m_name.Dump(s);
+void Section::DumpName(Stream *s) const {
+ SectionSP parent_sp(GetParent());
+ if (parent_sp) {
+ parent_sp->DumpName(s);
+ s->PutChar('.');
+ } else {
+ // The top most section prints the module basename
+ const char *name = NULL;
+ ModuleSP module_sp(GetModule());
+ const FileSpec &file_spec = m_obj_file->GetFileSpec();
+
+ if (m_obj_file)
+ name = file_spec.GetFilename().AsCString();
+ if ((!name || !name[0]) && module_sp)
+ name = module_sp->GetFileSpec().GetFilename().AsCString();
+ if (name && name[0])
+ s->Printf("%s.", name);
+ }
+ m_name.Dump(s);
}
-bool
-Section::IsDescendant (const Section *section)
-{
- if (this == section)
- return true;
- SectionSP parent_sp (GetParent ());
- if (parent_sp)
- return parent_sp->IsDescendant (section);
- return false;
+bool Section::IsDescendant(const Section *section) {
+ if (this == section)
+ return true;
+ SectionSP parent_sp(GetParent());
+ if (parent_sp)
+ return parent_sp->IsDescendant(section);
+ return false;
}
-bool
-Section::Slide (addr_t slide_amount, bool slide_children)
-{
- if (m_file_addr != LLDB_INVALID_ADDRESS)
- {
- if (slide_amount == 0)
- return true;
+bool Section::Slide(addr_t slide_amount, bool slide_children) {
+ if (m_file_addr != LLDB_INVALID_ADDRESS) {
+ if (slide_amount == 0)
+ return true;
- m_file_addr += slide_amount;
+ m_file_addr += slide_amount;
- if (slide_children)
- m_children.Slide (slide_amount, slide_children);
+ if (slide_children)
+ m_children.Slide(slide_amount, slide_children);
- return true;
- }
- return false;
+ return true;
+ }
+ return false;
}
//------------------------------------------------------------------
/// Get the permissions as OR'ed bits from lldb::Permissions
//------------------------------------------------------------------
-uint32_t
-Section::GetPermissions() const
-{
- uint32_t permissions = 0;
- if (m_readable)
- permissions |= ePermissionsReadable;
- if (m_writable)
- permissions |= ePermissionsWritable;
- if (m_executable)
- permissions |= ePermissionsExecutable;
- return permissions;
+uint32_t Section::GetPermissions() const {
+ uint32_t permissions = 0;
+ if (m_readable)
+ permissions |= ePermissionsReadable;
+ if (m_writable)
+ permissions |= ePermissionsWritable;
+ if (m_executable)
+ permissions |= ePermissionsExecutable;
+ return permissions;
}
//------------------------------------------------------------------
/// Set the permissions using bits OR'ed from lldb::Permissions
//------------------------------------------------------------------
-void
-Section::SetPermissions(uint32_t permissions)
-{
- m_readable = (permissions & ePermissionsReadable) != 0;
- m_writable = (permissions & ePermissionsWritable) != 0;
- m_executable = (permissions & ePermissionsExecutable) != 0;
+void Section::SetPermissions(uint32_t permissions) {
+ m_readable = (permissions & ePermissionsReadable) != 0;
+ m_writable = (permissions & ePermissionsWritable) != 0;
+ m_executable = (permissions & ePermissionsExecutable) != 0;
}
-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(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;
+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 () :
- m_sections()
-{
-}
-
+SectionList::SectionList() : m_sections() {}
-SectionList::~SectionList ()
-{
-}
+SectionList::~SectionList() {}
-SectionList &
-SectionList::operator = (const SectionList& rhs)
-{
- if (this != &rhs)
- m_sections = rhs.m_sections;
- return *this;
+SectionList &SectionList::operator=(const SectionList &rhs) {
+ if (this != &rhs)
+ m_sections = rhs.m_sections;
+ return *this;
}
-size_t
-SectionList::AddSection (const lldb::SectionSP& section_sp)
-{
- if (section_sp)
- {
- size_t section_index = m_sections.size();
- m_sections.push_back(section_sp);
- return section_index;
- }
+size_t SectionList::AddSection(const lldb::SectionSP &section_sp) {
+ if (section_sp) {
+ size_t section_index = m_sections.size();
+ m_sections.push_back(section_sp);
+ return section_index;
+ }
- return std::numeric_limits<size_t>::max ();
+ return std::numeric_limits<size_t>::max();
}
// Warning, this can be slow as it's removing items from a std::vector.
-bool
-SectionList::DeleteSection (size_t idx)
-{
- if (idx < m_sections.size())
- {
- m_sections.erase (m_sections.begin() + idx);
- return true;
- }
- return false;
-}
-
-size_t
-SectionList::FindSectionIndex (const Section* sect)
-{
- iterator sect_iter;
- iterator begin = m_sections.begin();
- iterator end = m_sections.end();
- for (sect_iter = begin; sect_iter != end; ++sect_iter)
- {
- if (sect_iter->get() == sect)
- {
- // The secton was already in this section list
- return std::distance (begin, sect_iter);
- }
- }
- return UINT32_MAX;
-}
-
-size_t
-SectionList::AddUniqueSection (const lldb::SectionSP& sect_sp)
-{
- size_t sect_idx = FindSectionIndex (sect_sp.get());
- if (sect_idx == UINT32_MAX)
- {
- sect_idx = AddSection (sect_sp);
- }
- return sect_idx;
-}
-
-bool
-SectionList::ReplaceSection (user_id_t sect_id, const lldb::SectionSP& sect_sp, uint32_t depth)
-{
- iterator sect_iter, end = m_sections.end();
- for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
- {
- if ((*sect_iter)->GetID() == sect_id)
- {
- *sect_iter = sect_sp;
- return true;
- }
- else if (depth > 0)
- {
- if ((*sect_iter)->GetChildren().ReplaceSection(sect_id, sect_sp, depth - 1))
- return true;
- }
+bool SectionList::DeleteSection(size_t idx) {
+ if (idx < m_sections.size()) {
+ m_sections.erase(m_sections.begin() + idx);
+ return true;
+ }
+ return false;
+}
+
+size_t SectionList::FindSectionIndex(const Section *sect) {
+ iterator sect_iter;
+ iterator begin = m_sections.begin();
+ iterator end = m_sections.end();
+ for (sect_iter = begin; sect_iter != end; ++sect_iter) {
+ if (sect_iter->get() == sect) {
+ // The secton was already in this section list
+ return std::distance(begin, sect_iter);
}
- return false;
-}
-
-size_t
-SectionList::GetNumSections (uint32_t depth) const
-{
- size_t count = m_sections.size();
- if (depth > 0)
- {
- const_iterator sect_iter, end = m_sections.end();
- for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
- {
- count += (*sect_iter)->GetChildren().GetNumSections(depth - 1);
- }
+ }
+ return UINT32_MAX;
+}
+
+size_t SectionList::AddUniqueSection(const lldb::SectionSP &sect_sp) {
+ size_t sect_idx = FindSectionIndex(sect_sp.get());
+ if (sect_idx == UINT32_MAX) {
+ sect_idx = AddSection(sect_sp);
+ }
+ return sect_idx;
+}
+
+bool SectionList::ReplaceSection(user_id_t sect_id,
+ const lldb::SectionSP &sect_sp,
+ uint32_t depth) {
+ iterator sect_iter, end = m_sections.end();
+ for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) {
+ if ((*sect_iter)->GetID() == sect_id) {
+ *sect_iter = sect_sp;
+ return true;
+ } else if (depth > 0) {
+ if ((*sect_iter)
+ ->GetChildren()
+ .ReplaceSection(sect_id, sect_sp, depth - 1))
+ return true;
}
- return count;
+ }
+ return false;
}
-SectionSP
-SectionList::GetSectionAtIndex (size_t idx) const
-{
- SectionSP sect_sp;
- if (idx < m_sections.size())
- sect_sp = m_sections[idx];
- return sect_sp;
-}
-
-SectionSP
-SectionList::FindSectionByName (const ConstString &section_dstr) const
-{
- SectionSP sect_sp;
- // Check if we have a valid section string
- if (section_dstr && !m_sections.empty())
- {
- const_iterator sect_iter;
- const_iterator end = m_sections.end();
- for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
- {
- Section *child_section = sect_iter->get();
- if (child_section)
- {
- if (child_section->GetName() == section_dstr)
- {
- sect_sp = *sect_iter;
- }
- else
- {
- sect_sp = child_section->GetChildren().FindSectionByName(section_dstr);
- }
- }
- }
+size_t SectionList::GetNumSections(uint32_t depth) const {
+ size_t count = m_sections.size();
+ if (depth > 0) {
+ const_iterator sect_iter, end = m_sections.end();
+ for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) {
+ count += (*sect_iter)->GetChildren().GetNumSections(depth - 1);
}
- return sect_sp;
+ }
+ return count;
}
-SectionSP
-SectionList::FindSectionByID (user_id_t sect_id) const
-{
- SectionSP sect_sp;
- if (sect_id)
- {
- const_iterator sect_iter;
- const_iterator end = m_sections.end();
- for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
- {
- if ((*sect_iter)->GetID() == sect_id)
- {
- sect_sp = *sect_iter;
- break;
- }
- else
- {
- sect_sp = (*sect_iter)->GetChildren().FindSectionByID (sect_id);
- }
- }
- }
- return sect_sp;
+SectionSP SectionList::GetSectionAtIndex(size_t idx) const {
+ SectionSP sect_sp;
+ if (idx < m_sections.size())
+ sect_sp = m_sections[idx];
+ return sect_sp;
}
-
SectionSP
-SectionList::FindSectionByType (SectionType sect_type, bool check_children, size_t start_idx) const
-{
- SectionSP sect_sp;
- size_t num_sections = m_sections.size();
- for (size_t idx = start_idx; idx < num_sections; ++idx)
- {
- if (m_sections[idx]->GetType() == sect_type)
- {
- sect_sp = m_sections[idx];
- break;
- }
- else if (check_children)
- {
- sect_sp = m_sections[idx]->GetChildren().FindSectionByType (sect_type, check_children, 0);
- if (sect_sp)
- break;
+SectionList::FindSectionByName(const ConstString &section_dstr) const {
+ SectionSP sect_sp;
+ // Check if we have a valid section string
+ if (section_dstr && !m_sections.empty()) {
+ const_iterator sect_iter;
+ const_iterator end = m_sections.end();
+ for (sect_iter = m_sections.begin();
+ sect_iter != end && sect_sp.get() == NULL; ++sect_iter) {
+ Section *child_section = sect_iter->get();
+ if (child_section) {
+ if (child_section->GetName() == section_dstr) {
+ sect_sp = *sect_iter;
+ } else {
+ sect_sp =
+ child_section->GetChildren().FindSectionByName(section_dstr);
}
+ }
}
- return sect_sp;
+ }
+ return sect_sp;
}
-SectionSP
-SectionList::FindSectionContainingFileAddress (addr_t vm_addr, uint32_t depth) const
-{
- SectionSP sect_sp;
+SectionSP SectionList::FindSectionByID(user_id_t sect_id) const {
+ SectionSP sect_sp;
+ if (sect_id) {
const_iterator sect_iter;
const_iterator end = m_sections.end();
- for (sect_iter = m_sections.begin(); sect_iter != end && sect_sp.get() == NULL; ++sect_iter)
- {
- Section *sect = sect_iter->get();
- if (sect->ContainsFileAddress (vm_addr))
- {
- // The file address is in this section. We need to make sure one of our child
- // sections doesn't contain this address as well as obeying the depth limit
- // that was passed in.
- if (depth > 0)
- sect_sp = sect->GetChildren().FindSectionContainingFileAddress(vm_addr, depth - 1);
-
- if (sect_sp.get() == NULL && !sect->IsFake())
- sect_sp = *sect_iter;
- }
+ for (sect_iter = m_sections.begin();
+ sect_iter != end && sect_sp.get() == NULL; ++sect_iter) {
+ if ((*sect_iter)->GetID() == sect_id) {
+ sect_sp = *sect_iter;
+ break;
+ } else {
+ sect_sp = (*sect_iter)->GetChildren().FindSectionByID(sect_id);
+ }
}
- return sect_sp;
-}
-
-bool
-SectionList::ContainsSection(user_id_t sect_id) const
-{
- return FindSectionByID (sect_id).get() != NULL;
-}
-
-void
-SectionList::Dump (Stream *s, Target *target, bool show_header, uint32_t depth) const
-{
- bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty();
- if (show_header && !m_sections.empty())
- {
- s->Indent();
- s->Printf("SectID Type %s Address Perm File Off. File Size Flags "
- " Section Name\n",
- target_has_loaded_sections ? "Load" : "File");
- s->Indent();
- s->PutCString("---------- ---------------- --------------------------------------- ---- ---------- ---------- "
- "---------- ----------------------------\n");
+ }
+ return sect_sp;
+}
+
+SectionSP SectionList::FindSectionByType(SectionType sect_type,
+ bool check_children,
+ size_t start_idx) const {
+ SectionSP sect_sp;
+ size_t num_sections = m_sections.size();
+ for (size_t idx = start_idx; idx < num_sections; ++idx) {
+ if (m_sections[idx]->GetType() == sect_type) {
+ sect_sp = m_sections[idx];
+ break;
+ } else if (check_children) {
+ sect_sp = m_sections[idx]->GetChildren().FindSectionByType(
+ sect_type, check_children, 0);
+ if (sect_sp)
+ break;
}
-
-
- const_iterator sect_iter;
- const_iterator end = m_sections.end();
- for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter)
- {
- (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL, depth);
+ }
+ return sect_sp;
+}
+
+SectionSP SectionList::FindSectionContainingFileAddress(addr_t vm_addr,
+ uint32_t depth) const {
+ SectionSP sect_sp;
+ const_iterator sect_iter;
+ const_iterator end = m_sections.end();
+ for (sect_iter = m_sections.begin();
+ sect_iter != end && sect_sp.get() == NULL; ++sect_iter) {
+ Section *sect = sect_iter->get();
+ if (sect->ContainsFileAddress(vm_addr)) {
+ // The file address is in this section. We need to make sure one of our
+ // child
+ // sections doesn't contain this address as well as obeying the depth
+ // limit
+ // that was passed in.
+ if (depth > 0)
+ sect_sp = sect->GetChildren().FindSectionContainingFileAddress(
+ vm_addr, depth - 1);
+
+ if (sect_sp.get() == NULL && !sect->IsFake())
+ sect_sp = *sect_iter;
}
+ }
+ return sect_sp;
+}
- if (show_header && !m_sections.empty())
- s->IndentLess();
-
+bool SectionList::ContainsSection(user_id_t sect_id) const {
+ return FindSectionByID(sect_id).get() != NULL;
}
-size_t
-SectionList::Slide (addr_t slide_amount, bool slide_children)
-{
- size_t count = 0;
- const_iterator pos, end = m_sections.end();
- for (pos = m_sections.begin(); pos != end; ++pos)
- {
- if ((*pos)->Slide(slide_amount, slide_children))
- ++count;
- }
- return count;
+void SectionList::Dump(Stream *s, Target *target, bool show_header,
+ uint32_t depth) const {
+ bool target_has_loaded_sections =
+ target && !target->GetSectionLoadList().IsEmpty();
+ if (show_header && !m_sections.empty()) {
+ s->Indent();
+ s->Printf("SectID Type %s Address "
+ " Perm File Off. File Size Flags "
+ " Section Name\n",
+ target_has_loaded_sections ? "Load" : "File");
+ s->Indent();
+ s->PutCString("---------- ---------------- "
+ "--------------------------------------- ---- ---------- "
+ "---------- "
+ "---------- ----------------------------\n");
+ }
+
+ const_iterator sect_iter;
+ const_iterator end = m_sections.end();
+ for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) {
+ (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL, depth);
+ }
+
+ if (show_header && !m_sections.empty())
+ s->IndentLess();
+}
+
+size_t SectionList::Slide(addr_t slide_amount, bool slide_children) {
+ size_t count = 0;
+ const_iterator pos, end = m_sections.end();
+ for (pos = m_sections.begin(); pos != end; ++pos) {
+ if ((*pos)->Slide(slide_amount, slide_children))
+ ++count;
+ }
+ return count;
}
diff --git a/source/Core/SourceManager.cpp b/source/Core/SourceManager.cpp
index a69e75fe244a..603fe5711498 100644
--- a/source/Core/SourceManager.cpp
+++ b/source/Core/SourceManager.cpp
@@ -18,682 +18,680 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
+#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/Target.h"
+#include "lldb/Utility/AnsiTerminal.h"
using namespace lldb;
using namespace lldb_private;
-
-static inline bool is_newline_char(char ch)
-{
- return ch == '\n' || ch == '\r';
-}
-
+static inline bool is_newline_char(char ch) { return ch == '\n' || ch == '\r'; }
//----------------------------------------------------------------------
// SourceManager constructor
//----------------------------------------------------------------------
-SourceManager::SourceManager(const TargetSP &target_sp) :
- m_last_file_sp (),
- m_last_line (0),
- m_last_count (0),
- m_default_set(false),
- m_target_wp (target_sp),
- m_debugger_wp(target_sp->GetDebugger().shared_from_this())
-{
-}
+SourceManager::SourceManager(const TargetSP &target_sp)
+ : m_last_file_sp(), m_last_line(0), m_last_count(0), m_default_set(false),
+ m_target_wp(target_sp),
+ m_debugger_wp(target_sp->GetDebugger().shared_from_this()) {}
-SourceManager::SourceManager(const DebuggerSP &debugger_sp) :
- m_last_file_sp (),
- m_last_line (0),
- m_last_count (0),
- m_default_set(false),
- m_target_wp (),
- m_debugger_wp (debugger_sp)
-{
-}
+SourceManager::SourceManager(const DebuggerSP &debugger_sp)
+ : m_last_file_sp(), m_last_line(0), m_last_count(0), m_default_set(false),
+ m_target_wp(), m_debugger_wp(debugger_sp) {}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-SourceManager::~SourceManager()
-{
-}
+SourceManager::~SourceManager() {}
+
+SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) {
+ bool same_as_previous =
+ m_last_file_sp && m_last_file_sp->FileSpecMatches(file_spec);
+
+ DebuggerSP debugger_sp(m_debugger_wp.lock());
+ FileSP file_sp;
+ if (same_as_previous)
+ file_sp = m_last_file_sp;
+ else if (debugger_sp)
+ file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(file_spec);
+
+ TargetSP target_sp(m_target_wp.lock());
+
+ // It the target source path map has been updated, get this file again so we
+ // can successfully remap the source file
+ 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()) {
+ if (target_sp)
+ file_sp.reset(new File(file_spec, target_sp.get()));
+ else
+ file_sp.reset(new File(file_spec, debugger_sp));
-SourceManager::FileSP
-SourceManager::GetFile (const FileSpec &file_spec)
-{
- bool same_as_previous = m_last_file_sp && m_last_file_sp->FileSpecMatches (file_spec);
-
- DebuggerSP debugger_sp (m_debugger_wp.lock());
- FileSP file_sp;
- if (same_as_previous)
- file_sp = m_last_file_sp;
- else if (debugger_sp)
- file_sp = debugger_sp->GetSourceFileCache().FindSourceFile (file_spec);
-
- TargetSP target_sp (m_target_wp.lock());
-
- // It the target source path map has been updated, get this file again so we
- // can successfully remap the source file
- 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())
- {
- file_sp.reset (new File (file_spec, target_sp.get()));
-
- if (debugger_sp)
- debugger_sp->GetSourceFileCache().AddSourceFile(file_sp);
- }
- return file_sp;
+ if (debugger_sp)
+ debugger_sp->GetSourceFileCache().AddSourceFile(file_sp);
+ }
+ return file_sp;
}
-size_t
-SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile (uint32_t start_line,
- uint32_t count,
- uint32_t curr_line,
- const char* current_line_cstr,
- Stream *s,
- const SymbolContextList *bp_locs)
-{
- if (count == 0)
- return 0;
- size_t return_value = 0;
- if (start_line == 0)
- {
- if (m_last_line != 0 && m_last_line != UINT32_MAX)
- start_line = m_last_line + m_last_count;
- else
- start_line = 1;
- }
+static bool should_show_stop_column_with_ansi(DebuggerSP debugger_sp) {
+ // We don't use ANSI stop column formatting if we can't lookup values from
+ // the debugger.
+ if (!debugger_sp)
+ return false;
- if (!m_default_set)
- {
- FileSpec tmp_spec;
- uint32_t tmp_line;
- GetDefaultFileAndLine(tmp_spec, tmp_line);
- }
+ // We don't use ANSI stop column formatting if the debugger doesn't think
+ // it should be using color.
+ if (!debugger_sp->GetUseColor())
+ return false;
- m_last_line = start_line;
- m_last_count = count;
-
- if (m_last_file_sp.get())
- {
- const uint32_t end_line = start_line + count - 1;
- for (uint32_t line = start_line; line <= end_line; ++line)
- {
- if (!m_last_file_sp->LineIsValid (line))
- {
- m_last_line = UINT32_MAX;
- break;
- }
+ // We only use ANSI stop column formatting if we're either supposed to show
+ // ANSI where available (which we know we have when we get to this point), or
+ // if we're only supposed to use ANSI.
+ const auto value = debugger_sp->GetStopShowColumn();
+ return ((value == eStopShowColumnAnsiOrCaret) ||
+ (value == eStopShowColumnAnsi));
+}
- char prefix[32] = "";
- if (bp_locs)
- {
- uint32_t bp_count = bp_locs->NumLineEntriesWithLine (line);
-
- if (bp_count > 0)
- ::snprintf (prefix, sizeof (prefix), "[%u] ", bp_count);
- else
- ::snprintf (prefix, sizeof (prefix), " ");
- }
+static bool should_show_stop_column_with_caret(DebuggerSP debugger_sp) {
+ // We don't use text-based stop column formatting if we can't lookup values
+ // from the debugger.
+ if (!debugger_sp)
+ return false;
- return_value += s->Printf("%s%2.2s %-4u\t",
- prefix,
- line == curr_line ? current_line_cstr : "",
- line);
- size_t this_line_size = m_last_file_sp->DisplaySourceLines (line, 0, 0, s);
- if (this_line_size == 0)
- {
- m_last_line = UINT32_MAX;
- break;
- }
- else
- return_value += this_line_size;
- }
- }
- return return_value;
+ // If we're asked to show the first available of ANSI or caret, then
+ // we do show the caret when ANSI is not available.
+ const auto value = debugger_sp->GetStopShowColumn();
+ if ((value == eStopShowColumnAnsiOrCaret) && !debugger_sp->GetUseColor())
+ return true;
+
+ // The only other time we use caret is if we're explicitly asked to show
+ // caret.
+ return value == eStopShowColumnCaret;
}
-size_t
-SourceManager::DisplaySourceLinesWithLineNumbers
-(
- const FileSpec &file_spec,
- uint32_t line,
- uint32_t context_before,
- uint32_t context_after,
- const char* current_line_cstr,
- Stream *s,
- const SymbolContextList *bp_locs
-)
-{
- FileSP file_sp (GetFile (file_spec));
-
- uint32_t start_line;
- uint32_t count = context_before + context_after + 1;
- if (line > context_before)
- start_line = line - context_before;
+size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile(
+ uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column,
+ const char *current_line_cstr, Stream *s,
+ const SymbolContextList *bp_locs) {
+ if (count == 0)
+ return 0;
+ size_t return_value = 0;
+ if (start_line == 0) {
+ if (m_last_line != 0 && m_last_line != UINT32_MAX)
+ start_line = m_last_line + m_last_count;
else
- start_line = 1;
-
- if (m_last_file_sp.get() != file_sp.get())
- {
- if (line == 0)
- m_last_line = 0;
- m_last_file_sp = file_sp;
+ start_line = 1;
+ }
+
+ if (!m_default_set) {
+ FileSpec tmp_spec;
+ uint32_t tmp_line;
+ GetDefaultFileAndLine(tmp_spec, tmp_line);
+ }
+
+ m_last_line = start_line;
+ m_last_count = count;
+
+ if (m_last_file_sp.get()) {
+ const uint32_t end_line = start_line + count - 1;
+ for (uint32_t line = start_line; line <= end_line; ++line) {
+ if (!m_last_file_sp->LineIsValid(line)) {
+ m_last_line = UINT32_MAX;
+ break;
+ }
+
+ char prefix[32] = "";
+ if (bp_locs) {
+ uint32_t bp_count = bp_locs->NumLineEntriesWithLine(line);
+
+ if (bp_count > 0)
+ ::snprintf(prefix, sizeof(prefix), "[%u] ", bp_count);
+ else
+ ::snprintf(prefix, sizeof(prefix), " ");
+ }
+
+ return_value +=
+ s->Printf("%s%2.2s %-4u\t", prefix,
+ line == curr_line ? current_line_cstr : "", line);
+ size_t this_line_size = m_last_file_sp->DisplaySourceLines(
+ line, line == curr_line ? column : 0, 0, 0, s);
+ if (column != 0 && line == curr_line &&
+ should_show_stop_column_with_caret(m_debugger_wp.lock())) {
+ // Display caret cursor.
+ std::string src_line;
+ m_last_file_sp->GetLine(line, src_line);
+ return_value += s->Printf(" \t");
+ // Insert a space for every non-tab character in the source line.
+ for (size_t i = 0; i + 1 < column && i < src_line.length(); ++i)
+ return_value += s->PutChar(src_line[i] == '\t' ? '\t' : ' ');
+ // Now add the caret.
+ return_value += s->Printf("^\n");
+ }
+ if (this_line_size == 0) {
+ m_last_line = UINT32_MAX;
+ break;
+ } else
+ return_value += this_line_size;
}
- return DisplaySourceLinesWithLineNumbersUsingLastFile (start_line, count, line, current_line_cstr, s, bp_locs);
+ }
+ return return_value;
}
-size_t
-SourceManager::DisplayMoreWithLineNumbers (Stream *s,
- uint32_t count,
- bool reverse,
- const SymbolContextList *bp_locs)
-{
- // If we get called before anybody has set a default file and line, then try to figure it out here.
- const bool have_default_file_line = m_last_file_sp && m_last_line > 0;
- if (!m_default_set)
- {
- FileSpec tmp_spec;
- uint32_t tmp_line;
- GetDefaultFileAndLine(tmp_spec, tmp_line);
- }
-
- if (m_last_file_sp)
- {
- if (m_last_line == UINT32_MAX)
- return 0;
-
- if (reverse && m_last_line == 1)
- return 0;
-
- if (count > 0)
- m_last_count = count;
- else if (m_last_count == 0)
- m_last_count = 10;
-
- if (m_last_line > 0)
- {
- if (reverse)
- {
- // If this is the first time we've done a reverse, then back up one more time so we end
- // up showing the chunk before the last one we've shown:
- if (m_last_line > m_last_count)
- m_last_line -= m_last_count;
- else
- m_last_line = 1;
- }
- else if (have_default_file_line)
- m_last_line += m_last_count;
- }
+size_t SourceManager::DisplaySourceLinesWithLineNumbers(
+ const FileSpec &file_spec, uint32_t line, uint32_t column,
+ uint32_t context_before, uint32_t context_after,
+ const char *current_line_cstr, Stream *s,
+ const SymbolContextList *bp_locs) {
+ FileSP file_sp(GetFile(file_spec));
+
+ uint32_t start_line;
+ uint32_t count = context_before + context_after + 1;
+ if (line > context_before)
+ start_line = line - context_before;
+ else
+ start_line = 1;
+
+ if (m_last_file_sp.get() != file_sp.get()) {
+ if (line == 0)
+ m_last_line = 0;
+ m_last_file_sp = file_sp;
+ }
+ return DisplaySourceLinesWithLineNumbersUsingLastFile(
+ start_line, count, line, column, current_line_cstr, s, bp_locs);
+}
+
+size_t SourceManager::DisplayMoreWithLineNumbers(
+ Stream *s, uint32_t count, bool reverse, const SymbolContextList *bp_locs) {
+ // If we get called before anybody has set a default file and line, then try
+ // to figure it out here.
+ const bool have_default_file_line = m_last_file_sp && m_last_line > 0;
+ if (!m_default_set) {
+ FileSpec tmp_spec;
+ uint32_t tmp_line;
+ GetDefaultFileAndLine(tmp_spec, tmp_line);
+ }
+
+ if (m_last_file_sp) {
+ if (m_last_line == UINT32_MAX)
+ return 0;
+
+ if (reverse && m_last_line == 1)
+ return 0;
+
+ if (count > 0)
+ m_last_count = count;
+ else if (m_last_count == 0)
+ m_last_count = 10;
+
+ if (m_last_line > 0) {
+ if (reverse) {
+ // If this is the first time we've done a reverse, then back up one more
+ // time so we end
+ // up showing the chunk before the last one we've shown:
+ if (m_last_line > m_last_count)
+ m_last_line -= m_last_count;
else
- m_last_line = 1;
-
- return DisplaySourceLinesWithLineNumbersUsingLastFile (m_last_line, m_last_count, UINT32_MAX, "", s, bp_locs);
- }
- return 0;
+ m_last_line = 1;
+ } else if (have_default_file_line)
+ m_last_line += m_last_count;
+ } else
+ m_last_line = 1;
+
+ const uint32_t column = 0;
+ return DisplaySourceLinesWithLineNumbersUsingLastFile(
+ m_last_line, m_last_count, UINT32_MAX, column, "", s, bp_locs);
+ }
+ return 0;
}
-bool
-SourceManager::SetDefaultFileAndLine (const FileSpec &file_spec, uint32_t line)
-{
- FileSP old_file_sp = m_last_file_sp;
- m_last_file_sp = GetFile (file_spec);
-
- m_default_set = true;
- if (m_last_file_sp)
- {
- m_last_line = line;
- return true;
- }
- else
- {
- m_last_file_sp = old_file_sp;
- return false;
- }
+bool SourceManager::SetDefaultFileAndLine(const FileSpec &file_spec,
+ uint32_t line) {
+ FileSP old_file_sp = m_last_file_sp;
+ m_last_file_sp = GetFile(file_spec);
+
+ m_default_set = true;
+ if (m_last_file_sp) {
+ m_last_line = line;
+ return true;
+ } else {
+ m_last_file_sp = old_file_sp;
+ return false;
+ }
}
-bool
-SourceManager::GetDefaultFileAndLine (FileSpec &file_spec, uint32_t &line)
-{
- if (m_last_file_sp)
- {
- file_spec = m_last_file_sp->GetFileSpec();
- line = m_last_line;
- return true;
- }
- else if (!m_default_set)
- {
- TargetSP target_sp (m_target_wp.lock());
-
- if (target_sp)
- {
- // If nobody has set the default file and line then try here. If there's no executable, then we
- // will try again later when there is one. Otherwise, if we can't find it we won't look again,
- // somebody will have to set it (for instance when we stop somewhere...)
- Module *executable_ptr = target_sp->GetExecutableModulePointer();
- if (executable_ptr)
- {
- SymbolContextList sc_list;
- ConstString main_name("main");
- bool symbols_okay = false; // Force it to be a debug symbol.
- bool inlines_okay = true;
- bool append = false;
- size_t num_matches = executable_ptr->FindFunctions (main_name,
- NULL,
- lldb::eFunctionNameTypeBase,
- inlines_okay,
- symbols_okay,
- append,
- sc_list);
- for (size_t idx = 0; idx < num_matches; idx++)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex(idx, sc);
- if (sc.function)
- {
- lldb_private::LineEntry line_entry;
- if (sc.function->GetAddressRange().GetBaseAddress().CalculateSymbolContextLineEntry (line_entry))
- {
- SetDefaultFileAndLine (line_entry.file,
- line_entry.line);
- file_spec = m_last_file_sp->GetFileSpec();
- line = m_last_line;
- return true;
- }
- }
- }
+bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) {
+ if (m_last_file_sp) {
+ file_spec = m_last_file_sp->GetFileSpec();
+ line = m_last_line;
+ return true;
+ } else if (!m_default_set) {
+ TargetSP target_sp(m_target_wp.lock());
+
+ if (target_sp) {
+ // If nobody has set the default file and line then try here. If there's
+ // no executable, then we
+ // will try again later when there is one. Otherwise, if we can't find it
+ // we won't look again,
+ // somebody will have to set it (for instance when we stop somewhere...)
+ Module *executable_ptr = target_sp->GetExecutableModulePointer();
+ if (executable_ptr) {
+ SymbolContextList sc_list;
+ ConstString main_name("main");
+ bool symbols_okay = false; // Force it to be a debug symbol.
+ bool inlines_okay = true;
+ bool append = false;
+ size_t num_matches = executable_ptr->FindFunctions(
+ main_name, NULL, lldb::eFunctionNameTypeBase, inlines_okay,
+ symbols_okay, append, sc_list);
+ for (size_t idx = 0; idx < num_matches; idx++) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(idx, sc);
+ if (sc.function) {
+ lldb_private::LineEntry line_entry;
+ if (sc.function->GetAddressRange()
+ .GetBaseAddress()
+ .CalculateSymbolContextLineEntry(line_entry)) {
+ SetDefaultFileAndLine(line_entry.file, line_entry.line);
+ file_spec = m_last_file_sp->GetFileSpec();
+ line = m_last_line;
+ return true;
}
+ }
}
+ }
}
- return false;
+ }
+ return false;
}
-void
-SourceManager::FindLinesMatchingRegex (FileSpec &file_spec,
- RegularExpression& regex,
- uint32_t start_line,
- uint32_t end_line,
- std::vector<uint32_t> &match_lines)
-{
- match_lines.clear();
- FileSP file_sp = GetFile (file_spec);
- if (!file_sp)
- return;
- return file_sp->FindLinesMatchingRegex (regex, start_line, end_line, match_lines);
+void SourceManager::FindLinesMatchingRegex(FileSpec &file_spec,
+ RegularExpression &regex,
+ uint32_t start_line,
+ uint32_t end_line,
+ std::vector<uint32_t> &match_lines) {
+ match_lines.clear();
+ FileSP file_sp = GetFile(file_spec);
+ if (!file_sp)
+ return;
+ return file_sp->FindLinesMatchingRegex(regex, start_line, end_line,
+ match_lines);
}
-SourceManager::File::File(const FileSpec &file_spec, Target *target) :
- m_file_spec_orig (file_spec),
- m_file_spec(file_spec),
- m_mod_time (file_spec.GetModificationTime()),
- m_source_map_mod_id (0),
- m_data_sp(),
- m_offsets()
-{
- if (!m_mod_time.IsValid())
- {
- if (target)
- {
- m_source_map_mod_id = target->GetSourcePathMap().GetModificationID();
-
- if (!file_spec.GetDirectory() && file_spec.GetFilename())
- {
- // If this is just a file name, lets see if we can find it in the target:
- bool check_inlines = false;
- SymbolContextList sc_list;
- size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath (file_spec.GetFilename().AsCString(),
- 0,
- check_inlines,
- lldb::eSymbolContextModule | lldb::eSymbolContextCompUnit,
- sc_list);
- bool got_multiple = false;
- if (num_matches != 0)
- {
- if (num_matches > 1)
- {
- SymbolContext sc;
- FileSpec *test_cu_spec = NULL;
-
- for (unsigned i = 0; i < num_matches; i++)
- {
- sc_list.GetContextAtIndex(i, sc);
- if (sc.comp_unit)
- {
- if (test_cu_spec)
- {
- if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit))
- got_multiple = true;
- break;
- }
- else
- test_cu_spec = sc.comp_unit;
- }
- }
- }
- if (!got_multiple)
- {
- SymbolContext sc;
- sc_list.GetContextAtIndex (0, sc);
- m_file_spec = sc.comp_unit;
- m_mod_time = m_file_spec.GetModificationTime();
- }
- }
- }
- // Try remapping if m_file_spec does not correspond to an existing file.
- if (!m_file_spec.Exists())
- {
- FileSpec new_file_spec;
- // Check target specific source remappings first, then fall back to
- // modules objects can have individual path remappings that were detected
- // when the debug info for a module was found.
- // then
- if (target->GetSourcePathMap().FindFile (m_file_spec, new_file_spec) ||
- target->GetImages().FindSourceFile (m_file_spec, new_file_spec))
- {
- m_file_spec = new_file_spec;
- m_mod_time = m_file_spec.GetModificationTime();
- }
+SourceManager::File::File(const FileSpec &file_spec,
+ lldb::DebuggerSP debugger_sp)
+ : m_file_spec_orig(file_spec), m_file_spec(file_spec),
+ m_mod_time(FileSystem::GetModificationTime(file_spec)),
+ m_debugger_wp(debugger_sp) {
+ CommonInitializer(file_spec, nullptr);
+}
+
+SourceManager::File::File(const FileSpec &file_spec, Target *target)
+ : m_file_spec_orig(file_spec), m_file_spec(file_spec),
+ m_mod_time(FileSystem::GetModificationTime(file_spec)),
+ m_debugger_wp(target ? target->GetDebugger().shared_from_this()
+ : DebuggerSP()) {
+ CommonInitializer(file_spec, target);
+}
+
+void SourceManager::File::CommonInitializer(const FileSpec &file_spec,
+ Target *target) {
+ if (m_mod_time == llvm::sys::TimePoint<>()) {
+ if (target) {
+ m_source_map_mod_id = target->GetSourcePathMap().GetModificationID();
+
+ if (!file_spec.GetDirectory() && file_spec.GetFilename()) {
+ // If this is just a file name, lets see if we can find it in the
+ // target:
+ bool check_inlines = false;
+ SymbolContextList sc_list;
+ size_t num_matches =
+ target->GetImages().ResolveSymbolContextForFilePath(
+ file_spec.GetFilename().AsCString(), 0, check_inlines,
+ lldb::eSymbolContextModule | lldb::eSymbolContextCompUnit,
+ sc_list);
+ bool got_multiple = false;
+ if (num_matches != 0) {
+ if (num_matches > 1) {
+ SymbolContext sc;
+ FileSpec *test_cu_spec = NULL;
+
+ for (unsigned i = 0; i < num_matches; i++) {
+ sc_list.GetContextAtIndex(i, sc);
+ if (sc.comp_unit) {
+ if (test_cu_spec) {
+ if (test_cu_spec != static_cast<FileSpec *>(sc.comp_unit))
+ got_multiple = true;
+ break;
+ } else
+ test_cu_spec = sc.comp_unit;
+ }
}
+ }
+ if (!got_multiple) {
+ SymbolContext sc;
+ sc_list.GetContextAtIndex(0, sc);
+ m_file_spec = sc.comp_unit;
+ m_mod_time = FileSystem::GetModificationTime(m_file_spec);
+ }
+ }
+ }
+ // Try remapping if m_file_spec does not correspond to an existing file.
+ if (!m_file_spec.Exists()) {
+ FileSpec new_file_spec;
+ // Check target specific source remappings first, then fall back to
+ // modules objects can have individual path remappings that were
+ // detected
+ // when the debug info for a module was found.
+ // then
+ if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) ||
+ target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) {
+ m_file_spec = new_file_spec;
+ m_mod_time = FileSystem::GetModificationTime(m_file_spec);
}
+ }
}
-
- if (m_mod_time.IsValid())
- m_data_sp = m_file_spec.ReadFileContents ();
-}
+ }
-SourceManager::File::~File()
-{
+ if (m_mod_time != llvm::sys::TimePoint<>())
+ m_data_sp = m_file_spec.ReadFileContents();
}
-uint32_t
-SourceManager::File::GetLineOffset (uint32_t line)
-{
- if (line == 0)
- return UINT32_MAX;
+uint32_t SourceManager::File::GetLineOffset(uint32_t line) {
+ if (line == 0)
+ return UINT32_MAX;
- if (line == 1)
- return 0;
+ if (line == 1)
+ return 0;
- if (CalculateLineOffsets (line))
- {
- if (line < m_offsets.size())
- return m_offsets[line - 1]; // yes we want "line - 1" in the index
- }
- return UINT32_MAX;
+ if (CalculateLineOffsets(line)) {
+ if (line < m_offsets.size())
+ return m_offsets[line - 1]; // yes we want "line - 1" in the index
+ }
+ return UINT32_MAX;
}
-uint32_t
-SourceManager::File::GetNumLines ()
-{
- CalculateLineOffsets();
- return m_offsets.size();
+uint32_t SourceManager::File::GetNumLines() {
+ CalculateLineOffsets();
+ return m_offsets.size();
}
-const char *
-SourceManager::File::PeekLineData (uint32_t line)
-{
- if (!LineIsValid(line))
- return NULL;
-
- size_t line_offset = GetLineOffset (line);
- if (line_offset < m_data_sp->GetByteSize())
- return (const char *)m_data_sp->GetBytes() + line_offset;
+const char *SourceManager::File::PeekLineData(uint32_t line) {
+ if (!LineIsValid(line))
return NULL;
+
+ size_t line_offset = GetLineOffset(line);
+ if (line_offset < m_data_sp->GetByteSize())
+ return (const char *)m_data_sp->GetBytes() + line_offset;
+ return NULL;
}
-uint32_t
-SourceManager::File::GetLineLength (uint32_t line, bool include_newline_chars)
-{
- if (!LineIsValid(line))
- return false;
-
- size_t start_offset = GetLineOffset (line);
- size_t end_offset = GetLineOffset (line + 1);
- if (end_offset == UINT32_MAX)
- end_offset = m_data_sp->GetByteSize();
-
- if (end_offset > start_offset)
- {
- uint32_t length = end_offset - start_offset;
- if (include_newline_chars == false)
- {
- const char *line_start = (const char *)m_data_sp->GetBytes() + start_offset;
- while (length > 0)
- {
- const char last_char = line_start[length-1];
- if ((last_char == '\r') || (last_char == '\n'))
- --length;
- else
- break;
- }
- }
- return length;
+uint32_t SourceManager::File::GetLineLength(uint32_t line,
+ bool include_newline_chars) {
+ if (!LineIsValid(line))
+ return false;
+
+ size_t start_offset = GetLineOffset(line);
+ size_t end_offset = GetLineOffset(line + 1);
+ if (end_offset == UINT32_MAX)
+ end_offset = m_data_sp->GetByteSize();
+
+ if (end_offset > start_offset) {
+ uint32_t length = end_offset - start_offset;
+ if (include_newline_chars == false) {
+ const char *line_start =
+ (const char *)m_data_sp->GetBytes() + start_offset;
+ while (length > 0) {
+ const char last_char = line_start[length - 1];
+ if ((last_char == '\r') || (last_char == '\n'))
+ --length;
+ else
+ break;
+ }
}
- return 0;
+ return length;
+ }
+ return 0;
}
-bool
-SourceManager::File::LineIsValid (uint32_t line)
-{
- if (line == 0)
- return false;
-
- if (CalculateLineOffsets (line))
- return line < m_offsets.size();
+bool SourceManager::File::LineIsValid(uint32_t line) {
+ if (line == 0)
return false;
+
+ if (CalculateLineOffsets(line))
+ return line < m_offsets.size();
+ return false;
}
-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.
- // For now we check each time we want to display info for the file.
- TimeValue curr_mod_time (m_file_spec.GetModificationTime());
-
- if (curr_mod_time.IsValid() && m_mod_time != curr_mod_time)
- {
- m_mod_time = curr_mod_time;
- m_data_sp = m_file_spec.ReadFileContents ();
- m_offsets.clear();
- }
+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.
+ // For now we check each time we want to display info for the file.
+ auto curr_mod_time = FileSystem::GetModificationTime(m_file_spec);
+
+ if (curr_mod_time != llvm::sys::TimePoint<>() &&
+ m_mod_time != curr_mod_time) {
+ m_mod_time = curr_mod_time;
+ 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;
-
- const uint32_t start_line = line <= context_before ? 1 : line - context_before;
- const uint32_t start_line_offset = GetLineOffset (start_line);
- if (start_line_offset != UINT32_MAX)
- {
- const uint32_t end_line = line + context_after;
- uint32_t end_line_offset = GetLineOffset (end_line + 1);
- if (end_line_offset == UINT32_MAX)
- end_line_offset = m_data_sp->GetByteSize();
-
- assert (start_line_offset <= end_line_offset);
- size_t bytes_written = 0;
- if (start_line_offset < end_line_offset)
- {
- size_t count = end_line_offset - start_line_offset;
- const uint8_t *cstr = m_data_sp->GetBytes() + start_line_offset;
- bytes_written = s->Write(cstr, count);
- if (!is_newline_char(cstr[count-1]))
- bytes_written += s->EOL();
+size_t SourceManager::File::DisplaySourceLines(uint32_t line, uint32_t column,
+ uint32_t context_before,
+ uint32_t context_after,
+ Stream *s) {
+ // Nothing to write if there's no stream.
+ if (!s)
+ return 0;
+
+ // Sanity check m_data_sp before proceeding.
+ if (!m_data_sp)
+ return 0;
+
+ const uint32_t start_line =
+ line <= context_before ? 1 : line - context_before;
+ const uint32_t start_line_offset = GetLineOffset(start_line);
+ if (start_line_offset != UINT32_MAX) {
+ const uint32_t end_line = line + context_after;
+ uint32_t end_line_offset = GetLineOffset(end_line + 1);
+ if (end_line_offset == UINT32_MAX)
+ end_line_offset = m_data_sp->GetByteSize();
+
+ assert(start_line_offset <= end_line_offset);
+ size_t bytes_written = 0;
+ if (start_line_offset < end_line_offset) {
+ size_t count = end_line_offset - start_line_offset;
+ const uint8_t *cstr = m_data_sp->GetBytes() + start_line_offset;
+
+ bool displayed_line = false;
+
+ if (column && (column < count)) {
+ auto debugger_sp = m_debugger_wp.lock();
+ if (should_show_stop_column_with_ansi(debugger_sp) && debugger_sp) {
+ // Check if we have any ANSI codes with which to mark this column.
+ // If not, no need to do this work.
+ auto ansi_prefix_entry = debugger_sp->GetStopShowColumnAnsiPrefix();
+ auto ansi_suffix_entry = debugger_sp->GetStopShowColumnAnsiSuffix();
+
+ // We only bother breaking up the line to format the marked column if
+ // there is any marking specified on both sides of the marked column.
+ // In ANSI-terminal-sequence land, there must be a post if there is a
+ // pre format, and vice versa.
+ if (ansi_prefix_entry && ansi_suffix_entry) {
+ // Mark the current column with the desired escape sequence for
+ // formatting the column (e.g. underline, inverse, etc.)
+
+ // First print the part before the column to mark.
+ bytes_written = s->Write(cstr, column - 1);
+
+ // Write the pre escape sequence.
+ const SymbolContext *sc = nullptr;
+ const ExecutionContext *exe_ctx = nullptr;
+ const Address addr = LLDB_INVALID_ADDRESS;
+ ValueObject *valobj = nullptr;
+ const bool function_changed = false;
+ const bool initial_function = false;
+
+ FormatEntity::Format(*ansi_prefix_entry, *s, sc, exe_ctx, &addr,
+ valobj, function_changed, initial_function);
+
+ // Write the marked column.
+ bytes_written += s->Write(cstr + column - 1, 1);
+
+ // Write the post escape sequence.
+ FormatEntity::Format(*ansi_suffix_entry, *s, sc, exe_ctx, &addr,
+ valobj, function_changed, initial_function);
+
+ // And finish up with the rest of the line.
+ bytes_written += s->Write(cstr + column, count - column);
+
+ // Keep track of the fact that we just wrote the line.
+ displayed_line = true;
+ }
}
- return bytes_written;
+ }
+
+ // If we didn't end up displaying the line with ANSI codes for whatever
+ // reason, display it now sans codes.
+ if (!displayed_line)
+ bytes_written = s->Write(cstr, count);
+
+ // Ensure we get an end of line character one way or another.
+ if (!is_newline_char(cstr[count - 1]))
+ bytes_written += s->EOL();
}
- return 0;
+ return bytes_written;
+ }
+ return 0;
}
-void
-SourceManager::File::FindLinesMatchingRegex (RegularExpression& regex, uint32_t start_line, uint32_t end_line, std::vector<uint32_t> &match_lines)
-{
- match_lines.clear();
-
- if (!LineIsValid(start_line) || (end_line != UINT32_MAX && !LineIsValid(end_line)))
- return;
- if (start_line > end_line)
- return;
-
- for (uint32_t line_no = start_line; line_no < end_line; line_no++)
- {
- std::string buffer;
- if (!GetLine (line_no, buffer))
- break;
- if (regex.Execute(buffer.c_str()))
- {
- match_lines.push_back(line_no);
- }
+void SourceManager::File::FindLinesMatchingRegex(
+ RegularExpression &regex, uint32_t start_line, uint32_t end_line,
+ std::vector<uint32_t> &match_lines) {
+ match_lines.clear();
+
+ if (!LineIsValid(start_line) ||
+ (end_line != UINT32_MAX && !LineIsValid(end_line)))
+ return;
+ if (start_line > end_line)
+ return;
+
+ for (uint32_t line_no = start_line; line_no < end_line; line_no++) {
+ std::string buffer;
+ if (!GetLine(line_no, buffer))
+ break;
+ if (regex.Execute(buffer)) {
+ match_lines.push_back(line_no);
}
+ }
}
-bool
-SourceManager::File::FileSpecMatches (const FileSpec &file_spec)
-{
- return FileSpec::Equal (m_file_spec, file_spec, false);
+bool SourceManager::File::FileSpecMatches(const FileSpec &file_spec) {
+ return FileSpec::Equal(m_file_spec, file_spec, false);
}
-bool
-lldb_private::operator== (const SourceManager::File &lhs, const SourceManager::File &rhs)
-{
- if (lhs.m_file_spec == rhs.m_file_spec)
- {
- if (lhs.m_mod_time.IsValid())
- {
- if (rhs.m_mod_time.IsValid())
- return lhs.m_mod_time == rhs.m_mod_time;
- else
- return false;
- }
- else if (rhs.m_mod_time.IsValid())
- return false;
- else
- return true;
- }
- else
- return false;
+bool lldb_private::operator==(const SourceManager::File &lhs,
+ const SourceManager::File &rhs) {
+ if (lhs.m_file_spec != rhs.m_file_spec)
+ return false;
+ return lhs.m_mod_time == rhs.m_mod_time;
}
-bool
-SourceManager::File::CalculateLineOffsets (uint32_t line)
-{
- line = UINT32_MAX; // TODO: take this line out when we support partial indexing
- if (line == UINT32_MAX)
- {
- // Already done?
- if (!m_offsets.empty() && m_offsets[0] == UINT32_MAX)
- return true;
-
- if (m_offsets.empty())
- {
- if (m_data_sp.get() == NULL)
- return false;
-
- const char *start = (char *)m_data_sp->GetBytes();
- if (start)
- {
- const char *end = start + m_data_sp->GetByteSize();
-
- // Calculate all line offsets from scratch
-
- // Push a 1 at index zero to indicate the file has been completely indexed.
- m_offsets.push_back(UINT32_MAX);
- const char *s;
- for (s = start; s < end; ++s)
- {
- char curr_ch = *s;
- if (is_newline_char (curr_ch))
- {
- if (s + 1 < end)
- {
- char next_ch = s[1];
- if (is_newline_char (next_ch))
- {
- if (curr_ch != next_ch)
- ++s;
- }
- }
- m_offsets.push_back(s + 1 - start);
- }
- }
- if (!m_offsets.empty())
- {
- if (m_offsets.back() < end - start)
- m_offsets.push_back(end - start);
- }
- return true;
+bool SourceManager::File::CalculateLineOffsets(uint32_t line) {
+ line =
+ UINT32_MAX; // TODO: take this line out when we support partial indexing
+ if (line == UINT32_MAX) {
+ // Already done?
+ if (!m_offsets.empty() && m_offsets[0] == UINT32_MAX)
+ return true;
+
+ if (m_offsets.empty()) {
+ if (m_data_sp.get() == NULL)
+ return false;
+
+ const char *start = (char *)m_data_sp->GetBytes();
+ if (start) {
+ const char *end = start + m_data_sp->GetByteSize();
+
+ // Calculate all line offsets from scratch
+
+ // Push a 1 at index zero to indicate the file has been completely
+ // indexed.
+ m_offsets.push_back(UINT32_MAX);
+ const char *s;
+ for (s = start; s < end; ++s) {
+ char curr_ch = *s;
+ if (is_newline_char(curr_ch)) {
+ if (s + 1 < end) {
+ char next_ch = s[1];
+ if (is_newline_char(next_ch)) {
+ if (curr_ch != next_ch)
+ ++s;
+ }
}
+ m_offsets.push_back(s + 1 - start);
+ }
}
- else
- {
- // Some lines have been populated, start where we last left off
- assert("Not implemented yet" && false);
+ if (!m_offsets.empty()) {
+ if (m_offsets.back() < size_t(end - start))
+ m_offsets.push_back(end - start);
}
-
- }
- else
- {
- // Calculate all line offsets up to "line"
- assert("Not implemented yet" && false);
+ return true;
+ }
+ } else {
+ // Some lines have been populated, start where we last left off
+ assert("Not implemented yet" && false);
}
- return false;
+
+ } else {
+ // Calculate all line offsets up to "line"
+ assert("Not implemented yet" && false);
+ }
+ return false;
}
-bool
-SourceManager::File::GetLine (uint32_t line_no, std::string &buffer)
-{
- if (!LineIsValid(line_no))
- return false;
+bool SourceManager::File::GetLine(uint32_t line_no, std::string &buffer) {
+ if (!LineIsValid(line_no))
+ return false;
- size_t start_offset = GetLineOffset (line_no);
- size_t end_offset = GetLineOffset (line_no + 1);
- if (end_offset == UINT32_MAX)
- {
- end_offset = m_data_sp->GetByteSize();
- }
- buffer.assign((char *) m_data_sp->GetBytes() + start_offset, end_offset - start_offset);
-
- return true;
-}
+ size_t start_offset = GetLineOffset(line_no);
+ size_t end_offset = GetLineOffset(line_no + 1);
+ if (end_offset == UINT32_MAX) {
+ end_offset = m_data_sp->GetByteSize();
+ }
+ buffer.assign((char *)m_data_sp->GetBytes() + start_offset,
+ end_offset - start_offset);
-void
-SourceManager::SourceFileCache::AddSourceFile (const FileSP &file_sp)
-{
- FileSpec file_spec;
- FileCache::iterator pos = m_file_cache.find(file_spec);
- if (pos == m_file_cache.end())
- m_file_cache[file_spec] = file_sp;
- else
- {
- if (file_sp != pos->second)
- m_file_cache[file_spec] = file_sp;
- }
+ return true;
}
-SourceManager::FileSP
-SourceManager::SourceFileCache::FindSourceFile (const FileSpec &file_spec) const
-{
- FileSP file_sp;
- FileCache::const_iterator pos = m_file_cache.find(file_spec);
- if (pos != m_file_cache.end())
- file_sp = pos->second;
- return file_sp;
+void SourceManager::SourceFileCache::AddSourceFile(const FileSP &file_sp) {
+ FileSpec file_spec;
+ FileCache::iterator pos = m_file_cache.find(file_spec);
+ if (pos == m_file_cache.end())
+ m_file_cache[file_spec] = file_sp;
+ else {
+ if (file_sp != pos->second)
+ m_file_cache[file_spec] = file_sp;
+ }
}
+SourceManager::FileSP SourceManager::SourceFileCache::FindSourceFile(
+ const FileSpec &file_spec) const {
+ FileSP file_sp;
+ FileCache::const_iterator pos = m_file_cache.find(file_spec);
+ if (pos != m_file_cache.end())
+ file_sp = pos->second;
+ return file_sp;
+}
diff --git a/source/Core/State.cpp b/source/Core/State.cpp
index 7d9ccda532a2..80497dd77b87 100644
--- a/source/Core/State.cpp
+++ b/source/Core/State.cpp
@@ -17,99 +17,103 @@
using namespace lldb;
using namespace lldb_private;
-const char *
-lldb_private::StateAsCString (StateType state)
-{
- switch (state)
- {
- case eStateInvalid: return "invalid";
- case eStateUnloaded: return "unloaded";
- case eStateConnected: return "connected";
- case eStateAttaching: return "attaching";
- case eStateLaunching: return "launching";
- case eStateStopped: return "stopped";
- case eStateRunning: return "running";
- case eStateStepping: return "stepping";
- case eStateCrashed: return "crashed";
- case eStateDetached: return "detached";
- case eStateExited: return "exited";
- case eStateSuspended: return "suspended";
- }
- static char unknown_state_string[64];
- snprintf(unknown_state_string, sizeof (unknown_state_string), "StateType = %i", state);
- return unknown_state_string;
+const char *lldb_private::StateAsCString(StateType state) {
+ switch (state) {
+ case eStateInvalid:
+ return "invalid";
+ case eStateUnloaded:
+ return "unloaded";
+ case eStateConnected:
+ return "connected";
+ case eStateAttaching:
+ return "attaching";
+ case eStateLaunching:
+ return "launching";
+ case eStateStopped:
+ return "stopped";
+ case eStateRunning:
+ return "running";
+ case eStateStepping:
+ return "stepping";
+ case eStateCrashed:
+ return "crashed";
+ case eStateDetached:
+ return "detached";
+ case eStateExited:
+ return "exited";
+ case eStateSuspended:
+ return "suspended";
+ }
+ static char unknown_state_string[64];
+ snprintf(unknown_state_string, sizeof(unknown_state_string), "StateType = %i",
+ state);
+ return unknown_state_string;
}
-const char *
-lldb_private::GetPermissionsAsCString (uint32_t permissions)
-{
- switch (permissions)
- {
- case 0: return "---";
- case ePermissionsWritable: return "-w-";
- case ePermissionsReadable: return "r--";
- case ePermissionsExecutable: return "--x";
- case ePermissionsReadable |
- ePermissionsWritable: return "rw-";
- case ePermissionsReadable |
- ePermissionsExecutable: return "r-x";
- case ePermissionsWritable |
- ePermissionsExecutable: return "-wx";
- case ePermissionsReadable |
- ePermissionsWritable |
- ePermissionsExecutable: return "rwx";
- default:
- break;
- }
- return "???";
+const char *lldb_private::GetPermissionsAsCString(uint32_t permissions) {
+ switch (permissions) {
+ case 0:
+ return "---";
+ case ePermissionsWritable:
+ return "-w-";
+ case ePermissionsReadable:
+ return "r--";
+ case ePermissionsExecutable:
+ return "--x";
+ case ePermissionsReadable | ePermissionsWritable:
+ return "rw-";
+ case ePermissionsReadable | ePermissionsExecutable:
+ return "r-x";
+ case ePermissionsWritable | ePermissionsExecutable:
+ return "-wx";
+ case ePermissionsReadable | ePermissionsWritable | ePermissionsExecutable:
+ return "rwx";
+ default:
+ break;
+ }
+ return "???";
}
-bool
-lldb_private::StateIsRunningState (StateType state)
-{
- switch (state)
- {
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- return true;
+bool lldb_private::StateIsRunningState(StateType state) {
+ switch (state) {
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ return true;
- case eStateConnected:
- case eStateDetached:
- case eStateInvalid:
- case eStateUnloaded:
- case eStateStopped:
- case eStateCrashed:
- case eStateExited:
- case eStateSuspended:
- break;
- }
- return false;
+ case eStateConnected:
+ case eStateDetached:
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateExited:
+ case eStateSuspended:
+ break;
+ }
+ return false;
}
-bool
-lldb_private::StateIsStoppedState (StateType state, bool must_exist)
-{
- switch (state)
- {
- case eStateInvalid:
- case eStateConnected:
- case eStateAttaching:
- case eStateLaunching:
- case eStateRunning:
- case eStateStepping:
- case eStateDetached:
- break;
+bool lldb_private::StateIsStoppedState(StateType state, bool must_exist) {
+ switch (state) {
+ case eStateInvalid:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ break;
- case eStateUnloaded:
- case eStateExited:
- return !must_exist;
+ case eStateUnloaded:
+ case eStateExited:
+ return !must_exist;
- case eStateStopped:
- case eStateCrashed:
- case eStateSuspended:
- return true;
- }
- return false;
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateSuspended:
+ return true;
+ }
+ return false;
}
diff --git a/source/Core/Stream.cpp b/source/Core/Stream.cpp
index 15876d558ec5..2f9c650ee5b0 100644
--- a/source/Core/Stream.cpp
+++ b/source/Core/Stream.cpp
@@ -9,778 +9,622 @@
#include "lldb/Core/Stream.h"
#include "lldb/Host/Endian.h"
+#include "lldb/Host/PosixApi.h"
#include <stddef.h>
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include <inttypes.h>
using namespace lldb;
using namespace lldb_private;
-Stream::Stream (uint32_t flags, uint32_t addr_size, ByteOrder byte_order) :
- m_flags (flags),
- m_addr_size (addr_size),
- m_byte_order (byte_order),
- m_indent_level(0)
-{
-}
+Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
+ : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order),
+ m_indent_level(0) {}
-Stream::Stream () :
- m_flags (0),
- m_addr_size (4),
- m_byte_order (endian::InlHostByteOrder()),
- m_indent_level(0)
-{
-}
+Stream::Stream()
+ : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()),
+ m_indent_level(0) {}
//------------------------------------------------------------------
// Destructor
//------------------------------------------------------------------
-Stream::~Stream ()
-{
-}
+Stream::~Stream() {}
-ByteOrder
-Stream::SetByteOrder (ByteOrder byte_order)
-{
- ByteOrder old_byte_order = m_byte_order;
- m_byte_order = byte_order;
- return old_byte_order;
+ByteOrder Stream::SetByteOrder(ByteOrder byte_order) {
+ ByteOrder old_byte_order = m_byte_order;
+ m_byte_order = byte_order;
+ return old_byte_order;
}
//------------------------------------------------------------------
// Put an offset "uval" out to the stream using the printf format
// in "format".
//------------------------------------------------------------------
-void
-Stream::Offset (uint32_t uval, const char *format)
-{
- Printf (format, uval);
-}
+void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); }
//------------------------------------------------------------------
// Put an SLEB128 "uval" out to the stream using the printf format
// in "format".
//------------------------------------------------------------------
-size_t
-Stream::PutSLEB128 (int64_t sval)
-{
- size_t bytes_written = 0;
- if (m_flags.Test(eBinary))
- {
- bool more = true;
- while (more)
- {
- uint8_t byte = sval & 0x7fu;
- sval >>= 7;
- /* sign bit of byte is 2nd high order bit (0x40) */
- if ((sval == 0 && !(byte & 0x40)) ||
- (sval == -1 && (byte & 0x40)) )
- more = false;
- else
- // more bytes to come
- byte |= 0x80u;
- bytes_written += Write(&byte, 1);
- }
- }
- else
- {
- bytes_written = Printf ("0x%" PRIi64, sval);
+size_t Stream::PutSLEB128(int64_t sval) {
+ size_t bytes_written = 0;
+ if (m_flags.Test(eBinary)) {
+ bool more = true;
+ while (more) {
+ uint8_t byte = sval & 0x7fu;
+ sval >>= 7;
+ /* sign bit of byte is 2nd high order bit (0x40) */
+ if ((sval == 0 && !(byte & 0x40)) || (sval == -1 && (byte & 0x40)))
+ more = false;
+ else
+ // more bytes to come
+ byte |= 0x80u;
+ bytes_written += Write(&byte, 1);
}
+ } else {
+ bytes_written = Printf("0x%" PRIi64, sval);
+ }
- return bytes_written;
-
+ return bytes_written;
}
//------------------------------------------------------------------
// Put an ULEB128 "uval" out to the stream using the printf format
// in "format".
//------------------------------------------------------------------
-size_t
-Stream::PutULEB128 (uint64_t uval)
-{
- size_t bytes_written = 0;
- if (m_flags.Test(eBinary))
- {
- do
- {
-
- uint8_t byte = uval & 0x7fu;
- uval >>= 7;
- if (uval != 0)
- {
- // more bytes to come
- byte |= 0x80u;
- }
- bytes_written += Write(&byte, 1);
- } while (uval != 0);
- }
- else
- {
- bytes_written = Printf ("0x%" PRIx64, uval);
- }
- return bytes_written;
+size_t Stream::PutULEB128(uint64_t uval) {
+ size_t bytes_written = 0;
+ if (m_flags.Test(eBinary)) {
+ do {
+
+ uint8_t byte = uval & 0x7fu;
+ uval >>= 7;
+ if (uval != 0) {
+ // more bytes to come
+ byte |= 0x80u;
+ }
+ bytes_written += Write(&byte, 1);
+ } while (uval != 0);
+ } else {
+ bytes_written = Printf("0x%" PRIx64, uval);
+ }
+ return bytes_written;
}
//------------------------------------------------------------------
// Print a raw NULL terminated C string to the stream.
//------------------------------------------------------------------
-size_t
-Stream::PutCString (const char *cstr)
-{
- size_t cstr_len = strlen(cstr);
- // when in binary mode, emit the NULL terminator
- if (m_flags.Test(eBinary))
- ++cstr_len;
- return Write (cstr, cstr_len);
+size_t Stream::PutCString(llvm::StringRef str) {
+ size_t bytes_written = 0;
+ bytes_written = Write(str.data(), str.size());
+
+ // when in binary mode, emit the NULL terminator
+ if (m_flags.Test(eBinary))
+ bytes_written += PutChar('\0');
+ return bytes_written;
}
//------------------------------------------------------------------
// Print a double quoted NULL terminated C string to the stream
// using the printf format in "format".
//------------------------------------------------------------------
-void
-Stream::QuotedCString (const char *cstr, const char *format)
-{
- Printf (format, cstr);
+void Stream::QuotedCString(const char *cstr, const char *format) {
+ Printf(format, cstr);
}
//------------------------------------------------------------------
// Put an address "addr" out to the stream with optional prefix
// and suffix strings.
//------------------------------------------------------------------
-void
-Stream::Address (uint64_t addr, uint32_t addr_size, const char *prefix, const char *suffix)
-{
- if (prefix == NULL)
- prefix = "";
- if (suffix == NULL)
- suffix = "";
-// int addr_width = m_addr_size << 1;
-// Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
- Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
+void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
+ const char *suffix) {
+ if (prefix == NULL)
+ prefix = "";
+ if (suffix == NULL)
+ suffix = "";
+ // int addr_width = m_addr_size << 1;
+ // Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
+ Printf("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
}
//------------------------------------------------------------------
// Put an address range out to the stream with optional prefix
// and suffix strings.
//------------------------------------------------------------------
-void
-Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr, uint32_t addr_size, const char *prefix, const char *suffix)
-{
- if (prefix && prefix[0])
- PutCString (prefix);
- Address (lo_addr, addr_size, "[");
- Address (hi_addr, addr_size, "-", ")");
- if (suffix && suffix[0])
- PutCString (suffix);
-}
-
-
-size_t
-Stream::PutChar (char ch)
-{
- return Write (&ch, 1);
+void Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr,
+ uint32_t addr_size, const char *prefix,
+ const char *suffix) {
+ if (prefix && prefix[0])
+ PutCString(prefix);
+ Address(lo_addr, addr_size, "[");
+ Address(hi_addr, addr_size, "-", ")");
+ if (suffix && suffix[0])
+ PutCString(suffix);
}
+size_t Stream::PutChar(char ch) { return Write(&ch, 1); }
//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
-size_t
-Stream::Printf (const char *format, ...)
-{
- va_list args;
- va_start (args, format);
- size_t result = PrintfVarArg(format, args);
- va_end (args);
- return result;
+size_t Stream::Printf(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ size_t result = PrintfVarArg(format, args);
+ va_end(args);
+ return result;
}
//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
-size_t
-Stream::PrintfVarArg (const char *format, va_list args)
-{
- char str[1024];
- va_list args_copy;
-
- va_copy (args_copy, args);
-
- size_t bytes_written = 0;
- // Try and format our string into a fixed buffer first and see if it fits
- size_t length = ::vsnprintf (str, sizeof(str), format, args);
- if (length < sizeof(str))
- {
- // Include the NULL termination byte for binary output
- if (m_flags.Test(eBinary))
- length += 1;
- // The formatted string fit into our stack based buffer, so we can just
- // append that to our packet
- bytes_written = Write (str, length);
- }
- else
- {
- // Our stack buffer wasn't big enough to contain the entire formatted
- // string, so lets let vasprintf create the string for us!
- char *str_ptr = NULL;
- length = ::vasprintf (&str_ptr, format, args_copy);
- if (str_ptr)
- {
- // Include the NULL termination byte for binary output
- if (m_flags.Test(eBinary))
- length += 1;
- bytes_written = Write (str_ptr, length);
- ::free (str_ptr);
- }
+size_t Stream::PrintfVarArg(const char *format, va_list args) {
+ char str[1024];
+ va_list args_copy;
+
+ va_copy(args_copy, args);
+
+ size_t bytes_written = 0;
+ // Try and format our string into a fixed buffer first and see if it fits
+ size_t length = ::vsnprintf(str, sizeof(str), format, args);
+ if (length < sizeof(str)) {
+ // Include the NULL termination byte for binary output
+ if (m_flags.Test(eBinary))
+ length += 1;
+ // The formatted string fit into our stack based buffer, so we can just
+ // append that to our packet
+ bytes_written = Write(str, length);
+ } else {
+ // Our stack buffer wasn't big enough to contain the entire formatted
+ // string, so lets let vasprintf create the string for us!
+ char *str_ptr = NULL;
+ length = ::vasprintf(&str_ptr, format, args_copy);
+ if (str_ptr) {
+ // Include the NULL termination byte for binary output
+ if (m_flags.Test(eBinary))
+ length += 1;
+ bytes_written = Write(str_ptr, length);
+ ::free(str_ptr);
}
- va_end (args_copy);
- return bytes_written;
+ }
+ va_end(args_copy);
+ return bytes_written;
}
//------------------------------------------------------------------
// Print and End of Line character to the stream
//------------------------------------------------------------------
-size_t
-Stream::EOL()
-{
- return PutChar ('\n');
-}
+size_t Stream::EOL() { return PutChar('\n'); }
//------------------------------------------------------------------
// Indent the current line using the current indentation level and
// print an optional string following the indentation spaces.
//------------------------------------------------------------------
-size_t
-Stream::Indent(const char *s)
-{
- return Printf ("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
+size_t Stream::Indent(const char *s) {
+ return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
+}
+
+size_t Stream::Indent(llvm::StringRef str) {
+ return Printf("%*.*s%s", m_indent_level, m_indent_level, "", str.str().c_str());
}
//------------------------------------------------------------------
// Stream a character "ch" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (char ch)
-{
- PutChar (ch);
- return *this;
+Stream &Stream::operator<<(char ch) {
+ PutChar(ch);
+ return *this;
}
//------------------------------------------------------------------
// Stream the NULL terminated C string out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (const char *s)
-{
- Printf ("%s", s);
- return *this;
+Stream &Stream::operator<<(const char *s) {
+ Printf("%s", s);
+ return *this;
+}
+
+Stream &Stream::operator<<(llvm::StringRef str) {
+ Write(str.data(), str.size());
+ return *this;
}
//------------------------------------------------------------------
// Stream the pointer value out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (const void *p)
-{
- Printf ("0x%.*tx", (int)sizeof(const void*) * 2, (ptrdiff_t)p);
- return *this;
+Stream &Stream::operator<<(const void *p) {
+ Printf("0x%.*tx", (int)sizeof(const void *) * 2, (ptrdiff_t)p);
+ return *this;
}
//------------------------------------------------------------------
// Stream a uint8_t "uval" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (uint8_t uval)
-{
- PutHex8(uval);
- return *this;
+Stream &Stream::operator<<(uint8_t uval) {
+ PutHex8(uval);
+ return *this;
}
//------------------------------------------------------------------
// Stream a uint16_t "uval" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (uint16_t uval)
-{
- PutHex16(uval, m_byte_order);
- return *this;
+Stream &Stream::operator<<(uint16_t uval) {
+ PutHex16(uval, m_byte_order);
+ return *this;
}
//------------------------------------------------------------------
// Stream a uint32_t "uval" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (uint32_t uval)
-{
- PutHex32(uval, m_byte_order);
- return *this;
+Stream &Stream::operator<<(uint32_t uval) {
+ PutHex32(uval, m_byte_order);
+ return *this;
}
//------------------------------------------------------------------
// Stream a uint64_t "uval" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (uint64_t uval)
-{
- PutHex64(uval, m_byte_order);
- return *this;
+Stream &Stream::operator<<(uint64_t uval) {
+ PutHex64(uval, m_byte_order);
+ return *this;
}
//------------------------------------------------------------------
// Stream a int8_t "sval" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (int8_t sval)
-{
- Printf ("%i", (int)sval);
- return *this;
+Stream &Stream::operator<<(int8_t sval) {
+ Printf("%i", (int)sval);
+ return *this;
}
//------------------------------------------------------------------
// Stream a int16_t "sval" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (int16_t sval)
-{
- Printf ("%i", (int)sval);
- return *this;
+Stream &Stream::operator<<(int16_t sval) {
+ Printf("%i", (int)sval);
+ return *this;
}
//------------------------------------------------------------------
// Stream a int32_t "sval" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (int32_t sval)
-{
- Printf ("%i", (int)sval);
- return *this;
+Stream &Stream::operator<<(int32_t sval) {
+ Printf("%i", (int)sval);
+ return *this;
}
//------------------------------------------------------------------
// Stream a int64_t "sval" out to this stream.
//------------------------------------------------------------------
-Stream&
-Stream::operator<< (int64_t sval)
-{
- Printf ("%" PRIi64, sval);
- return *this;
+Stream &Stream::operator<<(int64_t sval) {
+ Printf("%" PRIi64, sval);
+ return *this;
}
//------------------------------------------------------------------
// Get the current indentation level
//------------------------------------------------------------------
-int
-Stream::GetIndentLevel() const
-{
- return m_indent_level;
-}
+int Stream::GetIndentLevel() const { return m_indent_level; }
//------------------------------------------------------------------
// Set the current indentation level
//------------------------------------------------------------------
-void
-Stream::SetIndentLevel(int indent_level)
-{
- m_indent_level = indent_level;
-}
+void Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; }
//------------------------------------------------------------------
// Increment the current indentation level
//------------------------------------------------------------------
-void
-Stream::IndentMore(int amount)
-{
- m_indent_level += amount;
-}
+void Stream::IndentMore(int amount) { m_indent_level += amount; }
//------------------------------------------------------------------
// Decrement the current indentation level
//------------------------------------------------------------------
-void
-Stream::IndentLess (int amount)
-{
- if (m_indent_level >= amount)
- m_indent_level -= amount;
- else
- m_indent_level = 0;
+void Stream::IndentLess(int amount) {
+ if (m_indent_level >= amount)
+ m_indent_level -= amount;
+ else
+ m_indent_level = 0;
}
//------------------------------------------------------------------
// Get the address size in bytes
//------------------------------------------------------------------
-uint32_t
-Stream::GetAddressByteSize() const
-{
- return m_addr_size;
-}
+uint32_t Stream::GetAddressByteSize() const { return m_addr_size; }
//------------------------------------------------------------------
// Set the address size in bytes
//------------------------------------------------------------------
-void
-Stream::SetAddressByteSize(uint32_t addr_size)
-{
- m_addr_size = addr_size;
-}
+void Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; }
//------------------------------------------------------------------
// Returns true if the verbose flag bit is set in this stream.
//------------------------------------------------------------------
-bool
-Stream::GetVerbose() const
-{
- return m_flags.Test(eVerbose);
-}
+bool Stream::GetVerbose() const { return m_flags.Test(eVerbose); }
//------------------------------------------------------------------
// Returns true if the debug flag bit is set in this stream.
//------------------------------------------------------------------
-bool
-Stream::GetDebug() const
-{
- return m_flags.Test(eDebug);
-}
+bool Stream::GetDebug() const { return m_flags.Test(eDebug); }
//------------------------------------------------------------------
// The flags get accessor
//------------------------------------------------------------------
-Flags&
-Stream::GetFlags()
-{
- return m_flags;
-}
+Flags &Stream::GetFlags() { return m_flags; }
//------------------------------------------------------------------
// The flags const get accessor
//------------------------------------------------------------------
-const Flags&
-Stream::GetFlags() const
-{
- return m_flags;
-}
+const Flags &Stream::GetFlags() const { return m_flags; }
//------------------------------------------------------------------
// The byte order get accessor
//------------------------------------------------------------------
-lldb::ByteOrder
-Stream::GetByteOrder() const
-{
- return m_byte_order;
-}
-
-size_t
-Stream::PrintfAsRawHex8 (const char *format, ...)
-{
- va_list args;
- va_list args_copy;
- va_start (args, format);
- va_copy (args_copy,args); // Copy this so we
-
- char str[1024];
- size_t bytes_written = 0;
- // Try and format our string into a fixed buffer first and see if it fits
- size_t length = ::vsnprintf (str, sizeof(str), format, args);
- if (length < sizeof(str))
- {
- // The formatted string fit into our stack based buffer, so we can just
- // append that to our packet
- for (size_t i=0; i<length; ++i)
- bytes_written += _PutHex8 (str[i], false);
- }
- else
- {
- // Our stack buffer wasn't big enough to contain the entire formatted
- // string, so lets let vasprintf create the string for us!
- char *str_ptr = NULL;
- length = ::vasprintf (&str_ptr, format, args_copy);
- if (str_ptr)
- {
- for (size_t i=0; i<length; ++i)
- bytes_written += _PutHex8 (str_ptr[i], false);
- ::free (str_ptr);
- }
- }
- va_end (args);
- va_end (args_copy);
-
- return bytes_written;
-}
-
-size_t
-Stream::PutNHex8 (size_t n, uint8_t uvalue)
-{
- size_t bytes_written = 0;
- for (size_t i=0; i<n; ++i)
- bytes_written += _PutHex8 (uvalue, m_flags.Test(eAddPrefix));
- return bytes_written;
-}
-
-size_t
-Stream::_PutHex8 (uint8_t uvalue, bool add_prefix)
-{
- size_t bytes_written = 0;
- if (m_flags.Test(eBinary))
- {
- bytes_written = Write (&uvalue, 1);
- }
- else
- {
- if (add_prefix)
- PutCString("0x");
-
- static char g_hex_to_ascii_hex_char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- char nibble_chars[2];
- nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
- nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
- bytes_written = Write (nibble_chars, sizeof(nibble_chars));
- }
- return bytes_written;
-}
-
-size_t
-Stream::PutHex8 (uint8_t uvalue)
-{
- return _PutHex8 (uvalue, m_flags.Test(eAddPrefix));
-}
-
-size_t
-Stream::PutHex16 (uint16_t uvalue, ByteOrder byte_order)
-{
- if (byte_order == eByteOrderInvalid)
- byte_order = m_byte_order;
-
- bool add_prefix = m_flags.Test(eAddPrefix);
- size_t bytes_written = 0;
- if (byte_order == eByteOrderLittle)
- {
- for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
- bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
+lldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; }
+
+size_t Stream::PrintfAsRawHex8(const char *format, ...) {
+ va_list args;
+ va_list args_copy;
+ va_start(args, format);
+ va_copy(args_copy, args); // Copy this so we
+
+ char str[1024];
+ size_t bytes_written = 0;
+ // Try and format our string into a fixed buffer first and see if it fits
+ size_t length = ::vsnprintf(str, sizeof(str), format, args);
+ if (length < sizeof(str)) {
+ // The formatted string fit into our stack based buffer, so we can just
+ // append that to our packet
+ for (size_t i = 0; i < length; ++i)
+ bytes_written += _PutHex8(str[i], false);
+ } else {
+ // Our stack buffer wasn't big enough to contain the entire formatted
+ // string, so lets let vasprintf create the string for us!
+ char *str_ptr = NULL;
+ length = ::vasprintf(&str_ptr, format, args_copy);
+ if (str_ptr) {
+ for (size_t i = 0; i < length; ++i)
+ bytes_written += _PutHex8(str_ptr[i], false);
+ ::free(str_ptr);
}
- else
- {
- for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
- bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
- }
- return bytes_written;
-}
-
-size_t
-Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order)
-{
- if (byte_order == eByteOrderInvalid)
- byte_order = m_byte_order;
+ }
+ va_end(args);
+ va_end(args_copy);
+
+ return bytes_written;
+}
+
+size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
+ size_t bytes_written = 0;
+ for (size_t i = 0; i < n; ++i)
+ bytes_written += _PutHex8(uvalue, m_flags.Test(eAddPrefix));
+ return bytes_written;
+}
+
+size_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
+ size_t bytes_written = 0;
+ if (m_flags.Test(eBinary)) {
+ bytes_written = Write(&uvalue, 1);
+ } else {
+ if (add_prefix)
+ PutCString("0x");
+
+ static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5',
+ '6', '7', '8', '9', 'a', 'b',
+ 'c', 'd', 'e', 'f'};
+ char nibble_chars[2];
+ nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
+ nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
+ bytes_written = Write(nibble_chars, sizeof(nibble_chars));
+ }
+ return bytes_written;
+}
+
+size_t Stream::PutHex8(uint8_t uvalue) {
+ return _PutHex8(uvalue, m_flags.Test(eAddPrefix));
+}
- bool add_prefix = m_flags.Test(eAddPrefix);
- size_t bytes_written = 0;
- if (byte_order == eByteOrderLittle)
- {
- for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
- bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
- }
- else
- {
- for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
- bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
- }
- return bytes_written;
-}
-
-size_t
-Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order)
-{
- if (byte_order == eByteOrderInvalid)
- byte_order = m_byte_order;
-
- bool add_prefix = m_flags.Test(eAddPrefix);
- size_t bytes_written = 0;
- if (byte_order == eByteOrderLittle)
- {
- for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
- bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
- }
- else
- {
- for (size_t byte = sizeof(uvalue)-1; byte < sizeof(uvalue); --byte, add_prefix = false)
- bytes_written += _PutHex8 ((uint8_t)(uvalue >> (byte * 8)), add_prefix);
- }
- return bytes_written;
-}
-
-size_t
-Stream::PutMaxHex64
-(
- uint64_t uvalue,
- size_t byte_size,
- lldb::ByteOrder byte_order
-)
-{
- switch (byte_size)
- {
- case 1: return PutHex8 ((uint8_t)uvalue);
- case 2: return PutHex16 ((uint16_t)uvalue);
- case 4: return PutHex32 ((uint32_t)uvalue);
- case 8: return PutHex64 (uvalue);
- }
- return 0;
-}
-
-size_t
-Stream::PutPointer (void *ptr)
-{
- return PutRawBytes (&ptr, sizeof(ptr), endian::InlHostByteOrder(), endian::InlHostByteOrder());
-}
-
-size_t
-Stream::PutFloat(float f, ByteOrder byte_order)
-{
- if (byte_order == eByteOrderInvalid)
- byte_order = m_byte_order;
-
- return PutRawBytes (&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
-}
-
-size_t
-Stream::PutDouble(double d, ByteOrder byte_order)
-{
- if (byte_order == eByteOrderInvalid)
- byte_order = m_byte_order;
-
- return PutRawBytes (&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
-}
-
-size_t
-Stream::PutLongDouble(long double ld, ByteOrder byte_order)
-{
- if (byte_order == eByteOrderInvalid)
- byte_order = m_byte_order;
-
- return PutRawBytes (&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
-}
-
-size_t
-Stream::PutRawBytes (const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order)
-{
- if (src_byte_order == eByteOrderInvalid)
- src_byte_order = m_byte_order;
-
- if (dst_byte_order == eByteOrderInvalid)
- dst_byte_order = m_byte_order;
-
- size_t bytes_written = 0;
- const uint8_t *src = (const uint8_t *)s;
- bool binary_was_set = m_flags.Test (eBinary);
- if (!binary_was_set)
- m_flags.Set (eBinary);
- if (src_byte_order == dst_byte_order)
- {
- for (size_t i = 0; i < src_len; ++i)
- bytes_written += _PutHex8 (src[i], false);
- }
- else
- {
- for (size_t i = src_len-1; i < src_len; --i)
- bytes_written += _PutHex8 (src[i], false);
- }
- if (!binary_was_set)
- m_flags.Clear (eBinary);
-
- return bytes_written;
-}
-
-size_t
-Stream::PutBytesAsRawHex8 (const void *s, size_t src_len, ByteOrder src_byte_order, ByteOrder dst_byte_order)
-{
- if (src_byte_order == eByteOrderInvalid)
- src_byte_order = m_byte_order;
-
- if (dst_byte_order == eByteOrderInvalid)
- dst_byte_order = m_byte_order;
-
- size_t bytes_written = 0;
- const uint8_t *src = (const uint8_t *)s;
- bool binary_is_set = m_flags.Test(eBinary);
+size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
+ if (byte_order == eByteOrderInvalid)
+ byte_order = m_byte_order;
+
+ bool add_prefix = m_flags.Test(eAddPrefix);
+ size_t bytes_written = 0;
+ if (byte_order == eByteOrderLittle) {
+ for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
+ bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
+ } else {
+ for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
+ --byte, add_prefix = false)
+ bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
+ }
+ return bytes_written;
+}
+
+size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
+ if (byte_order == eByteOrderInvalid)
+ byte_order = m_byte_order;
+
+ bool add_prefix = m_flags.Test(eAddPrefix);
+ size_t bytes_written = 0;
+ if (byte_order == eByteOrderLittle) {
+ for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
+ bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
+ } else {
+ for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
+ --byte, add_prefix = false)
+ bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
+ }
+ return bytes_written;
+}
+
+size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
+ if (byte_order == eByteOrderInvalid)
+ byte_order = m_byte_order;
+
+ bool add_prefix = m_flags.Test(eAddPrefix);
+ size_t bytes_written = 0;
+ if (byte_order == eByteOrderLittle) {
+ for (size_t byte = 0; byte < sizeof(uvalue); ++byte, add_prefix = false)
+ bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
+ } else {
+ for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue);
+ --byte, add_prefix = false)
+ bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), add_prefix);
+ }
+ return bytes_written;
+}
+
+size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
+ lldb::ByteOrder byte_order) {
+ switch (byte_size) {
+ case 1:
+ return PutHex8((uint8_t)uvalue);
+ case 2:
+ return PutHex16((uint16_t)uvalue);
+ case 4:
+ return PutHex32((uint32_t)uvalue);
+ case 8:
+ return PutHex64(uvalue);
+ }
+ return 0;
+}
+
+size_t Stream::PutPointer(void *ptr) {
+ return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(),
+ endian::InlHostByteOrder());
+}
+
+size_t Stream::PutFloat(float f, ByteOrder byte_order) {
+ if (byte_order == eByteOrderInvalid)
+ byte_order = m_byte_order;
+
+ return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
+}
+
+size_t Stream::PutDouble(double d, ByteOrder byte_order) {
+ if (byte_order == eByteOrderInvalid)
+ byte_order = m_byte_order;
+
+ return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
+}
+
+size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
+ if (byte_order == eByteOrderInvalid)
+ byte_order = m_byte_order;
+
+ return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
+}
+
+size_t Stream::PutRawBytes(const void *s, size_t src_len,
+ ByteOrder src_byte_order, ByteOrder dst_byte_order) {
+ if (src_byte_order == eByteOrderInvalid)
+ src_byte_order = m_byte_order;
+
+ if (dst_byte_order == eByteOrderInvalid)
+ dst_byte_order = m_byte_order;
+
+ size_t bytes_written = 0;
+ const uint8_t *src = (const uint8_t *)s;
+ bool binary_was_set = m_flags.Test(eBinary);
+ if (!binary_was_set)
+ m_flags.Set(eBinary);
+ if (src_byte_order == dst_byte_order) {
+ for (size_t i = 0; i < src_len; ++i)
+ bytes_written += _PutHex8(src[i], false);
+ } else {
+ for (size_t i = src_len - 1; i < src_len; --i)
+ bytes_written += _PutHex8(src[i], false);
+ }
+ if (!binary_was_set)
m_flags.Clear(eBinary);
- if (src_byte_order == dst_byte_order)
- {
- for (size_t i = 0; i < src_len; ++i)
- bytes_written += _PutHex8 (src[i], false);
- }
- else
- {
- for (size_t i = src_len-1; i < src_len; --i)
- bytes_written += _PutHex8 (src[i], false);
- }
- if (binary_is_set)
- m_flags.Set(eBinary);
- return bytes_written;
+ return bytes_written;
+}
+
+size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
+ ByteOrder src_byte_order,
+ ByteOrder dst_byte_order) {
+ if (src_byte_order == eByteOrderInvalid)
+ src_byte_order = m_byte_order;
+
+ if (dst_byte_order == eByteOrderInvalid)
+ dst_byte_order = m_byte_order;
+
+ size_t bytes_written = 0;
+ const uint8_t *src = (const uint8_t *)s;
+ bool binary_is_set = m_flags.Test(eBinary);
+ m_flags.Clear(eBinary);
+ if (src_byte_order == dst_byte_order) {
+ for (size_t i = 0; i < src_len; ++i)
+ bytes_written += _PutHex8(src[i], false);
+ } else {
+ for (size_t i = src_len - 1; i < src_len; --i)
+ bytes_written += _PutHex8(src[i], false);
+ }
+ if (binary_is_set)
+ m_flags.Set(eBinary);
+
+ return bytes_written;
+}
+
+size_t Stream::PutCStringAsRawHex8(const char *s) {
+ size_t bytes_written = 0;
+ bool binary_is_set = m_flags.Test(eBinary);
+ m_flags.Clear(eBinary);
+ do {
+ bytes_written += _PutHex8(*s, false);
+ ++s;
+ } while (*s);
+ if (binary_is_set)
+ m_flags.Set(eBinary);
+ return bytes_written;
+}
+
+void Stream::UnitTest(Stream *s) {
+ s->PutHex8(0x12);
+
+ s->PutChar(' ');
+ s->PutHex16(0x3456, endian::InlHostByteOrder());
+ s->PutChar(' ');
+ s->PutHex16(0x3456, eByteOrderBig);
+ s->PutChar(' ');
+ s->PutHex16(0x3456, eByteOrderLittle);
+
+ s->PutChar(' ');
+ s->PutHex32(0x789abcde, endian::InlHostByteOrder());
+ s->PutChar(' ');
+ s->PutHex32(0x789abcde, eByteOrderBig);
+ s->PutChar(' ');
+ s->PutHex32(0x789abcde, eByteOrderLittle);
+
+ s->PutChar(' ');
+ s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder());
+ s->PutChar(' ');
+ s->PutHex64(0x1122334455667788ull, eByteOrderBig);
+ s->PutChar(' ');
+ s->PutHex64(0x1122334455667788ull, eByteOrderLittle);
+
+ const char *hola = "Hello World!!!";
+ s->PutChar(' ');
+ s->PutCString(hola);
+
+ s->PutChar(' ');
+ s->Write(hola, 5);
+
+ s->PutChar(' ');
+ s->PutCStringAsRawHex8(hola);
+
+ s->PutChar(' ');
+ s->PutCStringAsRawHex8("01234");
+
+ s->PutChar(' ');
+ s->Printf("pid=%i", 12733);
+
+ s->PutChar(' ');
+ s->PrintfAsRawHex8("pid=%i", 12733);
+ s->PutChar('\n');
}
-
-size_t
-Stream::PutCStringAsRawHex8 (const char *s)
-{
- size_t bytes_written = 0;
- bool binary_is_set = m_flags.Test(eBinary);
- m_flags.Clear(eBinary);
- do
- {
- bytes_written += _PutHex8 (*s, false);
- ++s;
- } while (*s);
- if (binary_is_set)
- m_flags.Set(eBinary);
- return bytes_written;
-}
-
-void
-Stream::UnitTest(Stream *s)
-{
- s->PutHex8(0x12);
-
- s->PutChar(' ');
- s->PutHex16(0x3456, endian::InlHostByteOrder());
- s->PutChar(' ');
- s->PutHex16(0x3456, eByteOrderBig);
- s->PutChar(' ');
- s->PutHex16(0x3456, eByteOrderLittle);
-
- s->PutChar(' ');
- s->PutHex32(0x789abcde, endian::InlHostByteOrder());
- s->PutChar(' ');
- s->PutHex32(0x789abcde, eByteOrderBig);
- s->PutChar(' ');
- s->PutHex32(0x789abcde, eByteOrderLittle);
-
- s->PutChar(' ');
- s->PutHex64(0x1122334455667788ull, endian::InlHostByteOrder());
- s->PutChar(' ');
- s->PutHex64(0x1122334455667788ull, eByteOrderBig);
- s->PutChar(' ');
- s->PutHex64(0x1122334455667788ull, eByteOrderLittle);
-
- const char *hola = "Hello World!!!";
- s->PutChar(' ');
- s->PutCString (hola);
-
- s->PutChar(' ');
- s->Write (hola, 5);
-
- s->PutChar(' ');
- s->PutCStringAsRawHex8 (hola);
-
- s->PutChar(' ');
- s->PutCStringAsRawHex8 ("01234");
-
- s->PutChar(' ');
- s->Printf ("pid=%i", 12733);
-
- s->PutChar(' ');
- s->PrintfAsRawHex8 ("pid=%i", 12733);
- s->PutChar('\n');
-}
-
diff --git a/source/Core/StreamAsynchronousIO.cpp b/source/Core/StreamAsynchronousIO.cpp
index 6f8fcce932e7..1f7e634dfe33 100644
--- a/source/Core/StreamAsynchronousIO.cpp
+++ b/source/Core/StreamAsynchronousIO.cpp
@@ -1,4 +1,4 @@
-//===-- StreamBroadcast.cpp -------------------------------------*- C++ -*-===//
+//===-- StreamAsynchronousIO.cpp --------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,40 +9,29 @@
#include "lldb/Core/StreamAsynchronousIO.h"
-#include "lldb/lldb-private.h"
#include "lldb/Core/Debugger.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
+StreamAsynchronousIO::StreamAsynchronousIO(Debugger &debugger, bool for_stdout)
+ : Stream(0, 4, eByteOrderBig), m_debugger(debugger), m_data(),
+ m_for_stdout(for_stdout) {}
-StreamAsynchronousIO::StreamAsynchronousIO (Debugger &debugger, bool for_stdout) :
- Stream (0, 4, eByteOrderBig),
- m_debugger (debugger),
- m_data (),
- m_for_stdout (for_stdout)
-{
-}
-
-StreamAsynchronousIO::~StreamAsynchronousIO ()
-{
- // Flush when we destroy to make sure we display the data
- Flush();
+StreamAsynchronousIO::~StreamAsynchronousIO() {
+ // Flush when we destroy to make sure we display the data
+ Flush();
}
-void
-StreamAsynchronousIO::Flush ()
-{
- if (!m_data.empty())
- {
- m_debugger.PrintAsync (m_data.data(), m_data.size(), m_for_stdout);
- m_data = std::string();
- }
+void StreamAsynchronousIO::Flush() {
+ if (!m_data.empty()) {
+ m_debugger.PrintAsync(m_data.data(), m_data.size(), m_for_stdout);
+ m_data = std::string();
+ }
}
-size_t
-StreamAsynchronousIO::Write (const void *s, size_t length)
-{
- m_data.append ((const char *)s, length);
- return length;
+size_t StreamAsynchronousIO::Write(const void *s, size_t length) {
+ m_data.append((const char *)s, length);
+ return length;
}
diff --git a/source/Core/StreamCallback.cpp b/source/Core/StreamCallback.cpp
index 9f0adee2a159..de784101e969 100644
--- a/source/Core/StreamCallback.cpp
+++ b/source/Core/StreamCallback.cpp
@@ -9,51 +9,42 @@
#include <stdio.h>
-#include "lldb/lldb-private.h"
#include "lldb/Core/Broadcaster.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/StreamCallback.h"
#include "lldb/Host/Host.h"
+#include "lldb/lldb-private.h"
using namespace lldb;
using namespace lldb_private;
StreamCallback::StreamCallback(lldb::LogOutputCallback callback, void *baton)
- : Stream(0, 4, eByteOrderBig), m_callback(callback), m_baton(baton), m_accumulated_data(), m_collection_mutex()
-{
-}
-
-StreamCallback::~StreamCallback ()
-{
-}
-
-StreamString &
-StreamCallback::FindStreamForThread(lldb::tid_t cur_tid)
-{
- std::lock_guard<std::mutex> guard(m_collection_mutex);
- collection::iterator iter = m_accumulated_data.find (cur_tid);
- if (iter == m_accumulated_data.end())
- {
- std::pair<collection::iterator, bool> ret;
- ret = m_accumulated_data.insert(std::pair<lldb::tid_t,StreamString>(cur_tid, StreamString()));
- iter = ret.first;
- }
- return (*iter).second;
+ : Stream(0, 4, eByteOrderBig), m_callback(callback), m_baton(baton),
+ m_accumulated_data(), m_collection_mutex() {}
+
+StreamCallback::~StreamCallback() {}
+
+StreamString &StreamCallback::FindStreamForThread(lldb::tid_t cur_tid) {
+ std::lock_guard<std::mutex> guard(m_collection_mutex);
+ collection::iterator iter = m_accumulated_data.find(cur_tid);
+ if (iter == m_accumulated_data.end()) {
+ std::pair<collection::iterator, bool> ret;
+ ret = m_accumulated_data.insert(
+ std::pair<lldb::tid_t, StreamString>(cur_tid, StreamString()));
+ iter = ret.first;
+ }
+ return (*iter).second;
}
-void
-StreamCallback::Flush ()
-{
- lldb::tid_t cur_tid = Host::GetCurrentThreadID();
- StreamString &out_stream = FindStreamForThread(cur_tid);
- m_callback (out_stream.GetData(), m_baton);
- out_stream.Clear();
+void StreamCallback::Flush() {
+ lldb::tid_t cur_tid = Host::GetCurrentThreadID();
+ StreamString &out_stream = FindStreamForThread(cur_tid);
+ m_callback(out_stream.GetData(), m_baton);
+ out_stream.Clear();
}
-size_t
-StreamCallback::Write (const void *s, size_t length)
-{
- lldb::tid_t cur_tid = Host::GetCurrentThreadID();
- FindStreamForThread(cur_tid).Write (s, length);
- return length;
+size_t StreamCallback::Write(const void *s, size_t length) {
+ lldb::tid_t cur_tid = Host::GetCurrentThreadID();
+ FindStreamForThread(cur_tid).Write(s, length);
+ return length;
}
diff --git a/source/Core/StreamFile.cpp b/source/Core/StreamFile.cpp
index 8c9700c6dcba..f8c7fb9a84dc 100644
--- a/source/Core/StreamFile.cpp
+++ b/source/Core/StreamFile.cpp
@@ -16,65 +16,37 @@
// Project includes
#include "lldb/Core/Error.h"
-
using namespace lldb;
using namespace lldb_private;
//----------------------------------------------------------------------
// StreamFile constructor
//----------------------------------------------------------------------
-StreamFile::StreamFile () :
- Stream (),
- m_file ()
-{
-}
+StreamFile::StreamFile() : Stream(), m_file() {}
-StreamFile::StreamFile (uint32_t flags, uint32_t addr_size, ByteOrder byte_order) :
- Stream (flags, addr_size, byte_order),
- m_file ()
-{
-}
+StreamFile::StreamFile(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
+ : Stream(flags, addr_size, byte_order), m_file() {}
-StreamFile::StreamFile (int fd, bool transfer_ownership) :
- Stream (),
- m_file (fd, transfer_ownership)
-{
-}
+StreamFile::StreamFile(int fd, bool transfer_ownership)
+ : Stream(), m_file(fd, transfer_ownership) {}
-StreamFile::StreamFile (FILE *fh, bool transfer_ownership) :
- Stream (),
- m_file (fh, transfer_ownership)
-{
-}
+StreamFile::StreamFile(FILE *fh, bool transfer_ownership)
+ : Stream(), m_file(fh, transfer_ownership) {}
-StreamFile::StreamFile (const char *path) :
- Stream (),
- m_file (path, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec,
- lldb::eFilePermissionsFileDefault)
-{
-}
+StreamFile::StreamFile(const char *path)
+ : Stream(),
+ m_file(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionCloseOnExec,
+ lldb::eFilePermissionsFileDefault) {}
-StreamFile::StreamFile (const char *path,
- uint32_t options,
- uint32_t permissions) :
- Stream(),
- m_file(path, options, permissions)
-{
-}
+StreamFile::StreamFile(const char *path, uint32_t options, uint32_t permissions)
+ : Stream(), m_file(path, options, permissions) {}
-StreamFile::~StreamFile()
-{
-}
+StreamFile::~StreamFile() {}
-void
-StreamFile::Flush ()
-{
- m_file.Flush();
-}
+void StreamFile::Flush() { m_file.Flush(); }
-size_t
-StreamFile::Write (const void *s, size_t length)
-{
- m_file.Write (s, length);
- return length;
+size_t StreamFile::Write(const void *s, size_t length) {
+ m_file.Write(s, length);
+ return length;
}
diff --git a/source/Core/StreamGDBRemote.cpp b/source/Core/StreamGDBRemote.cpp
index 46cb99ce98a5..a371d1316c7c 100644
--- a/source/Core/StreamGDBRemote.cpp
+++ b/source/Core/StreamGDBRemote.cpp
@@ -13,42 +13,30 @@
using namespace lldb;
using namespace lldb_private;
-StreamGDBRemote::StreamGDBRemote () :
-StreamString ()
-{
+StreamGDBRemote::StreamGDBRemote() : StreamString() {}
+
+StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size,
+ ByteOrder byte_order)
+ : StreamString(flags, addr_size, byte_order) {}
+
+StreamGDBRemote::~StreamGDBRemote() {}
+
+int StreamGDBRemote::PutEscapedBytes(const void *s, size_t src_len) {
+ int bytes_written = 0;
+ const uint8_t *src = (const uint8_t *)s;
+ bool binary_is_set = m_flags.Test(eBinary);
+ m_flags.Clear(eBinary);
+ while (src_len) {
+ uint8_t byte = *src;
+ src++;
+ src_len--;
+ if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a) {
+ bytes_written += PutChar(0x7d);
+ byte ^= 0x20;
+ }
+ bytes_written += PutChar(byte);
+ };
+ if (binary_is_set)
+ m_flags.Set(eBinary);
+ return bytes_written;
}
-
-StreamGDBRemote::StreamGDBRemote(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) :
-StreamString (flags, addr_size, byte_order)
-{
-}
-
-StreamGDBRemote::~StreamGDBRemote()
-{
-}
-
-
-int
-StreamGDBRemote::PutEscapedBytes (const void* s,
- size_t src_len)
-{
- int bytes_written = 0;
- const uint8_t *src = (const uint8_t *)s;
- bool binary_is_set = m_flags.Test(eBinary);
- m_flags.Clear(eBinary);
- while (src_len)
- {
- uint8_t byte = *src;
- src++; src_len--;
- if (byte == 0x23 || byte == 0x24 || byte == 0x7d || byte == 0x2a)
- {
- bytes_written += PutChar(0x7d);
- byte ^= 0x20;
- }
- bytes_written += PutChar(byte);
- };
- if (binary_is_set)
- m_flags.Set(eBinary);
- return bytes_written;
-}
-
diff --git a/source/Core/StreamString.cpp b/source/Core/StreamString.cpp
index 36e086b0b433..461648815f18 100644
--- a/source/Core/StreamString.cpp
+++ b/source/Core/StreamString.cpp
@@ -13,104 +13,53 @@
using namespace lldb;
using namespace lldb_private;
-StreamString::StreamString () :
- Stream (0, 4, eByteOrderBig)
-{
-}
+StreamString::StreamString() : Stream(0, 4, eByteOrderBig) {}
-StreamString::StreamString(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) :
- Stream (flags, addr_size, byte_order),
- m_packet ()
-{
-}
+StreamString::StreamString(uint32_t flags, uint32_t addr_size,
+ ByteOrder byte_order)
+ : Stream(flags, addr_size, byte_order), m_packet() {}
-StreamString::~StreamString()
-{
-}
+StreamString::~StreamString() {}
-void
-StreamString::Flush ()
-{
- // Nothing to do when flushing a buffer based stream...
+void StreamString::Flush() {
+ // Nothing to do when flushing a buffer based stream...
}
-size_t
-StreamString::Write (const void *s, size_t length)
-{
- m_packet.append (reinterpret_cast<const char *>(s), length);
- return length;
+size_t StreamString::Write(const void *s, size_t length) {
+ m_packet.append(reinterpret_cast<const char *>(s), length);
+ return length;
}
-void
-StreamString::Clear()
-{
- m_packet.clear();
-}
+void StreamString::Clear() { m_packet.clear(); }
-bool
-StreamString::Empty() const
-{
- return GetSize() == 0;
-}
+bool StreamString::Empty() const { return GetSize() == 0; }
-const char *
-StreamString::GetData () const
-{
- return m_packet.c_str();
-}
+size_t StreamString::GetSize() const { return m_packet.size(); }
-size_t
-StreamString::GetSize () const
-{
- return m_packet.size();
-}
-
-size_t
-StreamString::GetSizeOfLastLine () const
-{
- const size_t length = m_packet.size();
- size_t last_line_begin_pos = m_packet.find_last_of("\r\n");
- if (last_line_begin_pos == std::string::npos)
- {
- return length;
- }
- else
- {
- ++last_line_begin_pos;
- return length - last_line_begin_pos;
- }
-}
-
-std::string &
-StreamString::GetString()
-{
- return m_packet;
-}
-
-const std::string &
-StreamString::GetString() const
-{
- return m_packet;
+size_t StreamString::GetSizeOfLastLine() const {
+ const size_t length = m_packet.size();
+ size_t last_line_begin_pos = m_packet.find_last_of("\r\n");
+ if (last_line_begin_pos == std::string::npos) {
+ return length;
+ } else {
+ ++last_line_begin_pos;
+ return length - last_line_begin_pos;
+ }
}
-void
-StreamString::FillLastLineToColumn (uint32_t column, char fill_char)
-{
- const size_t length = m_packet.size();
- size_t last_line_begin_pos = m_packet.find_last_of("\r\n");
- if (last_line_begin_pos == std::string::npos)
- {
- last_line_begin_pos = 0;
- }
- else
- {
- ++last_line_begin_pos;
- }
-
- const size_t line_columns = length - last_line_begin_pos;
- if (column > line_columns)
- {
- m_packet.append(column - line_columns, fill_char);
- }
+llvm::StringRef StreamString::GetString() const { return m_packet; }
+
+void StreamString::FillLastLineToColumn(uint32_t column, char fill_char) {
+ const size_t length = m_packet.size();
+ size_t last_line_begin_pos = m_packet.find_last_of("\r\n");
+ if (last_line_begin_pos == std::string::npos) {
+ last_line_begin_pos = 0;
+ } else {
+ ++last_line_begin_pos;
+ }
+
+ const size_t line_columns = length - last_line_begin_pos;
+ if (column > line_columns) {
+ m_packet.append(column - line_columns, fill_char);
+ }
}
-
diff --git a/source/Core/StringList.cpp b/source/Core/StringList.cpp
index 98a079007fba..d2c4ac6775aa 100644
--- a/source/Core/StringList.cpp
+++ b/source/Core/StringList.cpp
@@ -9,369 +9,263 @@
#include "lldb/Core/StringList.h"
+#include "lldb/Core/Log.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Host/FileSpec.h"
-#include "lldb/Core/Log.h"
#include <string>
using namespace lldb_private;
-StringList::StringList () :
- m_strings ()
-{
-}
+StringList::StringList() : m_strings() {}
-StringList::StringList (const char *str) :
- m_strings ()
-{
- if (str)
- m_strings.push_back (str);
+StringList::StringList(const char *str) : m_strings() {
+ if (str)
+ m_strings.push_back(str);
}
-StringList::StringList (const char **strv, int strc) :
- m_strings ()
-{
- for (int i = 0; i < strc; ++i)
- {
- if (strv[i])
- m_strings.push_back (strv[i]);
- }
+StringList::StringList(const char **strv, int strc) : m_strings() {
+ for (int i = 0; i < strc; ++i) {
+ if (strv[i])
+ m_strings.push_back(strv[i]);
+ }
}
-StringList::~StringList ()
-{
-}
+StringList::~StringList() {}
-void
-StringList::AppendString (const char *str)
-{
- if (str)
- m_strings.push_back (str);
+void StringList::AppendString(const char *str) {
+ if (str)
+ m_strings.push_back(str);
}
-void
-StringList::AppendString (const std::string &s)
-{
- m_strings.push_back (s);
-}
+void StringList::AppendString(const std::string &s) { m_strings.push_back(s); }
-void
-StringList::AppendString (std::string &&s)
-{
- m_strings.push_back (s);
-}
+void StringList::AppendString(std::string &&s) { m_strings.push_back(s); }
-void
-StringList::AppendString (const char *str, size_t str_len)
-{
- if (str)
- m_strings.push_back (std::string (str, str_len));
+void StringList::AppendString(const char *str, size_t str_len) {
+ if (str)
+ m_strings.push_back(std::string(str, str_len));
}
-void
-StringList::AppendString(llvm::StringRef str)
-{
- m_strings.push_back(str.str());
+void StringList::AppendString(llvm::StringRef str) {
+ m_strings.push_back(str.str());
}
-void
-StringList::AppendList (const char **strv, int strc)
-{
- for (int i = 0; i < strc; ++i)
- {
- if (strv[i])
- m_strings.push_back (strv[i]);
- }
+void StringList::AppendList(const char **strv, int strc) {
+ for (int i = 0; i < strc; ++i) {
+ if (strv[i])
+ m_strings.push_back(strv[i]);
+ }
}
-void
-StringList::AppendList (StringList strings)
-{
- size_t len = strings.GetSize();
+void StringList::AppendList(StringList strings) {
+ size_t len = strings.GetSize();
- for (size_t i = 0; i < len; ++i)
- m_strings.push_back (strings.GetStringAtIndex(i));
+ for (size_t i = 0; i < len; ++i)
+ m_strings.push_back(strings.GetStringAtIndex(i));
}
-bool
-StringList::ReadFileLines (FileSpec &input_file)
-{
- return input_file.ReadFileLines (m_strings);
+bool StringList::ReadFileLines(FileSpec &input_file) {
+ return input_file.ReadFileLines(m_strings);
}
-size_t
-StringList::GetSize () const
-{
- return m_strings.size();
+size_t StringList::GetSize() const { return m_strings.size(); }
+
+size_t StringList::GetMaxStringLength() const {
+ size_t max_length = 0;
+ for (const auto &s : m_strings) {
+ const size_t len = s.size();
+ if (max_length < len)
+ max_length = len;
+ }
+ return max_length;
}
-size_t
-StringList::GetMaxStringLength () const
-{
- size_t max_length = 0;
- for (const auto &s : m_strings)
- {
- const size_t len = s.size();
- if (max_length < len)
- max_length = len;
- }
- return max_length;
+const char *StringList::GetStringAtIndex(size_t idx) const {
+ if (idx < m_strings.size())
+ return m_strings[idx].c_str();
+ return NULL;
}
+void StringList::Join(const char *separator, Stream &strm) {
+ size_t size = GetSize();
-const char *
-StringList::GetStringAtIndex (size_t idx) const
-{
- if (idx < m_strings.size())
- return m_strings[idx].c_str();
- return NULL;
-}
+ if (size == 0)
+ return;
-void
-StringList::Join (const char *separator, Stream &strm)
-{
- size_t size = GetSize();
-
- if (size == 0)
- return;
-
- for (uint32_t i = 0; i < size; ++i)
- {
- if (i > 0)
- strm.PutCString(separator);
- strm.PutCString(GetStringAtIndex(i));
- }
+ for (uint32_t i = 0; i < size; ++i) {
+ if (i > 0)
+ strm.PutCString(separator);
+ strm.PutCString(GetStringAtIndex(i));
+ }
}
-void
-StringList::Clear ()
-{
- m_strings.clear();
-}
+void StringList::Clear() { m_strings.clear(); }
-void
-StringList::LongestCommonPrefix (std::string &common_prefix)
-{
- const size_t num_strings = m_strings.size();
+void StringList::LongestCommonPrefix(std::string &common_prefix) {
+ common_prefix.clear();
+ if (m_strings.empty())
+ return;
- if (num_strings == 0)
- {
- common_prefix.clear();
- }
- else
- {
- common_prefix = m_strings.front();
-
- for (size_t idx = 1; idx < num_strings; ++idx)
- {
- std::string &curr_string = m_strings[idx];
- size_t new_size = curr_string.size();
-
- // First trim common_prefix if it is longer than the current element:
- if (common_prefix.size() > new_size)
- common_prefix.erase (new_size);
-
- // Then trim it at the first disparity:
- for (size_t i = 0; i < common_prefix.size(); i++)
- {
- if (curr_string[i] != common_prefix[i])
- {
- common_prefix.erase(i);
- break;
- }
- }
-
- // If we've emptied the common prefix, we're done.
- if (common_prefix.empty())
- break;
- }
+ auto args = llvm::makeArrayRef(m_strings);
+ llvm::StringRef prefix = args.front();
+ for (auto arg : args.drop_front()) {
+ size_t count = 0;
+ for (count = 0; count < std::min(prefix.size(), arg.size()); ++count) {
+ if (prefix[count] != arg[count])
+ break;
}
+ prefix = prefix.take_front(count);
+ }
+ common_prefix = prefix;
}
-void
-StringList::InsertStringAtIndex (size_t idx, const char *str)
-{
- if (str)
- {
- if (idx < m_strings.size())
- m_strings.insert (m_strings.begin() + idx, str);
- else
- m_strings.push_back (str);
- }
-}
-
-void
-StringList::InsertStringAtIndex (size_t idx, const std::string &str)
-{
+void StringList::InsertStringAtIndex(size_t idx, const char *str) {
+ if (str) {
if (idx < m_strings.size())
- m_strings.insert (m_strings.begin() + idx, str);
+ m_strings.insert(m_strings.begin() + idx, str);
else
- m_strings.push_back (str);
+ m_strings.push_back(str);
+ }
}
-void
-StringList::InsertStringAtIndex (size_t idx, std::string &&str)
-{
- if (idx < m_strings.size())
- m_strings.insert (m_strings.begin() + idx, str);
- else
- m_strings.push_back (str);
+void StringList::InsertStringAtIndex(size_t idx, const std::string &str) {
+ if (idx < m_strings.size())
+ m_strings.insert(m_strings.begin() + idx, str);
+ else
+ m_strings.push_back(str);
}
-void
-StringList::DeleteStringAtIndex (size_t idx)
-{
- if (idx < m_strings.size())
- m_strings.erase (m_strings.begin() + idx);
+void StringList::InsertStringAtIndex(size_t idx, std::string &&str) {
+ if (idx < m_strings.size())
+ m_strings.insert(m_strings.begin() + idx, str);
+ else
+ m_strings.push_back(str);
}
-size_t
-StringList::SplitIntoLines (const std::string &lines)
-{
- return SplitIntoLines (lines.c_str(), lines.size());
+void StringList::DeleteStringAtIndex(size_t idx) {
+ if (idx < m_strings.size())
+ m_strings.erase(m_strings.begin() + idx);
}
-size_t
-StringList::SplitIntoLines (const char *lines, size_t len)
-{
- const size_t orig_size = m_strings.size();
-
- if (len == 0)
- return 0;
-
- const char *k_newline_chars = "\r\n";
- const char *p = lines;
- const char *end = lines + len;
- while (p < end)
- {
- size_t count = strcspn (p, k_newline_chars);
- if (count == 0)
- {
- if (p[count] == '\r' || p[count] == '\n')
- m_strings.push_back(std::string());
- else
- break;
- }
- else
- {
- if (p + count > end)
- count = end - p;
- m_strings.push_back(std::string(p, count));
- }
- if (p[count] == '\r' && p[count+1] == '\n')
- count++; // Skip an extra newline char for the DOS newline
- count++; // Skip the newline character
- p += count;
- }
- return m_strings.size() - orig_size;
+size_t StringList::SplitIntoLines(const std::string &lines) {
+ return SplitIntoLines(lines.c_str(), lines.size());
}
-void
-StringList::RemoveBlankLines ()
-{
- if (GetSize() == 0)
- return;
-
- size_t idx = 0;
- while (idx < m_strings.size())
- {
- if (m_strings[idx].empty())
- DeleteStringAtIndex(idx);
- else
- idx++;
+size_t StringList::SplitIntoLines(const char *lines, size_t len) {
+ const size_t orig_size = m_strings.size();
+
+ if (len == 0)
+ return 0;
+
+ const char *k_newline_chars = "\r\n";
+ const char *p = lines;
+ const char *end = lines + len;
+ while (p < end) {
+ size_t count = strcspn(p, k_newline_chars);
+ if (count == 0) {
+ if (p[count] == '\r' || p[count] == '\n')
+ m_strings.push_back(std::string());
+ else
+ break;
+ } else {
+ if (p + count > end)
+ count = end - p;
+ m_strings.push_back(std::string(p, count));
}
+ if (p[count] == '\r' && p[count + 1] == '\n')
+ count++; // Skip an extra newline char for the DOS newline
+ count++; // Skip the newline character
+ p += count;
+ }
+ return m_strings.size() - orig_size;
+}
+
+void StringList::RemoveBlankLines() {
+ if (GetSize() == 0)
+ return;
+
+ size_t idx = 0;
+ while (idx < m_strings.size()) {
+ if (m_strings[idx].empty())
+ DeleteStringAtIndex(idx);
+ else
+ idx++;
+ }
}
-std::string
-StringList::CopyList(const char* item_preamble, const char* items_sep) const
-{
- StreamString strm;
- for (size_t i = 0; i < GetSize(); i++)
- {
- if (i && items_sep && items_sep[0])
- strm << items_sep;
- if (item_preamble)
- strm << item_preamble;
- strm << GetStringAtIndex(i);
- }
- return std::string(strm.GetData());
+std::string StringList::CopyList(const char *item_preamble,
+ const char *items_sep) const {
+ StreamString strm;
+ for (size_t i = 0; i < GetSize(); i++) {
+ if (i && items_sep && items_sep[0])
+ strm << items_sep;
+ if (item_preamble)
+ strm << item_preamble;
+ strm << GetStringAtIndex(i);
+ }
+ return strm.GetString();
}
-StringList&
-StringList::operator << (const char* str)
-{
- AppendString(str);
- return *this;
+StringList &StringList::operator<<(const char *str) {
+ AppendString(str);
+ return *this;
}
-StringList&
-StringList::operator << (const std::string& str)
-{
- AppendString(str);
- return *this;
+StringList &StringList::operator<<(const std::string &str) {
+ AppendString(str);
+ return *this;
}
-StringList&
-StringList::operator << (StringList strings)
-{
- AppendList(strings);
- return *this;
+StringList &StringList::operator<<(StringList strings) {
+ AppendList(strings);
+ return *this;
}
-StringList&
-StringList::operator = (const std::vector<std::string> &rhs)
-{
- Clear();
- for (const auto &s : rhs)
- m_strings.push_back(s);
+StringList &StringList::operator=(const std::vector<std::string> &rhs) {
+ Clear();
+ for (const auto &s : rhs)
+ m_strings.push_back(s);
- return *this;
+ return *this;
}
-size_t
-StringList::AutoComplete (const char *s, StringList &matches, size_t &exact_idx) const
-{
- matches.Clear();
- exact_idx = SIZE_MAX;
- if (s && s[0])
- {
- const size_t s_len = strlen (s);
- const size_t num_strings = m_strings.size();
-
- for (size_t i=0; i<num_strings; ++i)
- {
- if (m_strings[i].find(s) == 0)
- {
- if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len)
- exact_idx = matches.GetSize();
- matches.AppendString (m_strings[i]);
- }
- }
- }
- else
- {
- // No string, so it matches everything
- matches = *this;
- }
+size_t StringList::AutoComplete(llvm::StringRef s, StringList &matches,
+ size_t &exact_idx) const {
+ matches.Clear();
+ exact_idx = SIZE_MAX;
+ if (s.empty()) {
+ // No string, so it matches everything
+ matches = *this;
return matches.GetSize();
-}
+ }
-void
-StringList::LogDump(Log *log, const char *name)
-{
- if (!log)
- return;
-
- StreamString strm;
- if (name)
- strm.Printf("Begin %s:\n", name);
- for (const auto &s : m_strings) {
- strm.Indent();
- strm.Printf("%s\n", s.c_str());
+ const size_t s_len = s.size();
+ const size_t num_strings = m_strings.size();
+
+ for (size_t i = 0; i < num_strings; ++i) {
+ if (m_strings[i].find(s) == 0) {
+ if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len)
+ exact_idx = matches.GetSize();
+ matches.AppendString(m_strings[i]);
}
- if (name)
- strm.Printf("End %s.\n", name);
+ }
+ return matches.GetSize();
+}
+
+void StringList::LogDump(Log *log, const char *name) {
+ if (!log)
+ return;
+
+ StreamString strm;
+ if (name)
+ strm.Printf("Begin %s:\n", name);
+ for (const auto &s : m_strings) {
+ strm.Indent();
+ strm.Printf("%s\n", s.c_str());
+ }
+ if (name)
+ strm.Printf("End %s.\n", name);
- log->Debug("%s", strm.GetData());
+ log->Debug("%s", strm.GetData());
}
diff --git a/source/Core/StructuredData.cpp b/source/Core/StructuredData.cpp
index efc104f1f3e8..1e190f52314e 100644
--- a/source/Core/StructuredData.cpp
+++ b/source/Core/StructuredData.cpp
@@ -1,4 +1,4 @@
-//===---------------------StructuredData.cpp ---------------------*- C++ -*-===//
+//===---------------------StructuredData.cpp ---------------------*- C++-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,296 +10,298 @@
#include "lldb/Core/StructuredData.h"
#include <errno.h>
-#include <stdlib.h>
#include <inttypes.h>
+#include <stdlib.h>
+#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/Error.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Host/File.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Host/StringConvert.h"
#include "lldb/Utility/JSON.h"
using namespace lldb_private;
-
//----------------------------------------------------------------------
// Functions that use a JSONParser to parse JSON into StructuredData
//----------------------------------------------------------------------
-static StructuredData::ObjectSP ParseJSONValue (JSONParser &json_parser);
-static StructuredData::ObjectSP ParseJSONObject (JSONParser &json_parser);
-static StructuredData::ObjectSP ParseJSONArray (JSONParser &json_parser);
-
-static StructuredData::ObjectSP
-ParseJSONObject (JSONParser &json_parser)
-{
- // The "JSONParser::Token::ObjectStart" token should have already been consumed
- // by the time this function is called
- std::unique_ptr<StructuredData::Dictionary> dict_up(new StructuredData::Dictionary());
-
- std::string value;
- std::string key;
- while (1)
- {
- JSONParser::Token token = json_parser.GetToken(value);
-
- if (token == JSONParser::Token::String)
- {
- key.swap(value);
- token = json_parser.GetToken(value);
- if (token == JSONParser::Token::Colon)
- {
- StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
- if (value_sp)
- dict_up->AddItem(key, value_sp);
- else
- break;
- }
- }
- else if (token == JSONParser::Token::ObjectEnd)
- {
- return StructuredData::ObjectSP(dict_up.release());
- }
- else if (token == JSONParser::Token::Comma)
- {
- continue;
- }
- else
- {
- break;
- }
- }
- return StructuredData::ObjectSP();
+static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser);
+static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser);
+static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser);
+
+StructuredData::ObjectSP
+StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Error &error) {
+ StructuredData::ObjectSP return_sp;
+ if (!input_spec.Exists()) {
+ error.SetErrorStringWithFormat("input file %s does not exist.",
+ input_spec.GetPath().c_str());
+ return return_sp;
+ }
+
+ File input_file(nullptr, File::OpenOptions::eOpenOptionRead,
+ lldb::eFilePermissionsUserRead);
+ std::string input_path = input_spec.GetPath();
+ error =
+ input_file.Open(input_path.c_str(), File::OpenOptions::eOpenOptionRead,
+ lldb::eFilePermissionsUserRead);
+
+ if (!error.Success()) {
+ error.SetErrorStringWithFormat("could not open input file: %s - %s.",
+ input_spec.GetPath().c_str(),
+ error.AsCString());
+ return return_sp;
+ }
+
+ lldb::DataBufferSP input_data;
+ size_t num_bytes = std::numeric_limits<size_t>::max();
+ off_t offset = 0;
+ error = input_file.Read(num_bytes, offset, true, input_data);
+ if (!error.Success()) {
+ error.SetErrorStringWithFormat("could not read input file: %s - %s.",
+ input_spec.GetPath().c_str(),
+ error.AsCString());
+ return return_sp;
+ }
+ JSONParser json_parser((char *)input_data->GetBytes());
+ return_sp = ParseJSONValue(json_parser);
+ return return_sp;
}
-static StructuredData::ObjectSP
-ParseJSONArray (JSONParser &json_parser)
-{
- // The "JSONParser::Token::ObjectStart" token should have already been consumed
- // by the time this function is called
- std::unique_ptr<StructuredData::Array> array_up(new StructuredData::Array());
-
- std::string value;
- std::string key;
- while (1)
- {
+static StructuredData::ObjectSP ParseJSONObject(JSONParser &json_parser) {
+ // The "JSONParser::Token::ObjectStart" token should have already been
+ // consumed
+ // by the time this function is called
+ std::unique_ptr<StructuredData::Dictionary> dict_up(
+ new StructuredData::Dictionary());
+
+ std::string value;
+ std::string key;
+ while (1) {
+ JSONParser::Token token = json_parser.GetToken(value);
+
+ if (token == JSONParser::Token::String) {
+ key.swap(value);
+ token = json_parser.GetToken(value);
+ if (token == JSONParser::Token::Colon) {
StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
if (value_sp)
- array_up->AddItem(value_sp);
- else
- break;
-
- JSONParser::Token token = json_parser.GetToken(value);
- if (token == JSONParser::Token::Comma)
- {
- continue;
- }
- else if (token == JSONParser::Token::ArrayEnd)
- {
- return StructuredData::ObjectSP(array_up.release());
- }
+ dict_up->AddItem(key, value_sp);
else
- {
- break;
- }
+ break;
+ }
+ } else if (token == JSONParser::Token::ObjectEnd) {
+ return StructuredData::ObjectSP(dict_up.release());
+ } else if (token == JSONParser::Token::Comma) {
+ continue;
+ } else {
+ break;
}
- return StructuredData::ObjectSP();
+ }
+ return StructuredData::ObjectSP();
}
-static StructuredData::ObjectSP
-ParseJSONValue (JSONParser &json_parser)
-{
- std::string value;
- const JSONParser::Token token = json_parser.GetToken(value);
- switch (token)
- {
- case JSONParser::Token::ObjectStart:
- return ParseJSONObject(json_parser);
-
- case JSONParser::Token::ArrayStart:
- return ParseJSONArray(json_parser);
-
- case JSONParser::Token::Integer:
- {
- bool success = false;
- uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
- if (success)
- return StructuredData::ObjectSP(new StructuredData::Integer(uval));
- }
- break;
-
- case JSONParser::Token::Float:
- {
- bool success = false;
- double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
- if (success)
- return StructuredData::ObjectSP(new StructuredData::Float(val));
- }
- break;
-
- case JSONParser::Token::String:
- return StructuredData::ObjectSP(new StructuredData::String(value));
-
- case JSONParser::Token::True:
- case JSONParser::Token::False:
- return StructuredData::ObjectSP(new StructuredData::Boolean(token == JSONParser::Token::True));
-
- case JSONParser::Token::Null:
- return StructuredData::ObjectSP(new StructuredData::Null());
-
- default:
- break;
+static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser) {
+ // The "JSONParser::Token::ObjectStart" token should have already been
+ // consumed
+ // by the time this function is called
+ std::unique_ptr<StructuredData::Array> array_up(new StructuredData::Array());
+
+ std::string value;
+ std::string key;
+ while (1) {
+ StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
+ if (value_sp)
+ array_up->AddItem(value_sp);
+ else
+ break;
+
+ JSONParser::Token token = json_parser.GetToken(value);
+ if (token == JSONParser::Token::Comma) {
+ continue;
+ } else if (token == JSONParser::Token::ArrayEnd) {
+ return StructuredData::ObjectSP(array_up.release());
+ } else {
+ break;
}
- return StructuredData::ObjectSP();
+ }
+ return StructuredData::ObjectSP();
+}
+static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser) {
+ std::string value;
+ const JSONParser::Token token = json_parser.GetToken(value);
+ switch (token) {
+ case JSONParser::Token::ObjectStart:
+ return ParseJSONObject(json_parser);
+
+ case JSONParser::Token::ArrayStart:
+ return ParseJSONArray(json_parser);
+
+ case JSONParser::Token::Integer: {
+ bool success = false;
+ uint64_t uval = StringConvert::ToUInt64(value.c_str(), 0, 0, &success);
+ if (success)
+ return StructuredData::ObjectSP(new StructuredData::Integer(uval));
+ } break;
+
+ case JSONParser::Token::Float: {
+ bool success = false;
+ double val = StringConvert::ToDouble(value.c_str(), 0.0, &success);
+ if (success)
+ return StructuredData::ObjectSP(new StructuredData::Float(val));
+ } break;
+
+ case JSONParser::Token::String:
+ return StructuredData::ObjectSP(new StructuredData::String(value));
+
+ case JSONParser::Token::True:
+ case JSONParser::Token::False:
+ return StructuredData::ObjectSP(
+ new StructuredData::Boolean(token == JSONParser::Token::True));
+
+ case JSONParser::Token::Null:
+ return StructuredData::ObjectSP(new StructuredData::Null());
+
+ default:
+ break;
+ }
+ return StructuredData::ObjectSP();
}
-StructuredData::ObjectSP
-StructuredData::ParseJSON (std::string json_text)
-{
- JSONParser json_parser(json_text.c_str());
- StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser);
- return object_sp;
+StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
+ JSONParser json_parser(json_text.c_str());
+ StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser);
+ return object_sp;
}
StructuredData::ObjectSP
-StructuredData::Object::GetObjectForDotSeparatedPath (llvm::StringRef path)
-{
- if (this->GetType() == Type::eTypeDictionary)
- {
- std::pair<llvm::StringRef, llvm::StringRef> match = path.split('.');
- std::string key = match.first.str();
- ObjectSP value = this->GetAsDictionary()->GetValueForKey (key.c_str());
- if (value.get())
- {
- // Do we have additional words to descend? If not, return the
- // value we're at right now.
- if (match.second.empty())
- {
- return value;
- }
- else
- {
- return value->GetObjectForDotSeparatedPath (match.second);
- }
- }
- return ObjectSP();
+StructuredData::Object::GetObjectForDotSeparatedPath(llvm::StringRef path) {
+ if (this->GetType() == Type::eTypeDictionary) {
+ std::pair<llvm::StringRef, llvm::StringRef> match = path.split('.');
+ std::string key = match.first.str();
+ ObjectSP value = this->GetAsDictionary()->GetValueForKey(key);
+ if (value.get()) {
+ // Do we have additional words to descend? If not, return the
+ // value we're at right now.
+ if (match.second.empty()) {
+ return value;
+ } else {
+ return value->GetObjectForDotSeparatedPath(match.second);
+ }
}
+ return ObjectSP();
+ }
- if (this->GetType() == Type::eTypeArray)
- {
- std::pair<llvm::StringRef, llvm::StringRef> match = path.split('[');
- if (match.second.size() == 0)
- {
- return this->shared_from_this();
- }
- errno = 0;
- uint64_t val = strtoul (match.second.str().c_str(), NULL, 10);
- if (errno == 0)
- {
- return this->GetAsArray()->GetItemAtIndex(val);
- }
- return ObjectSP();
+ if (this->GetType() == Type::eTypeArray) {
+ std::pair<llvm::StringRef, llvm::StringRef> match = path.split('[');
+ if (match.second.size() == 0) {
+ return this->shared_from_this();
+ }
+ errno = 0;
+ uint64_t val = strtoul(match.second.str().c_str(), NULL, 10);
+ if (errno == 0) {
+ return this->GetAsArray()->GetItemAtIndex(val);
}
+ return ObjectSP();
+ }
- return this->shared_from_this();
+ return this->shared_from_this();
}
-void
-StructuredData::Object::DumpToStdout() const
-{
- StreamString stream;
- Dump(stream);
- printf("%s\n", stream.GetString().c_str());
+void StructuredData::Object::DumpToStdout(bool pretty_print) const {
+ StreamString stream;
+ Dump(stream, pretty_print);
+ printf("%s\n", stream.GetData());
}
-void
-StructuredData::Array::Dump(Stream &s) const
-{
- bool first = true;
- s << "[\n";
+void StructuredData::Array::Dump(Stream &s, bool pretty_print) const {
+ bool first = true;
+ s << "[";
+ if (pretty_print) {
+ s << "\n";
s.IndentMore();
- for (const auto &item_sp : m_items)
- {
- if (first)
- first = false;
- else
- s << ",\n";
-
- s.Indent();
- item_sp->Dump(s);
+ }
+ for (const auto &item_sp : m_items) {
+ if (first) {
+ first = false;
+ } else {
+ s << ",";
+ if (pretty_print)
+ s << "\n";
}
+
+ if (pretty_print)
+ s.Indent();
+ item_sp->Dump(s, pretty_print);
+ }
+ if (pretty_print) {
s.IndentLess();
s.EOL();
s.Indent();
- s << "]";
+ }
+ s << "]";
}
-void
-StructuredData::Integer::Dump (Stream &s) const
-{
- s.Printf ("%" PRIu64, m_value);
+void StructuredData::Integer::Dump(Stream &s, bool pretty_print) const {
+ s.Printf("%" PRIu64, m_value);
}
-
-void
-StructuredData::Float::Dump (Stream &s) const
-{
- s.Printf ("%lg", m_value);
+void StructuredData::Float::Dump(Stream &s, bool pretty_print) const {
+ s.Printf("%lg", m_value);
}
-void
-StructuredData::Boolean::Dump (Stream &s) const
-{
- if (m_value == true)
- s.PutCString ("true");
- else
- s.PutCString ("false");
+void StructuredData::Boolean::Dump(Stream &s, bool pretty_print) const {
+ if (m_value == true)
+ s.PutCString("true");
+ else
+ s.PutCString("false");
}
-
-void
-StructuredData::String::Dump (Stream &s) const
-{
- std::string quoted;
- const size_t strsize = m_value.size();
- for (size_t i = 0; i < strsize ; ++i)
- {
- char ch = m_value[i];
- if (ch == '"')
- quoted.push_back ('\\');
- quoted.push_back (ch);
- }
- s.Printf ("\"%s\"", quoted.c_str());
+void StructuredData::String::Dump(Stream &s, bool pretty_print) const {
+ std::string quoted;
+ const size_t strsize = m_value.size();
+ for (size_t i = 0; i < strsize; ++i) {
+ char ch = m_value[i];
+ if (ch == '"' || ch == '\\')
+ quoted.push_back('\\');
+ quoted.push_back(ch);
+ }
+ s.Printf("\"%s\"", quoted.c_str());
}
-void
-StructuredData::Dictionary::Dump (Stream &s) const
-{
- bool first = true;
- s << "{\n";
+void StructuredData::Dictionary::Dump(Stream &s, bool pretty_print) const {
+ bool first = true;
+ s << "{";
+ if (pretty_print) {
+ s << "\n";
s.IndentMore();
- for (const auto &pair : m_dict)
- {
- if (first)
- first = false;
- else
- s << ",\n";
- s.Indent();
- s << "\"" << pair.first.AsCString() << "\" : ";
- pair.second->Dump(s);
+ }
+ for (const auto &pair : m_dict) {
+ if (first)
+ first = false;
+ else {
+ s << ",";
+ if (pretty_print)
+ s << "\n";
}
+ if (pretty_print)
+ s.Indent();
+ s << "\"" << pair.first.AsCString() << "\" : ";
+ pair.second->Dump(s, pretty_print);
+ }
+ if (pretty_print) {
s.IndentLess();
s.EOL();
s.Indent();
- s << "}";
+ }
+ s << "}";
}
-void
-StructuredData::Null::Dump (Stream &s) const
-{
- s << "null";
+void StructuredData::Null::Dump(Stream &s, bool pretty_print) const {
+ s << "null";
}
-void
-StructuredData::Generic::Dump(Stream &s) const
-{
- s << "0x" << m_object;
+void StructuredData::Generic::Dump(Stream &s, bool pretty_print) const {
+ s << "0x" << m_object;
}
diff --git a/source/Core/Timer.cpp b/source/Core/Timer.cpp
index f4cd33fc3cb5..ca1a2b749ec3 100644
--- a/source/Core/Timer.cpp
+++ b/source/Core/Timer.cpp
@@ -22,245 +22,133 @@ using namespace lldb_private;
#define TIMER_INDENT_AMOUNT 2
-namespace
-{
- typedef std::map<const char*, uint64_t> TimerCategoryMap;
-
- struct TimerStack
- {
- TimerStack() :
- m_depth(0)
- {}
-
- uint32_t m_depth;
- std::vector<Timer*> m_stack;
- };
+namespace {
+typedef std::map<const char *, std::chrono::nanoseconds> TimerCategoryMap;
+typedef std::vector<Timer *> TimerStack;
} // end of anonymous namespace
std::atomic<bool> Timer::g_quiet(true);
std::atomic<unsigned> Timer::g_display_depth(0);
-static std::mutex &
-GetFileMutex()
-{
- static std::mutex *g_file_mutex_ptr = nullptr;
- static std::once_flag g_once_flag;
- std::call_once(g_once_flag, []() {
- // leaked on purpose to ensure this mutex works after main thread has run
- // global C++ destructor chain
- g_file_mutex_ptr = new std::mutex();
- });
- return *g_file_mutex_ptr;
+static std::mutex &GetFileMutex() {
+ static std::mutex *g_file_mutex_ptr = new std::mutex();
+ return *g_file_mutex_ptr;
}
-static std::mutex &
-GetCategoryMutex()
-{
- static std::mutex g_category_mutex;
- return g_category_mutex;
+static std::mutex &GetCategoryMutex() {
+ static std::mutex g_category_mutex;
+ return g_category_mutex;
}
-static TimerCategoryMap &
-GetCategoryMap()
-{
- static TimerCategoryMap g_category_map;
- return g_category_map;
+static TimerCategoryMap &GetCategoryMap() {
+ static TimerCategoryMap g_category_map;
+ return g_category_map;
}
-static void
-ThreadSpecificCleanup(void *p)
-{
- delete static_cast<TimerStack *>(p);
+static void ThreadSpecificCleanup(void *p) {
+ delete static_cast<TimerStack *>(p);
}
-static TimerStack *
-GetTimerStackForCurrentThread ()
-{
- static lldb::thread_key_t g_key = Host::ThreadLocalStorageCreate(ThreadSpecificCleanup);
-
- void *timer_stack = Host::ThreadLocalStorageGet(g_key);
- if (timer_stack == NULL)
- {
- Host::ThreadLocalStorageSet(g_key, new TimerStack);
- timer_stack = Host::ThreadLocalStorageGet(g_key);
- }
- return (TimerStack *)timer_stack;
-}
+static TimerStack *GetTimerStackForCurrentThread() {
+ static lldb::thread_key_t g_key =
+ Host::ThreadLocalStorageCreate(ThreadSpecificCleanup);
-void
-Timer::SetQuiet (bool value)
-{
- g_quiet = value;
+ void *timer_stack = Host::ThreadLocalStorageGet(g_key);
+ if (timer_stack == NULL) {
+ Host::ThreadLocalStorageSet(g_key, new TimerStack);
+ timer_stack = Host::ThreadLocalStorageGet(g_key);
+ }
+ return (TimerStack *)timer_stack;
}
-Timer::Timer (const char *category, const char *format, ...) :
- m_category (category),
- m_total_start (),
- m_timer_start (),
- m_total_ticks (0),
- m_timer_ticks (0)
-{
- TimerStack *stack = GetTimerStackForCurrentThread ();
- if (!stack)
- return;
+void Timer::SetQuiet(bool value) { g_quiet = value; }
- if (stack->m_depth++ < g_display_depth)
- {
- if (g_quiet == false)
- {
- std::lock_guard<std::mutex> lock(GetFileMutex());
-
- // Indent
- ::fprintf(stdout, "%*s", stack->m_depth * TIMER_INDENT_AMOUNT, "");
- // Print formatted string
- va_list args;
- va_start (args, format);
- ::vfprintf(stdout, format, args);
- va_end (args);
-
- // Newline
- ::fprintf(stdout, "\n");
- }
- TimeValue start_time(TimeValue::Now());
- m_total_start = start_time;
- m_timer_start = start_time;
-
- 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();
- if (m_total_start.IsValid())
- {
- m_total_ticks += (stop_time - m_total_start);
- m_total_start.Clear();
- }
- if (m_timer_start.IsValid())
- {
- m_timer_ticks += (stop_time - m_timer_start);
- m_timer_start.Clear();
- }
-
- 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();
- const double total_nsec = total_nsec_uint;
- const double timer_nsec = timer_nsec_uint;
-
- if (g_quiet == false)
- {
- std::lock_guard<std::mutex> lock(GetFileMutex());
- ::fprintf(stdout, "%*s%.9f sec (%.9f sec)\n", (stack->m_depth - 1) * TIMER_INDENT_AMOUNT, "",
- total_nsec / 1000000000.0, timer_nsec / 1000000000.0);
- }
-
- // Keep total results for each category so we can dump results.
- std::lock_guard<std::mutex> guard(GetCategoryMutex());
- TimerCategoryMap &category_map = GetCategoryMap();
- category_map[m_category] += timer_nsec_uint;
- }
- if (stack->m_depth > 0)
- --stack->m_depth;
-}
+Timer::Timer(const char *category, const char *format, ...)
+ : m_category(category), m_total_start(std::chrono::steady_clock::now()) {
+ TimerStack *stack = GetTimerStackForCurrentThread();
+ if (!stack)
+ return;
-uint64_t
-Timer::GetTotalElapsedNanoSeconds()
-{
- uint64_t total_ticks = m_total_ticks;
+ stack->push_back(this);
+ if (g_quiet && stack->size() <= g_display_depth) {
+ std::lock_guard<std::mutex> lock(GetFileMutex());
- // If we are currently running, we need to add the current
- // elapsed time of the running timer...
- if (m_total_start.IsValid())
- total_ticks += (TimeValue::Now() - m_total_start);
+ // Indent
+ ::fprintf(stdout, "%*s", int(stack->size() - 1) * TIMER_INDENT_AMOUNT, "");
+ // Print formatted string
+ va_list args;
+ va_start(args, format);
+ ::vfprintf(stdout, format, args);
+ va_end(args);
- return total_ticks;
+ // Newline
+ ::fprintf(stdout, "\n");
+ }
}
-uint64_t
-Timer::GetTimerElapsedNanoSeconds()
-{
- uint64_t timer_ticks = m_timer_ticks;
+Timer::~Timer() {
+ using namespace std::chrono;
- // If we are currently running, we need to add the current
- // elapsed time of the running timer...
- if (m_timer_start.IsValid())
- timer_ticks += (TimeValue::Now() - m_timer_start);
+ TimerStack *stack = GetTimerStackForCurrentThread();
+ if (!stack)
+ return;
- return timer_ticks;
-}
+ auto stop_time = steady_clock::now();
+ auto total_dur = stop_time - m_total_start;
+ auto timer_dur = total_dur - m_child_duration;
-void
-Timer::ChildStarted (const TimeValue& start_time)
-{
- if (m_timer_start.IsValid())
- {
- m_timer_ticks += (start_time - m_timer_start);
- m_timer_start.Clear();
- }
-}
+ if (g_quiet && stack->size() <= g_display_depth) {
+ std::lock_guard<std::mutex> lock(GetFileMutex());
+ ::fprintf(stdout, "%*s%.9f sec (%.9f sec)\n",
+ int(stack->size() - 1) * TIMER_INDENT_AMOUNT, "",
+ duration<double>(total_dur).count(),
+ duration<double>(timer_dur).count());
+ }
-void
-Timer::ChildStopped (const TimeValue& stop_time)
-{
- if (!m_timer_start.IsValid())
- m_timer_start = stop_time;
-}
+ assert(stack->back() == this);
+ stack->pop_back();
+ if (!stack->empty())
+ stack->back()->ChildDuration(total_dur);
-void
-Timer::SetDisplayDepth (uint32_t depth)
-{
- g_display_depth = depth;
+ // Keep total results for each category so we can dump results.
+ {
+ std::lock_guard<std::mutex> guard(GetCategoryMutex());
+ TimerCategoryMap &category_map = GetCategoryMap();
+ category_map[m_category] += timer_dur;
+ }
}
+void Timer::SetDisplayDepth(uint32_t depth) { g_display_depth = depth; }
/* binary function predicate:
* - returns whether a person is less than another person
*/
static bool
-CategoryMapIteratorSortCriterion (const TimerCategoryMap::const_iterator& lhs, const TimerCategoryMap::const_iterator& rhs)
-{
- return lhs->second > rhs->second;
-}
-
-
-void
-Timer::ResetCategoryTimes ()
-{
- std::lock_guard<std::mutex> guard(GetCategoryMutex());
- TimerCategoryMap &category_map = GetCategoryMap();
- category_map.clear();
-}
-
-void
-Timer::DumpCategoryTimes (Stream *s)
-{
- std::lock_guard<std::mutex> guard(GetCategoryMutex());
- TimerCategoryMap &category_map = GetCategoryMap();
- std::vector<TimerCategoryMap::const_iterator> sorted_iterators;
- TimerCategoryMap::const_iterator pos, end = category_map.end();
- for (pos = category_map.begin(); pos != end; ++pos)
- {
- sorted_iterators.push_back (pos);
- }
- std::sort (sorted_iterators.begin(), sorted_iterators.end(), CategoryMapIteratorSortCriterion);
-
- const size_t count = sorted_iterators.size();
- for (size_t i=0; i<count; ++i)
- {
- const double timer_nsec = sorted_iterators[i]->second;
- s->Printf("%.9f sec for %s\n", timer_nsec / 1000000000.0, sorted_iterators[i]->first);
- }
+CategoryMapIteratorSortCriterion(const TimerCategoryMap::const_iterator &lhs,
+ const TimerCategoryMap::const_iterator &rhs) {
+ return lhs->second > rhs->second;
+}
+
+void Timer::ResetCategoryTimes() {
+ std::lock_guard<std::mutex> guard(GetCategoryMutex());
+ TimerCategoryMap &category_map = GetCategoryMap();
+ category_map.clear();
+}
+
+void Timer::DumpCategoryTimes(Stream *s) {
+ std::lock_guard<std::mutex> guard(GetCategoryMutex());
+ TimerCategoryMap &category_map = GetCategoryMap();
+ std::vector<TimerCategoryMap::const_iterator> sorted_iterators;
+ TimerCategoryMap::const_iterator pos, end = category_map.end();
+ for (pos = category_map.begin(); pos != end; ++pos) {
+ sorted_iterators.push_back(pos);
+ }
+ std::sort(sorted_iterators.begin(), sorted_iterators.end(),
+ CategoryMapIteratorSortCriterion);
+
+ const size_t count = sorted_iterators.size();
+ for (size_t i = 0; i < count; ++i) {
+ const auto timer = sorted_iterators[i]->second;
+ s->Printf("%.9f sec for %s\n", std::chrono::duration<double>(timer).count(),
+ sorted_iterators[i]->first);
+ }
}
diff --git a/source/Core/UUID.cpp b/source/Core/UUID.cpp
index 88290d137943..a08a748821de 100644
--- a/source/Core/UUID.cpp
+++ b/source/Core/UUID.cpp
@@ -9,9 +9,9 @@
#include "lldb/Core/UUID.h"
// C Includes
-#include <string.h>
-#include <stdio.h>
#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
// C++ Includes
#include <string>
@@ -22,261 +22,203 @@
namespace lldb_private {
-UUID::UUID() : m_num_uuid_bytes(16)
-{
- ::memset (m_uuid, 0, sizeof(m_uuid));
-}
+UUID::UUID() : m_num_uuid_bytes(16) { ::memset(m_uuid, 0, sizeof(m_uuid)); }
-UUID::UUID(const UUID& rhs)
-{
- m_num_uuid_bytes = rhs.m_num_uuid_bytes;
- ::memcpy (m_uuid, rhs.m_uuid, sizeof (m_uuid));
+UUID::UUID(const UUID &rhs) {
+ m_num_uuid_bytes = rhs.m_num_uuid_bytes;
+ ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid));
}
-UUID::UUID (const void *uuid_bytes, uint32_t num_uuid_bytes)
-{
- SetBytes (uuid_bytes, num_uuid_bytes);
+UUID::UUID(const void *uuid_bytes, uint32_t num_uuid_bytes) {
+ SetBytes(uuid_bytes, num_uuid_bytes);
}
-const UUID&
-UUID::operator=(const UUID& rhs)
-{
- if (this != &rhs)
- {
- m_num_uuid_bytes = rhs.m_num_uuid_bytes;
- ::memcpy (m_uuid, rhs.m_uuid, sizeof (m_uuid));
+const UUID &UUID::operator=(const UUID &rhs) {
+ if (this != &rhs) {
+ m_num_uuid_bytes = rhs.m_num_uuid_bytes;
+ ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid));
+ }
+ return *this;
+}
+
+UUID::~UUID() {}
+
+void UUID::Clear() {
+ m_num_uuid_bytes = 16;
+ ::memset(m_uuid, 0, sizeof(m_uuid));
+}
+
+const void *UUID::GetBytes() const { return m_uuid; }
+
+std::string UUID::GetAsString(const char *separator) const {
+ std::string result;
+ char buf[256];
+ if (!separator)
+ separator = "-";
+ const uint8_t *u = (const uint8_t *)GetBytes();
+ if (sizeof(buf) >
+ (size_t)snprintf(buf, sizeof(buf), "%2.2X%2.2X%2.2X%2.2X%s%2.2X%2.2X%s%2."
+ "2X%2.2X%s%2.2X%2.2X%s%2.2X%2.2X%2.2X%"
+ "2.2X%2.2X%2.2X",
+ u[0], u[1], u[2], u[3], separator, u[4], u[5], separator,
+ u[6], u[7], separator, u[8], u[9], separator, u[10],
+ u[11], u[12], u[13], u[14], u[15])) {
+ result.append(buf);
+ if (m_num_uuid_bytes == 20) {
+ if (sizeof(buf) > (size_t)snprintf(buf, sizeof(buf),
+ "%s%2.2X%2.2X%2.2X%2.2X", separator,
+ u[16], u[17], u[18], u[19]))
+ result.append(buf);
}
- return *this;
-}
-
-UUID::~UUID()
-{
-}
-
-void
-UUID::Clear()
-{
- m_num_uuid_bytes = 16;
- ::memset (m_uuid, 0, sizeof(m_uuid));
-}
-
-const void *
-UUID::GetBytes() const
-{
- return m_uuid;
-}
-
-std::string
-UUID::GetAsString (const char *separator) const
-{
- std::string result;
- char buf[256];
- if (!separator)
- separator = "-";
- const uint8_t *u = (const uint8_t *)GetBytes();
- if (sizeof (buf) > (size_t)snprintf (buf,
- sizeof (buf),
- "%2.2X%2.2X%2.2X%2.2X%s%2.2X%2.2X%s%2.2X%2.2X%s%2.2X%2.2X%s%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
- u[0],u[1],u[2],u[3],separator,
- u[4],u[5],separator,
- u[6],u[7],separator,
- u[8],u[9],separator,
- u[10],u[11],u[12],u[13],u[14],u[15]))
- {
- result.append (buf);
- if (m_num_uuid_bytes == 20)
- {
- if (sizeof (buf) > (size_t)snprintf (buf, sizeof (buf), "%s%2.2X%2.2X%2.2X%2.2X", separator,u[16],u[17],u[18],u[19]))
- result.append (buf);
- }
+ }
+ return result;
+}
+
+void UUID::Dump(Stream *s) const {
+ const uint8_t *u = (const uint8_t *)GetBytes();
+ s->Printf("%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%"
+ "2.2X%2.2X%2.2X%2.2X",
+ u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9], u[10],
+ u[11], u[12], u[13], u[14], u[15]);
+ if (m_num_uuid_bytes == 20) {
+ s->Printf("-%2.2X%2.2X%2.2X%2.2X", u[16], u[17], u[18], u[19]);
+ }
+}
+
+bool UUID::SetBytes(const void *uuid_bytes, uint32_t num_uuid_bytes) {
+ if (uuid_bytes) {
+ switch (num_uuid_bytes) {
+ case 20:
+ m_num_uuid_bytes = 20;
+ break;
+ case 16:
+ m_num_uuid_bytes = 16;
+ m_uuid[16] = m_uuid[17] = m_uuid[18] = m_uuid[19] = 0;
+ break;
+ default:
+ // Unsupported UUID byte size
+ m_num_uuid_bytes = 0;
+ break;
}
- return result;
-}
-void
-UUID::Dump (Stream *s) const
-{
- const uint8_t *u = (const uint8_t *)GetBytes();
- s->Printf ("%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X",
- u[0],u[1],u[2],u[3],u[4],u[5],u[6],u[7],u[8],u[9],u[10],u[11],u[12],u[13],u[14],u[15]);
- if (m_num_uuid_bytes == 20)
- {
- s->Printf ("-%2.2X%2.2X%2.2X%2.2X", u[16],u[17],u[18],u[19]);
+ if (m_num_uuid_bytes > 0) {
+ ::memcpy(m_uuid, uuid_bytes, m_num_uuid_bytes);
+ return true;
}
-}
-
-bool
-UUID::SetBytes (const void *uuid_bytes, uint32_t num_uuid_bytes)
-{
- if (uuid_bytes)
- {
- switch (num_uuid_bytes)
- {
- case 20:
- m_num_uuid_bytes = 20;
- break;
- case 16:
- m_num_uuid_bytes = 16;
- m_uuid[16] = m_uuid[17] = m_uuid[18] = m_uuid[19] = 0;
- break;
- default:
- // Unsupported UUID byte size
- m_num_uuid_bytes = 0;
- break;
- }
-
- if (m_num_uuid_bytes > 0)
- {
- ::memcpy (m_uuid, uuid_bytes, m_num_uuid_bytes);
- return true;
- }
+ }
+ ::memset(m_uuid, 0, sizeof(m_uuid));
+ return false;
+}
+
+size_t UUID::GetByteSize() { return m_num_uuid_bytes; }
+
+bool UUID::IsValid() const {
+ return m_uuid[0] || m_uuid[1] || m_uuid[2] || m_uuid[3] || m_uuid[4] ||
+ m_uuid[5] || m_uuid[6] || m_uuid[7] || m_uuid[8] || m_uuid[9] ||
+ m_uuid[10] || m_uuid[11] || m_uuid[12] || m_uuid[13] || m_uuid[14] ||
+ m_uuid[15] || m_uuid[16] || m_uuid[17] || m_uuid[18] || m_uuid[19];
+}
+
+static inline int xdigit_to_int(char ch) {
+ ch = tolower(ch);
+ if (ch >= 'a' && ch <= 'f')
+ return 10 + ch - 'a';
+ return ch - '0';
+}
+
+llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
+ ValueType &uuid_bytes,
+ uint32_t &bytes_decoded,
+ uint32_t num_uuid_bytes) {
+ ::memset(uuid_bytes, 0, sizeof(uuid_bytes));
+ size_t uuid_byte_idx = 0;
+ while (!p.empty()) {
+ if (isxdigit(p[0]) && isxdigit(p[1])) {
+ int hi_nibble = xdigit_to_int(p[0]);
+ int lo_nibble = xdigit_to_int(p[1]);
+ // Translate the two hex nibble characters into a byte
+ uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble;
+
+ // Skip both hex digits
+ p = p.drop_front(2);
+
+ // Increment the byte that we are decoding within the UUID value
+ // and break out if we are done
+ if (++uuid_byte_idx == num_uuid_bytes)
+ break;
+ } else if (p.front() == '-') {
+ // Skip dashes
+ p = p.drop_front();
+ } else {
+ // UUID values can only consist of hex characters and '-' chars
+ break;
}
- ::memset (m_uuid, 0, sizeof(m_uuid));
- return false;
-}
+ }
-size_t
-UUID::GetByteSize()
-{
- return m_num_uuid_bytes;
+ // Clear trailing bytes to 0.
+ for (uint32_t i = uuid_byte_idx; i < sizeof(ValueType); i++)
+ uuid_bytes[i] = 0;
+ bytes_decoded = uuid_byte_idx;
+ return p;
}
+size_t UUID::SetFromCString(const char *cstr, uint32_t num_uuid_bytes) {
+ if (cstr == NULL)
+ return 0;
-bool
-UUID::IsValid () const
-{
- return m_uuid[0] ||
- m_uuid[1] ||
- m_uuid[2] ||
- m_uuid[3] ||
- m_uuid[4] ||
- m_uuid[5] ||
- m_uuid[6] ||
- m_uuid[7] ||
- m_uuid[8] ||
- m_uuid[9] ||
- m_uuid[10] ||
- m_uuid[11] ||
- m_uuid[12] ||
- m_uuid[13] ||
- m_uuid[14] ||
- m_uuid[15] ||
- m_uuid[16] ||
- m_uuid[17] ||
- m_uuid[18] ||
- m_uuid[19];
-}
+ llvm::StringRef orig(cstr);
+ llvm::StringRef p = orig;
-static inline int
-xdigit_to_int (char ch)
-{
- ch = tolower(ch);
- if (ch >= 'a' && ch <= 'f')
- return 10 + ch - 'a';
- return ch - '0';
-}
+ // Skip leading whitespace characters
+ p = p.ltrim();
-size_t
-UUID::DecodeUUIDBytesFromCString (const char *p, ValueType &uuid_bytes, const char **end, uint32_t num_uuid_bytes)
-{
- size_t uuid_byte_idx = 0;
- if (p)
- {
- while (*p)
- {
- if (isxdigit(p[0]) && isxdigit(p[1]))
- {
- int hi_nibble = xdigit_to_int(p[0]);
- int lo_nibble = xdigit_to_int(p[1]);
- // Translate the two hex nibble characters into a byte
- uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble;
-
- // Skip both hex digits
- p += 2;
-
- // Increment the byte that we are decoding within the UUID value
- // and break out if we are done
- if (++uuid_byte_idx == num_uuid_bytes)
- break;
- }
- else if (*p == '-')
- {
- // Skip dashes
- p++;
- }
- else
- {
- // UUID values can only consist of hex characters and '-' chars
- break;
- }
- }
- }
- if (end)
- *end = p;
- // Clear trailing bytes to 0.
- for (uint32_t i = uuid_byte_idx; i < sizeof(ValueType); i++)
- uuid_bytes[i] = 0;
- return uuid_byte_idx;
-}
-size_t
-UUID::SetFromCString (const char *cstr, uint32_t num_uuid_bytes)
-{
- if (cstr == NULL)
- return 0;
-
- const char *p = cstr;
-
- // Skip leading whitespace characters
- while (isspace(*p))
- ++p;
-
- const size_t uuid_byte_idx = UUID::DecodeUUIDBytesFromCString (p, m_uuid, &p, num_uuid_bytes);
-
- // If we successfully decoded a UUID, return the amount of characters that
- // were consumed
- if (uuid_byte_idx == num_uuid_bytes)
- {
- m_num_uuid_bytes = num_uuid_bytes;
- return p - cstr;
- }
+ uint32_t bytes_decoded = 0;
+ llvm::StringRef rest =
+ UUID::DecodeUUIDBytesFromString(p, m_uuid, bytes_decoded, num_uuid_bytes);
- // Else return zero to indicate we were not able to parse a UUID value
- return 0;
-}
+ // If we successfully decoded a UUID, return the amount of characters that
+ // were consumed
+ if (bytes_decoded == num_uuid_bytes) {
+ m_num_uuid_bytes = num_uuid_bytes;
+ return orig.size() - rest.size();
+ }
+ // Else return zero to indicate we were not able to parse a UUID value
+ return 0;
+}
}
-bool
-lldb_private::operator == (const lldb_private::UUID &lhs, const lldb_private::UUID &rhs)
-{
- return ::memcmp (lhs.GetBytes(), rhs.GetBytes(), sizeof (lldb_private::UUID::ValueType)) == 0;
+bool lldb_private::operator==(const lldb_private::UUID &lhs,
+ const lldb_private::UUID &rhs) {
+ return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
+ sizeof(lldb_private::UUID::ValueType)) == 0;
}
-bool
-lldb_private::operator != (const lldb_private::UUID &lhs, const lldb_private::UUID &rhs)
-{
- return ::memcmp (lhs.GetBytes(), rhs.GetBytes(), sizeof (lldb_private::UUID::ValueType)) != 0;
+bool lldb_private::operator!=(const lldb_private::UUID &lhs,
+ const lldb_private::UUID &rhs) {
+ return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
+ sizeof(lldb_private::UUID::ValueType)) != 0;
}
-bool
-lldb_private::operator < (const lldb_private::UUID &lhs, const lldb_private::UUID &rhs)
-{
- return ::memcmp (lhs.GetBytes(), rhs.GetBytes(), sizeof (lldb_private::UUID::ValueType)) < 0;
+bool lldb_private::operator<(const lldb_private::UUID &lhs,
+ const lldb_private::UUID &rhs) {
+ return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
+ sizeof(lldb_private::UUID::ValueType)) < 0;
}
-bool
-lldb_private::operator <= (const lldb_private::UUID &lhs, const lldb_private::UUID &rhs)
-{
- return ::memcmp (lhs.GetBytes(), rhs.GetBytes(), sizeof (lldb_private::UUID::ValueType)) <= 0;
+bool lldb_private::operator<=(const lldb_private::UUID &lhs,
+ const lldb_private::UUID &rhs) {
+ return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
+ sizeof(lldb_private::UUID::ValueType)) <= 0;
}
-bool
-lldb_private::operator > (const lldb_private::UUID &lhs, const lldb_private::UUID &rhs)
-{
- return ::memcmp (lhs.GetBytes(), rhs.GetBytes(), sizeof (lldb_private::UUID::ValueType)) > 0;
+bool lldb_private::operator>(const lldb_private::UUID &lhs,
+ const lldb_private::UUID &rhs) {
+ return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
+ sizeof(lldb_private::UUID::ValueType)) > 0;
}
-bool
-lldb_private::operator >= (const lldb_private::UUID &lhs, const lldb_private::UUID &rhs)
-{
- return ::memcmp (lhs.GetBytes(), rhs.GetBytes(), sizeof (lldb_private::UUID::ValueType)) >= 0;
+bool lldb_private::operator>=(const lldb_private::UUID &lhs,
+ const lldb_private::UUID &rhs) {
+ return ::memcmp(lhs.GetBytes(), rhs.GetBytes(),
+ sizeof(lldb_private::UUID::ValueType)) >= 0;
}
diff --git a/source/Core/UserID.cpp b/source/Core/UserID.cpp
index f3d6e5b22185..5446154c1d27 100644
--- a/source/Core/UserID.cpp
+++ b/source/Core/UserID.cpp
@@ -15,9 +15,7 @@
using namespace lldb;
using namespace lldb_private;
-Stream&
-lldb_private::operator << (Stream& strm, const UserID& uid)
-{
- strm.Printf("{0x%8.8" PRIx64 "}", uid.GetID());
- return strm;
+Stream &lldb_private::operator<<(Stream &strm, const UserID &uid) {
+ strm.Printf("{0x%8.8" PRIx64 "}", uid.GetID());
+ return strm;
}
diff --git a/source/Core/UserSettingsController.cpp b/source/Core/UserSettingsController.cpp
index 6313fa1eb13a..92c3c8440d15 100644
--- a/source/Core/UserSettingsController.cpp
+++ b/source/Core/UserSettingsController.cpp
@@ -1,4 +1,5 @@
-//====-- UserSettingsController.cpp ------------------------------*- C++ -*-===//
+//====-- UserSettingsController.cpp ------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,14 +8,14 @@
//
//===----------------------------------------------------------------------===//
-#include <string.h>
#include <algorithm>
+#include <string.h>
-#include "lldb/Core/UserSettingsController.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/Core/UserSettingsController.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/OptionValueProperties.h"
#include "lldb/Interpreter/OptionValueString.h"
@@ -22,113 +23,81 @@
using namespace lldb;
using namespace lldb_private;
-
lldb::OptionValueSP
-Properties::GetPropertyValue (const ExecutionContext *exe_ctx,
- const char *path,
- bool will_modify,
- Error &error) const
-{
- OptionValuePropertiesSP properties_sp (GetValueProperties ());
- if (properties_sp)
- return properties_sp->GetSubValue(exe_ctx, path, will_modify, error);
- return lldb::OptionValueSP();
+Properties::GetPropertyValue(const ExecutionContext *exe_ctx, llvm::StringRef path,
+ bool will_modify, Error &error) const {
+ OptionValuePropertiesSP properties_sp(GetValueProperties());
+ if (properties_sp)
+ return properties_sp->GetSubValue(exe_ctx, path, will_modify, error);
+ return lldb::OptionValueSP();
}
-Error
-Properties::SetPropertyValue (const ExecutionContext *exe_ctx,
- VarSetOperationType op,
- const char *path,
- const char *value)
-{
- OptionValuePropertiesSP properties_sp (GetValueProperties ());
- if (properties_sp)
- return properties_sp->SetSubValue(exe_ctx, op, path, value);
- Error error;
- error.SetErrorString ("no properties");
- return error;
+Error Properties::SetPropertyValue(const ExecutionContext *exe_ctx,
+ VarSetOperationType op, llvm::StringRef path,
+ llvm::StringRef value) {
+ OptionValuePropertiesSP properties_sp(GetValueProperties());
+ if (properties_sp)
+ return properties_sp->SetSubValue(exe_ctx, op, path, value);
+ Error error;
+ error.SetErrorString("no properties");
+ return error;
}
-void
-Properties::DumpAllPropertyValues (const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask)
-{
- OptionValuePropertiesSP properties_sp (GetValueProperties ());
- if (properties_sp)
- return properties_sp->DumpValue (exe_ctx, strm, dump_mask);
+void Properties::DumpAllPropertyValues(const ExecutionContext *exe_ctx,
+ Stream &strm, uint32_t dump_mask) {
+ OptionValuePropertiesSP properties_sp(GetValueProperties());
+ if (properties_sp)
+ return properties_sp->DumpValue(exe_ctx, strm, dump_mask);
}
-void
-Properties::DumpAllDescriptions (CommandInterpreter &interpreter,
- Stream &strm) const
-{
- strm.PutCString("Top level variables:\n\n");
+void Properties::DumpAllDescriptions(CommandInterpreter &interpreter,
+ Stream &strm) const {
+ strm.PutCString("Top level variables:\n\n");
- OptionValuePropertiesSP properties_sp (GetValueProperties ());
- if (properties_sp)
- return properties_sp->DumpAllDescriptions (interpreter, strm);
+ OptionValuePropertiesSP properties_sp(GetValueProperties());
+ if (properties_sp)
+ return properties_sp->DumpAllDescriptions(interpreter, strm);
}
-
-
-Error
-Properties::DumpPropertyValue (const ExecutionContext *exe_ctx, Stream &strm, const char *property_path, uint32_t dump_mask)
-{
- OptionValuePropertiesSP properties_sp (GetValueProperties ());
- if (properties_sp)
- {
- return properties_sp->DumpPropertyValue (exe_ctx,
- strm,
- property_path,
- dump_mask);
- }
- Error error;
- error.SetErrorString("empty property list");
- return error;
+Error Properties::DumpPropertyValue(const ExecutionContext *exe_ctx,
+ Stream &strm, llvm::StringRef property_path,
+ uint32_t dump_mask) {
+ OptionValuePropertiesSP properties_sp(GetValueProperties());
+ if (properties_sp) {
+ return properties_sp->DumpPropertyValue(exe_ctx, strm, property_path,
+ dump_mask);
+ }
+ Error error;
+ error.SetErrorString("empty property list");
+ return error;
}
size_t
-Properties::Apropos (const char *keyword, std::vector<const Property *> &matching_properties) const
-{
- OptionValuePropertiesSP properties_sp (GetValueProperties ());
- if (properties_sp)
- {
- properties_sp->Apropos (keyword, matching_properties);
- }
- return matching_properties.size();
+Properties::Apropos(llvm::StringRef keyword,
+ std::vector<const Property *> &matching_properties) const {
+ OptionValuePropertiesSP properties_sp(GetValueProperties());
+ if (properties_sp) {
+ properties_sp->Apropos(keyword, matching_properties);
+ }
+ return matching_properties.size();
}
-
lldb::OptionValuePropertiesSP
-Properties::GetSubProperty (const ExecutionContext *exe_ctx,
- const ConstString &name)
-{
- OptionValuePropertiesSP properties_sp (GetValueProperties ());
- if (properties_sp)
- return properties_sp->GetSubProperty (exe_ctx, name);
- return lldb::OptionValuePropertiesSP();
+Properties::GetSubProperty(const ExecutionContext *exe_ctx,
+ const ConstString &name) {
+ OptionValuePropertiesSP properties_sp(GetValueProperties());
+ if (properties_sp)
+ return properties_sp->GetSubProperty(exe_ctx, name);
+ return lldb::OptionValuePropertiesSP();
}
-const char *
-Properties::GetExperimentalSettingsName()
-{
- return "experimental";
-}
+const char *Properties::GetExperimentalSettingsName() { return "experimental"; }
-bool
-Properties::IsSettingExperimental(const char *setting)
-{
- if (setting == nullptr)
- return false;
-
- const char *experimental = GetExperimentalSettingsName();
- const char *dot_pos = strchr(setting, '.');
- if (dot_pos == nullptr)
- return strcmp(experimental, setting) == 0;
- else
- {
- size_t first_elem_len = dot_pos - setting;
- return strncmp(experimental, setting, first_elem_len) == 0;
- }
+bool Properties::IsSettingExperimental(llvm::StringRef setting) {
+ if (setting.empty())
+ return false;
+ llvm::StringRef experimental = GetExperimentalSettingsName();
+ size_t dot_pos = setting.find_first_of('.');
+ return setting.take_front(dot_pos) == experimental;
}
-
diff --git a/source/Core/VMRange.cpp b/source/Core/VMRange.cpp
index 902489e1ff38..8d21f4b1273c 100644
--- a/source/Core/VMRange.cpp
+++ b/source/Core/VMRange.cpp
@@ -16,97 +16,82 @@
using namespace lldb;
using namespace lldb_private;
-bool
-VMRange::ContainsValue(const VMRange::collection& coll, lldb::addr_t value)
-{
- ValueInRangeUnaryPredicate in_range_predicate(value);
- VMRange::const_iterator pos;
- VMRange::const_iterator end = coll.end();
- pos = std::find_if( coll.begin(), end, in_range_predicate );
- if (pos != end)
- return true;
- return false;
+bool VMRange::ContainsValue(const VMRange::collection &coll,
+ lldb::addr_t value) {
+ ValueInRangeUnaryPredicate in_range_predicate(value);
+ VMRange::const_iterator pos;
+ VMRange::const_iterator end = coll.end();
+ pos = std::find_if(coll.begin(), end, in_range_predicate);
+ if (pos != end)
+ return true;
+ return false;
}
-bool
-VMRange::ContainsRange(const VMRange::collection& coll, const VMRange& range)
-{
- RangeInRangeUnaryPredicate in_range_predicate(range);
- VMRange::const_iterator pos;
- VMRange::const_iterator end = coll.end();
- pos = std::find_if( coll.begin(), end, in_range_predicate );
- if (pos != end)
- return true;
- return false;
+bool VMRange::ContainsRange(const VMRange::collection &coll,
+ const VMRange &range) {
+ RangeInRangeUnaryPredicate in_range_predicate(range);
+ VMRange::const_iterator pos;
+ VMRange::const_iterator end = coll.end();
+ pos = std::find_if(coll.begin(), end, in_range_predicate);
+ if (pos != end)
+ return true;
+ return false;
}
-size_t
-VMRange::FindRangeIndexThatContainsValue (const VMRange::collection& coll, lldb::addr_t value)
-{
- ValueInRangeUnaryPredicate in_range_predicate(value);
- VMRange::const_iterator begin = coll.begin();
- VMRange::const_iterator end = coll.end();
- VMRange::const_iterator pos = std::find_if (begin, end, in_range_predicate);
- if (pos != end)
- return std::distance (begin, pos);
- return UINT32_MAX;
+size_t VMRange::FindRangeIndexThatContainsValue(const VMRange::collection &coll,
+ lldb::addr_t value) {
+ ValueInRangeUnaryPredicate in_range_predicate(value);
+ VMRange::const_iterator begin = coll.begin();
+ VMRange::const_iterator end = coll.end();
+ VMRange::const_iterator pos = std::find_if(begin, end, in_range_predicate);
+ if (pos != end)
+ return std::distance(begin, pos);
+ return UINT32_MAX;
}
-void
-VMRange::Dump(Stream *s, lldb::addr_t offset, uint32_t addr_width) const
-{
- s->AddressRange(offset + GetBaseAddress(), offset + GetEndAddress(), addr_width);
+void VMRange::Dump(Stream *s, lldb::addr_t offset, uint32_t addr_width) const {
+ s->AddressRange(offset + GetBaseAddress(), offset + GetEndAddress(),
+ addr_width);
}
-bool
-lldb_private::operator== (const VMRange& lhs, const VMRange& rhs)
-{
- return lhs.GetBaseAddress() == rhs.GetBaseAddress() && lhs.GetEndAddress() == rhs.GetEndAddress();
+bool lldb_private::operator==(const VMRange &lhs, const VMRange &rhs) {
+ return lhs.GetBaseAddress() == rhs.GetBaseAddress() &&
+ lhs.GetEndAddress() == rhs.GetEndAddress();
}
-bool
-lldb_private::operator!= (const VMRange& lhs, const VMRange& rhs)
-{
- return lhs.GetBaseAddress() != rhs.GetBaseAddress() || lhs.GetEndAddress() != rhs.GetEndAddress();
+bool lldb_private::operator!=(const VMRange &lhs, const VMRange &rhs) {
+ return lhs.GetBaseAddress() != rhs.GetBaseAddress() ||
+ lhs.GetEndAddress() != rhs.GetEndAddress();
}
-bool
-lldb_private::operator< (const VMRange& lhs, const VMRange& rhs)
-{
- if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
- return true;
- else if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
- return false;
- return lhs.GetEndAddress() < rhs.GetEndAddress();
+bool lldb_private::operator<(const VMRange &lhs, const VMRange &rhs) {
+ if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
+ return true;
+ else if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
+ return false;
+ return lhs.GetEndAddress() < rhs.GetEndAddress();
}
-bool
-lldb_private::operator<= (const VMRange& lhs, const VMRange& rhs)
-{
- if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
- return true;
- else if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
- return false;
- return lhs.GetEndAddress() <= rhs.GetEndAddress();
+bool lldb_private::operator<=(const VMRange &lhs, const VMRange &rhs) {
+ if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
+ return true;
+ else if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
+ return false;
+ return lhs.GetEndAddress() <= rhs.GetEndAddress();
}
-bool
-lldb_private::operator> (const VMRange& lhs, const VMRange& rhs)
-{
- if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
- return true;
- else if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
- return false;
- return lhs.GetEndAddress() > rhs.GetEndAddress();
+bool lldb_private::operator>(const VMRange &lhs, const VMRange &rhs) {
+ if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
+ return true;
+ else if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
+ return false;
+ return lhs.GetEndAddress() > rhs.GetEndAddress();
}
-bool
-lldb_private::operator>= (const VMRange& lhs, const VMRange& rhs)
-{
- if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
- return true;
- else if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
- return false;
- return lhs.GetEndAddress() >= rhs.GetEndAddress();
+bool lldb_private::operator>=(const VMRange &lhs, const VMRange &rhs) {
+ if (lhs.GetBaseAddress() > rhs.GetBaseAddress())
+ return true;
+ else if (lhs.GetBaseAddress() < rhs.GetBaseAddress())
+ return false;
+ return lhs.GetEndAddress() >= rhs.GetEndAddress();
}
-
diff --git a/source/Core/Value.cpp b/source/Core/Value.cpp
index eb250eb77e46..a480c3cf375a 100644
--- a/source/Core/Value.cpp
+++ b/source/Core/Value.cpp
@@ -13,13 +13,13 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/DataBufferHeap.h"
+#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/State.h"
#include "lldb/Core/Stream.h"
-#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
@@ -32,828 +32,675 @@
using namespace lldb;
using namespace lldb_private;
-Value::Value() :
- m_value (),
- m_vector (),
- m_compiler_type (),
- m_context (NULL),
- m_value_type (eValueTypeScalar),
- m_context_type (eContextTypeInvalid),
- m_data_buffer ()
-{
-}
+Value::Value()
+ : m_value(), m_vector(), m_compiler_type(), m_context(NULL),
+ m_value_type(eValueTypeScalar), m_context_type(eContextTypeInvalid),
+ m_data_buffer() {}
+
+Value::Value(const Scalar &scalar)
+ : m_value(scalar), m_vector(), m_compiler_type(), m_context(NULL),
+ m_value_type(eValueTypeScalar), m_context_type(eContextTypeInvalid),
+ m_data_buffer() {}
+
+Value::Value(const void *bytes, int len)
+ : m_value(), m_vector(), m_compiler_type(), m_context(NULL),
+ m_value_type(eValueTypeHostAddress), m_context_type(eContextTypeInvalid),
+ m_data_buffer() {
+ SetBytes(bytes, len);
+}
+
+Value::Value(const Value &v)
+ : m_value(v.m_value), m_vector(v.m_vector),
+ 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),
+ m_data_buffer() {
+ const uintptr_t rhs_value =
+ (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ if ((rhs_value != 0) &&
+ (rhs_value == (uintptr_t)v.m_data_buffer.GetBytes())) {
+ m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),
+ v.m_data_buffer.GetByteSize());
-Value::Value(const Scalar& scalar) :
- m_value (scalar),
- m_vector (),
- m_compiler_type (),
- m_context (NULL),
- m_value_type (eValueTypeScalar),
- m_context_type (eContextTypeInvalid),
- m_data_buffer ()
-{
-}
-
-
-Value::Value(const void *bytes, int len) :
- m_value (),
- m_vector (),
- m_compiler_type (),
- m_context (NULL),
- m_value_type (eValueTypeHostAddress),
- m_context_type (eContextTypeInvalid),
- m_data_buffer ()
-{
- SetBytes(bytes, len);
-}
-
-Value::Value(const Value &v) :
- m_value (v.m_value),
- m_vector (v.m_vector),
- 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),
- m_data_buffer ()
-{
- const uintptr_t rhs_value = (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);
- if ((rhs_value != 0) && (rhs_value == (uintptr_t)v.m_data_buffer.GetBytes()))
- {
- m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),
- v.m_data_buffer.GetByteSize());
-
- m_value = (uintptr_t)m_data_buffer.GetBytes();
+ m_value = (uintptr_t)m_data_buffer.GetBytes();
+ }
+}
+
+Value &Value::operator=(const Value &rhs) {
+ if (this != &rhs) {
+ m_value = rhs.m_value;
+ m_vector = rhs.m_vector;
+ 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;
+ const uintptr_t rhs_value =
+ (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ if ((rhs_value != 0) &&
+ (rhs_value == (uintptr_t)rhs.m_data_buffer.GetBytes())) {
+ m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),
+ rhs.m_data_buffer.GetByteSize());
+
+ m_value = (uintptr_t)m_data_buffer.GetBytes();
}
-}
-
-Value &
-Value::operator=(const Value &rhs)
-{
- if (this != &rhs)
- {
- m_value = rhs.m_value;
- m_vector = rhs.m_vector;
- 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;
- const uintptr_t rhs_value = (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS);
- if ((rhs_value != 0) && (rhs_value == (uintptr_t)rhs.m_data_buffer.GetBytes()))
- {
- m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),
- rhs.m_data_buffer.GetByteSize());
-
- m_value = (uintptr_t)m_data_buffer.GetBytes();
- }
+ }
+ return *this;
+}
+
+void Value::SetBytes(const void *bytes, int len) {
+ m_value_type = eValueTypeHostAddress;
+ m_data_buffer.CopyData(bytes, len);
+ m_value = (uintptr_t)m_data_buffer.GetBytes();
+}
+
+void Value::AppendBytes(const void *bytes, int len) {
+ m_value_type = eValueTypeHostAddress;
+ m_data_buffer.AppendData(bytes, len);
+ m_value = (uintptr_t)m_data_buffer.GetBytes();
+}
+
+void Value::Dump(Stream *strm) {
+ m_value.GetValue(strm, true);
+ strm->Printf(", value_type = %s, context = %p, context_type = %s",
+ Value::GetValueTypeAsCString(m_value_type), m_context,
+ Value::GetContextTypeAsCString(m_context_type));
+}
+
+Value::ValueType Value::GetValueType() const { return m_value_type; }
+
+AddressType Value::GetValueAddressType() const {
+ switch (m_value_type) {
+ default:
+ case eValueTypeScalar:
+ break;
+ case eValueTypeLoadAddress:
+ return eAddressTypeLoad;
+ case eValueTypeFileAddress:
+ return eAddressTypeFile;
+ case eValueTypeHostAddress:
+ return eAddressTypeHost;
+ }
+ return eAddressTypeInvalid;
+}
+
+RegisterInfo *Value::GetRegisterInfo() const {
+ if (m_context_type == eContextTypeRegisterInfo)
+ return static_cast<RegisterInfo *>(m_context);
+ return NULL;
+}
+
+Type *Value::GetType() {
+ if (m_context_type == eContextTypeLLDBType)
+ return static_cast<Type *>(m_context);
+ return NULL;
+}
+
+size_t Value::AppendDataToHostBuffer(const Value &rhs) {
+ size_t curr_size = m_data_buffer.GetByteSize();
+ Error error;
+ switch (rhs.GetValueType()) {
+ case eValueTypeScalar: {
+ const size_t scalar_size = rhs.m_value.GetByteSize();
+ if (scalar_size > 0) {
+ const size_t new_size = curr_size + scalar_size;
+ if (ResizeData(new_size) == new_size) {
+ rhs.m_value.GetAsMemoryData(m_data_buffer.GetBytes() + curr_size,
+ scalar_size, endian::InlHostByteOrder(),
+ error);
+ return scalar_size;
+ }
}
- return *this;
-}
-
-void
-Value::SetBytes (const void *bytes, int len)
-{
- m_value_type = eValueTypeHostAddress;
- m_data_buffer.CopyData(bytes, len);
- m_value = (uintptr_t)m_data_buffer.GetBytes();
-}
-
-void
-Value::AppendBytes (const void *bytes, int len)
-{
- m_value_type = eValueTypeHostAddress;
- m_data_buffer.AppendData (bytes, len);
- m_value = (uintptr_t)m_data_buffer.GetBytes();
-}
-
-void
-Value::Dump (Stream* strm)
-{
- m_value.GetValue (strm, true);
- strm->Printf(", value_type = %s, context = %p, context_type = %s",
- Value::GetValueTypeAsCString(m_value_type),
- m_context,
- Value::GetContextTypeAsCString(m_context_type));
-}
-
-Value::ValueType
-Value::GetValueType() const
-{
- return m_value_type;
-}
-
-AddressType
-Value::GetValueAddressType () const
-{
- switch (m_value_type)
- {
- default:
- case eValueTypeScalar:
- break;
- case eValueTypeLoadAddress: return eAddressTypeLoad;
- case eValueTypeFileAddress: return eAddressTypeFile;
- case eValueTypeHostAddress: return eAddressTypeHost;
+ } break;
+ case eValueTypeVector: {
+ const size_t vector_size = rhs.m_vector.length;
+ if (vector_size > 0) {
+ const size_t new_size = curr_size + vector_size;
+ if (ResizeData(new_size) == new_size) {
+ ::memcpy(m_data_buffer.GetBytes() + curr_size, rhs.m_vector.bytes,
+ vector_size);
+ return vector_size;
+ }
+ }
+ } break;
+ case eValueTypeFileAddress:
+ case eValueTypeLoadAddress:
+ case eValueTypeHostAddress: {
+ const uint8_t *src = rhs.GetBuffer().GetBytes();
+ const size_t src_len = rhs.GetBuffer().GetByteSize();
+ if (src && src_len > 0) {
+ const size_t new_size = curr_size + src_len;
+ if (ResizeData(new_size) == new_size) {
+ ::memcpy(m_data_buffer.GetBytes() + curr_size, src, src_len);
+ return src_len;
+ }
}
- return eAddressTypeInvalid;
+ } break;
+ }
+ return 0;
}
-RegisterInfo *
-Value::GetRegisterInfo() const
-{
- if (m_context_type == eContextTypeRegisterInfo)
- return static_cast<RegisterInfo *> (m_context);
- return NULL;
+size_t Value::ResizeData(size_t len) {
+ m_value_type = eValueTypeHostAddress;
+ m_data_buffer.SetByteSize(len);
+ m_value = (uintptr_t)m_data_buffer.GetBytes();
+ return m_data_buffer.GetByteSize();
}
-Type *
-Value::GetType()
-{
- if (m_context_type == eContextTypeLLDBType)
- return static_cast<Type *> (m_context);
- return NULL;
-}
+bool Value::ValueOf(ExecutionContext *exe_ctx) {
+ switch (m_context_type) {
+ case eContextTypeInvalid:
+ case eContextTypeRegisterInfo: // RegisterInfo *
+ case eContextTypeLLDBType: // Type *
+ break;
-size_t
-Value::AppendDataToHostBuffer (const Value &rhs)
-{
- size_t curr_size = m_data_buffer.GetByteSize();
- Error error;
- switch (rhs.GetValueType())
- {
- case eValueTypeScalar:
- {
- const size_t scalar_size = rhs.m_value.GetByteSize();
- if (scalar_size > 0)
- {
- const size_t new_size = curr_size + scalar_size;
- if (ResizeData(new_size) == new_size)
- {
- rhs.m_value.GetAsMemoryData (m_data_buffer.GetBytes() + curr_size,
- scalar_size,
- endian::InlHostByteOrder(),
- error);
- return scalar_size;
- }
- }
- }
- break;
- case eValueTypeVector:
- {
- const size_t vector_size = rhs.m_vector.length;
- if (vector_size > 0)
- {
- const size_t new_size = curr_size + vector_size;
- if (ResizeData(new_size) == new_size)
- {
- ::memcpy (m_data_buffer.GetBytes() + curr_size,
- rhs.m_vector.bytes,
- vector_size);
- return vector_size;
- }
- }
- }
- break;
- case eValueTypeFileAddress:
- case eValueTypeLoadAddress:
- case eValueTypeHostAddress:
- {
- const uint8_t *src = rhs.GetBuffer().GetBytes();
- const size_t src_len = rhs.GetBuffer().GetByteSize();
- if (src && src_len > 0)
- {
- const size_t new_size = curr_size + src_len;
- if (ResizeData(new_size) == new_size)
- {
- ::memcpy (m_data_buffer.GetBytes() + curr_size, src, src_len);
- return src_len;
- }
- }
- }
- break;
- }
- return 0;
+ case eContextTypeVariable: // Variable *
+ ResolveValue(exe_ctx);
+ return true;
+ }
+ return false;
}
-size_t
-Value::ResizeData(size_t len)
-{
- m_value_type = eValueTypeHostAddress;
- m_data_buffer.SetByteSize(len);
- m_value = (uintptr_t)m_data_buffer.GetBytes();
- return m_data_buffer.GetByteSize();
-}
+uint64_t Value::GetValueByteSize(Error *error_ptr, ExecutionContext *exe_ctx) {
+ uint64_t byte_size = 0;
-bool
-Value::ValueOf(ExecutionContext *exe_ctx)
-{
- switch (m_context_type)
- {
- case eContextTypeInvalid:
- case eContextTypeRegisterInfo: // RegisterInfo *
- case eContextTypeLLDBType: // Type *
- break;
+ switch (m_context_type) {
+ case eContextTypeRegisterInfo: // RegisterInfo *
+ if (GetRegisterInfo())
+ byte_size = GetRegisterInfo()->byte_size;
+ break;
- case eContextTypeVariable: // Variable *
- ResolveValue(exe_ctx);
- return true;
+ case eContextTypeInvalid:
+ case eContextTypeLLDBType: // Type *
+ case eContextTypeVariable: // Variable *
+ {
+ const CompilerType &ast_type = GetCompilerType();
+ if (ast_type.IsValid())
+ byte_size = ast_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
+ } break;
+ }
+
+ if (error_ptr) {
+ if (byte_size == 0) {
+ if (error_ptr->Success())
+ error_ptr->SetErrorString("Unable to determine byte size.");
+ } else {
+ error_ptr->Clear();
}
- return false;
+ }
+ return byte_size;
}
-uint64_t
-Value::GetValueByteSize (Error *error_ptr, ExecutionContext *exe_ctx)
-{
- uint64_t byte_size = 0;
-
- switch (m_context_type)
- {
- case eContextTypeRegisterInfo: // RegisterInfo *
- if (GetRegisterInfo())
- byte_size = GetRegisterInfo()->byte_size;
- break;
-
+const CompilerType &Value::GetCompilerType() {
+ if (!m_compiler_type.IsValid()) {
+ switch (m_context_type) {
case eContextTypeInvalid:
- case eContextTypeLLDBType: // Type *
- case eContextTypeVariable: // Variable *
- {
- const CompilerType &ast_type = GetCompilerType();
- if (ast_type.IsValid())
- byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
- }
- break;
- }
+ break;
- if (error_ptr)
- {
- if (byte_size == 0)
- {
- if (error_ptr->Success())
- error_ptr->SetErrorString("Unable to determine byte size.");
- }
- else
- {
- error_ptr->Clear();
- }
- }
- return byte_size;
-}
-
-const CompilerType &
-Value::GetCompilerType ()
-{
- if (!m_compiler_type.IsValid())
- {
- switch (m_context_type)
- {
- case eContextTypeInvalid:
- break;
-
- case eContextTypeRegisterInfo:
- break; // TODO: Eventually convert into a compiler type?
-
- case eContextTypeLLDBType:
- {
- Type *lldb_type = GetType();
- if (lldb_type)
- m_compiler_type = lldb_type->GetForwardCompilerType ();
- }
- break;
-
- case eContextTypeVariable:
- {
- Variable *variable = GetVariable();
- if (variable)
- {
- Type *variable_type = variable->GetType();
- if (variable_type)
- m_compiler_type = variable_type->GetForwardCompilerType ();
- }
- }
- break;
- }
+ case eContextTypeRegisterInfo:
+ break; // TODO: Eventually convert into a compiler type?
+
+ case eContextTypeLLDBType: {
+ Type *lldb_type = GetType();
+ if (lldb_type)
+ m_compiler_type = lldb_type->GetForwardCompilerType();
+ } break;
+
+ case eContextTypeVariable: {
+ Variable *variable = GetVariable();
+ if (variable) {
+ Type *variable_type = variable->GetType();
+ if (variable_type)
+ m_compiler_type = variable_type->GetForwardCompilerType();
+ }
+ } break;
}
+ }
- return m_compiler_type;
+ return m_compiler_type;
}
-void
-Value::SetCompilerType (const CompilerType &compiler_type)
-{
- m_compiler_type = compiler_type;
+void Value::SetCompilerType(const CompilerType &compiler_type) {
+ m_compiler_type = compiler_type;
}
-lldb::Format
-Value::GetValueDefaultFormat ()
-{
- switch (m_context_type)
- {
- case eContextTypeRegisterInfo:
- if (GetRegisterInfo())
- return GetRegisterInfo()->format;
- break;
-
- case eContextTypeInvalid:
- case eContextTypeLLDBType:
- case eContextTypeVariable:
- {
- const CompilerType &ast_type = GetCompilerType();
- if (ast_type.IsValid())
- return ast_type.GetFormat();
- }
- break;
+lldb::Format Value::GetValueDefaultFormat() {
+ switch (m_context_type) {
+ case eContextTypeRegisterInfo:
+ if (GetRegisterInfo())
+ return GetRegisterInfo()->format;
+ break;
+ case eContextTypeInvalid:
+ case eContextTypeLLDBType:
+ case eContextTypeVariable: {
+ const CompilerType &ast_type = GetCompilerType();
+ if (ast_type.IsValid())
+ return ast_type.GetFormat();
+ } break;
+ }
+
+ // Return a good default in case we can't figure anything out
+ return eFormatHex;
+}
+
+bool Value::GetData(DataExtractor &data) {
+ switch (m_value_type) {
+ default:
+ break;
+
+ case eValueTypeScalar:
+ if (m_value.GetData(data))
+ return true;
+ break;
+
+ case eValueTypeLoadAddress:
+ case eValueTypeFileAddress:
+ case eValueTypeHostAddress:
+ if (m_data_buffer.GetByteSize()) {
+ data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(),
+ data.GetByteOrder());
+ return true;
}
+ break;
+ }
- // Return a good default in case we can't figure anything out
- return eFormatHex;
+ return false;
}
-bool
-Value::GetData (DataExtractor &data)
-{
- switch (m_value_type)
- {
- default:
- break;
-
- case eValueTypeScalar:
- if (m_value.GetData (data))
- return true;
- break;
+Error Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
+ uint32_t data_offset, Module *module) {
+ data.Clear();
- case eValueTypeLoadAddress:
- case eValueTypeFileAddress:
- case eValueTypeHostAddress:
- if (m_data_buffer.GetByteSize())
- {
- data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(), data.GetByteOrder());
- return true;
- }
- break;
- }
+ Error error;
+ lldb::addr_t address = LLDB_INVALID_ADDRESS;
+ AddressType address_type = eAddressTypeFile;
+ Address file_so_addr;
+ const CompilerType &ast_type = GetCompilerType();
+ switch (m_value_type) {
+ case eValueTypeVector:
+ if (ast_type.IsValid())
+ data.SetAddressByteSize(ast_type.GetPointerByteSize());
+ else
+ data.SetAddressByteSize(sizeof(void *));
+ data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order);
+ break;
+
+ case eValueTypeScalar: {
+ data.SetByteOrder(endian::InlHostByteOrder());
+ if (ast_type.IsValid())
+ data.SetAddressByteSize(ast_type.GetPointerByteSize());
+ else
+ data.SetAddressByteSize(sizeof(void *));
- return false;
+ uint32_t limit_byte_size = UINT32_MAX;
-}
+ if (ast_type.IsValid()) {
+ limit_byte_size = ast_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
+ }
-Error
-Value::GetValueAsData (ExecutionContext *exe_ctx,
- DataExtractor &data,
- uint32_t data_offset,
- Module *module)
-{
- data.Clear();
-
- Error error;
- lldb::addr_t address = LLDB_INVALID_ADDRESS;
- AddressType address_type = eAddressTypeFile;
- Address file_so_addr;
- const CompilerType &ast_type = GetCompilerType();
- switch (m_value_type)
- {
- case eValueTypeVector:
- if (ast_type.IsValid())
- data.SetAddressByteSize (ast_type.GetPointerByteSize());
- else
- data.SetAddressByteSize(sizeof(void *));
- data.SetData(m_vector.bytes, m_vector.length, m_vector.byte_order);
- break;
+ if (limit_byte_size <= m_value.GetByteSize()) {
+ if (m_value.GetData(data, limit_byte_size))
+ return error; // Success;
+ }
- case eValueTypeScalar:
- {
- data.SetByteOrder (endian::InlHostByteOrder());
- if (ast_type.IsValid())
- data.SetAddressByteSize (ast_type.GetPointerByteSize());
- else
- data.SetAddressByteSize(sizeof(void *));
-
- uint32_t limit_byte_size = UINT32_MAX;
-
- if (ast_type.IsValid())
- {
- limit_byte_size = ast_type.GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
- }
-
- if (limit_byte_size <= m_value.GetByteSize())
- {
- if (m_value.GetData (data, limit_byte_size))
- return error; // Success;
- }
-
- error.SetErrorStringWithFormat("extracting data from value failed");
- break;
- }
- case eValueTypeLoadAddress:
- if (exe_ctx == NULL)
- {
- error.SetErrorString ("can't read load address (no execution context)");
+ error.SetErrorStringWithFormat("extracting data from value failed");
+ break;
+ }
+ case eValueTypeLoadAddress:
+ if (exe_ctx == NULL) {
+ error.SetErrorString("can't read load address (no execution context)");
+ } else {
+ Process *process = exe_ctx->GetProcessPtr();
+ if (process == NULL || !process->IsAlive()) {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target) {
+ // Allow expressions to run and evaluate things when the target
+ // has memory sections loaded. This allows you to use "target modules
+ // load"
+ // to load your executable and any shared libraries, then execute
+ // commands where you can look at types in data sections.
+ const SectionLoadList &target_sections = target->GetSectionLoadList();
+ if (!target_sections.IsEmpty()) {
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ if (target_sections.ResolveLoadAddress(address, file_so_addr)) {
+ address_type = eAddressTypeLoad;
+ data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(
+ target->GetArchitecture().GetAddressByteSize());
+ } else
+ address = LLDB_INVALID_ADDRESS;
+ }
+ // else
+ // {
+ // ModuleSP exe_module_sp
+ // (target->GetExecutableModule());
+ // if (exe_module_sp)
+ // {
+ // address =
+ // m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ // if (address != LLDB_INVALID_ADDRESS)
+ // {
+ // if
+ // (exe_module_sp->ResolveFileAddress(address,
+ // file_so_addr))
+ // {
+ // data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ // data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ // address_type = eAddressTypeFile;
+ // }
+ // else
+ // {
+ // address = LLDB_INVALID_ADDRESS;
+ // }
+ // }
+ // }
+ // }
+ } else {
+ error.SetErrorString("can't read load address (invalid process)");
}
- else
- {
- Process *process = exe_ctx->GetProcessPtr();
- if (process == NULL || !process->IsAlive())
- {
- Target *target = exe_ctx->GetTargetPtr();
- if (target)
- {
- // Allow expressions to run and evaluate things when the target
- // has memory sections loaded. This allows you to use "target modules load"
- // to load your executable and any shared libraries, then execute
- // commands where you can look at types in data sections.
- const SectionLoadList &target_sections = target->GetSectionLoadList();
- if (!target_sections.IsEmpty())
- {
- address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- if (target_sections.ResolveLoadAddress(address, file_so_addr))
- {
- address_type = eAddressTypeLoad;
- data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
- }
- else
- address = LLDB_INVALID_ADDRESS;
- }
-// else
-// {
-// ModuleSP exe_module_sp (target->GetExecutableModule());
-// if (exe_module_sp)
-// {
-// address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
-// if (address != LLDB_INVALID_ADDRESS)
-// {
-// if (exe_module_sp->ResolveFileAddress(address, file_so_addr))
-// {
-// data.SetByteOrder(target->GetArchitecture().GetByteOrder());
-// data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
-// address_type = eAddressTypeFile;
-// }
-// else
-// {
-// address = LLDB_INVALID_ADDRESS;
-// }
-// }
-// }
-// }
- }
- else
- {
- error.SetErrorString ("can't read load address (invalid process)");
- }
- }
- else
- {
- address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- address_type = eAddressTypeLoad;
- data.SetByteOrder(process->GetTarget().GetArchitecture().GetByteOrder());
- data.SetAddressByteSize(process->GetTarget().GetArchitecture().GetAddressByteSize());
- }
+ } else {
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ address_type = eAddressTypeLoad;
+ data.SetByteOrder(
+ process->GetTarget().GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(
+ process->GetTarget().GetArchitecture().GetAddressByteSize());
+ }
+ }
+ break;
+
+ case eValueTypeFileAddress:
+ if (exe_ctx == NULL) {
+ error.SetErrorString("can't read file address (no execution context)");
+ } else if (exe_ctx->GetTargetPtr() == NULL) {
+ error.SetErrorString("can't read file address (invalid target)");
+ } else {
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ if (address == LLDB_INVALID_ADDRESS) {
+ error.SetErrorString("invalid file address");
+ } else {
+ if (module == NULL) {
+ // The only thing we can currently lock down to a module so that
+ // we can resolve a file address, is a variable.
+ Variable *variable = GetVariable();
+ if (variable) {
+ SymbolContext var_sc;
+ variable->CalculateSymbolContext(&var_sc);
+ module = var_sc.module_sp.get();
+ }
}
- break;
- case eValueTypeFileAddress:
- if (exe_ctx == NULL)
- {
- error.SetErrorString ("can't read file address (no execution context)");
- }
- else if (exe_ctx->GetTargetPtr() == NULL)
- {
- error.SetErrorString ("can't read file address (invalid target)");
- }
- else
- {
- address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- if (address == LLDB_INVALID_ADDRESS)
- {
- error.SetErrorString ("invalid file address");
+ if (module) {
+ bool resolved = false;
+ ObjectFile *objfile = module->GetObjectFile();
+ if (objfile) {
+ Address so_addr(address, objfile->GetSectionList());
+ addr_t load_address =
+ so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
+ bool process_launched_and_stopped =
+ exe_ctx->GetProcessPtr()
+ ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(),
+ true /* must_exist */)
+ : false;
+ // Don't use the load address if the process has exited.
+ if (load_address != LLDB_INVALID_ADDRESS &&
+ process_launched_and_stopped) {
+ resolved = true;
+ address = load_address;
+ address_type = eAddressTypeLoad;
+ data.SetByteOrder(
+ exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(exe_ctx->GetTargetRef()
+ .GetArchitecture()
+ .GetAddressByteSize());
+ } else {
+ if (so_addr.IsSectionOffset()) {
+ resolved = true;
+ file_so_addr = so_addr;
+ data.SetByteOrder(objfile->GetByteOrder());
+ data.SetAddressByteSize(objfile->GetAddressByteSize());
+ }
}
- else
- {
- if (module == NULL)
- {
- // The only thing we can currently lock down to a module so that
- // we can resolve a file address, is a variable.
- Variable *variable = GetVariable();
- if (variable)
- {
- SymbolContext var_sc;
- variable->CalculateSymbolContext(&var_sc);
- module = var_sc.module_sp.get();
- }
- }
-
- if (module)
- {
- bool resolved = false;
- ObjectFile *objfile = module->GetObjectFile();
- if (objfile)
- {
- Address so_addr(address, objfile->GetSectionList());
- addr_t load_address = so_addr.GetLoadAddress (exe_ctx->GetTargetPtr());
- bool process_launched_and_stopped = exe_ctx->GetProcessPtr()
- ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(), true /* must_exist */)
- : false;
- // Don't use the load address if the process has exited.
- if (load_address != LLDB_INVALID_ADDRESS && process_launched_and_stopped)
- {
- resolved = true;
- address = load_address;
- address_type = eAddressTypeLoad;
- data.SetByteOrder(exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
- data.SetAddressByteSize(exe_ctx->GetTargetRef().GetArchitecture().GetAddressByteSize());
- }
- else
- {
- if (so_addr.IsSectionOffset())
- {
- resolved = true;
- file_so_addr = so_addr;
- data.SetByteOrder(objfile->GetByteOrder());
- data.SetAddressByteSize(objfile->GetAddressByteSize());
- }
- }
- }
- if (!resolved)
- {
- Variable *variable = GetVariable();
-
- if (module)
- {
- if (variable)
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s' in %s",
- address,
- variable->GetName().AsCString(""),
- module->GetFileSpec().GetPath().c_str());
- else
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " in %s",
- address,
- module->GetFileSpec().GetPath().c_str());
- }
- else
- {
- if (variable)
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64 " for variable '%s'",
- address,
- variable->GetName().AsCString(""));
- else
- error.SetErrorStringWithFormat ("unable to resolve the module for file address 0x%" PRIx64, address);
- }
- }
- }
- else
- {
- // Can't convert a file address to anything valid without more
- // context (which Module it came from)
- error.SetErrorString ("can't read memory from file address without more context");
- }
+ }
+ if (!resolved) {
+ Variable *variable = GetVariable();
+
+ if (module) {
+ if (variable)
+ error.SetErrorStringWithFormat(
+ "unable to resolve the module for file address 0x%" PRIx64
+ " for variable '%s' in %s",
+ address, variable->GetName().AsCString(""),
+ module->GetFileSpec().GetPath().c_str());
+ else
+ error.SetErrorStringWithFormat(
+ "unable to resolve the module for file address 0x%" PRIx64
+ " in %s",
+ address, module->GetFileSpec().GetPath().c_str());
+ } else {
+ if (variable)
+ error.SetErrorStringWithFormat(
+ "unable to resolve the module for file address 0x%" PRIx64
+ " for variable '%s'",
+ address, variable->GetName().AsCString(""));
+ else
+ error.SetErrorStringWithFormat(
+ "unable to resolve the module for file address 0x%" PRIx64,
+ address);
}
+ }
+ } else {
+ // Can't convert a file address to anything valid without more
+ // context (which Module it came from)
+ error.SetErrorString(
+ "can't read memory from file address without more context");
}
+ }
+ }
+ break;
+
+ case eValueTypeHostAddress:
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ address_type = eAddressTypeHost;
+ if (exe_ctx) {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target) {
+ data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
break;
-
- case eValueTypeHostAddress:
- address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- address_type = eAddressTypeHost;
- if (exe_ctx)
- {
- Target *target = exe_ctx->GetTargetPtr();
- if (target)
- {
- data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
- break;
- }
- }
- // fallback to host settings
- data.SetByteOrder(endian::InlHostByteOrder());
- data.SetAddressByteSize(sizeof(void *));
- break;
+ }
}
+ // fallback to host settings
+ data.SetByteOrder(endian::InlHostByteOrder());
+ data.SetAddressByteSize(sizeof(void *));
+ break;
+ }
+
+ // Bail if we encountered any errors
+ if (error.Fail())
+ return error;
- // Bail if we encountered any errors
- if (error.Fail())
- return error;
+ if (address == LLDB_INVALID_ADDRESS) {
+ error.SetErrorStringWithFormat("invalid %s address",
+ address_type == eAddressTypeHost ? "host"
+ : "load");
+ return error;
+ }
- if (address == LLDB_INVALID_ADDRESS)
- {
- error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
- return error;
- }
+ // If we got here, we need to read the value from memory
+ size_t byte_size = GetValueByteSize(&error, exe_ctx);
- // If we got here, we need to read the value from memory
- size_t byte_size = GetValueByteSize (&error, exe_ctx);
+ // Bail if we encountered any errors getting the byte size
+ if (error.Fail())
+ return error;
- // Bail if we encountered any errors getting the byte size
- if (error.Fail())
+ // Make sure we have enough room within "data", and if we don't make
+ // something large enough that does
+ if (!data.ValidOffsetForDataOfSize(data_offset, byte_size)) {
+ DataBufferSP data_sp(new DataBufferHeap(data_offset + byte_size, '\0'));
+ data.SetData(data_sp);
+ }
+
+ uint8_t *dst = const_cast<uint8_t *>(data.PeekData(data_offset, byte_size));
+ if (dst != NULL) {
+ if (address_type == eAddressTypeHost) {
+ // The address is an address in this process, so just copy it.
+ if (address == 0) {
+ error.SetErrorStringWithFormat(
+ "trying to read from host address of 0.");
return error;
-
- // Make sure we have enough room within "data", and if we don't make
- // something large enough that does
- if (!data.ValidOffsetForDataOfSize (data_offset, byte_size))
- {
- DataBufferSP data_sp(new DataBufferHeap (data_offset + byte_size, '\0'));
- data.SetData(data_sp);
- }
-
- uint8_t* dst = const_cast<uint8_t*>(data.PeekData (data_offset, byte_size));
- if (dst != NULL)
- {
- if (address_type == eAddressTypeHost)
- {
- // The address is an address in this process, so just copy it.
- if (address == 0)
- {
- error.SetErrorStringWithFormat("trying to read from host address of 0.");
- return error;
- }
- memcpy (dst, (uint8_t*)NULL + address, byte_size);
- }
- else if ((address_type == eAddressTypeLoad) || (address_type == eAddressTypeFile))
- {
- if (file_so_addr.IsValid())
- {
- // We have a file address that we were able to translate into a
- // section offset address so we might be able to read this from
- // the object files if we don't have a live process. Lets always
- // try and read from the process if we have one though since we
- // want to read the actual value by setting "prefer_file_cache"
- // to false.
- const bool prefer_file_cache = false;
- if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache, dst, byte_size, error) != byte_size)
- {
- error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed", (uint64_t)address);
- }
- }
- else
- {
- // The execution context might have a NULL process, but it
- // might have a valid process in the exe_ctx->target, so use
- // the ExecutionContext::GetProcess accessor to ensure we
- // get the process if there is one.
- Process *process = exe_ctx->GetProcessPtr();
-
- if (process)
- {
- const size_t bytes_read = process->ReadMemory(address, dst, byte_size, error);
- if (bytes_read != byte_size)
- error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
- (uint64_t)address,
- (uint32_t)bytes_read,
- (uint32_t)byte_size);
- }
- else
- {
- error.SetErrorStringWithFormat("read memory from 0x%" PRIx64 " failed (invalid process)", (uint64_t)address);
- }
- }
+ }
+ memcpy(dst, (uint8_t *)NULL + address, byte_size);
+ } else if ((address_type == eAddressTypeLoad) ||
+ (address_type == eAddressTypeFile)) {
+ if (file_so_addr.IsValid()) {
+ // We have a file address that we were able to translate into a
+ // section offset address so we might be able to read this from
+ // the object files if we don't have a live process. Lets always
+ // try and read from the process if we have one though since we
+ // want to read the actual value by setting "prefer_file_cache"
+ // to false.
+ const bool prefer_file_cache = false;
+ if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, prefer_file_cache,
+ dst, byte_size,
+ error) != byte_size) {
+ error.SetErrorStringWithFormat(
+ "read memory from 0x%" PRIx64 " failed", (uint64_t)address);
}
- else
- {
- error.SetErrorStringWithFormat ("unsupported AddressType value (%i)", address_type);
+ } else {
+ // The execution context might have a NULL process, but it
+ // might have a valid process in the exe_ctx->target, so use
+ // the ExecutionContext::GetProcess accessor to ensure we
+ // get the process if there is one.
+ Process *process = exe_ctx->GetProcessPtr();
+
+ if (process) {
+ const size_t bytes_read =
+ process->ReadMemory(address, dst, byte_size, error);
+ if (bytes_read != byte_size)
+ error.SetErrorStringWithFormat(
+ "read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
+ (uint64_t)address, (uint32_t)bytes_read, (uint32_t)byte_size);
+ } else {
+ error.SetErrorStringWithFormat("read memory from 0x%" PRIx64
+ " failed (invalid process)",
+ (uint64_t)address);
}
+ }
+ } else {
+ error.SetErrorStringWithFormat("unsupported AddressType value (%i)",
+ address_type);
}
- else
- {
- error.SetErrorStringWithFormat ("out of memory");
- }
+ } else {
+ error.SetErrorStringWithFormat("out of memory");
+ }
- return error;
+ return error;
}
-Scalar &
-Value::ResolveValue(ExecutionContext *exe_ctx)
-{
- const CompilerType &compiler_type = GetCompilerType();
- if (compiler_type.IsValid())
+Scalar &Value::ResolveValue(ExecutionContext *exe_ctx) {
+ const CompilerType &compiler_type = GetCompilerType();
+ if (compiler_type.IsValid()) {
+ switch (m_value_type) {
+ case eValueTypeScalar: // raw scalar value
+ break;
+
+ default:
+ case eValueTypeFileAddress:
+ case eValueTypeLoadAddress: // load address value
+ case eValueTypeHostAddress: // host address value (for memory in the process
+ // that is using liblldb)
{
- switch (m_value_type)
- {
- case eValueTypeScalar: // raw scalar value
- break;
-
- default:
- case eValueTypeFileAddress:
- case eValueTypeLoadAddress: // load address value
- case eValueTypeHostAddress: // host address value (for memory in the process that is using liblldb)
- {
- DataExtractor data;
- lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
- Error error (GetValueAsData (exe_ctx, data, 0, NULL));
- if (error.Success())
- {
- Scalar scalar;
- if (compiler_type.GetValueAsScalar (data, 0, data.GetByteSize(), scalar))
- {
- m_value = scalar;
- m_value_type = eValueTypeScalar;
- }
- else
- {
- if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
- {
- m_value.Clear();
- m_value_type = eValueTypeScalar;
- }
- }
- }
- else
- {
- if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes())
- {
- m_value.Clear();
- m_value_type = eValueTypeScalar;
- }
- }
- }
- break;
+ DataExtractor data;
+ lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ Error error(GetValueAsData(exe_ctx, data, 0, NULL));
+ if (error.Success()) {
+ Scalar scalar;
+ if (compiler_type.GetValueAsScalar(data, 0, data.GetByteSize(),
+ scalar)) {
+ m_value = scalar;
+ m_value_type = eValueTypeScalar;
+ } else {
+ if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
+ m_value.Clear();
+ m_value_type = eValueTypeScalar;
+ }
}
+ } else {
+ if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
+ m_value.Clear();
+ m_value_type = eValueTypeScalar;
+ }
+ }
+ } break;
}
- return m_value;
-}
-
-Variable *
-Value::GetVariable()
-{
- if (m_context_type == eContextTypeVariable)
- return static_cast<Variable *> (m_context);
+ }
+ return m_value;
+}
+
+Variable *Value::GetVariable() {
+ if (m_context_type == eContextTypeVariable)
+ return static_cast<Variable *>(m_context);
+ return NULL;
+}
+
+void Value::Clear() {
+ m_value.Clear();
+ m_vector.Clear();
+ m_compiler_type.Clear();
+ m_value_type = eValueTypeScalar;
+ m_context = NULL;
+ m_context_type = eContextTypeInvalid;
+ m_data_buffer.Clear();
+}
+
+const char *Value::GetValueTypeAsCString(ValueType value_type) {
+ switch (value_type) {
+ case eValueTypeScalar:
+ return "scalar";
+ case eValueTypeVector:
+ return "vector";
+ case eValueTypeFileAddress:
+ return "file address";
+ case eValueTypeLoadAddress:
+ return "load address";
+ case eValueTypeHostAddress:
+ return "host address";
+ };
+ return "???";
+}
+
+const char *Value::GetContextTypeAsCString(ContextType context_type) {
+ switch (context_type) {
+ case eContextTypeInvalid:
+ return "invalid";
+ case eContextTypeRegisterInfo:
+ return "RegisterInfo *";
+ case eContextTypeLLDBType:
+ return "Type *";
+ case eContextTypeVariable:
+ return "Variable *";
+ };
+ return "???";
+}
+
+ValueList::ValueList(const ValueList &rhs) { m_values = rhs.m_values; }
+
+const ValueList &ValueList::operator=(const ValueList &rhs) {
+ m_values = rhs.m_values;
+ return *this;
+}
+
+void ValueList::PushValue(const Value &value) { m_values.push_back(value); }
+
+size_t ValueList::GetSize() { return m_values.size(); }
+
+Value *ValueList::GetValueAtIndex(size_t idx) {
+ if (idx < GetSize()) {
+ return &(m_values[idx]);
+ } else
return NULL;
}
-void
-Value::Clear()
-{
- m_value.Clear();
- m_vector.Clear();
- m_compiler_type.Clear();
- m_value_type = eValueTypeScalar;
- m_context = NULL;
- m_context_type = eContextTypeInvalid;
- m_data_buffer.Clear();
-}
-
-
-const char *
-Value::GetValueTypeAsCString (ValueType value_type)
-{
- switch (value_type)
- {
- case eValueTypeScalar: return "scalar";
- case eValueTypeVector: return "vector";
- case eValueTypeFileAddress: return "file address";
- case eValueTypeLoadAddress: return "load address";
- case eValueTypeHostAddress: return "host address";
- };
- return "???";
-}
-
-const char *
-Value::GetContextTypeAsCString (ContextType context_type)
-{
- switch (context_type)
- {
- case eContextTypeInvalid: return "invalid";
- case eContextTypeRegisterInfo: return "RegisterInfo *";
- case eContextTypeLLDBType: return "Type *";
- case eContextTypeVariable: return "Variable *";
- };
- return "???";
-}
-
-ValueList::ValueList (const ValueList &rhs)
-{
- m_values = rhs.m_values;
-}
-
-const ValueList &
-ValueList::operator= (const ValueList &rhs)
-{
- m_values = rhs.m_values;
- return *this;
-}
-
-void
-ValueList::PushValue (const Value &value)
-{
- m_values.push_back (value);
-}
-
-size_t
-ValueList::GetSize()
-{
- return m_values.size();
-}
-
-Value *
-ValueList::GetValueAtIndex (size_t idx)
-{
- if (idx < GetSize())
- {
- return &(m_values[idx]);
- }
- else
- return NULL;
-}
-
-void
-ValueList::Clear ()
-{
- m_values.clear();
-}
-
+void ValueList::Clear() { m_values.clear(); }
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index 3e0a31833ef6..fc2312d60d57 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -41,9 +41,9 @@
#include "lldb/Interpreter/CommandInterpreter.h"
-#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Target/ExecutionContext.h"
@@ -65,2032 +65,1684 @@ static user_id_t g_value_obj_uid = 0;
//----------------------------------------------------------------------
// ValueObject constructor
//----------------------------------------------------------------------
-ValueObject::ValueObject (ValueObject &parent) :
- UserID (++g_value_obj_uid), // Unique identifier for every value object
- m_parent (&parent),
- m_root (NULL),
- m_update_point (parent.GetUpdatePoint ()),
- m_name (),
- m_data (),
- m_value (),
- m_error (),
- m_value_str (),
- m_old_value_str (),
- m_location_str (),
- m_summary_str (),
- m_object_desc_str (),
- m_validation_result(),
- m_manager(parent.GetManager()),
- m_children (),
- m_synthetic_children (),
- m_dynamic_value (NULL),
- m_synthetic_value(NULL),
- m_deref_valobj(NULL),
- m_format (eFormatDefault),
- m_last_format (eFormatDefault),
- m_last_format_mgr_revision(0),
- m_type_summary_sp(),
- m_type_format_sp(),
- m_synthetic_children_sp(),
- m_type_validator_sp(),
- m_user_id_of_forced_summary(),
- 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),
- m_old_value_valid (false),
- m_is_deref_of_parent (false),
- m_is_array_item_for_pointer(false),
- m_is_bitfield_for_scalar(false),
- m_is_child_at_offset(false),
- m_is_getting_summary(false),
- m_did_calculate_complete_objc_class_type(false),
- m_is_synthetic_children_generated(parent.m_is_synthetic_children_generated)
-{
- m_manager->ManageObject(this);
+ValueObject::ValueObject(ValueObject &parent)
+ : UserID(++g_value_obj_uid), // Unique identifier for every value object
+ m_parent(&parent), m_root(NULL), m_update_point(parent.GetUpdatePoint()),
+ m_name(), m_data(), m_value(), m_error(), m_value_str(),
+ m_old_value_str(), m_location_str(), m_summary_str(), m_object_desc_str(),
+ m_validation_result(), m_manager(parent.GetManager()), m_children(),
+ m_synthetic_children(), m_dynamic_value(NULL), m_synthetic_value(NULL),
+ m_deref_valobj(NULL), m_format(eFormatDefault),
+ m_last_format(eFormatDefault), m_last_format_mgr_revision(0),
+ m_type_summary_sp(), m_type_format_sp(), m_synthetic_children_sp(),
+ m_type_validator_sp(), m_user_id_of_forced_summary(),
+ 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), m_old_value_valid(false),
+ m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
+ m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
+ m_is_getting_summary(false),
+ m_did_calculate_complete_objc_class_type(false),
+ m_is_synthetic_children_generated(
+ parent.m_is_synthetic_children_generated) {
+ m_manager->ManageObject(this);
}
//----------------------------------------------------------------------
// ValueObject constructor
//----------------------------------------------------------------------
-ValueObject::ValueObject (ExecutionContextScope *exe_scope,
- AddressType child_ptr_or_ref_addr_type) :
- UserID (++g_value_obj_uid), // Unique identifier for every value object
- m_parent (NULL),
- m_root (NULL),
- m_update_point (exe_scope),
- m_name (),
- m_data (),
- m_value (),
- m_error (),
- m_value_str (),
- m_old_value_str (),
- m_location_str (),
- m_summary_str (),
- m_object_desc_str (),
- m_validation_result(),
- m_manager(),
- m_children (),
- m_synthetic_children (),
- m_dynamic_value (NULL),
- m_synthetic_value(NULL),
- m_deref_valobj(NULL),
- m_format (eFormatDefault),
- m_last_format (eFormatDefault),
- m_last_format_mgr_revision(0),
- m_type_summary_sp(),
- m_type_format_sp(),
- m_synthetic_children_sp(),
- m_type_validator_sp(),
- m_user_id_of_forced_summary(),
- 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),
- m_old_value_valid (false),
- m_is_deref_of_parent (false),
- m_is_array_item_for_pointer(false),
- m_is_bitfield_for_scalar(false),
- m_is_child_at_offset(false),
- m_is_getting_summary(false),
- m_did_calculate_complete_objc_class_type(false),
- m_is_synthetic_children_generated(false)
-{
- m_manager = new ValueObjectManager();
- m_manager->ManageObject (this);
+ValueObject::ValueObject(ExecutionContextScope *exe_scope,
+ AddressType child_ptr_or_ref_addr_type)
+ : UserID(++g_value_obj_uid), // Unique identifier for every value object
+ m_parent(NULL), m_root(NULL), m_update_point(exe_scope), m_name(),
+ m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(),
+ m_location_str(), m_summary_str(), m_object_desc_str(),
+ m_validation_result(), m_manager(), m_children(), m_synthetic_children(),
+ m_dynamic_value(NULL), m_synthetic_value(NULL), m_deref_valobj(NULL),
+ m_format(eFormatDefault), m_last_format(eFormatDefault),
+ m_last_format_mgr_revision(0), m_type_summary_sp(), m_type_format_sp(),
+ m_synthetic_children_sp(), m_type_validator_sp(),
+ m_user_id_of_forced_summary(),
+ 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), m_old_value_valid(false),
+ m_is_deref_of_parent(false), m_is_array_item_for_pointer(false),
+ m_is_bitfield_for_scalar(false), m_is_child_at_offset(false),
+ m_is_getting_summary(false),
+ m_did_calculate_complete_objc_class_type(false),
+ m_is_synthetic_children_generated(false) {
+ m_manager = new ValueObjectManager();
+ m_manager->ManageObject(this);
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-ValueObject::~ValueObject ()
-{
-}
+ValueObject::~ValueObject() {}
+
+bool ValueObject::UpdateValueIfNeeded(bool update_format) {
+
+ bool did_change_formats = false;
+
+ if (update_format)
+ did_change_formats = UpdateFormatsIfNeeded();
+
+ // If this is a constant value, then our success is predicated on whether
+ // we have an error or not
+ if (GetIsConstant()) {
+ // if you are constant, things might still have changed behind your back
+ // (e.g. you are a frozen object and things have changed deeper than you
+ // cared to freeze-dry yourself)
+ // in this case, your value has not changed, but "computed" entries might
+ // have, so you might now have
+ // a different summary, or a different object description. clear these so we
+ // will recompute them
+ if (update_format && !did_change_formats)
+ ClearUserVisibleData(eClearUserVisibleDataItemsSummary |
+ eClearUserVisibleDataItemsDescription);
+ return m_error.Success();
+ }
-bool
-ValueObject::UpdateValueIfNeeded (bool update_format)
-{
-
- bool did_change_formats = false;
-
- if (update_format)
- did_change_formats = UpdateFormatsIfNeeded();
-
- // If this is a constant value, then our success is predicated on whether
- // we have an error or not
- if (GetIsConstant())
- {
- // if you are constant, things might still have changed behind your back
- // (e.g. you are a frozen object and things have changed deeper than you cared to freeze-dry yourself)
- // in this case, your value has not changed, but "computed" entries might have, so you might now have
- // a different summary, or a different object description. clear these so we will recompute them
- if (update_format && !did_change_formats)
- ClearUserVisibleData(eClearUserVisibleDataItemsSummary | eClearUserVisibleDataItemsDescription);
- return m_error.Success();
+ bool first_update = IsChecksumEmpty();
+
+ if (NeedsUpdating()) {
+ m_update_point.SetUpdated();
+
+ // Save the old value using swap to avoid a string copy which
+ // also will clear our m_value_str
+ if (m_value_str.empty()) {
+ m_old_value_valid = false;
+ } else {
+ m_old_value_valid = true;
+ m_old_value_str.swap(m_value_str);
+ ClearUserVisibleData(eClearUserVisibleDataItemsValue);
}
- bool first_update = IsChecksumEmpty();
-
- if (NeedsUpdating())
- {
- m_update_point.SetUpdated();
-
- // Save the old value using swap to avoid a string copy which
- // also will clear our m_value_str
- if (m_value_str.empty())
- {
- m_old_value_valid = false;
- }
- else
- {
- m_old_value_valid = true;
- m_old_value_str.swap (m_value_str);
- ClearUserVisibleData(eClearUserVisibleDataItemsValue);
- }
+ ClearUserVisibleData();
- ClearUserVisibleData();
-
- if (IsInScope())
- {
- const bool value_was_valid = GetValueIsValid();
- SetValueDidChange (false);
-
- m_error.Clear();
-
- // Call the pure virtual function to update the value
-
- bool need_compare_checksums = false;
- llvm::SmallVector<uint8_t, 16> old_checksum;
-
- if (!first_update && CanProvideValue())
- {
- need_compare_checksums = true;
- old_checksum.resize(m_value_checksum.size());
- std::copy(m_value_checksum.begin(), m_value_checksum.end(), old_checksum.begin());
- }
-
- bool success = UpdateValue ();
-
- SetValueIsValid (success);
-
- if (success)
- {
- const uint64_t max_checksum_size = 128;
- m_data.Checksum(m_value_checksum,
- max_checksum_size);
- }
- else
- {
- need_compare_checksums = false;
- m_value_checksum.clear();
- }
-
- assert (!need_compare_checksums || (!old_checksum.empty() && !m_value_checksum.empty()));
-
- if (first_update)
- SetValueDidChange (false);
- else if (!m_value_did_change && success == false)
- {
- // The value wasn't gotten successfully, so we mark this
- // as changed if the value used to be valid and now isn't
- SetValueDidChange (value_was_valid);
- }
- else if (need_compare_checksums)
- {
- SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0], m_value_checksum.size()));
- }
-
- }
- else
- {
- m_error.SetErrorString("out of scope");
- }
+ if (IsInScope()) {
+ const bool value_was_valid = GetValueIsValid();
+ SetValueDidChange(false);
+
+ m_error.Clear();
+
+ // Call the pure virtual function to update the value
+
+ bool need_compare_checksums = false;
+ llvm::SmallVector<uint8_t, 16> old_checksum;
+
+ if (!first_update && CanProvideValue()) {
+ need_compare_checksums = true;
+ old_checksum.resize(m_value_checksum.size());
+ std::copy(m_value_checksum.begin(), m_value_checksum.end(),
+ old_checksum.begin());
+ }
+
+ bool success = UpdateValue();
+
+ SetValueIsValid(success);
+
+ if (success) {
+ const uint64_t max_checksum_size = 128;
+ m_data.Checksum(m_value_checksum, max_checksum_size);
+ } else {
+ need_compare_checksums = false;
+ m_value_checksum.clear();
+ }
+
+ assert(!need_compare_checksums ||
+ (!old_checksum.empty() && !m_value_checksum.empty()));
+
+ if (first_update)
+ SetValueDidChange(false);
+ else if (!m_value_did_change && success == false) {
+ // The value wasn't gotten successfully, so we mark this
+ // as changed if the value used to be valid and now isn't
+ SetValueDidChange(value_was_valid);
+ } else if (need_compare_checksums) {
+ SetValueDidChange(memcmp(&old_checksum[0], &m_value_checksum[0],
+ m_value_checksum.size()));
+ }
+
+ } else {
+ m_error.SetErrorString("out of scope");
}
- return m_error.Success();
+ }
+ return m_error.Success();
}
-bool
-ValueObject::UpdateFormatsIfNeeded()
-{
- 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),
- m_last_format_mgr_revision,
- DataVisualization::GetCurrentRevision());
+bool ValueObject::UpdateFormatsIfNeeded() {
+ 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),
+ m_last_format_mgr_revision,
+ DataVisualization::GetCurrentRevision());
- bool any_change = false;
+ bool any_change = false;
- if ( (m_last_format_mgr_revision != DataVisualization::GetCurrentRevision()))
- {
- m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
- any_change = true;
-
- SetValueFormat(DataVisualization::GetFormat (*this, eNoDynamicValues));
- SetSummaryFormat(DataVisualization::GetSummaryFormat (*this, GetDynamicValueType()));
+ if ((m_last_format_mgr_revision != DataVisualization::GetCurrentRevision())) {
+ m_last_format_mgr_revision = DataVisualization::GetCurrentRevision();
+ any_change = true;
+
+ SetValueFormat(DataVisualization::GetFormat(*this, eNoDynamicValues));
+ SetSummaryFormat(
+ DataVisualization::GetSummaryFormat(*this, GetDynamicValueType()));
#ifndef LLDB_DISABLE_PYTHON
- SetSyntheticChildren(DataVisualization::GetSyntheticChildren (*this, GetDynamicValueType()));
+ SetSyntheticChildren(
+ DataVisualization::GetSyntheticChildren(*this, GetDynamicValueType()));
#endif
- SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
- }
+ SetValidator(DataVisualization::GetValidator(*this, GetDynamicValueType()));
+ }
- return any_change;
+ return any_change;
}
-void
-ValueObject::SetNeedsUpdate ()
-{
- m_update_point.SetNeedsUpdate();
- // We have to clear the value string here so ConstResult children will notice if their values are
- // changed by hand (i.e. with SetValueAsCString).
- ClearUserVisibleData(eClearUserVisibleDataItemsValue);
+void ValueObject::SetNeedsUpdate() {
+ m_update_point.SetNeedsUpdate();
+ // We have to clear the value string here so ConstResult children will notice
+ // if their values are
+ // changed by hand (i.e. with SetValueAsCString).
+ ClearUserVisibleData(eClearUserVisibleDataItemsValue);
}
-void
-ValueObject::ClearDynamicTypeInformation ()
-{
- m_children_count_valid = false;
- m_did_calculate_complete_objc_class_type = false;
- m_last_format_mgr_revision = 0;
- m_override_type = CompilerType();
- SetValueFormat(lldb::TypeFormatImplSP());
- SetSummaryFormat(lldb::TypeSummaryImplSP());
- SetSyntheticChildren(lldb::SyntheticChildrenSP());
+void ValueObject::ClearDynamicTypeInformation() {
+ m_children_count_valid = false;
+ m_did_calculate_complete_objc_class_type = false;
+ m_last_format_mgr_revision = 0;
+ m_override_type = CompilerType();
+ SetValueFormat(lldb::TypeFormatImplSP());
+ SetSummaryFormat(lldb::TypeSummaryImplSP());
+ SetSyntheticChildren(lldb::SyntheticChildrenSP());
}
-CompilerType
-ValueObject::MaybeCalculateCompleteType ()
-{
- CompilerType compiler_type(GetCompilerTypeImpl());
-
- if (m_did_calculate_complete_objc_class_type)
- {
- if (m_override_type.IsValid())
- return m_override_type;
- else
- return compiler_type;
- }
-
- CompilerType class_type;
- bool is_pointer_type = false;
-
- if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type))
- {
- is_pointer_type = true;
- }
- else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type))
- {
- class_type = compiler_type;
- }
+CompilerType ValueObject::MaybeCalculateCompleteType() {
+ CompilerType compiler_type(GetCompilerTypeImpl());
+
+ if (m_did_calculate_complete_objc_class_type) {
+ if (m_override_type.IsValid())
+ return m_override_type;
else
- {
- return compiler_type;
- }
-
- m_did_calculate_complete_objc_class_type = true;
-
- if (class_type)
- {
- ConstString class_name (class_type.GetConstTypeName());
-
- if (class_name)
- {
- ProcessSP process_sp(GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
-
- if (process_sp)
- {
- ObjCLanguageRuntime *objc_language_runtime(process_sp->GetObjCLanguageRuntime());
-
- if (objc_language_runtime)
- {
- TypeSP complete_objc_class_type_sp = objc_language_runtime->LookupInCompleteClassCache(class_name);
-
- if (complete_objc_class_type_sp)
- {
- CompilerType complete_class(complete_objc_class_type_sp->GetFullCompilerType ());
-
- if (complete_class.GetCompleteType())
- {
- if (is_pointer_type)
- {
- m_override_type = complete_class.GetPointerType();
- }
- else
- {
- m_override_type = complete_class;
- }
-
- if (m_override_type.IsValid())
- return m_override_type;
- }
- }
- }
- }
- }
- }
+ return compiler_type;
+ }
+
+ CompilerType class_type;
+ bool is_pointer_type = false;
+
+ if (ClangASTContext::IsObjCObjectPointerType(compiler_type, &class_type)) {
+ is_pointer_type = true;
+ } else if (ClangASTContext::IsObjCObjectOrInterfaceType(compiler_type)) {
+ class_type = compiler_type;
+ } else {
return compiler_type;
-}
+ }
-CompilerType
-ValueObject::GetCompilerType ()
-{
- return MaybeCalculateCompleteType();
-}
+ m_did_calculate_complete_objc_class_type = true;
-TypeImpl
-ValueObject::GetTypeImpl ()
-{
- return TypeImpl(GetCompilerType());
-}
+ if (class_type) {
+ ConstString class_name(class_type.GetConstTypeName());
-DataExtractor &
-ValueObject::GetDataExtractor ()
-{
- UpdateValueIfNeeded(false);
- return m_data;
-}
+ if (class_name) {
+ ProcessSP process_sp(
+ GetUpdatePoint().GetExecutionContextRef().GetProcessSP());
-const Error &
-ValueObject::GetError()
-{
- UpdateValueIfNeeded(false);
- return m_error;
-}
+ if (process_sp) {
+ ObjCLanguageRuntime *objc_language_runtime(
+ process_sp->GetObjCLanguageRuntime());
-const ConstString &
-ValueObject::GetName() const
-{
- return m_name;
-}
+ if (objc_language_runtime) {
+ TypeSP complete_objc_class_type_sp =
+ objc_language_runtime->LookupInCompleteClassCache(class_name);
-const char *
-ValueObject::GetLocationAsCString ()
-{
- return GetLocationAsCStringImpl(m_value,
- m_data);
-}
+ if (complete_objc_class_type_sp) {
+ CompilerType complete_class(
+ complete_objc_class_type_sp->GetFullCompilerType());
-const char *
-ValueObject::GetLocationAsCStringImpl (const Value& value,
- const DataExtractor& data)
-{
- if (UpdateValueIfNeeded(false))
- {
- if (m_location_str.empty())
- {
- StreamString sstr;
-
- Value::ValueType value_type = value.GetValueType();
-
- switch (value_type)
- {
- case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
- if (value.GetContextType() == Value::eContextTypeRegisterInfo)
- {
- RegisterInfo *reg_info = value.GetRegisterInfo();
- if (reg_info)
- {
- if (reg_info->name)
- m_location_str = reg_info->name;
- else if (reg_info->alt_name)
- m_location_str = reg_info->alt_name;
- if (m_location_str.empty())
- m_location_str = (reg_info->encoding == lldb::eEncodingVector) ? "vector" : "scalar";
- }
- }
- if (m_location_str.empty())
- m_location_str = (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
- break;
-
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeFileAddress:
- case Value::eValueTypeHostAddress:
- {
- uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
- sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
- m_location_str.swap(sstr.GetString());
- }
- break;
+ if (complete_class.GetCompleteType()) {
+ if (is_pointer_type) {
+ m_override_type = complete_class.GetPointerType();
+ } else {
+ m_override_type = complete_class;
+ }
+
+ if (m_override_type.IsValid())
+ return m_override_type;
}
+ }
}
+ }
}
- return m_location_str.c_str();
+ }
+ return compiler_type;
}
-Value &
-ValueObject::GetValue()
-{
- return m_value;
+CompilerType ValueObject::GetCompilerType() {
+ return MaybeCalculateCompleteType();
}
-const Value &
-ValueObject::GetValue() const
-{
- return m_value;
-}
+TypeImpl ValueObject::GetTypeImpl() { return TypeImpl(GetCompilerType()); }
-bool
-ValueObject::ResolveValue (Scalar &scalar)
-{
- if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Value tmp_value(m_value);
- scalar = tmp_value.ResolveValue(&exe_ctx);
- if (scalar.IsValid())
- {
- const uint32_t bitfield_bit_size = GetBitfieldBitSize();
- if (bitfield_bit_size)
- return scalar.ExtractBitfield (bitfield_bit_size, GetBitfieldBitOffset());
- return true;
- }
- }
- return false;
+DataExtractor &ValueObject::GetDataExtractor() {
+ UpdateValueIfNeeded(false);
+ return m_data;
}
-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;
+const Error &ValueObject::GetError() {
+ UpdateValueIfNeeded(false);
+ return m_error;
}
-bool
-ValueObject::GetValueIsValid () const
-{
- return m_value_is_valid;
+const ConstString &ValueObject::GetName() const { return m_name; }
+
+const char *ValueObject::GetLocationAsCString() {
+ return GetLocationAsCStringImpl(m_value, m_data);
}
+const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
+ const DataExtractor &data) {
+ if (UpdateValueIfNeeded(false)) {
+ if (m_location_str.empty()) {
+ StreamString sstr;
-void
-ValueObject::SetValueIsValid (bool b)
-{
- m_value_is_valid = b;
-}
+ Value::ValueType value_type = value.GetValueType();
+
+ switch (value_type) {
+ case Value::eValueTypeScalar:
+ case Value::eValueTypeVector:
+ if (value.GetContextType() == Value::eContextTypeRegisterInfo) {
+ RegisterInfo *reg_info = value.GetRegisterInfo();
+ if (reg_info) {
+ if (reg_info->name)
+ m_location_str = reg_info->name;
+ else if (reg_info->alt_name)
+ m_location_str = reg_info->alt_name;
+ if (m_location_str.empty())
+ m_location_str = (reg_info->encoding == lldb::eEncodingVector)
+ ? "vector"
+ : "scalar";
+ }
+ }
+ if (m_location_str.empty())
+ m_location_str =
+ (value_type == Value::eValueTypeVector) ? "vector" : "scalar";
+ break;
+
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeHostAddress: {
+ uint32_t addr_nibble_size = data.GetAddressByteSize() * 2;
+ sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size,
+ value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS));
+ m_location_str = sstr.GetString();
+ } break;
+ }
+ }
+ }
+ return m_location_str.c_str();
+}
+
+Value &ValueObject::GetValue() { return m_value; }
+
+const Value &ValueObject::GetValue() const { return m_value; }
+
+bool ValueObject::ResolveValue(Scalar &scalar) {
+ if (UpdateValueIfNeeded(
+ false)) // make sure that you are up to date before returning anything
+ {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Value tmp_value(m_value);
+ scalar = tmp_value.ResolveValue(&exe_ctx);
+ if (scalar.IsValid()) {
+ const uint32_t bitfield_bit_size = GetBitfieldBitSize();
+ if (bitfield_bit_size)
+ return scalar.ExtractBitfield(bitfield_bit_size,
+ GetBitfieldBitOffset());
+ return true;
+ }
+ }
+ return false;
+}
+
+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
-ValueObject::GetValueDidChange ()
-{
- return m_value_did_change;
+ bool ret;
+ if (scalar_value.ULongLong(1) == 0)
+ ret = false;
+ else
+ ret = true;
+ error.Clear();
+ return ret;
}
-void
-ValueObject::SetValueDidChange (bool value_changed)
-{
- m_value_did_change = value_changed;
+bool ValueObject::GetValueIsValid() const { return m_value_is_valid; }
+
+void ValueObject::SetValueIsValid(bool b) { m_value_is_valid = b; }
+
+bool ValueObject::GetValueDidChange() { return m_value_did_change; }
+
+void ValueObject::SetValueDidChange(bool value_changed) {
+ m_value_did_change = value_changed;
}
-ValueObjectSP
-ValueObject::GetChildAtIndex (size_t idx, bool can_create)
-{
- ValueObjectSP child_sp;
- // We may need to update our value if we are dynamic
- if (IsPossibleDynamicType ())
- UpdateValueIfNeeded(false);
- if (idx < GetNumChildren())
- {
- // Check if we have already made the child value object?
- if (can_create && !m_children.HasChildAtIndex(idx))
- {
- // No we haven't created the child at this index, so lets have our
- // subclass do it and cache the result for quick future access.
- m_children.SetChildAtIndex(idx,CreateChildAtIndex (idx, false, 0));
- }
-
- ValueObject* child = m_children.GetChildAtIndex(idx);
- if (child != NULL)
- return child->GetSP();
+ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
+ ValueObjectSP child_sp;
+ // We may need to update our value if we are dynamic
+ if (IsPossibleDynamicType())
+ UpdateValueIfNeeded(false);
+ if (idx < GetNumChildren()) {
+ // Check if we have already made the child value object?
+ if (can_create && !m_children.HasChildAtIndex(idx)) {
+ // No we haven't created the child at this index, so lets have our
+ // subclass do it and cache the result for quick future access.
+ m_children.SetChildAtIndex(idx, CreateChildAtIndex(idx, false, 0));
}
- return child_sp;
+
+ ValueObject *child = m_children.GetChildAtIndex(idx);
+ if (child != NULL)
+ return child->GetSP();
+ }
+ return child_sp;
}
ValueObjectSP
-ValueObject::GetChildAtIndexPath (const std::initializer_list<size_t>& idxs,
- size_t* index_of_error)
-{
- return GetChildAtIndexPath( std::vector<size_t>(idxs),
- index_of_error );
+ValueObject::GetChildAtIndexPath(const std::initializer_list<size_t> &idxs,
+ size_t *index_of_error) {
+ 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)
-{
- return GetChildAtIndexPath( std::vector<std::pair<size_t,bool>>(idxs),
- index_of_error );
+ValueObjectSP ValueObject::GetChildAtIndexPath(
+ const std::initializer_list<std::pair<size_t, bool>> &idxs,
+ size_t *index_of_error) {
+ return GetChildAtIndexPath(std::vector<std::pair<size_t, bool>>(idxs),
+ index_of_error);
}
lldb::ValueObjectSP
-ValueObject::GetChildAtIndexPath (const std::vector<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;
- }
+ValueObject::GetChildAtIndexPath(const std::vector<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 root;
}
-lldb::ValueObjectSP
-ValueObject::GetChildAtIndexPath (const std::vector< 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;
- }
+lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
+ const std::vector<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 root;
}
lldb::ValueObjectSP
-ValueObject::GetChildAtNamePath (const std::initializer_list<ConstString> &names,
- ConstString* name_of_error)
-{
- return GetChildAtNamePath( std::vector<ConstString>(names),
- name_of_error );
+ValueObject::GetChildAtNamePath(const std::initializer_list<ConstString> &names,
+ ConstString *name_of_error) {
+ 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 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
-ValueObject::GetChildAtNamePath (const std::vector<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;
- }
+ValueObject::GetChildAtNamePath(const std::vector<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;
+}
+
+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;
+ }
+ 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 GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
+ omit_empty_base_classes);
}
-size_t
-ValueObject::GetIndexOfChildWithName (const ConstString &name)
-{
- bool omit_empty_base_classes = true;
- return GetCompilerType().GetIndexOfChildWithName (name.GetCString(), omit_empty_base_classes);
+ValueObjectSP ValueObject::GetChildMemberWithName(const ConstString &name,
+ bool can_create) {
+ // when getting a child by name, it could be buried inside some base
+ // classes (which really aren't part of the expression path), so we
+ // need a vector of indexes that can get us down to the correct child
+ ValueObjectSP child_sp;
+
+ // We may need to update our value if we are dynamic
+ if (IsPossibleDynamicType())
+ UpdateValueIfNeeded(false);
+
+ std::vector<uint32_t> child_indexes;
+ bool omit_empty_base_classes = true;
+ const size_t num_child_indexes =
+ GetCompilerType().GetIndexOfChildMemberWithName(
+ name.GetCString(), omit_empty_base_classes, child_indexes);
+ if (num_child_indexes > 0) {
+ std::vector<uint32_t>::const_iterator pos = child_indexes.begin();
+ std::vector<uint32_t>::const_iterator end = child_indexes.end();
+
+ child_sp = GetChildAtIndex(*pos, can_create);
+ for (++pos; pos != end; ++pos) {
+ if (child_sp) {
+ ValueObjectSP new_child_sp(child_sp->GetChildAtIndex(*pos, can_create));
+ child_sp = new_child_sp;
+ } else {
+ child_sp.reset();
+ }
+ }
+ }
+ return child_sp;
+}
+
+size_t 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());
+ }
+ return m_children.GetChildrenCount();
+}
+
+bool ValueObject::MightHaveChildren() {
+ bool has_children = false;
+ const uint32_t type_info = GetTypeInfo();
+ if (type_info) {
+ if (type_info & (eTypeHasChildren | eTypeIsPointer | eTypeIsReference))
+ has_children = true;
+ } else {
+ has_children = GetNumChildren() > 0;
+ }
+ return has_children;
}
-ValueObjectSP
-ValueObject::GetChildMemberWithName (const ConstString &name, bool can_create)
-{
- // when getting a child by name, it could be buried inside some base
- // classes (which really aren't part of the expression path), so we
- // need a vector of indexes that can get us down to the correct child
- ValueObjectSP child_sp;
-
- // We may need to update our value if we are dynamic
- if (IsPossibleDynamicType ())
- UpdateValueIfNeeded(false);
-
- std::vector<uint32_t> child_indexes;
- bool omit_empty_base_classes = true;
- const size_t num_child_indexes = GetCompilerType().GetIndexOfChildMemberWithName (name.GetCString(),
- omit_empty_base_classes,
- child_indexes);
- if (num_child_indexes > 0)
- {
- std::vector<uint32_t>::const_iterator pos = child_indexes.begin ();
- std::vector<uint32_t>::const_iterator end = child_indexes.end ();
+// Should only be called by ValueObject::GetNumChildren()
+void ValueObject::SetNumChildren(size_t num_children) {
+ m_children_count_valid = true;
+ m_children.SetChildrenCount(num_children);
+}
+
+void ValueObject::SetName(const ConstString &name) { m_name = name; }
+
+ValueObject *ValueObject::CreateChildAtIndex(size_t idx,
+ bool synthetic_array_member,
+ int32_t synthetic_index) {
+ ValueObject *valobj = NULL;
+
+ bool omit_empty_base_classes = true;
+ bool ignore_array_bounds = synthetic_array_member;
+ std::string child_name_str;
+ uint32_t child_byte_size = 0;
+ int32_t child_byte_offset = 0;
+ uint32_t child_bitfield_bit_size = 0;
+ 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;
+ CompilerType child_compiler_type;
+
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+
+ 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;
+
+ ConstString child_name;
+ if (!child_name_str.empty())
+ child_name.SetCString(child_name_str.c_str());
+
+ valobj = new ValueObjectChild(
+ *this, 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, eAddressTypeInvalid,
+ language_flags);
+ // if (valobj)
+ // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid);
+ }
+
+ return valobj;
+}
+
+bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
+ std::string &destination,
+ lldb::LanguageType lang) {
+ return GetSummaryAsCString(summary_ptr, destination,
+ TypeSummaryOptions().SetLanguage(lang));
+}
+
+bool ValueObject::GetSummaryAsCString(TypeSummaryImpl *summary_ptr,
+ std::string &destination,
+ 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)
+ return false;
- child_sp = GetChildAtIndex(*pos, can_create);
- for (++pos; pos != end; ++pos)
- {
- if (child_sp)
- {
- ValueObjectSP new_child_sp(child_sp->GetChildAtIndex (*pos, can_create));
- child_sp = new_child_sp;
- }
- else
- {
- child_sp.reset();
- }
+ 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());*/
+
+ 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, actual_options);
+ }
+ m_is_getting_summary = false;
+ return !destination.empty();
+}
+
+const char *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,
+ summary_options);
+ }
+ if (m_summary_str.empty())
+ return NULL;
+ return m_summary_str.c_str();
+}
- }
- }
- return child_sp;
+bool ValueObject::GetSummaryAsCString(std::string &destination,
+ const TypeSummaryOptions &options) {
+ return GetSummaryAsCString(GetSummaryFormat().get(), destination, options);
}
+bool ValueObject::IsCStringContainer(bool check_pointer) {
+ 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_compiler_type.IsCharType());
+ if (!is_char_arr_ptr)
+ return false;
+ if (!check_pointer)
+ return true;
+ if (type_flags.Test(eTypeIsArray))
+ return true;
+ addr_t cstr_address = LLDB_INVALID_ADDRESS;
+ AddressType cstr_address_type = eAddressTypeInvalid;
+ cstr_address = GetAddressOf(true, &cstr_address_type);
+ return (cstr_address != LLDB_INVALID_ADDRESS);
+}
+
+size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx,
+ uint32_t item_count) {
+ 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))
+ return 0;
-size_t
-ValueObject::GetNumChildren (uint32_t max)
-{
- UpdateValueIfNeeded();
+ if (item_count == 0)
+ return 0;
- 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);
- }
+ ExecutionContext exe_ctx(GetExecutionContextRef());
- if (!m_children_count_valid)
- {
- SetNumChildren (CalculateNumChildren());
- }
- return m_children.GetChildrenCount();
-}
+ 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;
-bool
-ValueObject::MightHaveChildren()
-{
- bool has_children = false;
- const uint32_t type_info = GetTypeInfo();
- if (type_info)
- {
- if (type_info & (eTypeHasChildren |
- eTypeIsPointer |
- eTypeIsReference))
- has_children = true;
- }
- else
- {
- has_children = GetNumChildren () > 0;
+ if (item_idx == 0 && item_count == 1) // simply a deref
+ {
+ if (is_pointer_type) {
+ Error error;
+ ValueObjectSP pointee_sp = Dereference(error);
+ if (error.Fail() || pointee_sp.get() == NULL)
+ return 0;
+ return pointee_sp->GetData(data, error);
+ } else {
+ ValueObjectSP child_sp = GetChildAtIndex(0, true);
+ if (child_sp.get() == NULL)
+ return 0;
+ Error error;
+ return child_sp->GetData(data, error);
}
- return has_children;
-}
+ return true;
+ } else /* (items > 1) */
+ {
+ Error error;
+ lldb_private::DataBufferHeap *heap_buf_ptr = NULL;
+ lldb::DataBufferSP data_sp(heap_buf_ptr =
+ new lldb_private::DataBufferHeap());
+
+ AddressType addr_type;
+ lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type)
+ : GetAddressOf(true, &addr_type);
+
+ switch (addr_type) {
+ case eAddressTypeFile: {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
+ addr = addr + offset;
+ Address so_addr;
+ module_sp->ResolveFileAddress(addr, so_addr);
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ heap_buf_ptr->SetByteSize(bytes);
+ size_t bytes_read = target->ReadMemory(
+ so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
+ if (error.Success()) {
+ data.SetData(data_sp);
+ return bytes_read;
+ }
+ }
+ }
+ } break;
+ case eAddressTypeLoad: {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ heap_buf_ptr->SetByteSize(bytes);
+ size_t bytes_read = process->ReadMemory(
+ addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
+ if (error.Success() || bytes_read > 0) {
+ data.SetData(data_sp);
+ return bytes_read;
+ }
+ }
+ } break;
+ case eAddressTypeHost: {
+ 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 == 0 || addr == LLDB_INVALID_ADDRESS)
+ break;
+ heap_buf_ptr->CopyData((uint8_t *)(addr + offset), bytes_read);
+ data.SetData(data_sp);
+ return bytes_read;
+ }
+ } break;
+ case eAddressTypeInvalid:
+ break;
+ }
+ }
+ return 0;
+}
+
+uint64_t ValueObject::GetData(DataExtractor &data, Error &error) {
+ UpdateValueIfNeeded(false);
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
+ if (error.Fail()) {
+ if (m_data.GetByteSize()) {
+ data = m_data;
+ error.Clear();
+ return data.GetByteSize();
+ } else {
+ return 0;
+ }
+ }
+ data.SetAddressByteSize(m_data.GetAddressByteSize());
+ data.SetByteOrder(m_data.GetByteOrder());
+ return data.GetByteSize();
+}
+
+bool ValueObject::SetData(DataExtractor &data, Error &error) {
+ error.Clear();
+ // Make sure our value is up to date first so that our location and location
+ // type is valid.
+ if (!UpdateValueIfNeeded(false)) {
+ error.SetErrorString("unable to read value");
+ return false;
+ }
-// Should only be called by ValueObject::GetNumChildren()
-void
-ValueObject::SetNumChildren (size_t num_children)
-{
- m_children_count_valid = true;
- m_children.SetChildrenCount(num_children);
-}
+ uint64_t count = 0;
+ const Encoding encoding = GetCompilerType().GetEncoding(count);
-void
-ValueObject::SetName (const ConstString &name)
-{
- m_name = name;
-}
+ const size_t byte_size = GetByteSize();
-ValueObject *
-ValueObject::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
-{
- ValueObject *valobj = NULL;
-
- bool omit_empty_base_classes = true;
- bool ignore_array_bounds = synthetic_array_member;
- std::string child_name_str;
- uint32_t child_byte_size = 0;
- int32_t child_byte_offset = 0;
- uint32_t child_bitfield_bit_size = 0;
- 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;
+ Value::ValueType value_type = m_value.GetValueType();
- const bool transparent_pointers = synthetic_array_member == false;
- CompilerType child_compiler_type;
-
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- 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;
-
- ConstString child_name;
- if (!child_name_str.empty())
- child_name.SetCString (child_name_str.c_str());
-
- valobj = new ValueObjectChild (*this,
- 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,
- eAddressTypeInvalid,
- language_flags);
- //if (valobj)
- // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid);
- }
-
- return valobj;
-}
+ switch (value_type) {
+ case Value::eValueTypeScalar: {
+ Error set_error =
+ m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
-bool
-ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
- std::string& destination,
- lldb::LanguageType lang)
-{
- return GetSummaryAsCString(summary_ptr, destination, TypeSummaryOptions().SetLanguage(lang));
-}
-
-bool
-ValueObject::GetSummaryAsCString (TypeSummaryImpl* summary_ptr,
- std::string& destination,
- 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)
- return false;
-
- 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());*/
-
- 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, actual_options);
+ if (!set_error.Success()) {
+ error.SetErrorStringWithFormat("unable to set scalar value: %s",
+ set_error.AsCString());
+ return false;
}
- m_is_getting_summary = false;
- return !destination.empty();
-}
+ } break;
+ case Value::eValueTypeLoadAddress: {
+ // If it is a load address, then the scalar value is the storage location
+ // of the data, and we have to shove this value down to that load location.
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ size_t bytes_written = process->WriteMemory(
+ target_addr, data.GetDataStart(), byte_size, error);
+ if (!error.Success())
+ return false;
+ if (bytes_written != byte_size) {
+ error.SetErrorString("unable to write value to memory");
+ return false;
+ }
+ }
+ } break;
+ case Value::eValueTypeHostAddress: {
+ // If it is a host address, then we stuff the scalar as a DataBuffer into
+ // the Value's data.
+ DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
+ m_data.SetData(buffer_sp, 0);
+ data.CopyByteOrderedData(0, byte_size,
+ const_cast<uint8_t *>(m_data.GetDataStart()),
+ byte_size, m_data.GetByteOrder());
+ m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
+ } break;
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeVector:
+ break;
+ }
+
+ // If we have reached this point, then we have successfully changed the value.
+ SetNeedsUpdate();
+ return true;
+}
+
+static bool CopyStringDataToBufferSP(const StreamString &source,
+ lldb::DataBufferSP &destination) {
+ destination.reset(new DataBufferHeap(source.GetSize() + 1, 0));
+ memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize());
+ return true;
+}
+
+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();
+
+ if (!target) {
+ s << "<no target to read from>";
+ error.SetErrorString("no target to read from");
+ CopyStringDataToBufferSP(s, buffer_sp);
+ return {0, was_capped};
+ }
-const char *
-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,
- summary_options);
- }
- if (m_summary_str.empty())
- return NULL;
- return m_summary_str.c_str();
-}
+ if (max_length == 0)
+ max_length = target->GetMaximumSizeOfStringSummary();
-bool
-ValueObject::GetSummaryAsCString (std::string& destination,
- const TypeSummaryOptions& options)
-{
- return GetSummaryAsCString(GetSummaryFormat().get(),
- destination,
- options);
-}
+ size_t bytes_read = 0;
+ size_t total_bytes_read = 0;
-bool
-ValueObject::IsCStringContainer(bool check_pointer)
-{
- 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_compiler_type.IsCharType ());
- if (!is_char_arr_ptr)
- return false;
- if (!check_pointer)
- return true;
- if (type_flags.Test(eTypeIsArray))
- return true;
+ 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_compiler_type.IsCharType()) {
addr_t cstr_address = LLDB_INVALID_ADDRESS;
AddressType cstr_address_type = eAddressTypeInvalid;
- cstr_address = GetAddressOf (true, &cstr_address_type);
- return (cstr_address != LLDB_INVALID_ADDRESS);
-}
-size_t
-ValueObject::GetPointeeData (DataExtractor& data,
- uint32_t item_idx,
- uint32_t item_count)
-{
- 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))
- return 0;
-
- if (item_count == 0)
- return 0;
-
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- 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;
-
- if (item_idx == 0 && item_count == 1) // simply a deref
- {
- if (is_pointer_type)
- {
- Error error;
- ValueObjectSP pointee_sp = Dereference(error);
- if (error.Fail() || pointee_sp.get() == NULL)
- return 0;
- return pointee_sp->GetData(data, error);
- }
- else
- {
- ValueObjectSP child_sp = GetChildAtIndex(0, true);
- if (child_sp.get() == NULL)
- return 0;
- Error error;
- return child_sp->GetData(data, error);
- }
- return true;
- }
- else /* (items > 1) */
- {
- Error error;
- lldb_private::DataBufferHeap* heap_buf_ptr = NULL;
- lldb::DataBufferSP data_sp(heap_buf_ptr = new lldb_private::DataBufferHeap());
-
- AddressType addr_type;
- lldb::addr_t addr = is_pointer_type ? GetPointerValue(&addr_type) : GetAddressOf(true, &addr_type);
-
- switch (addr_type)
- {
- case eAddressTypeFile:
- {
- ModuleSP module_sp (GetModule());
- if (module_sp)
- {
- addr = addr + offset;
- Address so_addr;
- module_sp->ResolveFileAddress(addr, so_addr);
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Target* target = exe_ctx.GetTargetPtr();
- if (target)
- {
- heap_buf_ptr->SetByteSize(bytes);
- size_t bytes_read = target->ReadMemory(so_addr, false, heap_buf_ptr->GetBytes(), bytes, error);
- if (error.Success())
- {
- data.SetData(data_sp);
- return bytes_read;
- }
- }
- }
- }
- break;
- case eAddressTypeLoad:
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- heap_buf_ptr->SetByteSize(bytes);
- size_t bytes_read = process->ReadMemory(addr + offset, heap_buf_ptr->GetBytes(), bytes, error);
- if (error.Success() || bytes_read > 0)
- {
- data.SetData(data_sp);
- return bytes_read;
- }
- }
- }
- break;
- case eAddressTypeHost:
- {
- 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 == 0 || addr == LLDB_INVALID_ADDRESS)
- break;
- heap_buf_ptr->CopyData((uint8_t*)(addr + offset), bytes_read);
- data.SetData(data_sp);
- return bytes_read;
- }
- }
- break;
- case eAddressTypeInvalid:
- break;
- }
- }
- return 0;
-}
+ size_t cstr_len = 0;
+ bool capped_data = false;
+ const bool is_array = type_flags.Test(eTypeIsArray);
+ if (is_array) {
+ // We have an array
+ uint64_t array_size = 0;
+ if (compiler_type.IsArrayType(NULL, &array_size, NULL)) {
+ cstr_len = array_size;
+ if (cstr_len > max_length) {
+ capped_data = true;
+ cstr_len = max_length;
+ }
+ }
+ cstr_address = GetAddressOf(true, &cstr_address_type);
+ } else {
+ // We have a pointer
+ cstr_address = GetPointerValue(&cstr_address_type);
+ }
+
+ if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS) {
+ if (cstr_address_type == eAddressTypeHost && is_array) {
+ const char *cstr = GetDataExtractor().PeekCStr(0);
+ if (cstr == nullptr) {
+ s << "<invalid address>";
+ error.SetErrorString("invalid address");
+ CopyStringDataToBufferSP(s, buffer_sp);
+ return {0, was_capped};
+ }
+ buffer_sp.reset(new DataBufferHeap(cstr_len, 0));
+ memcpy(buffer_sp->GetBytes(), cstr, cstr_len);
+ return {cstr_len, was_capped};
+ } else {
+ s << "<invalid address>";
+ error.SetErrorString("invalid address");
+ CopyStringDataToBufferSP(s, buffer_sp);
+ return {0, was_capped};
+ }
+ }
+
+ Address cstr_so_addr(cstr_address);
+ DataExtractor data;
+ if (cstr_len > 0 && honor_array) {
+ // I am using GetPointeeData() here to abstract the fact that some
+ // ValueObjects are actually frozen pointers in the host
+ // but the pointed-to data lives in the debuggee, and GetPointeeData()
+ // automatically takes care of this
+ GetPointeeData(data, 0, cstr_len);
+
+ if ((bytes_read = data.GetByteSize()) > 0) {
+ total_bytes_read = bytes_read;
+ for (size_t offset = 0; offset < bytes_read; offset++)
+ s.Printf("%c", *data.PeekData(offset, 1));
+ if (capped_data)
+ was_capped = true;
+ }
+ } else {
+ cstr_len = max_length;
+ const size_t k_max_buf_size = 64;
+
+ size_t offset = 0;
+
+ int cstr_len_displayed = -1;
+ bool capped_cstr = false;
+ // I am using GetPointeeData() here to abstract the fact that some
+ // ValueObjects are actually frozen pointers in the host
+ // but the pointed-to data lives in the debuggee, and GetPointeeData()
+ // automatically takes care of this
+ while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0) {
+ total_bytes_read += bytes_read;
+ const char *cstr = data.PeekCStr(0);
+ size_t len = strnlen(cstr, k_max_buf_size);
+ if (cstr_len_displayed < 0)
+ cstr_len_displayed = len;
+
+ if (len == 0)
+ break;
+ cstr_len_displayed += len;
+ if (len > bytes_read)
+ len = bytes_read;
+ if (len > cstr_len)
+ len = cstr_len;
+
+ for (size_t offset = 0; offset < bytes_read; offset++)
+ s.Printf("%c", *data.PeekData(offset, 1));
+
+ if (len < k_max_buf_size)
+ break;
+
+ if (len >= cstr_len) {
+ capped_cstr = true;
+ break;
+ }
+
+ cstr_len -= len;
+ offset += len;
+ }
+
+ if (cstr_len_displayed >= 0) {
+ if (capped_cstr)
+ was_capped = true;
+ }
+ }
+ } else {
+ error.SetErrorString("not a string object");
+ s << "<not a string object>";
+ }
+ CopyStringDataToBufferSP(s, buffer_sp);
+ return {total_bytes_read, was_capped};
+}
+
+std::pair<TypeValidatorResult, std::string> ValueObject::GetValidationStatus() {
+ if (!UpdateValueIfNeeded(true))
+ return {TypeValidatorResult::Success,
+ ""}; // not the validator's job to discuss update problems
+
+ if (m_validation_result.hasValue())
+ return m_validation_result.getValue();
+
+ if (!m_type_validator_sp)
+ return {TypeValidatorResult::Success, ""}; // no validator no failure
+
+ auto outcome = m_type_validator_sp->FormatObject(this);
+
+ return (m_validation_result = {outcome.m_result, outcome.m_message})
+ .getValue();
+}
+
+const char *ValueObject::GetObjectDescription() {
+
+ if (!UpdateValueIfNeeded(true))
+ return NULL;
-uint64_t
-ValueObject::GetData (DataExtractor& data, Error &error)
-{
- UpdateValueIfNeeded(false);
- ExecutionContext exe_ctx (GetExecutionContextRef());
- error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
- if (error.Fail())
- {
- if (m_data.GetByteSize())
- {
- data = m_data;
- error.Clear();
- return data.GetByteSize();
- }
- else
- {
- return 0;
- }
- }
- data.SetAddressByteSize(m_data.GetAddressByteSize());
- data.SetByteOrder(m_data.GetByteOrder());
- return data.GetByteSize();
-}
+ if (!m_object_desc_str.empty())
+ return m_object_desc_str.c_str();
-bool
-ValueObject::SetData (DataExtractor &data, Error &error)
-{
- error.Clear();
- // Make sure our value is up to date first so that our location and location
- // type is valid.
- if (!UpdateValueIfNeeded(false))
- {
- error.SetErrorString("unable to read value");
- return false;
- }
-
- uint64_t count = 0;
- const Encoding encoding = GetCompilerType().GetEncoding(count);
-
- const size_t byte_size = GetByteSize();
-
- Value::ValueType value_type = m_value.GetValueType();
-
- switch (value_type)
- {
- case Value::eValueTypeScalar:
- {
- Error set_error = m_value.GetScalar().SetValueFromData(data, encoding, byte_size);
-
- if (!set_error.Success())
- {
- error.SetErrorStringWithFormat("unable to set scalar value: %s", set_error.AsCString());
- return false;
- }
- }
- break;
- case Value::eValueTypeLoadAddress:
- {
- // If it is a load address, then the scalar value is the storage location
- // of the data, and we have to shove this value down to that load location.
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- size_t bytes_written = process->WriteMemory(target_addr,
- data.GetDataStart(),
- byte_size,
- error);
- if (!error.Success())
- return false;
- if (bytes_written != byte_size)
- {
- error.SetErrorString("unable to write value to memory");
- return false;
- }
- }
- }
- break;
- case Value::eValueTypeHostAddress:
- {
- // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
- DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
- m_data.SetData(buffer_sp, 0);
- data.CopyByteOrderedData (0,
- byte_size,
- const_cast<uint8_t *>(m_data.GetDataStart()),
- byte_size,
- m_data.GetByteOrder());
- m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
- }
- break;
- case Value::eValueTypeFileAddress:
- case Value::eValueTypeVector:
- break;
- }
-
- // If we have reached this point, then we have successfully changed the value.
- SetNeedsUpdate();
- return true;
-}
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process == NULL)
+ return NULL;
-static bool
-CopyStringDataToBufferSP(const StreamString& source,
- lldb::DataBufferSP& destination)
-{
- destination.reset(new DataBufferHeap(source.GetSize()+1,0));
- memcpy(destination->GetBytes(), source.GetString().c_str(), source.GetSize());
- return true;
-}
+ StreamString s;
-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();
-
- if (!target)
- {
- s << "<no target to read from>";
- error.SetErrorString("no target to read from");
- CopyStringDataToBufferSP(s, buffer_sp);
- return {0,was_capped};
- }
-
- if (max_length == 0)
- max_length = target->GetMaximumSizeOfStringSummary();
-
- size_t bytes_read = 0;
- size_t total_bytes_read = 0;
-
+ LanguageType language = GetObjectRuntimeLanguage();
+ LanguageRuntime *runtime = process->GetLanguageRuntime(language);
+
+ if (runtime == NULL) {
+ // Aw, hell, if the things a pointer, or even just an integer, let's try
+ // ObjC anyway...
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_compiler_type.IsCharType ())
- {
- addr_t cstr_address = LLDB_INVALID_ADDRESS;
- AddressType cstr_address_type = eAddressTypeInvalid;
-
- size_t cstr_len = 0;
- bool capped_data = false;
- if (type_flags.Test (eTypeIsArray))
- {
- // We have an array
- uint64_t array_size = 0;
- if (compiler_type.IsArrayType(NULL, &array_size, NULL))
- {
- cstr_len = array_size;
- if (cstr_len > max_length)
- {
- capped_data = true;
- cstr_len = max_length;
- }
- }
- cstr_address = GetAddressOf (true, &cstr_address_type);
- }
- else
- {
- // We have a pointer
- cstr_address = GetPointerValue (&cstr_address_type);
- }
-
- if (cstr_address == 0 || cstr_address == LLDB_INVALID_ADDRESS)
- {
- s << "<invalid address>";
- error.SetErrorString("invalid address");
- CopyStringDataToBufferSP(s, buffer_sp);
- return {0,was_capped};
- }
-
- Address cstr_so_addr (cstr_address);
- DataExtractor data;
- if (cstr_len > 0 && honor_array)
- {
- // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
- // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
- GetPointeeData(data, 0, cstr_len);
-
- if ((bytes_read = data.GetByteSize()) > 0)
- {
- total_bytes_read = bytes_read;
- for (size_t offset = 0; offset < bytes_read; offset++)
- s.Printf("%c", *data.PeekData(offset, 1));
- if (capped_data)
- was_capped = true;
- }
- }
- else
- {
- cstr_len = max_length;
- const size_t k_max_buf_size = 64;
-
- size_t offset = 0;
-
- int cstr_len_displayed = -1;
- bool capped_cstr = false;
- // I am using GetPointeeData() here to abstract the fact that some ValueObjects are actually frozen pointers in the host
- // but the pointed-to data lives in the debuggee, and GetPointeeData() automatically takes care of this
- while ((bytes_read = GetPointeeData(data, offset, k_max_buf_size)) > 0)
- {
- total_bytes_read += bytes_read;
- const char *cstr = data.PeekCStr(0);
- size_t len = strnlen (cstr, k_max_buf_size);
- if (cstr_len_displayed < 0)
- cstr_len_displayed = len;
-
- if (len == 0)
- break;
- cstr_len_displayed += len;
- if (len > bytes_read)
- len = bytes_read;
- if (len > cstr_len)
- len = cstr_len;
-
- for (size_t offset = 0; offset < bytes_read; offset++)
- s.Printf("%c", *data.PeekData(offset, 1));
-
- if (len < k_max_buf_size)
- break;
-
- if (len >= cstr_len)
- {
- capped_cstr = true;
- break;
- }
-
- cstr_len -= len;
- offset += len;
- }
-
- if (cstr_len_displayed >= 0)
- {
- if (capped_cstr)
- was_capped = true;
- }
- }
+ if (compiler_type) {
+ bool is_signed;
+ if (compiler_type.IsIntegerType(is_signed) ||
+ compiler_type.IsPointerType()) {
+ runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
+ }
}
- else
- {
- error.SetErrorString("not a string object");
- s << "<not a string object>";
- }
- CopyStringDataToBufferSP(s, buffer_sp);
- return {total_bytes_read,was_capped};
+ }
+
+ if (runtime && runtime->GetObjectDescription(s, *this)) {
+ m_object_desc_str.append(s.GetString());
+ }
+
+ if (m_object_desc_str.empty())
+ return NULL;
+ else
+ return m_object_desc_str.c_str();
}
-std::pair<TypeValidatorResult, std::string>
-ValueObject::GetValidationStatus ()
-{
- if (!UpdateValueIfNeeded(true))
- return {TypeValidatorResult::Success,""}; // not the validator's job to discuss update problems
-
- if (m_validation_result.hasValue())
- return m_validation_result.getValue();
-
- if (!m_type_validator_sp)
- return {TypeValidatorResult::Success,""}; // no validator no failure
-
- auto outcome = m_type_validator_sp->FormatObject(this);
-
- return (m_validation_result = {outcome.m_result,outcome.m_message}).getValue();
+bool ValueObject::GetValueAsCString(const lldb_private::TypeFormatImpl &format,
+ std::string &destination) {
+ if (UpdateValueIfNeeded(false))
+ return format.FormatObject(this, destination);
+ else
+ return false;
}
-const char *
-ValueObject::GetObjectDescription ()
-{
-
- if (!UpdateValueIfNeeded (true))
- return NULL;
+bool ValueObject::GetValueAsCString(lldb::Format format,
+ std::string &destination) {
+ return GetValueAsCString(TypeFormatImpl_Format(format), destination);
+}
+
+const char *ValueObject::GetValueAsCString() {
+ if (UpdateValueIfNeeded(true)) {
+ lldb::TypeFormatImplSP format_sp;
+ lldb::Format my_format = GetFormat();
+ if (my_format == lldb::eFormatDefault) {
+ if (m_type_format_sp)
+ format_sp = m_type_format_sp;
+ else {
+ if (m_is_bitfield_for_scalar)
+ my_format = eFormatUnsigned;
+ else {
+ if (m_value.GetContextType() == Value::eContextTypeRegisterInfo) {
+ const RegisterInfo *reg_info = m_value.GetRegisterInfo();
+ if (reg_info)
+ my_format = reg_info->format;
+ } else {
+ my_format = GetValue().GetCompilerType().GetFormat();
+ }
+ }
+ }
+ }
+ if (my_format != m_last_format || m_value_str.empty()) {
+ m_last_format = my_format;
+ if (!format_sp)
+ format_sp.reset(new TypeFormatImpl_Format(my_format));
+ if (GetValueAsCString(*format_sp.get(), m_value_str)) {
+ if (!m_value_did_change && m_old_value_valid) {
+ // The value was gotten successfully, so we consider the
+ // value as changed if the value string differs
+ SetValueDidChange(m_old_value_str != m_value_str);
+ }
+ }
+ }
+ }
+ if (m_value_str.empty())
+ return NULL;
+ return m_value_str.c_str();
+}
- if (!m_object_desc_str.empty())
- return m_object_desc_str.c_str();
+// if > 8bytes, 0 is returned. this method should mostly be used
+// to read address values out of pointers
+uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) {
+ // If our byte size is zero this is an aggregate type that has children
+ if (CanProvideValue()) {
+ Scalar scalar;
+ if (ResolveValue(scalar)) {
+ if (success)
+ *success = true;
+ return scalar.ULongLong(fail_value);
+ }
+ // fallthrough, otherwise...
+ }
+
+ if (success)
+ *success = false;
+ return fail_value;
+}
+
+int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) {
+ // If our byte size is zero this is an aggregate type that has children
+ if (CanProvideValue()) {
+ Scalar scalar;
+ if (ResolveValue(scalar)) {
+ if (success)
+ *success = true;
+ return scalar.SLongLong(fail_value);
+ }
+ // fallthrough, otherwise...
+ }
+
+ if (success)
+ *success = false;
+ return fail_value;
+}
+
+// if any more "special cases" are added to
+// ValueObject::DumpPrintableRepresentation() please keep
+// this call up to date by returning true for your new special cases. We will
+// eventually move
+// to checking this call result before trying to display special cases
+bool ValueObject::HasSpecialPrintableRepresentation(
+ ValueObjectRepresentationStyle val_obj_display, Format custom_format) {
+ Flags flags(GetTypeInfo());
+ if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
+ val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
+ if (IsCStringContainer(true) &&
+ (custom_format == eFormatCString || custom_format == eFormatCharArray ||
+ custom_format == eFormatChar || custom_format == eFormatVectorOfChar))
+ return true;
+
+ if (flags.Test(eTypeIsArray)) {
+ if ((custom_format == eFormatBytes) ||
+ (custom_format == eFormatBytesWithASCII))
+ return true;
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process == NULL)
- return NULL;
-
- StreamString s;
-
- LanguageType language = GetObjectRuntimeLanguage();
- LanguageRuntime *runtime = process->GetLanguageRuntime(language);
-
- if (runtime == NULL)
- {
- // Aw, hell, if the things a pointer, or even just an integer, let's try ObjC anyway...
- CompilerType compiler_type = GetCompilerType();
- if (compiler_type)
- {
- bool is_signed;
- if (compiler_type.IsIntegerType (is_signed) || compiler_type.IsPointerType ())
- {
- runtime = process->GetLanguageRuntime(eLanguageTypeObjC);
- }
- }
- }
-
- if (runtime && runtime->GetObjectDescription(s, *this))
- {
- m_object_desc_str.append (s.GetData());
+ if ((custom_format == eFormatVectorOfChar) ||
+ (custom_format == eFormatVectorOfFloat32) ||
+ (custom_format == eFormatVectorOfFloat64) ||
+ (custom_format == eFormatVectorOfSInt16) ||
+ (custom_format == eFormatVectorOfSInt32) ||
+ (custom_format == eFormatVectorOfSInt64) ||
+ (custom_format == eFormatVectorOfSInt8) ||
+ (custom_format == eFormatVectorOfUInt128) ||
+ (custom_format == eFormatVectorOfUInt16) ||
+ (custom_format == eFormatVectorOfUInt32) ||
+ (custom_format == eFormatVectorOfUInt64) ||
+ (custom_format == eFormatVectorOfUInt8))
+ return true;
}
-
- if (m_object_desc_str.empty())
- return NULL;
- else
- return m_object_desc_str.c_str();
+ }
+ return false;
}
-bool
-ValueObject::GetValueAsCString (const lldb_private::TypeFormatImpl& format,
- std::string& destination)
-{
- if (UpdateValueIfNeeded(false))
- return format.FormatObject(this,destination);
- else
- return false;
-}
+bool ValueObject::DumpPrintableRepresentation(
+ Stream &s, ValueObjectRepresentationStyle val_obj_display,
+ Format custom_format, PrintableRepresentationSpecialCases special,
+ bool do_dump_error) {
-bool
-ValueObject::GetValueAsCString (lldb::Format format,
- std::string& destination)
-{
- return GetValueAsCString(TypeFormatImpl_Format(format),destination);
-}
+ Flags flags(GetTypeInfo());
-const char *
-ValueObject::GetValueAsCString ()
-{
- if (UpdateValueIfNeeded(true))
- {
- lldb::TypeFormatImplSP format_sp;
- lldb::Format my_format = GetFormat();
- if (my_format == lldb::eFormatDefault)
- {
- if (m_type_format_sp)
- format_sp = m_type_format_sp;
- else
- {
- if (m_is_bitfield_for_scalar)
- my_format = eFormatUnsigned;
- else
- {
- if (m_value.GetContextType() == Value::eContextTypeRegisterInfo)
- {
- const RegisterInfo *reg_info = m_value.GetRegisterInfo();
- if (reg_info)
- my_format = reg_info->format;
- }
- else
- {
- my_format = GetValue().GetCompilerType().GetFormat();
- }
- }
- }
- }
- if (my_format != m_last_format || m_value_str.empty())
- {
- m_last_format = my_format;
- if (!format_sp)
- format_sp.reset(new TypeFormatImpl_Format(my_format));
- if (GetValueAsCString(*format_sp.get(), m_value_str))
- {
- if (!m_value_did_change && m_old_value_valid)
- {
- // The value was gotten successfully, so we consider the
- // value as changed if the value string differs
- SetValueDidChange (m_old_value_str != m_value_str);
- }
- }
- }
- }
- if (m_value_str.empty())
- return NULL;
- return m_value_str.c_str();
-}
+ bool allow_special =
+ (special == ValueObject::PrintableRepresentationSpecialCases::eAllow);
+ const bool only_special = false;
-// if > 8bytes, 0 is returned. this method should mostly be used
-// to read address values out of pointers
-uint64_t
-ValueObject::GetValueAsUnsigned (uint64_t fail_value, bool *success)
-{
- // If our byte size is zero this is an aggregate type that has children
- if (CanProvideValue())
- {
- Scalar scalar;
- if (ResolveValue (scalar))
- {
- if (success)
- *success = true;
- return scalar.ULongLong(fail_value);
- }
- // fallthrough, otherwise...
- }
+ if (allow_special) {
+ if (flags.AnySet(eTypeIsArray | eTypeIsPointer) &&
+ val_obj_display == ValueObject::eValueObjectRepresentationStyleValue) {
+ // when being asked to get a printable display an array or pointer type
+ // directly,
+ // try to "do the right thing"
- if (success)
- *success = false;
- return fail_value;
-}
+ if (IsCStringContainer(true) &&
+ (custom_format == eFormatCString ||
+ custom_format == eFormatCharArray || custom_format == eFormatChar ||
+ custom_format ==
+ eFormatVectorOfChar)) // print char[] & char* directly
+ {
+ Error error;
+ lldb::DataBufferSP buffer_sp;
+ 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());
+ options.SetIsTruncated(read_string.second);
+ formatters::StringPrinter::ReadBufferAndDumpToStream<
+ lldb_private::formatters::StringPrinter::StringElementType::ASCII>(
+ options);
+ return !error.Fail();
+ }
+
+ if (custom_format == eFormatEnum)
+ return false;
-int64_t
-ValueObject::GetValueAsSigned (int64_t fail_value, bool *success)
-{
- // If our byte size is zero this is an aggregate type that has children
- if (CanProvideValue())
- {
- Scalar scalar;
- if (ResolveValue (scalar))
- {
- if (success)
- *success = true;
- return scalar.SLongLong(fail_value);
- }
- // fallthrough, otherwise...
- }
-
- if (success)
- *success = false;
- return fail_value;
-}
+ // this only works for arrays, because I have no way to know when
+ // the pointed memory ends, and no special \0 end of data marker
+ if (flags.Test(eTypeIsArray)) {
+ if ((custom_format == eFormatBytes) ||
+ (custom_format == eFormatBytesWithASCII)) {
+ const size_t count = GetNumChildren();
-// if any more "special cases" are added to ValueObject::DumpPrintableRepresentation() please keep
-// this call up to date by returning true for your new special cases. We will eventually move
-// to checking this call result before trying to display special cases
-bool
-ValueObject::HasSpecialPrintableRepresentation(ValueObjectRepresentationStyle val_obj_display,
- Format custom_format)
-{
- Flags flags(GetTypeInfo());
- if (flags.AnySet(eTypeIsArray | eTypeIsPointer)
- && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
- {
- if (IsCStringContainer(true) &&
- (custom_format == eFormatCString ||
- custom_format == eFormatCharArray ||
- custom_format == eFormatChar ||
- custom_format == eFormatVectorOfChar))
- return true;
-
- if (flags.Test(eTypeIsArray))
- {
- if ((custom_format == eFormatBytes) ||
- (custom_format == eFormatBytesWithASCII))
- return true;
-
- if ((custom_format == eFormatVectorOfChar) ||
- (custom_format == eFormatVectorOfFloat32) ||
- (custom_format == eFormatVectorOfFloat64) ||
- (custom_format == eFormatVectorOfSInt16) ||
- (custom_format == eFormatVectorOfSInt32) ||
- (custom_format == eFormatVectorOfSInt64) ||
- (custom_format == eFormatVectorOfSInt8) ||
- (custom_format == eFormatVectorOfUInt128) ||
- (custom_format == eFormatVectorOfUInt16) ||
- (custom_format == eFormatVectorOfUInt32) ||
- (custom_format == eFormatVectorOfUInt64) ||
- (custom_format == eFormatVectorOfUInt8))
- return true;
- }
- }
- return false;
-}
+ s << '[';
+ for (size_t low = 0; low < count; low++) {
-bool
-ValueObject::DumpPrintableRepresentation(Stream& s,
- ValueObjectRepresentationStyle val_obj_display,
- Format custom_format,
- PrintableRepresentationSpecialCases special,
- bool do_dump_error)
-{
-
- Flags flags(GetTypeInfo());
-
- bool allow_special = ((special & ePrintableRepresentationSpecialCasesAllow) == ePrintableRepresentationSpecialCasesAllow);
- bool only_special = ((special & ePrintableRepresentationSpecialCasesOnly) == ePrintableRepresentationSpecialCasesOnly);
-
- if (allow_special)
- {
- if (flags.AnySet(eTypeIsArray | eTypeIsPointer)
- && val_obj_display == ValueObject::eValueObjectRepresentationStyleValue)
- {
- // when being asked to get a printable display an array or pointer type directly,
- // try to "do the right thing"
-
- if (IsCStringContainer(true) &&
- (custom_format == eFormatCString ||
- custom_format == eFormatCharArray ||
- custom_format == eFormatChar ||
- custom_format == eFormatVectorOfChar)) // print char[] & char* directly
- {
- Error error;
- lldb::DataBufferSP buffer_sp;
- 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());
- options.SetIsTruncated(read_string.second);
- formatters::StringPrinter::ReadBufferAndDumpToStream<lldb_private::formatters::StringPrinter::StringElementType::ASCII>(options);
- return !error.Fail();
+ if (low)
+ s << ',';
+
+ ValueObjectSP child = GetChildAtIndex(low, true);
+ if (!child.get()) {
+ s << "<invalid child>";
+ continue;
}
-
- if (custom_format == eFormatEnum)
- return false;
-
- // this only works for arrays, because I have no way to know when
- // the pointed memory ends, and no special \0 end of data marker
- if (flags.Test(eTypeIsArray))
- {
- if ((custom_format == eFormatBytes) ||
- (custom_format == eFormatBytesWithASCII))
- {
- const size_t count = GetNumChildren();
-
- s << '[';
- for (size_t low = 0; low < count; low++)
- {
-
- if (low)
- s << ',';
-
- ValueObjectSP child = GetChildAtIndex(low,true);
- if (!child.get())
- {
- s << "<invalid child>";
- continue;
- }
- child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, custom_format);
- }
-
- s << ']';
-
- return true;
- }
-
- if ((custom_format == eFormatVectorOfChar) ||
- (custom_format == eFormatVectorOfFloat32) ||
- (custom_format == eFormatVectorOfFloat64) ||
- (custom_format == eFormatVectorOfSInt16) ||
- (custom_format == eFormatVectorOfSInt32) ||
- (custom_format == eFormatVectorOfSInt64) ||
- (custom_format == eFormatVectorOfSInt8) ||
- (custom_format == eFormatVectorOfUInt128) ||
- (custom_format == eFormatVectorOfUInt16) ||
- (custom_format == eFormatVectorOfUInt32) ||
- (custom_format == eFormatVectorOfUInt64) ||
- (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes with ASCII or any vector format should be printed directly
- {
- const size_t count = GetNumChildren();
-
- Format format = FormatManager::GetSingleItemFormat(custom_format);
-
- s << '[';
- for (size_t low = 0; low < count; low++)
- {
-
- if (low)
- s << ',';
-
- ValueObjectSP child = GetChildAtIndex(low,true);
- if (!child.get())
- {
- s << "<invalid child>";
- continue;
- }
- child->DumpPrintableRepresentation(s, ValueObject::eValueObjectRepresentationStyleValue, format);
- }
-
- s << ']';
-
- return true;
- }
+ child->DumpPrintableRepresentation(
+ s, ValueObject::eValueObjectRepresentationStyleValue,
+ custom_format);
+ }
+
+ s << ']';
+
+ return true;
+ }
+
+ if ((custom_format == eFormatVectorOfChar) ||
+ (custom_format == eFormatVectorOfFloat32) ||
+ (custom_format == eFormatVectorOfFloat64) ||
+ (custom_format == eFormatVectorOfSInt16) ||
+ (custom_format == eFormatVectorOfSInt32) ||
+ (custom_format == eFormatVectorOfSInt64) ||
+ (custom_format == eFormatVectorOfSInt8) ||
+ (custom_format == eFormatVectorOfUInt128) ||
+ (custom_format == eFormatVectorOfUInt16) ||
+ (custom_format == eFormatVectorOfUInt32) ||
+ (custom_format == eFormatVectorOfUInt64) ||
+ (custom_format == eFormatVectorOfUInt8)) // arrays of bytes, bytes
+ // with ASCII or any vector
+ // format should be printed
+ // directly
+ {
+ const size_t count = GetNumChildren();
+
+ Format format = FormatManager::GetSingleItemFormat(custom_format);
+
+ s << '[';
+ for (size_t low = 0; low < count; low++) {
+
+ if (low)
+ s << ',';
+
+ ValueObjectSP child = GetChildAtIndex(low, true);
+ if (!child.get()) {
+ s << "<invalid child>";
+ continue;
}
-
- if ((custom_format == eFormatBoolean) ||
- (custom_format == eFormatBinary) ||
- (custom_format == eFormatChar) ||
- (custom_format == eFormatCharPrintable) ||
- (custom_format == eFormatComplexFloat) ||
- (custom_format == eFormatDecimal) ||
- (custom_format == eFormatHex) ||
- (custom_format == eFormatHexUppercase) ||
- (custom_format == eFormatFloat) ||
- (custom_format == eFormatOctal) ||
- (custom_format == eFormatOSType) ||
- (custom_format == eFormatUnicode16) ||
- (custom_format == eFormatUnicode32) ||
- (custom_format == eFormatUnsigned) ||
- (custom_format == eFormatPointer) ||
- (custom_format == eFormatComplexInteger) ||
- (custom_format == eFormatComplex) ||
- (custom_format == eFormatDefault)) // use the [] operator
- return false;
- }
- }
-
- if (only_special)
+ child->DumpPrintableRepresentation(
+ s, ValueObject::eValueObjectRepresentationStyleValue, format);
+ }
+
+ s << ']';
+
+ return true;
+ }
+ }
+
+ if ((custom_format == eFormatBoolean) ||
+ (custom_format == eFormatBinary) || (custom_format == eFormatChar) ||
+ (custom_format == eFormatCharPrintable) ||
+ (custom_format == eFormatComplexFloat) ||
+ (custom_format == eFormatDecimal) || (custom_format == eFormatHex) ||
+ (custom_format == eFormatHexUppercase) ||
+ (custom_format == eFormatFloat) || (custom_format == eFormatOctal) ||
+ (custom_format == eFormatOSType) ||
+ (custom_format == eFormatUnicode16) ||
+ (custom_format == eFormatUnicode32) ||
+ (custom_format == eFormatUnsigned) ||
+ (custom_format == eFormatPointer) ||
+ (custom_format == eFormatComplexInteger) ||
+ (custom_format == eFormatComplex) ||
+ (custom_format == eFormatDefault)) // use the [] operator
return false;
-
- bool var_success = false;
-
- {
- const char *cstr = NULL;
-
- // this is a local stream that we are using to ensure that the data pointed to by cstr survives
- // long enough for us to copy it to its destination - it is necessary to have this temporary storage
- // area for cases where our desired output is not backed by some other longer-term storage
- StreamString strm;
-
- if (custom_format != eFormatInvalid)
- SetFormat(custom_format);
-
- switch(val_obj_display)
- {
- case eValueObjectRepresentationStyleValue:
- cstr = GetValueAsCString();
- break;
-
- case eValueObjectRepresentationStyleSummary:
- cstr = GetSummaryAsCString();
- break;
-
- case eValueObjectRepresentationStyleLanguageSpecific:
- cstr = GetObjectDescription();
- break;
-
- case eValueObjectRepresentationStyleLocation:
- cstr = GetLocationAsCString();
- break;
-
- case eValueObjectRepresentationStyleChildrenCount:
- strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
- cstr = strm.GetString().c_str();
- break;
-
- case eValueObjectRepresentationStyleType:
- cstr = GetTypeName().AsCString();
- break;
-
- case eValueObjectRepresentationStyleName:
- cstr = GetName().AsCString();
- break;
-
- case eValueObjectRepresentationStyleExpressionPath:
- GetExpressionPath(strm, false);
- cstr = strm.GetString().c_str();
- break;
- }
-
- if (!cstr)
- {
- if (val_obj_display == eValueObjectRepresentationStyleValue)
- cstr = GetSummaryAsCString();
- else if (val_obj_display == eValueObjectRepresentationStyleSummary)
- {
- if (!CanProvideValue())
- {
- strm.Printf("%s @ %s", GetTypeName().AsCString(), GetLocationAsCString());
- cstr = strm.GetString().c_str();
- }
- else
- cstr = GetValueAsCString();
- }
- }
-
- if (cstr)
- s.PutCString(cstr);
- else
- {
- if (m_error.Fail())
- {
- if (do_dump_error)
- s.Printf("<%s>", m_error.AsCString());
- else
- return false;
- }
- else if (val_obj_display == eValueObjectRepresentationStyleSummary)
- s.PutCString("<no summary available>");
- else if (val_obj_display == eValueObjectRepresentationStyleValue)
- s.PutCString("<no value available>");
- else if (val_obj_display == eValueObjectRepresentationStyleLanguageSpecific)
- s.PutCString("<not a valid Objective-C object>"); // edit this if we have other runtimes that support a description
- else
- s.PutCString("<no printable representation>");
- }
-
- // we should only return false here if we could not do *anything*
- // even if we have an error message as output, that's a success
- // from our callers' perspective, so return true
- var_success = true;
-
- if (custom_format != eFormatInvalid)
- SetFormat(eFormatDefault);
}
-
- return var_success;
-}
+ }
-addr_t
-ValueObject::GetAddressOf (bool scalar_is_load_address, AddressType *address_type)
-{
- // Can't take address of a bitfield
- if (IsBitfield())
- return LLDB_INVALID_ADDRESS;
-
- if (!UpdateValueIfNeeded(false))
- return LLDB_INVALID_ADDRESS;
-
- switch (m_value.GetValueType())
- {
- case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
- if (scalar_is_load_address)
- {
- if(address_type)
- *address_type = eAddressTypeLoad;
- return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- }
- break;
+ if (only_special)
+ return false;
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeFileAddress:
- {
- if(address_type)
- *address_type = m_value.GetValueAddressType ();
- return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- }
- break;
- case Value::eValueTypeHostAddress:
- {
- if(address_type)
- *address_type = m_value.GetValueAddressType ();
- return LLDB_INVALID_ADDRESS;
- }
- break;
- }
- if (address_type)
- *address_type = eAddressTypeInvalid;
+ bool var_success = false;
+
+ {
+ llvm::StringRef str;
+
+ // this is a local stream that we are using to ensure that the data pointed
+ // to by cstr survives long enough for us to copy it to its destination - it
+ // is necessary to have this temporary storage area for cases where our
+ // desired output is not backed by some other longer-term storage
+ StreamString strm;
+
+ if (custom_format != eFormatInvalid)
+ SetFormat(custom_format);
+
+ switch (val_obj_display) {
+ case eValueObjectRepresentationStyleValue:
+ str = GetValueAsCString();
+ break;
+
+ case eValueObjectRepresentationStyleSummary:
+ str = GetSummaryAsCString();
+ break;
+
+ case eValueObjectRepresentationStyleLanguageSpecific:
+ str = GetObjectDescription();
+ break;
+
+ case eValueObjectRepresentationStyleLocation:
+ str = GetLocationAsCString();
+ break;
+
+ case eValueObjectRepresentationStyleChildrenCount:
+ strm.Printf("%" PRIu64 "", (uint64_t)GetNumChildren());
+ str = strm.GetString();
+ break;
+
+ case eValueObjectRepresentationStyleType:
+ str = GetTypeName().GetStringRef();
+ break;
+
+ case eValueObjectRepresentationStyleName:
+ str = GetName().GetStringRef();
+ break;
+
+ case eValueObjectRepresentationStyleExpressionPath:
+ GetExpressionPath(strm, false);
+ str = strm.GetString();
+ break;
+ }
+
+ if (str.empty()) {
+ if (val_obj_display == eValueObjectRepresentationStyleValue)
+ str = GetSummaryAsCString();
+ else if (val_obj_display == eValueObjectRepresentationStyleSummary) {
+ if (!CanProvideValue()) {
+ strm.Printf("%s @ %s", GetTypeName().AsCString(),
+ GetLocationAsCString());
+ str = strm.GetString();
+ } else
+ str = GetValueAsCString();
+ }
+ }
+
+ if (!str.empty())
+ s << str;
+ else {
+ if (m_error.Fail()) {
+ if (do_dump_error)
+ s.Printf("<%s>", m_error.AsCString());
+ else
+ return false;
+ } else if (val_obj_display == eValueObjectRepresentationStyleSummary)
+ s.PutCString("<no summary available>");
+ else if (val_obj_display == eValueObjectRepresentationStyleValue)
+ s.PutCString("<no value available>");
+ else if (val_obj_display ==
+ eValueObjectRepresentationStyleLanguageSpecific)
+ s.PutCString("<not a valid Objective-C object>"); // edit this if we
+ // have other runtimes
+ // that support a
+ // description
+ else
+ s.PutCString("<no printable representation>");
+ }
+
+ // we should only return false here if we could not do *anything*
+ // even if we have an error message as output, that's a success
+ // from our callers' perspective, so return true
+ var_success = true;
+
+ if (custom_format != eFormatInvalid)
+ SetFormat(eFormatDefault);
+ }
+
+ return var_success;
+}
+
+addr_t ValueObject::GetAddressOf(bool scalar_is_load_address,
+ AddressType *address_type) {
+ // Can't take address of a bitfield
+ if (IsBitfield())
return LLDB_INVALID_ADDRESS;
-}
-addr_t
-ValueObject::GetPointerValue (AddressType *address_type)
-{
- addr_t address = LLDB_INVALID_ADDRESS;
- if(address_type)
- *address_type = eAddressTypeInvalid;
-
- if (!UpdateValueIfNeeded(false))
- return address;
-
- switch (m_value.GetValueType())
- {
- case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
- address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- break;
+ if (!UpdateValueIfNeeded(false))
+ return LLDB_INVALID_ADDRESS;
- case Value::eValueTypeHostAddress:
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeFileAddress:
- {
- lldb::offset_t data_offset = 0;
- address = m_data.GetPointer(&data_offset);
- }
- break;
+ switch (m_value.GetValueType()) {
+ case Value::eValueTypeScalar:
+ case Value::eValueTypeVector:
+ if (scalar_is_load_address) {
+ if (address_type)
+ *address_type = eAddressTypeLoad;
+ return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
}
+ break;
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeFileAddress: {
if (address_type)
- *address_type = GetAddressTypeOfChildren();
+ *address_type = m_value.GetValueAddressType();
+ return m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ } break;
+ case Value::eValueTypeHostAddress: {
+ if (address_type)
+ *address_type = m_value.GetValueAddressType();
+ return LLDB_INVALID_ADDRESS;
+ } break;
+ }
+ if (address_type)
+ *address_type = eAddressTypeInvalid;
+ return LLDB_INVALID_ADDRESS;
+}
+addr_t ValueObject::GetPointerValue(AddressType *address_type) {
+ addr_t address = LLDB_INVALID_ADDRESS;
+ if (address_type)
+ *address_type = eAddressTypeInvalid;
+
+ if (!UpdateValueIfNeeded(false))
return address;
-}
-bool
-ValueObject::SetValueFromCString (const char *value_str, Error& error)
-{
- error.Clear();
- // Make sure our value is up to date first so that our location and location
- // type is valid.
- if (!UpdateValueIfNeeded(false))
- {
- error.SetErrorString("unable to read value");
- return false;
- }
+ switch (m_value.GetValueType()) {
+ case Value::eValueTypeScalar:
+ case Value::eValueTypeVector:
+ address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ break;
- uint64_t count = 0;
- const Encoding encoding = GetCompilerType().GetEncoding (count);
+ case Value::eValueTypeHostAddress:
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeFileAddress: {
+ lldb::offset_t data_offset = 0;
+ address = m_data.GetPointer(&data_offset);
+ } break;
+ }
- const size_t byte_size = GetByteSize();
+ if (address_type)
+ *address_type = GetAddressTypeOfChildren();
- Value::ValueType value_type = m_value.GetValueType();
-
- if (value_type == Value::eValueTypeScalar)
- {
- // 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 <= 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.
- Scalar new_scalar;
- error = new_scalar.SetValueFromCString (value_str, encoding, byte_size);
- if (error.Success())
- {
- switch (value_type)
- {
- case Value::eValueTypeLoadAddress:
- {
- // If it is a load address, then the scalar value is the storage location
- // of the data, and we have to shove this value down to that load location.
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- addr_t target_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- size_t bytes_written = process->WriteScalarToMemory (target_addr,
- new_scalar,
- byte_size,
- error);
- if (!error.Success())
- return false;
- if (bytes_written != byte_size)
- {
- error.SetErrorString("unable to write value to memory");
- return false;
- }
- }
- }
- break;
- case Value::eValueTypeHostAddress:
- {
- // If it is a host address, then we stuff the scalar as a DataBuffer into the Value's data.
- DataExtractor new_data;
- new_data.SetByteOrder (m_data.GetByteOrder());
-
- DataBufferSP buffer_sp (new DataBufferHeap(byte_size, 0));
- m_data.SetData(buffer_sp, 0);
- bool success = new_scalar.GetData(new_data);
- if (success)
- {
- new_data.CopyByteOrderedData (0,
- byte_size,
- const_cast<uint8_t *>(m_data.GetDataStart()),
- byte_size,
- m_data.GetByteOrder());
- }
- m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
-
- }
- break;
- case Value::eValueTypeFileAddress:
- case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
- break;
- }
- }
- else
- {
- return false;
- }
- }
- else
- {
- // We don't support setting things bigger than a scalar at present.
- error.SetErrorString("unable to write aggregate data type");
- return false;
- }
-
- // If we have reached this point, then we have successfully changed the value.
- SetNeedsUpdate();
- return true;
+ return address;
}
-bool
-ValueObject::GetDeclaration (Declaration &decl)
-{
- decl.Clear();
+bool ValueObject::SetValueFromCString(const char *value_str, Error &error) {
+ error.Clear();
+ // Make sure our value is up to date first so that our location and location
+ // type is valid.
+ if (!UpdateValueIfNeeded(false)) {
+ error.SetErrorString("unable to read value");
return false;
-}
+ }
+
+ uint64_t count = 0;
+ const Encoding encoding = GetCompilerType().GetEncoding(count);
+
+ const size_t byte_size = GetByteSize();
+
+ Value::ValueType value_type = m_value.GetValueType();
+
+ if (value_type == Value::eValueTypeScalar) {
+ // 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 <= 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.
+ Scalar new_scalar;
+ error = new_scalar.SetValueFromCString(value_str, encoding, byte_size);
+ if (error.Success()) {
+ switch (value_type) {
+ case Value::eValueTypeLoadAddress: {
+ // If it is a load address, then the scalar value is the storage
+ // location
+ // of the data, and we have to shove this value down to that load
+ // location.
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ addr_t target_addr =
+ m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ size_t bytes_written = process->WriteScalarToMemory(
+ target_addr, new_scalar, byte_size, error);
+ if (!error.Success())
+ return false;
+ if (bytes_written != byte_size) {
+ error.SetErrorString("unable to write value to memory");
+ return false;
+ }
+ }
+ } break;
+ case Value::eValueTypeHostAddress: {
+ // If it is a host address, then we stuff the scalar as a DataBuffer
+ // into the Value's data.
+ DataExtractor new_data;
+ new_data.SetByteOrder(m_data.GetByteOrder());
+
+ DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
+ m_data.SetData(buffer_sp, 0);
+ bool success = new_scalar.GetData(new_data);
+ if (success) {
+ new_data.CopyByteOrderedData(
+ 0, byte_size, const_cast<uint8_t *>(m_data.GetDataStart()),
+ byte_size, m_data.GetByteOrder());
+ }
+ m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
+
+ } break;
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeScalar:
+ case Value::eValueTypeVector:
+ break;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ // We don't support setting things bigger than a scalar at present.
+ error.SetErrorString("unable to write aggregate data type");
+ return false;
+ }
-ConstString
-ValueObject::GetTypeName()
-{
- return GetCompilerType().GetConstTypeName();
+ // If we have reached this point, then we have successfully changed the value.
+ SetNeedsUpdate();
+ return true;
}
-ConstString
-ValueObject::GetDisplayTypeName()
-{
- return GetTypeName();
+bool ValueObject::GetDeclaration(Declaration &decl) {
+ decl.Clear();
+ return false;
}
-ConstString
-ValueObject::GetQualifiedTypeName()
-{
- return GetCompilerType().GetConstQualifiedTypeName();
+ConstString ValueObject::GetTypeName() {
+ return GetCompilerType().GetConstTypeName();
}
+ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); }
-LanguageType
-ValueObject::GetObjectRuntimeLanguage ()
-{
- return GetCompilerType().GetMinimumLanguage ();
+ConstString ValueObject::GetQualifiedTypeName() {
+ return GetCompilerType().GetConstQualifiedTypeName();
}
-void
-ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
-{
- m_synthetic_children[key] = valobj;
+LanguageType ValueObject::GetObjectRuntimeLanguage() {
+ return GetCompilerType().GetMinimumLanguage();
}
-ValueObjectSP
-ValueObject::GetSyntheticChild (const ConstString &key) const
-{
- ValueObjectSP synthetic_child_sp;
- std::map<ConstString, ValueObject *>::const_iterator pos = m_synthetic_children.find (key);
- if (pos != m_synthetic_children.end())
- synthetic_child_sp = pos->second->GetSP();
- return synthetic_child_sp;
+void ValueObject::AddSyntheticChild(const ConstString &key,
+ ValueObject *valobj) {
+ m_synthetic_children[key] = valobj;
}
-uint32_t
-ValueObject::GetTypeInfo (CompilerType *pointee_or_element_compiler_type)
-{
- return GetCompilerType().GetTypeInfo (pointee_or_element_compiler_type);
+ValueObjectSP ValueObject::GetSyntheticChild(const ConstString &key) const {
+ ValueObjectSP synthetic_child_sp;
+ std::map<ConstString, ValueObject *>::const_iterator pos =
+ m_synthetic_children.find(key);
+ if (pos != m_synthetic_children.end())
+ synthetic_child_sp = pos->second->GetSP();
+ return synthetic_child_sp;
}
-bool
-ValueObject::IsPointerType ()
-{
- return GetCompilerType().IsPointerType();
+uint32_t
+ValueObject::GetTypeInfo(CompilerType *pointee_or_element_compiler_type) {
+ return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
}
-bool
-ValueObject::IsArrayType ()
-{
- return GetCompilerType().IsArrayType (NULL, NULL, NULL);
-}
+bool ValueObject::IsPointerType() { return GetCompilerType().IsPointerType(); }
-bool
-ValueObject::IsScalarType ()
-{
- return GetCompilerType().IsScalarType ();
+bool ValueObject::IsArrayType() {
+ return GetCompilerType().IsArrayType(NULL, NULL, NULL);
}
-bool
-ValueObject::IsIntegerType (bool &is_signed)
-{
- return GetCompilerType().IsIntegerType (is_signed);
+bool ValueObject::IsScalarType() { return GetCompilerType().IsScalarType(); }
+
+bool ValueObject::IsIntegerType(bool &is_signed) {
+ return GetCompilerType().IsIntegerType(is_signed);
}
-bool
-ValueObject::IsPointerOrReferenceType ()
-{
- return GetCompilerType().IsPointerOrReferenceType ();
+bool ValueObject::IsPointerOrReferenceType() {
+ return GetCompilerType().IsPointerOrReferenceType();
}
-bool
-ValueObject::IsPossibleDynamicType ()
-{
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- return process->IsPossibleDynamicValue(*this);
- else
- return GetCompilerType().IsPossibleDynamicType (NULL, true, true);
+bool ValueObject::IsPossibleDynamicType() {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process)
+ return process->IsPossibleDynamicValue(*this);
+ else
+ return GetCompilerType().IsPossibleDynamicType(NULL, true, true);
}
-bool
-ValueObject::IsRuntimeSupportValue ()
-{
- Process *process(GetProcessSP().get());
- if (process)
- {
- LanguageRuntime *runtime = process->GetLanguageRuntime(GetObjectRuntimeLanguage());
- if (!runtime)
- runtime = process->GetObjCLanguageRuntime();
- if (runtime)
- return runtime->IsRuntimeSupportValue(*this);
- }
- return false;
+bool ValueObject::IsRuntimeSupportValue() {
+ Process *process(GetProcessSP().get());
+ if (process) {
+ LanguageRuntime *runtime =
+ process->GetLanguageRuntime(GetObjectRuntimeLanguage());
+ if (!runtime)
+ runtime = process->GetObjCLanguageRuntime();
+ if (runtime)
+ return runtime->IsRuntimeSupportValue(*this);
+ }
+ return false;
}
-bool
-ValueObject::IsNilReference ()
-{
- if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage()))
- {
- return language->IsNilReference(*this);
- }
- return false;
+bool ValueObject::IsNilReference() {
+ 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;
+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
@@ -2104,2243 +1756,1694 @@ ValueObject::IsUninitializedReference ()
// The size of the "item_array" is 1, but many times in practice
// there are more items in "item_array".
-ValueObjectSP
-ValueObject::GetSyntheticArrayMember (size_t index, bool can_create)
-{
- ValueObjectSP synthetic_child_sp;
- if (IsPointerType () || IsArrayType())
- {
- char index_str[64];
- snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
- ConstString index_const_str(index_str);
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
- synthetic_child_sp = GetSyntheticChild (index_const_str);
- if (!synthetic_child_sp)
- {
- ValueObject *synthetic_child;
- // We haven't made a synthetic array member for INDEX yet, so
- // lets make one and cache it for any future reference.
- synthetic_child = CreateChildAtIndex(0, true, index);
-
- // Cache the value if we got one back...
- if (synthetic_child)
- {
- AddSyntheticChild(index_const_str, synthetic_child);
- synthetic_child_sp = synthetic_child->GetSP();
- synthetic_child_sp->SetName(ConstString(index_str));
- synthetic_child_sp->m_is_array_item_for_pointer = true;
- }
- }
- }
- return synthetic_child_sp;
-}
-
-ValueObjectSP
-ValueObject::GetSyntheticBitFieldChild (uint32_t from, uint32_t to, bool can_create)
-{
- ValueObjectSP synthetic_child_sp;
- if (IsScalarType ())
- {
- char index_str[64];
- snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
- ConstString index_const_str(index_str);
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
- synthetic_child_sp = GetSyntheticChild (index_const_str);
- if (!synthetic_child_sp)
- {
- uint32_t bit_field_size = to - from + 1;
- uint32_t bit_field_offset = from;
- if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
- bit_field_offset = GetByteSize() * 8 - bit_field_size - bit_field_offset;
- // 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,
- GetCompilerType(),
- index_const_str,
- GetByteSize(),
- 0,
- bit_field_size,
- bit_field_offset,
- false,
- false,
- eAddressTypeInvalid,
- 0);
-
- // Cache the value if we got one back...
- if (synthetic_child)
- {
- AddSyntheticChild(index_const_str, synthetic_child);
- synthetic_child_sp = synthetic_child->GetSP();
- synthetic_child_sp->SetName(ConstString(index_str));
- synthetic_child_sp->m_is_bitfield_for_scalar = true;
- }
- }
- }
- return synthetic_child_sp;
-}
-
-ValueObjectSP
-ValueObject::GetSyntheticChildAtOffset(uint32_t offset,
- const CompilerType& type,
- bool can_create,
- ConstString name_const_str)
-{
-
- ValueObjectSP synthetic_child_sp;
-
- if (name_const_str.IsEmpty())
- {
- char name_str[64];
- snprintf(name_str, sizeof(name_str), "@%i", offset);
- name_const_str.SetCString(name_str);
- }
-
+ValueObjectSP ValueObject::GetSyntheticArrayMember(size_t index,
+ bool can_create) {
+ ValueObjectSP synthetic_child_sp;
+ if (IsPointerType() || IsArrayType()) {
+ char index_str[64];
+ snprintf(index_str, sizeof(index_str), "[%" PRIu64 "]", (uint64_t)index);
+ ConstString index_const_str(index_str);
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
- synthetic_child_sp = GetSyntheticChild (name_const_str);
-
- if (synthetic_child_sp.get())
- return synthetic_child_sp;
-
- if (!can_create)
- return ValueObjectSP();
-
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
- type,
- name_const_str,
- type.GetByteSize(exe_ctx.GetBestExecutionContextScope()),
- offset,
- 0,
- 0,
- false,
- false,
- eAddressTypeInvalid,
- 0);
- if (synthetic_child)
- {
- AddSyntheticChild(name_const_str, synthetic_child);
+ synthetic_child_sp = GetSyntheticChild(index_const_str);
+ if (!synthetic_child_sp) {
+ ValueObject *synthetic_child;
+ // We haven't made a synthetic array member for INDEX yet, so
+ // lets make one and cache it for any future reference.
+ synthetic_child = CreateChildAtIndex(0, true, index);
+
+ // Cache the value if we got one back...
+ if (synthetic_child) {
+ AddSyntheticChild(index_const_str, synthetic_child);
synthetic_child_sp = synthetic_child->GetSP();
- synthetic_child_sp->SetName(name_const_str);
- synthetic_child_sp->m_is_child_at_offset = true;
+ synthetic_child_sp->SetName(ConstString(index_str));
+ synthetic_child_sp->m_is_array_item_for_pointer = true;
+ }
}
- return synthetic_child_sp;
+ }
+ return synthetic_child_sp;
}
-ValueObjectSP
-ValueObject::GetSyntheticBase (uint32_t offset,
- const CompilerType& type,
- bool can_create,
- ConstString name_const_str)
-{
- ValueObjectSP synthetic_child_sp;
-
- if (name_const_str.IsEmpty())
- {
- char name_str[128];
- snprintf(name_str, sizeof(name_str), "base%s@%i", type.GetTypeName().AsCString("<unknown>"), offset);
- name_const_str.SetCString(name_str);
- }
-
+ValueObjectSP ValueObject::GetSyntheticBitFieldChild(uint32_t from, uint32_t to,
+ bool can_create) {
+ ValueObjectSP synthetic_child_sp;
+ if (IsScalarType()) {
+ char index_str[64];
+ snprintf(index_str, sizeof(index_str), "[%i-%i]", from, to);
+ ConstString index_const_str(index_str);
// Check if we have already created a synthetic array member in this
// valid object. If we have we will re-use it.
- synthetic_child_sp = GetSyntheticChild (name_const_str);
-
- if (synthetic_child_sp.get())
- return synthetic_child_sp;
-
- if (!can_create)
- return ValueObjectSP();
-
- const bool is_base_class = true;
-
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- ValueObjectChild *synthetic_child = new ValueObjectChild(*this,
- type,
- name_const_str,
- type.GetByteSize(exe_ctx.GetBestExecutionContextScope()),
- offset,
- 0,
- 0,
- is_base_class,
- false,
- eAddressTypeInvalid,
- 0);
- if (synthetic_child)
- {
- AddSyntheticChild(name_const_str, synthetic_child);
+ synthetic_child_sp = GetSyntheticChild(index_const_str);
+ if (!synthetic_child_sp) {
+ uint32_t bit_field_size = to - from + 1;
+ uint32_t bit_field_offset = from;
+ if (GetDataExtractor().GetByteOrder() == eByteOrderBig)
+ bit_field_offset =
+ GetByteSize() * 8 - bit_field_size - bit_field_offset;
+ // 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, GetCompilerType(), index_const_str, GetByteSize(), 0,
+ bit_field_size, bit_field_offset, false, false, eAddressTypeInvalid,
+ 0);
+
+ // Cache the value if we got one back...
+ if (synthetic_child) {
+ AddSyntheticChild(index_const_str, synthetic_child);
synthetic_child_sp = synthetic_child->GetSP();
- synthetic_child_sp->SetName(name_const_str);
+ synthetic_child_sp->SetName(ConstString(index_str));
+ synthetic_child_sp->m_is_bitfield_for_scalar = true;
+ }
}
- return synthetic_child_sp;
+ }
+ return synthetic_child_sp;
}
+ValueObjectSP ValueObject::GetSyntheticChildAtOffset(
+ uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str) {
+
+ ValueObjectSP synthetic_child_sp;
+
+ if (name_const_str.IsEmpty()) {
+ char name_str[64];
+ snprintf(name_str, sizeof(name_str), "@%i", offset);
+ name_const_str.SetCString(name_str);
+ }
+
+ // Check if we have already created a synthetic array member in this
+ // valid object. If we have we will re-use it.
+ synthetic_child_sp = GetSyntheticChild(name_const_str);
+
+ if (synthetic_child_sp.get())
+ return synthetic_child_sp;
+
+ if (!can_create)
+ return ValueObjectSP();
+
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+
+ ValueObjectChild *synthetic_child = new ValueObjectChild(
+ *this, type, name_const_str,
+ type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
+ false, false, eAddressTypeInvalid, 0);
+ if (synthetic_child) {
+ AddSyntheticChild(name_const_str, synthetic_child);
+ synthetic_child_sp = synthetic_child->GetSP();
+ synthetic_child_sp->SetName(name_const_str);
+ synthetic_child_sp->m_is_child_at_offset = true;
+ }
+ return synthetic_child_sp;
+}
+
+ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset,
+ const CompilerType &type,
+ bool can_create,
+ ConstString name_const_str) {
+ ValueObjectSP synthetic_child_sp;
+
+ if (name_const_str.IsEmpty()) {
+ char name_str[128];
+ snprintf(name_str, sizeof(name_str), "base%s@%i",
+ type.GetTypeName().AsCString("<unknown>"), offset);
+ name_const_str.SetCString(name_str);
+ }
+
+ // Check if we have already created a synthetic array member in this
+ // valid object. If we have we will re-use it.
+ synthetic_child_sp = GetSyntheticChild(name_const_str);
+
+ if (synthetic_child_sp.get())
+ return synthetic_child_sp;
+
+ if (!can_create)
+ return ValueObjectSP();
+
+ const bool is_base_class = true;
+
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+
+ ValueObjectChild *synthetic_child = new ValueObjectChild(
+ *this, type, name_const_str,
+ type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0,
+ is_base_class, false, eAddressTypeInvalid, 0);
+ if (synthetic_child) {
+ AddSyntheticChild(name_const_str, synthetic_child);
+ synthetic_child_sp = synthetic_child->GetSP();
+ synthetic_child_sp->SetName(name_const_str);
+ }
+ return synthetic_child_sp;
+}
// your expression path needs to have a leading . or ->
// (unless it somehow "looks like" an array, in which case it has
// a leading [ symbol). while the [ is meaningful and should be shown
// to the user, . and -> are just parser design, but by no means
// added information for the user.. strip them off
-static const char*
-SkipLeadingExpressionPathSeparators(const char* expression)
-{
- if (!expression || !expression[0])
- return expression;
- if (expression[0] == '.')
- return expression+1;
- if (expression[0] == '-' && expression[1] == '>')
- return expression+2;
+static const char *SkipLeadingExpressionPathSeparators(const char *expression) {
+ if (!expression || !expression[0])
return expression;
+ if (expression[0] == '.')
+ return expression + 1;
+ if (expression[0] == '-' && expression[1] == '>')
+ return expression + 2;
+ return expression;
}
ValueObjectSP
-ValueObject::GetSyntheticExpressionPathChild(const char* expression, bool can_create)
-{
- ValueObjectSP synthetic_child_sp;
- ConstString name_const_string(expression);
- // Check if we have already created a synthetic array member in this
- // valid object. If we have we will re-use it.
- synthetic_child_sp = GetSyntheticChild (name_const_string);
- if (!synthetic_child_sp)
- {
- // We haven't made a synthetic array member for expression yet, so
- // lets make one and cache it for any future reference.
- synthetic_child_sp = GetValueForExpressionPath(expression,
- NULL, NULL, NULL,
- GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None));
-
- // Cache the value if we got one back...
- if (synthetic_child_sp.get())
- {
- // FIXME: this causes a "real" child to end up with its name changed to the contents of expression
- AddSyntheticChild(name_const_string, synthetic_child_sp.get());
- synthetic_child_sp->SetName(ConstString(SkipLeadingExpressionPathSeparators(expression)));
- }
+ValueObject::GetSyntheticExpressionPathChild(const char *expression,
+ bool can_create) {
+ ValueObjectSP synthetic_child_sp;
+ ConstString name_const_string(expression);
+ // Check if we have already created a synthetic array member in this
+ // valid object. If we have we will re-use it.
+ synthetic_child_sp = GetSyntheticChild(name_const_string);
+ if (!synthetic_child_sp) {
+ // We haven't made a synthetic array member for expression yet, so
+ // lets make one and cache it for any future reference.
+ synthetic_child_sp = GetValueForExpressionPath(
+ expression, NULL, NULL,
+ GetValueForExpressionPathOptions().SetSyntheticChildrenTraversal(
+ GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ None));
+
+ // Cache the value if we got one back...
+ if (synthetic_child_sp.get()) {
+ // FIXME: this causes a "real" child to end up with its name changed to
+ // the contents of expression
+ AddSyntheticChild(name_const_string, synthetic_child_sp.get());
+ synthetic_child_sp->SetName(
+ ConstString(SkipLeadingExpressionPathSeparators(expression)));
+ }
+ }
+ return synthetic_child_sp;
+}
+
+void ValueObject::CalculateSyntheticValue(bool use_synthetic) {
+ if (use_synthetic == false)
+ return;
+
+ TargetSP target_sp(GetTargetSP());
+ if (target_sp && target_sp->GetEnableSyntheticValue() == false) {
+ m_synthetic_value = NULL;
+ return;
+ }
+
+ lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
+
+ if (!UpdateFormatsIfNeeded() && m_synthetic_value)
+ return;
+
+ if (m_synthetic_children_sp.get() == NULL)
+ return;
+
+ if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
+ return;
+
+ m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
+}
+
+void ValueObject::CalculateDynamicValue(DynamicValueType use_dynamic) {
+ if (use_dynamic == eNoDynamicValues)
+ return;
+
+ if (!m_dynamic_value && !IsDynamic()) {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsPossibleDynamicValue(*this)) {
+ ClearDynamicTypeInformation();
+ m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
}
- return synthetic_child_sp;
+ }
}
-void
-ValueObject::CalculateSyntheticValue (bool use_synthetic)
-{
- if (use_synthetic == false)
- return;
-
- TargetSP target_sp(GetTargetSP());
- if (target_sp && target_sp->GetEnableSyntheticValue() == false)
- {
- m_synthetic_value = NULL;
- return;
- }
-
- lldb::SyntheticChildrenSP current_synth_sp(m_synthetic_children_sp);
-
- if (!UpdateFormatsIfNeeded() && m_synthetic_value)
- return;
-
- if (m_synthetic_children_sp.get() == NULL)
- return;
-
- if (current_synth_sp == m_synthetic_children_sp && m_synthetic_value)
- return;
-
- m_synthetic_value = new ValueObjectSynthetic(*this, m_synthetic_children_sp);
-}
+ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) {
+ if (use_dynamic == eNoDynamicValues)
+ return ValueObjectSP();
-void
-ValueObject::CalculateDynamicValue (DynamicValueType use_dynamic)
-{
- if (use_dynamic == eNoDynamicValues)
- return;
-
- if (!m_dynamic_value && !IsDynamic())
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsPossibleDynamicValue(*this))
- {
- ClearDynamicTypeInformation ();
- m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
- }
- }
+ if (!IsDynamic() && m_dynamic_value == NULL) {
+ CalculateDynamicValue(use_dynamic);
+ }
+ if (m_dynamic_value)
+ return m_dynamic_value->GetSP();
+ else
+ return ValueObjectSP();
}
-ValueObjectSP
-ValueObject::GetDynamicValue (DynamicValueType use_dynamic)
-{
- if (use_dynamic == eNoDynamicValues)
- return ValueObjectSP();
-
- if (!IsDynamic() && m_dynamic_value == NULL)
- {
- CalculateDynamicValue(use_dynamic);
- }
- if (m_dynamic_value)
- return m_dynamic_value->GetSP();
- else
- return ValueObjectSP();
-}
+ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); }
-ValueObjectSP
-ValueObject::GetStaticValue()
-{
- return GetSP();
-}
+lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); }
-lldb::ValueObjectSP
-ValueObject::GetNonSyntheticValue ()
-{
- return GetSP();
-}
+ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) {
+ if (use_synthetic == false)
+ return ValueObjectSP();
-ValueObjectSP
-ValueObject::GetSyntheticValue (bool use_synthetic)
-{
- if (use_synthetic == false)
- return ValueObjectSP();
+ CalculateSyntheticValue(use_synthetic);
- CalculateSyntheticValue(use_synthetic);
-
- if (m_synthetic_value)
- return m_synthetic_value->GetSP();
- else
- return ValueObjectSP();
+ if (m_synthetic_value)
+ return m_synthetic_value->GetSP();
+ else
+ return ValueObjectSP();
}
-bool
-ValueObject::HasSyntheticValue()
-{
- UpdateFormatsIfNeeded();
-
- if (m_synthetic_children_sp.get() == NULL)
- return false;
-
- CalculateSyntheticValue(true);
-
- if (m_synthetic_value)
- return true;
- else
- return false;
-}
+bool ValueObject::HasSyntheticValue() {
+ UpdateFormatsIfNeeded();
-bool
-ValueObject::GetBaseClassPath (Stream &s)
-{
- if (IsBaseClass())
- {
- bool parent_had_base_class = GetParent() && GetParent()->GetBaseClassPath (s);
- CompilerType compiler_type = GetCompilerType();
- std::string 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)
- s.PutCString("::");
- s.PutCString(cxx_class_name.c_str());
- }
- return parent_had_base_class || this_had_base_class;
- }
+ if (m_synthetic_children_sp.get() == NULL)
return false;
-}
+ CalculateSyntheticValue(true);
-ValueObject *
-ValueObject::GetNonBaseClassParent()
-{
- if (GetParent())
- {
- if (GetParent()->IsBaseClass())
- return GetParent()->GetNonBaseClassParent();
- else
- return GetParent();
- }
- return NULL;
+ if (m_synthetic_value)
+ return true;
+ else
+ return false;
}
+bool ValueObject::GetBaseClassPath(Stream &s) {
+ if (IsBaseClass()) {
+ bool parent_had_base_class =
+ GetParent() && GetParent()->GetBaseClassPath(s);
+ CompilerType compiler_type = GetCompilerType();
+ std::string 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)
+ s.PutCString("::");
+ s.PutCString(cxx_class_name);
+ }
+ return parent_had_base_class || this_had_base_class;
+ }
+ return false;
+}
+
+ValueObject *ValueObject::GetNonBaseClassParent() {
+ if (GetParent()) {
+ if (GetParent()->IsBaseClass())
+ return GetParent()->GetNonBaseClassParent();
+ else
+ return GetParent();
+ }
+ return NULL;
+}
-bool
-ValueObject::IsBaseClass (uint32_t& depth)
-{
- if (!IsBaseClass())
- {
- depth = 0;
- return false;
- }
- if (GetParent())
- {
- GetParent()->IsBaseClass(depth);
- depth = depth + 1;
- return true;
- }
- // TODO: a base of no parent? weird..
- depth = 1;
+bool ValueObject::IsBaseClass(uint32_t &depth) {
+ if (!IsBaseClass()) {
+ depth = 0;
+ return false;
+ }
+ if (GetParent()) {
+ GetParent()->IsBaseClass(depth);
+ depth = depth + 1;
return true;
-}
+ }
+ // TODO: a base of no parent? weird..
+ depth = 1;
+ return true;
+}
+
+void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes,
+ GetExpressionPathFormat epformat) {
+ // synthetic children do not actually "exist" as part of the hierarchy, and
+ // sometimes they are consed up in ways
+ // that don't make sense from an underlying language/API standpoint. So, use a
+ // special code path here to return
+ // something that can hopefully be used in expression
+ if (m_is_synthetic_children_generated) {
+ UpdateValueIfNeeded();
-void
-ValueObject::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
-{
- // synthetic children do not actually "exist" as part of the hierarchy, and sometimes they are consed up in ways
- // that don't make sense from an underlying language/API standpoint. So, use a special code path here to return
- // something that can hopefully be used in expression
- if (m_is_synthetic_children_generated)
- {
- UpdateValueIfNeeded();
-
- if (m_value.GetValueType() == Value::eValueTypeLoadAddress)
- {
- if (IsPointerOrReferenceType())
- {
- s.Printf("((%s)0x%" PRIx64 ")",
- GetTypeName().AsCString("void"),
- GetValueAsUnsigned(0));
- return;
+ if (m_value.GetValueType() == Value::eValueTypeLoadAddress) {
+ if (IsPointerOrReferenceType()) {
+ s.Printf("((%s)0x%" PRIx64 ")", GetTypeName().AsCString("void"),
+ GetValueAsUnsigned(0));
+ return;
+ } else {
+ uint64_t load_addr =
+ m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ s.Printf("(*( (%s *)0x%" PRIx64 "))", GetTypeName().AsCString("void"),
+ load_addr);
+ return;
+ }
+ }
+ }
+
+ if (CanProvideValue()) {
+ s.Printf("((%s)%s)", GetTypeName().AsCString("void"),
+ GetValueAsCString());
+ return;
+ }
+
+ return;
+ }
+
+ const bool is_deref_of_parent = IsDereferenceOfParent();
+
+ if (is_deref_of_parent &&
+ epformat == eGetExpressionPathFormatDereferencePointers) {
+ // this is the original format of GetExpressionPath() producing code like
+ // *(a_ptr).memberName, which is entirely
+ // fine, until you put this into
+ // StackFrame::GetValueForVariableExpressionPath() which prefers to see
+ // a_ptr->memberName.
+ // the eHonorPointers mode is meant to produce strings in this latter format
+ s.PutCString("*(");
+ }
+
+ ValueObject *parent = GetParent();
+
+ if (parent)
+ parent->GetExpressionPath(s, qualify_cxx_base_classes, epformat);
+
+ // if we are a deref_of_parent just because we are synthetic array
+ // members made up to allow ptr[%d] syntax to work in variable
+ // printing, then add our name ([%d]) to the expression path
+ if (m_is_array_item_for_pointer &&
+ epformat == eGetExpressionPathFormatHonorPointers)
+ s.PutCString(m_name.AsCString());
+
+ if (!IsBaseClass()) {
+ if (!is_deref_of_parent) {
+ ValueObject *non_base_class_parent = GetNonBaseClassParent();
+ if (non_base_class_parent &&
+ !non_base_class_parent->GetName().IsEmpty()) {
+ 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) {
+ s.PutCString("->");
+ } else {
+ const uint32_t non_base_class_parent_type_info =
+ non_base_class_parent_compiler_type.GetTypeInfo();
+
+ if (non_base_class_parent_type_info & eTypeIsPointer) {
+ s.PutCString("->");
+ } else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
+ !(non_base_class_parent_type_info & eTypeIsArray)) {
+ s.PutChar('.');
}
- else
- {
- uint64_t load_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- s.Printf("(*( (%s *)0x%" PRIx64 "))",
- GetTypeName().AsCString("void"),
- load_addr);
- return;
- }
+ }
+ }
+ }
+
+ const char *name = GetName().GetCString();
+ if (name) {
+ if (qualify_cxx_base_classes) {
+ if (GetBaseClassPath(s))
+ s.PutCString("::");
+ }
+ s.PutCString(name);
+ }
+ }
+ }
+
+ if (is_deref_of_parent &&
+ epformat == eGetExpressionPathFormatDereferencePointers) {
+ s.PutChar(')');
+ }
+}
+
+ValueObjectSP ValueObject::GetValueForExpressionPath(
+ llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
+ ExpressionPathEndResultType *final_value_type,
+ const GetValueForExpressionPathOptions &options,
+ ExpressionPathAftermath *final_task_on_target) {
+
+ ExpressionPathScanEndReason dummy_reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonUnknown;
+ ExpressionPathEndResultType dummy_final_value_type =
+ ValueObject::eExpressionPathEndResultTypeInvalid;
+ ExpressionPathAftermath dummy_final_task_on_target =
+ ValueObject::eExpressionPathAftermathNothing;
+
+ ValueObjectSP ret_val = GetValueForExpressionPath_Impl(
+ expression, reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
+ final_value_type ? final_value_type : &dummy_final_value_type, options,
+ final_task_on_target ? final_task_on_target
+ : &dummy_final_task_on_target);
+
+ if (!final_task_on_target ||
+ *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
+ return ret_val;
+
+ if (ret_val.get() &&
+ ((final_value_type ? *final_value_type : dummy_final_value_type) ==
+ eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress
+ // of plain objects
+ {
+ if ((final_task_on_target ? *final_task_on_target
+ : dummy_final_task_on_target) ==
+ ValueObject::eExpressionPathAftermathDereference) {
+ Error error;
+ ValueObjectSP final_value = ret_val->Dereference(error);
+ if (error.Fail() || !final_value.get()) {
+ if (reason_to_stop)
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+ if (final_value_type)
+ *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return ValueObjectSP();
+ } else {
+ if (final_task_on_target)
+ *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
+ return final_value;
+ }
+ }
+ if (*final_task_on_target ==
+ ValueObject::eExpressionPathAftermathTakeAddress) {
+ Error error;
+ ValueObjectSP final_value = ret_val->AddressOf(error);
+ if (error.Fail() || !final_value.get()) {
+ if (reason_to_stop)
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
+ if (final_value_type)
+ *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return ValueObjectSP();
+ } else {
+ if (final_task_on_target)
+ *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
+ return final_value;
+ }
+ }
+ }
+ return ret_val; // final_task_on_target will still have its original value, so
+ // you know I did not do it
+}
+
+ValueObjectSP ValueObject::GetValueForExpressionPath_Impl(
+ llvm::StringRef expression, ExpressionPathScanEndReason *reason_to_stop,
+ ExpressionPathEndResultType *final_result,
+ const GetValueForExpressionPathOptions &options,
+ ExpressionPathAftermath *what_next) {
+ ValueObjectSP root = GetSP();
+
+ if (!root)
+ return nullptr;
+
+ llvm::StringRef remainder = expression;
+
+ while (true) {
+ llvm::StringRef temp_expression = remainder;
+
+ 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 (temp_expression.empty()) {
+ *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
+ return root;
+ }
+
+ switch (temp_expression.front()) {
+ case '-': {
+ temp_expression = temp_expression.drop_front();
+ if (options.m_check_dot_vs_arrow_syntax &&
+ root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
+ // use -> on a
+ // non-pointer and I
+ // must catch the error
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonArrowInsteadOfDot;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return ValueObjectSP();
+ }
+ 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) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return ValueObjectSP();
+ }
+ if (!temp_expression.startswith(">")) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return ValueObjectSP();
+ }
+ }
+ LLVM_FALLTHROUGH;
+ case '.': // or fallthrough from ->
+ {
+ if (options.m_check_dot_vs_arrow_syntax &&
+ temp_expression.front() == '.' &&
+ root_compiler_type_info.Test(eTypeIsPointer)) // if you are trying to
+ // use . on a pointer
+ // and I must catch the
+ // error
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonDotInsteadOfArrow;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+ temp_expression = temp_expression.drop_front(); // skip . or >
+
+ size_t next_sep_pos = temp_expression.find_first_of("-.[", 1);
+ ConstString child_name;
+ if (next_sep_pos == llvm::StringRef::npos) // if no other separator just
+ // expand this last layer
+ {
+ child_name.SetString(temp_expression);
+ ValueObjectSP child_valobj_sp =
+ root->GetChildMemberWithName(child_name, true);
+
+ if (child_valobj_sp.get()) // we know we are done, so just return
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonEndOfString;
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
+ return child_valobj_sp;
+ } else {
+ switch (options.m_synthetic_children_traversal) {
+ case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ None:
+ break;
+ case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ FromSynthetic:
+ if (root->IsSynthetic()) {
+ child_valobj_sp = root->GetNonSyntheticValue();
+ if (child_valobj_sp.get())
+ child_valobj_sp =
+ child_valobj_sp->GetChildMemberWithName(child_name, true);
}
- }
-
- if (CanProvideValue())
- {
- s.Printf("((%s)%s)",
- GetTypeName().AsCString("void"),
- GetValueAsCString());
- return;
- }
-
- return;
- }
-
- const bool is_deref_of_parent = IsDereferenceOfParent ();
-
- if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
- {
- // this is the original format of GetExpressionPath() producing code like *(a_ptr).memberName, which is entirely
- // fine, until you put this into StackFrame::GetValueForVariableExpressionPath() which prefers to see a_ptr->memberName.
- // the eHonorPointers mode is meant to produce strings in this latter format
- s.PutCString("*(");
- }
-
- ValueObject* parent = GetParent();
-
- if (parent)
- parent->GetExpressionPath (s, qualify_cxx_base_classes, epformat);
-
- // if we are a deref_of_parent just because we are synthetic array
- // members made up to allow ptr[%d] syntax to work in variable
- // printing, then add our name ([%d]) to the expression path
- if (m_is_array_item_for_pointer && epformat == eGetExpressionPathFormatHonorPointers)
- s.PutCString(m_name.AsCString());
-
- if (!IsBaseClass())
- {
- if (!is_deref_of_parent)
- {
- ValueObject *non_base_class_parent = GetNonBaseClassParent();
- if (non_base_class_parent && !non_base_class_parent->GetName().IsEmpty())
- {
- 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)
- {
- s.PutCString("->");
- }
- else
- {
- const uint32_t non_base_class_parent_type_info = non_base_class_parent_compiler_type.GetTypeInfo();
-
- if (non_base_class_parent_type_info & eTypeIsPointer)
- {
- s.PutCString("->");
- }
- else if ((non_base_class_parent_type_info & eTypeHasChildren) &&
- !(non_base_class_parent_type_info & eTypeIsArray))
- {
- s.PutChar('.');
- }
- }
- }
+ break;
+ case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ ToSynthetic:
+ if (!root->IsSynthetic()) {
+ child_valobj_sp = root->GetSyntheticValue();
+ if (child_valobj_sp.get())
+ child_valobj_sp =
+ child_valobj_sp->GetChildMemberWithName(child_name, true);
}
-
- const char *name = GetName().GetCString();
- if (name)
- {
- if (qualify_cxx_base_classes)
- {
- if (GetBaseClassPath (s))
- s.PutCString("::");
- }
- s.PutCString(name);
+ break;
+ case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ Both:
+ if (root->IsSynthetic()) {
+ child_valobj_sp = root->GetNonSyntheticValue();
+ if (child_valobj_sp.get())
+ child_valobj_sp =
+ child_valobj_sp->GetChildMemberWithName(child_name, true);
+ } else {
+ child_valobj_sp = root->GetSyntheticValue();
+ if (child_valobj_sp.get())
+ child_valobj_sp =
+ child_valobj_sp->GetChildMemberWithName(child_name, true);
}
- }
- }
-
- if (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
- {
- s.PutChar(')');
- }
-}
-
-ValueObjectSP
-ValueObject::GetValueForExpressionPath(const char* expression,
- const char** first_unparsed,
- ExpressionPathScanEndReason* reason_to_stop,
- ExpressionPathEndResultType* final_value_type,
- const GetValueForExpressionPathOptions& options,
- ExpressionPathAftermath* final_task_on_target)
-{
-
- const char* dummy_first_unparsed;
- ExpressionPathScanEndReason dummy_reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnknown;
- ExpressionPathEndResultType dummy_final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
- ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
-
- ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
- first_unparsed ? first_unparsed : &dummy_first_unparsed,
- reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
- final_value_type ? final_value_type : &dummy_final_value_type,
- options,
- final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
-
- if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
- return ret_val;
-
- if (ret_val.get() && ((final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain)) // I can only deref and takeaddress of plain objects
- {
- if ( (final_task_on_target ? *final_task_on_target : dummy_final_task_on_target) == ValueObject::eExpressionPathAftermathDereference)
- {
- Error error;
- ValueObjectSP final_value = ret_val->Dereference(error);
- if (error.Fail() || !final_value.get())
- {
- if (reason_to_stop)
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
- if (final_value_type)
- *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
+ break;
+ }
+ }
+
+ // if we are here and options.m_no_synthetic_children is true,
+ // child_valobj_sp is going to be a NULL SP,
+ // so we hit the "else" branch, and return an error
+ if (child_valobj_sp.get()) // if it worked, just return
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonEndOfString;
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
+ return child_valobj_sp;
+ } else {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+ } else // other layers do expand
+ {
+ llvm::StringRef next_separator = temp_expression.substr(next_sep_pos);
+
+ child_name.SetString(temp_expression.slice(0, next_sep_pos));
+
+ ValueObjectSP child_valobj_sp =
+ root->GetChildMemberWithName(child_name, true);
+ if (child_valobj_sp.get()) // store the new root and move on
+ {
+ root = child_valobj_sp;
+ remainder = next_separator;
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
+ continue;
+ } else {
+ switch (options.m_synthetic_children_traversal) {
+ case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ None:
+ break;
+ case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ FromSynthetic:
+ if (root->IsSynthetic()) {
+ child_valobj_sp = root->GetNonSyntheticValue();
+ if (child_valobj_sp.get())
+ child_valobj_sp =
+ child_valobj_sp->GetChildMemberWithName(child_name, true);
}
- else
- {
- if (final_task_on_target)
- *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
- return final_value;
+ break;
+ case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ ToSynthetic:
+ if (!root->IsSynthetic()) {
+ child_valobj_sp = root->GetSyntheticValue();
+ if (child_valobj_sp.get())
+ child_valobj_sp =
+ child_valobj_sp->GetChildMemberWithName(child_name, true);
}
- }
- if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress)
- {
+ break;
+ case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::
+ Both:
+ if (root->IsSynthetic()) {
+ child_valobj_sp = root->GetNonSyntheticValue();
+ if (child_valobj_sp.get())
+ child_valobj_sp =
+ child_valobj_sp->GetChildMemberWithName(child_name, true);
+ } else {
+ child_valobj_sp = root->GetSyntheticValue();
+ if (child_valobj_sp.get())
+ child_valobj_sp =
+ child_valobj_sp->GetChildMemberWithName(child_name, true);
+ }
+ break;
+ }
+ }
+
+ // if we are here and options.m_no_synthetic_children is true,
+ // child_valobj_sp is going to be a NULL SP,
+ // so we hit the "else" branch, and return an error
+ if (child_valobj_sp.get()) // if it worked, move on
+ {
+ root = child_valobj_sp;
+ remainder = next_separator;
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
+ continue;
+ } else {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+ }
+ break;
+ }
+ case '[': {
+ 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_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
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return ValueObjectSP();
+ }
+ } else if (!options.m_allow_bitfields_syntax) // if this is a scalar,
+ // check that we can
+ // expand bitfields
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return ValueObjectSP();
+ }
+ }
+ if (temp_expression[1] ==
+ ']') // if this is an unbounded range it only works for arrays
+ {
+ if (!root_compiler_type_info.Test(eTypeIsArray)) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ } else // even if something follows, we cannot expand unbounded ranges,
+ // just let the caller do it
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
+ *final_result =
+ ValueObject::eExpressionPathEndResultTypeUnboundedRange;
+ return root;
+ }
+ }
+
+ size_t close_bracket_position = temp_expression.find(']', 1);
+ if (close_bracket_position ==
+ llvm::StringRef::npos) // if there is no ], this is a syntax error
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+
+ llvm::StringRef bracket_expr =
+ temp_expression.slice(1, close_bracket_position);
+
+ // If this was an empty expression it would have been caught by the if
+ // above.
+ assert(!bracket_expr.empty());
+
+ if (!bracket_expr.contains('-')) {
+ // if no separator, this is of the form [N]. Note that this cannot
+ // be an unbounded range of the form [], because that case was handled
+ // above with an unconditional return.
+ unsigned long index = 0;
+ if (bracket_expr.getAsInteger(0, index)) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+
+ // from here on we do have a valid index
+ if (root_compiler_type_info.Test(eTypeIsArray)) {
+ ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
+ if (!child_valobj_sp)
+ child_valobj_sp = root->GetSyntheticArrayMember(index, true);
+ if (!child_valobj_sp)
+ if (root->HasSyntheticValue() &&
+ root->GetSyntheticValue()->GetNumChildren() > index)
+ child_valobj_sp =
+ root->GetSyntheticValue()->GetChildAtIndex(index, true);
+ if (child_valobj_sp) {
+ root = child_valobj_sp;
+ remainder =
+ temp_expression.substr(close_bracket_position + 1); // skip ]
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
+ continue;
+ } else {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+ } 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_compiler_type_info.Test(eTypeIsScalar)) {
Error error;
- ValueObjectSP final_value = ret_val->AddressOf(error);
- if (error.Fail() || !final_value.get())
- {
- if (reason_to_stop)
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
- if (final_value_type)
- *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
+ root = root->Dereference(error);
+ if (error.Fail() || !root) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ } else {
+ *what_next = eExpressionPathAftermathNothing;
+ continue;
}
- else
- {
- if (final_task_on_target)
- *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
- return final_value;
+ } else {
+ 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)) {
+ root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
+ } else
+ root = root->GetSyntheticArrayMember(index, true);
+ if (!root) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ } else {
+ remainder =
+ temp_expression.substr(close_bracket_position + 1); // skip ]
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
+ continue;
}
- }
- }
- return ret_val; // final_task_on_target will still have its original value, so you know I did not do it
+ }
+ } else if (root_compiler_type_info.Test(eTypeIsScalar)) {
+ root = root->GetSyntheticBitFieldChild(index, index, true);
+ if (!root) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ } else // we do not know how to expand members of bitfields, so we
+ // just return and let the caller do any further processing
+ {
+ *reason_to_stop = ValueObject::
+ eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
+ *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
+ return root;
+ }
+ } else if (root_compiler_type_info.Test(eTypeIsVector)) {
+ root = root->GetChildAtIndex(index, true);
+ if (!root) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return ValueObjectSP();
+ } else {
+ remainder =
+ temp_expression.substr(close_bracket_position + 1); // skip ]
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
+ continue;
+ }
+ } else if (options.m_synthetic_children_traversal ==
+ GetValueForExpressionPathOptions::
+ SyntheticChildrenTraversal::ToSynthetic ||
+ options.m_synthetic_children_traversal ==
+ GetValueForExpressionPathOptions::
+ SyntheticChildrenTraversal::Both) {
+ if (root->HasSyntheticValue())
+ root = root->GetSyntheticValue();
+ else if (!root->IsSynthetic()) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+ // if we are here, then root itself is a synthetic VO.. should be good
+ // to go
+
+ if (!root) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+ root = root->GetChildAtIndex(index, true);
+ if (!root) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ } else {
+ remainder =
+ temp_expression.substr(close_bracket_position + 1); // skip ]
+ *final_result = ValueObject::eExpressionPathEndResultTypePlain;
+ continue;
+ }
+ } else {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+ } else {
+ // we have a low and a high index
+ llvm::StringRef sleft, sright;
+ unsigned long low_index, high_index;
+ std::tie(sleft, sright) = bracket_expr.split('-');
+ if (sleft.getAsInteger(0, low_index) ||
+ sright.getAsInteger(0, high_index)) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+
+ if (low_index > high_index) // swap indices if required
+ std::swap(low_index, high_index);
+
+ if (root_compiler_type_info.Test(
+ eTypeIsScalar)) // expansion only works for scalars
+ {
+ root = root->GetSyntheticBitFieldChild(low_index, high_index, true);
+ if (!root) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonNoSuchChild;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ } else {
+ *reason_to_stop = ValueObject::
+ eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
+ *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
+ return root;
+ }
+ } 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_compiler_type_info.Test(eTypeIsScalar)) {
+ Error error;
+ root = root->Dereference(error);
+ if (error.Fail() || !root) {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ } else {
+ *what_next = ValueObject::eExpressionPathAftermathNothing;
+ continue;
+ }
+ } else {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
+ *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
+ return root;
+ }
+ }
+ break;
+ }
+ default: // some non-separator is in the way
+ {
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return nullptr;
+ }
+ }
+ }
+}
+
+void ValueObject::LogValueObject(Log *log) {
+ if (log)
+ return LogValueObject(log, DumpValueObjectOptions(*this));
+}
+
+void ValueObject::LogValueObject(Log *log,
+ const DumpValueObjectOptions &options) {
+ if (log) {
+ StreamString s;
+ Dump(s, options);
+ if (s.GetSize())
+ log->PutCString(s.GetData());
+ }
}
-int
-ValueObject::GetValuesForExpressionPath(const char* expression,
- ValueObjectListSP& list,
- const char** first_unparsed,
- ExpressionPathScanEndReason* reason_to_stop,
- ExpressionPathEndResultType* final_value_type,
- const GetValueForExpressionPathOptions& options,
- ExpressionPathAftermath* final_task_on_target)
-{
- const char* dummy_first_unparsed;
- ExpressionPathScanEndReason dummy_reason_to_stop;
- ExpressionPathEndResultType dummy_final_value_type;
- ExpressionPathAftermath dummy_final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
-
- ValueObjectSP ret_val = GetValueForExpressionPath_Impl(expression,
- first_unparsed ? first_unparsed : &dummy_first_unparsed,
- reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
- final_value_type ? final_value_type : &dummy_final_value_type,
- options,
- final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
-
- if (!ret_val.get()) // if there are errors, I add nothing to the list
- return 0;
-
- if ( (reason_to_stop ? *reason_to_stop : dummy_reason_to_stop) != eExpressionPathScanEndReasonArrayRangeOperatorMet)
- {
- // I need not expand a range, just post-process the final value and return
- if (!final_task_on_target || *final_task_on_target == ValueObject::eExpressionPathAftermathNothing)
- {
- list->Append(ret_val);
- return 1;
- }
- if (ret_val.get() && (final_value_type ? *final_value_type : dummy_final_value_type) == eExpressionPathEndResultTypePlain) // I can only deref and takeaddress of plain objects
- {
- if (*final_task_on_target == ValueObject::eExpressionPathAftermathDereference)
- {
- Error error;
- ValueObjectSP final_value = ret_val->Dereference(error);
- if (error.Fail() || !final_value.get())
- {
- if (reason_to_stop)
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
- if (final_value_type)
- *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else
- {
- *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
- list->Append(final_value);
- return 1;
- }
- }
- if (*final_task_on_target == ValueObject::eExpressionPathAftermathTakeAddress)
- {
- Error error;
- ValueObjectSP final_value = ret_val->AddressOf(error);
- if (error.Fail() || !final_value.get())
- {
- if (reason_to_stop)
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonTakingAddressFailed;
- if (final_value_type)
- *final_value_type = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else
- {
- *final_task_on_target = ValueObject::eExpressionPathAftermathNothing;
- list->Append(final_value);
- return 1;
- }
- }
- }
- }
- else
- {
- return ExpandArraySliceExpression(first_unparsed ? *first_unparsed : dummy_first_unparsed,
- first_unparsed ? first_unparsed : &dummy_first_unparsed,
- ret_val,
- list,
- reason_to_stop ? reason_to_stop : &dummy_reason_to_stop,
- final_value_type ? final_value_type : &dummy_final_value_type,
- options,
- final_task_on_target ? final_task_on_target : &dummy_final_task_on_target);
- }
- // in any non-covered case, just do the obviously right thing
- list->Append(ret_val);
- return 1;
-}
+void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); }
-ValueObjectSP
-ValueObject::GetValueForExpressionPath_Impl(const char* expression_cstr,
- const char** first_unparsed,
- ExpressionPathScanEndReason* reason_to_stop,
- ExpressionPathEndResultType* final_result,
- const GetValueForExpressionPathOptions& options,
- ExpressionPathAftermath* what_next)
-{
- ValueObjectSP root = GetSP();
-
- if (!root.get())
- return ValueObjectSP();
-
- *first_unparsed = expression_cstr;
-
- while (true)
- {
-
- const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
-
- 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')
- {
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
- return root;
- }
-
- switch (*expression_cstr)
- {
- case '-':
- {
- if (options.m_check_dot_vs_arrow_syntax &&
- 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_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;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonFragileIVarNotAllowed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- if (expression_cstr[1] != '>')
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- expression_cstr++; // skip the -
- }
- LLVM_FALLTHROUGH;
- case '.': // or fallthrough from ->
- {
- if (options.m_check_dot_vs_arrow_syntax && *expression_cstr == '.' &&
- 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;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- expression_cstr++; // skip .
- const char *next_separator = strpbrk(expression_cstr+1,"-.[");
- ConstString child_name;
- if (!next_separator) // if no other separator just expand this last layer
- {
- child_name.SetCString (expression_cstr);
- ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
-
- if (child_valobj_sp.get()) // we know we are done, so just return
- {
- *first_unparsed = "";
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
- return child_valobj_sp;
- }
- else
- {
- switch (options.m_synthetic_children_traversal)
- {
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None:
- break;
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::FromSynthetic:
- if (root->IsSynthetic())
- {
- child_valobj_sp = root->GetNonSyntheticValue();
- if (child_valobj_sp.get())
- child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
- }
- break;
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::ToSynthetic:
- if (!root->IsSynthetic())
- {
- child_valobj_sp = root->GetSyntheticValue();
- if (child_valobj_sp.get())
- child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
- }
- break;
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both:
- if (root->IsSynthetic())
- {
- child_valobj_sp = root->GetNonSyntheticValue();
- if (child_valobj_sp.get())
- child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
- }
- else
- {
- child_valobj_sp = root->GetSyntheticValue();
- if (child_valobj_sp.get())
- child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
- }
- break;
- }
- }
-
- // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
- // so we hit the "else" branch, and return an error
- if(child_valobj_sp.get()) // if it worked, just return
- {
- *first_unparsed = "";
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
- return child_valobj_sp;
- }
- else
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- }
- else // other layers do expand
- {
- child_name.SetCStringWithLength(expression_cstr, next_separator - expression_cstr);
- ValueObjectSP child_valobj_sp = root->GetChildMemberWithName(child_name, true);
- if (child_valobj_sp.get()) // store the new root and move on
- {
- root = child_valobj_sp;
- *first_unparsed = next_separator;
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
- continue;
- }
- else
- {
- switch (options.m_synthetic_children_traversal)
- {
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::None:
- break;
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::FromSynthetic:
- if (root->IsSynthetic())
- {
- child_valobj_sp = root->GetNonSyntheticValue();
- if (child_valobj_sp.get())
- child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
- }
- break;
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::ToSynthetic:
- if (!root->IsSynthetic())
- {
- child_valobj_sp = root->GetSyntheticValue();
- if (child_valobj_sp.get())
- child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
- }
- break;
- case GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both:
- if (root->IsSynthetic())
- {
- child_valobj_sp = root->GetNonSyntheticValue();
- if (child_valobj_sp.get())
- child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
- }
- else
- {
- child_valobj_sp = root->GetSyntheticValue();
- if (child_valobj_sp.get())
- child_valobj_sp = child_valobj_sp->GetChildMemberWithName(child_name, true);
- }
- break;
- }
- }
-
- // if we are here and options.m_no_synthetic_children is true, child_valobj_sp is going to be a NULL SP,
- // so we hit the "else" branch, and return an error
- if(child_valobj_sp.get()) // if it worked, move on
- {
- root = child_valobj_sp;
- *first_unparsed = next_separator;
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
- continue;
- }
- else
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- }
- break;
- }
- case '[':
- {
- 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_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
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorInvalid;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- }
- else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- }
- if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
- {
- if (!root_compiler_type_info.Test(eTypeIsArray))
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- else // even if something follows, we cannot expand unbounded ranges, just let the caller do it
- {
- *first_unparsed = expression_cstr+2;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
- *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange;
- return root;
- }
- }
- const char *separator_position = ::strchr(expression_cstr+1,'-');
- const char *close_bracket_position = ::strchr(expression_cstr+1,']');
- if (!close_bracket_position) // if there is no ], this is a syntax error
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
- {
- char *end = NULL;
- unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
- if (!end || end != close_bracket_position) // if something weird is in our way return an error
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
- {
- if (root_compiler_type_info.Test(eTypeIsArray))
- {
- *first_unparsed = expression_cstr+2;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
- *final_result = ValueObject::eExpressionPathEndResultTypeUnboundedRange;
- return root;
- }
- else
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- }
- // from here on we do have a valid index
- if (root_compiler_type_info.Test(eTypeIsArray))
- {
- ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true);
- if (!child_valobj_sp)
- child_valobj_sp = root->GetSyntheticArrayMember(index, true);
- if (!child_valobj_sp)
- if (root->HasSyntheticValue() && root->GetSyntheticValue()->GetNumChildren() > index)
- child_valobj_sp = root->GetSyntheticValue()->GetChildAtIndex(index, true);
- if (child_valobj_sp)
- {
- root = child_valobj_sp;
- *first_unparsed = end+1; // skip ]
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
- continue;
- }
- else
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- }
- 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_compiler_type_info.Test(eTypeIsScalar))
- {
- Error error;
- root = root->Dereference(error);
- if (error.Fail() || !root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- else
- {
- *what_next = eExpressionPathAftermathNothing;
- continue;
- }
- }
- else
- {
- 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))
- {
- root = root->GetSyntheticValue()->GetChildAtIndex(index, true);
- }
- else
- root = root->GetSyntheticArrayMember(index, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- else
- {
- *first_unparsed = end+1; // skip ]
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
- continue;
- }
- }
- }
- else if (root_compiler_type_info.Test(eTypeIsScalar))
- {
- root = root->GetSyntheticBitFieldChild(index, index, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
- {
- *first_unparsed = end+1; // skip ]
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
- *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
- return root;
- }
- }
- else if (root_compiler_type_info.Test(eTypeIsVector))
- {
- root = root->GetChildAtIndex(index, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- else
- {
- *first_unparsed = end+1; // skip ]
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
- continue;
- }
- }
- else if (options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::ToSynthetic ||
- options.m_synthetic_children_traversal == GetValueForExpressionPathOptions::SyntheticChildrenTraversal::Both)
- {
- if (root->HasSyntheticValue())
- root = root->GetSyntheticValue();
- else if (!root->IsSynthetic())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- // if we are here, then root itself is a synthetic VO.. should be good to go
-
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonSyntheticValueMissing;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- root = root->GetChildAtIndex(index, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- else
- {
- *first_unparsed = end+1; // skip ]
- *final_result = ValueObject::eExpressionPathEndResultTypePlain;
- continue;
- }
- }
- else
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- }
- else // we have a low and a high index
- {
- char *end = NULL;
- unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
- if (!end || end != separator_position) // if something weird is in our way return an error
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
- if (!end || end != close_bracket_position) // if something weird is in our way return an error
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- if (index_lower > index_higher) // swap indices if required
- {
- unsigned long temp = index_lower;
- index_lower = index_higher;
- index_higher = temp;
- }
- if (root_compiler_type_info.Test(eTypeIsScalar)) // expansion only works for scalars
- {
- root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- else
- {
- *first_unparsed = end+1; // skip ]
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonBitfieldRangeOperatorMet;
- *final_result = ValueObject::eExpressionPathEndResultTypeBitfield;
- return root;
- }
- }
- 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_compiler_type_info.Test(eTypeIsScalar))
- {
- Error error;
- root = root->Dereference(error);
- if (error.Fail() || !root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- }
- else
- {
- *what_next = ValueObject::eExpressionPathAftermathNothing;
- continue;
- }
- }
- else
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonArrayRangeOperatorMet;
- *final_result = ValueObject::eExpressionPathEndResultTypeBoundedRange;
- return root;
- }
- }
- break;
- }
- default: // some non-separator is in the way
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return ValueObjectSP();
- break;
- }
- }
- }
+void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) {
+ ValueObjectPrinter printer(this, &s, options);
+ printer.PrintValueObject();
}
-int
-ValueObject::ExpandArraySliceExpression(const char* expression_cstr,
- const char** first_unparsed,
- ValueObjectSP root,
- ValueObjectListSP& list,
- ExpressionPathScanEndReason* reason_to_stop,
- ExpressionPathEndResultType* final_result,
- const GetValueForExpressionPathOptions& options,
- ExpressionPathAftermath* what_next)
-{
- if (!root.get())
- return 0;
-
- *first_unparsed = expression_cstr;
-
- while (true)
- {
-
- const char* expression_cstr = *first_unparsed; // hide the top level expression_cstr
-
- 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')
- {
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
- list->Append(root);
- return 1;
- }
-
- switch (*expression_cstr)
- {
- case '[':
- {
- if (!root_compiler_type_info.Test(eTypeIsArray) && !root_compiler_type_info.Test(eTypeIsPointer)) // if this is not a T[] nor a T*
- {
- 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;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else if (!options.m_allow_bitfields_syntax) // if this is a scalar, check that we can expand bitfields
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorNotAllowed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- }
- if (*(expression_cstr+1) == ']') // if this is an unbounded range it only works for arrays
- {
- if (!root_compiler_type_info.Test(eTypeIsArray))
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else // expand this into list
- {
- const size_t max_index = root->GetNumChildren() - 1;
- for (size_t index = 0; index < max_index; index++)
- {
- ValueObjectSP child =
- root->GetChildAtIndex(index, true);
- list->Append(child);
- }
- *first_unparsed = expression_cstr+2;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
- *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
- return max_index; // tell me number of items I added to the VOList
- }
- }
- const char *separator_position = ::strchr(expression_cstr+1,'-');
- const char *close_bracket_position = ::strchr(expression_cstr+1,']');
- if (!close_bracket_position) // if there is no ], this is a syntax error
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- if (!separator_position || separator_position > close_bracket_position) // if no separator, this is either [] or [N]
- {
- char *end = NULL;
- unsigned long index = ::strtoul (expression_cstr+1, &end, 0);
- if (!end || end != close_bracket_position) // if something weird is in our way return an error
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- if (end - expression_cstr == 1) // if this is [], only return a valid value for arrays
- {
- if (root_compiler_type_info.Test(eTypeIsArray))
- {
- const size_t max_index = root->GetNumChildren() - 1;
- for (size_t index = 0; index < max_index; index++)
- {
- ValueObjectSP child =
- root->GetChildAtIndex(index, true);
- list->Append(child);
- }
- *first_unparsed = expression_cstr+2;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
- *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
- return max_index; // tell me number of items I added to the VOList
- }
- else
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEmptyRangeNotAllowed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- }
- // from here on we do have a valid index
- if (root_compiler_type_info.Test(eTypeIsArray))
- {
- root = root->GetChildAtIndex(index, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else
- {
- list->Append(root);
- *first_unparsed = end+1; // skip ]
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
- *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
- return 1;
- }
- }
- 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_compiler_type_info.Test(eTypeIsScalar))
- {
- Error error;
- root = root->Dereference(error);
- if (error.Fail() || !root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else
- {
- *what_next = eExpressionPathAftermathNothing;
- continue;
- }
- }
- else
- {
- root = root->GetSyntheticArrayMember(index, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else
- {
- list->Append(root);
- *first_unparsed = end+1; // skip ]
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
- *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
- return 1;
- }
- }
- }
- else /*if (ClangASTContext::IsScalarType(root_compiler_type))*/
- {
- root = root->GetSyntheticBitFieldChild(index, index, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else // we do not know how to expand members of bitfields, so we just return and let the caller do any further processing
- {
- list->Append(root);
- *first_unparsed = end+1; // skip ]
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
- *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
- return 1;
- }
- }
- }
- else // we have a low and a high index
- {
- char *end = NULL;
- unsigned long index_lower = ::strtoul (expression_cstr+1, &end, 0);
- if (!end || end != separator_position) // if something weird is in our way return an error
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- unsigned long index_higher = ::strtoul (separator_position+1, &end, 0);
- if (!end || end != close_bracket_position) // if something weird is in our way return an error
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- if (index_lower > index_higher) // swap indices if required
- {
- unsigned long temp = index_lower;
- index_lower = index_higher;
- index_higher = temp;
- }
- if (root_compiler_type_info.Test(eTypeIsScalar)) // expansion only works for scalars
- {
- root = root->GetSyntheticBitFieldChild(index_lower, index_higher, true);
- if (!root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else
- {
- list->Append(root);
- *first_unparsed = end+1; // skip ]
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
- *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
- return 1;
- }
- }
- 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_compiler_type_info.Test(eTypeIsScalar))
- {
- Error error;
- root = root->Dereference(error);
- if (error.Fail() || !root.get())
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonDereferencingFailed;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- }
- else
- {
- *what_next = ValueObject::eExpressionPathAftermathNothing;
- continue;
- }
- }
- else
- {
- for (unsigned long index = index_lower;
- index <= index_higher; index++)
- {
- ValueObjectSP child =
- root->GetChildAtIndex(index, true);
- list->Append(child);
- }
- *first_unparsed = end+1;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonRangeOperatorExpanded;
- *final_result = ValueObject::eExpressionPathEndResultTypeValueObjectList;
- return index_higher-index_lower+1; // tell me number of items I added to the VOList
- }
- }
- break;
- }
- default: // some non-[ separator, or something entirely wrong, is in the way
- {
- *first_unparsed = expression_cstr;
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
- *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
- return 0;
- break;
- }
- }
- }
-}
+ValueObjectSP ValueObject::CreateConstantValue(const ConstString &name) {
+ ValueObjectSP valobj_sp;
-void
-ValueObject::LogValueObject (Log *log)
-{
- if (log)
- return LogValueObject (log, DumpValueObjectOptions(*this));
-}
+ if (UpdateValueIfNeeded(false) && m_error.Success()) {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
-void
-ValueObject::LogValueObject (Log *log, const DumpValueObjectOptions& options)
-{
- if (log)
- {
- StreamString s;
- Dump (s, options);
- if (s.GetSize())
- log->PutCString(s.GetData());
- }
-}
+ DataExtractor data;
+ data.SetByteOrder(m_data.GetByteOrder());
+ data.SetAddressByteSize(m_data.GetAddressByteSize());
-void
-ValueObject::Dump (Stream &s)
-{
- Dump (s, DumpValueObjectOptions(*this));
-}
+ if (IsBitfield()) {
+ Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
+ m_error = v.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
+ } else
+ m_error = m_value.GetValueAsData(&exe_ctx, data, 0, GetModule().get());
-void
-ValueObject::Dump (Stream &s,
- const DumpValueObjectOptions& options)
-{
- ValueObjectPrinter printer(this,&s,options);
- printer.PrintValueObject();
-}
+ valobj_sp = ValueObjectConstResult::Create(
+ exe_ctx.GetBestExecutionContextScope(), GetCompilerType(), name, data,
+ GetAddressOf());
+ }
-ValueObjectSP
-ValueObject::CreateConstantValue (const ConstString &name)
-{
- ValueObjectSP valobj_sp;
-
- if (UpdateValueIfNeeded(false) && m_error.Success())
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- DataExtractor data;
- data.SetByteOrder (m_data.GetByteOrder());
- data.SetAddressByteSize(m_data.GetAddressByteSize());
-
- if (IsBitfield())
- {
- Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
- m_error = v.GetValueAsData (&exe_ctx, data, 0, GetModule().get());
- }
- else
- m_error = m_value.GetValueAsData (&exe_ctx, data, 0, GetModule().get());
-
- valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- GetCompilerType(),
- name,
- data,
- GetAddressOf());
- }
-
- if (!valobj_sp)
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
- valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), m_error);
- }
- return valobj_sp;
+ if (!valobj_sp) {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ valobj_sp = ValueObjectConstResult::Create(
+ exe_ctx.GetBestExecutionContextScope(), m_error);
+ }
+ return valobj_sp;
}
-ValueObjectSP
-ValueObject::GetQualifiedRepresentationIfAvailable (lldb::DynamicValueType dynValue,
- bool synthValue)
-{
- ValueObjectSP result_sp(GetSP());
-
- switch (dynValue)
- {
- case lldb::eDynamicCanRunTarget:
- case lldb::eDynamicDontRunTarget:
- {
- if (!result_sp->IsDynamic())
- {
- if (result_sp->GetDynamicValue(dynValue))
- result_sp = result_sp->GetDynamicValue(dynValue);
- }
- }
- break;
- case lldb::eNoDynamicValues:
- {
- if (result_sp->IsDynamic())
- {
- if (result_sp->GetStaticValue())
- result_sp = result_sp->GetStaticValue();
- }
- }
- break;
+ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable(
+ lldb::DynamicValueType dynValue, bool synthValue) {
+ ValueObjectSP result_sp(GetSP());
+
+ switch (dynValue) {
+ case lldb::eDynamicCanRunTarget:
+ case lldb::eDynamicDontRunTarget: {
+ if (!result_sp->IsDynamic()) {
+ if (result_sp->GetDynamicValue(dynValue))
+ result_sp = result_sp->GetDynamicValue(dynValue);
}
-
- if (synthValue)
- {
- if (!result_sp->IsSynthetic())
- {
- if (result_sp->GetSyntheticValue())
- result_sp = result_sp->GetSyntheticValue();
- }
+ } break;
+ case lldb::eNoDynamicValues: {
+ if (result_sp->IsDynamic()) {
+ if (result_sp->GetStaticValue())
+ result_sp = result_sp->GetStaticValue();
}
- else
- {
- if (result_sp->IsSynthetic())
- {
- if (result_sp->GetNonSyntheticValue())
- result_sp = result_sp->GetNonSyntheticValue();
- }
- }
-
- return result_sp;
-}
+ } break;
+ }
-lldb::addr_t
-ValueObject::GetCPPVTableAddress (AddressType &address_type)
-{
- CompilerType pointee_type;
- CompilerType this_type(GetCompilerType());
- uint32_t type_info = this_type.GetTypeInfo(&pointee_type);
- if (type_info)
- {
- bool ptr_or_ref = false;
- if (type_info & (eTypeIsPointer | eTypeIsReference))
- {
- ptr_or_ref = true;
- type_info = pointee_type.GetTypeInfo();
- }
-
- const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
- if ((type_info & cpp_class) == cpp_class)
- {
- if (ptr_or_ref)
- {
- address_type = GetAddressTypeOfChildren();
- return GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
- }
- else
- return GetAddressOf (false, &address_type);
- }
+ if (synthValue) {
+ if (!result_sp->IsSynthetic()) {
+ if (result_sp->GetSyntheticValue())
+ result_sp = result_sp->GetSyntheticValue();
+ }
+ } else {
+ if (result_sp->IsSynthetic()) {
+ if (result_sp->GetNonSyntheticValue())
+ result_sp = result_sp->GetNonSyntheticValue();
}
+ }
- address_type = eAddressTypeInvalid;
- return LLDB_INVALID_ADDRESS;
+ return result_sp;
}
-ValueObjectSP
-ValueObject::Dereference (Error &error)
-{
- if (m_deref_valobj)
- return m_deref_valobj->GetSP();
-
- 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;
-
- std::string child_name_str;
- uint32_t child_byte_size = 0;
- int32_t child_byte_offset = 0;
- uint32_t child_bitfield_bit_size = 0;
- uint32_t child_bitfield_bit_offset = 0;
- bool child_is_base_class = false;
- bool child_is_deref_of_parent = false;
- const bool transparent_pointers = false;
- CompilerType compiler_type = GetCompilerType();
- CompilerType child_compiler_type;
- uint64_t language_flags;
-
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- 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_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,
- eAddressTypeInvalid,
- language_flags);
- }
+lldb::addr_t ValueObject::GetCPPVTableAddress(AddressType &address_type) {
+ CompilerType pointee_type;
+ CompilerType this_type(GetCompilerType());
+ uint32_t type_info = this_type.GetTypeInfo(&pointee_type);
+ if (type_info) {
+ bool ptr_or_ref = false;
+ if (type_info & (eTypeIsPointer | eTypeIsReference)) {
+ ptr_or_ref = true;
+ type_info = pointee_type.GetTypeInfo();
}
- if (m_deref_valobj)
- {
- error.Clear();
- return m_deref_valobj->GetSP();
+ const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus;
+ if ((type_info & cpp_class) == cpp_class) {
+ if (ptr_or_ref) {
+ address_type = GetAddressTypeOfChildren();
+ return GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+ } else
+ return GetAddressOf(false, &address_type);
}
- else
- {
- StreamString strm;
- GetExpressionPath(strm, true);
+ }
- 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 or reference type: (%s) %s", GetTypeName().AsCString("<invalid type>"), strm.GetString().c_str());
- return ValueObjectSP();
- }
+ address_type = eAddressTypeInvalid;
+ return LLDB_INVALID_ADDRESS;
}
-ValueObjectSP
-ValueObject::AddressOf (Error &error)
-{
- if (m_addr_of_valobj_sp)
- return m_addr_of_valobj_sp;
-
- AddressType address_type = eAddressTypeInvalid;
- const bool scalar_is_load_address = false;
- addr_t addr = GetAddressOf (scalar_is_load_address, &address_type);
- error.Clear();
- if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost)
- {
- switch (address_type)
- {
- case eAddressTypeInvalid:
- {
- StreamString expr_path_strm;
- GetExpressionPath(expr_path_strm, true);
- error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetString().c_str());
- }
- break;
-
- case eAddressTypeFile:
- case eAddressTypeLoad:
- {
- 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(),
- compiler_type.GetPointerType(),
- ConstString (name.c_str()),
- addr,
- eAddressTypeInvalid,
- m_data.GetAddressByteSize());
- }
- }
- break;
- default:
- break;
- }
- }
- else
- {
- StreamString expr_path_strm;
- GetExpressionPath(expr_path_strm, true);
- error.SetErrorStringWithFormat("'%s' doesn't have a valid address", expr_path_strm.GetString().c_str());
- }
-
- return m_addr_of_valobj_sp;
-}
+ValueObjectSP ValueObject::Dereference(Error &error) {
+ if (m_deref_valobj)
+ return m_deref_valobj->GetSP();
-ValueObjectSP
-ValueObject::Cast (const CompilerType &compiler_type)
-{
- return ValueObjectCast::Create (*this, GetName(), compiler_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;
-ValueObjectSP
-ValueObject::CastPointerType (const char *name, CompilerType &compiler_type)
-{
- ValueObjectSP valobj_sp;
- AddressType address_type;
- addr_t ptr_value = GetPointerValue (&address_type);
-
- if (ptr_value != LLDB_INVALID_ADDRESS)
- {
- Address ptr_addr (ptr_value);
- ExecutionContext exe_ctx (GetExecutionContextRef());
- valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(),
- name,
- ptr_addr,
- compiler_type);
- }
- return valobj_sp;
-}
+ std::string child_name_str;
+ uint32_t child_byte_size = 0;
+ int32_t child_byte_offset = 0;
+ uint32_t child_bitfield_bit_size = 0;
+ uint32_t child_bitfield_bit_offset = 0;
+ bool child_is_base_class = false;
+ bool child_is_deref_of_parent = false;
+ const bool transparent_pointers = false;
+ CompilerType compiler_type = GetCompilerType();
+ CompilerType child_compiler_type;
+ uint64_t language_flags;
-ValueObjectSP
-ValueObject::CastPointerType (const char *name, TypeSP &type_sp)
-{
- ValueObjectSP valobj_sp;
- AddressType address_type;
- addr_t ptr_value = GetPointerValue (&address_type);
-
- if (ptr_value != LLDB_INVALID_ADDRESS)
- {
- Address ptr_addr (ptr_value);
- ExecutionContext exe_ctx (GetExecutionContextRef());
- valobj_sp = ValueObjectMemory::Create (exe_ctx.GetBestExecutionContextScope(),
- name,
- ptr_addr,
- type_sp);
- }
- return valobj_sp;
-}
+ ExecutionContext exe_ctx(GetExecutionContextRef());
-ValueObject::EvaluationPoint::EvaluationPoint () :
- m_mod_id(),
- m_exe_ctx_ref(),
- m_needs_update (true)
-{
-}
+ 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());
-ValueObject::EvaluationPoint::EvaluationPoint (ExecutionContextScope *exe_scope, bool use_selected):
- m_mod_id(),
- m_exe_ctx_ref(),
- m_needs_update (true)
-{
- ExecutionContext exe_ctx(exe_scope);
- TargetSP target_sp (exe_ctx.GetTargetSP());
- if (target_sp)
- {
- m_exe_ctx_ref.SetTargetSP (target_sp);
- ProcessSP process_sp (exe_ctx.GetProcessSP());
- if (!process_sp)
- process_sp = target_sp->GetProcessSP();
-
- if (process_sp)
- {
- m_mod_id = process_sp->GetModID();
- m_exe_ctx_ref.SetProcessSP (process_sp);
-
- ThreadSP thread_sp (exe_ctx.GetThreadSP());
-
- if (!thread_sp)
- {
- if (use_selected)
- thread_sp = process_sp->GetThreadList().GetSelectedThread();
- }
-
- if (thread_sp)
- {
- m_exe_ctx_ref.SetThreadSP(thread_sp);
-
- StackFrameSP frame_sp (exe_ctx.GetFrameSP());
- if (!frame_sp)
- {
- if (use_selected)
- frame_sp = thread_sp->GetSelectedFrame();
- }
- if (frame_sp)
- m_exe_ctx_ref.SetFrameSP(frame_sp);
- }
- }
+ m_deref_valobj = new ValueObjectChild(
+ *this, 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, eAddressTypeInvalid,
+ language_flags);
}
-}
+ }
-ValueObject::EvaluationPoint::EvaluationPoint (const ValueObject::EvaluationPoint &rhs) :
- m_mod_id(),
- m_exe_ctx_ref(rhs.m_exe_ctx_ref),
- m_needs_update (true)
-{
-}
+ if (m_deref_valobj) {
+ error.Clear();
+ return m_deref_valobj->GetSP();
+ } else {
+ StreamString strm;
+ GetExpressionPath(strm, true);
-ValueObject::EvaluationPoint::~EvaluationPoint ()
-{
+ if (is_pointer_or_reference_type)
+ error.SetErrorStringWithFormat("dereference failed: (%s) %s",
+ GetTypeName().AsCString("<invalid type>"),
+ strm.GetData());
+ else
+ error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
+ GetTypeName().AsCString("<invalid type>"),
+ strm.GetData());
+ return ValueObjectSP();
+ }
}
-// This function checks the EvaluationPoint against the current process state. If the current
-// state matches the evaluation point, or the evaluation point is already invalid, then we return
-// false, meaning "no change". If the current state is different, we update our state, and return
-// true meaning "yes, change". If we did see a change, we also set m_needs_update to true, so
+ValueObjectSP ValueObject::AddressOf(Error &error) {
+ if (m_addr_of_valobj_sp)
+ return m_addr_of_valobj_sp;
+
+ AddressType address_type = eAddressTypeInvalid;
+ const bool scalar_is_load_address = false;
+ addr_t addr = GetAddressOf(scalar_is_load_address, &address_type);
+ error.Clear();
+ if (addr != LLDB_INVALID_ADDRESS && address_type != eAddressTypeHost) {
+ switch (address_type) {
+ case eAddressTypeInvalid: {
+ StreamString expr_path_strm;
+ GetExpressionPath(expr_path_strm, true);
+ error.SetErrorStringWithFormat("'%s' is not in memory",
+ expr_path_strm.GetData());
+ } break;
+
+ case eAddressTypeFile:
+ case eAddressTypeLoad: {
+ 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(),
+ compiler_type.GetPointerType(), ConstString(name.c_str()), addr,
+ eAddressTypeInvalid, m_data.GetAddressByteSize());
+ }
+ } break;
+ default:
+ break;
+ }
+ } else {
+ StreamString expr_path_strm;
+ GetExpressionPath(expr_path_strm, true);
+ error.SetErrorStringWithFormat("'%s' doesn't have a valid address",
+ expr_path_strm.GetData());
+ }
+
+ return m_addr_of_valobj_sp;
+}
+
+ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
+ return ValueObjectCast::Create(*this, GetName(), compiler_type);
+}
+
+ValueObjectSP ValueObject::CastPointerType(const char *name,
+ CompilerType &compiler_type) {
+ ValueObjectSP valobj_sp;
+ AddressType address_type;
+ addr_t ptr_value = GetPointerValue(&address_type);
+
+ if (ptr_value != LLDB_INVALID_ADDRESS) {
+ Address ptr_addr(ptr_value);
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ valobj_sp = ValueObjectMemory::Create(
+ exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, compiler_type);
+ }
+ return valobj_sp;
+}
+
+ValueObjectSP ValueObject::CastPointerType(const char *name, TypeSP &type_sp) {
+ ValueObjectSP valobj_sp;
+ AddressType address_type;
+ addr_t ptr_value = GetPointerValue(&address_type);
+
+ if (ptr_value != LLDB_INVALID_ADDRESS) {
+ Address ptr_addr(ptr_value);
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ valobj_sp = ValueObjectMemory::Create(
+ exe_ctx.GetBestExecutionContextScope(), name, ptr_addr, type_sp);
+ }
+ return valobj_sp;
+}
+
+ValueObject::EvaluationPoint::EvaluationPoint()
+ : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {}
+
+ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope,
+ bool use_selected)
+ : m_mod_id(), m_exe_ctx_ref(), m_needs_update(true) {
+ ExecutionContext exe_ctx(exe_scope);
+ TargetSP target_sp(exe_ctx.GetTargetSP());
+ if (target_sp) {
+ m_exe_ctx_ref.SetTargetSP(target_sp);
+ ProcessSP process_sp(exe_ctx.GetProcessSP());
+ if (!process_sp)
+ process_sp = target_sp->GetProcessSP();
+
+ if (process_sp) {
+ m_mod_id = process_sp->GetModID();
+ m_exe_ctx_ref.SetProcessSP(process_sp);
+
+ ThreadSP thread_sp(exe_ctx.GetThreadSP());
+
+ if (!thread_sp) {
+ if (use_selected)
+ thread_sp = process_sp->GetThreadList().GetSelectedThread();
+ }
+
+ if (thread_sp) {
+ m_exe_ctx_ref.SetThreadSP(thread_sp);
+
+ StackFrameSP frame_sp(exe_ctx.GetFrameSP());
+ if (!frame_sp) {
+ if (use_selected)
+ frame_sp = thread_sp->GetSelectedFrame();
+ }
+ if (frame_sp)
+ m_exe_ctx_ref.SetFrameSP(frame_sp);
+ }
+ }
+ }
+}
+
+ValueObject::EvaluationPoint::EvaluationPoint(
+ const ValueObject::EvaluationPoint &rhs)
+ : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), m_needs_update(true) {}
+
+ValueObject::EvaluationPoint::~EvaluationPoint() {}
+
+// This function checks the EvaluationPoint against the current process state.
+// If the current
+// state matches the evaluation point, or the evaluation point is already
+// invalid, then we return
+// false, meaning "no change". If the current state is different, we update our
+// state, and return
+// true meaning "yes, change". If we did see a change, we also set
+// m_needs_update to true, so
// future calls to NeedsUpdate will return true.
// exe_scope will be set to the current execution context scope.
-bool
-ValueObject::EvaluationPoint::SyncWithProcessState(bool accept_invalid_exe_ctx)
-{
- // Start with the target, if it is NULL, then we're obviously not going to get any further:
- const bool thread_and_frame_only_if_stopped = true;
- ExecutionContext exe_ctx(m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
-
- if (exe_ctx.GetTargetPtr() == NULL)
- return false;
-
- // If we don't have a process nothing can change.
- Process *process = exe_ctx.GetProcessPtr();
- if (process == NULL)
- return false;
-
- // If our stop id is the current stop ID, nothing has changed:
- ProcessModID current_mod_id = process->GetModID();
-
- // If the current stop id is 0, either we haven't run yet, or the process state has been cleared.
- // In either case, we aren't going to be able to sync with the process state.
- if (current_mod_id.GetStopID() == 0)
- return false;
-
- bool changed = false;
- const bool was_valid = m_mod_id.IsValid();
- if (was_valid)
- {
- if (m_mod_id == current_mod_id)
- {
- // Everything is already up to date in this object, no need to
- // update the execution context scope.
- changed = false;
- }
- else
- {
- m_mod_id = current_mod_id;
- m_needs_update = true;
- changed = true;
- }
- }
-
- // Now re-look up the thread and frame in case the underlying objects have gone away & been recreated.
- // That way we'll be sure to return a valid exe_scope.
- // If we used to have a thread or a frame but can't find it anymore, then mark ourselves as invalid.
-
- if (!accept_invalid_exe_ctx)
- {
- if (m_exe_ctx_ref.HasThreadRef())
- {
- ThreadSP thread_sp (m_exe_ctx_ref.GetThreadSP());
- if (thread_sp)
- {
- if (m_exe_ctx_ref.HasFrameRef())
- {
- StackFrameSP frame_sp (m_exe_ctx_ref.GetFrameSP());
- if (!frame_sp)
- {
- // We used to have a frame, but now it is gone
- SetInvalid();
- changed = was_valid;
- }
- }
- }
- else
- {
- // We used to have a thread, but now it is gone
- SetInvalid();
- changed = was_valid;
- }
- }
- }
+bool ValueObject::EvaluationPoint::SyncWithProcessState(
+ bool accept_invalid_exe_ctx) {
+ // Start with the target, if it is NULL, then we're obviously not going to get
+ // any further:
+ const bool thread_and_frame_only_if_stopped = true;
+ ExecutionContext exe_ctx(
+ m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped));
- return changed;
-}
+ if (exe_ctx.GetTargetPtr() == NULL)
+ return false;
-void
-ValueObject::EvaluationPoint::SetUpdated ()
-{
- ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
- if (process_sp)
- m_mod_id = process_sp->GetModID();
- m_needs_update = false;
-}
-
-
-
-void
-ValueObject::ClearUserVisibleData(uint32_t clear_mask)
-{
- if ((clear_mask & eClearUserVisibleDataItemsValue) == eClearUserVisibleDataItemsValue)
- m_value_str.clear();
-
- if ((clear_mask & eClearUserVisibleDataItemsLocation) == eClearUserVisibleDataItemsLocation)
- m_location_str.clear();
-
- if ((clear_mask & eClearUserVisibleDataItemsSummary) == eClearUserVisibleDataItemsSummary)
- m_summary_str.clear();
-
- if ((clear_mask & eClearUserVisibleDataItemsDescription) == eClearUserVisibleDataItemsDescription)
- m_object_desc_str.clear();
-
- if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) == eClearUserVisibleDataItemsSyntheticChildren)
- {
- if (m_synthetic_value)
- m_synthetic_value = NULL;
- }
-
- if ((clear_mask & eClearUserVisibleDataItemsValidator) == eClearUserVisibleDataItemsValidator)
- m_validation_result.reset();
-}
+ // If we don't have a process nothing can change.
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process == NULL)
+ return false;
-SymbolContextScope *
-ValueObject::GetSymbolContextScope()
-{
- if (m_parent)
- {
- if (!m_parent->IsPointerOrReferenceType())
- return m_parent->GetSymbolContextScope();
- }
- return NULL;
-}
+ // If our stop id is the current stop ID, nothing has changed:
+ ProcessModID current_mod_id = process->GetModID();
-lldb::ValueObjectSP
-ValueObject::CreateValueObjectFromExpression (const char* name,
- const char* expression,
- const ExecutionContext& exe_ctx)
-{
- return CreateValueObjectFromExpression(name, expression, exe_ctx, EvaluateExpressionOptions());
-}
+ // If the current stop id is 0, either we haven't run yet, or the process
+ // state has been cleared.
+ // In either case, we aren't going to be able to sync with the process state.
+ if (current_mod_id.GetStopID() == 0)
+ return false;
+ bool changed = false;
+ const bool was_valid = m_mod_id.IsValid();
+ if (was_valid) {
+ if (m_mod_id == current_mod_id) {
+ // Everything is already up to date in this object, no need to
+ // update the execution context scope.
+ changed = false;
+ } else {
+ m_mod_id = current_mod_id;
+ m_needs_update = true;
+ changed = true;
+ }
+ }
+
+ // Now re-look up the thread and frame in case the underlying objects have
+ // gone away & been recreated.
+ // That way we'll be sure to return a valid exe_scope.
+ // If we used to have a thread or a frame but can't find it anymore, then mark
+ // ourselves as invalid.
+
+ if (!accept_invalid_exe_ctx) {
+ if (m_exe_ctx_ref.HasThreadRef()) {
+ ThreadSP thread_sp(m_exe_ctx_ref.GetThreadSP());
+ if (thread_sp) {
+ if (m_exe_ctx_ref.HasFrameRef()) {
+ StackFrameSP frame_sp(m_exe_ctx_ref.GetFrameSP());
+ if (!frame_sp) {
+ // We used to have a frame, but now it is gone
+ SetInvalid();
+ changed = was_valid;
+ }
+ }
+ } else {
+ // We used to have a thread, but now it is gone
+ SetInvalid();
+ changed = was_valid;
+ }
+ }
+ }
+
+ return changed;
+}
+
+void ValueObject::EvaluationPoint::SetUpdated() {
+ ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP());
+ if (process_sp)
+ m_mod_id = process_sp->GetModID();
+ m_needs_update = false;
+}
+
+void ValueObject::ClearUserVisibleData(uint32_t clear_mask) {
+ if ((clear_mask & eClearUserVisibleDataItemsValue) ==
+ eClearUserVisibleDataItemsValue)
+ m_value_str.clear();
+
+ if ((clear_mask & eClearUserVisibleDataItemsLocation) ==
+ eClearUserVisibleDataItemsLocation)
+ m_location_str.clear();
+
+ if ((clear_mask & eClearUserVisibleDataItemsSummary) ==
+ eClearUserVisibleDataItemsSummary)
+ m_summary_str.clear();
+
+ if ((clear_mask & eClearUserVisibleDataItemsDescription) ==
+ eClearUserVisibleDataItemsDescription)
+ m_object_desc_str.clear();
+
+ if ((clear_mask & eClearUserVisibleDataItemsSyntheticChildren) ==
+ eClearUserVisibleDataItemsSyntheticChildren) {
+ if (m_synthetic_value)
+ m_synthetic_value = NULL;
+ }
-lldb::ValueObjectSP
-ValueObject::CreateValueObjectFromExpression (const char* name,
- const char* expression,
- const ExecutionContext& exe_ctx,
- const EvaluateExpressionOptions& options)
-{
- lldb::ValueObjectSP retval_sp;
- lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
- if (!target_sp)
- return retval_sp;
- if (!expression || !*expression)
- return retval_sp;
- target_sp->EvaluateExpression (expression,
- exe_ctx.GetFrameSP().get(),
- retval_sp,
- options);
- if (retval_sp && name && *name)
- retval_sp->SetName(ConstString(name));
- return retval_sp;
+ if ((clear_mask & eClearUserVisibleDataItemsValidator) ==
+ eClearUserVisibleDataItemsValidator)
+ m_validation_result.reset();
}
-lldb::ValueObjectSP
-ValueObject::CreateValueObjectFromAddress (const char* name,
- uint64_t address,
- const ExecutionContext& exe_ctx,
- CompilerType type)
-{
- if (type)
- {
- CompilerType pointer_type(type.GetPointerType());
- if (pointer_type)
- {
- lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&address,sizeof(lldb::addr_t)));
- lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- pointer_type,
- ConstString(name),
- buffer,
- exe_ctx.GetByteOrder(),
- exe_ctx.GetAddressByteSize()));
- if (ptr_result_valobj_sp)
- {
- ptr_result_valobj_sp->GetValue().SetValueType(Value::eValueTypeLoadAddress);
- Error err;
- ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
- if (ptr_result_valobj_sp && name && *name)
- ptr_result_valobj_sp->SetName(ConstString(name));
- }
- return ptr_result_valobj_sp;
- }
- }
- return lldb::ValueObjectSP();
+SymbolContextScope *ValueObject::GetSymbolContextScope() {
+ if (m_parent) {
+ if (!m_parent->IsPointerOrReferenceType())
+ return m_parent->GetSymbolContextScope();
+ }
+ return NULL;
}
lldb::ValueObjectSP
-ValueObject::CreateValueObjectFromData (const char* name,
- const DataExtractor& data,
- const ExecutionContext& exe_ctx,
- CompilerType type)
-{
- lldb::ValueObjectSP new_value_sp;
- new_value_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- type,
- ConstString(name),
- data,
- LLDB_INVALID_ADDRESS);
- new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
- if (new_value_sp && name && *name)
- new_value_sp->SetName(ConstString(name));
- return new_value_sp;
+ValueObject::CreateValueObjectFromExpression(llvm::StringRef name,
+ llvm::StringRef expression,
+ const ExecutionContext &exe_ctx) {
+ return CreateValueObjectFromExpression(name, expression, exe_ctx,
+ EvaluateExpressionOptions());
+}
+
+lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
+ llvm::StringRef name, llvm::StringRef expression,
+ const ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options) {
+ lldb::ValueObjectSP retval_sp;
+ lldb::TargetSP target_sp(exe_ctx.GetTargetSP());
+ if (!target_sp)
+ return retval_sp;
+ if (expression.empty())
+ return retval_sp;
+ target_sp->EvaluateExpression(expression, exe_ctx.GetFrameSP().get(),
+ retval_sp, options);
+ if (retval_sp && !name.empty())
+ retval_sp->SetName(ConstString(name));
+ return retval_sp;
+}
+
+lldb::ValueObjectSP ValueObject::CreateValueObjectFromAddress(
+ llvm::StringRef name, uint64_t address, const ExecutionContext &exe_ctx,
+ CompilerType type) {
+ if (type) {
+ CompilerType pointer_type(type.GetPointerType());
+ if (pointer_type) {
+ lldb::DataBufferSP buffer(
+ new lldb_private::DataBufferHeap(&address, sizeof(lldb::addr_t)));
+ lldb::ValueObjectSP ptr_result_valobj_sp(ValueObjectConstResult::Create(
+ exe_ctx.GetBestExecutionContextScope(), pointer_type,
+ ConstString(name), buffer, exe_ctx.GetByteOrder(),
+ exe_ctx.GetAddressByteSize()));
+ if (ptr_result_valobj_sp) {
+ ptr_result_valobj_sp->GetValue().SetValueType(
+ Value::eValueTypeLoadAddress);
+ Error err;
+ ptr_result_valobj_sp = ptr_result_valobj_sp->Dereference(err);
+ if (ptr_result_valobj_sp && !name.empty())
+ ptr_result_valobj_sp->SetName(ConstString(name));
+ }
+ return ptr_result_valobj_sp;
+ }
+ }
+ return lldb::ValueObjectSP();
+}
+
+lldb::ValueObjectSP ValueObject::CreateValueObjectFromData(
+ llvm::StringRef name, const DataExtractor &data,
+ const ExecutionContext &exe_ctx, CompilerType type) {
+ lldb::ValueObjectSP new_value_sp;
+ new_value_sp = ValueObjectConstResult::Create(
+ exe_ctx.GetBestExecutionContextScope(), type, ConstString(name), data,
+ LLDB_INVALID_ADDRESS);
+ new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
+ if (new_value_sp && !name.empty())
+ new_value_sp->SetName(ConstString(name));
+ return new_value_sp;
+}
+
+ModuleSP ValueObject::GetModule() {
+ ValueObject *root(GetRoot());
+ if (root != this)
+ return root->GetModule();
+ return lldb::ModuleSP();
+}
+
+ValueObject *ValueObject::GetRoot() {
+ if (m_root)
+ return m_root;
+ return (m_root = FollowParentChain([](ValueObject *vo) -> bool {
+ return (vo->m_parent != nullptr);
+ }));
}
-ModuleSP
-ValueObject::GetModule ()
-{
- ValueObject* root(GetRoot());
+ValueObject *
+ValueObject::FollowParentChain(std::function<bool(ValueObject *)> f) {
+ ValueObject *vo = this;
+ while (vo) {
+ if (f(vo) == false)
+ break;
+ vo = vo->m_parent;
+ }
+ return vo;
+}
+
+AddressType ValueObject::GetAddressTypeOfChildren() {
+ if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid) {
+ ValueObject *root(GetRoot());
if (root != this)
- return root->GetModule();
- return lldb::ModuleSP();
+ return root->GetAddressTypeOfChildren();
+ }
+ return m_address_type_of_ptr_or_ref_children;
}
-ValueObject*
-ValueObject::GetRoot ()
-{
- if (m_root)
- return m_root;
- return (m_root = FollowParentChain( [] (ValueObject* vo) -> bool {
- return (vo->m_parent != nullptr);
- }));
+lldb::DynamicValueType ValueObject::GetDynamicValueType() {
+ ValueObject *with_dv_info = this;
+ while (with_dv_info) {
+ if (with_dv_info->HasDynamicValueTypeInfo())
+ return with_dv_info->GetDynamicValueTypeImpl();
+ with_dv_info = with_dv_info->m_parent;
+ }
+ return lldb::eNoDynamicValues;
}
-ValueObject*
-ValueObject::FollowParentChain (std::function<bool(ValueObject*)> f)
-{
- ValueObject* vo = this;
- while (vo)
- {
- if (f(vo) == false)
- break;
- vo = vo->m_parent;
- }
- return vo;
+lldb::Format ValueObject::GetFormat() const {
+ const ValueObject *with_fmt_info = this;
+ while (with_fmt_info) {
+ if (with_fmt_info->m_format != lldb::eFormatDefault)
+ return with_fmt_info->m_format;
+ with_fmt_info = with_fmt_info->m_parent;
+ }
+ return m_format;
}
-AddressType
-ValueObject::GetAddressTypeOfChildren()
-{
- if (m_address_type_of_ptr_or_ref_children == eAddressTypeInvalid)
- {
- ValueObject* root(GetRoot());
- if (root != this)
- return root->GetAddressTypeOfChildren();
+lldb::LanguageType ValueObject::GetPreferredDisplayLanguage() {
+ lldb::LanguageType type = m_preferred_display_language;
+ if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
+ if (GetRoot()) {
+ if (GetRoot() == this) {
+ if (StackFrameSP frame_sp = GetFrameSP()) {
+ const SymbolContext &sc(
+ frame_sp->GetSymbolContext(eSymbolContextCompUnit));
+ if (CompileUnit *cu = sc.comp_unit)
+ type = cu->GetLanguage();
+ }
+ } else {
+ type = GetRoot()->GetPreferredDisplayLanguage();
+ }
}
- return m_address_type_of_ptr_or_ref_children;
+ }
+ return (m_preferred_display_language = type); // only compute it once
}
-lldb::DynamicValueType
-ValueObject::GetDynamicValueType ()
-{
- ValueObject* with_dv_info = this;
- while (with_dv_info)
- {
- if (with_dv_info->HasDynamicValueTypeInfo())
- return with_dv_info->GetDynamicValueTypeImpl();
- with_dv_info = with_dv_info->m_parent;
- }
- return lldb::eNoDynamicValues;
+void ValueObject::SetPreferredDisplayLanguage(lldb::LanguageType lt) {
+ m_preferred_display_language = lt;
}
-lldb::Format
-ValueObject::GetFormat () const
-{
- const ValueObject* with_fmt_info = this;
- while (with_fmt_info)
- {
- if (with_fmt_info->m_format != lldb::eFormatDefault)
- return with_fmt_info->m_format;
- with_fmt_info = with_fmt_info->m_parent;
- }
- return m_format;
+void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
+ if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
+ SetPreferredDisplayLanguage(lt);
}
-lldb::LanguageType
-ValueObject::GetPreferredDisplayLanguage ()
-{
- lldb::LanguageType type = m_preferred_display_language;
- if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
- {
- if (GetRoot())
- {
- if (GetRoot() == this)
- {
- if (StackFrameSP frame_sp = GetFrameSP())
- {
- const SymbolContext& sc(frame_sp->GetSymbolContext(eSymbolContextCompUnit));
- if (CompileUnit* cu = sc.comp_unit)
- type = cu->GetLanguage();
- }
- }
- else
- {
- type = GetRoot()->GetPreferredDisplayLanguage();
- }
- }
- }
- return (m_preferred_display_language = type); // only compute it once
+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 CompilerType &type(GetCompilerType());
+ return (false == type.IsValid()) ||
+ (0 != (type.GetTypeInfo() & eTypeHasValue));
}
-void
-ValueObject::SetPreferredDisplayLanguage (lldb::LanguageType lt)
-{
- m_preferred_display_language = lt;
-}
+bool ValueObject::IsChecksumEmpty() { return m_value_checksum.empty(); }
-void
-ValueObject::SetPreferredDisplayLanguageIfNeeded (lldb::LanguageType lt)
-{
- if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
- SetPreferredDisplayLanguage(lt);
-}
+ValueObjectSP ValueObject::Persist() {
+ if (!UpdateValueIfNeeded())
+ return nullptr;
-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 CompilerType &type(GetCompilerType());
- return (false == type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
-}
+ TargetSP target_sp(GetTargetSP());
+ if (!target_sp)
+ return nullptr;
+
+ PersistentExpressionState *persistent_state =
+ target_sp->GetPersistentExpressionStateForLanguage(
+ GetPreferredDisplayLanguage());
+
+ if (!persistent_state)
+ return nullptr;
-bool
-ValueObject::IsChecksumEmpty ()
-{
- return m_value_checksum.empty();
+ 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();
}
-ValueObjectSP
-ValueObject::Persist ()
-{
- if (!UpdateValueIfNeeded())
- return nullptr;
-
- TargetSP target_sp(GetTargetSP());
- if (!target_sp)
- return nullptr;
-
- PersistentExpressionState *persistent_state = target_sp->GetPersistentExpressionStateForLanguage(GetPreferredDisplayLanguage());
-
- 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();
+bool ValueObject::IsSyntheticChildrenGenerated() {
+ return m_is_synthetic_children_generated;
}
-bool
-ValueObject::IsSyntheticChildrenGenerated ()
-{
- return m_is_synthetic_children_generated;
+void ValueObject::SetSyntheticChildrenGenerated(bool b) {
+ m_is_synthetic_children_generated = b;
}
-void
-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; }
+
+ValueObjectManager::ValueObjectManager(lldb::ValueObjectSP in_valobj_sp,
+ lldb::DynamicValueType use_dynamic,
+ bool use_synthetic) : m_root_valobj_sp(),
+ m_user_valobj_sp(), m_use_dynamic(use_dynamic), m_stop_id(UINT32_MAX),
+ m_use_synthetic(use_synthetic) {
+ if (!in_valobj_sp)
+ return;
+ // If the user passes in a value object that is dynamic or synthetic, then
+ // water it down to the static type.
+ m_root_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(lldb::eNoDynamicValues, false);
}
-uint64_t
-ValueObject::GetLanguageFlags ()
-{
- return m_language_flags;
+bool ValueObjectManager::IsValid() const {
+ if (!m_root_valobj_sp)
+ return false;
+ lldb::TargetSP target_sp = GetTargetSP();
+ if (target_sp)
+ return target_sp->IsValid();
+ return false;
}
-void
-ValueObject::SetLanguageFlags (uint64_t flags)
-{
- m_language_flags = flags;
+lldb::ValueObjectSP ValueObjectManager::GetSP() {
+ lldb::ProcessSP process_sp = GetProcessSP();
+ if (!process_sp)
+ return lldb::ValueObjectSP();
+
+ const uint32_t current_stop_id = process_sp->GetLastNaturalStopID();
+ if (current_stop_id == m_stop_id)
+ return m_user_valobj_sp;
+
+ m_stop_id = current_stop_id;
+
+ if (!m_root_valobj_sp) {
+ m_user_valobj_sp.reset();
+ return m_root_valobj_sp;
+ }
+
+ m_user_valobj_sp = m_root_valobj_sp;
+
+ if (m_use_dynamic != lldb::eNoDynamicValues) {
+ lldb::ValueObjectSP dynamic_sp = m_user_valobj_sp->GetDynamicValue(m_use_dynamic);
+ if (dynamic_sp)
+ m_user_valobj_sp = dynamic_sp;
+ }
+
+ if (m_use_synthetic) {
+ lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(m_use_synthetic);
+ if (synthetic_sp)
+ m_user_valobj_sp = synthetic_sp;
+ }
+
+ return m_user_valobj_sp;
+}
+
+void ValueObjectManager::SetUseDynamic(lldb::DynamicValueType use_dynamic) {
+ if (use_dynamic != m_use_dynamic) {
+ m_use_dynamic = use_dynamic;
+ m_user_valobj_sp.reset();
+ m_stop_id = UINT32_MAX;
+ }
+}
+
+void ValueObjectManager::SetUseSynthetic(bool use_synthetic) {
+ if (m_use_synthetic != use_synthetic) {
+ m_use_synthetic = use_synthetic;
+ m_user_valobj_sp.reset();
+ m_stop_id = UINT32_MAX;
+ }
+}
+
+lldb::TargetSP ValueObjectManager::GetTargetSP() const {
+ if (!m_root_valobj_sp)
+ return m_root_valobj_sp->GetTargetSP();
+ return lldb::TargetSP();
+}
+
+lldb::ProcessSP ValueObjectManager::GetProcessSP() const {
+ if (m_root_valobj_sp)
+ return m_root_valobj_sp->GetProcessSP();
+ return lldb::ProcessSP();
+}
+
+lldb::ThreadSP ValueObjectManager::GetThreadSP() const {
+ if (m_root_valobj_sp)
+ return m_root_valobj_sp->GetThreadSP();
+ return lldb::ThreadSP();
+}
+
+lldb::StackFrameSP ValueObjectManager::GetFrameSP() const {
+ if (m_root_valobj_sp)
+ return m_root_valobj_sp->GetFrameSP();
+ return lldb::StackFrameSP();
}
+
diff --git a/source/Core/ValueObjectCast.cpp b/source/Core/ValueObjectCast.cpp
index 1c5838b820e1..300aeae3b33a 100644
--- a/source/Core/ValueObjectCast.cpp
+++ b/source/Core/ValueObjectCast.cpp
@@ -1,4 +1,4 @@
-//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
+//===-- ValueObjectCast.cpp -------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "lldb/Core/ValueObjectCast.h"
// C Includes
@@ -16,9 +15,9 @@
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectList.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -34,97 +33,72 @@
using namespace lldb_private;
-lldb::ValueObjectSP
-ValueObjectCast::Create (ValueObject &parent,
- const ConstString &name,
- const CompilerType &cast_type)
-{
- ValueObjectCast *cast_valobj_ptr = new ValueObjectCast (parent, name, cast_type);
- return cast_valobj_ptr->GetSP();
+lldb::ValueObjectSP ValueObjectCast::Create(ValueObject &parent,
+ const ConstString &name,
+ const CompilerType &cast_type) {
+ ValueObjectCast *cast_valobj_ptr =
+ new ValueObjectCast(parent, name, cast_type);
+ return cast_valobj_ptr->GetSP();
}
-ValueObjectCast::ValueObjectCast
-(
- ValueObject &parent,
- const ConstString &name,
- const CompilerType &cast_type
-) :
- ValueObject(parent),
- m_cast_type (cast_type)
-{
- SetName (name);
- //m_value.SetContext (Value::eContextTypeClangType, cast_type.GetOpaqueQualType());
- m_value.SetCompilerType (cast_type);
+ValueObjectCast::ValueObjectCast(ValueObject &parent, const ConstString &name,
+ const CompilerType &cast_type)
+ : ValueObject(parent), m_cast_type(cast_type) {
+ SetName(name);
+ // m_value.SetContext (Value::eContextTypeClangType,
+ // cast_type.GetOpaqueQualType());
+ m_value.SetCompilerType(cast_type);
}
-ValueObjectCast::~ValueObjectCast()
-{
-}
+ValueObjectCast::~ValueObjectCast() {}
-CompilerType
-ValueObjectCast::GetCompilerTypeImpl ()
-{
- return m_cast_type;
-}
+CompilerType ValueObjectCast::GetCompilerTypeImpl() { return m_cast_type; }
-size_t
-ValueObjectCast::CalculateNumChildren(uint32_t max)
-{
- auto children_count = GetCompilerType().GetNumChildren (true);
- return children_count <= max ? children_count : max;
+size_t ValueObjectCast::CalculateNumChildren(uint32_t max) {
+ auto children_count = GetCompilerType().GetNumChildren(true);
+ return children_count <= max ? children_count : max;
}
-uint64_t
-ValueObjectCast::GetByteSize()
-{
- ExecutionContext exe_ctx (GetExecutionContextRef());
- return m_value.GetValueByteSize(nullptr, &exe_ctx);
+uint64_t ValueObjectCast::GetByteSize() {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ return m_value.GetValueByteSize(nullptr, &exe_ctx);
}
-lldb::ValueType
-ValueObjectCast::GetValueType() const
-{
- // Let our parent answer global, local, argument, etc...
- return m_parent->GetValueType();
+lldb::ValueType ValueObjectCast::GetValueType() const {
+ // Let our parent answer global, local, argument, etc...
+ return m_parent->GetValueType();
}
-bool
-ValueObjectCast::UpdateValue ()
-{
- SetValueIsValid (false);
- m_error.Clear();
-
- if (m_parent->UpdateValueIfNeeded(false))
- {
- Value old_value(m_value);
- m_update_point.SetUpdated();
- m_value = m_parent->GetValue();
- CompilerType compiler_type (GetCompilerType());
- //m_value.SetContext (Value::eContextTypeClangType, compiler_type);
- m_value.SetCompilerType (compiler_type);
- SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
- if (!CanProvideValue())
- {
- // this value object represents an aggregate type whose
- // children have values, but this object does not. So we
- // say we are changed if our location has changed.
- SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
- }
- ExecutionContext exe_ctx (GetExecutionContextRef());
- m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
- SetValueDidChange (m_parent->GetValueDidChange());
- return true;
+bool ValueObjectCast::UpdateValue() {
+ SetValueIsValid(false);
+ m_error.Clear();
+
+ if (m_parent->UpdateValueIfNeeded(false)) {
+ Value old_value(m_value);
+ m_update_point.SetUpdated();
+ m_value = m_parent->GetValue();
+ CompilerType compiler_type(GetCompilerType());
+ // m_value.SetContext (Value::eContextTypeClangType, compiler_type);
+ m_value.SetCompilerType(compiler_type);
+ SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren());
+ if (!CanProvideValue()) {
+ // this value object represents an aggregate type whose
+ // children have values, but this object does not. So we
+ // say we are changed if our location has changed.
+ SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
+ m_value.GetScalar() != old_value.GetScalar());
}
-
- // The dynamic value failed to get an error, pass the error along
- if (m_error.Success() && m_parent->GetError().Fail())
- m_error = m_parent->GetError();
- SetValueIsValid (false);
- return false;
-}
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ SetValueDidChange(m_parent->GetValueDidChange());
+ return true;
+ }
-bool
-ValueObjectCast::IsInScope ()
-{
- return m_parent->IsInScope();
+ // The dynamic value failed to get an error, pass the error along
+ if (m_error.Success() && m_parent->GetError().Fail())
+ m_error = m_parent->GetError();
+ SetValueIsValid(false);
+ return false;
}
+
+bool ValueObjectCast::IsInScope() { return m_parent->IsInScope(); }
diff --git a/source/Core/ValueObjectChild.cpp b/source/Core/ValueObjectChild.cpp
index 6ecc749b8953..9b2bdd1e468c 100644
--- a/source/Core/ValueObjectChild.cpp
+++ b/source/Core/ValueObjectChild.cpp
@@ -24,254 +24,205 @@
using namespace lldb_private;
-ValueObjectChild::ValueObjectChild
-(
- ValueObject &parent,
- const CompilerType &compiler_type,
- const ConstString &name,
- uint64_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,
- AddressType child_ptr_or_ref_addr_type,
- uint64_t language_flags
-) :
- ValueObject (parent),
- 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_can_update_with_invalid_exe_ctx()
-{
- m_name = name;
- SetAddressTypeOfChildren(child_ptr_or_ref_addr_type);
- SetLanguageFlags(language_flags);
+ValueObjectChild::ValueObjectChild(
+ ValueObject &parent, const CompilerType &compiler_type,
+ const ConstString &name, uint64_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,
+ AddressType child_ptr_or_ref_addr_type, uint64_t language_flags)
+ : ValueObject(parent), 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_can_update_with_invalid_exe_ctx() {
+ m_name = name;
+ SetAddressTypeOfChildren(child_ptr_or_ref_addr_type);
+ SetLanguageFlags(language_flags);
}
-ValueObjectChild::~ValueObjectChild()
-{
-}
+ValueObjectChild::~ValueObjectChild() {}
-lldb::ValueType
-ValueObjectChild::GetValueType() const
-{
- return m_parent->GetValueType();
+lldb::ValueType ValueObjectChild::GetValueType() const {
+ return m_parent->GetValueType();
}
-size_t
-ValueObjectChild::CalculateNumChildren(uint32_t max)
-{
- auto children_count = GetCompilerType().GetNumChildren (true);
- return children_count <= max ? children_count : max;
+size_t ValueObjectChild::CalculateNumChildren(uint32_t max) {
+ auto children_count = GetCompilerType().GetNumChildren(true);
+ return children_count <= max ? children_count : max;
}
-static void
-AdjustForBitfieldness(ConstString& name,
- uint8_t bitfield_bit_size)
-{
- if (name && bitfield_bit_size)
- {
- const char *compiler_type_name = name.AsCString();
- if (compiler_type_name)
- {
- 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());
- }
+static void AdjustForBitfieldness(ConstString &name,
+ uint8_t bitfield_bit_size) {
+ if (name && bitfield_bit_size) {
+ const char *compiler_type_name = name.AsCString();
+ if (compiler_type_name) {
+ 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());
}
+ }
}
-ConstString
-ValueObjectChild::GetTypeName()
-{
- if (m_type_name.IsEmpty())
- {
- m_type_name = GetCompilerType().GetConstTypeName ();
- AdjustForBitfieldness(m_type_name, m_bitfield_bit_size);
- }
- return m_type_name;
+ConstString ValueObjectChild::GetTypeName() {
+ if (m_type_name.IsEmpty()) {
+ m_type_name = GetCompilerType().GetConstTypeName();
+ AdjustForBitfieldness(m_type_name, m_bitfield_bit_size);
+ }
+ return m_type_name;
}
-ConstString
-ValueObjectChild::GetQualifiedTypeName()
-{
- ConstString qualified_name = GetCompilerType().GetConstTypeName();
- AdjustForBitfieldness(qualified_name, m_bitfield_bit_size);
- return qualified_name;
+ConstString ValueObjectChild::GetQualifiedTypeName() {
+ ConstString qualified_name = GetCompilerType().GetConstTypeName();
+ AdjustForBitfieldness(qualified_name, m_bitfield_bit_size);
+ return qualified_name;
}
-ConstString
-ValueObjectChild::GetDisplayTypeName()
-{
- ConstString display_name = GetCompilerType().GetDisplayTypeName();
- AdjustForBitfieldness(display_name, m_bitfield_bit_size);
- return display_name;
+ConstString ValueObjectChild::GetDisplayTypeName() {
+ ConstString display_name = GetCompilerType().GetDisplayTypeName();
+ AdjustForBitfieldness(display_name, m_bitfield_bit_size);
+ return display_name;
}
-LazyBool
-ValueObjectChild::CanUpdateWithInvalidExecutionContext ()
-{
- if (m_can_update_with_invalid_exe_ctx.hasValue())
- return m_can_update_with_invalid_exe_ctx.getValue();
- if (m_parent)
- {
- ValueObject *opinionated_parent = m_parent->FollowParentChain([] (ValueObject* valobj) -> bool {
- return (valobj->CanUpdateWithInvalidExecutionContext() == eLazyBoolCalculate);
+LazyBool ValueObjectChild::CanUpdateWithInvalidExecutionContext() {
+ if (m_can_update_with_invalid_exe_ctx.hasValue())
+ return m_can_update_with_invalid_exe_ctx.getValue();
+ if (m_parent) {
+ 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();
+ 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
-ValueObjectChild::UpdateValue ()
-{
- m_error.Clear();
- SetValueIsValid (false);
- ValueObject* parent = m_parent;
- if (parent)
- {
- if (parent->UpdateValueIfNeeded(false))
- {
- 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->GetCompilerType().ShouldTreatScalarValueAsAddress())
- {
- lldb::addr_t addr = parent->GetPointerValue ();
- m_value.GetScalar() = addr;
-
- if (addr == LLDB_INVALID_ADDRESS)
- {
- m_error.SetErrorString ("parent address is invalid.");
- }
- else if (addr == 0)
- {
- m_error.SetErrorString ("parent is NULL");
- }
- else
- {
- m_value.GetScalar() += m_byte_offset;
- AddressType addr_type = parent->GetAddressTypeOfChildren();
-
- 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);
- }
- break;
- case eAddressTypeLoad:
- m_value.SetValueType (is_instance_ptr_base ? Value::eValueTypeScalar: Value::eValueTypeLoadAddress);
- break;
- case eAddressTypeHost:
- m_value.SetValueType(Value::eValueTypeHostAddress);
- break;
- case eAddressTypeInvalid:
- // TODO: does this make sense?
- m_value.SetValueType(Value::eValueTypeScalar);
- break;
- }
- }
- }
+bool ValueObjectChild::UpdateValue() {
+ m_error.Clear();
+ SetValueIsValid(false);
+ ValueObject *parent = m_parent;
+ if (parent) {
+ if (parent->UpdateValueIfNeeded(false)) {
+ 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->GetCompilerType().ShouldTreatScalarValueAsAddress()) {
+ lldb::addr_t addr = parent->GetPointerValue();
+ m_value.GetScalar() = addr;
+
+ if (addr == LLDB_INVALID_ADDRESS) {
+ m_error.SetErrorString("parent address is invalid.");
+ } else if (addr == 0) {
+ m_error.SetErrorString("parent is NULL");
+ } else {
+ m_value.GetScalar() += m_byte_offset;
+ AddressType addr_type = parent->GetAddressTypeOfChildren();
+
+ switch (addr_type) {
+ case eAddressTypeFile: {
+ lldb::ProcessSP process_sp(GetProcessSP());
+ if (process_sp && process_sp->IsAlive() == true)
+ m_value.SetValueType(Value::eValueTypeLoadAddress);
else
- {
- switch (value_type)
- {
- 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)
- {
- m_error.SetErrorString ("parent address is invalid.");
- }
- else if (addr == 0)
- {
- m_error.SetErrorString ("parent is NULL");
- }
- else
- {
- // Set this object's scalar value to the address of its
- // value by adding its byte offset to the parent address
- m_value.GetScalar() += GetByteOffset();
- }
- }
- 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 (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...
- }
- }
-
+ m_value.SetValueType(Value::eValueTypeFileAddress);
+ } break;
+ case eAddressTypeLoad:
+ m_value.SetValueType(is_instance_ptr_base
+ ? Value::eValueTypeScalar
+ : Value::eValueTypeLoadAddress);
+ break;
+ case eAddressTypeHost:
+ m_value.SetValueType(Value::eValueTypeHostAddress);
+ break;
+ case eAddressTypeInvalid:
+ // TODO: does this make sense?
+ m_value.SetValueType(Value::eValueTypeScalar);
+ break;
+ }
}
- else
- {
- m_error.SetErrorStringWithFormat("parent failed to evaluate: %s", parent->GetError().AsCString());
+ } else {
+ switch (value_type) {
+ 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) {
+ m_error.SetErrorString("parent address is invalid.");
+ } else if (addr == 0) {
+ m_error.SetErrorString("parent is NULL");
+ } else {
+ // Set this object's scalar value to the address of its
+ // value by adding its byte offset to the parent address
+ m_value.GetScalar() += GetByteOffset();
+ }
+ } 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 (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 {
+ m_error.SetErrorStringWithFormat("parent failed to evaluate: %s",
+ parent->GetError().AsCString());
}
- else
- {
- m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
- }
-
- return m_error.Success();
-}
+ } else {
+ m_error.SetErrorString("ValueObjectChild has a NULL parent ValueObject.");
+ }
+ return m_error.Success();
+}
-bool
-ValueObjectChild::IsInScope ()
-{
- ValueObject* root(GetRoot());
- if (root)
- return root->IsInScope ();
- return false;
+bool ValueObjectChild::IsInScope() {
+ ValueObject *root(GetRoot());
+ if (root)
+ return root->IsInScope();
+ return false;
}
diff --git a/source/Core/ValueObjectConstResult.cpp b/source/Core/ValueObjectConstResult.cpp
index 441cee540f7c..f78574ef7ee3 100644
--- a/source/Core/ValueObjectConstResult.cpp
+++ b/source/Core/ValueObjectConstResult.cpp
@@ -9,10 +9,10 @@
#include "lldb/Core/ValueObjectConstResult.h"
-#include "lldb/Core/ValueObjectChild.h"
-#include "lldb/Core/ValueObjectConstResultChild.h"
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/Module.h"
+#include "lldb/Core/ValueObjectChild.h"
+#include "lldb/Core/ValueObjectConstResultChild.h"
#include "lldb/Core/ValueObjectDynamicValue.h"
#include "lldb/Core/ValueObjectList.h"
@@ -29,356 +29,270 @@
using namespace lldb;
using namespace lldb_private;
-ValueObjectSP
-ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
- ByteOrder byte_order,
- uint32_t addr_byte_size,
- lldb::addr_t address)
-{
- return (new ValueObjectConstResult (exe_scope,
- byte_order,
- addr_byte_size,
- address))->GetSP();
+ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
+ ByteOrder byte_order,
+ uint32_t addr_byte_size,
+ lldb::addr_t address) {
+ return (new ValueObjectConstResult(exe_scope, byte_order, addr_byte_size,
+ address))
+ ->GetSP();
}
-ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
- ByteOrder byte_order,
- uint32_t addr_byte_size,
- lldb::addr_t address) :
- ValueObject (exe_scope),
- m_type_name (),
- m_byte_size (0),
- m_impl(this, address)
-{
- SetIsConstant ();
- SetValueIsValid(true);
- m_data.SetByteOrder(byte_order);
- m_data.SetAddressByteSize(addr_byte_size);
- SetAddressTypeOfChildren(eAddressTypeLoad);
+ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
+ ByteOrder byte_order,
+ uint32_t addr_byte_size,
+ lldb::addr_t address)
+ : ValueObject(exe_scope), m_type_name(), m_byte_size(0),
+ m_impl(this, address) {
+ SetIsConstant();
+ SetValueIsValid(true);
+ m_data.SetByteOrder(byte_order);
+ m_data.SetAddressByteSize(addr_byte_size);
+ SetAddressTypeOfChildren(eAddressTypeLoad);
}
-ValueObjectSP
-ValueObjectConstResult::Create
-(
- ExecutionContextScope *exe_scope,
- const CompilerType &compiler_type,
- const ConstString &name,
- const DataExtractor &data,
- lldb::addr_t address
-)
-{
- return (new ValueObjectConstResult (exe_scope,
- compiler_type,
- name,
- data,
- address))->GetSP();
+ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
+ const CompilerType &compiler_type,
+ const ConstString &name,
+ const DataExtractor &data,
+ lldb::addr_t address) {
+ return (new ValueObjectConstResult(exe_scope, compiler_type, name, data,
+ address))
+ ->GetSP();
}
-ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
- const CompilerType &compiler_type,
- const ConstString &name,
- const DataExtractor &data,
- lldb::addr_t address) :
- ValueObject (exe_scope),
- m_type_name (),
- m_byte_size (0),
- m_impl(this, address)
-{
- m_data = data;
-
- if (!m_data.GetSharedDataBuffer())
- {
- DataBufferSP shared_data_buffer(new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));
- m_data.SetData(shared_data_buffer);
- }
-
- m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
- m_value.SetValueType(Value::eValueTypeHostAddress);
- m_value.SetCompilerType(compiler_type);
- m_name = name;
- SetIsConstant ();
- SetValueIsValid(true);
- SetAddressTypeOfChildren(eAddressTypeLoad);
+ValueObjectConstResult::ValueObjectConstResult(
+ ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
+ const ConstString &name, const DataExtractor &data, lldb::addr_t address)
+ : ValueObject(exe_scope), m_type_name(), m_byte_size(0),
+ m_impl(this, address) {
+ m_data = data;
+
+ if (!m_data.GetSharedDataBuffer()) {
+ DataBufferSP shared_data_buffer(
+ new DataBufferHeap(data.GetDataStart(), data.GetByteSize()));
+ m_data.SetData(shared_data_buffer);
+ }
+
+ m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
+ m_value.SetValueType(Value::eValueTypeHostAddress);
+ m_value.SetCompilerType(compiler_type);
+ m_name = name;
+ SetIsConstant();
+ SetValueIsValid(true);
+ SetAddressTypeOfChildren(eAddressTypeLoad);
}
-ValueObjectSP
-ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
- const CompilerType &compiler_type,
- const ConstString &name,
- const lldb::DataBufferSP &data_sp,
- lldb::ByteOrder data_byte_order,
- uint32_t data_addr_size,
- lldb::addr_t address)
-{
- return (new ValueObjectConstResult (exe_scope,
- compiler_type,
- name,
- data_sp,
- data_byte_order,
- data_addr_size,
- address))->GetSP();
+ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
+ const CompilerType &compiler_type,
+ const ConstString &name,
+ const lldb::DataBufferSP &data_sp,
+ lldb::ByteOrder data_byte_order,
+ uint32_t data_addr_size,
+ lldb::addr_t address) {
+ return (new ValueObjectConstResult(exe_scope, compiler_type, name, data_sp,
+ data_byte_order, data_addr_size, address))
+ ->GetSP();
}
-ValueObjectSP
-ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
- Value &value,
- const ConstString &name,
- Module *module)
-{
- return (new ValueObjectConstResult (exe_scope, value, name, module))->GetSP();
+ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
+ Value &value,
+ const ConstString &name,
+ Module *module) {
+ return (new ValueObjectConstResult(exe_scope, value, name, module))->GetSP();
}
-ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
- const CompilerType &compiler_type,
- const ConstString &name,
- const lldb::DataBufferSP &data_sp,
- lldb::ByteOrder data_byte_order,
- uint32_t data_addr_size,
- lldb::addr_t address) :
- ValueObject (exe_scope),
- m_type_name (),
- m_byte_size (0),
- m_impl(this, address)
-{
- m_data.SetByteOrder(data_byte_order);
- m_data.SetAddressByteSize(data_addr_size);
- m_data.SetData(data_sp);
- m_value.GetScalar() = (uintptr_t)data_sp->GetBytes();
- m_value.SetValueType(Value::eValueTypeHostAddress);
- //m_value.SetContext(Value::eContextTypeClangType, compiler_type);
- m_value.SetCompilerType (compiler_type);
- m_name = name;
- SetIsConstant ();
- SetValueIsValid(true);
- SetAddressTypeOfChildren(eAddressTypeLoad);
+ValueObjectConstResult::ValueObjectConstResult(
+ ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
+ const ConstString &name, const lldb::DataBufferSP &data_sp,
+ lldb::ByteOrder data_byte_order, uint32_t data_addr_size,
+ lldb::addr_t address)
+ : ValueObject(exe_scope), m_type_name(), m_byte_size(0),
+ m_impl(this, address) {
+ m_data.SetByteOrder(data_byte_order);
+ m_data.SetAddressByteSize(data_addr_size);
+ m_data.SetData(data_sp);
+ m_value.GetScalar() = (uintptr_t)data_sp->GetBytes();
+ m_value.SetValueType(Value::eValueTypeHostAddress);
+ // m_value.SetContext(Value::eContextTypeClangType, compiler_type);
+ m_value.SetCompilerType(compiler_type);
+ m_name = name;
+ SetIsConstant();
+ SetValueIsValid(true);
+ SetAddressTypeOfChildren(eAddressTypeLoad);
}
-ValueObjectSP
-ValueObjectConstResult::Create (ExecutionContextScope *exe_scope,
- const CompilerType &compiler_type,
- const ConstString &name,
- lldb::addr_t address,
- AddressType address_type,
- uint32_t addr_byte_size)
-{
- return (new ValueObjectConstResult (exe_scope,
- compiler_type,
- name,
- address,
- address_type,
- addr_byte_size))->GetSP();
+ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
+ const CompilerType &compiler_type,
+ const ConstString &name,
+ lldb::addr_t address,
+ AddressType address_type,
+ uint32_t addr_byte_size) {
+ return (new ValueObjectConstResult(exe_scope, compiler_type, name, address,
+ address_type, addr_byte_size))
+ ->GetSP();
}
-ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
- const CompilerType &compiler_type,
- const ConstString &name,
- lldb::addr_t address,
- AddressType address_type,
- uint32_t addr_byte_size) :
- ValueObject (exe_scope),
- m_type_name (),
- m_byte_size (0),
- m_impl(this, address)
-{
- m_value.GetScalar() = address;
- m_data.SetAddressByteSize(addr_byte_size);
- m_value.GetScalar().GetData (m_data, addr_byte_size);
- //m_value.SetValueType(Value::eValueTypeHostAddress);
- switch (address_type)
- {
- case eAddressTypeInvalid: m_value.SetValueType(Value::eValueTypeScalar); break;
- case eAddressTypeFile: m_value.SetValueType(Value::eValueTypeFileAddress); break;
- case eAddressTypeLoad: m_value.SetValueType(Value::eValueTypeLoadAddress); break;
- case eAddressTypeHost: m_value.SetValueType(Value::eValueTypeHostAddress); break;
- }
-// m_value.SetContext(Value::eContextTypeClangType, compiler_type);
- m_value.SetCompilerType (compiler_type);
- m_name = name;
- SetIsConstant ();
- SetValueIsValid(true);
- SetAddressTypeOfChildren(eAddressTypeLoad);
+ValueObjectConstResult::ValueObjectConstResult(
+ ExecutionContextScope *exe_scope, const CompilerType &compiler_type,
+ const ConstString &name, lldb::addr_t address, AddressType address_type,
+ uint32_t addr_byte_size)
+ : ValueObject(exe_scope), m_type_name(), m_byte_size(0),
+ m_impl(this, address) {
+ m_value.GetScalar() = address;
+ m_data.SetAddressByteSize(addr_byte_size);
+ m_value.GetScalar().GetData(m_data, addr_byte_size);
+ // m_value.SetValueType(Value::eValueTypeHostAddress);
+ switch (address_type) {
+ case eAddressTypeInvalid:
+ m_value.SetValueType(Value::eValueTypeScalar);
+ break;
+ case eAddressTypeFile:
+ m_value.SetValueType(Value::eValueTypeFileAddress);
+ break;
+ case eAddressTypeLoad:
+ m_value.SetValueType(Value::eValueTypeLoadAddress);
+ break;
+ case eAddressTypeHost:
+ m_value.SetValueType(Value::eValueTypeHostAddress);
+ break;
+ }
+ // m_value.SetContext(Value::eContextTypeClangType, compiler_type);
+ m_value.SetCompilerType(compiler_type);
+ m_name = name;
+ SetIsConstant();
+ SetValueIsValid(true);
+ SetAddressTypeOfChildren(eAddressTypeLoad);
}
-ValueObjectSP
-ValueObjectConstResult::Create
-(
- ExecutionContextScope *exe_scope,
- const Error& error
-)
-{
- return (new ValueObjectConstResult (exe_scope,
- error))->GetSP();
+ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope,
+ const Error &error) {
+ return (new ValueObjectConstResult(exe_scope, error))->GetSP();
}
-ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
- const Error& error) :
- ValueObject (exe_scope),
- m_type_name (),
- m_byte_size (0),
- m_impl(this)
-{
- m_error = error;
- SetIsConstant ();
+ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
+ const Error &error)
+ : ValueObject(exe_scope), m_type_name(), m_byte_size(0), m_impl(this) {
+ m_error = error;
+ SetIsConstant();
}
-ValueObjectConstResult::ValueObjectConstResult (ExecutionContextScope *exe_scope,
- const Value &value,
- const ConstString &name,
- Module *module) :
- ValueObject (exe_scope),
- m_type_name (),
- m_byte_size (0),
- m_impl(this)
-{
- m_value = value;
- m_name = name;
- ExecutionContext exe_ctx;
- exe_scope->CalculateExecutionContext(exe_ctx);
- m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, module);
+ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope,
+ const Value &value,
+ const ConstString &name,
+ Module *module)
+ : ValueObject(exe_scope), m_type_name(), m_byte_size(0), m_impl(this) {
+ m_value = value;
+ m_name = name;
+ ExecutionContext exe_ctx;
+ exe_scope->CalculateExecutionContext(exe_ctx);
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, module);
}
-ValueObjectConstResult::~ValueObjectConstResult()
-{
-}
+ValueObjectConstResult::~ValueObjectConstResult() {}
-CompilerType
-ValueObjectConstResult::GetCompilerTypeImpl()
-{
- return m_value.GetCompilerType();
+CompilerType ValueObjectConstResult::GetCompilerTypeImpl() {
+ return m_value.GetCompilerType();
}
-lldb::ValueType
-ValueObjectConstResult::GetValueType() const
-{
- return eValueTypeConstResult;
+lldb::ValueType ValueObjectConstResult::GetValueType() const {
+ return eValueTypeConstResult;
}
-uint64_t
-ValueObjectConstResult::GetByteSize()
-{
- ExecutionContext exe_ctx(GetExecutionContextRef());
+uint64_t ValueObjectConstResult::GetByteSize() {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
- if (m_byte_size == 0)
- SetByteSize(GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()));
- return m_byte_size;
+ if (m_byte_size == 0)
+ SetByteSize(
+ GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()));
+ return m_byte_size;
}
-void
-ValueObjectConstResult::SetByteSize (size_t size)
-{
- m_byte_size = size;
-}
+void ValueObjectConstResult::SetByteSize(size_t size) { m_byte_size = size; }
-size_t
-ValueObjectConstResult::CalculateNumChildren(uint32_t max)
-{
- auto children_count = GetCompilerType().GetNumChildren (true);
- return children_count <= max ? children_count : max;
+size_t ValueObjectConstResult::CalculateNumChildren(uint32_t max) {
+ auto children_count = GetCompilerType().GetNumChildren(true);
+ return children_count <= max ? children_count : max;
}
-ConstString
-ValueObjectConstResult::GetTypeName()
-{
- if (m_type_name.IsEmpty())
- m_type_name = GetCompilerType().GetConstTypeName ();
- return m_type_name;
+ConstString ValueObjectConstResult::GetTypeName() {
+ if (m_type_name.IsEmpty())
+ m_type_name = GetCompilerType().GetConstTypeName();
+ return m_type_name;
}
-ConstString
-ValueObjectConstResult::GetDisplayTypeName()
-{
- return GetCompilerType().GetDisplayTypeName();
+ConstString ValueObjectConstResult::GetDisplayTypeName() {
+ return GetCompilerType().GetDisplayTypeName();
}
-bool
-ValueObjectConstResult::UpdateValue ()
-{
- // Const value is always valid
- SetValueIsValid (true);
- return true;
+bool ValueObjectConstResult::UpdateValue() {
+ // Const value is always valid
+ SetValueIsValid(true);
+ return true;
}
-
-bool
-ValueObjectConstResult::IsInScope ()
-{
- // A const result value is always in scope since it serializes all
- // information needed to contain the constant value.
- return true;
+bool ValueObjectConstResult::IsInScope() {
+ // A const result value is always in scope since it serializes all
+ // information needed to contain the constant value.
+ return true;
}
-lldb::ValueObjectSP
-ValueObjectConstResult::Dereference (Error &error)
-{
- return m_impl.Dereference(error);
+lldb::ValueObjectSP ValueObjectConstResult::Dereference(Error &error) {
+ return m_impl.Dereference(error);
}
-lldb::ValueObjectSP
-ValueObjectConstResult::GetSyntheticChildAtOffset(uint32_t offset,
- const CompilerType& type,
- bool can_create,
- ConstString name_const_str)
-{
- return m_impl.GetSyntheticChildAtOffset(offset, type, can_create, name_const_str);
+lldb::ValueObjectSP ValueObjectConstResult::GetSyntheticChildAtOffset(
+ uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str) {
+ return m_impl.GetSyntheticChildAtOffset(offset, type, can_create,
+ name_const_str);
}
-lldb::ValueObjectSP
-ValueObjectConstResult::AddressOf (Error &error)
-{
- return m_impl.AddressOf(error);
+lldb::ValueObjectSP ValueObjectConstResult::AddressOf(Error &error) {
+ return m_impl.AddressOf(error);
}
-lldb::addr_t
-ValueObjectConstResult::GetAddressOf (bool scalar_is_load_address,
- AddressType *address_type)
-{
- return m_impl.GetAddressOf(scalar_is_load_address, address_type);
+lldb::addr_t ValueObjectConstResult::GetAddressOf(bool scalar_is_load_address,
+ AddressType *address_type) {
+ return m_impl.GetAddressOf(scalar_is_load_address, address_type);
}
-ValueObject *
-ValueObjectConstResult::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
-{
- return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index);
+ValueObject *ValueObjectConstResult::CreateChildAtIndex(
+ size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
+ return m_impl.CreateChildAtIndex(idx, synthetic_array_member,
+ synthetic_index);
}
-size_t
-ValueObjectConstResult::GetPointeeData (DataExtractor& data,
- uint32_t item_idx,
- uint32_t item_count)
-{
- return m_impl.GetPointeeData(data, item_idx, item_count);
+size_t ValueObjectConstResult::GetPointeeData(DataExtractor &data,
+ uint32_t item_idx,
+ uint32_t item_count) {
+ return m_impl.GetPointeeData(data, item_idx, item_count);
}
lldb::ValueObjectSP
-ValueObjectConstResult::GetDynamicValue (lldb::DynamicValueType use_dynamic)
-{
- // Always recalculate dynamic values for const results as the memory that
- // they might point to might have changed at any time.
- if (use_dynamic != eNoDynamicValues)
- {
- if (!IsDynamic())
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Process *process = exe_ctx.GetProcessPtr();
- if (process && process->IsPossibleDynamicValue(*this))
- m_dynamic_value = new ValueObjectDynamicValue (*this, use_dynamic);
- }
- if (m_dynamic_value)
- return m_dynamic_value->GetSP();
+ValueObjectConstResult::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
+ // Always recalculate dynamic values for const results as the memory that
+ // they might point to might have changed at any time.
+ if (use_dynamic != eNoDynamicValues) {
+ if (!IsDynamic()) {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process && process->IsPossibleDynamicValue(*this))
+ m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic);
}
- return ValueObjectSP();
+ if (m_dynamic_value)
+ return m_dynamic_value->GetSP();
+ }
+ return ValueObjectSP();
}
lldb::ValueObjectSP
-ValueObjectConstResult::Cast (const CompilerType &compiler_type)
-{
- return m_impl.Cast(compiler_type);
+ValueObjectConstResult::Cast(const CompilerType &compiler_type) {
+ return m_impl.Cast(compiler_type);
}
-lldb::LanguageType
-ValueObjectConstResult::GetPreferredDisplayLanguage ()
-{
- if (m_preferred_display_language != lldb::eLanguageTypeUnknown)
- return m_preferred_display_language;
- return GetCompilerTypeImpl().GetMinimumLanguage();
+lldb::LanguageType ValueObjectConstResult::GetPreferredDisplayLanguage() {
+ 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
index 1611503c4bf1..32451468c183 100644
--- a/source/Core/ValueObjectConstResultCast.cpp
+++ b/source/Core/ValueObjectConstResultCast.cpp
@@ -17,60 +17,42 @@
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;
+ 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()
-{
-}
+ValueObjectConstResultCast::~ValueObjectConstResultCast() {}
-lldb::ValueObjectSP
-ValueObjectConstResultCast::Dereference (Error &error)
-{
- return m_impl.Dereference(error);
+lldb::ValueObjectSP ValueObjectConstResultCast::Dereference(Error &error) {
+ return m_impl.Dereference(error);
}
-lldb::ValueObjectSP
-ValueObjectConstResultCast::GetSyntheticChildAtOffset(uint32_t offset,
- const CompilerType& type,
- bool can_create,
- ConstString name_const_str)
-{
- return m_impl.GetSyntheticChildAtOffset(offset, type, can_create, name_const_str);
+lldb::ValueObjectSP ValueObjectConstResultCast::GetSyntheticChildAtOffset(
+ uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str) {
+ return m_impl.GetSyntheticChildAtOffset(offset, type, can_create,
+ name_const_str);
}
-lldb::ValueObjectSP
-ValueObjectConstResultCast::AddressOf (Error &error)
-{
- return m_impl.AddressOf(error);
+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);
+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);
+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);
+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 e3afa36351a8..c4c9c63c765d 100644
--- a/source/Core/ValueObjectConstResultChild.cpp
+++ b/source/Core/ValueObjectConstResultChild.cpp
@@ -1,4 +1,5 @@
-//===-- ValueObjectConstResultChild.cpp ------------------------------*- C++ -*-===//
+//===-- ValueObjectConstResultChild.cpp ------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,80 +17,49 @@
using namespace lldb_private;
-ValueObjectConstResultChild::ValueObjectConstResultChild
-(
- ValueObject &parent,
- 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,
- lldb::addr_t live_address,
- uint64_t language_flags
-) :
- ValueObjectChild (parent,
- compiler_type,
- name,
- byte_size,
- byte_offset,
- bitfield_bit_size,
- bitfield_bit_offset,
- is_base_class,
- is_deref_of_parent,
- eAddressTypeLoad,
- language_flags),
- m_impl(this, live_address)
-{
- m_name = name;
+ValueObjectConstResultChild::ValueObjectConstResultChild(
+ ValueObject &parent, 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, lldb::addr_t live_address,
+ uint64_t language_flags)
+ : ValueObjectChild(parent, compiler_type, name, byte_size, byte_offset,
+ bitfield_bit_size, bitfield_bit_offset, is_base_class,
+ is_deref_of_parent, eAddressTypeLoad, language_flags),
+ m_impl(this, live_address) {
+ m_name = name;
}
-ValueObjectConstResultChild::~ValueObjectConstResultChild()
-{
-}
+ValueObjectConstResultChild::~ValueObjectConstResultChild() {}
-lldb::ValueObjectSP
-ValueObjectConstResultChild::Dereference (Error &error)
-{
- return m_impl.Dereference(error);
+lldb::ValueObjectSP ValueObjectConstResultChild::Dereference(Error &error) {
+ return m_impl.Dereference(error);
}
-lldb::ValueObjectSP
-ValueObjectConstResultChild::GetSyntheticChildAtOffset(uint32_t offset,
- const CompilerType& type,
- bool can_create,
- ConstString name_const_str)
-{
- return m_impl.GetSyntheticChildAtOffset(offset,
- type,
- can_create,
- name_const_str);
+lldb::ValueObjectSP ValueObjectConstResultChild::GetSyntheticChildAtOffset(
+ uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str) {
+ return m_impl.GetSyntheticChildAtOffset(offset, type, can_create,
+ name_const_str);
}
-lldb::ValueObjectSP
-ValueObjectConstResultChild::AddressOf (Error &error)
-{
- return m_impl.AddressOf(error);
+lldb::ValueObjectSP ValueObjectConstResultChild::AddressOf(Error &error) {
+ return m_impl.AddressOf(error);
}
-ValueObject *
-ValueObjectConstResultChild::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
-{
- return m_impl.CreateChildAtIndex(idx, synthetic_array_member, synthetic_index);
+ValueObject *ValueObjectConstResultChild::CreateChildAtIndex(
+ size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
+ return m_impl.CreateChildAtIndex(idx, synthetic_array_member,
+ synthetic_index);
}
-size_t
-ValueObjectConstResultChild::GetPointeeData (DataExtractor& data,
- uint32_t item_idx,
- uint32_t item_count)
-{
- return m_impl.GetPointeeData(data, item_idx, item_count);
+size_t ValueObjectConstResultChild::GetPointeeData(DataExtractor &data,
+ uint32_t item_idx,
+ uint32_t item_count) {
+ return m_impl.GetPointeeData(data, item_idx, item_count);
}
lldb::ValueObjectSP
-ValueObjectConstResultChild::Cast (const CompilerType &compiler_type)
-{
- return m_impl.Cast(compiler_type);
+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 6db7f184da8f..0e4f73f13b52 100644
--- a/source/Core/ValueObjectConstResultImpl.cpp
+++ b/source/Core/ValueObjectConstResultImpl.cpp
@@ -1,4 +1,5 @@
-//===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++ -*-===//
+//===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,14 +10,14 @@
#include "lldb/Core/ValueObjectConstResultImpl.h"
+#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Module.h"
#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/Core/ValueObjectMemory.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -31,176 +32,143 @@
using namespace lldb;
using namespace lldb_private;
-ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
- lldb::addr_t live_address) :
- m_impl_backend(valobj),
- m_live_address(live_address),
- m_live_address_type(eAddressTypeLoad),
- m_load_addr_backend(),
- m_address_of_backend()
-{
-}
+ValueObjectConstResultImpl::ValueObjectConstResultImpl(
+ ValueObject *valobj, lldb::addr_t live_address)
+ : m_impl_backend(valobj), m_live_address(live_address),
+ m_live_address_type(eAddressTypeLoad), m_load_addr_backend(),
+ m_address_of_backend() {}
-lldb::ValueObjectSP
-ValueObjectConstResultImpl::Dereference (Error &error)
-{
- if (m_impl_backend == NULL)
- return lldb::ValueObjectSP();
-
- return m_impl_backend->ValueObject::Dereference(error);
+lldb::ValueObjectSP ValueObjectConstResultImpl::Dereference(Error &error) {
+ if (m_impl_backend == NULL)
+ return lldb::ValueObjectSP();
+
+ return m_impl_backend->ValueObject::Dereference(error);
}
-ValueObject *
-ValueObjectConstResultImpl::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
-{
- if (m_impl_backend == NULL)
- return NULL;
-
- m_impl_backend->UpdateValueIfNeeded(false);
-
- ValueObjectConstResultChild *valobj = NULL;
-
- bool omit_empty_base_classes = true;
- bool ignore_array_bounds = synthetic_array_member;
- std::string child_name_str;
- uint32_t child_byte_size = 0;
- int32_t child_byte_offset = 0;
- uint32_t child_bitfield_bit_size = 0;
- 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;
- CompilerType compiler_type = m_impl_backend->GetCompilerType();
- CompilerType child_compiler_type;
-
- ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
-
- 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;
-
- ConstString child_name;
- if (!child_name_str.empty())
- child_name.SetCString (child_name_str.c_str());
-
- valobj = new ValueObjectConstResultChild (*m_impl_backend,
- 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,
- m_live_address == LLDB_INVALID_ADDRESS ? m_live_address : m_live_address+child_byte_offset,
- language_flags);
- }
-
- return valobj;
+ValueObject *ValueObjectConstResultImpl::CreateChildAtIndex(
+ size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
+ if (m_impl_backend == NULL)
+ return NULL;
+
+ m_impl_backend->UpdateValueIfNeeded(false);
+
+ ValueObjectConstResultChild *valobj = NULL;
+
+ bool omit_empty_base_classes = true;
+ bool ignore_array_bounds = synthetic_array_member;
+ std::string child_name_str;
+ uint32_t child_byte_size = 0;
+ int32_t child_byte_offset = 0;
+ uint32_t child_bitfield_bit_size = 0;
+ 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;
+ CompilerType compiler_type = m_impl_backend->GetCompilerType();
+ CompilerType child_compiler_type;
+
+ ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());
+
+ 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;
+
+ ConstString child_name;
+ if (!child_name_str.empty())
+ child_name.SetCString(child_name_str.c_str());
+
+ valobj = new ValueObjectConstResultChild(
+ *m_impl_backend, 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,
+ 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 CompilerType& type,
- bool can_create,
- ConstString name_const_str)
-{
- if (m_impl_backend == NULL)
- return lldb::ValueObjectSP();
-
- return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(offset,
- type,
- can_create,
- name_const_str);
+lldb::ValueObjectSP ValueObjectConstResultImpl::GetSyntheticChildAtOffset(
+ uint32_t offset, const CompilerType &type, bool can_create,
+ ConstString name_const_str) {
+ if (m_impl_backend == NULL)
+ return lldb::ValueObjectSP();
+
+ return m_impl_backend->ValueObject::GetSyntheticChildAtOffset(
+ offset, type, can_create, name_const_str);
}
-lldb::ValueObjectSP
-ValueObjectConstResultImpl::AddressOf (Error &error)
-{
- if (m_address_of_backend.get() != NULL)
- return m_address_of_backend;
-
- if (m_impl_backend == NULL)
- return lldb::ValueObjectSP();
- if (m_live_address != LLDB_INVALID_ADDRESS)
- {
- CompilerType compiler_type(m_impl_backend->GetCompilerType());
-
- lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(&m_live_address,sizeof(lldb::addr_t)));
-
- std::string new_name("&");
- new_name.append(m_impl_backend->GetName().AsCString(""));
- ExecutionContext exe_ctx (m_impl_backend->GetExecutionContextRef());
- m_address_of_backend = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- compiler_type.GetPointerType(),
- ConstString(new_name.c_str()),
- buffer,
- endian::InlHostByteOrder(),
- exe_ctx.GetAddressByteSize());
-
- m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
- m_address_of_backend->GetValue().GetScalar() = m_live_address;
-
- return m_address_of_backend;
- }
- else
- return m_impl_backend->ValueObject::AddressOf(error);
+lldb::ValueObjectSP ValueObjectConstResultImpl::AddressOf(Error &error) {
+ if (m_address_of_backend.get() != NULL)
+ return m_address_of_backend;
+
+ if (m_impl_backend == NULL)
+ return lldb::ValueObjectSP();
+ if (m_live_address != LLDB_INVALID_ADDRESS) {
+ CompilerType compiler_type(m_impl_backend->GetCompilerType());
+
+ lldb::DataBufferSP buffer(new lldb_private::DataBufferHeap(
+ &m_live_address, sizeof(lldb::addr_t)));
+
+ std::string new_name("&");
+ new_name.append(m_impl_backend->GetName().AsCString(""));
+ ExecutionContext exe_ctx(m_impl_backend->GetExecutionContextRef());
+ m_address_of_backend = ValueObjectConstResult::Create(
+ exe_ctx.GetBestExecutionContextScope(), compiler_type.GetPointerType(),
+ ConstString(new_name.c_str()), buffer, endian::InlHostByteOrder(),
+ exe_ctx.GetAddressByteSize());
+
+ m_address_of_backend->GetValue().SetValueType(Value::eValueTypeScalar);
+ m_address_of_backend->GetValue().GetScalar() = m_live_address;
+
+ return m_address_of_backend;
+ } else
+ 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();
+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)
-{
-
- if (m_impl_backend == NULL)
- return 0;
-
- if (m_live_address == LLDB_INVALID_ADDRESS)
- {
- return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
- address_type);
- }
-
- if (address_type)
- *address_type = m_live_address_type;
-
- return m_live_address;
+ValueObjectConstResultImpl::GetAddressOf(bool scalar_is_load_address,
+ AddressType *address_type) {
+
+ if (m_impl_backend == NULL)
+ return 0;
+
+ if (m_live_address == LLDB_INVALID_ADDRESS) {
+ return m_impl_backend->ValueObject::GetAddressOf(scalar_is_load_address,
+ address_type);
+ }
+
+ if (address_type)
+ *address_type = m_live_address_type;
+
+ return m_live_address;
}
-size_t
-ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
- uint32_t item_idx,
- uint32_t item_count)
-{
- if (m_impl_backend == NULL)
- return 0;
- return m_impl_backend->ValueObject::GetPointeeData(data, item_idx, item_count);
+size_t ValueObjectConstResultImpl::GetPointeeData(DataExtractor &data,
+ uint32_t item_idx,
+ uint32_t item_count) {
+ if (m_impl_backend == NULL)
+ return 0;
+ return m_impl_backend->ValueObject::GetPointeeData(data, item_idx,
+ item_count);
}
diff --git a/source/Core/ValueObjectDynamicValue.cpp b/source/Core/ValueObjectDynamicValue.cpp
index 65deba096d82..1fb32d4e86a3 100644
--- a/source/Core/ValueObjectDynamicValue.cpp
+++ b/source/Core/ValueObjectDynamicValue.cpp
@@ -1,4 +1,5 @@
-//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
+//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +8,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "lldb/Core/ValueObjectDynamicValue.h"
// C Includes
@@ -16,9 +16,9 @@
// Project includes
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
-#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectList.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -35,427 +35,365 @@
using namespace lldb_private;
-ValueObjectDynamicValue::ValueObjectDynamicValue (ValueObject &parent, lldb::DynamicValueType use_dynamic) :
- ValueObject(parent),
- m_address (),
- m_dynamic_type_info(),
- m_use_dynamic (use_dynamic)
-{
- SetName (parent.GetName());
+ValueObjectDynamicValue::ValueObjectDynamicValue(
+ ValueObject &parent, lldb::DynamicValueType use_dynamic)
+ : ValueObject(parent), m_address(), m_dynamic_type_info(),
+ m_use_dynamic(use_dynamic) {
+ SetName(parent.GetName());
}
-ValueObjectDynamicValue::~ValueObjectDynamicValue()
-{
- m_owning_valobj_sp.reset();
+ValueObjectDynamicValue::~ValueObjectDynamicValue() {
+ m_owning_valobj_sp.reset();
}
-CompilerType
-ValueObjectDynamicValue::GetCompilerTypeImpl ()
-{
- const bool success = UpdateValueIfNeeded(false);
- if (success)
- {
- if (m_dynamic_type_info.HasType())
- return m_value.GetCompilerType();
- else
- return m_parent->GetCompilerType();
- }
- return m_parent->GetCompilerType();
+CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success) {
+ if (m_dynamic_type_info.HasType())
+ return m_value.GetCompilerType();
+ else
+ return m_parent->GetCompilerType();
+ }
+ return m_parent->GetCompilerType();
}
-ConstString
-ValueObjectDynamicValue::GetTypeName()
-{
- const bool success = UpdateValueIfNeeded(false);
- if (success)
- {
- if (m_dynamic_type_info.HasName())
- return m_dynamic_type_info.GetName();
- }
- return m_parent->GetTypeName();
+ConstString ValueObjectDynamicValue::GetTypeName() {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success) {
+ if (m_dynamic_type_info.HasName())
+ return m_dynamic_type_info.GetName();
+ }
+ return m_parent->GetTypeName();
}
-TypeImpl
-ValueObjectDynamicValue::GetTypeImpl ()
-{
- const bool success = UpdateValueIfNeeded(false);
- if (success && m_type_impl.IsValid())
- {
- return m_type_impl;
- }
- return m_parent->GetTypeImpl();
+TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success && m_type_impl.IsValid()) {
+ return m_type_impl;
+ }
+ return m_parent->GetTypeImpl();
}
-ConstString
-ValueObjectDynamicValue::GetQualifiedTypeName()
-{
- const bool success = UpdateValueIfNeeded(false);
- if (success)
- {
- if (m_dynamic_type_info.HasName())
- return m_dynamic_type_info.GetName();
- }
- return m_parent->GetQualifiedTypeName();
+ConstString ValueObjectDynamicValue::GetQualifiedTypeName() {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success) {
+ if (m_dynamic_type_info.HasName())
+ return m_dynamic_type_info.GetName();
+ }
+ return m_parent->GetQualifiedTypeName();
}
-ConstString
-ValueObjectDynamicValue::GetDisplayTypeName()
-{
- const bool success = UpdateValueIfNeeded(false);
- if (success)
- {
- if (m_dynamic_type_info.HasType())
- return GetCompilerType().GetDisplayTypeName();
- if (m_dynamic_type_info.HasName())
- return m_dynamic_type_info.GetName();
- }
- return m_parent->GetDisplayTypeName();
+ConstString ValueObjectDynamicValue::GetDisplayTypeName() {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success) {
+ if (m_dynamic_type_info.HasType())
+ return GetCompilerType().GetDisplayTypeName();
+ if (m_dynamic_type_info.HasName())
+ return m_dynamic_type_info.GetName();
+ }
+ return m_parent->GetDisplayTypeName();
}
-size_t
-ValueObjectDynamicValue::CalculateNumChildren(uint32_t max)
-{
- const bool success = UpdateValueIfNeeded(false);
- if (success && m_dynamic_type_info.HasType())
- {
- auto children_count = GetCompilerType().GetNumChildren (true);
- return children_count <= max ? children_count : max;
- }
- else
- return m_parent->GetNumChildren(max);
+size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success && m_dynamic_type_info.HasType()) {
+ auto children_count = GetCompilerType().GetNumChildren(true);
+ return children_count <= max ? children_count : max;
+ } else
+ return m_parent->GetNumChildren(max);
}
-uint64_t
-ValueObjectDynamicValue::GetByteSize()
-{
- const bool success = UpdateValueIfNeeded(false);
- if (success && m_dynamic_type_info.HasType())
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
- return m_value.GetValueByteSize(nullptr, &exe_ctx);
- }
- else
- return m_parent->GetByteSize();
+uint64_t ValueObjectDynamicValue::GetByteSize() {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success && m_dynamic_type_info.HasType()) {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ return m_value.GetValueByteSize(nullptr, &exe_ctx);
+ } else
+ return m_parent->GetByteSize();
}
-lldb::ValueType
-ValueObjectDynamicValue::GetValueType() const
-{
- return m_parent->GetValueType();
+lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
+ return m_parent->GetValueType();
}
-bool
-ValueObjectDynamicValue::UpdateValue ()
-{
- SetValueIsValid (false);
- m_error.Clear();
-
- if (!m_parent->UpdateValueIfNeeded(false))
- {
- // The dynamic value failed to get an error, pass the error along
- if (m_error.Success() && m_parent->GetError().Fail())
- m_error = m_parent->GetError();
- return false;
- }
+bool ValueObjectDynamicValue::UpdateValue() {
+ SetValueIsValid(false);
+ m_error.Clear();
- // Setting our type_sp to NULL will route everything back through our
- // parent which is equivalent to not using dynamic values.
- if (m_use_dynamic == lldb::eNoDynamicValues)
- {
- m_dynamic_type_info.Clear();
- return true;
- }
+ if (!m_parent->UpdateValueIfNeeded(false)) {
+ // The dynamic value failed to get an error, pass the error along
+ if (m_error.Success() && m_parent->GetError().Fail())
+ m_error = m_parent->GetError();
+ return false;
+ }
+
+ // Setting our type_sp to NULL will route everything back through our
+ // parent which is equivalent to not using dynamic values.
+ if (m_use_dynamic == lldb::eNoDynamicValues) {
+ m_dynamic_type_info.Clear();
+ return true;
+ }
+
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ }
+
+ // First make sure our Type and/or Address haven't changed:
+ Process *process = exe_ctx.GetProcessPtr();
+ if (!process)
+ return false;
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
- }
+ TypeAndOrName class_type_or_name;
+ Address dynamic_address;
+ bool found_dynamic_type = false;
+ Value::ValueType value_type;
- // First make sure our Type and/or Address haven't changed:
- Process *process = exe_ctx.GetProcessPtr();
- if (!process)
- return false;
-
- 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)
- {
- runtime = process->GetLanguageRuntime (known_type);
- if (runtime)
- found_dynamic_type = runtime->GetDynamicTypeAndAddress (*m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type);
- }
- else
- {
- 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)
- {
- 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);
- }
- }
+ LanguageRuntime *runtime = nullptr;
- // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
- // don't...
-
- m_update_point.SetUpdated();
-
- if (runtime && found_dynamic_type)
- {
- if (class_type_or_name.HasType())
- {
- m_type_impl = TypeImpl(m_parent->GetCompilerType(),
- runtime->FixUpDynamicType(class_type_or_name, *m_parent).GetCompilerType());
- }
- else
- {
- m_type_impl.Clear();
- }
+ lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
+ if (known_type != lldb::eLanguageTypeUnknown &&
+ known_type != lldb::eLanguageTypeC) {
+ runtime = process->GetLanguageRuntime(known_type);
+ if (runtime)
+ found_dynamic_type = runtime->GetDynamicTypeAndAddress(
+ *m_parent, m_use_dynamic, class_type_or_name, dynamic_address,
+ value_type);
+ } else {
+ 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) {
+ 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);
}
- else
- {
- m_type_impl.Clear();
+ }
+
+ // Getting the dynamic value may have run the program a bit, and so marked us
+ // as needing updating, but we really
+ // don't...
+
+ m_update_point.SetUpdated();
+
+ if (runtime && found_dynamic_type) {
+ if (class_type_or_name.HasType()) {
+ m_type_impl =
+ TypeImpl(m_parent->GetCompilerType(),
+ runtime->FixUpDynamicType(class_type_or_name, *m_parent)
+ .GetCompilerType());
+ } else {
+ m_type_impl.Clear();
}
-
- // If we don't have a dynamic type, then make ourselves just a echo of our parent.
- // Or we could return false, and make ourselves an echo of our parent?
- if (!found_dynamic_type)
- {
- if (m_dynamic_type_info)
- SetValueDidChange(true);
- ClearDynamicTypeInformation();
- m_dynamic_type_info.Clear();
- m_value = m_parent->GetValue();
- m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
- return m_error.Success();
+ } else {
+ m_type_impl.Clear();
+ }
+
+ // If we don't have a dynamic type, then make ourselves just a echo of our
+ // parent.
+ // Or we could return false, and make ourselves an echo of our parent?
+ if (!found_dynamic_type) {
+ if (m_dynamic_type_info)
+ SetValueDidChange(true);
+ ClearDynamicTypeInformation();
+ m_dynamic_type_info.Clear();
+ m_value = m_parent->GetValue();
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ return m_error.Success();
+ }
+
+ Value old_value(m_value);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TYPES));
+
+ bool has_changed_type = false;
+
+ if (!m_dynamic_type_info) {
+ m_dynamic_type_info = class_type_or_name;
+ has_changed_type = true;
+ } else if (class_type_or_name != m_dynamic_type_info) {
+ // We are another type, we need to tear down our children...
+ m_dynamic_type_info = class_type_or_name;
+ SetValueDidChange(true);
+ has_changed_type = true;
+ }
+
+ if (has_changed_type)
+ ClearDynamicTypeInformation();
+
+ if (!m_address.IsValid() || m_address != dynamic_address) {
+ if (m_address.IsValid())
+ SetValueDidChange(true);
+
+ // We've moved, so we should be fine...
+ m_address = dynamic_address;
+ lldb::TargetSP target_sp(GetTargetSP());
+ lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
+ m_value.GetScalar() = load_address;
+ }
+
+ if (runtime)
+ m_dynamic_type_info =
+ runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
+
+ // m_value.SetContext (Value::eContextTypeClangType, corrected_type);
+ m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType());
+
+ m_value.SetValueType(value_type);
+
+ if (has_changed_type && log)
+ log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
+ static_cast<void *>(this), GetTypeName().GetCString());
+
+ if (m_address.IsValid() && m_dynamic_type_info) {
+ // The variable value is in the Scalar value inside the m_value.
+ // We can point our m_data right to it.
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ if (m_error.Success()) {
+ if (!CanProvideValue()) {
+ // this value object represents an aggregate type whose
+ // children have values, but this object does not. So we
+ // say we are changed if our location has changed.
+ SetValueDidChange(m_value.GetValueType() != old_value.GetValueType() ||
+ m_value.GetScalar() != old_value.GetScalar());
+ }
+
+ SetValueIsValid(true);
+ return true;
}
+ }
- Value old_value(m_value);
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_TYPES));
-
- bool has_changed_type = false;
-
- if (!m_dynamic_type_info)
- {
- m_dynamic_type_info = class_type_or_name;
- has_changed_type = true;
- }
- else if (class_type_or_name != m_dynamic_type_info)
- {
- // We are another type, we need to tear down our children...
- m_dynamic_type_info = class_type_or_name;
- SetValueDidChange (true);
- has_changed_type = true;
- }
+ // We get here if we've failed above...
+ SetValueIsValid(false);
+ return false;
+}
- if (has_changed_type)
- ClearDynamicTypeInformation ();
+bool ValueObjectDynamicValue::IsInScope() { return m_parent->IsInScope(); }
- if (!m_address.IsValid() || m_address != dynamic_address)
- {
- if (m_address.IsValid())
- SetValueDidChange (true);
+bool ValueObjectDynamicValue::SetValueFromCString(const char *value_str,
+ Error &error) {
+ if (!UpdateValueIfNeeded(false)) {
+ error.SetErrorString("unable to read value");
+ return false;
+ }
- // We've moved, so we should be fine...
- m_address = dynamic_address;
- lldb::TargetSP target_sp (GetTargetSP());
- lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
- m_value.GetScalar() = load_address;
- }
+ uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
+ uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
- if (runtime)
- m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
-
- //m_value.SetContext (Value::eContextTypeClangType, corrected_type);
- m_value.SetCompilerType (m_dynamic_type_info.GetCompilerType());
-
- m_value.SetValueType(value_type);
-
- if (has_changed_type && log)
- log->Printf("[%s %p] has a new dynamic type %s", GetName().GetCString(),
- static_cast<void*>(this), GetTypeName().GetCString());
-
- if (m_address.IsValid() && m_dynamic_type_info)
- {
- // The variable value is in the Scalar value inside the m_value.
- // We can point our m_data right to it.
- m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
- if (m_error.Success())
- {
- if (!CanProvideValue())
- {
- // this value object represents an aggregate type whose
- // children have values, but this object does not. So we
- // say we are changed if our location has changed.
- SetValueDidChange (m_value.GetValueType() != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
- }
-
- SetValueIsValid (true);
- return true;
- }
+ if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
+ error.SetErrorString("unable to read value");
+ return false;
+ }
+
+ // if we are at an offset from our parent, in order to set ourselves correctly
+ // we would need
+ // to change the new value so that it refers to the correct dynamic type. we
+ // choose not to deal
+ // with that - if anything more than a value overwrite is required, you should
+ // be using the
+ // expression parser instead of the value editing facility
+ if (my_value != parent_value) {
+ // but NULL'ing out a value should always be allowed
+ if (strcmp(value_str, "0")) {
+ error.SetErrorString(
+ "unable to modify dynamic value, use 'expression' command");
+ return false;
}
+ }
- // We get here if we've failed above...
- SetValueIsValid (false);
- return false;
+ bool ret_val = m_parent->SetValueFromCString(value_str, error);
+ SetNeedsUpdate();
+ return ret_val;
}
+bool ValueObjectDynamicValue::SetData(DataExtractor &data, Error &error) {
+ if (!UpdateValueIfNeeded(false)) {
+ error.SetErrorString("unable to read value");
+ return false;
+ }
+ uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
+ uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
-bool
-ValueObjectDynamicValue::IsInScope ()
-{
- return m_parent->IsInScope();
-}
-
-bool
-ValueObjectDynamicValue::SetValueFromCString (const char *value_str, Error& error)
-{
- if (!UpdateValueIfNeeded(false))
- {
- error.SetErrorString("unable to read value");
- return false;
- }
-
- uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
- uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
-
- if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
- {
- error.SetErrorString("unable to read value");
- return false;
- }
-
- // if we are at an offset from our parent, in order to set ourselves correctly we would need
- // to change the new value so that it refers to the correct dynamic type. we choose not to deal
- // with that - if anything more than a value overwrite is required, you should be using the
- // expression parser instead of the value editing facility
- if (my_value != parent_value)
- {
- // but NULL'ing out a value should always be allowed
- if (strcmp(value_str,"0"))
- {
- error.SetErrorString("unable to modify dynamic value, use 'expression' command");
- return false;
- }
+ if (my_value == UINT64_MAX || parent_value == UINT64_MAX) {
+ error.SetErrorString("unable to read value");
+ return false;
+ }
+
+ // if we are at an offset from our parent, in order to set ourselves correctly
+ // we would need
+ // to change the new value so that it refers to the correct dynamic type. we
+ // choose not to deal
+ // with that - if anything more than a value overwrite is required, you should
+ // be using the
+ // expression parser instead of the value editing facility
+ if (my_value != parent_value) {
+ // but NULL'ing out a value should always be allowed
+ lldb::offset_t offset = 0;
+
+ if (data.GetPointer(&offset) != 0) {
+ error.SetErrorString(
+ "unable to modify dynamic value, use 'expression' command");
+ return false;
}
-
- bool ret_val = m_parent->SetValueFromCString(value_str,error);
- SetNeedsUpdate();
- return ret_val;
-}
+ }
-bool
-ValueObjectDynamicValue::SetData (DataExtractor &data, Error &error)
-{
- if (!UpdateValueIfNeeded(false))
- {
- error.SetErrorString("unable to read value");
- return false;
- }
-
- uint64_t my_value = GetValueAsUnsigned(UINT64_MAX);
- uint64_t parent_value = m_parent->GetValueAsUnsigned(UINT64_MAX);
-
- if (my_value == UINT64_MAX || parent_value == UINT64_MAX)
- {
- error.SetErrorString("unable to read value");
- return false;
- }
-
- // if we are at an offset from our parent, in order to set ourselves correctly we would need
- // to change the new value so that it refers to the correct dynamic type. we choose not to deal
- // with that - if anything more than a value overwrite is required, you should be using the
- // expression parser instead of the value editing facility
- if (my_value != parent_value)
- {
- // but NULL'ing out a value should always be allowed
- lldb::offset_t offset = 0;
-
- if (data.GetPointer(&offset) != 0)
- {
- error.SetErrorString("unable to modify dynamic value, use 'expression' command");
- return false;
- }
- }
-
- bool ret_val = m_parent->SetData(data, error);
- SetNeedsUpdate();
- return ret_val;
+ bool ret_val = m_parent->SetData(data, error);
+ SetNeedsUpdate();
+ return ret_val;
}
-void
-ValueObjectDynamicValue::SetPreferredDisplayLanguage (lldb::LanguageType lang)
-{
- this->ValueObject::SetPreferredDisplayLanguage(lang);
- if (m_parent)
- m_parent->SetPreferredDisplayLanguage(lang);
+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;
+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::IsSyntheticChildrenGenerated ()
-{
- if (m_parent)
- return m_parent->IsSyntheticChildrenGenerated();
- return false;
+bool ValueObjectDynamicValue::IsSyntheticChildrenGenerated() {
+ if (m_parent)
+ return m_parent->IsSyntheticChildrenGenerated();
+ return false;
}
-void
-ValueObjectDynamicValue::SetSyntheticChildrenGenerated (bool b)
-{
- if (m_parent)
- m_parent->SetSyntheticChildrenGenerated(b);
- this->ValueObject::SetSyntheticChildrenGenerated(b);
+void ValueObjectDynamicValue::SetSyntheticChildrenGenerated(bool b) {
+ if (m_parent)
+ m_parent->SetSyntheticChildrenGenerated(b);
+ this->ValueObject::SetSyntheticChildrenGenerated(b);
}
-bool
-ValueObjectDynamicValue::GetDeclaration (Declaration &decl)
-{
- if (m_parent)
- return m_parent->GetDeclaration(decl);
+bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
+ if (m_parent)
+ return m_parent->GetDeclaration(decl);
- return ValueObject::GetDeclaration(decl);
+ return ValueObject::GetDeclaration(decl);
}
-uint64_t
-ValueObjectDynamicValue::GetLanguageFlags ()
-{
- if (m_parent)
- return m_parent->GetLanguageFlags();
- return this->ValueObject::GetLanguageFlags();
+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);
+void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
+ if (m_parent)
+ m_parent->SetLanguageFlags(flags);
+ else
+ this->ValueObject::SetLanguageFlags(flags);
}
diff --git a/source/Core/ValueObjectList.cpp b/source/Core/ValueObjectList.cpp
index 180d4a0eaf12..7eae49744413 100644
--- a/source/Core/ValueObjectList.cpp
+++ b/source/Core/ValueObjectList.cpp
@@ -22,145 +22,101 @@
using namespace lldb;
using namespace lldb_private;
-ValueObjectList::ValueObjectList () :
- m_value_objects()
-{
-}
+ValueObjectList::ValueObjectList() : m_value_objects() {}
-ValueObjectList::ValueObjectList (const ValueObjectList &rhs) :
- m_value_objects(rhs.m_value_objects)
-{
-}
+ValueObjectList::ValueObjectList(const ValueObjectList &rhs)
+ : m_value_objects(rhs.m_value_objects) {}
+ValueObjectList::~ValueObjectList() {}
-ValueObjectList::~ValueObjectList ()
-{
+const ValueObjectList &ValueObjectList::operator=(const ValueObjectList &rhs) {
+ if (this != &rhs)
+ m_value_objects = rhs.m_value_objects;
+ return *this;
}
-const ValueObjectList &
-ValueObjectList::operator = (const ValueObjectList &rhs)
-{
- if (this != &rhs)
- m_value_objects = rhs.m_value_objects;
- return *this;
+void ValueObjectList::Append(const ValueObjectSP &val_obj_sp) {
+ m_value_objects.push_back(val_obj_sp);
}
-void
-ValueObjectList::Append (const ValueObjectSP &val_obj_sp)
-{
- m_value_objects.push_back(val_obj_sp);
+void ValueObjectList::Append(const ValueObjectList &valobj_list) {
+ std::copy(valobj_list.m_value_objects.begin(), // source begin
+ valobj_list.m_value_objects.end(), // source end
+ back_inserter(m_value_objects)); // destination
}
-void
-ValueObjectList::Append (const ValueObjectList &valobj_list)
-{
- std::copy(valobj_list.m_value_objects.begin(), // source begin
- valobj_list.m_value_objects.end(), // source end
- back_inserter(m_value_objects)); // destination
-
-}
+size_t ValueObjectList::GetSize() const { return m_value_objects.size(); }
+void ValueObjectList::Resize(size_t size) { m_value_objects.resize(size); }
-size_t
-ValueObjectList::GetSize() const
-{
- return m_value_objects.size();
+lldb::ValueObjectSP ValueObjectList::GetValueObjectAtIndex(size_t idx) {
+ lldb::ValueObjectSP valobj_sp;
+ if (idx < m_value_objects.size())
+ valobj_sp = m_value_objects[idx];
+ return valobj_sp;
}
-void
-ValueObjectList::Resize (size_t size)
-{
- m_value_objects.resize (size);
+lldb::ValueObjectSP ValueObjectList::RemoveValueObjectAtIndex(size_t idx) {
+ lldb::ValueObjectSP valobj_sp;
+ if (idx < m_value_objects.size()) {
+ valobj_sp = m_value_objects[idx];
+ m_value_objects.erase(m_value_objects.begin() + idx);
+ }
+ return valobj_sp;
}
-lldb::ValueObjectSP
-ValueObjectList::GetValueObjectAtIndex (size_t idx)
-{
- lldb::ValueObjectSP valobj_sp;
- if (idx < m_value_objects.size())
- valobj_sp = m_value_objects[idx];
- return valobj_sp;
+void ValueObjectList::SetValueObjectAtIndex(size_t idx,
+ const ValueObjectSP &valobj_sp) {
+ if (idx >= m_value_objects.size())
+ m_value_objects.resize(idx + 1);
+ m_value_objects[idx] = valobj_sp;
}
-lldb::ValueObjectSP
-ValueObjectList::RemoveValueObjectAtIndex (size_t idx)
-{
- lldb::ValueObjectSP valobj_sp;
- if (idx < m_value_objects.size())
- {
- valobj_sp = m_value_objects[idx];
- m_value_objects.erase (m_value_objects.begin() + idx);
+ValueObjectSP ValueObjectList::FindValueObjectByValueName(const char *name) {
+ ConstString name_const_str(name);
+ ValueObjectSP val_obj_sp;
+ collection::iterator pos, end = m_value_objects.end();
+ for (pos = m_value_objects.begin(); pos != end; ++pos) {
+ ValueObject *valobj = (*pos).get();
+ if (valobj && valobj->GetName() == name_const_str) {
+ val_obj_sp = *pos;
+ break;
}
- return valobj_sp;
+ }
+ return val_obj_sp;
}
-void
-ValueObjectList::SetValueObjectAtIndex (size_t idx, const ValueObjectSP &valobj_sp)
-{
- if (idx >= m_value_objects.size())
- m_value_objects.resize (idx + 1);
- m_value_objects[idx] = valobj_sp;
-}
-
-ValueObjectSP
-ValueObjectList::FindValueObjectByValueName (const char *name)
-{
- ConstString name_const_str(name);
- ValueObjectSP val_obj_sp;
- collection::iterator pos, end = m_value_objects.end();
- for (pos = m_value_objects.begin(); pos != end; ++pos)
- {
- ValueObject *valobj = (*pos).get();
- if (valobj && valobj->GetName() == name_const_str)
- {
- val_obj_sp = *pos;
- break;
- }
+ValueObjectSP ValueObjectList::FindValueObjectByUID(lldb::user_id_t uid) {
+ ValueObjectSP valobj_sp;
+ collection::iterator pos, end = m_value_objects.end();
+
+ for (pos = m_value_objects.begin(); pos != end; ++pos) {
+ // Watch out for NULL objects in our list as the list
+ // might get resized to a specific size and lazily filled in
+ ValueObject *valobj = (*pos).get();
+ if (valobj && valobj->GetID() == uid) {
+ valobj_sp = *pos;
+ break;
}
- return val_obj_sp;
+ }
+ return valobj_sp;
}
ValueObjectSP
-ValueObjectList::FindValueObjectByUID (lldb::user_id_t uid)
-{
- ValueObjectSP valobj_sp;
- collection::iterator pos, end = m_value_objects.end();
-
- for (pos = m_value_objects.begin(); pos != end; ++pos)
- {
- // Watch out for NULL objects in our list as the list
- // might get resized to a specific size and lazily filled in
- ValueObject *valobj = (*pos).get();
- if (valobj && valobj->GetID() == uid)
- {
- valobj_sp = *pos;
- break;
- }
- }
- return valobj_sp;
-}
-
-
-ValueObjectSP
-ValueObjectList::FindValueObjectByPointer (ValueObject *find_valobj)
-{
- ValueObjectSP valobj_sp;
- collection::iterator pos, end = m_value_objects.end();
-
- for (pos = m_value_objects.begin(); pos != end; ++pos)
- {
- ValueObject *valobj = (*pos).get();
- if (valobj && valobj == find_valobj)
- {
- valobj_sp = *pos;
- break;
- }
+ValueObjectList::FindValueObjectByPointer(ValueObject *find_valobj) {
+ ValueObjectSP valobj_sp;
+ collection::iterator pos, end = m_value_objects.end();
+
+ for (pos = m_value_objects.begin(); pos != end; ++pos) {
+ ValueObject *valobj = (*pos).get();
+ if (valobj && valobj == find_valobj) {
+ valobj_sp = *pos;
+ break;
}
- return valobj_sp;
+ }
+ return valobj_sp;
}
-void
-ValueObjectList::Swap (ValueObjectList &value_object_list)
-{
- m_value_objects.swap (value_object_list.m_value_objects);
+void ValueObjectList::Swap(ValueObjectList &value_object_list) {
+ m_value_objects.swap(value_object_list.m_value_objects);
}
diff --git a/source/Core/ValueObjectMemory.cpp b/source/Core/ValueObjectMemory.cpp
index b989710c95d5..86747b84522b 100644
--- a/source/Core/ValueObjectMemory.cpp
+++ b/source/Core/ValueObjectMemory.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "lldb/Core/ValueObjectMemory.h"
// C Includes
@@ -15,9 +14,9 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Module.h"
-#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/Value.h"
#include "lldb/Core/ValueObject.h"
+#include "lldb/Core/ValueObjectList.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -33,256 +32,201 @@
using namespace lldb;
using namespace lldb_private;
-ValueObjectSP
-ValueObjectMemory::Create (ExecutionContextScope *exe_scope,
- const char *name,
- const Address &address,
- lldb::TypeSP &type_sp)
-{
- return (new ValueObjectMemory (exe_scope, name, address, type_sp))->GetSP();
+ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope,
+ llvm::StringRef name,
+ const Address &address,
+ lldb::TypeSP &type_sp) {
+ return (new ValueObjectMemory(exe_scope, name, address, type_sp))->GetSP();
}
-ValueObjectSP
-ValueObjectMemory::Create (ExecutionContextScope *exe_scope,
- const char *name,
- const Address &address,
- const CompilerType &ast_type)
-{
- return (new ValueObjectMemory (exe_scope, name, address, ast_type))->GetSP();
+ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope,
+ llvm::StringRef name,
+ const Address &address,
+ const CompilerType &ast_type) {
+ return (new ValueObjectMemory(exe_scope, name, address, ast_type))->GetSP();
}
-ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
- const char *name,
- const Address &address,
- lldb::TypeSP &type_sp) :
- ValueObject(exe_scope),
- m_address (address),
- m_type_sp(type_sp),
- m_compiler_type()
-{
- // Do not attempt to construct one of these objects with no variable!
- assert (m_type_sp.get() != NULL);
- SetName (ConstString(name));
- m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
- TargetSP target_sp (GetTargetSP());
- lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
- if (load_address != LLDB_INVALID_ADDRESS)
- {
- m_value.SetValueType(Value::eValueTypeLoadAddress);
- m_value.GetScalar() = load_address;
- }
- else
- {
- lldb::addr_t file_address = m_address.GetFileAddress();
- if (file_address != LLDB_INVALID_ADDRESS)
- {
- m_value.SetValueType(Value::eValueTypeFileAddress);
- m_value.GetScalar() = file_address;
- }
- else
- {
- m_value.GetScalar() = m_address.GetOffset();
- m_value.SetValueType (Value::eValueTypeScalar);
- }
+ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope,
+ llvm::StringRef name,
+ const Address &address,
+ lldb::TypeSP &type_sp)
+ : ValueObject(exe_scope), m_address(address), m_type_sp(type_sp),
+ m_compiler_type() {
+ // Do not attempt to construct one of these objects with no variable!
+ assert(m_type_sp.get() != NULL);
+ SetName(ConstString(name));
+ m_value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
+ TargetSP target_sp(GetTargetSP());
+ lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get());
+ if (load_address != LLDB_INVALID_ADDRESS) {
+ m_value.SetValueType(Value::eValueTypeLoadAddress);
+ m_value.GetScalar() = load_address;
+ } else {
+ lldb::addr_t file_address = m_address.GetFileAddress();
+ if (file_address != LLDB_INVALID_ADDRESS) {
+ m_value.SetValueType(Value::eValueTypeFileAddress);
+ m_value.GetScalar() = file_address;
+ } else {
+ m_value.GetScalar() = m_address.GetOffset();
+ m_value.SetValueType(Value::eValueTypeScalar);
}
+ }
}
-ValueObjectMemory::ValueObjectMemory (ExecutionContextScope *exe_scope,
- const char *name,
- const Address &address,
- const CompilerType &ast_type) :
- ValueObject(exe_scope),
- m_address (address),
- m_type_sp(),
- m_compiler_type(ast_type)
-{
- // Do not attempt to construct one of these objects with no variable!
- assert (m_compiler_type.GetTypeSystem());
- assert (m_compiler_type.GetOpaqueQualType());
-
- TargetSP target_sp (GetTargetSP());
-
- SetName (ConstString(name));
-// 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)
- {
- m_value.SetValueType(Value::eValueTypeLoadAddress);
- m_value.GetScalar() = load_address;
- }
- else
- {
- lldb::addr_t file_address = m_address.GetFileAddress();
- if (file_address != LLDB_INVALID_ADDRESS)
- {
- m_value.SetValueType(Value::eValueTypeFileAddress);
- m_value.GetScalar() = file_address;
- }
- else
- {
- m_value.GetScalar() = m_address.GetOffset();
- m_value.SetValueType (Value::eValueTypeScalar);
- }
+ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope,
+ llvm::StringRef name,
+ const Address &address,
+ const CompilerType &ast_type)
+ : ValueObject(exe_scope), m_address(address), m_type_sp(),
+ m_compiler_type(ast_type) {
+ // Do not attempt to construct one of these objects with no variable!
+ assert(m_compiler_type.GetTypeSystem());
+ assert(m_compiler_type.GetOpaqueQualType());
+
+ TargetSP target_sp(GetTargetSP());
+
+ SetName(ConstString(name));
+ // 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) {
+ m_value.SetValueType(Value::eValueTypeLoadAddress);
+ m_value.GetScalar() = load_address;
+ } else {
+ lldb::addr_t file_address = m_address.GetFileAddress();
+ if (file_address != LLDB_INVALID_ADDRESS) {
+ m_value.SetValueType(Value::eValueTypeFileAddress);
+ m_value.GetScalar() = file_address;
+ } else {
+ m_value.GetScalar() = m_address.GetOffset();
+ m_value.SetValueType(Value::eValueTypeScalar);
}
+ }
}
-ValueObjectMemory::~ValueObjectMemory()
-{
-}
+ValueObjectMemory::~ValueObjectMemory() {}
-CompilerType
-ValueObjectMemory::GetCompilerTypeImpl ()
-{
- if (m_type_sp)
- return m_type_sp->GetForwardCompilerType ();
- return m_compiler_type;
+CompilerType ValueObjectMemory::GetCompilerTypeImpl() {
+ if (m_type_sp)
+ return m_type_sp->GetForwardCompilerType();
+ return m_compiler_type;
}
-ConstString
-ValueObjectMemory::GetTypeName()
-{
- if (m_type_sp)
- return m_type_sp->GetName();
- return m_compiler_type.GetConstTypeName();
+ConstString ValueObjectMemory::GetTypeName() {
+ if (m_type_sp)
+ return m_type_sp->GetName();
+ return m_compiler_type.GetConstTypeName();
}
-ConstString
-ValueObjectMemory::GetDisplayTypeName()
-{
- if (m_type_sp)
- return m_type_sp->GetForwardCompilerType ().GetDisplayTypeName();
- return m_compiler_type.GetDisplayTypeName();
+ConstString ValueObjectMemory::GetDisplayTypeName() {
+ if (m_type_sp)
+ return m_type_sp->GetForwardCompilerType().GetDisplayTypeName();
+ return m_compiler_type.GetDisplayTypeName();
}
-size_t
-ValueObjectMemory::CalculateNumChildren(uint32_t max)
-{
- if (m_type_sp)
- {
- auto child_count = m_type_sp->GetNumChildren(true);
- return child_count <= max ? child_count : max;
- }
-
- const bool omit_empty_base_classes = true;
- auto child_count = m_compiler_type.GetNumChildren (omit_empty_base_classes);
+size_t ValueObjectMemory::CalculateNumChildren(uint32_t max) {
+ if (m_type_sp) {
+ auto child_count = m_type_sp->GetNumChildren(true);
return child_count <= max ? child_count : max;
-}
+ }
-uint64_t
-ValueObjectMemory::GetByteSize()
-{
- if (m_type_sp)
- return m_type_sp->GetByteSize();
- return m_compiler_type.GetByteSize (nullptr);
+ const bool omit_empty_base_classes = true;
+ auto child_count = m_compiler_type.GetNumChildren(omit_empty_base_classes);
+ return child_count <= max ? child_count : max;
}
-lldb::ValueType
-ValueObjectMemory::GetValueType() const
-{
- // RETHINK: Should this be inherited from somewhere?
- return lldb::eValueTypeVariableGlobal;
+uint64_t ValueObjectMemory::GetByteSize() {
+ if (m_type_sp)
+ return m_type_sp->GetByteSize();
+ return m_compiler_type.GetByteSize(nullptr);
}
-bool
-ValueObjectMemory::UpdateValue ()
-{
- SetValueIsValid (false);
- m_error.Clear();
-
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
- }
+lldb::ValueType ValueObjectMemory::GetValueType() const {
+ // RETHINK: Should this be inherited from somewhere?
+ return lldb::eValueTypeVariableGlobal;
+}
- Value old_value(m_value);
- if (m_address.IsValid())
- {
- Value::ValueType value_type = m_value.GetValueType();
-
- switch (value_type)
- {
- default:
- assert(!"Unhandled expression result value kind...");
- break;
-
- case Value::eValueTypeScalar:
- // The variable value is in the Scalar value inside the m_value.
- // We can point our m_data right to it.
- m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
- break;
-
- case Value::eValueTypeFileAddress:
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeHostAddress:
- // The DWARF expression result was an address in the inferior
- // process. If this variable is an aggregate type, we just need
- // the address as the main value as all child variable objects
- // will rely upon this location and add an offset and then read
- // their own values as needed. If this variable is a simple
- // type, we read all data for it into m_data.
- // Make sure this type has a value before we try and read it
-
- // If we have a file address, convert it to a load address if we can.
- if (value_type == Value::eValueTypeFileAddress && exe_ctx.GetProcessPtr())
- {
- lldb::addr_t load_addr = m_address.GetLoadAddress(target);
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- m_value.SetValueType(Value::eValueTypeLoadAddress);
- m_value.GetScalar() = load_addr;
- }
- }
-
- if (!CanProvideValue())
- {
- // this value object represents an aggregate type whose
- // children have values, but this object does not. So we
- // say we are changed if our location has changed.
- SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
- }
- else
- {
- // Copy the Value and set the context to use our Variable
- // so it can extract read its value into m_data appropriately
- Value value(m_value);
- if (m_type_sp)
- value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
- else
- {
- //value.SetContext(Value::eContextTypeClangType, m_compiler_type.GetOpaqueQualType());
- value.SetCompilerType(m_compiler_type);
- }
-
- m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
- }
- break;
+bool ValueObjectMemory::UpdateValue() {
+ SetValueIsValid(false);
+ m_error.Clear();
+
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ }
+
+ Value old_value(m_value);
+ if (m_address.IsValid()) {
+ Value::ValueType value_type = m_value.GetValueType();
+
+ switch (value_type) {
+ default:
+ assert(!"Unhandled expression result value kind...");
+ break;
+
+ case Value::eValueTypeScalar:
+ // The variable value is in the Scalar value inside the m_value.
+ // We can point our m_data right to it.
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ break;
+
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeHostAddress:
+ // The DWARF expression result was an address in the inferior
+ // process. If this variable is an aggregate type, we just need
+ // the address as the main value as all child variable objects
+ // will rely upon this location and add an offset and then read
+ // their own values as needed. If this variable is a simple
+ // type, we read all data for it into m_data.
+ // Make sure this type has a value before we try and read it
+
+ // If we have a file address, convert it to a load address if we can.
+ if (value_type == Value::eValueTypeFileAddress &&
+ exe_ctx.GetProcessPtr()) {
+ lldb::addr_t load_addr = m_address.GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ m_value.SetValueType(Value::eValueTypeLoadAddress);
+ m_value.GetScalar() = load_addr;
+ }
+ }
+
+ if (!CanProvideValue()) {
+ // this value object represents an aggregate type whose
+ // children have values, but this object does not. So we
+ // say we are changed if our location has changed.
+ SetValueDidChange(value_type != old_value.GetValueType() ||
+ m_value.GetScalar() != old_value.GetScalar());
+ } else {
+ // Copy the Value and set the context to use our Variable
+ // so it can extract read its value into m_data appropriately
+ Value value(m_value);
+ if (m_type_sp)
+ value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get());
+ else {
+ // value.SetContext(Value::eContextTypeClangType,
+ // m_compiler_type.GetOpaqueQualType());
+ value.SetCompilerType(m_compiler_type);
}
- SetValueIsValid (m_error.Success());
+ m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ }
+ break;
}
- return m_error.Success();
-}
-
-
-bool
-ValueObjectMemory::IsInScope ()
-{
- // FIXME: Maybe try to read the memory address, and if that works, then
- // we are in scope?
- return true;
+ SetValueIsValid(m_error.Success());
+ }
+ return m_error.Success();
}
-
-lldb::ModuleSP
-ValueObjectMemory::GetModule()
-{
- return m_address.GetModule();
+bool ValueObjectMemory::IsInScope() {
+ // FIXME: Maybe try to read the memory address, and if that works, then
+ // we are in scope?
+ return true;
}
-
+lldb::ModuleSP ValueObjectMemory::GetModule() { return m_address.GetModule(); }
diff --git a/source/Core/ValueObjectRegister.cpp b/source/Core/ValueObjectRegister.cpp
index c7845cd03207..80e00e4007c4 100644
--- a/source/Core/ValueObjectRegister.cpp
+++ b/source/Core/ValueObjectRegister.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "lldb/Core/ValueObjectRegister.h"
// C Includes
@@ -15,8 +14,8 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/Module.h"
-#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
@@ -29,416 +28,322 @@ using namespace lldb_private;
#pragma mark ValueObjectRegisterContext
-ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP &reg_ctx) :
- ValueObject (parent),
- m_reg_ctx_sp (reg_ctx)
-{
- assert (reg_ctx);
- m_name.SetCString("Registers");
- SetValueIsValid (true);
+ValueObjectRegisterContext::ValueObjectRegisterContext(
+ ValueObject &parent, RegisterContextSP &reg_ctx)
+ : ValueObject(parent), m_reg_ctx_sp(reg_ctx) {
+ assert(reg_ctx);
+ m_name.SetCString("Registers");
+ SetValueIsValid(true);
}
-ValueObjectRegisterContext::~ValueObjectRegisterContext()
-{
-}
+ValueObjectRegisterContext::~ValueObjectRegisterContext() {}
-CompilerType
-ValueObjectRegisterContext::GetCompilerTypeImpl ()
-{
- return CompilerType();
+CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() {
+ return CompilerType();
}
-ConstString
-ValueObjectRegisterContext::GetTypeName()
-{
- return ConstString();
-}
+ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); }
-ConstString
-ValueObjectRegisterContext::GetDisplayTypeName()
-{
- return ConstString();
+ConstString ValueObjectRegisterContext::GetDisplayTypeName() {
+ return ConstString();
}
-ConstString
-ValueObjectRegisterContext::GetQualifiedTypeName()
-{
- return ConstString();
+ConstString ValueObjectRegisterContext::GetQualifiedTypeName() {
+ return ConstString();
}
-size_t
-ValueObjectRegisterContext::CalculateNumChildren(uint32_t max)
-{
- auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
- return reg_set_count <= max ? reg_set_count : max;
+size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) {
+ auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount();
+ return reg_set_count <= max ? reg_set_count : max;
}
-uint64_t
-ValueObjectRegisterContext::GetByteSize()
-{
- return 0;
-}
+uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; }
-bool
-ValueObjectRegisterContext::UpdateValue ()
-{
- m_error.Clear();
- ExecutionContext exe_ctx(GetExecutionContextRef());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame)
- m_reg_ctx_sp = frame->GetRegisterContext();
- else
- m_reg_ctx_sp.reset();
+bool ValueObjectRegisterContext::UpdateValue() {
+ m_error.Clear();
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame)
+ m_reg_ctx_sp = frame->GetRegisterContext();
+ else
+ m_reg_ctx_sp.reset();
- if (m_reg_ctx_sp.get() == NULL)
- {
- SetValueIsValid (false);
- m_error.SetErrorToGenericError();
- }
- else
- SetValueIsValid (true);
-
- return m_error.Success();
-}
+ if (m_reg_ctx_sp.get() == NULL) {
+ SetValueIsValid(false);
+ m_error.SetErrorToGenericError();
+ } else
+ SetValueIsValid(true);
-ValueObject *
-ValueObjectRegisterContext::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
-{
- ValueObject *new_valobj = NULL;
-
- const size_t num_children = GetNumChildren();
- if (idx < num_children)
- {
- ExecutionContext exe_ctx(GetExecutionContextRef());
- new_valobj = new ValueObjectRegisterSet(exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
- }
-
- return new_valobj;
+ return m_error.Success();
}
+ValueObject *ValueObjectRegisterContext::CreateChildAtIndex(
+ size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
+ ValueObject *new_valobj = NULL;
+
+ const size_t num_children = GetNumChildren();
+ if (idx < num_children) {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ new_valobj = new ValueObjectRegisterSet(
+ exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
+ }
+
+ return new_valobj;
+}
#pragma mark -
#pragma mark ValueObjectRegisterSet
ValueObjectSP
-ValueObjectRegisterSet::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t set_idx)
-{
- return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
+ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP &reg_ctx_sp,
+ uint32_t set_idx) {
+ return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
}
-
-ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_set_idx) :
- ValueObject (exe_scope),
- m_reg_ctx_sp (reg_ctx),
- m_reg_set (NULL),
- m_reg_set_idx (reg_set_idx)
-{
- assert (reg_ctx);
- m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
- if (m_reg_set)
- {
- m_name.SetCString (m_reg_set->name);
- }
+ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP &reg_ctx,
+ uint32_t reg_set_idx)
+ : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(NULL),
+ m_reg_set_idx(reg_set_idx) {
+ assert(reg_ctx);
+ m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
+ if (m_reg_set) {
+ m_name.SetCString(m_reg_set->name);
+ }
}
-ValueObjectRegisterSet::~ValueObjectRegisterSet()
-{
-}
+ValueObjectRegisterSet::~ValueObjectRegisterSet() {}
-CompilerType
-ValueObjectRegisterSet::GetCompilerTypeImpl ()
-{
- return CompilerType();
+CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
+ return CompilerType();
}
-ConstString
-ValueObjectRegisterSet::GetTypeName()
-{
- return ConstString();
-}
+ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
-ConstString
-ValueObjectRegisterSet::GetQualifiedTypeName()
-{
- return ConstString();
+ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
+ return ConstString();
}
-size_t
-ValueObjectRegisterSet::CalculateNumChildren(uint32_t max)
-{
- const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
- if (reg_set)
- {
- auto reg_count = reg_set->num_registers;
- return reg_count <= max ? reg_count : max;
- }
- return 0;
+size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
+ const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
+ if (reg_set) {
+ auto reg_count = reg_set->num_registers;
+ return reg_count <= max ? reg_count : max;
+ }
+ return 0;
}
-uint64_t
-ValueObjectRegisterSet::GetByteSize()
-{
- return 0;
-}
+uint64_t ValueObjectRegisterSet::GetByteSize() { return 0; }
-bool
-ValueObjectRegisterSet::UpdateValue ()
-{
- m_error.Clear();
- SetValueDidChange (false);
- ExecutionContext exe_ctx(GetExecutionContextRef());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame == NULL)
+bool ValueObjectRegisterSet::UpdateValue() {
+ m_error.Clear();
+ SetValueDidChange(false);
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame == NULL)
+ m_reg_ctx_sp.reset();
+ else {
+ m_reg_ctx_sp = frame->GetRegisterContext();
+ if (m_reg_ctx_sp) {
+ const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
+ if (reg_set == NULL)
m_reg_ctx_sp.reset();
- else
- {
- m_reg_ctx_sp = frame->GetRegisterContext ();
- if (m_reg_ctx_sp)
- {
- const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet (m_reg_set_idx);
- if (reg_set == NULL)
- m_reg_ctx_sp.reset();
- else if (m_reg_set != reg_set)
- {
- SetValueDidChange (true);
- m_name.SetCString(reg_set->name);
- }
- }
- }
- if (m_reg_ctx_sp)
- {
- SetValueIsValid (true);
- }
- else
- {
- SetValueIsValid (false);
- m_error.SetErrorToGenericError ();
- m_children.Clear();
- }
- return m_error.Success();
-}
-
-
-ValueObject *
-ValueObjectRegisterSet::CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index)
-{
- ValueObject *valobj = NULL;
- if (m_reg_ctx_sp && m_reg_set)
- {
- const size_t num_children = GetNumChildren();
- if (idx < num_children)
- valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, m_reg_set->registers[idx]);
+ else if (m_reg_set != reg_set) {
+ SetValueDidChange(true);
+ m_name.SetCString(reg_set->name);
+ }
}
- return valobj;
+ }
+ if (m_reg_ctx_sp) {
+ SetValueIsValid(true);
+ } else {
+ SetValueIsValid(false);
+ m_error.SetErrorToGenericError();
+ m_children.Clear();
+ }
+ return m_error.Success();
+}
+
+ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
+ size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
+ ValueObject *valobj = NULL;
+ if (m_reg_ctx_sp && m_reg_set) {
+ const size_t num_children = GetNumChildren();
+ if (idx < num_children)
+ valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
+ m_reg_set->registers[idx]);
+ }
+ return valobj;
}
lldb::ValueObjectSP
-ValueObjectRegisterSet::GetChildMemberWithName (const ConstString &name, bool can_create)
-{
- ValueObject *valobj = NULL;
- if (m_reg_ctx_sp && m_reg_set)
- {
- const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
- if (reg_info != NULL)
- valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]);
- }
- if (valobj)
- return valobj->GetSP();
- else
- return ValueObjectSP();
+ValueObjectRegisterSet::GetChildMemberWithName(const ConstString &name,
+ bool can_create) {
+ ValueObject *valobj = NULL;
+ if (m_reg_ctx_sp && m_reg_set) {
+ const RegisterInfo *reg_info =
+ m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
+ if (reg_info != NULL)
+ valobj = new ValueObjectRegister(*this, m_reg_ctx_sp,
+ reg_info->kinds[eRegisterKindLLDB]);
+ }
+ if (valobj)
+ return valobj->GetSP();
+ else
+ return ValueObjectSP();
}
size_t
-ValueObjectRegisterSet::GetIndexOfChildWithName (const ConstString &name)
-{
- if (m_reg_ctx_sp && m_reg_set)
- {
- const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName (name.AsCString());
- if (reg_info != NULL)
- return reg_info->kinds[eRegisterKindLLDB];
- }
- return UINT32_MAX;
+ValueObjectRegisterSet::GetIndexOfChildWithName(const ConstString &name) {
+ if (m_reg_ctx_sp && m_reg_set) {
+ const RegisterInfo *reg_info =
+ m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString());
+ if (reg_info != NULL)
+ return reg_info->kinds[eRegisterKindLLDB];
+ }
+ return UINT32_MAX;
}
#pragma mark -
#pragma mark ValueObjectRegister
-void
-ValueObjectRegister::ConstructObject (uint32_t reg_num)
-{
- const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex (reg_num);
- if (reg_info)
- {
- m_reg_info = *reg_info;
- if (reg_info->name)
- m_name.SetCString(reg_info->name);
- else if (reg_info->alt_name)
- m_name.SetCString(reg_info->alt_name);
- }
-}
-
-ValueObjectRegister::ValueObjectRegister (ValueObject &parent, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num) :
- ValueObject (parent),
- m_reg_ctx_sp (reg_ctx_sp),
- m_reg_info (),
- m_reg_value (),
- m_type_name (),
- m_compiler_type ()
-{
- assert (reg_ctx_sp.get());
- ConstructObject(reg_num);
-}
-
-ValueObjectSP
-ValueObjectRegister::Create (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx_sp, uint32_t reg_num)
-{
- return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
-}
-
-ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP &reg_ctx, uint32_t reg_num) :
- ValueObject (exe_scope),
- m_reg_ctx_sp (reg_ctx),
- m_reg_info (),
- m_reg_value (),
- m_type_name (),
- m_compiler_type ()
-{
- assert (reg_ctx);
- ConstructObject(reg_num);
-}
-
-ValueObjectRegister::~ValueObjectRegister()
-{
+void ValueObjectRegister::ConstructObject(uint32_t reg_num) {
+ const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num);
+ if (reg_info) {
+ m_reg_info = *reg_info;
+ if (reg_info->name)
+ m_name.SetCString(reg_info->name);
+ else if (reg_info->alt_name)
+ m_name.SetCString(reg_info->alt_name);
+ }
}
-CompilerType
-ValueObjectRegister::GetCompilerTypeImpl ()
-{
- if (!m_compiler_type.IsValid())
- {
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- Module *exe_module = target->GetExecutableModulePointer();
- if (exe_module)
- {
- 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_compiler_type;
+ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
+ lldb::RegisterContextSP &reg_ctx_sp,
+ uint32_t reg_num)
+ : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
+ m_reg_value(), m_type_name(), m_compiler_type() {
+ assert(reg_ctx_sp.get());
+ ConstructObject(reg_num);
}
-ConstString
-ValueObjectRegister::GetTypeName()
-{
- if (m_type_name.IsEmpty())
- m_type_name = GetCompilerType().GetConstTypeName ();
- return m_type_name;
+ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP &reg_ctx_sp,
+ uint32_t reg_num) {
+ return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
}
-size_t
-ValueObjectRegister::CalculateNumChildren(uint32_t max)
-{
- auto children_count = GetCompilerType().GetNumChildren (true);
- return children_count <= max ? children_count : max;
+ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP &reg_ctx,
+ uint32_t reg_num)
+ : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(),
+ m_reg_value(), m_type_name(), m_compiler_type() {
+ assert(reg_ctx);
+ ConstructObject(reg_num);
}
-uint64_t
-ValueObjectRegister::GetByteSize()
-{
- return m_reg_info.byte_size;
-}
+ValueObjectRegister::~ValueObjectRegister() {}
-bool
-ValueObjectRegister::UpdateValue ()
-{
- m_error.Clear();
+CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
+ if (!m_compiler_type.IsValid()) {
ExecutionContext exe_ctx(GetExecutionContextRef());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame == NULL)
- {
- m_reg_ctx_sp.reset();
- m_reg_value.Clear();
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ Module *exe_module = target->GetExecutableModulePointer();
+ if (exe_module) {
+ 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);
+ }
}
-
-
- if (m_reg_ctx_sp)
- {
- if (m_reg_ctx_sp->ReadRegister (&m_reg_info, m_reg_value))
- {
- if (m_reg_value.GetData (m_data))
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- m_data.SetAddressByteSize(process->GetAddressByteSize());
- m_value.SetContext(Value::eContextTypeRegisterInfo, (void *)&m_reg_info);
- m_value.SetValueType(Value::eValueTypeHostAddress);
- m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
- SetValueIsValid (true);
- return true;
- }
- }
+ }
+ return m_compiler_type;
+}
+
+ConstString ValueObjectRegister::GetTypeName() {
+ if (m_type_name.IsEmpty())
+ m_type_name = GetCompilerType().GetConstTypeName();
+ return m_type_name;
+}
+
+size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
+ auto children_count = GetCompilerType().GetNumChildren(true);
+ return children_count <= max ? children_count : max;
+}
+
+uint64_t ValueObjectRegister::GetByteSize() { return m_reg_info.byte_size; }
+
+bool ValueObjectRegister::UpdateValue() {
+ m_error.Clear();
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame == NULL) {
+ m_reg_ctx_sp.reset();
+ m_reg_value.Clear();
+ }
+
+ if (m_reg_ctx_sp) {
+ RegisterValue m_old_reg_value(m_reg_value);
+ if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
+ if (m_reg_value.GetData(m_data)) {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process)
+ m_data.SetAddressByteSize(process->GetAddressByteSize());
+ m_value.SetContext(Value::eContextTypeRegisterInfo,
+ (void *)&m_reg_info);
+ m_value.SetValueType(Value::eValueTypeHostAddress);
+ m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
+ SetValueIsValid(true);
+ SetValueDidChange(!(m_old_reg_value == m_reg_value));
+ return true;
+ }
}
-
- SetValueIsValid (false);
- m_error.SetErrorToGenericError ();
+ }
+
+ SetValueIsValid(false);
+ m_error.SetErrorToGenericError();
+ return false;
+}
+
+bool ValueObjectRegister::SetValueFromCString(const char *value_str,
+ Error &error) {
+ // The new value will be in the m_data. Copy that into our register value.
+ error =
+ m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
+ if (error.Success()) {
+ if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
+ SetNeedsUpdate();
+ return true;
+ } else
+ return false;
+ } else
return false;
}
-bool
-ValueObjectRegister::SetValueFromCString (const char *value_str, Error& error)
-{
- // The new value will be in the m_data. Copy that into our register value.
- error = m_reg_value.SetValueFromCString (&m_reg_info, value_str);
- if (error.Success())
- {
- if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
- {
- SetNeedsUpdate();
- return true;
- }
- else
- return false;
- }
- else
- return false;
-}
-
-bool
-ValueObjectRegister::SetData (DataExtractor &data, Error &error)
-{
- error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
- if (error.Success())
- {
- if (m_reg_ctx_sp->WriteRegister (&m_reg_info, m_reg_value))
- {
- SetNeedsUpdate();
- return true;
- }
- else
- return false;
- }
- else
- return false;
-}
-
-bool
-ValueObjectRegister::ResolveValue (Scalar &scalar)
-{
- if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
- return m_reg_value.GetScalarValue(scalar);
+bool ValueObjectRegister::SetData(DataExtractor &data, Error &error) {
+ error = m_reg_value.SetValueFromData(&m_reg_info, data, 0, false);
+ if (error.Success()) {
+ if (m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
+ SetNeedsUpdate();
+ return true;
+ } else
+ return false;
+ } else
return false;
}
-void
-ValueObjectRegister::GetExpressionPath (Stream &s, bool qualify_cxx_base_classes, GetExpressionPathFormat epformat)
-{
- s.Printf("$%s", m_reg_info.name);
+bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
+ if (UpdateValueIfNeeded(
+ false)) // make sure that you are up to date before returning anything
+ return m_reg_value.GetScalarValue(scalar);
+ return false;
}
-
+void ValueObjectRegister::GetExpressionPath(Stream &s,
+ bool qualify_cxx_base_classes,
+ GetExpressionPathFormat epformat) {
+ s.Printf("$%s", m_reg_info.name);
+}
diff --git a/source/Core/ValueObjectSyntheticFilter.cpp b/source/Core/ValueObjectSyntheticFilter.cpp
index f2f233711b9c..592f1ea56bdf 100644
--- a/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/source/Core/ValueObjectSyntheticFilter.cpp
@@ -19,441 +19,361 @@
using namespace lldb_private;
-class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
+class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- DummySyntheticFrontEnd(ValueObject &backend) :
- SyntheticChildrenFrontEnd(backend)
- {}
-
- size_t
- CalculateNumChildren() override
- {
- return m_backend.GetNumChildren();
- }
-
- lldb::ValueObjectSP
- GetChildAtIndex(size_t idx) override
- {
- return m_backend.GetChildAtIndex(idx, true);
- }
+ DummySyntheticFrontEnd(ValueObject &backend)
+ : SyntheticChildrenFrontEnd(backend) {}
- size_t
- GetIndexOfChildWithName(const ConstString &name) override
- {
- return m_backend.GetIndexOfChildWithName(name);
- }
-
- bool
- MightHaveChildren() override
- {
- return true;
- }
-
- bool
- Update() override
- {
- return false;
- }
+ size_t CalculateNumChildren() override { return m_backend.GetNumChildren(); }
+
+ lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
+ return m_backend.GetChildAtIndex(idx, true);
+ }
+
+ size_t GetIndexOfChildWithName(const ConstString &name) override {
+ return m_backend.GetIndexOfChildWithName(name);
+ }
+
+ bool MightHaveChildren() override { return true; }
+
+ bool Update() override { return false; }
};
-ValueObjectSynthetic::ValueObjectSynthetic (ValueObject &parent, lldb::SyntheticChildrenSP filter) :
- ValueObject(parent),
- m_synth_sp(filter),
- m_children_byindex(),
- m_name_toindex(),
- m_synthetic_children_count(UINT32_MAX),
- m_synthetic_children_cache(),
- m_parent_type_name(parent.GetTypeName()),
- m_might_have_children(eLazyBoolCalculate),
- m_provides_value(eLazyBoolCalculate)
-{
- SetName(parent.GetName());
- CopyValueData(m_parent);
- CreateSynthFilter();
+ValueObjectSynthetic::ValueObjectSynthetic(ValueObject &parent,
+ lldb::SyntheticChildrenSP filter)
+ : ValueObject(parent), m_synth_sp(filter), m_children_byindex(),
+ m_name_toindex(), m_synthetic_children_count(UINT32_MAX),
+ m_synthetic_children_cache(), m_parent_type_name(parent.GetTypeName()),
+ m_might_have_children(eLazyBoolCalculate),
+ m_provides_value(eLazyBoolCalculate) {
+ SetName(parent.GetName());
+ CopyValueData(m_parent);
+ CreateSynthFilter();
}
ValueObjectSynthetic::~ValueObjectSynthetic() = default;
-CompilerType
-ValueObjectSynthetic::GetCompilerTypeImpl ()
-{
- return m_parent->GetCompilerType();
+CompilerType ValueObjectSynthetic::GetCompilerTypeImpl() {
+ return m_parent->GetCompilerType();
}
-ConstString
-ValueObjectSynthetic::GetTypeName()
-{
- return m_parent->GetTypeName();
+ConstString ValueObjectSynthetic::GetTypeName() {
+ return m_parent->GetTypeName();
}
-ConstString
-ValueObjectSynthetic::GetQualifiedTypeName()
-{
- return m_parent->GetQualifiedTypeName();
+ConstString ValueObjectSynthetic::GetQualifiedTypeName() {
+ return m_parent->GetQualifiedTypeName();
}
-ConstString
-ValueObjectSynthetic::GetDisplayTypeName()
-{
- if (ConstString synth_name = m_synth_filter_ap->GetSyntheticTypeName())
- return synth_name;
+ConstString ValueObjectSynthetic::GetDisplayTypeName() {
+ if (ConstString synth_name = m_synth_filter_ap->GetSyntheticTypeName())
+ return synth_name;
- return m_parent->GetDisplayTypeName();
+ return m_parent->GetDisplayTypeName();
}
-size_t
-ValueObjectSynthetic::CalculateNumChildren(uint32_t max)
-{
- Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
-
- UpdateValueIfNeeded();
- if (m_synthetic_children_count < UINT32_MAX)
- return m_synthetic_children_count <= max ? m_synthetic_children_count : max;
-
- if (max < UINT32_MAX)
- {
- size_t num_children = m_synth_filter_ap->CalculateNumChildren(max);
- if (log)
- log->Printf("[ValueObjectSynthetic::CalculateNumChildren] for VO of name %s and type %s, the filter returned %zu child values",
- GetName().AsCString(),
- GetTypeName().AsCString(),
- num_children);
- return num_children;
- }
- else
- {
- size_t num_children = (m_synthetic_children_count = m_synth_filter_ap->CalculateNumChildren(max));
- if (log)
- log->Printf("[ValueObjectSynthetic::CalculateNumChildren] for VO of name %s and type %s, the filter returned %zu child values",
- GetName().AsCString(),
- GetTypeName().AsCString(),
- num_children);
- return num_children;
- }
+size_t ValueObjectSynthetic::CalculateNumChildren(uint32_t max) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
+
+ UpdateValueIfNeeded();
+ if (m_synthetic_children_count < UINT32_MAX)
+ return m_synthetic_children_count <= max ? m_synthetic_children_count : max;
+
+ if (max < UINT32_MAX) {
+ size_t num_children = m_synth_filter_ap->CalculateNumChildren(max);
+ if (log)
+ log->Printf("[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
+ "%s and type %s, the filter returned %zu child values",
+ GetName().AsCString(), GetTypeName().AsCString(),
+ num_children);
+ return num_children;
+ } else {
+ size_t num_children = (m_synthetic_children_count =
+ m_synth_filter_ap->CalculateNumChildren(max));
+ if (log)
+ log->Printf("[ValueObjectSynthetic::CalculateNumChildren] for VO of name "
+ "%s and type %s, the filter returned %zu child values",
+ GetName().AsCString(), GetTypeName().AsCString(),
+ num_children);
+ return num_children;
+ }
}
lldb::ValueObjectSP
-ValueObjectSynthetic::GetDynamicValue (lldb::DynamicValueType valueType)
-{
- if (!m_parent)
- return lldb::ValueObjectSP();
- if (IsDynamic() && GetDynamicValueType() == valueType)
- return GetSP();
- return m_parent->GetDynamicValue(valueType);
+ValueObjectSynthetic::GetDynamicValue(lldb::DynamicValueType valueType) {
+ if (!m_parent)
+ return lldb::ValueObjectSP();
+ if (IsDynamic() && GetDynamicValueType() == valueType)
+ return GetSP();
+ return m_parent->GetDynamicValue(valueType);
}
-bool
-ValueObjectSynthetic::MightHaveChildren()
-{
- if (m_might_have_children == eLazyBoolCalculate)
- m_might_have_children = (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
- return (m_might_have_children == eLazyBoolNo ? false : true);
+bool ValueObjectSynthetic::MightHaveChildren() {
+ if (m_might_have_children == eLazyBoolCalculate)
+ m_might_have_children =
+ (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo);
+ return (m_might_have_children == eLazyBoolNo ? false : true);
}
-uint64_t
-ValueObjectSynthetic::GetByteSize()
-{
- return m_parent->GetByteSize();
-}
+uint64_t ValueObjectSynthetic::GetByteSize() { return m_parent->GetByteSize(); }
-lldb::ValueType
-ValueObjectSynthetic::GetValueType() const
-{
- return m_parent->GetValueType();
+lldb::ValueType ValueObjectSynthetic::GetValueType() const {
+ return m_parent->GetValueType();
}
-void
-ValueObjectSynthetic::CreateSynthFilter ()
-{
- m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent));
- if (!m_synth_filter_ap.get())
- m_synth_filter_ap.reset(new DummySyntheticFrontEnd(*m_parent));
+void ValueObjectSynthetic::CreateSynthFilter() {
+ m_synth_filter_ap = (m_synth_sp->GetFrontEnd(*m_parent));
+ if (!m_synth_filter_ap.get())
+ m_synth_filter_ap.reset(new DummySyntheticFrontEnd(*m_parent));
}
-bool
-ValueObjectSynthetic::UpdateValue ()
-{
- Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
-
- SetValueIsValid (false);
- m_error.Clear();
-
- if (!m_parent->UpdateValueIfNeeded(false))
- {
- // our parent could not update.. as we are meaningless without a parent, just stop
- if (m_parent->GetError().Fail())
- m_error = m_parent->GetError();
- return false;
- }
-
- // regenerate the synthetic filter if our typename changes
- // <rdar://problem/12424824>
- ConstString new_parent_type_name = m_parent->GetTypeName();
- if (new_parent_type_name != m_parent_type_name)
- {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, type changed from %s to %s, recomputing synthetic filter",
- GetName().AsCString(),
- m_parent_type_name.AsCString(),
- new_parent_type_name.AsCString());
- m_parent_type_name = new_parent_type_name;
- CreateSynthFilter();
- }
+bool ValueObjectSynthetic::UpdateValue() {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
- // let our backend do its update
- if (m_synth_filter_ap->Update() == false)
- {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic filter said caches are stale - clearing", GetName().AsCString());
- // filter said that cached values are stale
- m_children_byindex.Clear();
- m_name_toindex.Clear();
- // usually, an object's value can change but this does not alter its children count
- // for a synthetic VO that might indeed happen, so we need to tell the upper echelons
- // that they need to come back to us asking for children
- m_children_count_valid = false;
- m_synthetic_children_cache.Clear();
- m_synthetic_children_count = UINT32_MAX;
- m_might_have_children = eLazyBoolCalculate;
- }
- else
- {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic filter said caches are still valid", GetName().AsCString());
- }
-
- m_provides_value = eLazyBoolCalculate;
-
- lldb::ValueObjectSP synth_val(m_synth_filter_ap->GetSyntheticValue());
-
- if (synth_val && synth_val->CanProvideValue())
- {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic filter said it can provide a value", GetName().AsCString());
-
- m_provides_value = eLazyBoolYes;
- CopyValueData(synth_val.get());
- }
- else
- {
- if (log)
- log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic filter said it will not provide a value", GetName().AsCString());
+ SetValueIsValid(false);
+ m_error.Clear();
- m_provides_value = eLazyBoolNo;
- CopyValueData(m_parent);
- }
-
- SetValueIsValid(true);
- return true;
-}
+ if (!m_parent->UpdateValueIfNeeded(false)) {
+ // our parent could not update.. as we are meaningless without a parent,
+ // just stop
+ if (m_parent->GetError().Fail())
+ m_error = m_parent->GetError();
+ return false;
+ }
-lldb::ValueObjectSP
-ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
-{
- Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
-
+ // regenerate the synthetic filter if our typename changes
+ // <rdar://problem/12424824>
+ ConstString new_parent_type_name = m_parent->GetTypeName();
+ if (new_parent_type_name != m_parent_type_name) {
if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, retrieving child at index %zu",
- GetName().AsCString(),
- idx);
-
- UpdateValueIfNeeded();
-
- ValueObject *valobj;
- if (m_children_byindex.GetValueForKey(idx, valobj) == false)
- {
- if (can_create && m_synth_filter_ap.get() != nullptr)
- {
- if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu not cached and will be created",
- GetName().AsCString(),
- idx);
-
- lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex (idx);
-
- if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu created as %p (is synthetic: %s)",
- GetName().AsCString(),
- idx,
- synth_guy.get(),
- synth_guy.get() ? (synth_guy->IsSyntheticChildrenGenerated() ? "yes" : "no") : "no");
-
- if (!synth_guy)
- return synth_guy;
-
- if (synth_guy->IsSyntheticChildrenGenerated())
- m_synthetic_children_cache.AppendObject(synth_guy);
- m_children_byindex.SetValueForKey(idx, synth_guy.get());
- synth_guy->SetPreferredDisplayLanguageIfNeeded(GetPreferredDisplayLanguage());
- return synth_guy;
- }
- else
- {
- if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu not cached and cannot be created (can_create = %s, synth_filter = %p)",
- GetName().AsCString(),
- idx,
- can_create ? "yes" : "no",
- m_synth_filter_ap.get());
-
- return lldb::ValueObjectSP();
- }
- }
- else
- {
- if (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu cached as %p",
- GetName().AsCString(),
- idx,
- valobj);
-
- return valobj->GetSP();
- }
-}
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, type changed "
+ "from %s to %s, recomputing synthetic filter",
+ GetName().AsCString(), m_parent_type_name.AsCString(),
+ new_parent_type_name.AsCString());
+ m_parent_type_name = new_parent_type_name;
+ CreateSynthFilter();
+ }
-lldb::ValueObjectSP
-ValueObjectSynthetic::GetChildMemberWithName (const ConstString &name, bool can_create)
-{
- UpdateValueIfNeeded();
+ // let our backend do its update
+ if (m_synth_filter_ap->Update() == false) {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
+ "filter said caches are stale - clearing",
+ GetName().AsCString());
+ // filter said that cached values are stale
+ m_children_byindex.Clear();
+ m_name_toindex.Clear();
+ // usually, an object's value can change but this does not alter its
+ // children count
+ // for a synthetic VO that might indeed happen, so we need to tell the upper
+ // echelons
+ // that they need to come back to us asking for children
+ m_children_count_valid = false;
+ m_synthetic_children_cache.Clear();
+ m_synthetic_children_count = UINT32_MAX;
+ m_might_have_children = eLazyBoolCalculate;
+ } else {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
+ "filter said caches are still valid",
+ GetName().AsCString());
+ }
- uint32_t index = GetIndexOfChildWithName(name);
-
- if (index == UINT32_MAX)
- return lldb::ValueObjectSP();
-
- return GetChildAtIndex(index, can_create);
+ m_provides_value = eLazyBoolCalculate;
+
+ lldb::ValueObjectSP synth_val(m_synth_filter_ap->GetSyntheticValue());
+
+ if (synth_val && synth_val->CanProvideValue()) {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
+ "filter said it can provide a value",
+ GetName().AsCString());
+
+ m_provides_value = eLazyBoolYes;
+ CopyValueData(synth_val.get());
+ } else {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic "
+ "filter said it will not provide a value",
+ GetName().AsCString());
+
+ m_provides_value = eLazyBoolNo;
+ CopyValueData(m_parent);
+ }
+
+ SetValueIsValid(true);
+ return true;
}
-size_t
-ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
-{
- UpdateValueIfNeeded();
-
- 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() != nullptr)
- {
- uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName (name);
- if (index == UINT32_MAX)
- return index;
- m_name_toindex.SetValueForKey(name.GetCString(), index);
- return index;
+lldb::ValueObjectSP ValueObjectSynthetic::GetChildAtIndex(size_t idx,
+ bool can_create) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
+
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, retrieving "
+ "child at index %zu",
+ GetName().AsCString(), idx);
+
+ UpdateValueIfNeeded();
+
+ ValueObject *valobj;
+ if (m_children_byindex.GetValueForKey(idx, valobj) == false) {
+ if (can_create && m_synth_filter_ap.get() != nullptr) {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
+ "index %zu not cached and will be created",
+ GetName().AsCString(), idx);
+
+ lldb::ValueObjectSP synth_guy = m_synth_filter_ap->GetChildAtIndex(idx);
+
+ if (log)
+ log->Printf(
+ "[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index "
+ "%zu created as %p (is "
+ "synthetic: %s)",
+ GetName().AsCString(), idx, static_cast<void *>(synth_guy.get()),
+ synth_guy.get()
+ ? (synth_guy->IsSyntheticChildrenGenerated() ? "yes" : "no")
+ : "no");
+
+ if (!synth_guy)
+ return synth_guy;
+
+ if (synth_guy->IsSyntheticChildrenGenerated())
+ m_synthetic_children_cache.AppendObject(synth_guy);
+ m_children_byindex.SetValueForKey(idx, synth_guy.get());
+ synth_guy->SetPreferredDisplayLanguageIfNeeded(
+ GetPreferredDisplayLanguage());
+ return synth_guy;
+ } else {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
+ "index %zu not cached and cannot "
+ "be created (can_create = %s, synth_filter = %p)",
+ GetName().AsCString(), idx, can_create ? "yes" : "no",
+ static_cast<void *>(m_synth_filter_ap.get()));
+
+ return lldb::ValueObjectSP();
}
- else if (!did_find && m_synth_filter_ap.get() == nullptr)
- return UINT32_MAX;
- else /*if (iter != m_name_toindex.end())*/
- return found_index;
-}
+ } else {
+ if (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
+ "index %zu cached as %p",
+ GetName().AsCString(), idx, static_cast<void *>(valobj));
-bool
-ValueObjectSynthetic::IsInScope ()
-{
- return m_parent->IsInScope();
+ return valobj->GetSP();
+ }
}
lldb::ValueObjectSP
-ValueObjectSynthetic::GetNonSyntheticValue ()
-{
- return m_parent->GetSP();
+ValueObjectSynthetic::GetChildMemberWithName(const ConstString &name,
+ bool can_create) {
+ UpdateValueIfNeeded();
+
+ uint32_t index = GetIndexOfChildWithName(name);
+
+ if (index == UINT32_MAX)
+ return lldb::ValueObjectSP();
+
+ return GetChildAtIndex(index, can_create);
+}
+
+size_t ValueObjectSynthetic::GetIndexOfChildWithName(const ConstString &name) {
+ UpdateValueIfNeeded();
+
+ 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() != nullptr) {
+ uint32_t index = m_synth_filter_ap->GetIndexOfChildWithName(name);
+ if (index == UINT32_MAX)
+ return index;
+ m_name_toindex.SetValueForKey(name.GetCString(), index);
+ return index;
+ } else if (!did_find && m_synth_filter_ap.get() == nullptr)
+ return UINT32_MAX;
+ else /*if (iter != m_name_toindex.end())*/
+ return found_index;
}
-void
-ValueObjectSynthetic::CopyValueData (ValueObject *source)
-{
- m_value = (source->UpdateValueIfNeeded(), source->GetValue());
- ExecutionContext exe_ctx (GetExecutionContextRef());
- m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
+bool ValueObjectSynthetic::IsInScope() { return m_parent->IsInScope(); }
+
+lldb::ValueObjectSP ValueObjectSynthetic::GetNonSyntheticValue() {
+ return m_parent->GetSP();
}
-bool
-ValueObjectSynthetic::CanProvideValue ()
-{
- if (!UpdateValueIfNeeded())
- return false;
- if (m_provides_value == eLazyBoolYes)
- return true;
- return m_parent->CanProvideValue();
+void ValueObjectSynthetic::CopyValueData(ValueObject *source) {
+ m_value = (source->UpdateValueIfNeeded(), source->GetValue());
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ m_error = m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
}
-bool
-ValueObjectSynthetic::SetValueFromCString (const char *value_str, Error& error)
-{
- return m_parent->SetValueFromCString(value_str, error);
+bool ValueObjectSynthetic::CanProvideValue() {
+ if (!UpdateValueIfNeeded())
+ return false;
+ if (m_provides_value == eLazyBoolYes)
+ return true;
+ return m_parent->CanProvideValue();
}
-void
-ValueObjectSynthetic::SetFormat (lldb::Format format)
-{
- if (m_parent)
- {
- m_parent->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
- m_parent->SetFormat(format);
- }
- this->ValueObject::SetFormat(format);
- this->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
+bool ValueObjectSynthetic::SetValueFromCString(const char *value_str,
+ Error &error) {
+ return m_parent->SetValueFromCString(value_str, error);
}
-void
-ValueObjectSynthetic::SetPreferredDisplayLanguage (lldb::LanguageType lang)
-{
- this->ValueObject::SetPreferredDisplayLanguage(lang);
- if (m_parent)
- m_parent->SetPreferredDisplayLanguage(lang);
+void ValueObjectSynthetic::SetFormat(lldb::Format format) {
+ if (m_parent) {
+ m_parent->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
+ m_parent->SetFormat(format);
+ }
+ this->ValueObject::SetFormat(format);
+ this->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
}
-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;
+void ValueObjectSynthetic::SetPreferredDisplayLanguage(
+ lldb::LanguageType lang) {
+ this->ValueObject::SetPreferredDisplayLanguage(lang);
+ if (m_parent)
+ m_parent->SetPreferredDisplayLanguage(lang);
}
-bool
-ValueObjectSynthetic::IsSyntheticChildrenGenerated ()
-{
+lldb::LanguageType ValueObjectSynthetic::GetPreferredDisplayLanguage() {
+ if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
if (m_parent)
- return m_parent->IsSyntheticChildrenGenerated();
- return false;
+ return m_parent->GetPreferredDisplayLanguage();
+ return lldb::eLanguageTypeUnknown;
+ } else
+ return m_preferred_display_language;
}
-void
-ValueObjectSynthetic::SetSyntheticChildrenGenerated (bool b)
-{
- if (m_parent)
- m_parent->SetSyntheticChildrenGenerated(b);
- this->ValueObject::SetSyntheticChildrenGenerated(b);
+bool ValueObjectSynthetic::IsSyntheticChildrenGenerated() {
+ if (m_parent)
+ return m_parent->IsSyntheticChildrenGenerated();
+ return false;
}
-bool
-ValueObjectSynthetic::GetDeclaration (Declaration &decl)
-{
- if (m_parent)
- return m_parent->GetDeclaration(decl);
+void ValueObjectSynthetic::SetSyntheticChildrenGenerated(bool b) {
+ if (m_parent)
+ m_parent->SetSyntheticChildrenGenerated(b);
+ this->ValueObject::SetSyntheticChildrenGenerated(b);
+}
+
+bool ValueObjectSynthetic::GetDeclaration(Declaration &decl) {
+ if (m_parent)
+ return m_parent->GetDeclaration(decl);
- return ValueObject::GetDeclaration(decl);
+ return ValueObject::GetDeclaration(decl);
}
-uint64_t
-ValueObjectSynthetic::GetLanguageFlags ()
-{
- if (m_parent)
- return m_parent->GetLanguageFlags();
- return this->ValueObject::GetLanguageFlags();
+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);
+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 a29d858d169f..f8eedc30e709 100644
--- a/source/Core/ValueObjectVariable.cpp
+++ b/source/Core/ValueObjectVariable.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "lldb/Core/ValueObjectVariable.h"
// C Includes
@@ -16,8 +15,8 @@
// Project includes
#include "lldb/Core/Module.h"
#include "lldb/Core/RegisterValue.h"
-#include "lldb/Core/ValueObjectList.h"
#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectList.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
@@ -32,422 +31,357 @@
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
-
using namespace lldb_private;
lldb::ValueObjectSP
-ValueObjectVariable::Create (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp)
-{
- return (new ValueObjectVariable (exe_scope, var_sp))->GetSP();
+ValueObjectVariable::Create(ExecutionContextScope *exe_scope,
+ const lldb::VariableSP &var_sp) {
+ return (new ValueObjectVariable(exe_scope, var_sp))->GetSP();
}
-ValueObjectVariable::ValueObjectVariable (ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp) :
- ValueObject(exe_scope),
- m_variable_sp(var_sp)
-{
- // Do not attempt to construct one of these objects with no variable!
- assert (m_variable_sp.get() != NULL);
- m_name = var_sp->GetName();
+ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope,
+ const lldb::VariableSP &var_sp)
+ : ValueObject(exe_scope), m_variable_sp(var_sp) {
+ // Do not attempt to construct one of these objects with no variable!
+ assert(m_variable_sp.get() != NULL);
+ m_name = var_sp->GetName();
}
-ValueObjectVariable::~ValueObjectVariable()
-{
-}
+ValueObjectVariable::~ValueObjectVariable() {}
-CompilerType
-ValueObjectVariable::GetCompilerTypeImpl ()
-{
- Type *var_type = m_variable_sp->GetType();
- if (var_type)
- return var_type->GetForwardCompilerType ();
- return CompilerType();
+CompilerType ValueObjectVariable::GetCompilerTypeImpl() {
+ Type *var_type = m_variable_sp->GetType();
+ if (var_type)
+ return var_type->GetForwardCompilerType();
+ return CompilerType();
}
-ConstString
-ValueObjectVariable::GetTypeName()
-{
- Type * var_type = m_variable_sp->GetType();
- if (var_type)
- return var_type->GetName();
- return ConstString();
+ConstString ValueObjectVariable::GetTypeName() {
+ Type *var_type = m_variable_sp->GetType();
+ if (var_type)
+ return var_type->GetName();
+ return ConstString();
}
-ConstString
-ValueObjectVariable::GetDisplayTypeName()
-{
- Type * var_type = m_variable_sp->GetType();
- if (var_type)
- return var_type->GetForwardCompilerType ().GetDisplayTypeName();
- return ConstString();
+ConstString ValueObjectVariable::GetDisplayTypeName() {
+ Type *var_type = m_variable_sp->GetType();
+ if (var_type)
+ return var_type->GetForwardCompilerType().GetDisplayTypeName();
+ return ConstString();
}
-ConstString
-ValueObjectVariable::GetQualifiedTypeName()
-{
- Type * var_type = m_variable_sp->GetType();
- if (var_type)
- return var_type->GetQualifiedName();
- return ConstString();
+ConstString ValueObjectVariable::GetQualifiedTypeName() {
+ Type *var_type = m_variable_sp->GetType();
+ if (var_type)
+ return var_type->GetQualifiedName();
+ return ConstString();
}
-size_t
-ValueObjectVariable::CalculateNumChildren(uint32_t max)
-{
- CompilerType type(GetCompilerType());
-
- if (!type.IsValid())
- return 0;
-
- const bool omit_empty_base_classes = true;
- auto child_count = type.GetNumChildren(omit_empty_base_classes);
- return child_count <= max ? child_count : max;
+size_t ValueObjectVariable::CalculateNumChildren(uint32_t max) {
+ CompilerType type(GetCompilerType());
+
+ if (!type.IsValid())
+ return 0;
+
+ const bool omit_empty_base_classes = true;
+ auto child_count = type.GetNumChildren(omit_empty_base_classes);
+ return child_count <= max ? child_count : max;
}
-uint64_t
-ValueObjectVariable::GetByteSize()
-{
- ExecutionContext exe_ctx(GetExecutionContextRef());
-
- CompilerType type(GetCompilerType());
-
- if (!type.IsValid())
- return 0;
-
- return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
+uint64_t ValueObjectVariable::GetByteSize() {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+
+ CompilerType type(GetCompilerType());
+
+ if (!type.IsValid())
+ return 0;
+
+ return type.GetByteSize(exe_ctx.GetBestExecutionContextScope());
}
-lldb::ValueType
-ValueObjectVariable::GetValueType() const
-{
- if (m_variable_sp)
- return m_variable_sp->GetScope();
- return lldb::eValueTypeInvalid;
+lldb::ValueType ValueObjectVariable::GetValueType() const {
+ if (m_variable_sp)
+ return m_variable_sp->GetScope();
+ return lldb::eValueTypeInvalid;
}
-bool
-ValueObjectVariable::UpdateValue ()
-{
- SetValueIsValid (false);
- m_error.Clear();
-
- Variable *variable = m_variable_sp.get();
- DWARFExpression &expr = variable->LocationExpression();
-
- if (variable->GetLocationIsConstantValueData())
- {
- // expr doesn't contain DWARF bytes, it contains the constant variable
- // value bytes themselves...
- if (expr.GetExpressionData(m_data))
- m_value.SetContext(Value::eContextTypeVariable, variable);
- else
- m_error.SetErrorString ("empty constant data");
- // constant bytes can't be edited - sorry
- m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
- }
- else
- {
- lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
- ExecutionContext exe_ctx (GetExecutionContextRef());
-
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
- }
+bool ValueObjectVariable::UpdateValue() {
+ SetValueIsValid(false);
+ m_error.Clear();
- if (expr.IsLocationList())
- {
- SymbolContext sc;
- variable->CalculateSymbolContext (&sc);
- if (sc.function)
- loclist_base_load_addr = sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (target);
- }
- Value old_value(m_value);
- if (expr.Evaluate (&exe_ctx,
- nullptr,
- nullptr,
- nullptr,
- loclist_base_load_addr,
- nullptr,
- nullptr,
- m_value,
- &m_error))
- {
- m_resolved_value = m_value;
- m_value.SetContext(Value::eContextTypeVariable, variable);
-
- 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 = compiler_type.GetTypeInfo();
- const bool is_pointer_or_ref = (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
-
- switch (value_type)
- {
- case Value::eValueTypeFileAddress:
- // If this type is a pointer, then its children will be considered load addresses
- // if the pointer or reference is dereferenced, but only if the process is alive.
- //
- // There could be global variables like in the following code:
- // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
- // Foo g_foo1;
- // Foo g_foo2;
- // LinkedListNode g_second_node = { &g_foo2, NULL };
- // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
- //
- // When we aren't running, we should be able to look at these variables using
- // the "target variable" command. Children of the "g_first_node" always will
- // be of the same address type as the parent. But children of the "next" member of
- // LinkedListNode will become load addresses if we have a live process, or remain
- // what a file address if it what a file address.
- if (process_is_alive && is_pointer_or_ref)
- SetAddressTypeOfChildren(eAddressTypeLoad);
- else
- SetAddressTypeOfChildren(eAddressTypeFile);
- break;
- case Value::eValueTypeHostAddress:
- // Same as above for load addresses, except children of pointer or refs are always
- // load addresses. Host addresses are used to store freeze dried variables. If this
- // type is a struct, the entire struct contents will be copied into the heap of the
- // LLDB process, but we do not currrently follow any pointers.
- if (is_pointer_or_ref)
- SetAddressTypeOfChildren(eAddressTypeLoad);
- else
- SetAddressTypeOfChildren(eAddressTypeHost);
- break;
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeScalar:
- case Value::eValueTypeVector:
- SetAddressTypeOfChildren(eAddressTypeLoad);
- break;
- }
+ Variable *variable = m_variable_sp.get();
+ DWARFExpression &expr = variable->LocationExpression();
- switch (value_type)
- {
- case Value::eValueTypeVector:
- // fall through
- case Value::eValueTypeScalar:
- // The variable value is in the Scalar value inside the m_value.
- // We can point our m_data right to it.
- m_error = m_value.GetValueAsData (&exe_ctx, m_data, 0, GetModule().get());
- break;
-
- case Value::eValueTypeFileAddress:
- case Value::eValueTypeLoadAddress:
- case Value::eValueTypeHostAddress:
- // The DWARF expression result was an address in the inferior
- // process. If this variable is an aggregate type, we just need
- // the address as the main value as all child variable objects
- // will rely upon this location and add an offset and then read
- // their own values as needed. If this variable is a simple
- // type, we read all data for it into m_data.
- // Make sure this type has a value before we try and read it
-
- // If we have a file address, convert it to a load address if we can.
- if (value_type == Value::eValueTypeFileAddress && process_is_alive)
- {
- lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- if (file_addr != LLDB_INVALID_ADDRESS)
- {
- SymbolContext var_sc;
- variable->CalculateSymbolContext(&var_sc);
- if (var_sc.module_sp)
- {
- ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
- if (objfile)
- {
- Address so_addr(file_addr, objfile->GetSectionList());
- lldb::addr_t load_addr = so_addr.GetLoadAddress (target);
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- m_value.SetValueType(Value::eValueTypeLoadAddress);
- m_value.GetScalar() = load_addr;
- }
- }
- }
- }
- }
+ if (variable->GetLocationIsConstantValueData()) {
+ // expr doesn't contain DWARF bytes, it contains the constant variable
+ // value bytes themselves...
+ if (expr.GetExpressionData(m_data))
+ m_value.SetContext(Value::eContextTypeVariable, variable);
+ else
+ m_error.SetErrorString("empty constant data");
+ // constant bytes can't be edited - sorry
+ m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
+ } else {
+ lldb::addr_t loclist_base_load_addr = LLDB_INVALID_ADDRESS;
+ ExecutionContext exe_ctx(GetExecutionContextRef());
- if (!CanProvideValue())
- {
- // this value object represents an aggregate type whose
- // children have values, but this object does not. So we
- // say we are changed if our location has changed.
- SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
- }
- else
- {
- // Copy the Value and set the context to use our Variable
- // so it can extract read its value into m_data appropriately
- Value value(m_value);
- value.SetContext(Value::eContextTypeVariable, variable);
- m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
-
- SetValueDidChange (value_type != old_value.GetValueType() || m_value.GetScalar() != old_value.GetScalar());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ }
+
+ if (expr.IsLocationList()) {
+ SymbolContext sc;
+ variable->CalculateSymbolContext(&sc);
+ if (sc.function)
+ loclist_base_load_addr =
+ sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress(
+ target);
+ }
+ Value old_value(m_value);
+ if (expr.Evaluate(&exe_ctx, nullptr, nullptr, nullptr,
+ loclist_base_load_addr, nullptr, nullptr, m_value,
+ &m_error)) {
+ m_resolved_value = m_value;
+ m_value.SetContext(Value::eContextTypeVariable, variable);
+
+ 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 = compiler_type.GetTypeInfo();
+ const bool is_pointer_or_ref =
+ (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0;
+
+ switch (value_type) {
+ case Value::eValueTypeFileAddress:
+ // If this type is a pointer, then its children will be considered load
+ // addresses
+ // if the pointer or reference is dereferenced, but only if the process
+ // is alive.
+ //
+ // There could be global variables like in the following code:
+ // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
+ // Foo g_foo1;
+ // Foo g_foo2;
+ // LinkedListNode g_second_node = { &g_foo2, NULL };
+ // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
+ //
+ // When we aren't running, we should be able to look at these variables
+ // using
+ // the "target variable" command. Children of the "g_first_node" always
+ // will
+ // be of the same address type as the parent. But children of the "next"
+ // member of
+ // LinkedListNode will become load addresses if we have a live process,
+ // or remain
+ // what a file address if it what a file address.
+ if (process_is_alive && is_pointer_or_ref)
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ else
+ SetAddressTypeOfChildren(eAddressTypeFile);
+ break;
+ case Value::eValueTypeHostAddress:
+ // Same as above for load addresses, except children of pointer or refs
+ // are always
+ // load addresses. Host addresses are used to store freeze dried
+ // variables. If this
+ // type is a struct, the entire struct contents will be copied into the
+ // heap of the
+ // LLDB process, but we do not currrently follow any pointers.
+ if (is_pointer_or_ref)
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ else
+ SetAddressTypeOfChildren(eAddressTypeHost);
+ break;
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeScalar:
+ case Value::eValueTypeVector:
+ SetAddressTypeOfChildren(eAddressTypeLoad);
+ break;
+ }
+
+ switch (value_type) {
+ case Value::eValueTypeVector:
+ // fall through
+ case Value::eValueTypeScalar:
+ // The variable value is in the Scalar value inside the m_value.
+ // We can point our m_data right to it.
+ m_error =
+ m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+ break;
+
+ case Value::eValueTypeFileAddress:
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeHostAddress:
+ // The DWARF expression result was an address in the inferior
+ // process. If this variable is an aggregate type, we just need
+ // the address as the main value as all child variable objects
+ // will rely upon this location and add an offset and then read
+ // their own values as needed. If this variable is a simple
+ // type, we read all data for it into m_data.
+ // Make sure this type has a value before we try and read it
+
+ // If we have a file address, convert it to a load address if we can.
+ if (value_type == Value::eValueTypeFileAddress && process_is_alive) {
+ lldb::addr_t file_addr =
+ m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ if (file_addr != LLDB_INVALID_ADDRESS) {
+ SymbolContext var_sc;
+ variable->CalculateSymbolContext(&var_sc);
+ if (var_sc.module_sp) {
+ ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
+ if (objfile) {
+ Address so_addr(file_addr, objfile->GetSectionList());
+ lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ m_value.SetValueType(Value::eValueTypeLoadAddress);
+ m_value.GetScalar() = load_addr;
}
- break;
+ }
}
-
- SetValueIsValid (m_error.Success());
+ }
}
- else
- {
- // could not find location, won't allow editing
- m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
+
+ if (!CanProvideValue()) {
+ // this value object represents an aggregate type whose
+ // children have values, but this object does not. So we
+ // say we are changed if our location has changed.
+ SetValueDidChange(value_type != old_value.GetValueType() ||
+ m_value.GetScalar() != old_value.GetScalar());
+ } else {
+ // Copy the Value and set the context to use our Variable
+ // so it can extract read its value into m_data appropriately
+ Value value(m_value);
+ value.SetContext(Value::eContextTypeVariable, variable);
+ m_error =
+ value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
+
+ SetValueDidChange(value_type != old_value.GetValueType() ||
+ m_value.GetScalar() != old_value.GetScalar());
}
+ break;
+ }
+
+ SetValueIsValid(m_error.Success());
+ } else {
+ // could not find location, won't allow editing
+ m_resolved_value.SetContext(Value::eContextTypeInvalid, NULL);
}
- return m_error.Success();
+ }
+ return m_error.Success();
}
-
-
-bool
-ValueObjectVariable::IsInScope ()
-{
- const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
- if (exe_ctx_ref.HasFrameRef())
- {
- ExecutionContext exe_ctx (exe_ctx_ref);
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame)
- {
- return m_variable_sp->IsInScope (frame);
- }
- else
- {
- // This ValueObject had a frame at one time, but now we
- // can't locate it, so return false since we probably aren't
- // in scope.
- return false;
- }
+bool ValueObjectVariable::IsInScope() {
+ const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef();
+ if (exe_ctx_ref.HasFrameRef()) {
+ ExecutionContext exe_ctx(exe_ctx_ref);
+ StackFrame *frame = exe_ctx.GetFramePtr();
+ if (frame) {
+ return m_variable_sp->IsInScope(frame);
+ } else {
+ // This ValueObject had a frame at one time, but now we
+ // can't locate it, so return false since we probably aren't
+ // in scope.
+ return false;
}
- // We have a variable that wasn't tied to a frame, which
- // means it is a global and is always in scope.
- return true;
-
+ }
+ // We have a variable that wasn't tied to a frame, which
+ // means it is a global and is always in scope.
+ return true;
}
-lldb::ModuleSP
-ValueObjectVariable::GetModule()
-{
- if (m_variable_sp)
- {
- SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
- if (sc_scope)
- {
- return sc_scope->CalculateSymbolContextModule();
- }
+lldb::ModuleSP ValueObjectVariable::GetModule() {
+ if (m_variable_sp) {
+ SymbolContextScope *sc_scope = m_variable_sp->GetSymbolContextScope();
+ if (sc_scope) {
+ return sc_scope->CalculateSymbolContextModule();
}
- return lldb::ModuleSP();
+ }
+ return lldb::ModuleSP();
}
-SymbolContextScope *
-ValueObjectVariable::GetSymbolContextScope()
-{
- if (m_variable_sp)
- return m_variable_sp->GetSymbolContextScope();
- return NULL;
+SymbolContextScope *ValueObjectVariable::GetSymbolContextScope() {
+ if (m_variable_sp)
+ return m_variable_sp->GetSymbolContextScope();
+ return NULL;
}
-bool
-ValueObjectVariable::GetDeclaration (Declaration &decl)
-{
- if (m_variable_sp)
- {
- decl = m_variable_sp->GetDeclaration();
- return true;
- }
- return false;
+bool ValueObjectVariable::GetDeclaration(Declaration &decl) {
+ if (m_variable_sp) {
+ decl = m_variable_sp->GetDeclaration();
+ return true;
+ }
+ return false;
}
-const char *
-ValueObjectVariable::GetLocationAsCString ()
-{
- if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
- return GetLocationAsCStringImpl(m_resolved_value,
- m_data);
- else
- return ValueObject::GetLocationAsCString();
+const char *ValueObjectVariable::GetLocationAsCString() {
+ if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
+ return GetLocationAsCStringImpl(m_resolved_value, m_data);
+ else
+ return ValueObject::GetLocationAsCString();
}
-bool
-ValueObjectVariable::SetValueFromCString (const char *value_str, Error& error)
-{
- if (!UpdateValueIfNeeded())
- {
- error.SetErrorString("unable to update value before writing");
- return false;
+bool ValueObjectVariable::SetValueFromCString(const char *value_str,
+ Error &error) {
+ if (!UpdateValueIfNeeded()) {
+ error.SetErrorString("unable to update value before writing");
+ return false;
+ }
+
+ if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) {
+ RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
+ RegisterValue reg_value;
+ if (!reg_info || !reg_ctx) {
+ error.SetErrorString("unable to retrieve register info");
+ return false;
}
-
- if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
- {
- RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
- ExecutionContext exe_ctx(GetExecutionContextRef());
- RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
- RegisterValue reg_value;
- if (!reg_info || !reg_ctx)
- {
- error.SetErrorString("unable to retrieve register info");
- return false;
- }
- error = reg_value.SetValueFromCString(reg_info, value_str);
- if (error.Fail())
- return false;
- if (reg_ctx->WriteRegister (reg_info, reg_value))
- {
- SetNeedsUpdate();
- return true;
- }
- else
- {
- error.SetErrorString("unable to write back to register");
- return false;
- }
+ error = reg_value.SetValueFromString(reg_info, llvm::StringRef(value_str));
+ if (error.Fail())
+ return false;
+ if (reg_ctx->WriteRegister(reg_info, reg_value)) {
+ SetNeedsUpdate();
+ return true;
+ } else {
+ error.SetErrorString("unable to write back to register");
+ return false;
}
- else
- return ValueObject::SetValueFromCString(value_str, error);
+ } else
+ return ValueObject::SetValueFromCString(value_str, error);
}
-bool
-ValueObjectVariable::SetData (DataExtractor &data, Error &error)
-{
- if (!UpdateValueIfNeeded())
- {
- error.SetErrorString("unable to update value before writing");
- return false;
+bool ValueObjectVariable::SetData(DataExtractor &data, Error &error) {
+ if (!UpdateValueIfNeeded()) {
+ error.SetErrorString("unable to update value before writing");
+ return false;
+ }
+
+ if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo) {
+ RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
+ RegisterValue reg_value;
+ if (!reg_info || !reg_ctx) {
+ error.SetErrorString("unable to retrieve register info");
+ return false;
}
-
- if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
- {
- RegisterInfo *reg_info = m_resolved_value.GetRegisterInfo();
- ExecutionContext exe_ctx(GetExecutionContextRef());
- RegisterContext *reg_ctx = exe_ctx.GetRegisterContext();
- RegisterValue reg_value;
- if (!reg_info || !reg_ctx)
- {
- error.SetErrorString("unable to retrieve register info");
- return false;
- }
- error = reg_value.SetValueFromData(reg_info, data, 0, true);
- if (error.Fail())
- return false;
- if (reg_ctx->WriteRegister (reg_info, reg_value))
- {
- SetNeedsUpdate();
- return true;
- }
- else
- {
- error.SetErrorString("unable to write back to register");
- return false;
- }
+ error = reg_value.SetValueFromData(reg_info, data, 0, true);
+ if (error.Fail())
+ return false;
+ if (reg_ctx->WriteRegister(reg_info, reg_value)) {
+ SetNeedsUpdate();
+ return true;
+ } else {
+ error.SetErrorString("unable to write back to register");
+ return false;
}
- else
- return ValueObject::SetData(data, error);
+ } else
+ return ValueObject::SetData(data, error);
}