*** This commit represents a complete reformatting of the LLDB source code
*** to conform to clang-format’s LLVM style. This kind of mass change has
*** two obvious implications:
Firstly, merging this particular commit into a downstream fork may be a huge
effort. Alternatively, it may be worth merging all changes up to this commit,
performing the same reformatting operation locally, and then discarding the
merge for this particular commit. The commands used to accomplish this
reformatting were as follows (with current working directory as the root of
the repository):
find . \( -iname "*.c" -or -iname "*.cpp" -or -iname "*.h" -or -iname "*.mm" \) -exec clang-format -i {} +
find . -iname "*.py" -exec autopep8 --in-place --aggressive --aggressive {} + ;
The version of clang-format used was 3.9.0, and autopep8 was 1.2.4.
Secondly, “blame” style tools will generally point to this commit instead of
a meaningful prior commit. There are alternatives available that will attempt
to look through this change and find the appropriate prior commit. YMMV.
llvm-svn: 280751
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index 2ef5bbe..6933aba 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/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;
+
+ 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;
+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) {
+ byte_order = target_sp->GetArchitecture().GetByteOrder();
+ addr_size = target_sp->GetArchitecture().GetAddressByteSize();
+ }
- 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();
- }
+ 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;
+ }
+ return byte_order != eByteOrderInvalid && addr_size != 0;
}
-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;
+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;
+ 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;
+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());
+ 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;
- }
-
- // 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);
+ assert(module_sp);
+ if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
return true;
}
- 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);
+ return true;
+ }
+ return false;
}
-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);
+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);
+ 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
+ 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;
- }
+ return true;
}
- return false;
+ }
+ 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
+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;
+ // 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
+ 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
+ 0); // bitfield bit offset
- total_len += bytes_read;
+ total_len += bytes_read;
- if (len < k_buf_len)
- break;
- curr_address.SetOffset (curr_address.GetOffset() + 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
}
- strm->PutChar ('"');
- return total_len;
+ }
+ m_offset = file_addr;
+ return false; // Failed to resolve this address to a section offset value
}
-Address::Address (lldb::addr_t abs_addr) :
- m_section_wp (),
- m_offset (abs_addr)
-{
+ModuleSP Address::GetModule() const {
+ lldb::ModuleSP module_sp;
+ SectionSP section_sp(GetSection());
+ if (section_sp)
+ module_sp = section_sp->GetModule();
+ return module_sp;
}
-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;
+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;
}
- return *this;
+ // 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;
}
-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
-}
+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);
-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;
- }
+ 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;
+ 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;
- }
- // No section, we just return the offset since it is the value in this case
- return m_offset;
-}
-
-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.
+ } 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;
-
- 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;
- }
+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 (code_addr == LLDB_INVALID_ADDRESS)
- return code_addr;
-
+ } else {
+ code_addr = GetLoadAddress(target);
+ }
+
+ if (code_addr == LLDB_INVALID_ADDRESS)
+ return code_addr;
+
+ if (target)
+ return target->GetCallableLoadAddress(code_addr, GetAddressClass());
+ return code_addr;
+}
+
+bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) {
+ if (SetLoadAddress(load_addr, target)) {
if (target)
- return target->GetCallableLoadAddress (code_addr, GetAddressClass());
- 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;
-}
-
-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::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);
- }
- 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;
- }
- }
- }
- }
- }
- 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))
- {
-#if VERBOSE_OUTPUT
- 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;
-#if VERBOSE_OUTPUT
- s->PutCString ("(objc_msgref *) -> { (func*)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
-#else
- 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))
- {
-#if VERBOSE_OUTPUT
- s->PutCString("), (char *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(" (");
-#else
- s->PutCString(", ");
-#endif
- ReadCStringFromMemory (exe_scope, so_addr, s);
- }
-#if VERBOSE_OUTPUT
- s->PutCString(") }");
-#else
- 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))
- {
-#if VERBOSE_OUTPUT
- s->PutCString("(CFString *) ");
- cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(" -> @");
-#else
- 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 (!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;
- }
- 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();
- }
- }
- }
- }
- }
- 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 (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
- }
- break;
- }
-
+ m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
return true;
+ }
+ return false;
}
-bool
-Address::SectionWasDeleted() const
-{
- if (GetSection())
- return false;
- return SectionWasDeletedPrivate();
+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::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);
- }
+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 0;
+ return true;
+ }
+ return false;
}
-ModuleSP
-Address::CalculateSymbolContextModule () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- return section_sp->GetModule();
- return ModuleSP();
-}
+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;
-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;
-}
+ 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);
+ }
-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();
+ Address so_addr;
+ switch (style) {
+ case DumpStyleInvalid:
return false;
+
+ 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;
+ }
+ }
+ }
+ }
+ }
+ 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)) {
+#if VERBOSE_OUTPUT
+ 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;
+#if VERBOSE_OUTPUT
+ s->PutCString("(objc_msgref *) -> { (func*)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+#else
+ 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)) {
+#if VERBOSE_OUTPUT
+ s->PutCString("), (char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(" (");
+#else
+ s->PutCString(", ");
+#endif
+ ReadCStringFromMemory(exe_scope, so_addr, s);
+ }
+#if VERBOSE_OUTPUT
+ s->PutCString(") }");
+#else
+ 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)) {
+#if VERBOSE_OUTPUT
+ s->PutCString("(CFString *) ");
+ cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(" -> @");
+#else
+ 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 (!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;
+ }
+ 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();
+ }
+ }
+ }
+ }
+ } 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 (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ } break;
+ }
+
+ return true;
}
-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;
+bool Address::SectionWasDeleted() const {
+ if (GetSection())
+ return false;
+ return SectionWasDeletedPrivate();
}
-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;
+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);
}
-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;
+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;
}
-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);
+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/lldb/source/Core/AddressRange.cpp b/lldb/source/Core/AddressRange.cpp
index 072c245..e03d721 100644
--- a/lldb/source/Core/AddressRange.cpp
+++ b/lldb/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 §ion, addr_t offset, addr_t byte_size) :
- m_base_addr(section, offset),
- m_byte_size(byte_size)
-{
-}
+AddressRange::AddressRange(const lldb::SectionSP §ion, 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;
-
- 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();
-
+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 (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;
-
- if (file_base_addr <= file_addr)
- return (file_addr - file_base_addr) < GetByteSize();
-
+ 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();
+
+ 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;
-
- if (load_base_addr <= load_addr)
- return (load_addr - load_base_addr) < GetByteSize();
-
+bool AddressRange::ContainsFileAddress(addr_t file_addr) const {
+ if (file_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;
-
- if (load_base_addr <= load_addr)
- return (load_addr - load_base_addr) < GetByteSize();
-
+ 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();
+
+ return false;
}
-void
-AddressRange::Clear()
-{
- m_base_addr.Clear();
- m_byte_size = 0;
+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;
+
+ if (load_base_addr <= load_addr)
+ return (load_addr - load_base_addr) < GetByteSize();
+
+ return false;
}
-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 AddressRange::ContainsLoadAddress(addr_t load_addr, Target *target) const {
+ if (load_addr == LLDB_INVALID_ADDRESS)
+ return false;
- 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;
+ addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);
+ if (load_base_addr == LLDB_INVALID_ADDRESS)
+ return false;
- case Address::DumpStyleModuleWithFileAddress:
- show_module = true;
- LLVM_FALLTHROUGH;
- case Address::DumpStyleFileAddress:
- vmaddr = m_base_addr.GetFileAddress();
- break;
+ if (load_base_addr <= load_addr)
+ return (load_addr - load_base_addr) < GetByteSize();
- case Address::DumpStyleLoadAddress:
- vmaddr = m_base_addr.GetLoadAddress(target);
- break;
+ return false;
+}
+
+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;
+ }
+
+ 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/lldb/source/Core/AddressResolver.cpp b/lldb/source/Core/AddressResolver.cpp
index aa45701..40f4d55 100644
--- a/lldb/source/Core/AddressResolver.cpp
+++ b/lldb/source/Core/AddressResolver.cpp
@@ -9,7 +9,6 @@
#include "lldb/Core/AddressResolver.h"
-
// Project includes
#include "lldb/Core/Address.h"
@@ -26,41 +25,27 @@
//----------------------------------------------------------------------
// AddressResolver:
//----------------------------------------------------------------------
-AddressResolver::AddressResolver ()
-{
+AddressResolver::AddressResolver() {}
+
+AddressResolver::~AddressResolver() {}
+
+void AddressResolver::ResolveAddressInModules(SearchFilter &filter,
+ ModuleList &modules) {
+ filter.SearchInModuleList(*this, modules);
}
-AddressResolver::~AddressResolver ()
-{
-
+void AddressResolver::ResolveAddress(SearchFilter &filter) {
+ filter.Search(*this);
}
-void
-AddressResolver::ResolveAddressInModules (SearchFilter &filter, ModuleList &modules)
-{
- filter.SearchInModuleList(*this, modules);
+std::vector<AddressRange> &AddressResolver::GetAddressRanges() {
+ return m_address_ranges;
}
-void
-AddressResolver::ResolveAddress (SearchFilter &filter)
-{
- filter.Search (*this);
+size_t AddressResolver::GetNumberOfAddresses() {
+ return m_address_ranges.size();
}
-std::vector<AddressRange> &
-AddressResolver::GetAddressRanges ()
-{
- return m_address_ranges;
-}
-
-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/lldb/source/Core/AddressResolverFileLine.cpp b/lldb/source/Core/AddressResolverFileLine.cpp
index e45076e..939cf45 100644
--- a/lldb/source/Core/AddressResolverFileLine.cpp
+++ b/lldb/source/Core/AddressResolverFileLine.cpp
@@ -21,81 +21,58 @@
//----------------------------------------------------------------------
// 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/lldb/source/Core/AddressResolverName.cpp b/lldb/source/Core/AddressResolverName.cpp
index dacc7d7..a2a45e6 100644
--- a/lldb/source/Core/AddressResolverName.cpp
+++ b/lldb/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));
+ 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());
- }
+ 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;
+ SymbolContext &context, Address *addr,
+ bool containing) {
+ SymbolContextList func_list;
+ SymbolContextList sym_list;
- bool skip_prologue = true;
- uint32_t i;
- SymbolContext sc;
- Address func_addr;
+ bool skip_prologue = true;
+ uint32_t i;
+ SymbolContext sc;
+ Address func_addr;
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+ 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;
+ 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);
}
+ break;
- 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::Glob:
- if (log)
- log->Warning ("glob is not supported yet.");
- 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;
- // 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;
+ case AddressResolver::Glob:
+ if (log)
+ log->Warning("glob is not supported yet.");
+ break;
+ }
- 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
- }
- }
- }
+ // 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;
- j++;
+ 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
}
+ }
}
- 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);
- }
- }
- }
- }
+ j++;
+ }
}
- 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);
- }
+ 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);
+ }
}
+ }
}
- return Searcher::eCallbackReturnContinue;
+ }
+
+ 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);
+ }
+ }
+ }
+ }
+ 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());
+ else
+ s->Printf("'%s'", m_func_name.AsCString());
}
diff --git a/lldb/source/Core/ArchSpec.cpp b/lldb/source/Core/ArchSpec.cpp
index 24aba81..285e30e 100644
--- a/lldb/source/Core/ArchSpec.cpp
+++ b/lldb/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" },
-
+ {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" },
+ {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"},
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },
- { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" },
+ {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"},
- { 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" },
+ {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"},
- { 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" },
+ {eByteOrderBig, 8, 2, 6, llvm::Triple::systemz,
+ ArchSpec::eCore_s390x_generic, "s390x"},
- { 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" },
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc,
+ ArchSpec::eCore_sparc_generic, "sparc"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9,
+ ArchSpec::eCore_sparc9_generic, "sparcv9"},
- { 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" }
-};
+ {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"},
-// Ensure that we have an entry in the g_core_definitions for each core. If you comment out an entry above,
+ {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");
+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 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(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);
}
- 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,311 @@
// 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()
+ : m_triple(), m_core(kCore_invalid), m_byte_order(eByteOrderInvalid),
+ m_flags(0), m_distribution_id() {}
+
+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) :
- 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)
+ : m_triple(), m_core(kCore_invalid), m_byte_order(eByteOrderInvalid),
+ m_flags(0), m_distribution_id() {
+ if (triple_cstr)
+ SetTriple(triple_cstr);
}
-
-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(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 llvm::Triple &triple) :
- m_triple (),
- m_core (kCore_invalid),
- m_byte_order (eByteOrderInvalid),
- m_flags (0),
- m_distribution_id ()
-{
- SetTriple(triple);
-}
-
-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(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() = default;
@@ -471,1007 +590,929 @@
//===----------------------------------------------------------------------===//
// 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::GetClangTargetCPU ()
-{
- std::string cpu;
- const llvm::Triple::ArchType machine = GetMachine();
+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;
- }
- }
- 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;
- }
- }
- 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;
- }
- }
- 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;
- }
- 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;
-
- return llvm::Triple::UnknownArch;
-}
-
-const ConstString&
-ArchSpec::GetDistributionId () const
-{
- return m_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;
- }
- return 0;
-}
-
-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()) {
+ 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:
- 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;
+ break;
}
+ }
+ return cpu;
}
-lldb::ByteOrder
-ArchSpec::GetByteOrder () const
-{
- if (m_byte_order == eByteOrderInvalid)
- return GetDefaultEndian();
- return m_byte_order;
+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;
+}
+
+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;
+}
+
+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;
+ }
+ return 1;
+}
+
+llvm::Triple::ArchType ArchSpec::GetMachine() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->machine;
+
+ return llvm::Triple::UnknownArch;
+}
+
+const ConstString &ArchSpec::GetDistributionId() const {
+ return m_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;
+ }
+ return 0;
+}
+
+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;
+ }
+}
+
+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)
- {
+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();
+}
+
+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;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+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, 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();
+ 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);
+ }
+}
+
+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;
- // 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();
- }
+ 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);
- return IsValid();
+ // 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);
+ }
+ }
+ }
+ CoreUpdated(update_triple);
+ 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;
- }
- }
- }
- }
+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;
+}
+
+bool ArchSpec::IsExactMatch(const ArchSpec &rhs) const {
+ return IsEqualTo(rhs, true);
+}
+
+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;
+
+ // 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;
+}
+
+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::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();
-}
+ const ArchSpec::Core lhs_core = GetCore();
+ const ArchSpec::Core rhs_core = rhs.GetCore();
-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);
+ const bool core_match = cores_match(lhs_core, rhs_core, true, exact_match);
- 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();
- return IsValid();
-}
+ if (core_match) {
+ const llvm::Triple &lhs_triple = GetTriple();
+ const llvm::Triple &rhs_triple = rhs.GetTriple();
-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);
- }
- }
- }
- 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::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::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;
-
- // 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;
-}
-
-bool
-ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const
-{
- // explicitly ignoring m_distribution_id in this method.
-
- if (GetByteOrder() != rhs.GetByteOrder())
+ 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;
-
- switch (core1)
- {
- case ArchSpec::kCore_any:
+ try_inverse = false;
+ if (core2 == ArchSpec::eCore_arm_armv7)
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;
-
- 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_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_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_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_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_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_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_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_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_mips32r6:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6)
- return true;
- }
- break;
-
- case ArchSpec::eCore_mips32r6el:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el)
- 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_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 (core2 == ArchSpec::eCore_arm_armv6m)
+ return true;
}
- if (try_inverse)
- return cores_match (core2, core1, false, enforce_exact_match);
- return false;
+ 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_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_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_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_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_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_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_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_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_mips32r6:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6)
+ return true;
+ }
+ break;
+
+ case ArchSpec::eCore_mips32r6el:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_mips32el ||
+ core2 == ArchSpec::eCore_mips32r6el)
+ 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_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).
+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.
+ 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();
@@ -1492,120 +1533,101 @@
}
}
#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
+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;
- }
+ 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();
+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()
- );
+ 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());
+ if (!environ_str.empty())
+ s.Printf("-%s", environ_str.str().c_str());
}
diff --git a/lldb/source/Core/Baton.cpp b/lldb/source/Core/Baton.cpp
index 8bed01b..1031e04 100644
--- a/lldb/source/Core/Baton.cpp
+++ b/lldb/source/Core/Baton.cpp
@@ -18,7 +18,4 @@
using namespace lldb;
using namespace lldb_private;
-void
-Baton::GetDescription (Stream *s, lldb::DescriptionLevel level) const
-{
-}
+void Baton::GetDescription(Stream *s, lldb::DescriptionLevel level) const {}
diff --git a/lldb/source/Core/Broadcaster.cpp b/lldb/source/Core/Broadcaster.cpp
index fb93f77..9f1ec53 100644
--- a/lldb/source/Core/Broadcaster.cpp
+++ b/lldb/source/Core/Broadcaster.cpp
@@ -13,533 +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());
+
+ Clear();
}
-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();
-}
-
-void
-Broadcaster::CheckInWithManager ()
-{
- if (m_manager_sp)
- {
- m_manager_sp->SignUpListenersForBroadcaster(*this);
- }
+void Broadcaster::CheckInWithManager() {
+ if (m_manager_sp) {
+ m_manager_sp->SignUpListenersForBroadcaster(*this);
+ }
}
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());
+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;
+ 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.
+ for (auto &pair : GetListeners())
+ pair.first->BroadcasterWillDestruct(&m_broadcaster);
+
+ m_listeners.clear();
+}
+
+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;
}
- else
- it = m_listeners.erase(it);
+ }
}
-
- return listeners;
+ }
+ return num_names_added > 0;
}
-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;
-}
-
-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;
- }
- }
- }
- }
- 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;
- for(auto &pair: GetListeners())
- {
- if (pair.first == listener_sp)
- {
- handled = true;
- pair.second |= event_mask;
- m_broadcaster.AddInitialEventsToListener (listener_sp, event_mask);
- break;
- }
+ 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);
+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;
-
- 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)
- 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);
-}
-
-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::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);
-
- const uint32_t event_type = event_sp->GetType();
-
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
-
- 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();
- }
-
- 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
- {
- for (auto &pair : GetListeners())
- {
- if (!(pair.second & event_type))
- continue;
- if (unique && pair.first->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type))
- continue;
-
- 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, 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);
-}
-
-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);
+ if (!m_hijacking_listeners.empty() && event_type & m_hijacking_masks.back())
return true;
+
+ for (auto &pair : GetListeners()) {
+ if (pair.second & event_type)
+ return true;
+ }
+ return false;
}
-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;
+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;
}
-const char *
-Broadcaster::BroadcasterImpl::GetHijackingListenerName()
-{
- if (m_hijacking_listeners.size())
- {
- return m_hijacking_listeners.back()->GetName();
- }
- else
- {
- return nullptr;
- }
+bool Broadcaster::BroadcasterImpl::RemoveListener(
+ const lldb::ListenerSP &listener_sp, uint32_t event_mask) {
+ return RemoveListener(listener_sp.get(), event_mask);
}
-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();
- }
- if (!m_hijacking_masks.empty())
- m_hijacking_masks.pop_back();
+void Broadcaster::BroadcasterImpl::BroadcastEvent(EventSP &event_sp) {
+ return PrivateBroadcastEvent(event_sp, false);
}
-ConstString &
-Broadcaster::GetBroadcasterClass() const
-{
- static ConstString class_name ("lldb.anonymous");
- return class_name;
+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;
+
+ // Update the broadcaster on this event
+ event_sp->SetBroadcaster(&m_broadcaster);
+
+ const uint32_t event_type = event_sp->GetType();
+
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ 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();
+ }
+
+ 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 {
+ for (auto &pair : GetListeners()) {
+ if (!(pair.second & event_type))
+ continue;
+ if (unique &&
+ pair.first->PeekAtNextEventForBroadcasterWithType(&m_broadcaster,
+ event_type))
+ continue;
+
+ 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, 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);
+}
+
+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);
+
+ 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;
+ }
+}
+
+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();
+ }
+ if (!m_hijacking_masks.empty())
+ m_hijacking_masks.pop_back();
+}
+
+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();
+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;
+
+BroadcasterManager::BroadcasterManager() : m_manager_mutex() {}
+
+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;
+}
+
+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;
+}
+
+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 GetBroadcasterClass() < rhs.GetBroadcasterClass();
- }
+ m_event_map.erase(iter);
+ }
}
-BroadcastEventSpec &
-BroadcastEventSpec::operator=(const BroadcastEventSpec &rhs) = default;
+void BroadcasterManager::RemoveListener(const lldb::ListenerSP &listener_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ ListenerMatches predicate(listener_sp);
-BroadcasterManager::BroadcasterManager() : m_manager_mutex()
-{
-}
+ if (m_listeners.erase(listener_sp) == 0)
+ return;
-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;
-}
-
-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;
+ 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::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::RemoveListener (const lldb::ListenerSP &listener_sp)
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
- ListenerMatches predicate (listener_sp);
+void BroadcasterManager::Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ listener_collection::iterator end_iter = m_listeners.end();
- 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::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();
+ 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/lldb/source/Core/Communication.cpp b/lldb/source/Core/Communication.cpp
index dbd0f77..a7114ce 100644
--- a/lldb/source/Core/Communication.cpp
+++ b/lldb/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,441 +26,398 @@
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);
+ 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");
+ 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();
+ 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)
+ 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;
+}
+
+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;
+}
+
+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.");
- 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::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;
- }
-
- ListenerSP listener_sp(Listener::MakeListener("Communication::Read"));
- listener_sp->StartListeningForEvents (this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
- EventSP event_sp;
- std::chrono::microseconds timeout = std::chrono::microseconds(0);
- if (timeout_usec != UINT32_MAX)
- timeout = std::chrono::microseconds(timeout_usec);
- while (listener_sp->WaitForEvent(timeout, 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;
+ status = eConnectionStatusNoConnection;
+ return 0;
}
- // 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 (error_ptr)
- error_ptr->SetErrorString("Invalid connection.");
- status = eConnectionStatusNoConnection;
- return 0;
-}
-
-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());
-
- 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;
-}
-
-bool
-Communication::StartReadThread (Error *error_ptr)
-{
- if (error_ptr)
- error_ptr->Clear();
-
- if (m_read_thread.IsJoinable())
- return true;
-
- 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());
-
- 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;
-
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::StopReadThread ()", this);
-
- m_read_thread_enabled = false;
-
- BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr);
-
- // error = m_read_thread.Cancel();
-
- Error error = m_read_thread.Join(nullptr);
- return error.Success();
-}
-
-bool
-Communication::JoinReadThread (Error *error_ptr)
-{
- if (!m_read_thread.IsJoinable())
- return true;
-
- 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();
-
- 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);
-
- 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);
- }
-}
-
-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);
-}
-
-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;
- }
- }
- 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::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);
-
- // 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();
-
- // Wait for the synchronization event.
+ ListenerSP listener_sp(Listener::MakeListener("Communication::Read"));
+ listener_sp->StartListeningForEvents(
+ this, eBroadcastBitReadThreadGotBytes | eBroadcastBitReadThreadDidExit);
EventSP event_sp;
- listener_sp->WaitForEvent(std::chrono::microseconds(0), event_sp);
+ std::chrono::microseconds timeout = std::chrono::microseconds(0);
+ if (timeout_usec != UINT32_MAX)
+ timeout = std::chrono::microseconds(timeout_usec);
+ while (listener_sp->WaitForEvent(timeout, 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;
+ }
+
+ // 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 (error_ptr)
+ error_ptr->SetErrorString("Invalid connection.");
+ status = eConnectionStatusNoConnection;
+ return 0;
}
-void
-Communication::SetConnection (Connection *connection)
-{
- Disconnect(nullptr);
- StopReadThread(nullptr);
- m_connection_sp.reset(connection);
+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());
+
+ 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;
+}
+
+bool Communication::StartReadThread(Error *error_ptr) {
+ if (error_ptr)
+ error_ptr->Clear();
+
+ if (m_read_thread.IsJoinable())
+ return true;
+
+ 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());
+
+ 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;
+
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_COMMUNICATION, "%p Communication::StopReadThread ()", this);
+
+ m_read_thread_enabled = false;
+
+ BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr);
+
+ // error = m_read_thread.Cancel();
+
+ Error error = m_read_thread.Join(nullptr);
+ return error.Success();
+}
+
+bool Communication::JoinReadThread(Error *error_ptr) {
+ if (!m_read_thread.IsJoinable())
+ return true;
+
+ 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();
+
+ 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);
+
+ 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);
+ }
+}
+
+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);
+}
+
+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;
+ }
+ }
+ 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::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);
+
+ // 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();
+
+ // Wait for the synchronization event.
+ EventSP event_sp;
+ listener_sp->WaitForEvent(std::chrono::microseconds(0), event_sp);
+}
+
+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";
- }
+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;
+ static char unknown_state_string[64];
+ snprintf(unknown_state_string, sizeof(unknown_state_string),
+ "ConnectionStatus = %i", status);
+ return unknown_state_string;
}
diff --git a/lldb/source/Core/Connection.cpp b/lldb/source/Core/Connection.cpp
index 3f740a1e..1ae046b 100644
--- a/lldb/source/Core/Connection.cpp
+++ b/lldb/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/lldb/source/Core/ConnectionMachPort.cpp b/lldb/source/Core/ConnectionMachPort.cpp
index e04c489..1fc87dc 100644
--- a/lldb/source/Core/ConnectionMachPort.cpp
+++ b/lldb/source/Core/ConnectionMachPort.cpp
@@ -23,309 +23,237 @@
using namespace lldb;
using namespace lldb_private;
-struct MessageType
-{
- mach_msg_header_t head;
- ConnectionMachPort::PayloadType payload;
+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); }
-ConnectionMachPort::ConnectionMachPort () :
- Connection(),
- m_task(mach_task_self()),
- m_port(MACH_PORT_TYPE_NONE)
-{
+bool ConnectionMachPort::IsConnected() const {
+ return 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;
- }
-
+ConnectionStatus ConnectionMachPort::Connect(const char *s, Error *error_ptr) {
+ if (IsConnected()) {
if (error_ptr)
- error_ptr->SetError (kret, eErrorTypeMachKernel);
- status = eConnectionStatusError;
- return 0;
-}
+ error_ptr->SetErrorString("already connected");
+ return eConnectionStatusError;
+ }
-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;
+ 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");
}
- status = eConnectionStatusError;
- return 0;
+ } 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;
}
-std::string
-ConnectionMachPort::GetURI()
-{
- return m_uri;
+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;
}
-ConnectionStatus
-ConnectionMachPort::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
-{
- return eConnectionStatusLostConnection;
+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;
}
-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;
+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;
}
-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;
+size_t ConnectionMachPort::Read(void *dst, size_t dst_len,
+ uint32_t timeout_usec, ConnectionStatus &status,
+ Error *error_ptr) {
+ PayloadType payload;
- return kret;
+ 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/lldb/source/Core/ConnectionSharedMemory.cpp b/lldb/source/Core/ConnectionSharedMemory.cpp
index 46948b8..74487b0 100644
--- a/lldb/source/Core/ConnectionSharedMemory.cpp
+++ b/lldb/source/Core/ConnectionSharedMemory.cpp
@@ -15,10 +15,10 @@
#ifdef _WIN32
#include "lldb/Host/windows/windows.h"
#else
+#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <fcntl.h>
#endif
// C++ Includes
@@ -26,8 +26,8 @@
#include <cstdlib>
// Other libraries and framework includes
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/MathExtras.h"
// Project includes
#include "lldb/Core/Communication.h"
@@ -37,135 +37,110 @@
using namespace lldb;
using namespace lldb_private;
-ConnectionSharedMemory::ConnectionSharedMemory () :
- Connection(),
- m_name(),
- m_fd (-1),
- m_mmap()
-{
+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;
}
-ConnectionSharedMemory::~ConnectionSharedMemory ()
-{
- Disconnect(nullptr);
+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;
}
-bool
-ConnectionSharedMemory::IsConnected () const
-{
- return m_fd >= 0;
+size_t ConnectionSharedMemory::Read(void *dst, size_t dst_len,
+ uint32_t timeout_usec,
+ ConnectionStatus &status,
+ Error *error_ptr) {
+ status = eConnectionStatusSuccess;
+ return 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;
-// }
+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("invalid connect arguments");
+ error_ptr->SetErrorString("already open");
return eConnectionStatusError;
-}
+ }
-ConnectionStatus
-ConnectionSharedMemory::Disconnect (Error *error_ptr)
-{
- m_mmap.Clear();
- if (!m_name.empty())
- {
+ m_name.assign(name);
+
#ifdef _WIN32
- close(m_fd);
- m_fd = -1;
+ 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
- shm_unlink (m_name.c_str());
+ 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
- m_name.clear();
- }
+
+ if (m_mmap.MemoryMapFromFileDescriptor(m_fd, 0, size, true, false) == size)
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;
+ Disconnect(nullptr);
+ return eConnectionStatusError;
}
#endif // __ANDROID_NDK__
diff --git a/lldb/source/Core/ConstString.cpp b/lldb/source/Core/ConstString.cpp
index f983f14..21b4d3d 100644
--- a/lldb/source/Core/ConstString.cpp
+++ b/lldb/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;
+ 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);
+ 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;
+ }
- 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;
+ 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;
+ }
- 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;
+ 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;
+ }
- 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 *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();
}
+ return nullptr;
+ }
- const char *
- GetConstCString (const char *cstr)
- {
- if (cstr != nullptr)
- return GetConstCStringWithLength (cstr, strlen (cstr));
- 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;
}
+ 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 *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;
+ }
- 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 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();
}
-
- 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;
- }
-
- 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 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 @@
// 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;
+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;
+ std::call_once(g_pool_initialization_flag,
+ []() { g_string_pool = new Pool(); });
+
+ return *g_string_pool;
}
-ConstString::ConstString (const char *cstr) :
- m_string (StringPool().GetConstCString (cstr))
-{
+ConstString::ConstString(const char *cstr)
+ : m_string(StringPool().GetConstCString(cstr)) {}
+
+ConstString::ConstString(const char *cstr, size_t cstr_len)
+ : m_string(StringPool().GetConstCStringWithLength(cstr, cstr_len)) {}
+
+ConstString::ConstString(const llvm::StringRef &s)
+ : m_string(StringPool().GetConstCStringWithLength(s.data(), s.size())) {}
+
+bool ConstString::operator<(const ConstString &rhs) const {
+ if (m_string == rhs.m_string)
+ return false;
+
+ 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;
}
-ConstString::ConstString (const char *cstr, size_t cstr_len) :
- m_string (StringPool().GetConstCStringWithLength (cstr, cstr_len))
-{
+Stream &lldb_private::operator<<(Stream &s, const ConstString &str) {
+ const char *cstr = str.GetCString();
+ if (cstr != nullptr)
+ s << cstr;
+
+ return s;
}
-ConstString::ConstString (const llvm::StringRef &s) :
- m_string (StringPool().GetConstCStringWithLength (s.data(), s.size()))
-{
+size_t ConstString::GetLength() const {
+ return StringPool().GetConstCStringLength(m_string);
}
-bool
-ConstString::operator < (const ConstString& rhs) const
-{
- if (m_string == rhs.m_string)
- return false;
+bool ConstString::Equals(const ConstString &lhs, const ConstString &rhs,
+ const bool case_sensitive) {
+ if (lhs.m_string == rhs.m_string)
+ return true;
- llvm::StringRef lhs_string_ref (m_string, StringPool().GetConstCStringLength (m_string));
- llvm::StringRef rhs_string_ref (rhs.m_string, StringPool().GetConstCStringLength (rhs.m_string));
+ // 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;
- // 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;
+ // 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);
}
-Stream&
-lldb_private::operator << (Stream& s, const ConstString& str)
-{
- const char *cstr = str.GetCString();
+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
+}
+
+void ConstString::Dump(Stream *s, const char *fail_value) const {
+ if (s != nullptr) {
+ const char *cstr = AsCString(fail_value);
if (cstr != nullptr)
- s << cstr;
-
- return s;
+ s->PutCString(cstr);
+ }
}
-size_t
-ConstString::GetLength () const
-{
- return StringPool().GetConstCStringLength (m_string);
+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));
}
-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);
+void ConstString::SetCString(const char *cstr) {
+ m_string = StringPool().GetConstCString(cstr);
}
-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
+void ConstString::SetString(const llvm::StringRef &s) {
+ m_string = StringPool().GetConstCStringWithLength(s.data(), s.size());
}
-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::SetCStringWithMangledCounterpart(const char *demangled,
+ const ConstString &mangled) {
+ m_string = StringPool().GetConstCStringAndSetMangledCounterPart(
+ demangled, mangled.m_string);
}
-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));
+bool ConstString::GetMangledCounterpart(ConstString &counterpart) const {
+ counterpart.m_string = StringPool().GetMangledCounterpart(m_string);
+ return (bool)counterpart;
}
-void
-ConstString::SetCString (const char *cstr)
-{
- m_string = StringPool().GetConstCString (cstr);
+void ConstString::SetCStringWithLength(const char *cstr, size_t cstr_len) {
+ m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len);
}
-void
-ConstString::SetString (const llvm::StringRef &s)
-{
- m_string = StringPool().GetConstCStringWithLength (s.data(), s.size());
+void ConstString::SetTrimmedCStringWithLength(const char *cstr,
+ size_t cstr_len) {
+ m_string = StringPool().GetConstTrimmedCStringWithLength(cstr, cstr_len);
}
-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;
-}
-
-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);
-}
-
-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/lldb/source/Core/CxaDemangle.cpp b/lldb/source/Core/CxaDemangle.cpp
index 4bb0af5..5c1c268 100644
--- a/lldb/source/Core/CxaDemangle.cpp
+++ b/lldb/source/Core/CxaDemangle.cpp
@@ -16,11 +16,11 @@
// - Include <cstdio> for fprintf, stderr like entities.
//----------------------------------------------------------------------
-#include "llvm/Support/Compiler.h" // LLVM_{NOEXCEPT, CONSTEXPR, ALIGNAS}
+#include "llvm/Support/Compiler.h" // LLVM_{NOEXCEPT, CONSTEXPR, ALIGNAS}
#include "lldb/Host/PosixApi.h"
#include "lldb/lldb-private.h"
-#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below
+#undef _LIBCPP_EXTERN_TEMPLATE // Avoid warning below
//===-------------------------- cxa_demangle.cpp --------------------------===//
//
@@ -34,237 +34,202 @@
#define _LIBCPP_EXTERN_TEMPLATE(...)
#define _LIBCPP_NO_EXCEPTIONS
-#include <vector>
#include <algorithm>
-#include <string>
-#include <numeric>
-#include <cstdlib>
-#include <cstring>
#include <cctype>
#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <numeric>
+#include <string>
+#include <vector>
-namespace lldb_private
-{
+namespace lldb_private {
-namespace
-{
+namespace {
-enum
-{
- unknown_error = -4,
- invalid_args = -3,
- invalid_mangled_name,
- memory_alloc_failure,
- success
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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);
+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;
+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, "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");
+ }
+ 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);
+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;
- }
- }
+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;
+ }
+ return first;
}
-template <class Float>
-struct float_data;
+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;
+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";
+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;
+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";
+const char *float_data<double>::spec = "%a";
-template <>
-struct float_data<long double>
-{
+template <> struct float_data<long double> {
#if defined(__arm__)
- static const size_t mangled_size = 16;
+ 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
+ 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;
+ static const size_t max_demangled_size = 40;
+ static const char *spec;
};
-const char* float_data<long double>::spec = "%LaL";
+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;
- }
+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);
}
- return first;
+ 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;
- }
- }
+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;
+ }
+ return first;
}
// <substitution> ::= S <seq-id> _
@@ -279,79 +244,70 @@
// <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;
- }
+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;
+ }
+ return first;
}
// <builtin-type> ::= v # void
@@ -387,587 +343,513 @@
// ::= 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;
+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("double");
- ++first;
- break;
+ db.names.push_back("decimal64");
+ first += 2;
+ 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;
+ 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;
+ }
+ 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;
- }
+const char *parse_cv_qualifiers(const char *first, const char *last,
+ unsigned &cv) {
+ cv = 0;
+ if (first != last) {
+ if (*first == 'r') {
+ cv |= 4;
+ ++first;
}
- return 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;
- }
- }
+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;
+ }
+ return first;
}
-// cc <type> <expression> # const_cast<type> (expression)
+// 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;
- }
- }
+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;
+ }
+ return first;
}
-// dc <type> <expression> # dynamic_cast<type> (expression)
+// 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;
- }
- }
+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;
+ }
+ return first;
}
-// rc <type> <expression> # reinterpret_cast<type> (expression)
+// 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;
- }
- }
+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;
+ }
+ return first;
}
-// sc <type> <expression> # static_cast<type> (expression)
+// 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;
- }
- }
+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;
+ }
+ 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;
+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;
- }
+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;
+ }
+ 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;
- }
+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;
+ }
+ return first;
}
-// sZ <template-param> # size of a parameter pack
+// 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;
- }
+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;
+ }
+ 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
+// <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;
- }
+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;
}
- 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;
+ }
+ return first;
}
-// sZ <function-param> # size of a function parameter pack
+// 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;
- }
+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;
+ }
+ 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;
- }
+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;
+ }
+ 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;
- }
+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;
+ }
+ 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;
- }
- }
+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;
+ }
+ 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;
+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>
@@ -975,615 +857,552 @@
// ::= <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;
- }
+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;
}
- 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)
- {
+ 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, "~");
+ 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;
+ }
+ 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>
+// <destructor-name> ::= <unresolved-type> # e.g.,
+// ~T or ~decltype(f())
+// ::= <simple-id> # e.g.,
+// ~A<2*N>
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;
- }
+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;
+ }
+ 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);
+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>
+// 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;
- }
- }
- }
+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;
}
- return first;
+ 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;
- }
- }
+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;
+ }
+ 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;
+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;
+ }
+ return first;
}
// [gs] nw <expression>* _ <type> E # new (expr-list) type
-// [gs] nw <expression>* _ <type> <initializer> # new (expr-list) type (init)
+// [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
+// [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;
- }
+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;
}
- 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;
+ 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();
- db.names.back() = "(" + db.names.back().move_full() + ")(" + tmp + ")";
- first = t;
+ 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;
+ }
+ 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;
- }
- }
+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;
+ }
+ return first;
}
// <ref-qualifier> ::= R # & ref-qualifier
@@ -1592,218 +1411,182 @@
// <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;
- }
+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;
+ }
+ 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;
- }
+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;
+ }
+ 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;
- }
+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 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;
}
- 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;
+ }
+ return first;
}
-// <decltype> ::= Dt <expression> E # decltype of an id-expression or class member access (C++0x)
+// <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;
- }
+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;
+ }
+ return first;
}
// extension:
@@ -1814,69 +1597,56 @@
// ::= 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;
- }
- }
+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;
- }
- }
+ }
+ } 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;
+ }
+ return first;
}
// <type> ::= <builtin-type>
@@ -1899,1026 +1669,893 @@
// 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>
+// <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;
- }
- }
+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;
}
- 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;
- }
+ if (cv & 2) {
+ db.names[k].second.insert(p, " volatile");
+ p += 9;
}
- break;
+ 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;
+ }
+ }
+ 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 # <=
+// ::= 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)
+// ::= 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 # +=
+// ::= 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
+// ::= 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;
+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;
+ }
+ 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;
+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;
}
- return 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
+// <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;
- }
- }
- }
+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;
+ }
+ }
+ 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;
+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;
- }
+ }
+ const char *p0 = pe - 1;
+ for (; p0 != pf; --p0) {
+ if (*p0 == ':') {
+ ++p0;
+ break;
}
- return String(p0, pe);
+ }
+ return String(p0, pe);
}
// <ctor-dtor-name> ::= C1 # complete object constructor
@@ -2931,209 +2568,180 @@
// 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;
- }
+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;
+ }
+ 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
+//
+// <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;
+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;
+ }
+ return first;
}
// <unqualified-name> ::= <operator-name>
// ::= <ctor-dtor-name>
-// ::= <source-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;
+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>
@@ -3141,775 +2749,743 @@
// 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;
- }
+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;
}
- return first;
+ 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;
- }
+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;
+ }
+ return first;
}
-// az <expression> # alignof (a expression)
+// 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;
- }
+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;
+ }
+ 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;
+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;
+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;
+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>
+// ::= <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)
+// ::= 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
+// ::= 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);
- }
+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;
}
- return first;
+ 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-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;
- }
+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;
+ }
+ 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));
-
+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;
}
- return first;
+ 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
-//
+// <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>
@@ -3918,262 +3494,223 @@
// ::= <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;
+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;
}
- return first;
+ 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;
- }
- }
+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;
- }
+ }
+ } else if (std::isdigit(*first)) {
+ const char *t1 = first + 1;
+ for (; t1 != last && std::isdigit(*t1); ++t1)
+ ;
+ first = t1;
}
- return first;
+ }
+ 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>
+// := 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;
- }
+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;
+ }
+ return first;
}
// <name> ::= <nested-name> // N
@@ -4185,125 +3722,102 @@
// ::= <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)
+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>
{
- case 'N':
- {
- const char* t1 = parse_nested_name(t0, last, db,
- ends_with_template_args);
- if (t1 != t0)
- first = t1;
- break;
+ 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;
}
- 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;
+ } 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;
+ }
+ }
+ 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;
- }
+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;
+ }
+ return first;
}
// <special-name> ::= TV <type> # virtual table
@@ -4316,185 +3830,161 @@
// # 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
+// ::= 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 ::= 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;
+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;
+ }
+ return first;
}
-template <class T>
-class save_value
-{
- T& restore_;
- T original_value_;
+template <class T> class save_value {
+ T &restore_;
+ T original_value_;
+
public:
- save_value(T& restore)
- : restore_(restore),
- original_value_(restore)
- {}
+ save_value(T &restore) : restore_(restore), original_value_(restore) {}
- ~save_value()
- {
- restore_ = std::move(original_value_);
- }
+ ~save_value() { restore_ = std::move(original_value_); }
- save_value(const save_value&) = delete;
- save_value& operator=(const save_value&) = delete;
+ save_value(const save_value &) = delete;
+ save_value &operator=(const save_value &) = delete;
};
// <encoding> ::= <function name> <bare-function-type>
@@ -4502,121 +3992,104 @@
// ::= <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;
+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;
+ }
+ }
+ return first;
}
// _block_invoke
@@ -4624,54 +4097,45 @@
// _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;
+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;
}
- 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;
+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
@@ -4681,333 +4145,258 @@
// ::= <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);
+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;
- }
- if (status == success && db.names.empty())
+ } 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>
-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)
-{
+void arena<N>::deallocate(char *p, std::size_t n) LLVM_NOEXCEPT {
+ if (pointer_in_buffer(p)) {
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));
+ if (p + n == ptr_)
+ ptr_ = p;
+ } else
+ std::free(p);
}
-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;
+template <class T, std::size_t N> class short_alloc {
+ arena<N> &a_;
public:
- template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};
+ typedef T value_type;
- 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;
+public:
+ template <class _Up> struct rebind { typedef short_alloc<_Up, N> other; };
- 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));
- }
+ 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;
- 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;
+ 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 U, std::size_t M> friend class short_alloc;
+ 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_;
+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);
+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
-{
+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;
+ 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 {}
+ 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();
- }
+ 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;
+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);
+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;
+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) {}
+ 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);}
+ 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;
+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)
- {}
+ template <size_t N>
+ Db(arena<N> &ar)
+ : names(ar), subs(0, names, ar), template_param(0, subs, ar) {}
};
-} // unnamed namespace
+} // 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;
+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 = internal_status;
- return buf;
+ *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
+} // lldb_private
diff --git a/lldb/source/Core/DataBufferHeap.cpp b/lldb/source/Core/DataBufferHeap.cpp
index 4e5389e..cdd37bf 100644
--- a/lldb/source/Core/DataBufferHeap.cpp
+++ b/lldb/source/Core/DataBufferHeap.cpp
@@ -19,30 +19,24 @@
//----------------------------------------------------------------------
// 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 @@
// 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/lldb/source/Core/DataBufferMemoryMap.cpp b/lldb/source/Core/DataBufferMemoryMap.cpp
index 48fe9e5..70e8a39 100644
--- a/lldb/source/Core/DataBufferMemoryMap.cpp
+++ b/lldb/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 @@
//----------------------------------------------------------------------
// 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 @@
// 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;
-
- 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);
- }
- }
+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);
}
- // We should only get here if there was an error
- Clear();
- return 0;
+ 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);
+ }
+ }
+ }
+ // 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 @@
// 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);
+ }
+ }
+#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;
+ }
- 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;
+ 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;
+
+ 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
+
+ // 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;
}
- 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;
- }
-
- 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;
-
- 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
-
- // 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());
- }
- }
+ 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/lldb/source/Core/DataEncoder.cpp b/lldb/source/Core/DataEncoder.cpp
index 3ef8295..dd6adc0 100644
--- a/lldb/source/Core/DataEncoder.cpp
+++ b/lldb/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 @@
// 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 @@
// 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 @@
// 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 @@
// 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;
+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
- }
- }
+ 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 @@
//
// 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 @@
//
// 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/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp
index 8444614..466f111 100644
--- a/lldb/source/Core/DataExtractor.cpp
+++ b/lldb/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 @@
// 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 @@
// 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);
- }
+ 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)
-{
+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 @@
// 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 @@
// 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 @@
// 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);
- }
+ // 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;
+ // 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 @@
// 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;
+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
- }
- }
+ 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 @@
//
// 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 @@
// 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 @@
//
// 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 @@
// 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 @@
//
// 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 @@
// 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 @@
//
// 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 @@
// 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 @@
//
// 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 @@
//
// 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(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;
+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;
+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;
+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;
+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;
- }
+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;
+ }
+ 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;
- }
+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 @@
//
// 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 @@
//
// 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 @@
// 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;
+ 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_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_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_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;
+ 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;
- // 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;
- }
+ default:
+ 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;
- }
+ // 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);
+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;
+ 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);
+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 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);
+ // 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;
- }
- 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;
- }
- }
+ // 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;
+ } 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;
}
//----------------------------------------------------------------------
@@ -1141,32 +1038,28 @@
// 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;
+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...
+ // 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 @@
// 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 @@
// 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 @@
//
// 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 @@
//
// 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;
- }
-
- // Sign bit of byte is 2nd high order bit (0x40)
- if (shift < size && (byte & 0x40))
- result |= - (1 << shift);
-
- *offset_ptr += bytecount;
- return result;
- }
+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;
+ }
+
+ // 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 @@
//
// 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;
+
+ 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);
- }
- result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
- return true;
+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);
}
- 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;
+ 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 false;
+ *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());
+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);
+ }
+
+ 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");
+
return offset;
-}
+ }
-static float
-half2float (uint16_t half)
-{
- union { float f; uint32_t u; } u;
- int32_t v = (int16_t) half;
+ if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) &&
+ item_byte_size > 8)
+ item_format = eFormatHex;
- 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);
- }
-
- 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);
- }
- }
+ 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);
}
- else
- s->Printf ("invalid target");
+ 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;
- if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && item_byte_size > 8)
- item_format = eFormatHex;
+ 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;
- 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 ));
+ case eFormatBytes:
+ case eFormatBytesWithASCII:
+ for (uint32_t i = 0; i < item_byte_size; ++i) {
+ s->Printf("%2.2x", GetU8(&offset));
+ }
- line_start_offset = offset;
- }
- else if (item_format != eFormatChar &&
- item_format != eFormatCharPrintable &&
- item_format != eFormatCharArray &&
- count > 0)
- {
- s->PutChar(' ');
- }
+ // 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;
- 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 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('\'');
- 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;
- }
- }
- 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 '\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('\'');
- }
- 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('\"');
- }
- }
- 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 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;
- }
- 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;
-
+ 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:
- 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);
- }
-
- 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 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_byte_size == 1)
+ s->Printf("\\x%2.2x", (uint8_t)ch);
+ else
+ s->Printf("%" PRIu64, ch);
+ break;
}
- }
+ } else {
+ s->PutChar(NON_PRINTABLE_CHAR);
+ }
- 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);
+ // 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 '\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('\'');
+ } 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('\"');
+ }
+ } 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 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;
+ } 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;
+
+ 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);
+ }
+
+ 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 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;
}
- 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 @@
// 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;
+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)));
- }
-
- 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;
- }
+ 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)));
}
- if (sstr.GetSize() > 0)
- log->Printf("%s", sstr.GetData());
+ 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;
+ }
+ }
- return offset; // Return the offset at which we ended up
+ if (sstr.GetSize() > 0)
+ log->Printf("%s", sstr.GetData());
+
+ return offset; // Return the offset at which we ended up
}
//----------------------------------------------------------------------
@@ -2133,137 +2030,114 @@
//
// 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
+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();
+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;
-
- if (rhs.GetByteSize() == 0)
- return true;
-
- if (GetByteSize() == 0)
- return (rhs.Copy(*this) > 0);
-
- size_t bytes = GetByteSize() + rhs.GetByteSize();
+bool DataExtractor::Append(DataExtractor &rhs) {
+ if (rhs.GetByteOrder() != GetByteOrder())
+ return false;
- 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 (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(), rhs.GetDataStart(), rhs.GetByteSize());
-
- SetData(buffer_sp);
-
- return true;
+
+ memcpy(bytes_ptr + GetByteSize(), buf, length);
+
+ 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());
+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());
- memcpy(bytes_ptr + GetByteSize(), buf, length);
-
- SetData(buffer_sp);
-
- return true;
-}
+ llvm::MD5 md5;
-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());
+ const llvm::ArrayRef<uint8_t> data(GetDataStart(), max_data);
+ md5.update(data);
- llvm::MD5 md5;
+ llvm::MD5::MD5Result result;
+ md5.final(result);
- const llvm::ArrayRef<uint8_t> data(GetDataStart(),max_data);
- md5.update(data);
-
- 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/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 200fa1a..835f803 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/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,7 +49,6 @@
#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"
@@ -58,8 +56,10 @@
#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;
@@ -70,1124 +70,983 @@
#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
+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_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 }
-};
+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}}}"
+#define MODULE_WITH_FUNC \
+ "{ " \
+ "${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
#define IS_OPTIMIZED "{${function.is-optimized} [opt]}"
-#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
- "{, ${frame.pc}}"\
- 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_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_FRAME_FORMAT \
+ "frame #${frame.index}: ${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}}:
+// {${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 }
-};
+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
+enum {
+ ePropertyAutoConfirm = 0,
+ ePropertyDisassemblyFormat,
+ ePropertyFrameFormat,
+ ePropertyNotiftVoid,
+ ePropertyPrompt,
+ ePropertyScriptLanguage,
+ ePropertyStopDisassemblyCount,
+ ePropertyStopDisassemblyDisplay,
+ ePropertyStopLineCountAfter,
+ ePropertyStopLineCountBefore,
+ ePropertyTerminalWidth,
+ ePropertyThreadFormat,
+ 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());
- }
- }
- }
- }
- else if (is_escape_non_printables)
- {
- DataVisualization::ForceUpdate();
- }
- }
- 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);
-}
-
-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);
-}
-
-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);
-}
-
-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())
+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);
+ 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());
+ }
+ }
+ }
+ } else if (is_escape_non_printables) {
+ DataVisualization::ForceUpdate();
+ }
+ }
+ return error;
}
-const FormatEntity::Entry *
-Debugger::GetThreadFormat() const
-{
- const uint32_t idx = ePropertyThreadFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+bool Debugger::GetAutoConfirm() const {
+ const uint32_t idx = ePropertyAutoConfirm;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-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::GetDisassemblyFormat() const {
+ const uint32_t idx = ePropertyDisassemblyFormat;
+ 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);
+const FormatEntity::Entry *Debugger::GetFrameFormat() const {
+ const uint32_t idx = ePropertyFrameFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-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::GetNotifyVoid() const {
+ const uint32_t idx = ePropertyNotiftVoid;
+ 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);
+const char *Debugger::GetPrompt() const {
+ const uint32_t idx = ePropertyPrompt;
+ return m_collection_sp->GetPropertyAtIndexAsString(
+ nullptr, idx, g_properties[idx].default_cstr_value);
}
-bool
-Debugger::GetUseExternalEditor () const
-{
- const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+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);
}
-bool
-Debugger::SetUseExternalEditor (bool b)
-{
- const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+const FormatEntity::Entry *Debugger::GetThreadFormat() const {
+ const uint32_t idx = ePropertyThreadFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::GetUseColor () const
-{
- const uint32_t idx = ePropertyUseColor;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+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);
}
-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::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
+ const uint32_t idx = ePropertyScriptLanguage;
+ return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx,
+ script_lang);
}
-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);
+uint32_t Debugger::GetTerminalWidth() const {
+ const uint32_t idx = ePropertyTerminalWidth;
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(
+ nullptr, idx, g_properties[idx].default_uint_value);
}
-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::SetTerminalWidth(uint32_t term_width) {
+ const uint32_t idx = ePropertyTerminalWidth;
+ return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
}
-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::GetUseExternalEditor() const {
+ const uint32_t idx = ePropertyUseExternalEditor;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-bool
-Debugger::GetAutoOneLineSummaries () const
-{
- const uint32_t idx = ePropertyAutoOneLineSummaries;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+bool Debugger::SetUseExternalEditor(bool b) {
+ const uint32_t idx = ePropertyUseExternalEditor;
+ 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);
+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::GetAutoIndent () const
-{
- const uint32_t idx = ePropertyAutoIndent;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+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::SetAutoIndent (bool b)
-{
- const uint32_t idx = ePropertyAutoIndent;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+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::GetPrintDecls () const
-{
- const uint32_t idx = ePropertyPrintDecls;
- 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::SetPrintDecls (bool b)
-{
- const uint32_t idx = ePropertyPrintDecls;
- 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);
}
-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::GetAutoOneLineSummaries() const {
+ const uint32_t idx = ePropertyAutoOneLineSummaries;
+ 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::GetEscapeNonPrintables() const {
+ const uint32_t idx = ePropertyEscapeNonPrintables;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+}
+
+bool Debugger::GetAutoIndent() const {
+ const uint32_t idx = ePropertyAutoIndent;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+}
+
+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;
- }
+LoadPluginCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &file_spec) {
+ Error error;
- Error plugin_load_error;
- debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
-
- return FileSpec::eEnumerateDirectoryResultNext;
+ 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;
}
- 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;
- }
-
+
+ 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);
- }
+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)
+void Debugger::Destroy(DebuggerSP &debugger_sp) {
+ if (!debugger_sp)
+ 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;
-
- 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;
+ }
+ 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;
- }
+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;
+ }
+ 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;
- }
+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;
+ }
+ 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);
+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);
- // Turn off use-color if this is a dumb terminal.
- const char *term = getenv ("TERM");
- if (term && !strcmp (term, "dumb"))
- SetUseColor (false);
+ 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();
-}
+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();
- }
- }
- 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);
-}
-
-bool
-Debugger::GetAsyncExecution ()
-{
- return !m_command_interpreter_ap->GetSynchronous();
-}
-
-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::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::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::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();
-}
-
-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::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);
- }
-}
-
-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;
- }
- }
+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();
-}
-
-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);
-}
-
-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);
-}
-
-const char *
-Debugger::GetIOHandlerCommandPrefix()
-{
- return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
-}
-
-const char *
-Debugger::GetIOHandlerHelpPrologue()
-{
- return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
-}
-
-void
-Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
-{
- PushIOHandler (reader_sp);
-
- 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;
- }
-
- while (true)
- {
- top_reader_sp = m_input_reader_stack.Top();
- if (top_reader_sp && top_reader_sp->GetIsDone())
- PopIOHandler (top_reader_sp);
- else
- break;
- }
+ 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();
+ });
}
-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();
-
- // If there is nothing, use stdin
- if (!in)
- 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)
- 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)
- err = StreamFileSP(new StreamFile(stdout, false));
- }
+bool Debugger::GetCloseInputOnEOF() const {
+ // return m_input_comm.GetCloseOnEOF();
+ return false;
}
-void
-Debugger::PushIOHandler(const IOHandlerSP &reader_sp)
-{
+void Debugger::SetCloseInputOnEOF(bool b) {
+ // m_input_comm.SetCloseOnEOF(b);
+}
+
+bool Debugger::GetAsyncExecution() {
+ return !m_command_interpreter_ap->GetSynchronous();
+}
+
+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::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::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::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();
+}
+
+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::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);
+ }
+}
+
+void Debugger::ExecuteIOHandlers() {
+ while (true) {
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
if (!reader_sp)
- return;
+ break;
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ reader_sp->Run();
- // Get the current top input reader...
- IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
+ // 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();
+}
- // Don't push the same IO handler twice...
- if (reader_sp == top_reader_sp)
- return;
+bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) {
+ return m_input_reader_stack.IsTop(reader_sp);
+}
- // Push our new input reader
- m_input_reader_stack.Push(reader_sp);
+bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type,
+ IOHandler::Type second_top_type) {
+ return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type);
+}
+
+void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
+ 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);
+}
+
+const char *Debugger::GetIOHandlerCommandPrefix() {
+ return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
+}
+
+const char *Debugger::GetIOHandlerHelpPrologue() {
+ return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
+}
+
+void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) {
+ PushIOHandler(reader_sp);
+
+ 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;
+ }
+
+ 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();
+
+ // If there is nothing, use stdin
+ if (!in)
+ 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)
+ 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)
+ err = StreamFileSP(new StreamFile(stdout, false));
+ }
+}
+
+void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) {
+ if (!reader_sp)
+ return;
+
+ 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());
+
+ // 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();
+
+ // 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;
+
+ 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;
+
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
+
+ if (pop_reader_sp != reader_sp)
+ return false;
+
+ reader_sp->Deactivate();
+ reader_sp->Cancel();
+ m_input_reader_stack.Pop();
+
+ reader_sp = m_input_reader_stack.Top();
+ if (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();
+ return true;
+}
+
+StreamSP Debugger::GetAsyncOutputStream() {
+ return StreamSP(new StreamAsynchronousIO(*this, true));
+}
+
+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;
+}
+
+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);
+ }
+
+ return 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;
+ }
}
-}
-
-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());
-
- // 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());
-
- if (pop_reader_sp != reader_sp)
- return false;
-
- reader_sp->Deactivate();
- reader_sp->Cancel();
- m_input_reader_stack.Pop();
-
- reader_sp = m_input_reader_stack.Top();
- if (reader_sp)
- reader_sp->Activate();
-
- return true;
-}
-
-StreamSP
-Debugger::GetAsyncOutputStream ()
-{
- return StreamSP (new StreamAsynchronousIO (*this, true));
-}
-
-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;
-}
-
-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);
- }
-
- return 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;
- }
- }
- }
- return debugger_sp;
+ }
+ return debugger_sp;
}
#if 0
@@ -1259,626 +1118,534 @@
}
#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;
+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;
+ 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;
}
- }
- 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;
- }
- }
+ } 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;
- }
- return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, function_changed, initial_function);
+ }
+ // 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));
+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;
+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;
- }
+ 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);
+ }
+ 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);
}
-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.
-// }
+ }
+ // 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();
+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();
+ 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;
+ 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();
- }
- 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();
+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 = (event_type == Process::eBroadcastBitStructuredData)
- ? EventDataStructuredData::GetProcessFromEvent(event_sp.get())
- : Process::ProcessEventData::GetProcessFromEvent(event_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();
+ 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);
+ 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;
+ 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);
- }
+ 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);
- }
+ // 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 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());
- }
+ // Now display and STDERR
+ if (got_stderr || got_state_changed) {
+ GetProcessSTDERR(process_sp.get(), error_stream_sp.get());
+ }
- // 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();
+ // 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().c_str());
- }
- }
- else
- {
- error_stream_sp->Printf("Failed to print structured "
- "data with plugin %s: %s",
- plugin_sp->GetPluginName()
- .AsCString(),
- error.AsCString());
- }
- }
+ // Print it.
+ output_stream_sp->PutCString(content_stream.GetString().c_str());
}
+ } else {
+ error_stream_sp->Printf("Failed to print structured "
+ "data with plugin %s: %s",
+ plugin_sp->GetPluginName().AsCString(),
+ error.AsCString());
+ }
}
-
- // 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);
- }
-
- 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();
- 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);
- }
+ // 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);
}
+
+ output_stream_sp->Flush();
+ error_stream_sp->Flush();
+
+ if (pop_process_io_handler)
+ process_sp->PopProcessIOHandler();
+ }
}
-bool
-Debugger::IsForwardingEvents ()
-{
- return (bool)m_forward_listener_sp;
+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);
+ }
+ }
}
-void
-Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
-{
- m_forward_listener_sp = listener_sp;
+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::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);
-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 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);
- 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 );
+ 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);
+ // 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(std::chrono::microseconds(0), 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();
- }
- }
- }
- }
- }
-
- if (m_forward_listener_sp)
- m_forward_listener_sp->AddEvent(event_sp);
+ bool done = false;
+ while (!done) {
+ EventSP event_sp;
+ if (listener_sp->WaitForEvent(std::chrono::microseconds(0), 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();
+ }
+ }
+ }
+ }
}
+
+ 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;
+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);
+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);
+ // 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(std::chrono::microseconds(0), event_sp);
+ // 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(std::chrono::microseconds(0), event_sp);
+ }
+ 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::JoinIOHandlerThread() {
+ if (HasIOHandlerThread()) {
+ thread_result_t result;
+ m_io_handler_thread.Join(&result);
+ m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
+ }
+}
+
+Target *Debugger::GetDummyTarget() {
+ return m_target_list.GetDummyTarget(*this).get();
+}
+
+Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
+ Target *target = nullptr;
+ if (!prefer_dummy) {
+ target = m_target_list.GetSelectedTarget().get();
+ if (target)
+ return target;
+ }
+
+ 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;
}
- 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);
- }
-}
+ Target *const target =
+ nullptr; // passing in an empty target means the REPL must create one
-lldb::thread_result_t
-Debugger::IOHandlerThread (lldb::thread_arg_t arg)
-{
- Debugger *debugger = (Debugger *)arg;
- debugger->ExecuteIOHandlers();
- debugger->StopEventHandlerThread();
- return NULL;
-}
+ REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));
-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::JoinIOHandlerThread()
-{
- if (HasIOHandlerThread())
- {
- thread_result_t result;
- m_io_handler_thread.Join(&result);
- m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
- }
-}
-
-Target *
-Debugger::GetDummyTarget()
-{
- return m_target_list.GetDummyTarget (*this).get();
-}
-
-Target *
-Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
-{
- Target *target = nullptr;
- if (!prefer_dummy)
- {
- target = m_target_list.GetSelectedTarget().get();
- if (target)
- return target;
- }
-
- 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
-
- 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/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index 2c22ee4..ba60bb9 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -45,1271 +45,1042 @@
using namespace lldb;
using namespace lldb_private;
-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);
+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));
+ DisassemblerCreateInstance create_callback = nullptr;
- if (disassembler_sp)
- return disassembler_sp;
- }
+ 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;
}
- return DisassemblerSP();
+ } 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();
}
-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,
+ 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();
+ }
}
- 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,
+ 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, 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,
+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;
+}
+
+bool Disassembler::Disassemble(Debugger &debugger, 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);
+ 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)
- {
- size_t bytes_disassembled = disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache);
- if (bytes_disassembled == 0)
- disasm_sp.reset();
- }
+ 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);
}
- return disasm_sp;
+ }
+ return false;
}
-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 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);
}
-
- 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));
+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 (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;
+ if (num_instructions > 0 && num_instructions < num_instructions_found)
+ num_instructions_found = num_instructions;
- return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, num_instructions,
- num_mixed_context_lines, options, strm);
+ 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();
+ }
+ 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.
+ 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);
+ }
}
- 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);
- }
- }
- return false;
-}
+ }
-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();
+ 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;
- TargetSP target_sp (exe_ctx.GetTargetSP());
- SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
+ prev_sc = sc;
- if (frame)
- {
- pc_addr_ptr = &frame->GetFrameCodeAddress();
- }
- const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
- const bool use_inline_block_range = false;
+ 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);
- 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;
- }
+ if (sc != prev_sc) {
+ if (offset != 0)
+ strm.EOL();
- // 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.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);
}
- sc.Clear(false);
+ }
}
+ }
+ } 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 {
+ break;
}
+ }
- 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);
- }
- }
- }
- }
- }
- 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
- {
- break;
- }
- }
-
- return true;
+ 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();
- }
-
- 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,
+ 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);
+ }
+
+ return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range,
+ num_instructions, 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(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);
+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;
- 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, ' ');
+ 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);
}
-
- 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);
+ }
+
+ 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());
+ }
+ s->Write(ss.GetData(), ss.GetSize());
+}
+
+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;
+}
+
+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;
+ }
+
+ 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();
+ }
+
+ 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(), ®ex_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;
+}
+
+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(), ®ex_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
- {
- // 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;
- }
+ } 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(), ""));
+ }
- 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());
+ 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);
}
- s->Write (ss.GetData(), ss.GetSize());
+ }
+
+ return option_value_sp;
}
-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::TestEmulation(Stream *out_stream, const char *file_name) {
+ if (!out_stream)
return false;
-}
-bool
-Instruction::HasDelaySlot ()
-{
- // Default is false.
+ if (!file_name) {
+ out_stream->Printf("Instruction::TestEmulation: Missing file_name.");
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;
- }
-
- 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();
- }
-
- 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(), ®ex_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;
-}
-
-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(), ®ex_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);
- }
- }
-
- return option_value_sp;
-}
-
-bool
-Instruction::TestEmulation (Stream *out_stream, const char *file_name)
-{
- if (!out_stream)
- return false;
-
- 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;
- }
-
- 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 (strncmp (buffer, "InstructionEmulationState={", 27) != 0)
- {
- out_stream->Printf ("Instructin::TestEmulation: Test file does not contain emulation state dictionary\n");
- fclose (test_file);
- return false;
- }
-
- // Read all the test information from the test file into an OptionValueDictionary.
-
- 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;
- }
-
- 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;
- }
-
- SetDescription (value_sp->GetStringValue());
-
- 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;
-}
-
-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);
- }
-
+ }
+ FILE *test_file = FileSystem::Fopen(file_name, "r");
+ if (!test_file) {
+ out_stream->Printf(
+ "Instruction::TestEmulation: Attempt to open test file failed.");
return false;
+ }
+
+ 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 (strncmp(buffer, "InstructionEmulationState={", 27) != 0) {
+ out_stream->Printf("Instructin::TestEmulation: Test file does not contain "
+ "emulation state dictionary\n");
+ fclose(test_file);
+ return false;
+ }
+
+ // Read all the test information from the test file into an
+ // OptionValueDictionary.
+
+ 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;
+ }
+
+ 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;
+ }
+
+ SetDescription(value_sp->GetStringValue());
+
+ 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;
}
-uint32_t
-Instruction::GetData (DataExtractor &data)
-{
- return m_opcode.GetData(data);
+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;
}
-InstructionList::InstructionList() :
- m_instructions()
-{
+uint32_t Instruction::GetData(DataExtractor &data) {
+ return m_opcode.GetData(data);
}
+InstructionList::InstructionList() : m_instructions() {}
+
InstructionList::~InstructionList() = default;
-size_t
-InstructionList::GetSize() const
-{
- return m_instructions.size();
+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;
+}
+
+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::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::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;
+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;
}
- return max_inst_size;
-}
+ }
-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::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;
+ // 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;
}
- 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);
+ 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;
+ }
}
-}
-void
-InstructionList::Clear()
-{
- m_instructions.clear();
-}
-
-void
-InstructionList::Append (lldb::InstructionSP &inst_sp)
-{
- if (inst_sp)
- m_instructions.push_back(inst_sp);
+ if (next_branch == UINT32_MAX) {
+ // We couldn't find the previous packet, so return start
+ next_branch = start;
+ }
+ }
+ return next_branch;
}
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::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;
}
-
- // 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;
- }
- }
-
- if (next_branch == UINT32_MAX)
- {
- // We couldn't find the previous packet, so return start
- next_branch = start;
- }
- }
- return next_branch;
+ }
+ return index;
}
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;
- }
- }
- return index;
+InstructionList::GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr,
+ Target &target) {
+ Address address;
+ address.SetLoadAddress(load_addr, &target);
+ return GetIndexOfInstructionAtAddress(address);
}
-uint32_t
-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");
- }
- 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();
-
- if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid())
- return 0;
-
+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();
- // 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;
+ 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);
+ 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 size_t bytes_read = target->ReadMemory(
+ range.GetBaseAddress(), prefer_file_cache, heap_buffer->GetBytes(),
+ heap_buffer->GetByteSize(), error, &load_addr);
- const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
+ 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");
+ }
+ return 0;
+}
- if (bytes_read == 0)
- return 0;
- DataExtractor data (data_sp,
- m_arch.GetByteOrder(),
- m_arch.GetAddressByteSize());
+size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx,
+ const Address &start,
+ uint32_t num_instructions,
+ bool prefer_file_cache) {
+ m_instruction_list.Clear();
- const bool append_instructions = true;
- DecodeInstructions (start,
- data,
- 0,
- num_instructions,
- append_instructions,
- data_from_file);
+ if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid())
+ return 0;
- return m_instruction_list.GetSize();
+ 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;
+
+ 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);
+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());
+ // 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::HasDelaySlot ()
-{
- // 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;
}
-size_t
-PseudoInstruction::Decode (const lldb_private::Disassembler &disassembler,
- const lldb_private::DataExtractor &data,
- lldb::offset_t data_offset)
-{
- return m_opcode.GetByteSize();
+bool PseudoInstruction::HasDelaySlot() {
+ // This is NOT a valid question for a pseudo instruction.
+ return false;
}
-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;
- }
+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::SetDescription (const char *description)
-{
- if (description && strlen (description) > 0)
- m_description = description;
+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(const char *description) {
+ if (description && strlen(description) > 0)
+ m_description = description;
}
diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp
index 625cccc..69c5ea3 100644
--- a/lldb/source/Core/DynamicLoader.cpp
+++ b/lldb/source/Core/DynamicLoader.cpp
@@ -11,50 +11,49 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/lldb-private.h"
+#include "lldb/Target/DynamicLoader.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Section.h"
-#include "lldb/Target/DynamicLoader.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;
@@ -63,203 +62,174 @@
// (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();
+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));
+ 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();
- }
+ // 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);
- }
- }
+ 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();
- ModuleSpec module_spec (file, target.GetArchitecture());
- ModuleSP module_sp;
+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;
- }
- }
-
- // 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;
- }
- }
- }
-
- 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 = 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;
+ }
+ }
+
+ // 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;
+ }
+ }
+ }
+
+ 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;
}
-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/lldb/source/Core/EmulateInstruction.cpp b/lldb/source/Core/EmulateInstruction.cpp
index e46cfb2..800ff8e 100644
--- a/lldb/source/Core/EmulateInstruction.cpp
+++ b/lldb/source/Core/EmulateInstruction.cpp
@@ -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;
+ }
+ 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));
+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(const RegisterInfo *reg_info,
+ RegisterValue ®_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 (®_info, reg_value);
- return false;
+bool EmulateInstruction::ReadRegister(lldb::RegisterKind reg_kind,
+ uint32_t reg_num,
+ RegisterValue ®_value) {
+ RegisterInfo reg_info;
+ if (GetRegisterInfo(reg_kind, reg_num, reg_info))
+ return ReadRegister(®_info, reg_value);
+ return false;
}
-uint64_t
-EmulateInstruction::ReadRegisterUnsigned (lldb::RegisterKind reg_kind,
- uint32_t reg_num,
- uint64_t fail_value,
- bool *success_ptr)
-{
+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 ®_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 ®_value) {
+ RegisterInfo reg_info;
+ if (GetRegisterInfo(reg_kind, reg_num, reg_info))
+ return WriteRegister(context, ®_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_kind, reg_num, reg_value))
- return reg_value.GetAsUInt64(fail_value, success_ptr);
- if (success_ptr)
- *success_ptr = false;
- return fail_value;
+ if (reg_value.SetUInt(uint_value, reg_info.byte_size))
+ return WriteRegister(context, ®_info, reg_value);
+ }
+ return false;
}
-uint64_t
-EmulateInstruction::ReadRegisterUnsigned (const RegisterInfo *reg_info,
- uint64_t fail_value,
- bool *success_ptr)
-{
+bool EmulateInstruction::WriteRegisterUnsigned(const Context &context,
+ const RegisterInfo *reg_info,
+ uint64_t uint_value) {
+ if (reg_info != nullptr) {
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;
+ if (reg_value.SetUInt(uint_value, reg_info->byte_size))
+ return WriteRegister(context, reg_info, reg_value);
+ }
+ return false;
}
-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;
+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;
}
-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, ®_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, ®_info, reg_value);
+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;
+ }
+
+ if (success_ptr)
+ *success_ptr = success;
+
+ if (!success)
+ uval64 = fail_value;
+ return uval64;
}
-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;
+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);
}
-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;
+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;
}
-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;
- }
- }
+void EmulateInstruction::SetBaton(void *baton) { m_baton = baton; }
- if (success_ptr)
- *success_ptr = success;
-
- if (!success)
- uval64 = fail_value;
- return uval64;
+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;
}
-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);
+void EmulateInstruction::SetReadMemCallback(
+ ReadMemoryCallback read_mem_callback) {
+ m_read_mem_callback = read_mem_callback;
}
-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::SetWriteMemCallback(
+ WriteMemoryCallback write_mem_callback) {
+ m_write_mem_callback = write_mem_callback;
}
-void
-EmulateInstruction::SetBaton (void *baton)
-{
- m_baton = baton;
+void EmulateInstruction::SetReadRegCallback(
+ ReadRegisterCallback read_reg_callback) {
+ m_read_reg_callback = read_reg_callback;
}
-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::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::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;
+
+ StackFrame *frame = (StackFrame *)baton;
+
+ ProcessSP process_sp(frame->CalculateProcess());
+ if (process_sp) {
+ Error error;
+ return process_sp->WriteMemory(addr, src, src_len, error);
+ }
+
+ return 0;
}
-bool
-EmulateInstruction::ReadRegisterFrame (EmulateInstruction *instruction,
- void *baton,
- const RegisterInfo *reg_info,
- RegisterValue ®_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 ®_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 ®_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 ®_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 ®_kind,
- uint32_t ®_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[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[eRegisterKindProcessPlugin];
- if (reg_num != LLDB_INVALID_REGNUM)
- {
- reg_kind = eRegisterKindProcessPlugin;
- return true;
- }
+bool EmulateInstruction::ReadRegisterFrame(EmulateInstruction *instruction,
+ void *baton,
+ const RegisterInfo *reg_info,
+ RegisterValue ®_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 ®_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 ®_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 ®_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 ®_kind,
+ uint32_t ®_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[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[eRegisterKindProcessPlugin];
+ if (reg_num != LLDB_INVALID_REGNUM) {
+ reg_kind = eRegisterKindProcessPlugin;
+ return true;
+ }
+ return false;
}
uint32_t
-EmulateInstruction::GetInternalRegisterNumber (RegisterContext *reg_ctx, const RegisterInfo ®_info)
-{
- lldb::RegisterKind reg_kind;
- uint32_t reg_num;
- if (reg_ctx && GetBestRegisterKindAndNumber (®_info, reg_kind, reg_num))
- return reg_ctx->ConvertRegisterKindToRegisterNumber (reg_kind, reg_num);
- return LLDB_INVALID_REGNUM;
+EmulateInstruction::GetInternalRegisterNumber(RegisterContext *reg_ctx,
+ const RegisterInfo ®_info) {
+ lldb::RegisterKind reg_kind;
+ uint32_t reg_num;
+ if (reg_ctx && GetBestRegisterKindAndNumber(®_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;
+bool EmulateInstruction::CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) {
+ unwind_plan.Clear();
+ return false;
}
diff --git a/lldb/source/Core/Error.cpp b/lldb/source/Core/Error.cpp
index cc27a2d..d91f16d 100644
--- a/lldb/source/Core/Error.cpp
+++ b/lldb/source/Core/Error.cpp
@@ -27,59 +27,42 @@
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;
@@ -89,81 +72,62 @@
// 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;
+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);
+ 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; }
//----------------------------------------------------------------------
// 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
@@ -174,34 +138,29 @@
// 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);
+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 = "???";
+ 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);
+ 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);
+ }
}
//----------------------------------------------------------------------
@@ -213,106 +172,90 @@
// 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);
+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 = "???";
+ 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());
+ 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);
- }
+ ::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;
+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;
+}
+
+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();
-}
-
-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;
+ }
+ 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();
}
//----------------------------------------------------------------------
@@ -321,19 +264,15 @@
// 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(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();
}
//------------------------------------------------------------------
@@ -342,74 +281,57 @@
/// @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();
+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;
+ // 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());
}
- else
- {
- m_string.clear();
- }
- 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/lldb/source/Core/Event.cpp b/lldb/source/Core/Event.cpp
index 96c1c56..cb753a9 100644
--- a/lldb/source/Core/Event.cpp
+++ b/lldb/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"
@@ -32,80 +32,59 @@
// Event functions
//------------------------------------------------------------------
-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(Broadcaster *broadcaster, uint32_t event_type, EventData *data)
+ : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type),
+ m_data_sp(data) {}
-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(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, 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(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);
+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 (m_data_sp)
- {
- s->PutChar('{');
- m_data_sp->Dump (s);
- s->PutChar('}');
- }
+ 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 ("<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 -
@@ -119,11 +98,7 @@
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"); }
#pragma mark -
#pragma mark EventDataBytes
@@ -132,119 +107,87 @@
// EventDataBytes functions
//------------------------------------------------------------------
+EventDataBytes::EventDataBytes() : m_bytes() {}
-EventDataBytes::EventDataBytes () :
- m_bytes()
-{
+EventDataBytes::EventDataBytes(const char *cstr) : m_bytes() {
+ SetBytesFromCString(cstr);
}
-EventDataBytes::EventDataBytes (const char *cstr) :
- m_bytes()
-{
- SetBytesFromCString (cstr);
-}
-
-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);
- }
- return nullptr;
+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);
+void EventDataBytes::SwapBytes(std::string &new_bytes) {
+ m_bytes.swap(new_bytes);
}
#pragma mark -
@@ -254,142 +197,104 @@
// EventDataStructuredData definitions
//------------------------------------------------------------------
-EventDataStructuredData::EventDataStructuredData() :
- EventData(),
- m_process_sp(),
- m_object_sp(),
- m_plugin_sp()
-{
-}
+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(
+ 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::~EventDataStructuredData() {}
//------------------------------------------------------------------
// EventDataStructuredData member functions
//------------------------------------------------------------------
-const ConstString &
-EventDataStructuredData::GetFlavor() const
-{
- return EventDataStructuredData::GetFlavorString();
+const ConstString &EventDataStructuredData::GetFlavor() const {
+ return EventDataStructuredData::GetFlavorString();
}
-void
-EventDataStructuredData::Dump(Stream *s) const
-{
- if (!s)
- return;
+void EventDataStructuredData::Dump(Stream *s) const {
+ if (!s)
+ return;
- if (m_object_sp)
- m_object_sp->Dump(*s);
+ if (m_object_sp)
+ m_object_sp->Dump(*s);
}
-const ProcessSP&
-EventDataStructuredData::GetProcess() const
-{
- return m_process_sp;
+const ProcessSP &EventDataStructuredData::GetProcess() const {
+ return m_process_sp;
}
-const StructuredData::ObjectSP&
-EventDataStructuredData::GetObject() const
-{
- return m_object_sp;
+const StructuredData::ObjectSP &EventDataStructuredData::GetObject() const {
+ return m_object_sp;
}
-const lldb::StructuredDataPluginSP&
-EventDataStructuredData::GetStructuredDataPlugin() const
-{
- return m_plugin_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::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::SetObject(
+ const StructuredData::ObjectSP &object_sp) {
+ m_object_sp = object_sp;
}
-void
-EventDataStructuredData::SetStructuredDataPlugin(const
- lldb::StructuredDataPluginSP
- &plugin_sp)
-{
- m_plugin_sp = plugin_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 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;
+ const EventData *event_data = event_ptr->GetData();
+ if (!event_data ||
+ event_data->GetFlavor() != EventDataStructuredData::GetFlavorString())
+ return nullptr;
- return static_cast<const EventDataStructuredData*>(event_data);
+ 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();
+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();
+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();
+EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr) {
+ auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
+ if (event_data)
+ return event_data->GetStructuredDataPlugin();
+ else
+ return StructuredDataPluginSP();
}
-const ConstString &
-EventDataStructuredData::GetFlavorString ()
-{
- static ConstString s_flavor("EventDataStructuredData");
- return s_flavor;
+const ConstString &EventDataStructuredData::GetFlavorString() {
+ static ConstString s_flavor("EventDataStructuredData");
+ return s_flavor;
}
-
-
diff --git a/lldb/source/Core/FastDemangle.cpp b/lldb/source/Core/FastDemangle.cpp
index 528f7f6..00a158a 100644
--- a/lldb/source/Core/FastDemangle.cpp
+++ b/lldb/source/Core/FastDemangle.cpp
@@ -8,8 +8,8 @@
//===----------------------------------------------------------------------===//
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include "lldb/lldb-private.h"
@@ -23,57 +23,52 @@
/// @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 +81,914 @@
/// Over time the full mangling spec should be supported without compromising
/// performance for the most common cases.
-class SymbolDemangler
-{
+class SymbolDemangler {
public:
+ //----------------------------------------------------
+ // Public API
+ //----------------------------------------------------
- //----------------------------------------------------
- // 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.
- /// @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;
- 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;
+ }
- 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
- /// @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;
- 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;
+ }
- // 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
- /// @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);
- }
+ ~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.
+ /// @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;
+ 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
+ //----------------------------------------------------
- //----------------------------------------------------
- // 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;
- 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;
- // 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;
- // ... 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;
- // 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;
+ }
- // 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);
}
- void
- GrowRewriteRanges()
- {
- // By default, double the size of the array
- int growth = m_rewrite_ranges_size;
+ // 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);
- // Apply reasonable minimum and maximum sizes for growth
- if (growth > 128)
- growth = 128;
- if (growth < 16)
- growth = 16;
+ // 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;
- // 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];
+ // 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);
}
- 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;
+ }
+ ++index;
}
+ }
- //----------------------------------------------------
- // Range and state management
- //----------------------------------------------------
+ void EndSubstitution(int start_cookie) {
+ if (m_next_substitute_index == m_next_template_arg_index)
+ GrowRewriteRanges();
- 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();
-
- 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
- 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;
+ 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('&');
}
-
- //----------------------------------------------------
- // 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;
+ if (qualifiers & QualifierRValueReference) {
+ if (space_before_reference)
+ WRITE(" &&");
+ else
+ WRITE("&&");
}
+ }
- void
- Write(const char *content)
- {
- Write(content, strlen(content));
- }
+ //----------------------------------------------------
+ // Rewrite methods
+ //
+ // Write another copy of content already present
+ // earlier in the output buffer
+ //----------------------------------------------------
- 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 RewriteRange(BufferRange range) {
+ Write(m_buffer + range.offset, range.length);
+ }
- 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)
- {
+ 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
- //----------------------------------------------------
+ //----------------------------------------------------
+ // 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 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;
+ int count = digit;
+ while (true) {
+ digit = *++m_read_ptr - '0';
+ if (digit > 9)
+ break;
- count = count * 10 + digit;
- }
- return count;
+ 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;
+ 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;
+ 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;
+ 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
+ // <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;
- }
- }
- }
+ 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;
- 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 };
}
+ --m_read_ptr;
+ return nullptr;
+ }
- // <CV-qualifiers> ::= [r] [V] [K]
- // <ref-qualifier> ::= R # & ref-qualifier
- // <ref-qualifier> ::= O # && ref-qualifier
+ // <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
- 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;
+ 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};
+ }
- // <discriminator> := _ <non-negative number> # when number < 10
- // := __ <non-negative number> _ # when number >= 10
- // extension := decimal-digit+
+ // <CV-qualifiers> ::= [r] [V] [K]
+ // <ref-qualifier> ::= R # & ref-qualifier
+ // <ref-qualifier> ::= O # && ref-qualifier
- 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;
+ 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;
+ }
}
-
- //----------------------------------------------------
- // 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;
- }
-
- // <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;
- }
-#ifdef DEBUG_FAILURES
- printf("*** Expected number\n");
-#endif
- 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 terminal _ in substitution\n");
-#endif
- return false;
- }
- return RewriteSubstitution (substitution_index + 1);
- }
- Write(substitution);
+ if (allow_ro) {
+ if (next == 'R') {
++m_read_ptr;
- return true;
+ qualifiers |= QualifierReference;
+ } else if (next == 'O') {
+ ++m_read_ptr;
+ qualifiers |= QualifierRValueReference;
+ }
+ }
+ return qualifiers;
+ }
+
+ // <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';
+ }
}
- // <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
- //
- // <bare-function-type> ::= <signature type>+ # types are possible return type, then parameter types
+ // Not a valid discriminator
+ m_read_ptr = discriminator_start;
+ return -1;
+ }
- bool
- ParseFunctionType (int inner_qualifiers = QualifierNone)
- {
+ //----------------------------------------------------
+ // 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("*** Function types not supported\n");
+ printf("*** Expected '%c'\n", character);
#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;
+ return false;
+ }
-#if 0 // TODO
+ // <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;
+ }
+#ifdef DEBUG_FAILURES
+ printf("*** Expected number\n");
+#endif
+ 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 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
+
+ bool ParseFunctionType(int inner_qualifiers = QualifierNone) {
+#ifdef DEBUG_FAILURES
+ 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;
+
+#if 0 // TODO
if (*m_read_ptr == 'Y')
++m_read_ptr;
@@ -1083,28 +1050,26 @@
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 +1117,573 @@
return true;
}
#endif // TODO
- }
+ }
- // <pointer-to-member-type> ::= M <class type> <member type>
+ // <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(' ');
+ // 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() {
+#ifdef DEBUG_FAILURES
+ 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;
- WRITE("::*");
-
- int type_cookie = GetStartCookie();
+ return false;
+ break;
+ case 'T':
+ case 't':
+ case 'v':
+ default:
+#ifdef DEBUG_FAILURES
+ 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;
- ReorderRange (EndRange (type_cookie), insertion_cookie);
- return true;
+ return false;
+ Write('*');
+ break;
+ }
+ break;
}
-
- // <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()
- {
-#ifdef DEBUG_FAILURES
- 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:
-#ifdef DEBUG_FAILURES
- 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':
-#ifdef DEBUG_FAILURES
- 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;
- }
-
- // <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':
-#ifdef DEBUG_FAILURES
- printf("*** Lambda type names unsupported\n");
-#endif
- return false;
- }
-#ifdef DEBUG_FAILURES
- printf("*** Unknown unnamed type %.3s\n", m_read_ptr - 2);
-#endif
+ case 'R': {
+ ++m_read_ptr;
+ if (!ParseType())
return false;
+ Write('&');
+ break;
}
-
- // <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;
- }
-#ifdef DEBUG_FAILURES
- printf("*** Broken constructor\n");
-#endif
+ case 'O': {
+ ++m_read_ptr;
+ if (!ParseType())
return false;
+ Write('&');
+ Write('&');
+ break;
}
-
- // <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;
- }
+ case 'C':
+ case 'G':
+ case 'U':
#ifdef DEBUG_FAILURES
- printf("*** Broken destructor\n");
+ 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;
}
- // See TryParseOperator()
+ // 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;
+ }
- bool
- ParseOperatorName(NameState & name_state)
- {
+ // <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':
#ifdef DEBUG_FAILURES
- const char *operator_ptr = m_read_ptr;
+ printf("*** Lambda type names unsupported\n");
#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:
+ return false;
+ }
#ifdef DEBUG_FAILURES
- printf("*** Unknown operator: %.2s\n", operator_ptr);
+ 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
+
+ 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;
}
-
- // <source-name> ::= <positive length number> <identifier>
-
- bool
- ParseSourceName()
- {
- int count = TryParseNumber();
- if (count == -1)
- {
#ifdef DEBUG_FAILURES
- printf("*** Malformed source name, missing length count\n");
+ printf("*** Broken constructor\n");
#endif
- return false;
- }
+ return false;
+ }
- const char *next_m_read_ptr = m_read_ptr + count;
- if (next_m_read_ptr > m_read_end)
- {
+ // <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("*** Malformed source name, premature termination\n");
+ printf("*** Broken destructor\n");
#endif
- return false;
- }
+ return false;
+ }
- if (count >= 10 && strncmp(m_read_ptr, "_GLOBAL__N", 10) == 0)
- WRITE("(anonymous namespace)");
- else Write(m_read_ptr, count);
+ // See TryParseOperator()
- m_read_ptr = next_m_read_ptr;
- return true;
+ bool ParseOperatorName(NameState &name_state) {
+#ifdef DEBUG_FAILURES
+ const char *operator_ptr = m_read_ptr;
+#endif
+ Operator parsed_operator = TryParseOperator();
+ if (parsed_operator.name) {
+ WRITE("operator");
+ Write(parsed_operator.name);
+ return true;
}
- // <unqualified-name> ::= <operator-name>
- // ::= <ctor-dtor-name>
- // ::= <source-name>
- // ::= <unnamed-type-name>
+ // 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);
+#endif
+ return false;
+ }
+ }
- 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);
- };
+ // <source-name> ::= <positive length number> <identifier>
+
+ bool ParseSourceName() {
+ int count = TryParseNumber();
+ if (count == -1) {
+#ifdef DEBUG_FAILURES
+ printf("*** Malformed source name, missing length count\n");
+#endif
+ return false;
}
- // <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);
+ 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");
+#endif
+ return false;
}
- 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);
+ 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');
+ }
+
+ 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");
+#endif
+ 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');
- }
-
- bool
- ParseBooleanLiteral()
- {
- switch (*m_read_ptr++)
- {
- case '0': WRITE("false"); break;
- case '1': WRITE("true"); break;
- default:
+ }
+ --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("*** Boolean literal not 0 or 1\n");
+ printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1);
#endif
- 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':
+ return false;
+ case 'T':
+// Invalid mangled name per
+// http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
#ifdef DEBUG_FAILURES
- printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1);
+ printf("*** Invalid primary expr encoding\n");
#endif
- 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");
-#endif
- 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>
-
- 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);
-#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()
- {
-#ifdef DEBUG_FAILURES
- printf("*** Base unresolved name unsupported\n");
-#endif
+ return false;
+ default:
+ --m_read_ptr;
+ Write('(');
+ if (!ParseType())
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");
-#endif
- //TODO: grammar for all of this seems unclear...
+ Write(')');
+ if (!ParseNumber())
return false;
+ return Parse('E');
+ }
+ }
+
+ // <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:
+#ifdef DEBUG_FAILURES
+ 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() {
+#ifdef DEBUG_FAILURES
+ 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() {
+#ifdef DEBUG_FAILURES
+ printf("*** Unresolved names not supported\n");
+#endif
+ // 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 +1692,675 @@
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>
+ // <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:
+ 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();
- }
+ return false;
}
- // <template-arg> ::= <type> # type or template
- // ::= X <expression> E # expression
- // ::= <expr-primary> # simple expressions
- // ::= J <template-arg>* E # argument pack
- // ::= LZ <encoding> E # extension
+ 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();
+ }
+ }
- bool
- ParseTemplateArg()
- {
- switch (*m_read_ptr) {
- case 'J':
+ // <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();
- }
+ 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>+
+ // <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 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();
+ 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);
+ 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;
+ }
+
+ // 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;
- return true;
+ 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;
+ }
}
- // <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;
- }
-
- // 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;
+ 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>
+ // <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;
+ 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;
-
- 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;
- }
- 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");
-#endif
+ 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;
+ }
- // <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
+ // <name> ::= <nested-name>
+ // ::= <local-name>
+ // ::= <unscoped-template-name> <template-args>
+ // ::= <unscoped-name>
- 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);
-#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();
- }
+ // <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;
- // <special-name> ::= GV <object name> # Guard variable for one-time initialization
- // # No <type>
- // extension ::= GR <object name> # reference temporary for object
+ if (*m_read_ptr == 'I') {
+ EndSubstitution(name_start_cookie);
- 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:
+ ++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("*** Unknown G encoding\n");
+ printf("*** Malformed call offset\n");
#endif
- return false;
- }
+ 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);
+#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();
+ }
+ }
+
+ // <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:
+#ifdef DEBUG_FAILURES
+ printf("*** Unknown G encoding\n");
+#endif
+ 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
-
- 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;
- }
-
- 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();
-
- if (!ParseType())
- return false;
- continue;
- }
- break;
- }
- Write(')');
- return true;
+ 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);
}
- // <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;
+ 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;
+ }
- 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;
+ // <encoding> ::= <function name> <bare-function-type>
+ // ::= <data name>
+ // ::= <special-name>
- if (*m_read_ptr++ != '_' || *m_read_ptr++ != 'Z')
- {
+ 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') {
#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:
-#ifdef DEBUG_FAILURES
- printf("*** Unparsed mangled content\n");
-#endif
- return false;
- }
+ 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");
+#endif
+ return false;
+ }
+ }
private:
+ // External scratch storage used during demanglings
- // 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;
- 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
- // 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;
+ 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;
};
} // 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);
- }
+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);
- }
+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);
+}
} // lldb_private namespace
diff --git a/lldb/source/Core/FileLineResolver.cpp b/lldb/source/Core/FileLineResolver.cpp
index e8ef87f..db56cae 100644
--- a/lldb/source/Core/FileLineResolver.cpp
+++ b/lldb/source/Core/FileLineResolver.cpp
@@ -21,96 +21,66 @@
//----------------------------------------------------------------------
// 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/lldb/source/Core/FileSpecList.cpp b/lldb/source/Core/FileSpecList.cpp
index cef1bfb..d4ce4b7 100644
--- a/lldb/source/Core/FileSpecList.cpp
+++ b/lldb/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 @@
// 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 @@
// 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();
+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();
+ // 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;
- }
+ 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 @@
// 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 @@
}
}
#endif
- return 0;
+ return 0;
}
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index e2097cc..99b4a80 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -49,251 +49,244 @@
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)
+ 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),
};
-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),
+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_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_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);
+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)
-{
+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) {}
+
+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);
}
-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::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::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 char *cstr) {
+ return AppendText(llvm::StringRef(cstr));
}
-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());
+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);
}
-void
-FormatEntity::Entry::AppendText (const char *cstr)
-{
- return AppendText (llvm::StringRef(cstr));
-}
+#define ENUM_TO_CSTR(eee) \
+ case FormatEntity::Entry::Type::eee: \
+ return #eee
-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
-
-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);
@@ -351,2280 +344,2034 @@
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);
+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 (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;
-}
-
-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);
- }
+ 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
-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 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 (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 (vaddr != LLDB_INVALID_ADDRESS) {
+ int addr_width = 0;
+ if (exe_ctx && target) {
+ addr_width = target->GetArchitecture().GetAddressByteSize() * 2;
}
- 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)
- {
- 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] [%" 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;
- }
- }
+ 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
-DumpFile (Stream &s, const FileSpec &file, FileKind file_kind)
-{
- switch (file_kind)
- {
- case FileKind::FileError:
- break;
+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;
- case FileKind::Basename:
- if (file.GetFilename())
- {
- s << file.GetFilename();
- return true;
+ 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();
}
- break;
-
- case FileKind::Dirname:
- if (file.GetDirectory())
- {
- s << file.GetDirectory();
- return true;
- }
- break;
-
- case FileKind::Fullpath:
- if (file)
- {
- s << file;
- return true;
- }
- break;
+ } else if (sc->symbol && sc->symbol->ValueIsAddress())
+ func_addr = sc->symbol->GetAddressRef();
}
- return false;
-}
-static bool
-DumpRegister (Stream &s,
- StackFrame *frame,
- RegisterKind reg_kind,
- uint32_t reg_num,
- Format format)
+ if (func_addr.IsValid()) {
+ const char *addr_offset_padding = no_padding ? "" : " ";
-{
- 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;
- }
- }
- }
+ 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 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);
+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("[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);
- }
- 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);
- }
- return item;
-}
-
-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;
-
- 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;
- }
- 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);
-
- Error error;
-
- 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(),
- &first_unparsed,
- &reason_to_stop,
- &final_value_type,
- options,
- &what_next).get();
-
- 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();
- }
- }
-
- 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.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();
- 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 true;
- }
- }
-
- // 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("[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());
- }
-
- // 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("[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(',');
- }
- s.PutChar(']');
- return success;
- }
-}
-
-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;
- }
- }
- }
- }
+ log->Printf("[ScanBracketedRange] no bracketed range, skipping entirely");
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);
+ close_bracket_index = subpath.find(']', open_bracket_index + 1);
- 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;
- }
- }
-
+ 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;
-static inline bool
-IsToken(const char *var_name_begin, const char *var)
-{
- return (::strncmp (var_name_begin, var, strlen(var)) == 0);
-}
+ 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);
-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);
- }
+ 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;
+ }
}
- return false;
+ }
+ return true;
}
-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);
- }
+static bool DumpFile(Stream &s, const FileSpec &file, FileKind file_kind) {
+ switch (file_kind) {
+ case FileKind::FileError:
+ break;
+
+ case FileKind::Basename:
+ if (file.GetFilename()) {
+ s << file.GetFilename();
+ return true;
}
- return false;
+ break;
+
+ case FileKind::Dirname:
+ if (file.GetDirectory()) {
+ s << file.GetDirectory();
+ return true;
+ }
+ break;
+
+ case FileKind::Fullpath:
+ if (file) {
+ s << file;
+ return true;
+ }
+ break;
+ }
+ return false;
}
-bool
-FormatEntity::Format (const Entry &entry,
- Stream &s,
- const SymbolContext *sc,
+static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind,
+ uint32_t reg_num, Format format)
+
+{
+ 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;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+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());
+ 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);
+ } 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);
+ }
+ return item;
+}
+
+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 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
- }
- }
- return true; // Only return true if all items succeeded
-
- case Entry::Type::String:
- s.PutCString(entry.string.c_str());
- return true;
-
- 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;
-
- 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::FunctionChanged:
- return function_changed;
-
- 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;
-
- 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;
- }
+ const FormatEntity::Entry &entry, ValueObject *valobj) {
+ if (valobj == nullptr)
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;
+ 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;
}
- return false;
-}
+ break;
-static Error
-ParseEntry (const llvm::StringRef &format_str,
- const FormatEntity::Entry::Definition *parent,
- FormatEntity::Entry &entry)
-{
+ default:
+ return false;
+ }
+
+ if (valobj == nullptr)
+ 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;
+ } 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);
+
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 std::string &expr_path = entry.string;
- 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
+ if (log)
+ log->Printf("[Debugger::FormatPrompt] symbol to expand: %s",
+ expr_path.c_str());
- case FormatEntity::Entry::Type::ParentNumber:
- entry.number = entry_def->data;
- return error; // Success
+ target = valobj
+ ->GetValueForExpressionPath(expr_path.c_str(), &first_unparsed,
+ &reason_to_stop, &final_value_type,
+ options, &what_next)
+ .get();
- 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.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;
- }
+ 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();
}
- 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;
+ }
+
+ 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.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();
+ 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 true;
+ }
+ }
+
+ // 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("[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());
+ }
+
+ // 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(
+ "[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(',');
+ }
+ s.PutChar(']');
+ return success;
+ }
+}
+
+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 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;
+ }
+ }
+
+ return false;
+}
+
+static inline bool IsToken(const char *var_name_begin, const char *var) {
+ return (::strncmp(var_name_begin, var, strlen(var)) == 0);
+}
+
+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;
+}
+
+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;
+}
+
+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
+ }
+ }
+ return true; // Only return true if all items succeeded
+
+ case Entry::Type::String:
+ s.PutCString(entry.string.c_str());
+ return true;
+
+ 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;
+
+ 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::FunctionChanged:
+ return function_changed;
+
+ 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;
+
+ 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;
+ }
+ 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;
+ }
+ return false;
+}
+
+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.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;
+ }
+ }
+ 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;
}
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;
- }
- }
- }
- }
- remainder = format_str;
- return parent;
-}
+FindEntry(const llvm::StringRef &format_str,
+ const FormatEntity::Entry::Definition *parent,
+ llvm::StringRef &remainder) {
+ Error error;
-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);
- }
-
- 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
- {
- // 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;
-
- 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;
- }
- }
- 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));
- }
- }
+ 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
- {
- variable_name = format_str.substr(0, paren_pos);
+ 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;
}
- // 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;
+ }
+ remainder = format_str;
+ return parent;
}
-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;
-}
+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("${}\\");
-static std::string
-MakeMatch (const llvm::StringRef &prefix, const char *suffix)
-{
- std::string match(prefix.str());
- match.append(suffix);
- return match;
-}
+ 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;
+ }
-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)
+ 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);
+ }
+
+ 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
{
- 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()));
+ // 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;
-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));
+ 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);
}
- 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;
+ break;
- 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);
- }
- }
- }
+ 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;
+ }
+
+ // 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;
}
- return matches.GetSize();
+ }
+ 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);
+ } 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;
+}
+
+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()));
+ }
+ }
+}
+
+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);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return matches.GetSize();
}
diff --git a/lldb/source/Core/History.cpp b/lldb/source/Core/History.cpp
index 0105dce..0466a83 100644
--- a/lldb/source/Core/History.cpp
+++ b/lldb/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/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp
index bab0263..fddf755 100644
--- a/lldb/source/Core/IOHandler.cpp
+++ b/lldb/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,585 @@
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)
+ : 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,
+ 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::GetErrorStreamFile() { return m_error_sp; }
+
+bool IOHandler::GetIsInteractive() {
+ return GetInputStreamFile()->GetFile().GetIsInteractive();
}
-StreamFileSP &
-IOHandler::GetOutputStreamFile()
-{
- return m_output_sp;
+bool IOHandler::GetIsRealTerminal() {
+ return GetInputStreamFile()->GetFile().GetIsRealTerminal();
}
-StreamFileSP &
-IOHandler::GetErrorStreamFile()
-{
- return m_error_sp;
+void IOHandler::SetPopped(bool b) { m_popped.SetValue(b, eBroadcastOnChange); }
+
+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);
+ }
}
-bool
-IOHandler::GetIsInteractive ()
-{
- return GetInputStreamFile()->GetFile().GetIsInteractive ();
-}
+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] ");
-bool
-IOHandler::GetIsRealTerminal ()
-{
- return GetInputStreamFile()->GetFile().GetIsRealTerminal();
-}
-
-void
-IOHandler::SetPopped (bool b)
-{
- m_popped.SetValue(b, eBroadcastOnChange);
-}
-
-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);
- }
-}
-
-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());
+ SetPrompt(prompt_stream.GetString().c_str());
}
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;
+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.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);
- }
+ 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;
- }
-
- return 0;
-}
-
-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)
-{
-}
-
-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),
-#ifndef LLDB_DISABLE_LIBEDIT
- 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);
-
-#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);
- }
- }
-#endif
- SetBaseLineNumber (m_base_line_number);
- SetPrompt(prompt ? prompt : "");
- SetContinuationPrompt(continuation_prompt);
-}
-
-IOHandlerEditline::~IOHandlerEditline ()
-{
-#ifndef LLDB_DISABLE_LIBEDIT
- m_editline_ap.reset();
-#endif
-}
-
-void
-IOHandlerEditline::Activate ()
-{
- IOHandler::Activate();
- m_delegate.IOHandlerActivated(*this);
-}
-
-void
-IOHandlerEditline::Deactivate ()
-{
- IOHandler::Deactivate();
- m_delegate.IOHandlerDeactivated(*this);
-}
-
-bool
-IOHandlerEditline::GetLine (std::string &line, bool &interrupted)
-{
-#ifndef LLDB_DISABLE_LIBEDIT
- 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);
- }
- }
- 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);
-}
-
-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,
+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,
- 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
+ int max_matches, StringList &matches) {
+ switch (m_completion) {
+ case Completion::None:
+ break;
-const char *
-IOHandlerEditline::GetPrompt ()
-{
-#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- {
- return m_editline_ap->GetPrompt ();
+ 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));
}
- else
- {
-#endif
- if (m_prompt.empty())
- return nullptr;
+ return num_matches;
+ } break;
+ }
+
+ return 0;
+}
+
+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) {}
+
+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),
#ifndef LLDB_DISABLE_LIBEDIT
+ 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);
+
+#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);
}
+ }
#endif
- return m_prompt.c_str();
+ SetBaseLineNumber(m_base_line_number);
+ SetPrompt(prompt ? prompt : "");
+ SetContinuationPrompt(continuation_prompt);
}
-bool
-IOHandlerEditline::SetPrompt (const char *p)
-{
- if (p && p[0])
- m_prompt = p;
- else
- m_prompt.clear();
+IOHandlerEditline::~IOHandlerEditline() {
#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- m_editline_ap->SetPrompt(m_prompt.empty() ? nullptr : m_prompt.c_str());
+ m_editline_ap.reset();
#endif
- return true;
}
-const char *
-IOHandlerEditline::GetContinuationPrompt ()
-{
- return (m_continuation_prompt.empty() ? nullptr : m_continuation_prompt.c_str());
+void IOHandlerEditline::Activate() {
+ IOHandler::Activate();
+ m_delegate.IOHandlerActivated(*this);
}
-void
-IOHandlerEditline::SetContinuationPrompt (const char *p)
-{
- if (p && p[0])
- m_continuation_prompt = p;
- else
- m_continuation_prompt.clear();
+void IOHandlerEditline::Deactivate() {
+ IOHandler::Deactivate();
+ m_delegate.IOHandlerDeactivated(*this);
+}
+bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) {
#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) {
+ return m_editline_ap->GetLine(line, interrupted);
+ } else {
#endif
-}
+ line.clear();
-void
-IOHandlerEditline::SetBaseLineNumber (uint32_t line)
-{
- m_base_line_number = line;
-}
+ FILE *in = GetInputFILE();
+ if (in) {
+ if (GetIsInteractive()) {
+ const char *prompt = nullptr;
-uint32_t
-IOHandlerEditline::GetCurrentLineIndex () const
-{
-#ifndef LLDB_DISABLE_LIBEDIT
- if (m_editline_ap)
- return m_editline_ap->GetCurrentLine();
-#endif
- return m_curr_line_idx;
-}
+ if (m_multi_line && m_curr_line_idx > 0)
+ prompt = GetContinuationPrompt();
-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
- {
-#endif
- bool done = false;
- Error error;
+ if (prompt == nullptr)
+ prompt = GetPrompt();
- 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;
- }
+ if (prompt && prompt[0]) {
+ FILE *out = GetOutputFILE();
+ if (out) {
+ ::fprintf(out, "%s", prompt);
+ ::fflush(out);
+ }
}
- success = lines.GetSize() > 0;
-#ifndef LLDB_DISABLE_LIBEDIT
+ }
+ 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);
+ }
+ }
+ 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
- return success;
+}
+
+#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);
+}
+
+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;
+}
+#endif
+
+const char *IOHandlerEditline::GetPrompt() {
+#ifndef LLDB_DISABLE_LIBEDIT
+ if (m_editline_ap) {
+ return m_editline_ap->GetPrompt();
+ } else {
+#endif
+ if (m_prompt.empty())
+ return nullptr;
+#ifndef LLDB_DISABLE_LIBEDIT
+ }
+#endif
+ return m_prompt.c_str();
+}
+
+bool IOHandlerEditline::SetPrompt(const char *p) {
+ if (p && p[0])
+ m_prompt = p;
+ else
+ m_prompt.clear();
+#ifndef LLDB_DISABLE_LIBEDIT
+ if (m_editline_ap)
+ m_editline_ap->SetPrompt(m_prompt.empty() ? nullptr : m_prompt.c_str());
+#endif
+ return true;
+}
+
+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();
+
+#ifndef LLDB_DISABLE_LIBEDIT
+ 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;
+}
+
+uint32_t IOHandlerEditline::GetCurrentLineIndex() const {
+#ifndef LLDB_DISABLE_LIBEDIT
+ if (m_editline_ap)
+ return m_editline_ap->GetCurrentLine();
+#endif
+ return m_curr_line_idx;
+}
+
+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 {
+#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
+ }
+#endif
+ 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);
+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 {
+ 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();
+ {
+ 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));
+ 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));
+ }
}
// 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
+#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;
+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 +640,4009 @@
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) {}
+
+ 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;
+}
+
+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;
+ }
- bool operator != (const Point &lhs, const Point &rhs)
- {
- return lhs.x != rhs.x || lhs.y != rhs.y;
+ // 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;
+ }
- struct Size
- {
- int width;
- int height;
- Size (int w = 0, int h = 0) :
- width (w),
- height (h)
- {
- }
-
- void
- Clear ()
- {
- width = 0;
- height = 0;
- }
+ void HorizontalSplitPercentage(float top_percentage, Rect &top,
+ Rect &bottom) const {
+ float top_height = top_percentage * size.height;
+ HorizontalSplit(top_height, top, bottom);
+ }
- 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 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();
}
+ }
- bool operator != (const Size &lhs, const Size &rhs)
- {
- return lhs.width != rhs.width || lhs.height != rhs.height;
+ 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();
}
+ }
+};
- 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;
+bool operator==(const Rect &lhs, const Rect &rhs) {
+ return lhs.origin == rhs.origin && lhs.size == rhs.size;
+}
- if (size.height > h*2)
- size.height -= h*2;
- origin.y += h;
- }
+bool operator!=(const Rect &lhs, const Rect &rhs) {
+ return lhs.origin != rhs.origin || lhs.size != rhs.size;
+}
- // 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;
- }
+enum HandleCharResult {
+ eKeyNotHandled = 0,
+ eKeyHandled = 1,
+ eQuitApplication = 2
+};
- // 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;
- }
+enum class MenuActionResult {
+ Handled,
+ NotHandled,
+ Quit // Exit all menus and quit
+};
- void
- HorizontalSplitPercentage (float top_percentage, Rect &top, Rect &bottom) const
- {
- float top_height = top_percentage * size.height;
- HorizontalSplit (top_height, top, bottom);
- }
+struct KeyHelp {
+ int ch;
+ const char *description;
+};
- 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);
- }
+class WindowDelegate {
+public:
+ virtual ~WindowDelegate() = default;
- 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();
- }
- }
- };
+ virtual bool WindowDelegateDraw(Window &window, bool force) {
+ return false; // Drawing not handled
+ }
- bool operator == (const Rect &lhs, const Rect &rhs)
- {
- return lhs.origin == rhs.origin && lhs.size == rhs.size;
+ 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;
}
-
- bool operator != (const Rect &lhs, const Rect &rhs)
- {
- return lhs.origin != rhs.origin || lhs.size != rhs.size;
+ if (m_window && m_delete) {
+ ::delwin(m_window);
+ m_window = nullptr;
+ m_delete = false;
}
-
- 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);
- }
-
- WINDOW *
- get()
- {
- return m_window;
- }
-
- 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);
- }
-
- 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;
- }
- }
- }
- }
-
- 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;
- }
-
- void
- SetCanBeActive (bool b)
- {
- m_can_activate = b;
- }
-
- const WindowDelegateSP &
- GetDelegate () const
- {
- return m_delegate_sp;
- }
-
- 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;
- }
- }
- }
- }
-
- const char *
- GetName () const
- {
- return m_name.c_str();
- }
-
- 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;
-
- virtual MenuActionResult
- MenuDelegateAction (Menu &menu) = 0;
- };
-
- 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;
- }
-
- 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;
- }
-
- Menus &
- GetSubmenus()
- {
- return m_submenus;
- }
-
- const Menus &
- GetSubmenus() const
- {
- return m_submenus;
- }
-
- int
- GetSelectedSubmenuIndex () const
- {
- return m_selected;
- }
-
- void
- SetSelectedSubmenuIndex (int idx)
- {
- m_selected = idx;
- }
-
- Type
- GetType () const
- {
- return m_type;
- }
-
- int
- GetStartingColumn() const
- {
- return m_start_col;
- }
-
- void
- SetStartingColumn(int col)
- {
- m_start_col = col;
- }
-
- int
- GetKeyValue() const
- {
- return m_key_value;
- }
-
- void
- SetKeyValue(int key_value)
- {
- m_key_value = key_value;
- }
-
- std::string &
- GetName()
- {
- return m_name;
- }
-
- std::string &
- GetKeyName()
- {
- return m_key_name;
- }
-
- int
- GetDrawWidth () const
- {
- return m_max_submenu_name_length + m_max_submenu_key_name_length + 8;
- }
-
- uint64_t
- GetIdentifier() const
- {
- return m_identifier;
- }
-
- void
- SetIdentifier (uint64_t identifier)
- {
- m_identifier = identifier;
- }
-
- 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()
- {
+ if (w) {
+ m_window = w;
+ m_panel = ::new_panel(m_window);
+ m_delete = del;
}
+ }
- // 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;
- }
+ 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
- {
- m_type = Type::Separator;
- }
+ ::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);
+ }
+
+ WINDOW *get() { return m_window; }
+
+ 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('>');
}
- 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 (bottom_message && bottom_message[0]) {
+ int bottom_message_length = strlen(bottom_message);
+ int x = GetWidth() - 3 - (bottom_message_length + 2);
- 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);
+ 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
- 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);
+ 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
- {
- 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());
- }
-
- 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));
- }
- }
+ help_window_sp = CreateSubWindow("Help", bounds, true);
+ help_window_sp->SetDelegate(
+ WindowDelegateSP(help_delegate_ap.release()));
+ return true;
+ }
}
-
- 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;
-
- 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;
+ return false;
+ }
- default:
- case Menu::Type::Separator:
- break;
- }
- return true; // Drawing handled...
- }
-
- 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)
- {
- }
+ 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;
}
- 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;
+ 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;
}
+ }
}
-
- void
- Initialize ()
- {
- ::setlocale(LC_ALL, "");
- ::setlocale(LC_CTYPE, "");
+ }
+
+ 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; }
+
+ void SetCanBeActive(bool b) { m_can_activate = b; }
+
+ const WindowDelegateSP &GetDelegate() const { return m_delegate_sp; }
+
+ 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;
+ }
+ }
+ }
+ }
+
+ const char *GetName() const { return m_name.c_str(); }
+
+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;
+
+ virtual MenuActionResult MenuDelegateAction(Menu &menu) = 0;
+};
+
+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;
+ }
+
+ 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; }
+
+ Menus &GetSubmenus() { return m_submenus; }
+
+ const Menus &GetSubmenus() const { return m_submenus; }
+
+ int GetSelectedSubmenuIndex() const { return m_selected; }
+
+ void SetSelectedSubmenuIndex(int idx) { m_selected = idx; }
+
+ Type GetType() const { return m_type; }
+
+ int GetStartingColumn() const { return m_start_col; }
+
+ void SetStartingColumn(int col) { m_start_col = col; }
+
+ int GetKeyValue() const { return m_key_value; }
+
+ void SetKeyValue(int key_value) { m_key_value = key_value; }
+
+ std::string &GetName() { return m_name; }
+
+ std::string &GetKeyName() { return m_key_name; }
+
+ int GetDrawWidth() const {
+ return m_max_submenu_name_length + m_max_submenu_key_name_length + 8;
+ }
+
+ uint64_t GetIdentifier() const { return m_identifier; }
+
+ void SetIdentifier(uint64_t identifier) { m_identifier = identifier; }
+
+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() {}
+
+// 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 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();
+ }
+}
+
+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);
+ }
+ }
+
+ if (!underlined_shortcut) {
+ window.PutCString(m_name.c_str());
+ }
+
+ 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));
+ }
+ }
+}
+
+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;
+
+ 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...
+}
+
+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;
+}
+
+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, "");
#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()
+ ::start_color();
+ ::curs_set(0);
+ ::noecho();
+ ::keypad(stdscr, TRUE);
+ }
- 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);
+ void Terminate() { ::endwin(); }
- bool update = true;
+ 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);
+ 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();
- doupdate();
- update = false;
- }
-
+ // 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;
- }
- }
- }
-
- 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;
- }
+ 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);
- protected:
- WindowSP m_window_sp;
- WindowDelegates m_window_delegates;
- SCREEN *m_screen;
- FILE *m_in;
- FILE *m_out;
- };
+ 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;
+ }
+ }
+ }
+
+ 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; }
+
+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));
- }
- }
- }
- }
-
- void
- Unexpand ()
- {
- expanded = false;
- }
-
- 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);
- }
- }
+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;
- 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 (' ');
- }
+ 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));
}
- else
- {
- if (reverse_depth == 0)
- {
- window.PutChar (ACS_LTEE);
- window.PutChar (ACS_HLINE);
- }
- else
- {
- window.PutChar (ACS_VLINE);
- window.PutChar (' ');
- }
- }
+ }
}
+ }
+
+ void Unexpand() { expanded = false; }
+
+ 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(' ');
+ }
+ }
+ }
};
-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;
+ }
+
+ 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]; }
+
+ void SetRowIndex(int row_idx) { m_row_idx = row_idx; }
+
+ size_t GetNumChildren() {
+ m_delegate.TreeDelegateGenerateChildren(*this);
+ return m_children.size();
+ }
+
+ void ItemWasSelected() { m_delegate.TreeDelegateItemSelected(*this); }
+
+ 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 *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 &
- 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;
+ 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
+ }
- size_t
- GetDepth () const
- {
- if (m_parent)
- return 1 + m_parent->GetDepth();
- return 0;
+ 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(' ');
+ }
}
-
- 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];
- }
-
- void
- SetRowIndex (int row_idx)
- {
- m_row_idx = row_idx;
- }
-
- size_t
- GetNumChildren ()
- {
- m_delegate.TreeDelegateGenerateChildren (*this);
- return m_children.size();
- }
-
- void
- ItemWasSelected ()
- {
- m_delegate.TreeDelegateItemSelected(*this);
- }
-
- 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 *
- 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;
- }
-
- 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
- }
-
- 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 *
- 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;
- }
-
- void *
- GetUserData() const
- {
- return m_user_data;
- }
-
- 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;
-};
-
-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;
- }
-
- 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;
-
- 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();
-
- 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;
-};
-
-class FrameTreeDelegate : public TreeDelegate
-{
-public:
- 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().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;
- }
-
-protected:
- FormatEntity::Entry m_format;
-};
-
-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().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))
- {
- 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;
- }
-
-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;
-};
-
-class ThreadsTreeDelegate : public TreeDelegate
-{
-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);
- }
-
- ~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().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();
- }
-
- 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);
- }
-
- ~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();
- 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;
- }
-
- 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;
-
- 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;
- }
-
- 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);
- }
- }
- }
-
- 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;
- }
-
- 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;
- }
-
- Row *
- GetRowForRowIndex (size_t row_index)
- {
- return GetRowForRowIndexImpl (m_rows, row_index);
- }
-
- int
- NumVisibleRows () const
- {
- return m_max_y - m_min_y;
- }
-
- static DisplayOptions g_options;
-};
-
-class FrameVariablesWindowDelegate : public ValueObjectListDelegate
-{
-public:
- 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
- }
- }
-
- 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);
- }
-
-protected:
- Debugger &m_debugger;
- Block *m_frame_block;
-};
-
-class RegistersWindowDelegate : public ValueObjectListDelegate
-{
-public:
- 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);
- }
-
-protected:
- 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";
-#ifdef KEY_EVENT
- case KEY_EVENT: return "We were interrupted by an event";
-#endif
- case KEY_RETURN: return "return";
- case ' ': return "space";
- case '\t': return "tab";
- 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;
+ 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;
+ }
+
+ void *GetUserData() const { return m_user_data; }
+
+ 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;
+};
+
+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; }
+
+ 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;
+
+ 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();
+
+ 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;
+};
+
+class FrameTreeDelegate : public TreeDelegate {
+public:
+ 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().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;
+ }
+
+protected:
+ FormatEntity::Entry m_format;
+};
+
+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().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)) {
+ 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;
+ }
+
+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;
+};
+
+class ThreadsTreeDelegate : public TreeDelegate {
+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);
+ }
+
+ ~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().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();
+ }
+
+ 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);
+ }
+
+ ~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();
+ 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;
+ }
+
+ 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;
+
+ 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;
+ }
+
+ 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);
+ }
+ }
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ Row *GetRowForRowIndex(size_t row_index) {
+ return GetRowForRowIndexImpl(m_rows, row_index);
+ }
+
+ int NumVisibleRows() const { return m_max_y - m_min_y; }
+
+ static DisplayOptions g_options;
+};
+
+class FrameVariablesWindowDelegate : public ValueObjectListDelegate {
+public:
+ 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
+ }
+ }
+
+ 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);
+ }
+
+protected:
+ Debugger &m_debugger;
+ Block *m_frame_block;
+};
+
+class RegistersWindowDelegate : public ValueObjectListDelegate {
+public:
+ 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);
+ }
+
+protected:
+ 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";
+#ifdef KEY_EVENT
+ case KEY_EVENT:
+ return "We were interrupted by an event";
+#endif
+ case KEY_RETURN:
+ return "return";
+ case ' ':
+ return "space";
+ case '\t':
+ return "tab";
+ 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("");
+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()));
}
- 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() = 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;
+
+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;
+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;
- case KEY_DOWN:
- if (m_first_visible_line + num_visible_lines < num_lines)
- ++m_first_visible_line;
- break;
+ 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_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_DOWN:
+ if (m_first_visible_line + num_visible_lines < num_lines)
+ ++m_first_visible_line;
+ 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;
-}
-
-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)
- {
- }
-
- ~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;
-
- 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;
- }
-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);
- }
-
- ~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);
- }
-
- 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;
- }
-
-protected:
- Debugger &m_debugger;
- FormatEntity::Entry m_format;
-};
-
-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;
- }
- }
-
- 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;
- }
- }
- 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();
- }
-
- 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;
- }
- }
- }
- }
- 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);
- 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);
- }
- }
- }
- }
- }
-
- 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;
- }
- }
- }
+ 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
- {
- 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);
- }
- }
- }
- }
+ m_first_visible_line = 0;
+ }
+ break;
- const attr_t selected_highlight_attr = A_REVERSE;
- const attr_t pc_highlight_attr = COLOR_PAIR(1);
+ 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;
- StreamString strm;
+ default:
+ done = true;
+ break;
+ }
+ }
+ if (done)
+ window.GetParent()->RemoveSubWindow(&window);
+ return eKeyHandled;
+}
- InstructionList &insts = m_disassembly_sp->GetInstructionList();
- Address pc_address;
+class ApplicationDelegate : public WindowDelegate, public MenuDelegate {
+public:
+ enum {
+ eMenuID_LLDB = 1,
+ eMenuID_LLDBAbout,
+ eMenuID_LLDBExit,
- 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;
- }
+ eMenuID_Target,
+ eMenuID_TargetCreate,
+ eMenuID_TargetDelete,
- 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;
+ eMenuID_Process,
+ eMenuID_ProcessAttach,
+ eMenuID_ProcessDetach,
+ eMenuID_ProcessLaunch,
+ eMenuID_ProcessContinue,
+ eMenuID_ProcessHalt,
+ eMenuID_ProcessKill,
- 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;
- }
+ eMenuID_Thread,
+ eMenuID_ThreadStepIn,
+ eMenuID_ThreadStepOver,
+ eMenuID_ThreadStepOut,
- 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;
+ eMenuID_View,
+ eMenuID_ViewBacktrace,
+ eMenuID_ViewRegisters,
+ eMenuID_ViewSource,
+ eMenuID_ViewVariables,
- 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;
+ eMenuID_Help,
+ eMenuID_HelpGUIHelp
+ };
- if (bp_file_addrs.find(inst->GetAddress().GetFileAddress()) != bp_file_addrs.end())
- bp_attr = COLOR_PAIR(2);
+ ApplicationDelegate(Application &app, Debugger &debugger)
+ : WindowDelegate(), MenuDelegate(), m_app(app), m_debugger(debugger) {}
- if (bp_attr)
- window.AttributeOn(bp_attr);
+ ~ApplicationDelegate() override = default;
- window.Printf (" 0x%16.16llx ",
- static_cast<unsigned long long>(inst->GetAddress().GetLoadAddress(target)));
+ bool WindowDelegateDraw(Window &window, bool force) override {
+ return false; // Drawing not handled, let standard window drawing happen
+ }
- if (bp_attr)
- window.AttributeOff(bp_attr);
+ HandleCharResult WindowDelegateHandleChar(Window &window, int key) override {
+ switch (key) {
+ case '\t':
+ window.SelectNextWindowAsActive();
+ return eKeyHandled;
- window.PutChar(ACS_VLINE);
- // Mark the line with the PC with a diamond
- if (is_pc_line)
- window.PutChar(ACS_DIAMOND);
- else
- window.PutChar(' ');
+ case 'h':
+ window.CreateHelpSubwindow();
+ return eKeyHandled;
- if (highlight_attr)
- window.AttributeOn(highlight_attr);
+ case KEY_ESCAPE:
+ return eQuitApplication;
- const char *mnemonic = inst->GetMnemonic(&exe_ctx);
- const char *operands = inst->GetOperands(&exe_ctx);
- const char *comment = inst->GetComment(&exe_ctx);
+ default:
+ break;
+ }
+ return eKeyNotHandled;
+ }
- if (mnemonic != nullptr && mnemonic[0] == '\0')
- mnemonic = nullptr;
- if (operands != nullptr && operands[0] == '\0')
- operands = nullptr;
- if (comment != nullptr && comment[0] == '\0')
- comment = nullptr;
+ 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:";
+ }
- strm.Clear();
+ 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;
+ }
- 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);
+ 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;
- int right_pad = 1;
- window.PutCStringTruncated(strm.GetString().c_str(), right_pad);
+ 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;
- 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);
- }
- }
+ 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())));
}
- window.DeferredRefresh();
- return true; // Drawing handled
+ } 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;
- size_t
- GetNumLines ()
- {
- size_t num_lines = GetNumSourceLines();
- if (num_lines == 0)
- num_lines = GetNumDisassemblyLines();
- return num_lines;
- }
+ 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();
- size_t
- GetNumSourceLines () const
- {
- if (m_file_sp)
- return m_file_sp->GetNumLines();
- return 0;
- }
+ if (variables_window_sp) {
+ const Rect variables_bounds = variables_window_sp->GetBounds();
- size_t
- GetNumDisassemblyLines () const
- {
- if (m_disassembly_sp)
- return m_disassembly_sp->GetInstructionList().GetSize();
- return 0;
- }
+ main_window_sp->RemoveSubWindow(variables_window_sp.get());
- 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;
-
- default:
- break;
+ 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);
}
- return eKeyNotHandled;
+ } 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;
+ }
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;
+ Application &m_app;
+ Debugger &m_debugger;
};
-DisplayOptions ValueObjectListDelegate::g_options = { true };
+class StatusBarWindowDelegate : public WindowDelegate {
+public:
+ StatusBarWindowDelegate(Debugger &debugger) : m_debugger(debugger) {
+ FormatEntity::Parse("Thread: ${thread.id%tid}", m_format);
+ }
-IOHandlerCursesGUI::IOHandlerCursesGUI (Debugger &debugger) :
- IOHandler (debugger, IOHandler::Type::Curses)
-{
-}
+ ~StatusBarWindowDelegate() override = default;
-void
-IOHandlerCursesGUI::Activate ()
-{
- IOHandler::Activate();
- if (!m_app_ap)
- {
- m_app_ap.reset (new Application (GetInputFILE(), GetOutputFILE()));
+ 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));
- // 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();
+ 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);
}
- 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 );
+ 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;
+ }
+
+protected:
+ Debugger &m_debugger;
+ FormatEntity::Entry m_format;
+};
+
+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;
+ }
+ }
+
+ 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;
+ }
+ } 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();
+ }
+
+ 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;
+ }
+ }
+ }
+ } 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);
+ 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);
+ }
+ }
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+ } 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);
+
+ StreamString strm;
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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);
+ }
+ }
+ }
+ 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 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');
+ }
+ 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;
+
+ 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;
+};
+
+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);
+ }
}
-void
-IOHandlerCursesGUI::Deactivate ()
-{
- m_app_ap->Terminate();
-}
+void IOHandlerCursesGUI::Deactivate() { m_app_ap->Terminate(); }
-void
-IOHandlerCursesGUI::Run ()
-{
- m_app_ap->Run(m_debugger);
- SetIsDone(true);
+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/lldb/source/Core/Listener.cpp b/lldb/source/Core/Listener.cpp
index f675110..216a302 100644
--- a/lldb/source/Core/Listener.cpp
+++ b/lldb/source/Core/Listener.cpp
@@ -16,516 +16,489 @@
// 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"
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);
- }
+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;
- };
+ BroadcasterManagerSP m_manager_sp;
+};
} // anonymous namespace
Listener::Listener(const char *name)
- : m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(), m_events_mutex()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ : 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));
+
+ Clear();
+
+ 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) {
+ // Scope for "locker"
+ // Tell the broadcaster to add this object as a listener
+ {
+ 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)));
+ }
+
+ uint32_t acquired_mask =
+ broadcaster->AddListener(this->shared_from_this(), event_mask);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
if (log != nullptr)
- log->Printf ("%p Listener::Listener('%s')",
- static_cast<void*>(this), m_name.c_str());
+ 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;
}
-Listener::~Listener()
-{
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+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
+ {
+ 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)));
+ }
- Clear();
+ uint32_t acquired_mask =
+ broadcaster->AddListener(this->shared_from_this(), event_mask);
- if (log)
- log->Printf("%p Listener::%s('%s')", static_cast<void *>(this), __FUNCTION__, m_name.c_str());
+ 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 acquired_mask;
+ }
+ return 0;
}
-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)
+bool Listener::StopListeningForEvents(Broadcaster *broadcaster,
+ uint32_t event_mask) {
+ if (broadcaster) {
+ // Scope for "locker"
{
- Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock());
- if (broadcaster_sp)
- broadcaster_sp->RemoveListener (this, pos->second.event_mask);
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ m_broadcasters.erase(broadcaster->GetBroadcasterImpl());
}
- m_broadcasters.clear();
+ // Remove the broadcaster from our set of broadcasters
+ return broadcaster->RemoveListener(this->shared_from_this(), event_mask);
+ }
- 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)
- {
- // Scope for "locker"
- // Tell the broadcaster to add this object as a listener
- {
- 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)));
- }
-
- uint32_t acquired_mask = broadcaster->AddListener (this->shared_from_this(), 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());
-
- return acquired_mask;
- }
- return 0;
-}
-
-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
- {
- 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)));
- }
-
- 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 acquired_mask;
- }
- return 0;
-}
-
-bool
-Listener::StopListeningForEvents (Broadcaster* broadcaster, uint32_t event_mask)
-{
- if (broadcaster)
- {
- // Scope for "locker"
- {
- 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> broadcasters_guard(m_broadcasters_mutex);
- m_broadcasters.erase (broadcaster->GetBroadcasterImpl());
+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;
}
-
- // 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;
+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);
+ 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()));
- std::lock_guard<std::mutex> guard(m_events_mutex);
- m_events.push_back (event_sp);
- m_events_condition.notify_all();
+ 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)
- {
- }
+ 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;
+ 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;
+ 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(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));
+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;
-
- 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 (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();
+ if (m_events.empty())
return false;
-}
-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;
-}
+ Listener::event_collection::iterator pos = m_events.end();
-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;
-}
+ 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));
+ }
-Event *
-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;
-}
+ if (pos != m_events.end()) {
+ event_sp = *pos;
-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)
-{
- std::unique_lock<std::mutex> guard(m_events_mutex);
- return FindNextEventInternal(guard, 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);
-}
-
-bool
-Listener::WaitForEventsInternal(const std::chrono::microseconds &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 = %llu us) for %s", static_cast<void *>(this),
- static_cast<unsigned long long>(timeout.count()), m_name.c_str());
+ 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()));
- 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 == std::chrono::microseconds(0))
- 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::WaitForEventsInternal() 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::WaitForEventsInternal() unknown error for %s", static_cast<void *>(this),
- m_name.c_str());
- return false;
- }
- }
+ 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;
+ }
- return false;
+ event_sp.reset();
+ return false;
}
-bool
-Listener::WaitForEventForBroadcasterWithType(const std::chrono::microseconds &timeout, Broadcaster *broadcaster,
- uint32_t event_type_mask, EventSP &event_sp)
-{
- return WaitForEventsInternal(timeout, broadcaster, nullptr, 0, event_type_mask, event_sp);
+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;
}
-bool
-Listener::WaitForEventForBroadcaster(const std::chrono::microseconds &timeout, Broadcaster *broadcaster,
- EventSP &event_sp)
-{
- return WaitForEventsInternal(timeout, broadcaster, nullptr, 0, 0, event_sp);
+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;
}
-bool
-Listener::WaitForEvent(const std::chrono::microseconds &timeout, EventSP &event_sp)
-{
- return WaitForEventsInternal(timeout, nullptr, nullptr, 0, 0, event_sp);
+Event *
+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;
}
-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;
- }
- }
+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) {
+ std::unique_lock<std::mutex> guard(m_events_mutex);
+ return FindNextEventInternal(guard, 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);
+}
+
+bool Listener::WaitForEventsInternal(
+ const std::chrono::microseconds &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 = %llu us) for %s",
+ static_cast<void *>(this),
+ static_cast<unsigned long long>(timeout.count()),
+ 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 == std::chrono::microseconds(0))
+ 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::WaitForEventsInternal() 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::WaitForEventsInternal() unknown error for %s",
+ static_cast<void *>(this), m_name.c_str());
+ return false;
+ }
}
- return num_handled;
+ }
+
+ return false;
+}
+
+bool Listener::WaitForEventForBroadcasterWithType(
+ const std::chrono::microseconds &timeout, Broadcaster *broadcaster,
+ uint32_t event_type_mask, EventSP &event_sp) {
+ return WaitForEventsInternal(timeout, broadcaster, nullptr, 0,
+ event_type_mask, event_sp);
+}
+
+bool Listener::WaitForEventForBroadcaster(
+ const std::chrono::microseconds &timeout, Broadcaster *broadcaster,
+ EventSP &event_sp) {
+ return WaitForEventsInternal(timeout, broadcaster, nullptr, 0, 0, event_sp);
+}
+
+bool Listener::WaitForEvent(const std::chrono::microseconds &timeout,
+ EventSP &event_sp) {
+ return WaitForEventsInternal(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;
+ }
+ }
+ }
+ 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);
+Listener::StartListeningForEventSpec(BroadcasterManagerSP manager_sp,
+ const BroadcastEventSpec &event_spec) {
+ if (!manager_sp)
+ return 0;
- 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;
+ // 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);
- std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
- return manager_sp->UnregisterListenerForEvents (this->shared_from_this(), event_spec);
+ 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;
}
-
-ListenerSP
-Listener::MakeListener(const char *name)
-{
- return ListenerSP(new Listener(name));
+
+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));
}
diff --git a/lldb/source/Core/Log.cpp b/lldb/source/Core/Log.cpp
index a292df3..a3d559c 100644
--- a/lldb/source/Core/Log.cpp
+++ b/lldb/source/Core/Log.cpp
@@ -18,8 +18,8 @@
// Other libraries and framework includes
#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
// Project includes
#include "lldb/Core/Log.h"
@@ -35,62 +35,31 @@
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); }
//----------------------------------------------------------------------
// 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 +67,384 @@
// 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;
+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);
+ // 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();
- }
+ // 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();
+ }
+ }
}
//----------------------------------------------------------------------
// 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;
+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);
+ va_list args;
+ va_start(args, format);
+ VAPrintf(format, args);
+ va_end(args);
}
//----------------------------------------------------------------------
// 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;
+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);
+ 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;
+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);
+ 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);
+void Log::VAError(const char *format, va_list args) {
+ char *arg_msg = nullptr;
+ ::vasprintf(&arg_msg, format, args);
- if (arg_msg == nullptr)
- return;
+ if (arg_msg == nullptr)
+ return;
- Printf("error: %s", arg_msg);
- free(arg_msg);
+ Printf("error: %s", arg_msg);
+ free(arg_msg);
}
//----------------------------------------------------------------------
// 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);
+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);
+ if (arg_msg != nullptr) {
+ Printf("error: %s", arg_msg);
+ ::free(arg_msg);
+ }
+ ::exit(err);
}
//----------------------------------------------------------------------
// 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;
+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);
+ va_list args;
+ va_start(args, format);
+ VAPrintf(format, args);
+ va_end(args);
}
//----------------------------------------------------------------------
// 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;
+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);
+ char *arg_msg = nullptr;
+ va_list args;
+ va_start(args, format);
+ ::vasprintf(&arg_msg, format, args);
+ va_end(args);
- if (arg_msg == nullptr)
- return;
+ if (arg_msg == nullptr)
+ return;
- Printf("warning: %s", arg_msg);
- free(arg_msg);
+ Printf("warning: %s", arg_msg);
+ free(arg_msg);
}
//----------------------------------------------------------------------
// 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);
+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;
+ if (arg_msg == nullptr)
+ return;
- Printf("warning: %s", arg_msg);
- free(arg_msg);
+ 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 CallbackMap &GetCallbackMap() {
+ static CallbackMap g_callback_map;
+ return g_callback_map;
}
-static LogChannelMap &
-GetChannelMap ()
-{
- static LogChannelMap g_channel_map;
- return g_channel_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));
+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::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;
+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();
+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;
- 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)
- 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;
+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;
- }
- }
+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;
- }
- 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/lldb/source/Core/Logging.cpp b/lldb/source/Core/Logging.cpp
index 9eb4f66..8b6d7ed 100644
--- a/lldb/source/Core/Logging.cpp
+++ b/lldb/source/Core/Logging.cpp
@@ -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 @@
// 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;
-}
-
-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);
-}
-
-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::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;
+static Log *GetLog() {
+ if (!g_log_enabled)
return nullptr;
+ return g_log;
}
-void
-lldb_private::DisableLog (const char **categories, Stream *feedback_strm)
-{
- Log *log(GetLog ());
+uint32_t lldb_private::GetLogMask() {
+ Log *log(GetLog());
+ if (log)
+ return log->GetMask().Get();
+ return 0;
+}
- 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];
+bool lldb_private::IsLogVerbose() {
+ uint32_t mask = GetLogMask();
+ return (mask & LIBLLDB_LOG_VERBOSE);
+}
- 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 *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::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;
+}
+
+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 (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->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;
+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)
- flag_bits = g_log->GetMask().Get();
+ g_log->SetStream(log_stream_sp);
else
- flag_bits = 0;
+ g_log = new Log(log_stream_sp);
+ }
- // 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);
+ if (g_log != nullptr) {
+ 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 == ::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];
-
- 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->GetMask().Reset(flag_bits);
- g_log->GetOptions().Reset(log_options);
- }
- 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/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp
index 5a1f1e8..bcf9fa3 100644
--- a/lldb/source/Core/Mangled.cpp
+++ b/lldb/source/Core/Mangled.cpp
@@ -7,7 +7,6 @@
//
//===----------------------------------------------------------------------===//
-
// FreeBSD9-STABLE requires this to know about size_t in cxxabi.h
#include <cstddef>
#if defined(_MSC_VER)
@@ -19,15 +18,16 @@
#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 "lldb/Core/FastDemangle.h"
#include "lldb/Core/CxaDemangle.h"
+#include "lldb/Core/FastDemangle.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"
@@ -35,119 +35,104 @@
#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;
+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;
+ // 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)
+ 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 (const ConstString &s) :
- m_mangled(),
- m_demangled()
-{
- if (s)
- SetValue(s);
+Mangled::Mangled(const ConstString &s) : m_mangled(), m_demangled() {
+ if (s)
+ SetValue(s);
}
//----------------------------------------------------------------------
// Destructor
//----------------------------------------------------------------------
-Mangled::~Mangled ()
-{
-}
+Mangled::~Mangled() {}
//----------------------------------------------------------------------
// Convert to pointer operator. This allows code to check any Mangled
@@ -157,9 +142,8 @@
// 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;
}
//----------------------------------------------------------------------
@@ -170,83 +154,58 @@
// 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();
- }
+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();
- }
+ } 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();
- }
+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();
- }
+ } else {
+ m_demangled.Clear();
+ m_mangled.Clear();
+ }
}
//----------------------------------------------------------------------
@@ -256,180 +215,165 @@
// 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 (LLVM_PRETTY_FUNCTION,
- "Mangled::GetDemangledName (m_mangled = %s)",
- m_mangled.GetCString());
+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);
+ 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:
- {
+ // 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 (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 (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 = __cxa_demangle(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 (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);
}
- if (!m_demangled)
- {
- // Set the demangled string to the empty string to indicate we
- // tried to parse it once and failed.
- m_demangled.SetCString("");
- }
+ 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 ®ex,
+ 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 Mangled::GetName(lldb::LanguageType language,
+ Mangled::NamePreference preference) const {
+ if (preference == ePreferMangled && m_mangled)
+ return m_mangled;
- ConstString demangled = GetDemangledName(language);
+ 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;
+ 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);
}
//----------------------------------------------------------------------
@@ -437,10 +381,8 @@
// 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();
}
//----------------------------------------------------------------------
@@ -451,37 +393,32 @@
// 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() << "'";
+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;
+ const ConstString &demangled =
+ obj.GetDemangledName(lldb::eLanguageTypeUnknown);
+ if (demangled)
+ s << ", demangled = '" << demangled << '\'';
+ else
+ s << ", demangled = <error>";
+ return s;
}
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index b7076c0..aa9e516 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/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"
@@ -37,14 +39,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 +56,49 @@
// 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;
+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
+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;
+ 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();
+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;
+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
@@ -141,1779 +139,1544 @@
#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);
- }
+ : 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() ? "" : ")");
+ 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;
+ // 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;
+ // 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();
+ 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 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 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 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 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();
+ // 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();
+ // 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);
- }
+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;
+ if (object_name)
+ m_object_name = *object_name;
- if (object_mod_time_ptr)
- m_object_mod_time = *object_mod_time_ptr;
+ if (object_mod_time_ptr)
+ m_object_mod_time = *object_mod_time_ptr;
- 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);
+ : 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
+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();
-}
+ 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());
-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());
- }
+ // 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.SetErrorString ("invalid process");
- }
+ } 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 ();
-
- if (obj_file != nullptr)
- {
- obj_file->GetUUID(&m_uuid);
- m_did_parse_uuid = true;
- }
- }
- }
- return m_uuid;
-}
-
-TypeSystem *
-Module::GetTypeSystemForLanguage (LanguageType language)
-{
- return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
-}
-
-void
-Module::ParseAllDebugSymbols()
-{
+const lldb_private::UUID &Module::GetUUID() {
+ if (!m_did_parse_uuid.load()) {
std::lock_guard<std::recursive_mutex> guard(m_mutex);
- size_t num_comp_units = GetNumCompileUnits();
- if (num_comp_units == 0)
- return;
+ if (!m_did_parse_uuid.load()) {
+ ObjectFile *obj_file = GetObjectFile();
- SymbolContext sc;
+ if (obj_file != nullptr) {
+ obj_file->GetUUID(&m_uuid);
+ m_did_parse_uuid = true;
+ }
+ }
+ }
+ return m_uuid;
+}
+
+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;
+
+ 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);
+
+ symbols->ParseCompileUnitFunctions(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 all types for this compile unit
+ sc.function = nullptr;
+ symbols->ParseTypes(sc);
+ }
+ }
+}
+
+void Module::CalculateSymbolContext(SymbolContext *sc) {
+ sc->module_sp = shared_from_this();
+}
+
+ModuleSP Module::CalculateSymbolContextModule() { return shared_from_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(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;
+
+ 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();
- SymbolVendor *symbols = GetSymbolVendor ();
+ resolved_flags |= eSymbolContextModule;
- 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);
+ SymbolVendor *sym_vendor = GetSymbolVendor();
+ if (!sym_vendor)
+ return resolved_flags;
- symbols->ParseCompileUnitFunctions(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 all types for this compile unit
- sc.function = nullptr;
- symbols->ParseTypes(sc);
- }
+ // 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);
}
-}
-void
-Module::CalculateSymbolContext(SymbolContext* sc)
-{
- sc->module_sp = shared_from_this();
-}
+ // 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;
-ModuleSP
-Module::CalculateSymbolContextModule ()
-{
- return shared_from_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(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;
-
- 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);
+ 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);
+ // 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.
- }
- }
+ 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;
+ }
+ 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::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);
+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();
+ const uint32_t initial_count = sc_list.GetSize();
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- symbols->ResolveSymbolContext (file_spec, line, check_inlines, resolve_scope, sc_list);
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ symbols->ResolveSymbolContext(file_spec, line, check_inlines, resolve_scope,
+ sc_list);
- return sc_list.GetSize() - initial_count;
+ 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 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::FindGlobalVariables(const RegularExpression ®ex, 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);
- }
+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;
+ }
+ 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;
+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;
- }
+ 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();
+ } 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 (!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;
- }
- }
+ 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"
+ // 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())
- {
- if (name_type_mask & eFunctionNameTypeFull)
- {
- CPlusPlusLanguage::MethodName cpp_method (name);
- basename = cpp_method.GetBasename();
- if (basename.empty())
- CPlusPlusLanguage::ExtractContextAndIdentifier (name_cstr, context, basename);
- }
- }
+ 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 (!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;
- }
+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();
+
+ 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);
+
+ 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 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;
- }
- }
+ const size_t new_size = sc_list.GetSize();
+
+ 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 ®ex,
+ 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
- {
- std::string qualified_name = cpp_method.GetScopeQualifiedName();
- if (qualified_name.compare(m_name.GetCString()) != 0)
- {
- sc_list.RemoveContextAtIndex(i);
- continue;
- }
- }
+ sc_list[pos->second].symbol = sc.symbol;
+ }
}
- ++i;
+ }
}
+ }
}
+ }
+ 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);
-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();
-
- // 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);
-
- 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);
- }
- }
-
- const size_t new_size = sc_list.GetSize();
-
- if (old_size < new_size)
- lookup_info.Prune (sc_list, old_size);
- }
+ 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
- {
- 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;
+ output_extern.push_back(addr);
+ }
}
-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 ();
+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)
- {
- 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;
- }
+ return symbols->FindTypes(sc, name, parent_decl_ctx, append, max_matches,
+ searched_symbol_files, types);
+ }
+ return 0;
+}
- 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;
- }
- }
- }
- }
- }
- }
+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;
}
- 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
- output_extern.push_back (addr);
+ 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();
}
-}
-
-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);
+ } 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 0;
+ }
+ if (num_matches > 0)
+ sc.SortTypeList(typesmap, types);
+ return num_matches;
}
-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;
- }
- 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();
- }
- }
- 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);
- }
- }
- 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(LLVM_PRETTY_FUNCTION, LLVM_PRETTY_FUNCTION);
- m_symfile_ap.reset(SymbolVendor::FindPlugin(shared_from_this(), feedback_strm));
- m_did_load_symbol_vendor = true;
- }
- }
- }
- 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 += ')';
- }
- return spec;
-}
-
-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);
+ }
+ return m_symfile_ap.get();
}
-void
-Module::ReportError (const char *format, ...)
-{
- if (format && format[0])
- {
+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 += ')';
+ }
+ 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.GetString().c_str());
+ }
+}
+
+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: ");
- 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());
- }
-}
-
-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());
- }
- }
- }
-}
-
-void
-Module::ReportWarning (const char *format, ...)
-{
- if (format && format[0])
- {
- 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.GetString().c_str());
+ }
}
+ }
}
-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();
}
+ Host::SystemLog(Host::eSystemLogWarning, "%s", strm.GetString().c_str());
+ }
}
-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());
- }
+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::Dump(Stream *s)
-{
+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());
+ }
+}
+
+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);
+
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ symbols->Dump(s);
+
+ s->IndentLess();
+}
+
+TypeList *Module::GetTypeList() {
+ SymbolVendor *symbols = GetSymbolVendor();
+ if (symbols)
+ return &symbols->GetTypeList();
+ return nullptr;
+}
+
+const ConstString &Module::GetObjectName() const { return m_object_name; }
+
+ObjectFile *Module::GetObjectFile() {
+ if (!m_did_load_objfile.load()) {
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);
-
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- symbols->Dump(s);
-
- s->IndentLess();
-}
-
-TypeList*
-Module::GetTypeList ()
-{
- SymbolVendor *symbols = GetSymbolVendor ();
- if (symbols)
- return &symbols->GetTypeList();
- return nullptr;
-}
-
-const ConstString &
-Module::GetObjectName() const
-{
- return m_object_name;
-}
-
-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());
- }
- }
+ 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();
+ }
+ return m_objfile_sp.get();
}
-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);
- }
- }
-}
-
-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 ®ex, 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(),
- 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;
-}
-
-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);
- }
- }
- }
- }
- }
- // 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)
-{
+SectionList *Module::GetSectionList() {
+ // Populate m_unified_sections_ap with sections from objfile.
+ if (!m_sections_ap) {
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 != 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);
}
+ }
+}
+
+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 ®ex,
+ 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(), 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;
+}
+
+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);
+ }
+ }
+ }
+ }
+ }
+ // 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::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::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;
}
-
- 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 false;
}
-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;
- }
+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;
+ }
+
+ 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;
}
-
-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;
- }
-
- 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;
- }
+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::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::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::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::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;
+ }
+
+ 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;
}
-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;
+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);
+}
+
+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/lldb/source/Core/ModuleChild.cpp b/lldb/source/Core/ModuleChild.cpp
index 9637fc3..8649574 100644
--- a/lldb/source/Core/ModuleChild.cpp
+++ b/lldb/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 &ModuleChild::operator=(const ModuleChild &rhs) {
+ if (this != &rhs)
+ m_module_wp = rhs.m_module_wp;
+ return *this;
}
-ModuleChild::ModuleChild (const ModuleChild& rhs) :
- m_module_wp(rhs.m_module_wp)
-{
-}
+lldb::ModuleSP ModuleChild::GetModule() const { return m_module_wp.lock(); }
-ModuleChild::~ModuleChild()
-{
-}
-
-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();
-}
-
-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/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index bfd53e7..a97be86 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -28,1131 +28,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(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(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;
- }
+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;
+ }
+ return *this;
}
ModuleList::~ModuleList() = default;
-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);
+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::Append(const ModuleSP &module_sp) { AppendImpl(module_sp); }
+
+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);
+ }
+}
+
+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;
+ }
+ return false;
+}
+
+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::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->ModuleAdded(*this, module_sp);
- }
-}
-
-void
-ModuleList::Append (const ModuleSP &module_sp)
-{
- AppendImpl (module_sp);
-}
-
-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);
- }
-}
-
-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);
+ m_notifier->ModuleRemoved(*this, module_sp);
return true;
+ }
}
- return false;
-}
-
-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::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)
-{
+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::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;
+ }
+ }
+ }
+ return false;
+}
+
+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) {
+ 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::Clear() { ClearImpl(); }
+
+void ModuleList::Destroy() { ClearImpl(); }
+
+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();
+}
+
+Module *ModuleList::GetModulePointerAtIndex(size_t idx) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ return GetModulePointerAtIndexUnlocked(idx);
+}
+
+Module *ModuleList::GetModulePointerAtIndexUnlocked(size_t idx) const {
+ if (idx < m_modules.size())
+ return m_modules[idx].get();
+ return nullptr;
+}
+
+ModuleSP ModuleList::GetModuleAtIndex(size_t idx) const {
+ std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
+ return GetModuleAtIndexUnlocked(idx);
+}
+
+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 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;
+}
+
+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);
+ }
+
+ 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)->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 ®ex,
+ 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 ®ex, 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);
- collection::iterator retval = m_modules.erase(pos);
- if (use_notifier && m_notifier)
- m_notifier->ModuleRemoved(*this, module_sp);
- return retval;
+ if (module_sp->MatchesModuleSpec(module_spec))
+ matching_module_list.Append(module_sp);
+ }
+ return matching_module_list.GetSize() - existing_matches;
}
-bool
-ModuleList::Remove (const ModuleSP &module_sp)
-{
- return RemoveImpl (module_sp);
-}
+ModuleSP ModuleList::FindModule(const Module *module_ptr) const {
+ ModuleSP 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;
- }
- }
- }
- return false;
-}
-
-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)
-{
- 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::Clear()
-{
- ClearImpl();
-}
-
-void
-ModuleList::Destroy()
-{
- ClearImpl();
-}
-
-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();
-}
-
-Module*
-ModuleList::GetModulePointerAtIndex (size_t idx) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- return GetModulePointerAtIndexUnlocked(idx);
-}
-
-Module*
-ModuleList::GetModulePointerAtIndexUnlocked (size_t idx) const
-{
- if (idx < m_modules.size())
- return m_modules[idx].get();
- return nullptr;
-}
-
-ModuleSP
-ModuleList::GetModuleAtIndex(size_t idx) const
-{
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- return GetModuleAtIndexUnlocked(idx);
-}
-
-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 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;
-}
-
-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);
- }
-
-
- 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)->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();
-
+ // 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)
- {
- (*pos)->FindFunctions (name, include_symbols, include_inlines, append, sc_list);
+
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if ((*pos).get() == module_ptr) {
+ module_sp = (*pos);
+ break;
+ }
}
-
- return sc_list.GetSize() - old_size;
+ }
+ return module_sp;
}
-size_t
-ModuleList::FindCompileUnits (const FileSpec &path,
- bool append,
- SymbolContextList &sc_list) const
-{
- if (!append)
- sc_list.Clear();
+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)
- {
- (*pos)->FindCompileUnits (path, true, sc_list);
+
+ for (pos = m_modules.begin(); pos != end; ++pos) {
+ if ((*pos)->GetUUID() == uuid) {
+ module_sp = (*pos);
+ break;
+ }
}
-
- return sc_list.GetSize();
+ }
+ return module_sp;
}
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);
+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;
+ }
}
- 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);
+ 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 variable_list.GetSize() - initial_size;
+ }
+
+ return total_matches;
}
-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;
+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;
}
-size_t
-ModuleList::FindSymbolsMatchingRegExAndType (const RegularExpression ®ex,
- 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;
+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);
+ }
}
-size_t
-ModuleList::FindModules (const ModuleSpec &module_spec, ModuleList& matching_module_list) const
-{
- size_t existing_matches = matching_module_list.GetSize();
+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;
+}
+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)
- {
- ModuleSP module_sp(*pos);
- if (module_sp->MatchesModuleSpec (module_spec))
- matching_module_list.Append(module_sp);
+ size = m_modules.size();
+ }
+ return size;
+}
+
+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);
+ }
+}
+
+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());
}
- return matching_module_list.GetSize() - existing_matches;
+ }
}
-ModuleSP
-ModuleList::FindModule (const Module *module_ptr) const
-{
- ModuleSP module_sp;
+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;
+ }
- // Scope for "locker"
- {
- std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
- collection::const_iterator pos, end = m_modules.end();
+ return false;
+}
- for (pos = m_modules.begin(); pos != end; ++pos)
- {
- if ((*pos).get() == module_ptr)
- {
- module_sp = (*pos);
- break;
- }
+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;
+ }
+ }
+
+ 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::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();
+}
+
+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 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;
- }
+ if (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()) {
+ // 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;
}
+
+ shared_module_list.ReplaceEquivalent(module_sp);
+ return error;
+ }
}
- return 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
-{
- 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;
-
-}
-
-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;
-}
-
-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);
- }
-}
-
-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)
- {
- resolved_flags = (*pos)->ResolveSymbolContextForAddress (so_addr,
- resolve_scope,
- sc);
- if (resolved_flags != 0)
- break;
- }
- }
-
- 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::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();
-}
-
-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;
-
+ } else {
module_sp.reset();
+ }
- if (did_create_ptr)
- *did_create_ptr = false;
- if (old_module_sp_ptr)
- old_module_sp_ptr->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;
- const UUID *uuid_ptr = module_spec.GetUUIDPtr();
- const FileSpec &module_file_spec = module_spec.GetFileSpec();
- const ArchSpec &arch = module_spec.GetArchitecture();
+ 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;
+ }
// 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);
+ 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);
- // 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;
- }
- }
- }
- }
-
- if (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())
- {
- // 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 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();
+ }
}
- 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
- {
- 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;
+ 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;
- 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();
- }
+ 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");
+ }
+ }
}
+ }
- // 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)
- {
- 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);
- }
- }
- 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);
+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;
- }
- }
+ 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/lldb/source/Core/Opcode.cpp b/lldb/source/Core/Opcode.cpp
index e36727e..11b9138 100644
--- a/lldb/source/Core/Opcode.cpp
+++ b/lldb/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/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index eb8b3f1..67744da 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/source/Core/PluginManager.cpp
@@ -31,1890 +31,1534 @@
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 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 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;
+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();
}
-template <typename FPtrTy>
-static FPtrTy
-CastToFPtr (void *VPtr)
-{
- return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
+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;
}
-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;
+template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) {
+ return reinterpret_cast<FPtrTy>(reinterpret_cast<intptr_t>(VPtr));
+}
- 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();
- }
+static FileSpec::EnumerateDirectoryResult
+LoadPluginCallback(void *baton, FileSpec::FileType file_type,
+ const FileSpec &file_spec) {
+ // PluginManager *plugin_manager = (PluginManager *)baton;
+ Error error;
- 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();
- }
+ // 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();
- // 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);
+ if (PluginIsLoaded(plugin_file_spec))
+ return FileSpec::eEnumerateDirectoryResultNext;
+ else {
+ PluginInfo plugin_info;
- return FileSpec::eEnumerateDirectoryResultNext;
- }
+ 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 (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;
+ 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;
+ }
+
+ 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);
- }
+ 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);
- }
+ 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 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;
+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;
-}
-
-ABICreateInstance
-PluginManager::GetABICreateCallbackAtIndex (uint32_t idx)
-{
+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());
- ABIInstances &instances = GetABIInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
+}
+
+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::GetABICreateCallbackForPluginName (const ConstString &name)
-{
- if (name)
- {
- std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex());
- ABIInstances &instances = GetABIInstances ();
+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 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;
+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;
-}
-
-DisassemblerCreateInstance
-PluginManager::GetDisassemblerCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- DisassemblerInstances &instances = GetDisassemblerInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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;
-}
-
-DynamicLoaderCreateInstance
-PluginManager::GetDynamicLoaderCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- DynamicLoaderInstances &instances = GetDynamicLoaderInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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;
-}
-
-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::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 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;
+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;
-}
-
-EmulateInstructionCreateInstance
-PluginManager::GetEmulateInstructionCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- EmulateInstructionInstances &instances = GetEmulateInstructionInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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;
-}
-
-OperatingSystemCreateInstance
-PluginManager::GetOperatingSystemCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- OperatingSystemInstances &instances = GetOperatingSystemInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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;
-}
-
-LanguageCreateInstance
-PluginManager::GetLanguageCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- LanguageInstances &instances = GetLanguageInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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);
+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;
-}
-
-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 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;
+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;
-}
-
-SystemRuntimeCreateInstance
-PluginManager::GetSystemRuntimeCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- SystemRuntimeInstances &instances = GetSystemRuntimeInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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)
- {
- }
+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;
+ 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 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;
+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);
+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;
-}
-
-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;
- }
+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;
+ }
+ return nullptr;
}
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;
- }
+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;
}
- return nullptr;
+ }
+ 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;
+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 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;
+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;
-}
-
-ObjectContainerCreateInstance
-PluginManager::GetObjectContainerCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- ObjectContainerInstances &instances = GetObjectContainerInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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;
-}
-
-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;
-}
-
-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;
+}
+
+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;
+}
+
+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::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;
+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;
- }
+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 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;
+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());
+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);
+ 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) {
+ 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;
+ }
}
- 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)
-{
- 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;
- }
- }
- }
- 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 ();
+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;
- }
+ 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);
+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());
- }
+ 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();
+ }
+ 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 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;
+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;
-}
-
-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::GetProcessPluginDescriptionAtIndex (uint32_t idx)
-{
+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) {
+ 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;
-}
+ ProcessInstances &instances = GetProcessInstances();
-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::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;
- }
+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;
}
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;
+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();
+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;
+ 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 (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);
+ // If we didn't find one, return the ScriptInterpreter for the null language.
+ assert(none_instance != nullptr);
+ return none_instance(interpreter);
}
#pragma mark -
@@ -1924,1301 +1568,1070 @@
// StructuredDataPlugin
// -----------------------------------------------------------------------------
-struct StructuredDataPluginInstance
-{
- StructuredDataPluginInstance() :
- name(),
- description(),
- create_callback(nullptr),
- debugger_init_callback(nullptr),
- filter_callback(nullptr)
- {
- }
+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;
+ ConstString name;
+ std::string description;
+ StructuredDataPluginCreateInstance create_callback;
+ DebuggerInitializeCallback debugger_init_callback;
+ StructuredDataFilterLaunchInfo filter_callback;
};
typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances;
-static std::recursive_mutex &
-GetStructuredDataPluginMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
+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;
+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::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;
-}
-
-StructuredDataPluginCreateInstance
-PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx)
-{
+bool PluginManager::UnregisterPlugin(
+ StructuredDataPluginCreateInstance create_callback) {
+ if (create_callback) {
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
StructuredDataPluginInstances &instances =
GetStructuredDataPluginInstances();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+
+ 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;
+}
+
+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;
}
StructuredDataPluginCreateInstance
PluginManager::GetStructuredDataPluginCreateCallbackForPluginName(
- const ConstString &name)
-{
- if (name)
- {
- 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 (name == pos->name)
- return pos->create_callback;
- }
- }
- return nullptr;
-}
-
-StructuredDataFilterLaunchInfo
-PluginManager::GetStructuredDataFilterCallbackAtIndex(uint32_t idx,
- bool &iteration_complete)
-{
+ const ConstString &name) {
+ if (name) {
std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex());
StructuredDataPluginInstances &instances =
GetStructuredDataPluginInstances();
- if (idx < instances.size())
- {
- iteration_complete = false;
- return instances[idx].filter_callback;
+
+ StructuredDataPluginInstances::iterator pos, end = instances.end();
+ for (pos = instances.begin(); pos != end; ++pos) {
+ if (name == pos->name)
+ return pos->create_callback;
}
- else
- {
- iteration_complete = true;
- }
- return nullptr;
+ }
+ return nullptr;
+}
+
+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 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;
+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;
-}
-
-SymbolFileCreateInstance
-PluginManager::GetSymbolFileCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- SymbolFileInstances &instances = GetSymbolFileInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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;
-}
-
-SymbolVendorCreateInstance
-PluginManager::GetSymbolVendorCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- SymbolVendorInstances &instances = GetSymbolVendorInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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;
-}
-
-UnwindAssemblyCreateInstance
-PluginManager::GetUnwindAssemblyCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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;
-}
-
-MemoryHistoryCreateInstance
-PluginManager::GetMemoryHistoryCreateCallbackAtIndex (uint32_t idx)
-{
+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());
- MemoryHistoryInstances &instances = GetMemoryHistoryInstances ();
- if (idx < instances.size())
- return instances[idx].create_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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;
+typedef std::vector<InstrumentationRuntimeInstance>
+ InstrumentationRuntimeInstances;
-static std::recursive_mutex &
-GetInstrumentationRuntimeMutex()
-{
- static std::recursive_mutex g_instances_mutex;
- return g_instances_mutex;
+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;
+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);
+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;
-}
-
-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 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;
+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);
+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;
-}
-
-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;
- }
- }
- return nullptr;
-}
-
-TypeSystemEnumerateSupportedLanguages
-PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex (uint32_t idx)
-{
+PluginManager::GetTypeSystemCreateCallbackForPluginName(
+ const ConstString &name) {
+ if (name) {
std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex());
- TypeSystemInstances &instances = GetTypeSystemInstances ();
- if (idx < instances.size())
- return instances[idx].enumerate_callback;
- return nullptr;
+ 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;
}
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::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;
}
- 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 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;
+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);
+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();
+
+ 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;
+ }
+ return false;
}
-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;
+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::GetREPLCreateCallbackAtIndex (uint32_t idx)
-{
+PluginManager::GetREPLCreateCallbackForPluginName(const ConstString &name) {
+ if (name) {
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();
-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;
- }
+ 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();
- // 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);
- }
+ 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 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 JITLoader plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex());
+ JITLoaderInstances &instances = GetJITLoaderInstances();
- // 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);
- }
+ 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 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 Platform plugins
+ {
+ std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+ PlatformInstances &instances = GetPlatformInstances();
- // 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);
- }
+ 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 StructuredDataPlugin plugins
- {
- std::lock_guard<std::recursive_mutex>
- guard(GetStructuredDataPluginMutex());
- for (auto &plugin: GetStructuredDataPluginInstances())
- {
- if (plugin.debugger_init_callback)
- plugin.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 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;
- }
+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);
}
- return lldb::OptionValuePropertiesSP();
+
+ 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;
+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;
- }
+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* kStructuredDataPluginName("structured-data");
+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));
+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);
+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);
+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);
+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));
+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);
+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));
+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);
+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;
- }
+ 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;
+ }
+ return false;
}
-lldb::OptionValuePropertiesSP
-PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger,
- const ConstString &setting_name)
-{
- return GetSettingForPlugin(debugger, setting_name, ConstString(kStructuredDataPluginName));
+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);
+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/lldb/source/Core/RegisterValue.cpp b/lldb/source/Core/RegisterValue.cpp
index d9085d7..a19b0f3 100644
--- a/lldb/source/Core/RegisterValue.cpp
+++ b/lldb/source/Core/RegisterValue.cpp
@@ -23,1012 +23,934 @@
#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 (" = ");
+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;
+ 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
+ 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;
+}
+
+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;
+ }
+
+ // 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);
+
+ 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;
}
- 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;
}
-bool
-RegisterValue::GetData (DataExtractor &data) const
-{
- return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
+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);
+
+ return m_type;
}
-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;
-}
+Error RegisterValue::SetValueFromData(const RegisterInfo *reg_info,
+ DataExtractor &src,
+ lldb::offset_t src_offset,
+ bool partial_data_ok) {
+ Error error;
-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;
- }
-
- // 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);
-
- 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;
- }
- return false;
-}
-
-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);
-
- 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;
- }
-
- if (reg_info->byte_size == 0)
- {
- error.SetErrorString ("invalid register info.");
- 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;
-
- // 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);
+ if (src.GetByteSize() == 0) {
+ error.SetErrorString("empty data.");
return error;
+ }
+
+ if (reg_info->byte_size == 0) {
+ error.SetErrorString("invalid register info.");
+ 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;
+
+ // 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;
}
-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);
+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);
}
-static inline void LStrip(llvm::StringRef &Str, char c)
-{
- if (!Str.empty() && Str.front() == c)
- Str = Str.substr(1);
+static inline void LStrip(llvm::StringRef &Str, char c) {
+ if (!Str.empty() && Str.front() == c)
+ Str = Str.substr(1);
}
-static inline void RStrip(llvm::StringRef &Str, char c)
-{
- if (!Str.empty() && Str.back() == c)
- Str = Str.substr(0, Str.size()-1);
+static inline void RStrip(llvm::StringRef &Str, char c) {
+ if (!Str.empty() && Str.back() == c)
+ Str = Str.substr(0, Str.size() - 1);
}
// 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);
+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 = ' ';
+ 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;
+ // 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);
- }
+ // 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);
+ }
- // Check for vector of exact byte_size elements.
- if (bytes.size() != byte_size)
- return false;
+ // Check for vector of exact byte_size elements.
+ if (bytes.size() != byte_size)
+ return false;
- reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
- return true;
+ reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
+ return true;
}
-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;
- }
-
- if (value_str == nullptr || value_str[0] == '\0')
- {
- error.SetErrorString ("Invalid c-string value string.");
- return error;
- }
- 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 (error.Fail())
- m_type = eTypeInvalid;
-
+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;
+ }
+
+ if (value_str == nullptr || value_str[0] == '\0') {
+ error.SetErrorString("Invalid c-string value string.");
+ return error;
+ }
+ 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 (error.Fail())
+ m_type = eTypeInvalid;
+
+ return error;
}
-bool
-RegisterValue::SignExtend (uint32_t sign_bitpos)
-{
- switch (m_type)
- {
- case eTypeInvalid:
- 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;
- }
+ 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;
}
-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;
+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;
}
- return true;
+ } break;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
}
-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;
+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;
}
-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;
+uint64_t RegisterValue::GetAsUInt64(uint64_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 eTypeUInt64:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.ULongLong(fail_value);
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ return *(const uint64_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
-{
- if (success_ptr)
- *success_ptr = true;
- switch (m_type)
- {
- default: break;
- case eTypeUInt8:
- case eTypeUInt16:
- case eTypeUInt32:
- case eTypeUInt64:
- case eTypeFloat:
- case eTypeDouble:
- case eTypeLongDouble: return m_scalar.ULongLong(fail_value);
- case eTypeBytes:
- {
- switch (buffer.length)
- {
- default: break;
- case 1:
- case 2:
- case 4:
- case 8: return *(const uint64_t *)buffer.bytes;
- }
- }
- 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;
}
-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;
- }
- 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
+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;
+ }
+ }
+ return false;
+}
+
+bool RegisterValue::operator!=(const RegisterValue &rhs) const {
+ if (m_type != rhs.m_type)
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;
- }
-}
-
-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;
- }
- }
+ 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;
+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.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;
+ 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 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 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/lldb/source/Core/RegularExpression.cpp b/lldb/source/Core/RegularExpression.cpp
index bdef3ce..bc3b516 100644
--- a/lldb/source/Core/RegularExpression.cpp
+++ b/lldb/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(const char *re)
+ : m_re(), m_comp_err(1), m_preg() {
+ memset(&m_preg, 0, sizeof(m_preg));
+ Compile(re);
}
-RegularExpression::RegularExpression(const RegularExpression &rhs)
-{
- memset(&m_preg,0,sizeof(m_preg));
+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());
-}
-
-const RegularExpression &
-RegularExpression::operator= (const RegularExpression &rhs)
-{
- if (&rhs != this)
- Compile (rhs.GetText());
- return *this;
+ return *this;
}
//----------------------------------------------------------------------
@@ -73,10 +64,7 @@
// 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 @@
// 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;
- }
+bool RegularExpression::Compile(const char *re) {
+ Free();
- return m_comp_err == 0;
+ 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;
}
//----------------------------------------------------------------------
@@ -117,145 +100,109 @@
// 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);
- }
+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;
- }
+ }
+
+ 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,
+ 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;
}
-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;
+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;
+
+ 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;
}
- return false;
+ }
+ return false;
}
-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;
-
- 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::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;
}
- 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;
- }
- }
- 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());
+const char *RegularExpression::GetText() const {
+ return (m_re.empty() ? nullptr : m_re.c_str());
}
//----------------------------------------------------------------------
// 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/lldb/source/Core/Scalar.cpp b/lldb/source/Core/Scalar.cpp
index ae0e216..6087f72 100644
--- a/lldb/source/Core/Scalar.cpp
+++ b/lldb/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 @@
// 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();
+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
- }
+ 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
+ // 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;
+ // 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() : 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 Scalar &rhs)
+ : m_type(rhs.m_type), m_integer(rhs.m_integer), m_float(rhs.m_float) {}
-//Scalar::Scalar(const RegisterValue& reg) :
+// Scalar::Scalar(const RegisterValue& reg) :
// m_type(e_void),
// m_data()
//{
@@ -103,7 +97,8 @@
// 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 @@
// 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,976 +128,1066 @@
// }
//}
-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());
+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;
+ 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.Clear();
- return false;
+
+ 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);
+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 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 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 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 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 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).c_str());
- break;
- case e_uint:
- case e_ulong:
- case e_ulonglong:
- case e_uint128:
- case e_uint256:
- s->PutCString(m_integer.toString(10, 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 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;
}
-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>";
+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;
}
-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;
+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;
}
-Scalar&
-Scalar::operator= (const int v)
-{
- m_type = e_sint;
- m_integer = llvm::APInt(sizeof(int) * 8, v, true);
- return *this;
+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).c_str());
+ break;
+ case e_uint:
+ case e_ulong:
+ case e_ulonglong:
+ case e_uint128:
+ case e_uint256:
+ s->PutCString(m_integer.toString(10, 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;
+ }
}
-Scalar&
-Scalar::operator= (unsigned int v)
-{
- m_type = e_uint;
- m_integer = llvm::APInt(sizeof(int) * 8, v);
- return *this;
+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= (long v)
-{
- m_type = e_slong;
- m_integer = llvm::APInt(sizeof(long) * 8, v, true);
- return *this;
+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= (unsigned long v)
-{
- m_type = e_ulong;
- m_integer = llvm::APInt(sizeof(long) * 8, v);
- 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= (long long v)
-{
- m_type = e_slonglong;
- m_integer = llvm::APInt(sizeof(long) * 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= (unsigned long long v)
-{
- m_type = e_ulonglong;
- m_integer = llvm::APInt(sizeof(long long) * 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= (float v)
-{
- m_type = e_float;
- m_float = llvm::APFloat(v);
- 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= (double v)
-{
- m_type = e_double;
- m_float = llvm::APFloat(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= (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));
+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)
- {
+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;
-
+ 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;
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
- case e_double:
- m_float = llvm::APFloat(m_integer.bitsToDouble());
- success = true;
- break;
-
- case e_long_double:
- if(m_ieee_quad)
- m_float = llvm::APFloat(llvm::APFloat::IEEEquad, m_integer);
- else
- m_float = llvm::APFloat(llvm::APFloat::x87DoubleExtended, m_integer);
- success = true;
- break;
- }
- break;
-
case e_float:
- switch (type)
- {
- case e_void:
- case e_sint:
- case e_uint:
- case e_slong:
- case e_ulong:
- case e_slonglong:
- case e_ulonglong:
- 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 (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;
- if (success)
- m_type = type;
- return success;
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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";
- }
- return "???";
+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;
+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;
}
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::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;
+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)
- {
+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;
+ 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;
+
+ case e_float:
+ switch (type) {
+ case e_void:
+ break;
case e_sint:
case e_uint:
case e_slong:
@@ -1112,265 +1198,33 @@
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:
- 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_float.bitcastToAPInt();
+ 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_float.convertToFloat());
+ 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_float.convertToFloat());
+ 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 (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;
- 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;
- }
-
- return success;
-}
-
-signed char
-Scalar::SChar(char 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:
@@ -1381,24 +1235,670 @@
case e_uint128:
case e_sint256:
case e_uint256:
- return (schar_t)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
+ m_integer = m_float.bitcastToAPInt();
+ success = true;
+ break;
case e_float:
- return (schar_t)m_float.convertToFloat();
+ m_float = llvm::APFloat(m_float.convertToDouble());
+ success = true;
+ break;
case e_double:
- return (schar_t)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 (schar_t)(ldbl_val.sextOrTrunc(sizeof(schar_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;
+
+ 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;
}
-unsigned char
-Scalar::UChar(unsigned char fail_value) const
-{
- switch (m_type)
- {
- case 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:
@@ -1409,472 +1909,45 @@
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;
-}
+ m_integer = a->m_integer + b->m_integer;
+ break;
-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();
+ m_float = a->m_float + b->m_float;
+ break;
}
- return fail_value;
+ }
+ return *this;
}
-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;
-}
+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;
-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:
- 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;
- }
- }
- return *this;
-}
-
-Scalar&
-Scalar::operator<<= (const Scalar& rhs)
-{
- 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:
+ 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:
@@ -1885,44 +1958,40 @@
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;
+ m_integer = m_integer << rhs.m_integer;
+ break;
}
- return *this;
+ break;
+ }
+ return *this;
}
-bool
-Scalar::ShiftRightLogical(const Scalar& rhs)
-{
- switch (m_type)
- {
+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:
@@ -1933,44 +2002,40 @@
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_integer = m_integer.lshr(rhs.m_integer);
+ break;
}
- return m_type != e_void;
+ break;
+ }
+ return m_type != e_void;
}
-Scalar&
-Scalar::operator>>= (const Scalar& rhs)
-{
- switch (m_type)
- {
+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 +2046,40 @@
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.ashr(rhs.m_integer);
+ break;
}
- return *this;
+ break;
+ }
+ return *this;
}
-Scalar&
-Scalar::operator&= (const Scalar& rhs)
-{
- switch (m_type)
- {
+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:
@@ -2029,1034 +2090,987 @@
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 &= rhs.m_integer;
+ break;
}
- return *this;
+ break;
+ }
+ return *this;
}
-bool
-Scalar::AbsoluteValue()
-{
- switch (m_type)
- {
- case e_void:
- break;
+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;
-
- 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;
-
- 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;
- }
- }
- 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;
-
- 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;
- }
+ 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
-lldb_private::operator< (const Scalar& lhs, const Scalar& rhs)
-{
- if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
- 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;
+}
- 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;
+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;
+
+ 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:
- 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;
+ }
+ // 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;
}
-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;
+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;
+}
- 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;
+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:
- 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:
- return a->m_integer.ule(b->m_integer);
+ 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:
- 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;
}
-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;
+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;
}
- return false;
+ } 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;
+
+ 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/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp
index 202a40f..5736b11 100644
--- a/lldb/source/Core/SearchFilter.cpp
+++ b/lldb/source/Core/SearchFilter.cpp
@@ -12,11 +12,11 @@
// 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;
@@ -25,76 +25,40 @@
Searcher::~Searcher() = default;
-void
-Searcher::GetDescription (Stream *s)
-{
-}
+void Searcher::GetDescription(Stream *s) {}
-SearchFilter::SearchFilter(const TargetSP &target_sp) :
- m_target_sp (target_sp)
-{
-}
+SearchFilter::SearchFilter(const TargetSP &target_sp)
+ : m_target_sp(target_sp) {}
-SearchFilter::SearchFilter(const SearchFilter& rhs) = default;
+SearchFilter::SearchFilter(const SearchFilter &rhs) = default;
-SearchFilter&
-SearchFilter::operator=(const SearchFilter& rhs) = default;
+SearchFilter &SearchFilter::operator=(const SearchFilter &rhs) = default;
SearchFilter::~SearchFilter() = default;
-bool
-SearchFilter::ModulePasses (const FileSpec &spec)
-{
- return true;
+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;
}
-bool
-SearchFilter::ModulePasses (const ModuleSP &module_sp)
-{
- return true;
-}
+void SearchFilter::GetDescription(Stream *s) {}
-bool
-SearchFilter::AddressPasses (Address &address)
-{
- return true;
-}
+void SearchFilter::Dump(Stream *s) const {}
-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;
+lldb::SearchFilterSP SearchFilter::CopyForBreakpoint(Breakpoint &breakpoint) {
+ SearchFilterSP ret_sp = DoCopyForBreakpoint(breakpoint);
+ TargetSP target_sp = breakpoint.GetTargetSP();
+ ret_sp->SetTarget(target_sp);
+ return ret_sp;
}
//----------------------------------------------------------------------
@@ -102,191 +66,165 @@
// 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();
+ 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;
- }
- }
+ 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);
- }
+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;
}
- 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;
+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());
+ if (searcher.GetDepth() == Searcher::eDepthCompUnit) {
+ SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
- shouldContinue = searcher.SearchCallback(*this, matchingContext, nullptr, false);
+ 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.
- }
- }
+ 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".
//----------------------------------------------------------------------
-bool
-SearchFilterForUnconstrainedSearches::ModulePasses (const FileSpec &module_spec)
-{
- if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches (module_spec))
- return false;
- else
- return true;
+bool SearchFilterForUnconstrainedSearches::ModulePasses(
+ const FileSpec &module_spec) {
+ if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_spec))
+ return false;
+ else
+ return true;
}
-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 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;
+lldb::SearchFilterSP SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint(
+ Breakpoint &breakpoint) {
+ SearchFilterSP ret_sp(new SearchFilterForUnconstrainedSearches(*this));
+ return ret_sp;
}
//----------------------------------------------------------------------
@@ -294,126 +232,97 @@
// 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), 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;
-void
-SearchFilterByModule::Search (Searcher &searcher)
-{
- if (!m_target_sp)
+ 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;
-
- 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;
}
//----------------------------------------------------------------------
@@ -421,160 +330,130 @@
// 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), m_module_spec_list(module_list) {}
-SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) = default;
+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::
+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;
+
+ if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX)
+ return true;
+ else
+ return false;
}
-void
-SearchFilterByModuleList::Search (Searcher &searcher)
-{
- if (!m_target_sp)
+bool SearchFilterByModuleList::AddressPasses(Address &address) {
+ // FIXME: Not yet implemented
+ return true;
+}
+
+bool SearchFilterByModuleList::CompUnitPasses(FileSpec &fileSpec) {
+ return true;
+}
+
+bool SearchFilterByModuleList::CompUnitPasses(CompileUnit &compUnit) {
+ return true;
+}
+
+void SearchFilterByModuleList::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.
+
+ 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;
-
- 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;
}
//----------------------------------------------------------------------
@@ -582,174 +461,140 @@
// 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),
+ 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;
+bool SearchFilterByModuleListAndCU::AddressPasses(Address &address) {
+ return true;
}
-bool
-SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec)
-{
- return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
+bool SearchFilterByModuleListAndCU::CompUnitPasses(FileSpec &fileSpec) {
+ return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
}
-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::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;
}
-void
-SearchFilterByModuleListAndCU::Search (Searcher &searcher)
-{
- if (!m_target_sp)
- 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 (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.
+ // 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());
+ 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;
+ 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;
+ 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;
}
- 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/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp
index 9622cb7..95bcdad 100644
--- a/lldb/source/Core/Section.cpp
+++ b/lldb/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;
+ : 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()
-{
-// printf ("Section::~Section(%p)\n", this);
+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;
}
-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;
- }
+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;
- }
-}
-
-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;
-}
-
-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);
- }
- }
- 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());
-#endif
+ m_file_addr = file_addr;
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();
- }
- }
- return false;
+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;
}
-int
-Section::Compare (const Section& a, const Section& b)
-{
- if (&a == &b)
- 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;
+}
- 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;
+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());
+
+#ifdef LLDB_CONFIGURATION_DEBUG
+ // For debug builds, ensure that there are no orphaned (i.e., moduleless)
+ // sections.
+ assert(GetModule().get());
+#endif
+ 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();
+ }
+ }
+ 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
- {
- // 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
- }
+ 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;
-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 (GetByteSize() == 0)
- s->Printf("%39s", "");
- 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);
+ 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);
+ }
- DumpName (s);
+ 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());
- s->EOL();
+ DumpName(s);
- if (depth > 0)
- m_children.Dump(s, target, false, depth - 1);
+ s->EOL();
+
+ 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();
+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);
+ 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 §ion_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::operator=(const SectionList &rhs) {
+ if (this != &rhs)
+ m_sections = rhs.m_sections;
+ return *this;
}
+size_t SectionList::AddSection(const lldb::SectionSP §ion_sp) {
+ if (section_sp) {
+ size_t section_index = m_sections.size();
+ m_sections.push_back(section_sp);
+ return section_index;
+ }
-SectionList::~SectionList ()
-{
-}
-
-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;
- }
-
- 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;
+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);
- }
+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;
+ }
+ 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;
+size_t SectionList::AddUniqueSection(const lldb::SectionSP §_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::ReplaceSection(user_id_t sect_id,
+ const lldb::SectionSP §_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 false;
+ }
+ 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);
- }
+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 count;
+ }
+ return count;
+}
+
+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::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 §ion_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;
-}
-
-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::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;
- }
- }
- return sect_sp;
-}
-
-SectionSP
-SectionList::FindSectionContainingFileAddress (addr_t vm_addr, uint32_t depth) const
-{
- SectionSP sect_sp;
+SectionList::FindSectionByName(const ConstString §ion_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 *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) {
+ 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;
}
-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");
- }
-
-
+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_iter)
- {
- (*sect_iter)->Dump(s, target_has_loaded_sections ? target : NULL, depth);
+ 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);
+ }
}
-
- if (show_header && !m_sections.empty())
- s->IndentLess();
-
+ }
+ return sect_sp;
}
-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;
+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;
}
- return count;
+ }
+ 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;
+}
+
+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");
+ }
+
+ 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/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp
index a69e75f..b262ad6 100644
--- a/lldb/source/Core/SourceManager.cpp
+++ b/lldb/source/Core/SourceManager.cpp
@@ -26,674 +26,554 @@
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()) {
+ file_sp.reset(new File(file_spec, target_sp.get()));
+
+ if (debugger_sp)
+ debugger_sp->GetSourceFileCache().AddSourceFile(file_sp);
+ }
+ return file_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;
-}
-
-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;
- }
-
- 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, 0, 0, s);
- if (this_line_size == 0)
- {
- m_last_line = UINT32_MAX;
- break;
- }
- else
- return_value += this_line_size;
- }
- }
- return return_value;
-}
-
-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;
- 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, 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;
- }
- else if (have_default_file_line)
- m_last_line += m_last_count;
- }
- else
- m_last_line = 1;
-
- return DisplaySourceLinesWithLineNumbersUsingLastFile (m_last_line, m_last_count, UINT32_MAX, "", s, bp_locs);
- }
+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;
-}
-
-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;
- }
+ 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
- {
- m_last_file_sp = old_file_sp;
- return false;
+ 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, 0, 0, s);
+ if (this_line_size == 0) {
+ m_last_line = UINT32_MAX;
+ break;
+ } else
+ return_value += this_line_size;
}
+ }
+ return return_value;
}
-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());
+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));
- 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;
-}
+ 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;
-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();
- }
- }
- }
- }
-
- if (m_mod_time.IsValid())
- m_data_sp = m_file_spec.ReadFileContents ();
-}
-
-SourceManager::File::~File()
-{
-}
-
-uint32_t
-SourceManager::File::GetLineOffset (uint32_t line)
-{
+ if (m_last_file_sp.get() != file_sp.get()) {
if (line == 0)
- return UINT32_MAX;
-
- 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;
+ m_last_line = 0;
+ m_last_file_sp = file_sp;
+ }
+ return DisplaySourceLinesWithLineNumbersUsingLastFile(
+ start_line, count, line, current_line_cstr, s, bp_locs);
}
-uint32_t
-SourceManager::File::GetNumLines ()
-{
- CalculateLineOffsets();
- return m_offsets.size();
-}
+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);
+ }
-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;
-}
+ if (m_last_file_sp) {
+ if (m_last_line == UINT32_MAX)
+ return 0;
-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;
- }
- return 0;
-}
+ if (reverse && m_last_line == 1)
+ return 0;
-bool
-SourceManager::File::LineIsValid (uint32_t line)
-{
- if (line == 0)
- return false;
+ if (count > 0)
+ m_last_count = count;
+ else if (m_last_count == 0)
+ m_last_count = 10;
- 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();
- }
-}
-
-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();
- }
- 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);
- }
- }
-}
-
-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;
+ 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
- return true;
- }
- else
- return false;
+ m_last_line = 1;
+ } else if (have_default_file_line)
+ 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;
}
-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;
+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);
- 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;
- }
- }
- else
- {
- // Some lines have been populated, start where we last left off
- assert("Not implemented yet" && 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;
-
- 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);
-
+ 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;
+ }
}
-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;
+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;
}
-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::FindLinesMatchingRegex(FileSpec &file_spec,
+ RegularExpression ®ex,
+ 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();
+ }
+ }
+ }
+ }
+
+ if (m_mod_time.IsValid())
+ m_data_sp = m_file_spec.ReadFileContents();
+}
+
+SourceManager::File::~File() {}
+
+uint32_t SourceManager::File::GetLineOffset(uint32_t line) {
+ if (line == 0)
+ return UINT32_MAX;
+
+ 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;
+}
+
+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;
+ 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;
+ }
+ return 0;
+}
+
+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();
+ }
+}
+
+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();
+ }
+ return bytes_written;
+ }
+ return 0;
+}
+
+void SourceManager::File::FindLinesMatchingRegex(
+ RegularExpression ®ex, 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);
+ }
+ }
+}
+
+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 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;
+ }
+ } else {
+ // Some lines have been populated, start where we last left off
+ assert("Not implemented yet" && 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;
+
+ 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;
+}
+
+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/lldb/source/Core/State.cpp b/lldb/source/Core/State.cpp
index 7d9ccda..80497dd 100644
--- a/lldb/source/Core/State.cpp
+++ b/lldb/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/lldb/source/Core/Stream.cpp b/lldb/source/Core/Stream.cpp
index 172be77..f8d78c3 100644
--- a/lldb/source/Core/Stream.cpp
+++ b/lldb/source/Core/Stream.cpp
@@ -12,776 +12,608 @@
#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);
- }
+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);
- }
+ } 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
- {
+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;
+ 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(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);
}
//------------------------------------------------------------------
// 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);
+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);
-}
-
+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;
+size_t Stream::PrintfVarArg(const char *format, va_list args) {
+ char str[1024];
+ va_list args_copy;
- va_copy (args_copy, args);
+ 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);
+ 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);
}
- 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 : "");
}
//------------------------------------------------------------------
// 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 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;
-}
+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
+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);
+ 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
- {
- // 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);
+ }
+ va_end(args);
+ va_end(args_copy);
- return bytes_written;
+ 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::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");
+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;
+ 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::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;
+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;
+ 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;
+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;
+ 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;
+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;
+ 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::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::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;
+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);
+ 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;
+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);
+ 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;
+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);
+ 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;
+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;
+ 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 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::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;
+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;
}
-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/lldb/source/Core/StreamAsynchronousIO.cpp b/lldb/source/Core/StreamAsynchronousIO.cpp
index 6f8fcce..af2bd2a 100644
--- a/lldb/source/Core/StreamAsynchronousIO.cpp
+++ b/lldb/source/Core/StreamAsynchronousIO.cpp
@@ -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/lldb/source/Core/StreamCallback.cpp b/lldb/source/Core/StreamCallback.cpp
index 9f0adee..de78410 100644
--- a/lldb/source/Core/StreamCallback.cpp
+++ b/lldb/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()
-{
+ : 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;
}
-StreamCallback::~StreamCallback ()
-{
+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();
}
-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();
-}
-
-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/lldb/source/Core/StreamFile.cpp b/lldb/source/Core/StreamFile.cpp
index 8c9700c..f8c7fb9a 100644
--- a/lldb/source/Core/StreamFile.cpp
+++ b/lldb/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/lldb/source/Core/StreamGDBRemote.cpp b/lldb/source/Core/StreamGDBRemote.cpp
index 46cb99c..a371d13 100644
--- a/lldb/source/Core/StreamGDBRemote.cpp
+++ b/lldb/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/lldb/source/Core/StreamString.cpp b/lldb/source/Core/StreamString.cpp
index 36e086b..cb08808 100644
--- a/lldb/source/Core/StreamString.cpp
+++ b/lldb/source/Core/StreamString.cpp
@@ -13,104 +13,57 @@
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() {}
+
+void StreamString::Flush() {
+ // Nothing to do when flushing a buffer based stream...
}
-StreamString::StreamString(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) :
- Stream (flags, addr_size, byte_order),
- m_packet ()
-{
+size_t StreamString::Write(const void *s, size_t length) {
+ m_packet.append(reinterpret_cast<const char *>(s), length);
+ return length;
}
-StreamString::~StreamString()
-{
-}
+void StreamString::Clear() { m_packet.clear(); }
-void
-StreamString::Flush ()
-{
- // Nothing to do when flushing a buffer based stream...
-}
+bool StreamString::Empty() const { return GetSize() == 0; }
-size_t
-StreamString::Write (const void *s, size_t length)
-{
- m_packet.append (reinterpret_cast<const char *>(s), length);
+const char *StreamString::GetData() const { return m_packet.c_str(); }
+
+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;
+ }
}
-void
-StreamString::Clear()
-{
- m_packet.clear();
-}
+std::string &StreamString::GetString() { return m_packet; }
-bool
-StreamString::Empty() const
-{
- return GetSize() == 0;
-}
+const std::string &StreamString::GetString() const { return m_packet; }
-const char *
-StreamString::GetData () const
-{
- return m_packet.c_str();
-}
+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;
+ }
-size_t
-StreamString::GetSize () const
-{
- return m_packet.size();
+ const size_t line_columns = length - last_line_begin_pos;
+ if (column > line_columns) {
+ m_packet.append(column - line_columns, fill_char);
+ }
}
-
-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;
-}
-
-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/lldb/source/Core/StringList.cpp b/lldb/source/Core/StringList.cpp
index 98a0790..5085c43 100644
--- a/lldb/source/Core/StringList.cpp
+++ b/lldb/source/Core/StringList.cpp
@@ -9,369 +9,275 @@
#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() {}
+
+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(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(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(StringList strings) {
+ size_t len = strings.GetSize();
+
+ 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);
+}
+
+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;
+}
+
+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();
+
+ if (size == 0)
+ return;
+
+ 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::LongestCommonPrefix(std::string &common_prefix) {
+ const size_t num_strings = m_strings.size();
+
+ 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;
}
+ }
}
-StringList::~StringList ()
-{
-}
-
-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 (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(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 (StringList strings)
-{
- size_t len = strings.GetSize();
-
- 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);
-}
-
-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;
-}
-
-
-const char *
-StringList::GetStringAtIndex (size_t idx) const
-{
+void StringList::InsertStringAtIndex(size_t idx, const char *str) {
+ if (str) {
if (idx < m_strings.size())
- return m_strings[idx].c_str();
- return NULL;
+ m_strings.insert(m_strings.begin() + idx, str);
+ else
+ m_strings.push_back(str);
+ }
}
-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));
+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::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::DeleteStringAtIndex(size_t idx) {
+ if (idx < m_strings.size())
+ m_strings.erase(m_strings.begin() + idx);
+}
+
+size_t StringList::SplitIntoLines(const std::string &lines) {
+ return SplitIntoLines(lines.c_str(), lines.size());
+}
+
+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::Clear ()
-{
- m_strings.clear();
+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++;
+ }
}
-void
-StringList::LongestCommonPrefix (std::string &common_prefix)
-{
+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());
+}
+
+StringList &StringList::operator<<(const char *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=(const std::vector<std::string> &rhs) {
+ Clear();
+ for (const auto &s : rhs)
+ m_strings.push_back(s);
+
+ 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();
- if (num_strings == 0)
- {
- common_prefix.clear();
+ 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
- {
- 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;
- }
- }
+ } else {
+ // No string, so it matches everything
+ matches = *this;
+ }
+ return matches.GetSize();
}
-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::LogDump(Log *log, const char *name) {
+ if (!log)
+ return;
-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);
-}
+ 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);
-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::DeleteStringAtIndex (size_t idx)
-{
- if (idx < m_strings.size())
- m_strings.erase (m_strings.begin() + idx);
-}
-
-size_t
-StringList::SplitIntoLines (const std::string &lines)
-{
- return SplitIntoLines (lines.c_str(), lines.size());
-}
-
-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());
-}
-
-StringList&
-StringList::operator << (const char* 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 = (const std::vector<std::string> &rhs)
-{
- Clear();
- for (const auto &s : rhs)
- m_strings.push_back(s);
-
- 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;
- }
- 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/lldb/source/Core/StructuredData.cpp b/lldb/source/Core/StructuredData.cpp
index 95bdeb5..6e544c1 100644
--- a/lldb/source/Core/StructuredData.cpp
+++ b/lldb/source/Core/StructuredData.cpp
@@ -1,4 +1,5 @@
-//===---------------------StructuredData.cpp ---------------------*- C++ -*-===//
+//===---------------------StructuredData.cpp ---------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,8 +11,8 @@
#include "lldb/Core/StructuredData.h"
#include <errno.h>
-#include <stdlib.h>
#include <inttypes.h>
+#include <stdlib.h>
#include "lldb/Core/StreamString.h"
#include "lldb/Host/StringConvert.h"
@@ -19,313 +20,247 @@
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 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());
+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);
+ 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
-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)
- {
+ 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);
+ dict_up->AddItem(key, 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;
- }
+ 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);
+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());
- 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::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();
- }
-
- 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();
-}
-
-void
-StructuredData::Object::DumpToStdout(bool pretty_print) const
-{
- StreamString stream;
- Dump(stream, pretty_print);
- printf("%s\n", stream.GetString().c_str());
-}
-
-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 << ",";
- 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 << "]";
-}
-
-void
-StructuredData::Integer::Dump (Stream &s, bool pretty_print) const
-{
- s.Printf ("%" PRIu64, m_value);
-}
-
-
-void
-StructuredData::Float::Dump (Stream &s, bool pretty_print) const
-{
- s.Printf ("%lg", m_value);
-}
-
-void
-StructuredData::Boolean::Dump (Stream &s, bool pretty_print) const
-{
- if (m_value == true)
- s.PutCString ("true");
+ std::string value;
+ std::string key;
+ while (1) {
+ StructuredData::ObjectSP value_sp = ParseJSONValue(json_parser);
+ if (value_sp)
+ array_up->AddItem(value_sp);
else
- s.PutCString ("false");
-}
+ break;
-
-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 == '"')
- quoted.push_back ('\\');
- quoted.push_back (ch);
+ 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;
}
- s.Printf ("\"%s\"", quoted.c_str());
+ }
+ return StructuredData::ObjectSP();
}
-void
-StructuredData::Dictionary::Dump (Stream &s, bool pretty_print) const
-{
- bool first = true;
- s << "{";
- if (pretty_print)
- {
+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::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();
+ }
+
+ 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();
+}
+
+void StructuredData::Object::DumpToStdout(bool pretty_print) const {
+ StreamString stream;
+ Dump(stream, pretty_print);
+ printf("%s\n", stream.GetString().c_str());
+}
+
+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 << ",";
+ if (pretty_print)
s << "\n";
- s.IndentMore();
}
- 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.Indent();
+ item_sp->Dump(s, pretty_print);
+ }
+ if (pretty_print) {
+ s.IndentLess();
+ s.EOL();
+ s.Indent();
+ }
+ s << "]";
+}
+
+void StructuredData::Integer::Dump(Stream &s, bool pretty_print) const {
+ s.Printf("%" PRIu64, m_value);
+}
+
+void StructuredData::Float::Dump(Stream &s, bool pretty_print) const {
+ s.Printf("%lg", m_value);
+}
+
+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, 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 == '"')
+ quoted.push_back('\\');
+ quoted.push_back(ch);
+ }
+ s.Printf("\"%s\"", quoted.c_str());
+}
+
+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 << ",";
+ if (pretty_print)
+ s << "\n";
}
if (pretty_print)
- {
- s.IndentLess();
- s.EOL();
- s.Indent();
- }
- s << "}";
+ s.Indent();
+ s << "\"" << pair.first.AsCString() << "\" : ";
+ pair.second->Dump(s, pretty_print);
+ }
+ if (pretty_print) {
+ s.IndentLess();
+ s.EOL();
+ s.Indent();
+ }
+ s << "}";
}
-void
-StructuredData::Null::Dump (Stream &s, bool pretty_print) const
-{
- s << "null";
+void StructuredData::Null::Dump(Stream &s, bool pretty_print) const {
+ s << "null";
}
-void
-StructuredData::Generic::Dump(Stream &s, bool pretty_print) const
-{
- s << "0x" << m_object;
+void StructuredData::Generic::Dump(Stream &s, bool pretty_print) const {
+ s << "0x" << m_object;
}
diff --git a/lldb/source/Core/Timer.cpp b/lldb/source/Core/Timer.cpp
index f4cd33f..613425f 100644
--- a/lldb/source/Core/Timer.cpp
+++ b/lldb/source/Core/Timer.cpp
@@ -22,245 +22,198 @@
#define TIMER_INDENT_AMOUNT 2
-namespace
-{
- typedef std::map<const char*, uint64_t> TimerCategoryMap;
+namespace {
+typedef std::map<const char *, uint64_t> TimerCategoryMap;
- struct TimerStack
- {
- TimerStack() :
- m_depth(0)
- {}
+struct TimerStack {
+ TimerStack() : m_depth(0) {}
- uint32_t m_depth;
- std::vector<Timer*> m_stack;
- };
+ uint32_t m_depth;
+ std::vector<Timer *> m_stack;
+};
} // end of anonymous namespace
std::atomic<bool> Timer::g_quiet(true);
std::atomic<unsigned> Timer::g_display_depth(0);
-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 = 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 &
-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);
+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);
+ 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;
+}
+
+void Timer::SetQuiet(bool value) { g_quiet = value; }
+
+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;
+
+ 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");
}
- return (TimerStack *)timer_stack;
+ 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);
+ }
}
-void
-Timer::SetQuiet (bool value)
-{
- g_quiet = value;
-}
+Timer::~Timer() {
+ TimerStack *stack = GetTimerStackForCurrentThread();
+ if (!stack)
+ return;
-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;
-
- 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);
+ 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();
}
-}
-
-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 (m_timer_start.IsValid()) {
+ m_timer_ticks += (stop_time - m_timer_start);
+ m_timer_start.Clear();
}
- if (stack->m_depth > 0)
- --stack->m_depth;
-}
-uint64_t
-Timer::GetTotalElapsedNanoSeconds()
-{
- uint64_t total_ticks = m_total_ticks;
+ assert(stack->m_stack.back() == this);
+ stack->m_stack.pop_back();
+ if (stack->m_stack.empty() == false)
+ stack->m_stack.back()->ChildStopped(stop_time);
- // 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);
+ 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;
- return total_ticks;
-}
-
-uint64_t
-Timer::GetTimerElapsedNanoSeconds()
-{
- uint64_t timer_ticks = m_timer_ticks;
-
- // 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);
-
- return timer_ticks;
-}
-
-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 == 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;
}
-void
-Timer::ChildStopped (const TimeValue& stop_time)
-{
- if (!m_timer_start.IsValid())
- m_timer_start = stop_time;
+uint64_t Timer::GetTotalElapsedNanoSeconds() {
+ uint64_t total_ticks = m_total_ticks;
+
+ // 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);
+
+ return total_ticks;
}
-void
-Timer::SetDisplayDepth (uint32_t depth)
-{
- g_display_depth = depth;
+uint64_t Timer::GetTimerElapsedNanoSeconds() {
+ uint64_t timer_ticks = m_timer_ticks;
+
+ // 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);
+
+ return timer_ticks;
}
+void Timer::ChildStarted(const TimeValue &start_time) {
+ if (m_timer_start.IsValid()) {
+ m_timer_ticks += (start_time - m_timer_start);
+ m_timer_start.Clear();
+ }
+}
+
+void Timer::ChildStopped(const TimeValue &stop_time) {
+ if (!m_timer_start.IsValid())
+ m_timer_start = stop_time;
+}
+
+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;
+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::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);
+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);
- }
+ 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);
+ }
}
diff --git a/lldb/source/Core/UUID.cpp b/lldb/source/Core/UUID.cpp
index 88290d1..d7d4e61 100644
--- a/lldb/source/Core/UUID.cpp
+++ b/lldb/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,202 @@
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)
-{
+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));
+ ::memcpy(m_uuid, rhs.m_uuid, sizeof(m_uuid));
+ }
+ return *this;
}
-UUID::UUID (const void *uuid_bytes, uint32_t num_uuid_bytes)
-{
- SetBytes (uuid_bytes, num_uuid_bytes);
+UUID::~UUID() {}
+
+void UUID::Clear() {
+ m_num_uuid_bytes = 16;
+ ::memset(m_uuid, 0, 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));
+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;
+ }
+ return result;
}
-UUID::~UUID()
-{
+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]);
+ }
}
-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;
- }
-
- 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';
-}
-
-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;
+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;
}
- // Else return zero to indicate we were not able to parse a UUID value
+ 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';
+}
+
+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;
+ }
+
+ // 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/lldb/source/Core/UserID.cpp b/lldb/source/Core/UserID.cpp
index f3d6e5b..5446154 100644
--- a/lldb/source/Core/UserID.cpp
+++ b/lldb/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/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp
index 6313fa1..0910f40 100644
--- a/lldb/source/Core/UserSettingsController.cpp
+++ b/lldb/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,86 @@
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, 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();
}
-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, 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;
}
-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, 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;
}
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(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();
}
-
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(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;
- }
-
-}
-
diff --git a/lldb/source/Core/VMRange.cpp b/lldb/source/Core/VMRange.cpp
index 902489e..8d21f4b 100644
--- a/lldb/source/Core/VMRange.cpp
+++ b/lldb/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;
+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;
+}
+
+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);
+}
+
+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
-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;
+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();
}
-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;
+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();
}
-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) {
+ 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)
-{
- 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();
-}
-
diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp
index eb250eb..a480c3c 100644
--- a/lldb/source/Core/Value.cpp
+++ b/lldb/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 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 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 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();
- }
-}
-
-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();
-}
+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());
-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;
+ m_value = (uintptr_t)m_data_buffer.GetBytes();
}
- return eAddressTypeInvalid;
+ }
+ return *this;
}
-RegisterInfo *
-Value::GetRegisterInfo() const
-{
- if (m_context_type == eContextTypeRegisterInfo)
- return static_cast<RegisterInfo *> (m_context);
- return NULL;
+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();
}
-Type *
-Value::GetType()
-{
- if (m_context_type == eContextTypeLLDBType)
- return static_cast<Type *> (m_context);
- return NULL;
+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();
}
-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;
+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 0;
-}
-
-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();
-}
-
-bool
-Value::ValueOf(ExecutionContext *exe_ctx)
-{
- switch (m_context_type)
- {
- case eContextTypeInvalid:
- case eContextTypeRegisterInfo: // RegisterInfo *
- case eContextTypeLLDBType: // Type *
- break;
-
- case eContextTypeVariable: // Variable *
- ResolveValue(exe_ctx);
- return true;
+ } 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;
+ }
}
- return false;
-}
-
-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;
-
- 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;
+ 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;
+ }
}
-
- 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;
+ } break;
+ }
+ return 0;
}
-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;
- }
- }
-
- return m_compiler_type;
+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();
}
-void
-Value::SetCompilerType (const CompilerType &compiler_type)
-{
- m_compiler_type = compiler_type;
+bool Value::ValueOf(ExecutionContext *exe_ctx) {
+ switch (m_context_type) {
+ case eContextTypeInvalid:
+ case eContextTypeRegisterInfo: // RegisterInfo *
+ case eContextTypeLLDBType: // Type *
+ break;
+
+ case eContextTypeVariable: // Variable *
+ ResolveValue(exe_ctx);
+ return true;
+ }
+ return false;
}
-lldb::Format
-Value::GetValueDefaultFormat ()
-{
- switch (m_context_type)
- {
- case eContextTypeRegisterInfo:
- if (GetRegisterInfo())
- return GetRegisterInfo()->format;
- break;
+uint64_t Value::GetValueByteSize(Error *error_ptr, ExecutionContext *exe_ctx) {
+ uint64_t byte_size = 0;
- case eContextTypeInvalid:
- case eContextTypeLLDBType:
- case eContextTypeVariable:
- {
- const CompilerType &ast_type = GetCompilerType();
- if (ast_type.IsValid())
- return ast_type.GetFormat();
- }
- break;
+ switch (m_context_type) {
+ case eContextTypeRegisterInfo: // RegisterInfo *
+ if (GetRegisterInfo())
+ byte_size = GetRegisterInfo()->byte_size;
+ 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 false;
-
-}
-
-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;
+ case eContextTypeInvalid:
+ case eContextTypeLLDBType: // Type *
+ case eContextTypeVariable: // Variable *
+ {
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 (ast_type.IsValid())
+ byte_size = ast_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
+ } break;
+ }
- 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)");
- }
- 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());
- }
- }
- 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();
- }
- }
-
- 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");
- }
- }
- }
- 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;
+ 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;
+}
- // Bail if we encountered any errors
- if (error.Fail())
- return error;
+const CompilerType &Value::GetCompilerType() {
+ if (!m_compiler_type.IsValid()) {
+ switch (m_context_type) {
+ case eContextTypeInvalid:
+ break;
- if (address == LLDB_INVALID_ADDRESS)
- {
- error.SetErrorStringWithFormat ("invalid %s address", address_type == eAddressTypeHost ? "host" : "load");
- return error;
+ 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;
}
+ }
- // If we got here, we need to read the value from memory
- size_t byte_size = GetValueByteSize (&error, exe_ctx);
+ return m_compiler_type;
+}
- // Bail if we encountered any errors getting the byte size
- if (error.Fail())
- return error;
+void Value::SetCompilerType(const CompilerType &compiler_type) {
+ m_compiler_type = compiler_type;
+}
- // 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);
+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;
+ }
- 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();
+ return false;
+}
- 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);
- }
- }
+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
- {
- error.SetErrorStringWithFormat ("out of memory");
+ 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 *));
+
+ uint32_t limit_byte_size = UINT32_MAX;
+
+ if (ast_type.IsValid()) {
+ limit_byte_size = ast_type.GetByteSize(
+ exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
}
- return error;
-}
+ if (limit_byte_size <= m_value.GetByteSize()) {
+ if (m_value.GetData(data, limit_byte_size))
+ return error; // Success;
+ }
-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)
- {
- 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;
+ 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 {
+ address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
+ address_type = eAddressTypeLoad;
+ data.SetByteOrder(
+ process->GetTarget().GetArchitecture().GetByteOrder());
+ data.SetAddressByteSize(
+ process->GetTarget().GetArchitecture().GetAddressByteSize());
+ }
}
- return m_value;
+ 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();
+ }
+ }
+
+ 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");
+ }
+ }
+ }
+ 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;
+ }
+
+ // 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 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;
+
+ // 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);
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat("unsupported AddressType value (%i)",
+ address_type);
+ }
+ } else {
+ error.SetErrorStringWithFormat("out of memory");
+ }
+
+ return error;
}
-Variable *
-Value::GetVariable()
-{
- if (m_context_type == eContextTypeVariable)
- return static_cast<Variable *> (m_context);
+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)
+ {
+ 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 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/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 6400e00..b0e4798 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/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,2050 +65,1687 @@
//----------------------------------------------------------------------
// 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 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 did_change_formats = false;
- ClearUserVisibleData();
-
- if (IsInScope())
- {
- const bool value_was_valid = GetValueIsValid();
- SetValueDidChange (false);
-
- m_error.Clear();
+ if (update_format)
+ did_change_formats = UpdateFormatsIfNeeded();
- // 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 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);
+ }
+
+ 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");
+ }
+ }
+ 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;
+ }
+
+ 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
-ValueObject::GetCompilerType ()
-{
- return MaybeCalculateCompleteType();
+CompilerType ValueObject::GetCompilerType() {
+ return MaybeCalculateCompleteType();
}
-TypeImpl
-ValueObject::GetTypeImpl ()
-{
- return TypeImpl(GetCompilerType());
+TypeImpl ValueObject::GetTypeImpl() { return TypeImpl(GetCompilerType()); }
+
+DataExtractor &ValueObject::GetDataExtractor() {
+ UpdateValueIfNeeded(false);
+ return m_data;
}
-DataExtractor &
-ValueObject::GetDataExtractor ()
-{
- UpdateValueIfNeeded(false);
- return m_data;
+const Error &ValueObject::GetError() {
+ UpdateValueIfNeeded(false);
+ return m_error;
}
-const Error &
-ValueObject::GetError()
-{
- UpdateValueIfNeeded(false);
- return m_error;
+const ConstString &ValueObject::GetName() const { return m_name; }
+
+const char *ValueObject::GetLocationAsCString() {
+ return GetLocationAsCStringImpl(m_value, m_data);
}
-const ConstString &
-ValueObject::GetName() const
-{
- return m_name;
-}
+const char *ValueObject::GetLocationAsCStringImpl(const Value &value,
+ const DataExtractor &data) {
+ if (UpdateValueIfNeeded(false)) {
+ if (m_location_str.empty()) {
+ StreamString sstr;
-const char *
-ValueObject::GetLocationAsCString ()
-{
- return GetLocationAsCStringImpl(m_value,
- m_data);
-}
+ Value::ValueType value_type = value.GetValueType();
-const char *
-ValueObject::GetLocationAsCStringImpl (const Value& value,
- const DataExtractor& data)
-{
- if (UpdateValueIfNeeded(false))
- {
+ 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())
- {
- 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;
+ 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;
- }
- }
+ 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;
+ }
}
- return m_location_str.c_str();
+ }
+ return m_location_str.c_str();
}
-Value &
-ValueObject::GetValue()
-{
- return m_value;
-}
+Value &ValueObject::GetValue() { return m_value; }
-const Value &
-ValueObject::GetValue() const
-{
- 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;
- }
+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 ret;
+ if (scalar_value.ULongLong(1) == 0)
+ ret = false;
+ else
+ ret = true;
+ error.Clear();
+ return ret;
}
-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;
- }
+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));
}
-
- Scalar scalar_value;
-
- if (!ResolveValue (scalar_value))
- {
- error.SetErrorString("failed to get a scalar result");
- return false;
- }
-
- bool ret;
- if (scalar_value.ULongLong(1) == 0)
- ret = false;
- else
- ret = true;
- error.Clear();
- return ret;
-}
-bool
-ValueObject::GetValueIsValid () const
-{
- return m_value_is_valid;
-}
-
-
-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;
+ ValueObject *child = m_children.GetChildAtIndex(idx);
+ if (child != NULL)
+ return child->GetSP();
+ }
+ return child_sp;
}
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();
- }
- return child_sp;
+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<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;
+ }
+ }
+ 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;
+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<ConstString> &names,
- ConstString* name_of_error)
-{
- return GetChildAtNamePath( std::vector<ConstString>(names),
- name_of_error );
+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::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<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;
}
-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;
- }
- }
- return root;
+size_t ValueObject::GetIndexOfChildWithName(const ConstString &name) {
+ bool omit_empty_base_classes = true;
+ return GetCompilerType().GetIndexOfChildWithName(name.GetCString(),
+ omit_empty_base_classes);
}
-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;
- }
+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 root;
+ }
+ return child_sp;
}
-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::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();
}
-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;
+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;
}
// 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::SetNumChildren(size_t num_children) {
+ m_children_count_valid = true;
+ m_children.SetChildrenCount(num_children);
}
-void
-ValueObject::SetName (const ConstString &name)
-{
- m_name = name;
+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;
}
-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,
- 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);
+ }
+ m_is_getting_summary = false;
+ return !destination.empty();
}
-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);
+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();
+}
+
+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;
+
+ 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);
}
- m_is_getting_summary = false;
- return !destination.empty();
-}
+ 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());
-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);
+ 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;
}
- if (m_summary_str.empty())
- return NULL;
- return m_summary_str.c_str();
+ }
+ return 0;
}
-bool
-ValueObject::GetSummaryAsCString (std::string& destination,
- const TypeSummaryOptions& options)
-{
- return GetSummaryAsCString(GetSummaryFormat().get(),
- destination,
- options);
+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::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)
+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 (!check_pointer)
- return true;
- if (type_flags.Test(eTypeIsArray))
- return true;
+ 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().c_str(), 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};
+ }
+
+ if (max_length == 0)
+ max_length = target->GetMaximumSizeOfStringSummary();
+
+ size_t bytes_read = 0;
+ size_t total_bytes_read = 0;
+
+ 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);
+ 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;
}
- else
- {
- ValueObjectSP child_sp = GetChildAtIndex(0, true);
- if (child_sp.get() == NULL)
- return 0;
- Error error;
- return child_sp->GetData(data, error);
- }
- return true;
+ }
+ cstr_address = GetAddressOf(true, &cstr_address_type);
+ } else {
+ // We have a pointer
+ cstr_address = GetPointerValue(&cstr_address_type);
}
- 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();
+ 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};
}
- 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;
- }
-
- 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;
-}
-
-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;
-}
-
-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");
+ 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};
+ return {0, was_capped};
+ }
}
-
- if (max_length == 0)
- max_length = target->GetMaximumSizeOfStringSummary();
-
- size_t bytes_read = 0;
- size_t total_bytes_read = 0;
-
+
+ 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;
+
+ if (!m_object_desc_str.empty())
+ return m_object_desc_str.c_str();
+
+ 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();
- 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;
- 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;
- }
- }
+ 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.GetData());
+ }
+
+ 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);
+}
- if (!m_object_desc_str.empty())
- return m_object_desc_str.c_str();
-
- 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);
- }
+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 (runtime && runtime->GetObjectDescription(s, *this))
- {
- m_object_desc_str.append (s.GetData());
- }
-
- if (m_object_desc_str.empty())
- return NULL;
- else
- return m_object_desc_str.c_str();
-}
-
-bool
-ValueObject::GetValueAsCString (const lldb_private::TypeFormatImpl& format,
- std::string& destination)
-{
- if (UpdateValueIfNeeded(false))
- return format.FormatObject(this,destination);
- else
- return false;
-}
-
-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 (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_value_str.empty())
+ return NULL;
+ return m_value_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...
+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;
+ 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...
+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);
}
-
- if (success)
- *success = false;
- return 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
+// 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;
+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;
- }
+ 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;
+ }
+ return false;
}
-bool
-ValueObject::DumpPrintableRepresentation(Stream& s,
- ValueObjectRepresentationStyle val_obj_display,
- Format custom_format,
- PrintableRepresentationSpecialCases special,
- bool do_dump_error)
-{
+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 (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();
+ Flags flags(GetTypeInfo());
- 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;
- }
- }
-
- 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)
+ 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 (custom_format == eFormatEnum)
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();
+ // 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 (cstr)
- s.PutCString(cstr);
- else
+
+ 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
{
- if (m_error.Fail())
- {
- if (do_dump_error)
- s.Printf("<%s>", m_error.AsCString());
- else
- return false;
+ 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;
}
- 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>");
+ child->DumpPrintableRepresentation(
+ s, ValueObject::eValueObjectRepresentationStyleValue, format);
+ }
+
+ s << ']';
+
+ return true;
}
-
- // 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);
+ }
+
+ 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;
}
-
- return var_success;
+ }
+
+ if (only_special)
+ 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;
-
- 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;
+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;
+
+ switch (m_value.GetValueType()) {
+ case Value::eValueTypeScalar:
+ case Value::eValueTypeVector:
+ address = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
+ break;
+
+ case Value::eValueTypeHostAddress:
+ case Value::eValueTypeLoadAddress:
+ case Value::eValueTypeFileAddress: {
+ lldb::offset_t data_offset = 0;
+ address = m_data.GetPointer(&data_offset);
+ } break;
+ }
+
+ if (address_type)
+ *address_type = GetAddressTypeOfChildren();
+
+ 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;
- }
-
- 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;
- }
-
- // If we have reached this point, then we have successfully changed the value.
- SetNeedsUpdate();
- return true;
-}
-
-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;
+ }
+
+ // If we have reached this point, then we have successfully changed the value.
+ SetNeedsUpdate();
+ return true;
}
-ConstString
-ValueObject::GetTypeName()
-{
- return GetCompilerType().GetConstTypeName();
+bool ValueObject::GetDeclaration(Declaration &decl) {
+ decl.Clear();
+ return false;
}
-ConstString
-ValueObject::GetDisplayTypeName()
-{
- return GetTypeName();
+ConstString ValueObject::GetTypeName() {
+ return GetCompilerType().GetConstTypeName();
}
-ConstString
-ValueObject::GetQualifiedTypeName()
-{
- return GetCompilerType().GetConstQualifiedTypeName();
+ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); }
+
+ConstString ValueObject::GetQualifiedTypeName() {
+ return GetCompilerType().GetConstQualifiedTypeName();
}
-
-LanguageType
-ValueObject::GetObjectRuntimeLanguage ()
-{
- return GetCompilerType().GetMinimumLanguage ();
+LanguageType ValueObject::GetObjectRuntimeLanguage() {
+ return GetCompilerType().GetMinimumLanguage();
}
-void
-ValueObject::AddSyntheticChild (const ConstString &key, ValueObject *valobj)
-{
- m_synthetic_children[key] = valobj;
+void ValueObject::AddSyntheticChild(const ConstString &key,
+ ValueObject *valobj) {
+ m_synthetic_children[key] = valobj;
}
-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;
+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;
}
uint32_t
-ValueObject::GetTypeInfo (CompilerType *pointee_or_element_compiler_type)
-{
- return GetCompilerType().GetTypeInfo (pointee_or_element_compiler_type);
+ValueObject::GetTypeInfo(CompilerType *pointee_or_element_compiler_type) {
+ return GetCompilerType().GetTypeInfo(pointee_or_element_compiler_type);
}
-bool
-ValueObject::IsPointerType ()
-{
- return GetCompilerType().IsPointerType();
+bool ValueObject::IsPointerType() { return GetCompilerType().IsPointerType(); }
+
+bool ValueObject::IsArrayType() {
+ return GetCompilerType().IsArrayType(NULL, NULL, NULL);
}
-bool
-ValueObject::IsArrayType ()
-{
- return GetCompilerType().IsArrayType (NULL, NULL, NULL);
+bool ValueObject::IsScalarType() { return GetCompilerType().IsScalarType(); }
+
+bool ValueObject::IsIntegerType(bool &is_signed) {
+ return GetCompilerType().IsIntegerType(is_signed);
}
-bool
-ValueObject::IsScalarType ()
-{
- return GetCompilerType().IsScalarType ();
+bool ValueObject::IsPointerOrReferenceType() {
+ return GetCompilerType().IsPointerOrReferenceType();
}
-bool
-ValueObject::IsIntegerType (bool &is_signed)
-{
- return GetCompilerType().IsIntegerType (is_signed);
+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::IsPointerOrReferenceType ()
-{
- return GetCompilerType().IsPointerOrReferenceType ();
+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::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::IsNilReference() {
+ if (Language *language = Language::FindPlugin(GetObjectRuntimeLanguage())) {
+ return language->IsNilReference(*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::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
@@ -2122,2243 +1759,2047 @@
// 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, 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;
+ }
+ 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;
+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);
}
-
- 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);
- }
- }
+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::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(); }
+
+lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); }
+
+ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) {
+ if (use_synthetic == false)
+ return ValueObjectSP();
+
+ CalculateSyntheticValue(use_synthetic);
+
+ if (m_synthetic_value)
+ return m_synthetic_value->GetSP();
+ else
+ return ValueObjectSP();
}
-ValueObjectSP
-ValueObject::GetStaticValue()
-{
- return GetSP();
-}
+bool ValueObject::HasSyntheticValue() {
+ UpdateFormatsIfNeeded();
-lldb::ValueObjectSP
-ValueObject::GetNonSyntheticValue ()
-{
- return GetSP();
-}
+ if (m_synthetic_children_sp.get() == NULL)
+ return false;
-ValueObjectSP
-ValueObject::GetSyntheticValue (bool use_synthetic)
-{
- if (use_synthetic == false)
- return ValueObjectSP();
+ CalculateSyntheticValue(true);
- CalculateSyntheticValue(use_synthetic);
-
- 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::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_value)
+ return true;
+ else
return false;
}
-
-ValueObject *
-ValueObject::GetNonBaseClassParent()
-{
- if (GetParent())
- {
- if (GetParent()->IsBaseClass())
- return GetParent()->GetNonBaseClassParent();
- else
- return GetParent();
+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 NULL;
+ 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();
-
- 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;
- }
-
+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;
- }
-
- 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('.');
- }
- }
- }
- }
-
- const char *name = GetName().GetCString();
- if (name)
- {
- if (qualify_cxx_base_classes)
- {
- if (GetBaseClassPath (s))
- s.PutCString("::");
- }
- s.PutCString(name);
- }
+ } 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 (is_deref_of_parent && epformat == eGetExpressionPathFormatDereferencePointers)
- {
- s.PutChar(')');
+
+ 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('.');
+ }
+ }
+ }
+ }
+
+ 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(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;
+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) {
- 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
-}
+ 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;
-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;
-}
+ 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);
-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())
+ 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();
-
- *first_unparsed = expression_cstr;
-
- while (true)
+ } 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
+}
+
+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
{
-
- 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')
+ 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;
+}
+
+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
{
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
+ *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();
+ }
}
-
- switch (*expression_cstr)
+ // 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
{
- 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;
- }
+ *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;
+ }
+ }
+ }
}
-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())
+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;
-
- *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')
+ }
+ 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
{
- *reason_to_stop = ValueObject::eExpressionPathScanEndReasonEndOfString;
+ *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;
- }
-
- 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;
+ }
+ } 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;
}
- 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;
+ } 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;
}
- }
- }
-}
-
-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());
- }
-}
-
-void
-ValueObject::Dump (Stream &s)
-{
- Dump (s, DumpValueObjectOptions(*this));
-}
-
-void
-ValueObject::Dump (Stream &s,
- const DumpValueObjectOptions& options)
-{
- ValueObjectPrinter printer(this,&s,options);
- printer.PrintValueObject();
-}
-
-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())
+ }
+ } else /*if (ClangASTContext::IsScalarType(root_compiler_type))*/
{
- Value v(Scalar(GetValueAsUnsigned(UINT64_MAX)));
- m_error = v.GetValueAsData (&exe_ctx, data, 0, GetModule().get());
+ 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
- m_error = m_value.GetValueAsData (&exe_ctx, data, 0, GetModule().get());
-
- valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(),
- GetCompilerType(),
- name,
- data,
- GetAddressOf());
+ } 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;
}
-
- if (!valobj_sp)
+ default: // some non-[ separator, or something entirely wrong, is in the way
{
- ExecutionContext exe_ctx (GetExecutionContextRef());
- valobj_sp = ValueObjectConstResult::Create (exe_ctx.GetBestExecutionContextScope(), m_error);
+ *first_unparsed = expression_cstr;
+ *reason_to_stop =
+ ValueObject::eExpressionPathScanEndReasonUnexpectedSymbol;
+ *final_result = ValueObject::eExpressionPathEndResultTypeInvalid;
+ return 0;
+ break;
}
- 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;
- }
-
- 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();
- }
- }
-
- return result_sp;
+void ValueObject::LogValueObject(Log *log) {
+ if (log)
+ return LogValueObject(log, DumpValueObjectOptions(*this));
}
-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);
- }
- }
-
- address_type = eAddressTypeInvalid;
- return LLDB_INVALID_ADDRESS;
+void ValueObject::LogValueObject(Log *log,
+ const DumpValueObjectOptions &options) {
+ if (log) {
+ StreamString s;
+ Dump(s, options);
+ if (s.GetSize())
+ log->PutCString(s.GetData());
+ }
}
-ValueObjectSP
-ValueObject::Dereference (Error &error)
-{
- if (m_deref_valobj)
- return m_deref_valobj->GetSP();
+void ValueObject::Dump(Stream &s) { Dump(s, DumpValueObjectOptions(*this)); }
- 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);
- }
- }
-
- if (m_deref_valobj)
- {
- error.Clear();
- return m_deref_valobj->GetSP();
- }
- 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();
- }
+void ValueObject::Dump(Stream &s, const DumpValueObjectOptions &options) {
+ ValueObjectPrinter printer(this, &s, options);
+ printer.PrintValueObject();
}
-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);
+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;
+}
+
+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;
+ }
+
+ 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();
+ }
+ }
+
+ return result_sp;
+}
+
+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);
+ }
+ }
+
+ address_type = eAddressTypeInvalid;
+ return LLDB_INVALID_ADDRESS;
+}
+
+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);
+ }
+ }
+
+ if (m_deref_valobj) {
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;
+ return m_deref_valobj->GetSP();
+ } else {
+ StreamString strm;
+ GetExpressionPath(strm, true);
- 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;
- }
- }
+ if (is_pointer_or_reference_type)
+ error.SetErrorStringWithFormat("dereference failed: (%s) %s",
+ GetTypeName().AsCString("<invalid type>"),
+ strm.GetString().c_str());
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());
- }
-
+ error.SetErrorStringWithFormat("not a pointer or reference type: (%s) %s",
+ GetTypeName().AsCString("<invalid type>"),
+ strm.GetString().c_str());
+ return ValueObjectSP();
+ }
+}
+
+ValueObjectSP ValueObject::AddressOf(Error &error) {
+ if (m_addr_of_valobj_sp)
return m_addr_of_valobj_sp;
-}
-ValueObjectSP
-ValueObject::Cast (const CompilerType &compiler_type)
-{
- return ValueObjectCast::Create (*this, GetName(), compiler_type);
-}
+ 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;
-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);
+ 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;
}
- return valobj_sp;
+ } 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::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;
+ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) {
+ return ValueObjectCast::Create(*this, GetName(), compiler_type);
}
-ValueObject::EvaluationPoint::EvaluationPoint () :
- m_mod_id(),
- m_exe_ctx_ref(),
- m_needs_update (true)
-{
+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;
}
-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);
- }
+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(
+ const ValueObject::EvaluationPoint &rhs)
+ : m_mod_id(), m_exe_ctx_ref(rhs.m_exe_ctx_ref), m_needs_update(true) {}
-ValueObject::EvaluationPoint::~EvaluationPoint ()
-{
-}
+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
+// 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;
+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
- {
- m_mod_id = current_mod_id;
- m_needs_update = true;
- changed = true;
- }
+ } else {
+ // We used to have a thread, but now it is gone
+ SetInvalid();
+ changed = was_valid;
+ }
}
-
- // 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;
+ 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;
- }
-
- if ((clear_mask & eClearUserVisibleDataItemsValidator) == eClearUserVisibleDataItemsValidator)
- m_validation_result.reset();
+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;
}
-SymbolContextScope *
-ValueObject::GetSymbolContextScope()
-{
- if (m_parent)
- {
- if (!m_parent->IsPointerOrReferenceType())
- return m_parent->GetSymbolContextScope();
- }
- return NULL;
+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();
}
-lldb::ValueObjectSP
-ValueObject::CreateValueObjectFromExpression (const char* name,
- const char* expression,
- const ExecutionContext& exe_ctx)
-{
- return CreateValueObjectFromExpression(name, expression, exe_ctx, EvaluateExpressionOptions());
+SymbolContextScope *ValueObject::GetSymbolContextScope() {
+ if (m_parent) {
+ if (!m_parent->IsPointerOrReferenceType())
+ return m_parent->GetSymbolContextScope();
+ }
+ return NULL;
}
+lldb::ValueObjectSP ValueObject::CreateValueObjectFromExpression(
+ const char *name, const char *expression, const ExecutionContext &exe_ctx) {
+ return CreateValueObjectFromExpression(name, expression, exe_ctx,
+ EvaluateExpressionOptions());
+}
-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));
+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;
}
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;
- }
+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();
+ }
+ return lldb::ValueObjectSP();
}
-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;
+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;
}
-ModuleSP
-ValueObject::GetModule ()
-{
- ValueObject* root(GetRoot());
+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);
+ }));
+}
+
+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();
- }
- return m_address_type_of_ptr_or_ref_children;
-}
-
-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;
-}
-
-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;
-}
-
-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();
- }
+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
+ }
+ return (m_preferred_display_language = type); // only compute it once
}
-void
-ValueObject::SetPreferredDisplayLanguage (lldb::LanguageType lt)
-{
- m_preferred_display_language = lt;
+void ValueObject::SetPreferredDisplayLanguage(lldb::LanguageType lt) {
+ m_preferred_display_language = lt;
}
-void
-ValueObject::SetPreferredDisplayLanguageIfNeeded (lldb::LanguageType lt)
-{
- if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
- SetPreferredDisplayLanguage(lt);
+void ValueObject::SetPreferredDisplayLanguageIfNeeded(lldb::LanguageType lt) {
+ if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
+ SetPreferredDisplayLanguage(lt);
}
-bool
-ValueObject::CanProvideValue ()
-{
- // we need to support invalid types as providers of values because some bare-board
- // debugging scenarios have no notion of types, but still manage to have raw numeric
- // values for things like registers. sigh.
- const CompilerType &type(GetCompilerType());
- return (false == type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue));
+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));
}
-bool
-ValueObject::IsChecksumEmpty ()
-{
- return m_value_checksum.empty();
+bool ValueObject::IsChecksumEmpty() { return m_value_checksum.empty(); }
+
+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();
}
-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; }
-uint64_t
-ValueObject::GetLanguageFlags ()
-{
- return m_language_flags;
-}
-
-void
-ValueObject::SetLanguageFlags (uint64_t flags)
-{
- m_language_flags = flags;
-}
+void ValueObject::SetLanguageFlags(uint64_t flags) { m_language_flags = flags; }
diff --git a/lldb/source/Core/ValueObjectCast.cpp b/lldb/source/Core/ValueObjectCast.cpp
index 1c5838b8..5aa2446 100644
--- a/lldb/source/Core/ValueObjectCast.cpp
+++ b/lldb/source/Core/ValueObjectCast.cpp
@@ -1,4 +1,5 @@
-//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++ -*-===//
+//===-- ValueObjectDynamicValue.cpp ---------------------------------*- C++
+//-*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,7 +8,6 @@
//
//===----------------------------------------------------------------------===//
-
#include "lldb/Core/ValueObjectCast.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"
@@ -34,97 +34,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; }
+
+size_t ValueObjectCast::CalculateNumChildren(uint32_t max) {
+ auto children_count = GetCompilerType().GetNumChildren(true);
+ return children_count <= max ? children_count : max;
}
-CompilerType
-ValueObjectCast::GetCompilerTypeImpl ()
-{
- return m_cast_type;
+uint64_t ValueObjectCast::GetByteSize() {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ return m_value.GetValueByteSize(nullptr, &exe_ctx);
}
-size_t
-ValueObjectCast::CalculateNumChildren(uint32_t max)
-{
- auto children_count = GetCompilerType().GetNumChildren (true);
- return children_count <= max ? children_count : max;
+lldb::ValueType ValueObjectCast::GetValueType() const {
+ // Let our parent answer global, local, argument, etc...
+ return m_parent->GetValueType();
}
-uint64_t
-ValueObjectCast::GetByteSize()
-{
- ExecutionContext exe_ctx (GetExecutionContextRef());
- return m_value.GetValueByteSize(nullptr, &exe_ctx);
-}
+bool ValueObjectCast::UpdateValue() {
+ SetValueIsValid(false);
+ m_error.Clear();
-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;
+ 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;
+ }
+
+ // 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();
-}
+bool ValueObjectCast::IsInScope() { return m_parent->IsInScope(); }
diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp
index 6ecc749..9b2bdd1 100644
--- a/lldb/source/Core/ValueObjectChild.cpp
+++ b/lldb/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)));
+bool ValueObjectChild::UpdateValue() {
+ m_error.Clear();
+ SetValueIsValid(false);
+ ValueObject *parent = m_parent;
+ if (parent) {
+ if (parent->UpdateValueIfNeeded(false)) {
+ m_value.SetCompilerType(GetCompilerType());
- 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;
- }
- }
- }
+ 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/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp
index 441cee540..f78574e 100644
--- a/lldb/source/Core/ValueObjectConstResult.cpp
+++ b/lldb/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();
+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,
+ 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);
+}
+
+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);
- m_value.SetCompilerType(compiler_type);
- m_name = name;
- SetIsConstant ();
- SetValueIsValid(true);
- SetAddressTypeOfChildren(eAddressTypeLoad);
+ 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 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 Error &error) {
+ return (new ValueObjectConstResult(exe_scope, error))->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 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 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 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);
}
-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() {}
+
+CompilerType ValueObjectConstResult::GetCompilerTypeImpl() {
+ return m_value.GetCompilerType();
}
-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;
+lldb::ValueType ValueObjectConstResult::GetValueType() const {
+ return eValueTypeConstResult;
+}
+
+uint64_t ValueObjectConstResult::GetByteSize() {
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+
+ 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; }
+
+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::GetDisplayTypeName() {
+ return GetCompilerType().GetDisplayTypeName();
+}
+
+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;
+}
+
+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::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);
+}
+
+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);
+}
+
+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);
}
-// 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();
-}
-
-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()
-{
-}
-
-CompilerType
-ValueObjectConstResult::GetCompilerTypeImpl()
-{
- return m_value.GetCompilerType();
-}
-
-lldb::ValueType
-ValueObjectConstResult::GetValueType() const
-{
- return eValueTypeConstResult;
-}
-
-uint64_t
-ValueObjectConstResult::GetByteSize()
-{
- ExecutionContext exe_ctx(GetExecutionContextRef());
-
- 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;
-}
-
-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::GetDisplayTypeName()
-{
- return GetCompilerType().GetDisplayTypeName();
-}
-
-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;
+ if (m_dynamic_value)
+ return m_dynamic_value->GetSP();
+ }
+ return ValueObjectSP();
}
lldb::ValueObjectSP
-ValueObjectConstResult::Dereference (Error &error)
-{
- return m_impl.Dereference(error);
+ValueObjectConstResult::Cast(const CompilerType &compiler_type) {
+ return m_impl.Cast(compiler_type);
}
-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::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);
-}
-
-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();
- }
- return ValueObjectSP();
-}
-
-lldb::ValueObjectSP
-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/lldb/source/Core/ValueObjectConstResultCast.cpp b/lldb/source/Core/ValueObjectConstResultCast.cpp
index 1611503..3245146 100644
--- a/lldb/source/Core/ValueObjectConstResultCast.cpp
+++ b/lldb/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::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);
+}
+
+ValueObject *ValueObjectConstResultCast::CreateChildAtIndex(
+ size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
+ return m_impl.CreateChildAtIndex(idx, synthetic_array_member,
+ synthetic_index);
+}
+
+size_t ValueObjectConstResultCast::GetPointeeData(DataExtractor &data,
+ uint32_t item_idx,
+ uint32_t item_count) {
+ return m_impl.GetPointeeData(data, item_idx, item_count);
}
lldb::ValueObjectSP
-ValueObjectConstResultCast::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::AddressOf (Error &error)
-{
- return m_impl.AddressOf(error);
-}
-
-ValueObject *
-ValueObjectConstResultCast::CreateChildAtIndex (size_t idx,
- bool synthetic_array_member,
- int32_t synthetic_index)
-{
- return m_impl.CreateChildAtIndex(
- idx, synthetic_array_member, synthetic_index);
-}
-
-size_t
-ValueObjectConstResultCast::GetPointeeData (DataExtractor& data,
- uint32_t item_idx,
- uint32_t item_count)
-{
- return m_impl.GetPointeeData(data, item_idx, item_count);
-}
-
-lldb::ValueObjectSP
-ValueObjectConstResultCast::Cast (const CompilerType &compiler_type)
-{
- return m_impl.Cast(compiler_type);
+ValueObjectConstResultCast::Cast(const CompilerType &compiler_type) {
+ return m_impl.Cast(compiler_type);
}
diff --git a/lldb/source/Core/ValueObjectConstResultChild.cpp b/lldb/source/Core/ValueObjectConstResultChild.cpp
index e3afa36..c4c9c63 100644
--- a/lldb/source/Core/ValueObjectConstResultChild.cpp
+++ b/lldb/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::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);
+}
+
+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);
}
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::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);
-}
-
-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/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp
index 6db7f18..0e4f73f 100644
--- a/lldb/source/Core/ValueObjectConstResultImpl.cpp
+++ b/lldb/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);
+}
+
+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::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::Dereference (Error &error)
-{
- if (m_impl_backend == NULL)
- return lldb::ValueObjectSP();
-
- return m_impl_backend->ValueObject::Dereference(error);
-}
+ValueObjectConstResultImpl::Cast(const CompilerType &compiler_type) {
+ if (m_impl_backend == NULL)
+ return lldb::ValueObjectSP();
-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::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();
+ 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/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp
index 65deba0..1fb32d4 100644
--- a/lldb/source/Core/ValueObjectDynamicValue.cpp
+++ b/lldb/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();
-}
-
-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();
-}
-
-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();
-}
-
-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;
- }
+CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success) {
+ if (m_dynamic_type_info.HasType())
+ return m_value.GetCompilerType();
else
- return m_parent->GetNumChildren(max);
+ return m_parent->GetCompilerType();
+ }
+ return m_parent->GetCompilerType();
}
-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();
+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();
}
-lldb::ValueType
-ValueObjectDynamicValue::GetValueType() const
-{
- return m_parent->GetValueType();
+TypeImpl ValueObjectDynamicValue::GetTypeImpl() {
+ const bool success = UpdateValueIfNeeded(false);
+ if (success && m_type_impl.IsValid()) {
+ return m_type_impl;
+ }
+ return m_parent->GetTypeImpl();
}
-bool
-ValueObjectDynamicValue::UpdateValue ()
-{
- SetValueIsValid (false);
- m_error.Clear();
+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();
+}
- 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;
- }
+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();
+}
- // 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;
- }
+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);
+}
- ExecutionContext exe_ctx (GetExecutionContextRef());
- Target *target = exe_ctx.GetTargetPtr();
- if (target)
- {
- m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
- m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
- }
+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();
+}
- // First make sure our Type and/or Address haven't changed:
- Process *process = exe_ctx.GetProcessPtr();
- if (!process)
- return false;
+lldb::ValueType ValueObjectDynamicValue::GetValueType() const {
+ return m_parent->GetValueType();
+}
- TypeAndOrName class_type_or_name;
- Address dynamic_address;
- bool found_dynamic_type = false;
- Value::ValueType value_type;
-
- LanguageRuntime *runtime = nullptr;
+bool ValueObjectDynamicValue::UpdateValue() {
+ SetValueIsValid(false);
+ m_error.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 (!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;
+ }
- 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);
- }
- }
+ // 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;
+ }
- // Getting the dynamic value may have run the program a bit, and so marked us as needing updating, but we really
- // don't...
+ ExecutionContext exe_ctx(GetExecutionContextRef());
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ }
- m_update_point.SetUpdated();
+ // First make sure our Type and/or Address haven't changed:
+ Process *process = exe_ctx.GetProcessPtr();
+ if (!process)
+ return false;
- 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();
- }
- }
- else
- {
- m_type_impl.Clear();
- }
+ TypeAndOrName class_type_or_name;
+ Address dynamic_address;
+ bool found_dynamic_type = false;
+ Value::ValueType value_type;
- // 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();
- }
+ LanguageRuntime *runtime = nullptr;
- 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;
- }
-
+ lldb::LanguageType known_type = m_parent->GetObjectRuntimeLanguage();
+ if (known_type != lldb::eLanguageTypeUnknown &&
+ known_type != lldb::eLanguageTypeC) {
+ runtime = process->GetLanguageRuntime(known_type);
if (runtime)
- m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent);
+ 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);
- //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 (!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);
}
+ }
- // We get here if we've failed above...
- SetValueIsValid (false);
+ // 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();
+ }
+ } 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;
+ }
+ }
+
+ // We get here if we've failed above...
+ SetValueIsValid(false);
+ return false;
+}
+
+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);
-
-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;
- }
- }
-
- 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;
-}
-
-void
-ValueObjectDynamicValue::SetPreferredDisplayLanguage (lldb::LanguageType lang)
-{
- this->ValueObject::SetPreferredDisplayLanguage(lang);
- if (m_parent)
- m_parent->SetPreferredDisplayLanguage(lang);
-}
-
-lldb::LanguageType
-ValueObjectDynamicValue::GetPreferredDisplayLanguage ()
-{
- if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
- {
- if (m_parent)
- return m_parent->GetPreferredDisplayLanguage();
- return lldb::eLanguageTypeUnknown;
- }
- else
- return m_preferred_display_language;
-}
-
-bool
-ValueObjectDynamicValue::IsSyntheticChildrenGenerated ()
-{
- if (m_parent)
- return m_parent->IsSyntheticChildrenGenerated();
+ 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;
+ }
+ }
+
+ bool ret_val = m_parent->SetValueFromCString(value_str, error);
+ SetNeedsUpdate();
+ return ret_val;
}
-void
-ValueObjectDynamicValue::SetSyntheticChildrenGenerated (bool b)
-{
- if (m_parent)
- m_parent->SetSyntheticChildrenGenerated(b);
- this->ValueObject::SetSyntheticChildrenGenerated(b);
+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
-ValueObjectDynamicValue::GetDeclaration (Declaration &decl)
-{
- if (m_parent)
- return m_parent->GetDeclaration(decl);
-
- return ValueObject::GetDeclaration(decl);
+void ValueObjectDynamicValue::SetPreferredDisplayLanguage(
+ lldb::LanguageType lang) {
+ this->ValueObject::SetPreferredDisplayLanguage(lang);
+ if (m_parent)
+ m_parent->SetPreferredDisplayLanguage(lang);
}
-uint64_t
-ValueObjectDynamicValue::GetLanguageFlags ()
-{
+lldb::LanguageType ValueObjectDynamicValue::GetPreferredDisplayLanguage() {
+ if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
if (m_parent)
- return m_parent->GetLanguageFlags();
- return this->ValueObject::GetLanguageFlags();
+ return m_parent->GetPreferredDisplayLanguage();
+ return lldb::eLanguageTypeUnknown;
+ } else
+ return m_preferred_display_language;
}
-void
-ValueObjectDynamicValue::SetLanguageFlags (uint64_t flags)
-{
- if (m_parent)
- m_parent->SetLanguageFlags(flags);
- else
- this->ValueObject::SetLanguageFlags(flags);
+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);
+}
+
+bool ValueObjectDynamicValue::GetDeclaration(Declaration &decl) {
+ if (m_parent)
+ return m_parent->GetDeclaration(decl);
+
+ return ValueObject::GetDeclaration(decl);
+}
+
+uint64_t ValueObjectDynamicValue::GetLanguageFlags() {
+ if (m_parent)
+ return m_parent->GetLanguageFlags();
+ return this->ValueObject::GetLanguageFlags();
+}
+
+void ValueObjectDynamicValue::SetLanguageFlags(uint64_t flags) {
+ if (m_parent)
+ m_parent->SetLanguageFlags(flags);
+ else
+ this->ValueObject::SetLanguageFlags(flags);
}
diff --git a/lldb/source/Core/ValueObjectList.cpp b/lldb/source/Core/ValueObjectList.cpp
index 180d4a0..7eae497 100644
--- a/lldb/source/Core/ValueObjectList.cpp
+++ b/lldb/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 &ValueObjectList::operator=(const ValueObjectList &rhs) {
+ if (this != &rhs)
+ m_value_objects = rhs.m_value_objects;
+ return *this;
}
-ValueObjectList::ValueObjectList (const ValueObjectList &rhs) :
- m_value_objects(rhs.m_value_objects)
-{
+void ValueObjectList::Append(const ValueObjectSP &val_obj_sp) {
+ m_value_objects.push_back(val_obj_sp);
}
-
-ValueObjectList::~ValueObjectList ()
-{
+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
}
-const ValueObjectList &
-ValueObjectList::operator = (const ValueObjectList &rhs)
-{
- if (this != &rhs)
- m_value_objects = rhs.m_value_objects;
- return *this;
+size_t ValueObjectList::GetSize() const { return m_value_objects.size(); }
+
+void ValueObjectList::Resize(size_t size) { m_value_objects.resize(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::Append (const ValueObjectSP &val_obj_sp)
-{
- m_value_objects.push_back(val_obj_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);
+ }
+ return valobj_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::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;
}
-
-size_t
-ValueObjectList::GetSize() const
-{
- return m_value_objects.size();
-}
-
-void
-ValueObjectList::Resize (size_t size)
-{
- m_value_objects.resize (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;
-}
-
-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::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::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;
- }
+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 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;
- }
- }
- 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/lldb/source/Core/ValueObjectMemory.cpp b/lldb/source/Core/ValueObjectMemory.cpp
index b989710..d631098 100644
--- a/lldb/source/Core/ValueObjectMemory.cpp
+++ b/lldb/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,199 @@
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,
+ 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,
- 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,
+ const char *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;
+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);
}
- 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,
- 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());
+ValueObjectMemory::~ValueObjectMemory() {}
- 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);
- }
- }
+CompilerType ValueObjectMemory::GetCompilerTypeImpl() {
+ if (m_type_sp)
+ return m_type_sp->GetForwardCompilerType();
+ return m_compiler_type;
}
-ValueObjectMemory::~ValueObjectMemory()
-{
+ConstString ValueObjectMemory::GetTypeName() {
+ if (m_type_sp)
+ return m_type_sp->GetName();
+ return m_compiler_type.GetConstTypeName();
}
-CompilerType
-ValueObjectMemory::GetCompilerTypeImpl ()
-{
- if (m_type_sp)
- return m_type_sp->GetForwardCompilerType ();
- return m_compiler_type;
+ConstString ValueObjectMemory::GetDisplayTypeName() {
+ if (m_type_sp)
+ return m_type_sp->GetForwardCompilerType().GetDisplayTypeName();
+ return m_compiler_type.GetDisplayTypeName();
}
-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();
-}
-
-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;
+ }
+
+ 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;
}
-uint64_t
-ValueObjectMemory::GetByteSize()
-{
- if (m_type_sp)
- return m_type_sp->GetByteSize();
- return m_compiler_type.GetByteSize (nullptr);
+uint64_t ValueObjectMemory::GetByteSize() {
+ if (m_type_sp)
+ return m_type_sp->GetByteSize();
+ return m_compiler_type.GetByteSize(nullptr);
}
-lldb::ValueType
-ValueObjectMemory::GetValueType() const
-{
- // RETHINK: Should this be inherited from somewhere?
- return lldb::eValueTypeVariableGlobal;
+lldb::ValueType ValueObjectMemory::GetValueType() const {
+ // RETHINK: Should this be inherited from somewhere?
+ return lldb::eValueTypeVariableGlobal;
}
-bool
-ValueObjectMemory::UpdateValue ()
-{
- SetValueIsValid (false);
- m_error.Clear();
+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());
- }
+ ExecutionContext exe_ctx(GetExecutionContextRef());
- Value old_value(m_value);
- if (m_address.IsValid())
- {
- Value::ValueType value_type = m_value.GetValueType();
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
+ }
- switch (value_type)
- {
- default:
- assert(!"Unhandled expression result value kind...");
- break;
+ Value old_value(m_value);
+ if (m_address.IsValid()) {
+ Value::ValueType value_type = m_value.GetValueType();
- 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;
+ switch (value_type) {
+ default:
+ assert(!"Unhandled expression result value kind...");
+ 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
+ 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;
- // 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;
- }
- }
+ 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 (!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);
- }
+ // 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;
+ }
+ }
- m_error = value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get());
- }
- break;
+ 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();
+
+ SetValueIsValid(m_error.Success());
+ }
+ 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;
+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();
-}
-
-
+lldb::ModuleSP ValueObjectMemory::GetModule() { return m_address.GetModule(); }
diff --git a/lldb/source/Core/ValueObjectRegister.cpp b/lldb/source/Core/ValueObjectRegister.cpp
index 2664281..0dc2cc0 100644
--- a/lldb/source/Core/ValueObjectRegister.cpp
+++ b/lldb/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,418 +28,321 @@
#pragma mark ValueObjectRegisterContext
-ValueObjectRegisterContext::ValueObjectRegisterContext (ValueObject &parent, RegisterContextSP ®_ctx) :
- ValueObject (parent),
- m_reg_ctx_sp (reg_ctx)
-{
- assert (reg_ctx);
- m_name.SetCString("Registers");
- SetValueIsValid (true);
+ValueObjectRegisterContext::ValueObjectRegisterContext(
+ ValueObject &parent, RegisterContextSP ®_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::GetDisplayTypeName() {
+ return ConstString();
}
-ConstString
-ValueObjectRegisterContext::GetTypeName()
-{
- return ConstString();
+ConstString ValueObjectRegisterContext::GetQualifiedTypeName() {
+ return ConstString();
}
-ConstString
-ValueObjectRegisterContext::GetDisplayTypeName()
-{
- 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;
}
-ConstString
-ValueObjectRegisterContext::GetQualifiedTypeName()
-{
- return ConstString();
+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();
+
+ if (m_reg_ctx_sp.get() == NULL) {
+ SetValueIsValid(false);
+ m_error.SetErrorToGenericError();
+ } else
+ SetValueIsValid(true);
+
+ return m_error.Success();
}
-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;
-}
+ValueObject *ValueObjectRegisterContext::CreateChildAtIndex(
+ size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
+ ValueObject *new_valobj = NULL;
-uint64_t
-ValueObjectRegisterContext::GetByteSize()
-{
- return 0;
-}
-
-bool
-ValueObjectRegisterContext::UpdateValue ()
-{
- m_error.Clear();
+ const size_t num_children = GetNumChildren();
+ if (idx < num_children) {
ExecutionContext exe_ctx(GetExecutionContextRef());
- StackFrame *frame = exe_ctx.GetFramePtr();
- if (frame)
- m_reg_ctx_sp = frame->GetRegisterContext();
- else
- m_reg_ctx_sp.reset();
+ new_valobj = new ValueObjectRegisterSet(
+ exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx);
+ }
- if (m_reg_ctx_sp.get() == NULL)
- {
- SetValueIsValid (false);
- m_error.SetErrorToGenericError();
- }
- else
- SetValueIsValid (true);
-
- return m_error.Success();
+ return new_valobj;
}
-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 ®_ctx_sp, uint32_t set_idx)
-{
- return (new ValueObjectRegisterSet (exe_scope, reg_ctx_sp, set_idx))->GetSP();
+ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP ®_ctx_sp,
+ uint32_t set_idx) {
+ return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP();
}
-
-ValueObjectRegisterSet::ValueObjectRegisterSet (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_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 ®_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::GetQualifiedTypeName() {
+ return ConstString();
}
-ConstString
-ValueObjectRegisterSet::GetTypeName()
-{
- 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;
}
-ConstString
-ValueObjectRegisterSet::GetQualifiedTypeName()
-{
- return ConstString();
-}
+uint64_t ValueObjectRegisterSet::GetByteSize() { 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;
-}
-
-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);
- }
- }
+ 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();
+ }
+ 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;
+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);
- }
+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 ®_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);
+ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
+ lldb::RegisterContextSP ®_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 ®_ctx_sp, uint32_t reg_num)
-{
- return (new ValueObjectRegister (exe_scope, reg_ctx_sp, reg_num))->GetSP();
+ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP ®_ctx_sp,
+ uint32_t reg_num) {
+ return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP();
}
-ValueObjectRegister::ValueObjectRegister (ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_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(ExecutionContextScope *exe_scope,
+ lldb::RegisterContextSP ®_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()
-{
-}
+ValueObjectRegister::~ValueObjectRegister() {}
-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;
-}
-
-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();
+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);
+ }
}
+ }
+ return m_compiler_type;
+}
+ConstString ValueObjectRegister::GetTypeName() {
+ if (m_type_name.IsEmpty())
+ m_type_name = GetCompilerType().GetConstTypeName();
+ return m_type_name;
+}
- 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;
- }
- }
+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.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::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/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
index 27e6264..592f1ea 100644
--- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp
+++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp
@@ -19,437 +19,361 @@
using namespace lldb_private;
-class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd
-{
+class DummySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
public:
- DummySyntheticFrontEnd(ValueObject &backend) :
- SyntheticChildrenFrontEnd(backend)
- {}
+ 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);
- }
+ size_t CalculateNumChildren() override { return m_backend.GetNumChildren(); }
- size_t
- GetIndexOfChildWithName(const ConstString &name) override
- {
- return m_backend.GetIndexOfChildWithName(name);
- }
-
- bool
- MightHaveChildren() override
- {
- return true;
- }
-
- bool
- Update() override
- {
- return false;
- }
+ 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;
+size_t ValueObjectSynthetic::CalculateNumChildren(uint32_t max) {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
- 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;
- }
-}
+ UpdateValueIfNeeded();
+ if (m_synthetic_children_count < UINT32_MAX)
+ return m_synthetic_children_count <= max ? m_synthetic_children_count : max;
-lldb::ValueObjectSP
-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);
-}
-
-uint64_t
-ValueObjectSynthetic::GetByteSize()
-{
- return m_parent->GetByteSize();
-}
-
-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));
-}
-
-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();
- }
-
- // 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());
-
- m_provides_value = eLazyBoolNo;
- CopyValueData(m_parent);
- }
-
- SetValueIsValid(true);
- return true;
-}
-
-lldb::ValueObjectSP
-ValueObjectSynthetic::GetChildAtIndex (size_t idx, bool can_create)
-{
- Log* log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
-
+ if (max < UINT32_MAX) {
+ size_t num_children = m_synth_filter_ap->CalculateNumChildren(max);
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 (log)
- log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at index %zu cached as %p",
- GetName().AsCString(), idx, static_cast<void *>(valobj));
-
- return valobj->GetSP();
- }
+ 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::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);
+ValueObjectSynthetic::GetDynamicValue(lldb::DynamicValueType valueType) {
+ if (!m_parent)
+ return lldb::ValueObjectSP();
+ if (IsDynamic() && GetDynamicValueType() == valueType)
+ return GetSP();
+ return m_parent->GetDynamicValue(valueType);
}
-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;
+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::IsInScope ()
-{
- return m_parent->IsInScope();
+uint64_t ValueObjectSynthetic::GetByteSize() { return m_parent->GetByteSize(); }
+
+lldb::ValueType ValueObjectSynthetic::GetValueType() const {
+ return m_parent->GetValueType();
}
-lldb::ValueObjectSP
-ValueObjectSynthetic::GetNonSyntheticValue ()
-{
- return m_parent->GetSP();
+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::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::UpdateValue() {
+ Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS);
-bool
-ValueObjectSynthetic::CanProvideValue ()
-{
- if (!UpdateValueIfNeeded())
- return false;
- if (m_provides_value == eLazyBoolYes)
- return true;
- return m_parent->CanProvideValue();
-}
+ SetValueIsValid(false);
+ m_error.Clear();
-bool
-ValueObjectSynthetic::SetValueFromCString (const char *value_str, Error& error)
-{
- return m_parent->SetValueFromCString(value_str, error);
-}
-
-void
-ValueObjectSynthetic::SetFormat (lldb::Format format)
-{
- if (m_parent)
- {
- m_parent->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
- m_parent->SetFormat(format);
- }
- this->ValueObject::SetFormat(format);
- this->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
-}
-
-void
-ValueObjectSynthetic::SetPreferredDisplayLanguage (lldb::LanguageType lang)
-{
- this->ValueObject::SetPreferredDisplayLanguage(lang);
- if (m_parent)
- m_parent->SetPreferredDisplayLanguage(lang);
-}
-
-lldb::LanguageType
-ValueObjectSynthetic::GetPreferredDisplayLanguage ()
-{
- if (m_preferred_display_language == lldb::eLanguageTypeUnknown)
- {
- if (m_parent)
- return m_parent->GetPreferredDisplayLanguage();
- return lldb::eLanguageTypeUnknown;
- }
- else
- return m_preferred_display_language;
-}
-
-bool
-ValueObjectSynthetic::IsSyntheticChildrenGenerated ()
-{
- if (m_parent)
- return m_parent->IsSyntheticChildrenGenerated();
+ 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();
+ }
+
+ // 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());
+
+ m_provides_value = eLazyBoolNo;
+ CopyValueData(m_parent);
+ }
+
+ SetValueIsValid(true);
+ return true;
}
-void
-ValueObjectSynthetic::SetSyntheticChildrenGenerated (bool b)
-{
- if (m_parent)
- m_parent->SetSyntheticChildrenGenerated(b);
- this->ValueObject::SetSyntheticChildrenGenerated(b);
+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 (log)
+ log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at "
+ "index %zu cached as %p",
+ GetName().AsCString(), idx, static_cast<void *>(valobj));
+
+ return valobj->GetSP();
+ }
}
-bool
-ValueObjectSynthetic::GetDeclaration (Declaration &decl)
-{
- if (m_parent)
- return m_parent->GetDeclaration(decl);
+lldb::ValueObjectSP
+ValueObjectSynthetic::GetChildMemberWithName(const ConstString &name,
+ bool can_create) {
+ UpdateValueIfNeeded();
- return ValueObject::GetDeclaration(decl);
+ uint32_t index = GetIndexOfChildWithName(name);
+
+ if (index == UINT32_MAX)
+ return lldb::ValueObjectSP();
+
+ return GetChildAtIndex(index, can_create);
}
-uint64_t
-ValueObjectSynthetic::GetLanguageFlags ()
-{
- if (m_parent)
- return m_parent->GetLanguageFlags();
- return this->ValueObject::GetLanguageFlags();
+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::SetLanguageFlags (uint64_t flags)
-{
+bool ValueObjectSynthetic::IsInScope() { return m_parent->IsInScope(); }
+
+lldb::ValueObjectSP ValueObjectSynthetic::GetNonSyntheticValue() {
+ return m_parent->GetSP();
+}
+
+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::CanProvideValue() {
+ if (!UpdateValueIfNeeded())
+ return false;
+ if (m_provides_value == eLazyBoolYes)
+ return true;
+ return m_parent->CanProvideValue();
+}
+
+bool ValueObjectSynthetic::SetValueFromCString(const char *value_str,
+ Error &error) {
+ return m_parent->SetValueFromCString(value_str, error);
+}
+
+void ValueObjectSynthetic::SetFormat(lldb::Format format) {
+ if (m_parent) {
+ m_parent->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
+ m_parent->SetFormat(format);
+ }
+ this->ValueObject::SetFormat(format);
+ this->ClearUserVisibleData(eClearUserVisibleDataItemsAll);
+}
+
+void ValueObjectSynthetic::SetPreferredDisplayLanguage(
+ lldb::LanguageType lang) {
+ this->ValueObject::SetPreferredDisplayLanguage(lang);
+ if (m_parent)
+ m_parent->SetPreferredDisplayLanguage(lang);
+}
+
+lldb::LanguageType ValueObjectSynthetic::GetPreferredDisplayLanguage() {
+ if (m_preferred_display_language == lldb::eLanguageTypeUnknown) {
if (m_parent)
- m_parent->SetLanguageFlags(flags);
- else
- this->ValueObject::SetLanguageFlags(flags);
+ return m_parent->GetPreferredDisplayLanguage();
+ return lldb::eLanguageTypeUnknown;
+ } else
+ return m_preferred_display_language;
+}
+
+bool ValueObjectSynthetic::IsSyntheticChildrenGenerated() {
+ if (m_parent)
+ return m_parent->IsSyntheticChildrenGenerated();
+ return false;
+}
+
+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);
+}
+
+uint64_t ValueObjectSynthetic::GetLanguageFlags() {
+ if (m_parent)
+ return m_parent->GetLanguageFlags();
+ return this->ValueObject::GetLanguageFlags();
+}
+
+void ValueObjectSynthetic::SetLanguageFlags(uint64_t flags) {
+ if (m_parent)
+ m_parent->SetLanguageFlags(flags);
+ else
+ this->ValueObject::SetLanguageFlags(flags);
}
diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp
index a29d858..f0695d8 100644
--- a/lldb/source/Core/ValueObjectVariable.cpp
+++ b/lldb/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()
-{
+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());
-
- 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;
-}
-
-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);
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target) {
+ m_data.SetByteOrder(target->GetArchitecture().GetByteOrder());
+ m_data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
}
- 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());
- }
- 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);
+ 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);
- Value::ValueType value_type = m_value.GetValueType();
+ CompilerType compiler_type = GetCompilerType();
+ if (compiler_type.IsValid())
+ m_value.SetCompilerType(compiler_type);
- 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;
+ Value::ValueType value_type = m_value.GetValueType();
- 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;
+ 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;
+ }
+ }
}
-
- 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 (!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);
+
+ 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.
+ }
+ // 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();
+ }
+ }
+ return lldb::ModuleSP();
+}
+
+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;
}
-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();
+const char *ValueObjectVariable::GetLocationAsCString() {
+ if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
+ return GetLocationAsCStringImpl(m_resolved_value, m_data);
+ else
+ return ValueObject::GetLocationAsCString();
}
-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;
- }
+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;
+ }
+ 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;
+ }
+ } else
+ return ValueObject::SetValueFromCString(value_str, error);
}
-const char *
-ValueObjectVariable::GetLocationAsCString ()
-{
- if (m_resolved_value.GetContextType() == Value::eContextTypeRegisterInfo)
- return GetLocationAsCStringImpl(m_resolved_value,
- m_data);
- else
- return ValueObject::GetLocationAsCString();
-}
+bool ValueObjectVariable::SetData(DataExtractor &data, 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.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::SetValueFromCString(value_str, error);
-}
-
-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;
- }
- 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);
}