[Lldb-commits] [lldb] r280751 - *** This commit represents a complete reformatting of the LLDB source code
Kate Stone via lldb-commits
lldb-commits at lists.llvm.org
Tue Sep 6 13:58:36 PDT 2016
Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Tue Sep 6 15:57:50 2016
@@ -19,1108 +19,963 @@
#include "lldb/Core/Section.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
-#include "lldb/Symbol/SymbolVendor.h"
using namespace lldb;
using namespace lldb_private;
-static size_t
-ReadBytes (ExecutionContextScope *exe_scope, const Address &address, void *dst, size_t dst_len)
-{
- if (exe_scope == nullptr)
- return 0;
-
- TargetSP target_sp (exe_scope->CalculateTarget());
- if (target_sp)
- {
- Error error;
- bool prefer_file_cache = false;
- return target_sp->ReadMemory (address, prefer_file_cache, dst, dst_len, error);
- }
+static size_t ReadBytes(ExecutionContextScope *exe_scope,
+ const Address &address, void *dst, size_t dst_len) {
+ if (exe_scope == nullptr)
return 0;
-}
-static bool
-GetByteOrderAndAddressSize (ExecutionContextScope *exe_scope, const Address &address, ByteOrder& byte_order, uint32_t& addr_size)
-{
- byte_order = eByteOrderInvalid;
- addr_size = 0;
- if (exe_scope == nullptr)
- return false;
-
- TargetSP target_sp (exe_scope->CalculateTarget());
- if (target_sp)
- {
- byte_order = target_sp->GetArchitecture().GetByteOrder();
- addr_size = target_sp->GetArchitecture().GetAddressByteSize();
- }
-
- if (byte_order == eByteOrderInvalid || addr_size == 0)
- {
- ModuleSP module_sp (address.GetModule());
- if (module_sp)
- {
- byte_order = module_sp->GetArchitecture().GetByteOrder();
- addr_size = module_sp->GetArchitecture().GetAddressByteSize();
- }
- }
- return byte_order != eByteOrderInvalid && addr_size != 0;
-}
+ TargetSP target_sp(exe_scope->CalculateTarget());
+ if (target_sp) {
+ 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 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;
-}
+ 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();
+ }
+ }
+ 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 bool
-ReadAddress (ExecutionContextScope *exe_scope, const Address &address, uint32_t pointer_size, Address &deref_so_addr)
-{
- if (exe_scope == nullptr)
- return false;
-
- bool success = false;
- addr_t deref_addr = ReadUIntMax64 (exe_scope, address, pointer_size, success);
- if (success)
- {
- ExecutionContext exe_ctx;
- exe_scope->CalculateExecutionContext(exe_ctx);
- // If we have any sections that are loaded, try and resolve using the
- // section load list
- Target *target = exe_ctx.GetTargetPtr();
- if (target && !target->GetSectionLoadList().IsEmpty())
- {
- if (target->GetSectionLoadList().ResolveLoadAddress (deref_addr, deref_so_addr))
- return true;
- }
- else
- {
- // If we were not running, yet able to read an integer, we must
- // have a module
- ModuleSP module_sp (address.GetModule());
-
- assert (module_sp);
- if (module_sp->ResolveFileAddress(deref_addr, deref_so_addr))
- return true;
- }
+ success = ReadBytes(exe_scope, address, &buf, byte_size) == byte_size;
+ if (success) {
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t addr_size = 0;
+ if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
+ DataExtractor data(&buf, sizeof(buf), byte_order, addr_size);
+ lldb::offset_t offset = 0;
+ uval64 = data.GetU64(&offset);
+ } else
+ success = false;
+ }
+ return uval64;
+}
+
+static bool ReadAddress(ExecutionContextScope *exe_scope,
+ const Address &address, uint32_t pointer_size,
+ Address &deref_so_addr) {
+ if (exe_scope == nullptr)
+ return false;
- // We couldn't make "deref_addr" into a section offset value, but we were
- // able to read the address, so we return a section offset address with
- // no section and "deref_addr" as the offset (address).
- deref_so_addr.SetRawAddress(deref_addr);
+ bool success = false;
+ addr_t deref_addr = ReadUIntMax64(exe_scope, address, pointer_size, success);
+ if (success) {
+ ExecutionContext exe_ctx;
+ exe_scope->CalculateExecutionContext(exe_ctx);
+ // If we have any sections that are loaded, try and resolve using the
+ // section load list
+ Target *target = exe_ctx.GetTargetPtr();
+ if (target && !target->GetSectionLoadList().IsEmpty()) {
+ if (target->GetSectionLoadList().ResolveLoadAddress(deref_addr,
+ deref_so_addr))
+ return true;
+ } 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;
}
- 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);
-
- 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
+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);
- return true;
- }
- }
- return false;
+ if (ReadBytes(exe_scope, address, &buf[0], buf.size()) == buf.size()) {
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t addr_size = 0;
+ if (GetByteOrderAndAddressSize(exe_scope, address, byte_order, addr_size)) {
+ DataExtractor data(&buf.front(), buf.size(), byte_order, addr_size);
+
+ data.Dump(strm,
+ 0, // Start offset in "data"
+ eFormatHex, // Print as characters
+ buf.size(), // Size of item
+ 1, // Items count
+ UINT32_MAX, // num per line
+ LLDB_INVALID_ADDRESS, // base address
+ 0, // bitfield bit size
+ 0); // bitfield bit offset
+
+ return true;
+ }
+ }
+ return false;
+}
+
+static size_t ReadCStringFromMemory(ExecutionContextScope *exe_scope,
+ const Address &address, Stream *strm) {
+ if (exe_scope == nullptr)
+ return 0;
+ const size_t k_buf_len = 256;
+ char buf[k_buf_len + 1];
+ buf[k_buf_len] = '\0'; // NULL terminate
+
+ // Byte order and address size don't matter for C string dumping..
+ DataExtractor data(buf, sizeof(buf), endian::InlHostByteOrder(), 4);
+ size_t total_len = 0;
+ size_t bytes_read;
+ Address curr_address(address);
+ strm->PutChar('"');
+ while ((bytes_read = ReadBytes(exe_scope, curr_address, buf, k_buf_len)) >
+ 0) {
+ size_t len = strlen(buf);
+ if (len == 0)
+ break;
+ if (len > bytes_read)
+ len = bytes_read;
+
+ data.Dump(strm,
+ 0, // Start offset in "data"
+ eFormatChar, // Print as characters
+ 1, // Size of item (1 byte for a char!)
+ len, // How many bytes to print?
+ UINT32_MAX, // num per line
+ LLDB_INVALID_ADDRESS, // base address
+ 0, // bitfield bit size
+
+ 0); // bitfield bit offset
+
+ total_len += bytes_read;
+
+ if (len < k_buf_len)
+ break;
+ curr_address.SetOffset(curr_address.GetOffset() + bytes_read);
+ }
+ strm->PutChar('"');
+ return total_len;
+}
+
+Address::Address(lldb::addr_t abs_addr) : m_section_wp(), m_offset(abs_addr) {}
+
+Address::Address(addr_t address, const SectionList *section_list)
+ : m_section_wp(), m_offset(LLDB_INVALID_ADDRESS) {
+ ResolveAddressUsingFileSections(address, section_list);
+}
+
+const Address &Address::operator=(const Address &rhs) {
+ if (this != &rhs) {
+ m_section_wp = rhs.m_section_wp;
+ m_offset = rhs.m_offset;
+ }
+ return *this;
+}
+
+bool Address::ResolveAddressUsingFileSections(addr_t file_addr,
+ const SectionList *section_list) {
+ if (section_list) {
+ SectionSP section_sp(
+ section_list->FindSectionContainingFileAddress(file_addr));
+ m_section_wp = section_sp;
+ if (section_sp) {
+ assert(section_sp->ContainsFileAddress(file_addr));
+ m_offset = file_addr - section_sp->GetFileAddress();
+ return true; // Successfully transformed addr into a section offset
+ // address
+ }
+ }
+ m_offset = file_addr;
+ return false; // Failed to resolve this address to a section offset value
+}
+
+ModuleSP Address::GetModule() const {
+ lldb::ModuleSP module_sp;
+ SectionSP section_sp(GetSection());
+ if (section_sp)
+ module_sp = section_sp->GetModule();
+ return module_sp;
+}
+
+addr_t Address::GetFileAddress() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ addr_t sect_file_addr = section_sp->GetFileAddress();
+ if (sect_file_addr == LLDB_INVALID_ADDRESS) {
+ // Section isn't resolved, we can't return a valid file address
+ return LLDB_INVALID_ADDRESS;
+ }
+ // We have a valid file range, so we can return the file based
+ // address by adding the file base address to our offset
+ return sect_file_addr + m_offset;
+ } else if (SectionWasDeletedPrivate()) {
+ // Used to have a valid section but it got deleted so the
+ // offset doesn't mean anything without the section
+ return LLDB_INVALID_ADDRESS;
+ }
+ // No section, we just return the offset since it is the value in this case
+ return m_offset;
}
-static size_t
-ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, Stream *strm)
-{
- if (exe_scope == nullptr)
- return 0;
- const size_t k_buf_len = 256;
- char buf[k_buf_len+1];
- buf[k_buf_len] = '\0'; // NULL terminate
-
- // Byte order and address size don't matter for C string dumping..
- DataExtractor data (buf, sizeof(buf), endian::InlHostByteOrder(), 4);
- size_t total_len = 0;
- size_t bytes_read;
- Address curr_address(address);
- strm->PutChar ('"');
- while ((bytes_read = ReadBytes (exe_scope, curr_address, buf, k_buf_len)) > 0)
- {
- size_t len = strlen(buf);
- if (len == 0)
- break;
- if (len > bytes_read)
- len = bytes_read;
-
- data.Dump (strm,
- 0, // Start offset in "data"
- eFormatChar, // Print as characters
- 1, // Size of item (1 byte for a char!)
- len, // How many bytes to print?
- UINT32_MAX, // num per line
- LLDB_INVALID_ADDRESS,// base address
- 0, // bitfield bit size
-
- 0); // bitfield bit offset
-
- total_len += bytes_read;
-
- if (len < k_buf_len)
- break;
- curr_address.SetOffset (curr_address.GetOffset() + bytes_read);
- }
- strm->PutChar ('"');
- return total_len;
-}
-
-Address::Address (lldb::addr_t abs_addr) :
- m_section_wp (),
- m_offset (abs_addr)
-{
-}
-
-Address::Address (addr_t address, const SectionList *section_list) :
- m_section_wp (),
- m_offset (LLDB_INVALID_ADDRESS)
-{
- ResolveAddressUsingFileSections(address, section_list);
-}
-
-const Address&
-Address::operator= (const Address& rhs)
-{
- if (this != &rhs)
- {
- m_section_wp = rhs.m_section_wp;
- m_offset = rhs.m_offset;
- }
- return *this;
-}
-
-bool
-Address::ResolveAddressUsingFileSections (addr_t file_addr, const SectionList *section_list)
-{
- if (section_list)
- {
- SectionSP section_sp (section_list->FindSectionContainingFileAddress(file_addr));
- m_section_wp = section_sp;
- if (section_sp)
- {
- assert( section_sp->ContainsFileAddress(file_addr) );
- m_offset = file_addr - section_sp->GetFileAddress();
- return true; // Successfully transformed addr into a section offset address
- }
- }
- m_offset = file_addr;
- return false; // Failed to resolve this address to a section offset value
-}
+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;
- }
- 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;
- }
- }
+ 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;
+ }
+ } else {
+ code_addr = GetLoadAddress(target);
+ }
-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;
-
- if (target)
- return target->GetCallableLoadAddress (code_addr, GetAddressClass());
+ if (code_addr == LLDB_INVALID_ADDRESS)
return code_addr;
-}
-bool
-Address::SetCallableLoadAddress (lldb::addr_t load_addr, Target *target)
-{
- if (SetLoadAddress (load_addr, target))
- {
- if (target)
- m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
- return true;
- }
- return false;
+ if (target)
+ return target->GetCallableLoadAddress(code_addr, GetAddressClass());
+ return code_addr;
}
-addr_t
-Address::GetOpcodeLoadAddress (Target *target, AddressClass addr_class) const
-{
- addr_t code_addr = GetLoadAddress (target);
- if (code_addr != LLDB_INVALID_ADDRESS)
- {
- if (addr_class == eAddressClassInvalid)
- addr_class = GetAddressClass();
- code_addr = target->GetOpcodeLoadAddress (code_addr, addr_class);
- }
- return code_addr;
+bool Address::SetCallableLoadAddress(lldb::addr_t load_addr, Target *target) {
+ if (SetLoadAddress(load_addr, target)) {
+ if (target)
+ m_offset = target->GetCallableLoadAddress(m_offset, GetAddressClass());
+ return true;
+ }
+ return false;
}
-bool
-Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target, AddressClass addr_class)
-{
- if (SetLoadAddress (load_addr, target))
- {
- if (target)
- {
- if (addr_class == eAddressClassInvalid)
- addr_class = GetAddressClass();
- m_offset = target->GetOpcodeLoadAddress (m_offset, addr_class);
- }
- return true;
+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 false;
+ 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;
+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);
+ }
- case DumpStyleLoadAddress:
- {
- addr_t load_addr = GetLoadAddress (target);
-
- /*
- * MIPS:
- * Display address in compressed form for MIPS16 or microMIPS
- * if the address belongs to eAddressClassCodeAlternateISA.
- */
- if (target)
- {
- const llvm::Triple::ArchType llvm_arch = target->GetArchitecture().GetMachine();
- if (llvm_arch == llvm::Triple::mips || llvm_arch == llvm::Triple::mipsel
- || llvm_arch == llvm::Triple::mips64 || llvm_arch == llvm::Triple::mips64el)
- load_addr = GetCallableLoadAddress (target);
- }
+ Address so_addr;
+ switch (style) {
+ case DumpStyleInvalid:
+ return false;
- if (load_addr == LLDB_INVALID_ADDRESS)
- {
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
+ 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;
+ }
+ }
+ }
}
- s->Address (load_addr, addr_size);
- }
- break;
+ }
+ 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 eSectionTypeDataCString:
- // Read the C string from memory and display it
- showed_info = true;
- ReadCStringFromMemory (exe_scope, *this, s);
- break;
-
- case eSectionTypeDataCStringPointers:
- if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
- {
+ case eSectionTypeDataCStringPointers:
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
#if VERBOSE_OUTPUT
- s->PutCString("(char *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(": ");
+ s->PutCString("(char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(": ");
#endif
- showed_info = true;
- ReadCStringFromMemory(exe_scope, so_addr, s);
- }
- break;
-
- case eSectionTypeDataObjCMessageRefs:
- if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
- {
- if (target && so_addr.IsSectionOffset())
- {
- SymbolContext func_sc;
- target->GetImages().ResolveSymbolContextForAddress(so_addr,
- eSymbolContextEverything,
- func_sc);
- if (func_sc.function != nullptr || func_sc.symbol != nullptr)
- {
- showed_info = true;
+ showed_info = true;
+ ReadCStringFromMemory(exe_scope, so_addr, s);
+ }
+ break;
+
+ case eSectionTypeDataObjCMessageRefs:
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
+ if (target && so_addr.IsSectionOffset()) {
+ SymbolContext func_sc;
+ target->GetImages().ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, func_sc);
+ if (func_sc.function != nullptr || func_sc.symbol != nullptr) {
+ showed_info = true;
#if VERBOSE_OUTPUT
- s->PutCString ("(objc_msgref *) -> { (func*)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
+ s->PutCString("(objc_msgref *) -> { (func*)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
#else
- s->PutCString ("{ ");
+ s->PutCString("{ ");
#endif
- Address cstr_addr(*this);
- cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
- func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true, true);
- if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr))
- {
+ Address cstr_addr(*this);
+ cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
+ func_sc.DumpStopContext(s, exe_scope, so_addr, true, true,
+ false, true, true);
+ if (ReadAddress(exe_scope, cstr_addr, pointer_size, so_addr)) {
#if VERBOSE_OUTPUT
- s->PutCString("), (char *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(" (");
+ s->PutCString("), (char *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(" (");
#else
- s->PutCString(", ");
+ s->PutCString(", ");
#endif
- ReadCStringFromMemory (exe_scope, so_addr, s);
- }
+ ReadCStringFromMemory(exe_scope, so_addr, s);
+ }
#if VERBOSE_OUTPUT
- s->PutCString(") }");
+ s->PutCString(") }");
#else
- s->PutCString(" }");
+ s->PutCString(" }");
#endif
- }
- }
- }
- break;
-
- case eSectionTypeDataObjCCFStrings:
- {
- Address cfstring_data_addr(*this);
- cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
- if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
- {
+ }
+ }
+ }
+ break;
+
+ case eSectionTypeDataObjCCFStrings: {
+ Address cfstring_data_addr(*this);
+ cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() +
+ (2 * pointer_size));
+ if (ReadAddress(exe_scope, cfstring_data_addr, pointer_size,
+ so_addr)) {
#if VERBOSE_OUTPUT
- s->PutCString("(CFString *) ");
- cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
- s->PutCString(" -> @");
+ s->PutCString("(CFString *) ");
+ cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+ s->PutCString(" -> @");
#else
- s->PutChar('@');
+ s->PutChar('@');
#endif
- if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
- showed_info = true;
- }
- }
- break;
-
- case eSectionTypeData4:
- // Read the 4 byte data and display it
- showed_info = true;
- s->PutCString("(uint32_t) ");
- DumpUInt (exe_scope, *this, 4, s);
- break;
-
- case eSectionTypeData8:
- // Read the 8 byte data and display it
- showed_info = true;
- s->PutCString("(uint64_t) ");
- DumpUInt (exe_scope, *this, 8, s);
- break;
-
- case eSectionTypeData16:
- // Read the 16 byte data and display it
- showed_info = true;
- s->PutCString("(uint128_t) ");
- DumpUInt (exe_scope, *this, 16, s);
- break;
-
- case eSectionTypeDataPointers:
- // Read the pointer data and display it
- if (ReadAddress(exe_scope, *this, pointer_size, so_addr))
- {
- s->PutCString ("(void *)");
- so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
-
- showed_info = true;
- if (so_addr.IsSectionOffset())
- {
- SymbolContext pointer_sc;
- if (target)
- {
- target->GetImages().ResolveSymbolContextForAddress(so_addr,
- eSymbolContextEverything,
- pointer_sc);
- if (pointer_sc.function != nullptr || pointer_sc.symbol != nullptr)
- {
- s->PutCString(": ");
- pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true, true);
- }
- }
- }
- }
- break;
-
- default:
- break;
+ if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
+ showed_info = true;
+ }
+ } break;
+
+ case eSectionTypeData4:
+ // Read the 4 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint32_t) ");
+ DumpUInt(exe_scope, *this, 4, s);
+ break;
+
+ case eSectionTypeData8:
+ // Read the 8 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint64_t) ");
+ DumpUInt(exe_scope, *this, 8, s);
+ break;
+
+ case eSectionTypeData16:
+ // Read the 16 byte data and display it
+ showed_info = true;
+ s->PutCString("(uint128_t) ");
+ DumpUInt(exe_scope, *this, 16, s);
+ break;
+
+ case eSectionTypeDataPointers:
+ // Read the pointer data and display it
+ if (ReadAddress(exe_scope, *this, pointer_size, so_addr)) {
+ s->PutCString("(void *)");
+ so_addr.Dump(s, exe_scope, DumpStyleLoadAddress,
+ DumpStyleFileAddress);
+
+ showed_info = true;
+ if (so_addr.IsSectionOffset()) {
+ SymbolContext pointer_sc;
+ if (target) {
+ target->GetImages().ResolveSymbolContextForAddress(
+ so_addr, eSymbolContextEverything, pointer_sc);
+ if (pointer_sc.function != nullptr ||
+ pointer_sc.symbol != nullptr) {
+ s->PutCString(": ");
+ pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
+ false, true, true);
}
+ }
}
+ }
+ break;
- if (!showed_info)
- {
- if (module_sp)
- {
- SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
- if (sc.function || sc.symbol)
- {
- bool show_stop_context = true;
- const bool show_module = (style == DumpStyleResolvedDescription);
- const bool show_fullpaths = false;
- const bool show_inlined_frames = true;
- const bool show_function_arguments = (style != DumpStyleResolvedDescriptionNoFunctionArguments);
- const bool show_function_name = (style != DumpStyleNoFunctionName);
- if (sc.function == nullptr && sc.symbol != nullptr)
- {
- // If we have just a symbol make sure it is in the right section
- if (sc.symbol->ValueIsAddress())
- {
- if (sc.symbol->GetAddressRef().GetSection() != GetSection())
- {
- // don't show the module if the symbol is a trampoline symbol
- show_stop_context = false;
- }
- }
- }
- if (show_stop_context)
- {
- // We have a function or a symbol from the same
- // sections as this address.
- sc.DumpStopContext (s,
- exe_scope,
- *this,
- show_fullpaths,
- show_module,
- show_inlined_frames,
- show_function_arguments,
- show_function_name);
- }
- else
- {
- // We found a symbol but it was in a different
- // section so it isn't the symbol we should be
- // showing, just show the section name + offset
- Dump (s, exe_scope, DumpStyleSectionNameOffset);
- }
- }
- }
- }
- }
- else
- {
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
+ default:
+ break;
}
- break;
+ }
- case DumpStyleDetailedSymbolContext:
- if (IsSectionOffset())
- {
- ModuleSP module_sp (GetModule());
- if (module_sp)
- {
- SymbolContext sc;
- module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything | eSymbolContextVariable, sc);
- if (sc.symbol)
- {
- // If we have just a symbol make sure it is in the same section
- // as our address. If it isn't, then we might have just found
- // the last symbol that came before the address that we are
- // looking up that has nothing to do with our address lookup.
- if (sc.symbol->ValueIsAddress() && sc.symbol->GetAddressRef().GetSection() != GetSection())
- sc.symbol = nullptr;
- }
- sc.GetDescription(s, eDescriptionLevelBrief, target);
-
- if (sc.block)
- {
- bool can_create = true;
- bool get_parent_variables = true;
- bool stop_if_block_is_inlined_function = false;
- VariableList variable_list;
- sc.block->AppendVariables (can_create,
- get_parent_variables,
- stop_if_block_is_inlined_function,
- [](Variable*) { return true; },
- &variable_list);
-
- const size_t num_variables = variable_list.GetSize();
- for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
- {
- Variable *var = variable_list.GetVariableAtIndex (var_idx).get();
- if (var && var->LocationIsValidForAddress (*this))
- {
- s->Indent();
- s->Printf (" Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\"",
- var->GetID(),
- var->GetName().GetCString());
- Type *type = var->GetType();
- if (type)
- s->Printf(", type = \"%s\"", type->GetName().GetCString());
- else
- s->PutCString(", type = <unknown>");
- s->PutCString(", location = ");
- var->DumpLocationForAddress(s, *this);
- s->PutCString(", decl = ");
- var->GetDeclaration().DumpStopContext(s, false);
- s->EOL();
- }
- }
+ if (!showed_info) {
+ if (module_sp) {
+ SymbolContext sc;
+ module_sp->ResolveSymbolContextForAddress(
+ *this, eSymbolContextEverything, sc);
+ if (sc.function || sc.symbol) {
+ bool show_stop_context = true;
+ const bool show_module = (style == DumpStyleResolvedDescription);
+ const bool show_fullpaths = false;
+ const bool show_inlined_frames = true;
+ const bool show_function_arguments =
+ (style != DumpStyleResolvedDescriptionNoFunctionArguments);
+ const bool show_function_name = (style != DumpStyleNoFunctionName);
+ if (sc.function == nullptr && sc.symbol != nullptr) {
+ // If we have just a symbol make sure it is in the right section
+ if (sc.symbol->ValueIsAddress()) {
+ if (sc.symbol->GetAddressRef().GetSection() != GetSection()) {
+ // don't show the module if the symbol is a trampoline symbol
+ show_stop_context = false;
}
+ }
}
- }
- else
- {
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
- }
- break;
-
- case DumpStyleResolvedPointerDescription:
- {
- Process *process = exe_ctx.GetProcessPtr();
- if (process)
- {
- addr_t load_addr = GetLoadAddress (target);
- if (load_addr != LLDB_INVALID_ADDRESS)
- {
- Error memory_error;
- addr_t dereferenced_load_addr = process->ReadPointerFromMemory(load_addr, memory_error);
- if (dereferenced_load_addr != LLDB_INVALID_ADDRESS)
- {
- Address dereferenced_addr;
- if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr, target))
- {
- StreamString strm;
- if (dereferenced_addr.Dump (&strm, exe_scope, DumpStyleResolvedDescription, DumpStyleInvalid, addr_size))
- {
- s->Address (dereferenced_load_addr, addr_size, " -> ", " ");
- s->Write(strm.GetData(), strm.GetSize());
- return true;
- }
- }
- }
- }
+ if (show_stop_context) {
+ // We have a function or a symbol from the same
+ // sections as this address.
+ sc.DumpStopContext(s, exe_scope, *this, show_fullpaths,
+ show_module, show_inlined_frames,
+ show_function_arguments, show_function_name);
+ } else {
+ // We found a symbol but it was in a different
+ // section so it isn't the symbol we should be
+ // showing, just show the section name + offset
+ Dump(s, exe_scope, DumpStyleSectionNameOffset);
}
- if (fallback_style != DumpStyleInvalid)
- return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
- return false;
- }
- break;
- }
-
- return true;
-}
-
-bool
-Address::SectionWasDeleted() const
-{
- if (GetSection())
- return false;
- return SectionWasDeletedPrivate();
-}
-
-bool
-Address::SectionWasDeletedPrivate() const
-{
- lldb::SectionWP empty_section_wp;
-
- // If either call to "std::weak_ptr::owner_before(...) value returns true, this
- // indicates that m_section_wp once contained (possibly still does) a reference
- // to a valid shared pointer. This helps us know if we had a valid reference to
- // a section which is now invalid because the module it was in was unloaded/deleted,
- // or if the address doesn't have a valid reference to a section.
- return empty_section_wp.owner_before(m_section_wp) || m_section_wp.owner_before(empty_section_wp);
-}
-
-uint32_t
-Address::CalculateSymbolContext (SymbolContext *sc, uint32_t resolve_scope) const
-{
- sc->Clear(false);
- // Absolute addresses don't have enough information to reconstruct even their target.
-
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- ModuleSP module_sp (section_sp->GetModule());
- if (module_sp)
- {
- sc->module_sp = module_sp;
- if (sc->module_sp)
- return sc->module_sp->ResolveSymbolContextForAddress (*this, resolve_scope, *sc);
- }
- }
- return 0;
-}
-
-ModuleSP
-Address::CalculateSymbolContextModule () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- return section_sp->GetModule();
- return ModuleSP();
-}
-
-CompileUnit *
-Address::CalculateSymbolContextCompileUnit () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- SymbolContext sc;
- sc.module_sp = section_sp->GetModule();
- if (sc.module_sp)
- {
- sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextCompUnit, sc);
- return sc.comp_unit;
- }
- }
- return nullptr;
-}
-
-Function *
-Address::CalculateSymbolContextFunction () const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- 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)
- {
+ }
+ } else {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ break;
+
+ case DumpStyleDetailedSymbolContext:
+ if (IsSectionOffset()) {
+ ModuleSP module_sp(GetModule());
+ if (module_sp) {
SymbolContext sc;
- sc.module_sp = section_sp->GetModule();
- if (sc.module_sp)
- {
- sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextSymbol, sc);
- return sc.symbol;
+ 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();
+ }
+ }
}
- }
- return nullptr;
-}
-
-bool
-Address::CalculateSymbolContextLineEntry (LineEntry &line_entry) const
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- SymbolContext sc;
- sc.module_sp = section_sp->GetModule();
- if (sc.module_sp)
- {
- sc.module_sp->ResolveSymbolContextForAddress (*this, eSymbolContextLineEntry, sc);
- if (sc.line_entry.IsValid())
- {
- line_entry = sc.line_entry;
- return true;
+ }
+ } else {
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ break;
+
+ case DumpStyleResolvedPointerDescription: {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process) {
+ addr_t load_addr = GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS) {
+ Error memory_error;
+ addr_t dereferenced_load_addr =
+ process->ReadPointerFromMemory(load_addr, memory_error);
+ if (dereferenced_load_addr != LLDB_INVALID_ADDRESS) {
+ Address dereferenced_addr;
+ if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr,
+ target)) {
+ StreamString strm;
+ if (dereferenced_addr.Dump(&strm, exe_scope,
+ DumpStyleResolvedDescription,
+ DumpStyleInvalid, addr_size)) {
+ s->Address(dereferenced_load_addr, addr_size, " -> ", " ");
+ s->Write(strm.GetData(), strm.GetSize());
+ return true;
}
+ }
}
+ }
}
- line_entry.Clear();
+ if (fallback_style != DumpStyleInvalid)
+ return Dump(s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
return false;
-}
+ } break;
+ }
-int
-Address::CompareFileAddress (const Address& a, const Address& b)
-{
- addr_t a_file_addr = a.GetFileAddress();
- addr_t b_file_addr = b.GetFileAddress();
- if (a_file_addr < b_file_addr)
- return -1;
- if (a_file_addr > b_file_addr)
- return +1;
- return 0;
+ return true;
}
-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::SectionWasDeleted() const {
+ if (GetSection())
+ return false;
+ return SectionWasDeletedPrivate();
}
-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;
-}
+bool Address::SectionWasDeletedPrivate() const {
+ lldb::SectionWP empty_section_wp;
-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);
+ // If either call to "std::weak_ptr::owner_before(...) value returns true,
+ // this
+ // indicates that m_section_wp once contained (possibly still does) a
+ // reference
+ // to a valid shared pointer. This helps us know if we had a valid reference
+ // to
+ // a section which is now invalid because the module it was in was
+ // unloaded/deleted,
+ // or if the address doesn't have a valid reference to a section.
+ return empty_section_wp.owner_before(m_section_wp) ||
+ m_section_wp.owner_before(empty_section_wp);
+}
+
+uint32_t Address::CalculateSymbolContext(SymbolContext *sc,
+ uint32_t resolve_scope) const {
+ sc->Clear(false);
+ // Absolute addresses don't have enough information to reconstruct even their
+ // target.
+
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ ModuleSP module_sp(section_sp->GetModule());
+ if (module_sp) {
+ sc->module_sp = module_sp;
+ if (sc->module_sp)
+ return sc->module_sp->ResolveSymbolContextForAddress(
+ *this, resolve_scope, *sc);
+ }
+ }
+ return 0;
+}
+
+ModuleSP Address::CalculateSymbolContextModule() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp)
+ return section_sp->GetModule();
+ return ModuleSP();
+}
+
+CompileUnit *Address::CalculateSymbolContextCompileUnit() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this,
+ eSymbolContextCompUnit, sc);
+ return sc.comp_unit;
+ }
+ }
+ return nullptr;
+}
+
+Function *Address::CalculateSymbolContextFunction() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this,
+ eSymbolContextFunction, sc);
+ return sc.function;
+ }
+ }
+ return nullptr;
+}
+
+Block *Address::CalculateSymbolContextBlock() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextBlock,
+ sc);
+ return sc.block;
+ }
+ }
+ return nullptr;
+}
+
+Symbol *Address::CalculateSymbolContextSymbol() const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextSymbol,
+ sc);
+ return sc.symbol;
+ }
+ }
+ return nullptr;
+}
+
+bool Address::CalculateSymbolContextLineEntry(LineEntry &line_entry) const {
+ SectionSP section_sp(GetSection());
+ if (section_sp) {
+ SymbolContext sc;
+ sc.module_sp = section_sp->GetModule();
+ if (sc.module_sp) {
+ sc.module_sp->ResolveSymbolContextForAddress(*this,
+ eSymbolContextLineEntry, sc);
+ if (sc.line_entry.IsValid()) {
+ line_entry = sc.line_entry;
+ return true;
+ }
+ }
+ }
+ line_entry.Clear();
+ return false;
+}
+
+int Address::CompareFileAddress(const Address &a, const Address &b) {
+ addr_t a_file_addr = a.GetFileAddress();
+ addr_t b_file_addr = b.GetFileAddress();
+ if (a_file_addr < b_file_addr)
+ return -1;
+ if (a_file_addr > b_file_addr)
+ return +1;
+ return 0;
+}
+
+int Address::CompareLoadAddress(const Address &a, const Address &b,
+ Target *target) {
+ assert(target != nullptr);
+ addr_t a_load_addr = a.GetLoadAddress(target);
+ addr_t b_load_addr = b.GetLoadAddress(target);
+ if (a_load_addr < b_load_addr)
+ return -1;
+ if (a_load_addr > b_load_addr)
+ return +1;
+ return 0;
+}
+
+int Address::CompareModulePointerAndOffset(const Address &a, const Address &b) {
+ ModuleSP a_module_sp(a.GetModule());
+ ModuleSP b_module_sp(b.GetModule());
+ Module *a_module = a_module_sp.get();
+ Module *b_module = b_module_sp.get();
+ if (a_module < b_module)
+ return -1;
+ if (a_module > b_module)
+ return +1;
+ // Modules are the same, just compare the file address since they should
+ // be unique
+ addr_t a_file_addr = a.GetFileAddress();
+ addr_t b_file_addr = b.GetFileAddress();
+ if (a_file_addr < b_file_addr)
+ return -1;
+ if (a_file_addr > b_file_addr)
+ return +1;
+ return 0;
+}
+
+size_t Address::MemorySize() const {
+ // Noting special for the memory size of a single Address object,
+ // it is just the size of itself.
+ return sizeof(Address);
}
//----------------------------------------------------------------------
-// NOTE: Be careful using this operator. It can correctly compare two
-// addresses from the same Module correctly. It can't compare two
+// NOTE: Be careful using this operator. It can correctly compare two
+// addresses from the same Module correctly. It can't compare two
// addresses from different modules in any meaningful way, but it will
// compare the module pointers.
-//
+//
// To sum things up:
// - works great for addresses within the same module
// - it works for addresses across multiple modules, but don't expect the
// address results to make much sense
//
-// This basically lets Address objects be used in ordered collection
+// This basically lets Address objects be used in ordered collection
// classes.
//----------------------------------------------------------------------
-bool
-lldb_private::operator< (const Address& lhs, const Address& rhs)
-{
- ModuleSP lhs_module_sp (lhs.GetModule());
- ModuleSP rhs_module_sp (rhs.GetModule());
- Module *lhs_module = lhs_module_sp.get();
- Module *rhs_module = rhs_module_sp.get();
- if (lhs_module == rhs_module)
- {
- // Addresses are in the same module, just compare the file addresses
- return lhs.GetFileAddress() < rhs.GetFileAddress();
- }
- else
- {
- // The addresses are from different modules, just use the module
- // pointer value to get consistent ordering
- return lhs_module < rhs_module;
- }
-}
-
-bool
-lldb_private::operator> (const Address& lhs, const Address& rhs)
-{
- ModuleSP lhs_module_sp (lhs.GetModule());
- ModuleSP rhs_module_sp (rhs.GetModule());
- Module *lhs_module = lhs_module_sp.get();
- Module *rhs_module = rhs_module_sp.get();
- if (lhs_module == rhs_module)
- {
- // Addresses are in the same module, just compare the file addresses
- return lhs.GetFileAddress() > rhs.GetFileAddress();
- }
- else
- {
- // The addresses are from different modules, just use the module
- // pointer value to get consistent ordering
- return lhs_module > rhs_module;
- }
+bool lldb_private::operator<(const Address &lhs, const Address &rhs) {
+ ModuleSP lhs_module_sp(lhs.GetModule());
+ ModuleSP rhs_module_sp(rhs.GetModule());
+ Module *lhs_module = lhs_module_sp.get();
+ Module *rhs_module = rhs_module_sp.get();
+ if (lhs_module == rhs_module) {
+ // Addresses are in the same module, just compare the file addresses
+ return lhs.GetFileAddress() < rhs.GetFileAddress();
+ } else {
+ // The addresses are from different modules, just use the module
+ // pointer value to get consistent ordering
+ return lhs_module < rhs_module;
+ }
+}
+
+bool lldb_private::operator>(const Address &lhs, const Address &rhs) {
+ ModuleSP lhs_module_sp(lhs.GetModule());
+ ModuleSP rhs_module_sp(rhs.GetModule());
+ Module *lhs_module = lhs_module_sp.get();
+ Module *rhs_module = rhs_module_sp.get();
+ if (lhs_module == rhs_module) {
+ // Addresses are in the same module, just compare the file addresses
+ return lhs.GetFileAddress() > rhs.GetFileAddress();
+ } else {
+ // The addresses are from different modules, just use the module
+ // pointer value to get consistent ordering
+ return lhs_module > rhs_module;
+ }
}
// The operator == checks for exact equality only (same section, same offset)
-bool
-lldb_private::operator== (const Address& a, const Address& rhs)
-{
- return a.GetOffset() == rhs.GetOffset() &&
- a.GetSection() == rhs.GetSection();
+bool lldb_private::operator==(const Address &a, const Address &rhs) {
+ return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection();
}
// The operator != checks for exact inequality only (differing section, or
// different offset)
-bool
-lldb_private::operator!= (const Address& a, const Address& rhs)
-{
- return a.GetOffset() != rhs.GetOffset() ||
- a.GetSection() != rhs.GetSection();
-}
-
-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;
+bool lldb_private::operator!=(const Address &a, const Address &rhs) {
+ return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection();
}
-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;
+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;
+}
+
+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;
}
Modified: lldb/trunk/source/Core/AddressRange.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/AddressRange.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/AddressRange.cpp (original)
+++ lldb/trunk/source/Core/AddressRange.cpp Tue Sep 6 15:57:50 2016
@@ -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;
-}
-
-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;
+ if (file_base_addr <= file_addr)
+ return (file_addr - file_base_addr) < GetByteSize();
- addr_t load_addr = addr.GetLoadAddress(target);
- if (load_addr == LLDB_INVALID_ADDRESS)
- return false;
+ 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;
+ addr_t file_base_addr = GetBaseAddress().GetFileAddress();
+ if (file_base_addr == LLDB_INVALID_ADDRESS)
return false;
-}
-bool
-AddressRange::ContainsLoadAddress (addr_t load_addr, Target *target) const
-{
- if (load_addr == LLDB_INVALID_ADDRESS)
- return false;
+ if (file_base_addr <= file_addr)
+ return (file_addr - file_base_addr) < GetByteSize();
- addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target);
- if (load_base_addr == LLDB_INVALID_ADDRESS)
- return false;
+ return false;
+}
- if (load_base_addr <= load_addr)
- return (load_addr - load_base_addr) < GetByteSize();
+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;
-}
-void
-AddressRange::Clear()
-{
- m_base_addr.Clear();
- m_byte_size = 0;
+ 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;
+}
- 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);
+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>"));
}
-
- return false;
+ 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;
}
-
-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();
Modified: lldb/trunk/source/Core/AddressResolver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/AddressResolver.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/AddressResolver.cpp (original)
+++ lldb/trunk/source/Core/AddressResolver.cpp Tue Sep 6 15:57:50 2016
@@ -9,7 +9,6 @@
#include "lldb/Core/AddressResolver.h"
-
// Project includes
#include "lldb/Core/Address.h"
@@ -26,41 +25,27 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// AddressResolver:
//----------------------------------------------------------------------
-AddressResolver::AddressResolver ()
-{
-}
+AddressResolver::AddressResolver() {}
-AddressResolver::~AddressResolver ()
-{
-
-}
+AddressResolver::~AddressResolver() {}
-void
-AddressResolver::ResolveAddressInModules (SearchFilter &filter, ModuleList &modules)
-{
- filter.SearchInModuleList(*this, modules);
+void AddressResolver::ResolveAddressInModules(SearchFilter &filter,
+ ModuleList &modules) {
+ filter.SearchInModuleList(*this, modules);
}
-void
-AddressResolver::ResolveAddress (SearchFilter &filter)
-{
- filter.Search (*this);
+void AddressResolver::ResolveAddress(SearchFilter &filter) {
+ filter.Search(*this);
}
-std::vector<AddressRange> &
-AddressResolver::GetAddressRanges ()
-{
- return m_address_ranges;
+std::vector<AddressRange> &AddressResolver::GetAddressRanges() {
+ return m_address_ranges;
}
-size_t
-AddressResolver::GetNumberOfAddresses ()
-{
- return m_address_ranges.size();
+size_t AddressResolver::GetNumberOfAddresses() {
+ return m_address_ranges.size();
}
-AddressRange &
-AddressResolver::GetAddressRangeAtIndex (size_t idx)
-{
+AddressRange &AddressResolver::GetAddressRangeAtIndex(size_t idx) {
return m_address_ranges[idx];
}
Modified: lldb/trunk/source/Core/AddressResolverFileLine.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/AddressResolverFileLine.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/AddressResolverFileLine.cpp (original)
+++ lldb/trunk/source/Core/AddressResolverFileLine.cpp Tue Sep 6 15:57:50 2016
@@ -21,81 +21,58 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// AddressResolverFileLine:
//----------------------------------------------------------------------
-AddressResolverFileLine::AddressResolverFileLine
-(
- const FileSpec &file_spec,
- uint32_t line_no,
- bool check_inlines
-) :
- AddressResolver (),
- m_file_spec (file_spec),
- m_line_number (line_no),
- m_inlines (check_inlines)
-{
-}
+AddressResolverFileLine::AddressResolverFileLine(const FileSpec &file_spec,
+ uint32_t line_no,
+ bool check_inlines)
+ : AddressResolver(), m_file_spec(file_spec), m_line_number(line_no),
+ m_inlines(check_inlines) {}
-AddressResolverFileLine::~AddressResolverFileLine ()
-{
-}
+AddressResolverFileLine::~AddressResolverFileLine() {}
Searcher::CallbackReturn
-AddressResolverFileLine::SearchCallback
-(
- SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing
-)
-{
- SymbolContextList sc_list;
- uint32_t sc_list_size;
- CompileUnit *cu = context.comp_unit;
-
- 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);
- }
+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));
+
+ 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);
}
-
-
Modified: lldb/trunk/source/Core/AddressResolverName.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/AddressResolverName.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/AddressResolverName.cpp (original)
+++ lldb/trunk/source/Core/AddressResolverName.cpp Tue Sep 6 15:57:50 2016
@@ -17,223 +17,176 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/Function.h"
-#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symbol.h"
+#include "lldb/Symbol/SymbolContext.h"
using namespace lldb;
using namespace lldb_private;
AddressResolverName::AddressResolverName(const char *func_name,
- AddressResolver::MatchType type) :
- AddressResolver(),
- m_func_name(func_name),
- m_class_name(nullptr),
- m_regex(),
- m_match_type(type)
-{
- if (m_match_type == AddressResolver::Regexp)
- {
- if (!m_regex.Compile (m_func_name.AsCString()))
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-
- if (log)
- log->Warning ("function name regexp: \"%s\" did not compile.", m_func_name.AsCString());
- }
+ AddressResolver::MatchType type)
+ : AddressResolver(), m_func_name(func_name), m_class_name(nullptr),
+ m_regex(), m_match_type(type) {
+ if (m_match_type == AddressResolver::Regexp) {
+ if (!m_regex.Compile(m_func_name.AsCString())) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ if (log)
+ log->Warning("function name regexp: \"%s\" did not compile.",
+ m_func_name.AsCString());
}
+ }
}
-AddressResolverName::AddressResolverName(RegularExpression &func_regex) :
- AddressResolver(),
- m_func_name(nullptr),
- m_class_name(nullptr),
- m_regex(func_regex),
- m_match_type(AddressResolver::Regexp)
-{
-}
+AddressResolverName::AddressResolverName(RegularExpression &func_regex)
+ : AddressResolver(), m_func_name(nullptr), m_class_name(nullptr),
+ m_regex(func_regex), m_match_type(AddressResolver::Regexp) {}
AddressResolverName::AddressResolverName(const char *class_name,
const char *method,
- AddressResolver::MatchType type) :
- AddressResolver (),
- m_func_name (method),
- m_class_name (class_name),
- m_regex (),
- m_match_type (type)
-{
-}
+ AddressResolver::MatchType type)
+ : AddressResolver(), m_func_name(method), m_class_name(class_name),
+ m_regex(), m_match_type(type) {}
AddressResolverName::~AddressResolverName() = default;
-// FIXME: Right now we look at the module level, and call the module's "FindFunctions".
-// Greg says he will add function tables, maybe at the CompileUnit level to accelerate function
-// lookup. At that point, we should switch the depth to CompileUnit, and look in these tables.
+// FIXME: Right now we look at the module level, and call the module's
+// "FindFunctions".
+// Greg says he will add function tables, maybe at the CompileUnit level to
+// accelerate function
+// lookup. At that point, we should switch the depth to CompileUnit, and look
+// in these tables.
Searcher::CallbackReturn
AddressResolverName::SearchCallback(SearchFilter &filter,
- SymbolContext &context,
- Address *addr,
- bool containing)
-{
- SymbolContextList func_list;
- SymbolContextList sym_list;
-
- bool skip_prologue = true;
- uint32_t i;
- SymbolContext sc;
- Address func_addr;
-
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
-
- if (m_class_name)
- {
- if (log)
- log->Warning ("Class/method function specification not supported yet.\n");
- return Searcher::eCallbackReturnStop;
- }
-
- 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;
+ SymbolContext &context, Address *addr,
+ bool containing) {
+ SymbolContextList func_list;
+ SymbolContextList sym_list;
+
+ bool skip_prologue = true;
+ uint32_t i;
+ SymbolContext sc;
+ Address func_addr;
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
+
+ if (m_class_name) {
+ if (log)
+ log->Warning("Class/method function specification not supported yet.\n");
+ return Searcher::eCallbackReturnStop;
+ }
+
+ const bool include_symbols = false;
+ const bool include_inlines = true;
+ const bool append = false;
+ switch (m_match_type) {
+ case AddressResolver::Exact:
+ if (context.module_sp) {
+ context.module_sp->FindSymbolsWithNameAndType(m_func_name,
+ eSymbolTypeCode, sym_list);
+ context.module_sp->FindFunctions(m_func_name, nullptr,
+ eFunctionNameTypeAuto, include_symbols,
+ include_inlines, append, func_list);
+ }
+ break;
- case AddressResolver::Glob:
- if (log)
- log->Warning ("glob is not supported yet.");
- break;
- }
-
- // Remove any duplicates between the function list and the symbol list
- if (func_list.GetSize())
- {
- for (i = 0; i < func_list.GetSize(); i++)
- {
- if (!func_list.GetContextAtIndex(i, sc))
- continue;
-
- if (sc.function == nullptr)
- continue;
- uint32_t j = 0;
- while (j < sym_list.GetSize())
- {
- SymbolContext symbol_sc;
- if (sym_list.GetContextAtIndex(j, symbol_sc))
- {
- if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress())
- {
- if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef())
- {
- sym_list.RemoveContextAtIndex(j);
- continue; // Don't increment j
- }
- }
- }
+ 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;
- j++;
+ case AddressResolver::Glob:
+ if (log)
+ log->Warning("glob is not supported yet.");
+ break;
+ }
+
+ // Remove any duplicates between the function list and the symbol list
+ if (func_list.GetSize()) {
+ for (i = 0; i < func_list.GetSize(); i++) {
+ if (!func_list.GetContextAtIndex(i, sc))
+ continue;
+
+ if (sc.function == nullptr)
+ continue;
+ uint32_t j = 0;
+ while (j < sym_list.GetSize()) {
+ SymbolContext symbol_sc;
+ if (sym_list.GetContextAtIndex(j, symbol_sc)) {
+ if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress()) {
+ if (sc.function->GetAddressRange().GetBaseAddress() ==
+ symbol_sc.symbol->GetAddressRef()) {
+ sym_list.RemoveContextAtIndex(j);
+ continue; // Don't increment j
}
+ }
}
- 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 < 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);
+ }
}
+ }
}
+ }
- 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 < 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;
+ }
+ 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: ");
-
- if (m_match_type == AddressResolver::Regexp)
- s->Printf("'%s' (regular expression)", m_regex.GetText());
- else
- s->Printf("'%s'", m_func_name.AsCString());
+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());
}
Modified: lldb/trunk/source/Core/ArchSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ArchSpec.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/ArchSpec.cpp (original)
+++ lldb/trunk/source/Core/ArchSpec.cpp Tue Sep 6 15:57:50 2016
@@ -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" },
-
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc , ArchSpec::eCore_sparc_generic , "sparc" },
- { eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9, ArchSpec::eCore_sparc9_generic , "sparcv9" },
-
- { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i386 , "i386" },
- { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486 , "i486" },
- { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i486sx , "i486sx" },
- { eByteOrderLittle, 4, 1, 15, llvm::Triple::x86 , ArchSpec::eCore_x86_32_i686 , "i686" },
-
- { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64 , "x86_64" },
- { eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64 , ArchSpec::eCore_x86_64_x86_64h , "x86_64h" },
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon , ArchSpec::eCore_hexagon_generic, "hexagon" },
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon , ArchSpec::eCore_hexagon_hexagonv4, "hexagonv4" },
- { eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon , ArchSpec::eCore_hexagon_hexagonv5, "hexagonv5" },
-
- { eByteOrderLittle, 4, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach32 , "unknown-mach-32" },
- { eByteOrderLittle, 8, 4, 4 , llvm::Triple::UnknownArch , ArchSpec::eCore_uknownMach64 , "unknown-mach-64" },
-
- { eByteOrderBig , 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba3 , "kalimba3" },
- { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba4 , "kalimba4" },
- { eByteOrderLittle, 4, 1, 1 , llvm::Triple::kalimba , ArchSpec::eCore_kalimba5 , "kalimba5" }
-};
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64,
+ "mips64"},
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64r2,
+ "mips64r2"},
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64r3,
+ "mips64r3"},
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64r5,
+ "mips64r5"},
+ {eByteOrderBig, 8, 2, 4, llvm::Triple::mips64, ArchSpec::eCore_mips64r6,
+ "mips64r6"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64el, "mips64el"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64r2el, "mips64r2el"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64r3el, "mips64r3el"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64r5el, "mips64r5el"},
+ {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el,
+ ArchSpec::eCore_mips64r6el, "mips64r6el"},
+
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_generic,
+ "powerpc"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc601,
+ "ppc601"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc602,
+ "ppc602"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc603,
+ "ppc603"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc603e,
+ "ppc603e"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc603ev,
+ "ppc603ev"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc604,
+ "ppc604"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc604e,
+ "ppc604e"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc620,
+ "ppc620"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc750,
+ "ppc750"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc7400,
+ "ppc7400"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc7450,
+ "ppc7450"},
+ {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc970,
+ "ppc970"},
+
+ {eByteOrderBig, 8, 4, 4, llvm::Triple::ppc64, ArchSpec::eCore_ppc64_generic,
+ "powerpc64"},
+ {eByteOrderBig, 8, 4, 4, llvm::Triple::ppc64,
+ ArchSpec::eCore_ppc64_ppc970_64, "ppc970-64"},
+
+ {eByteOrderBig, 8, 2, 6, llvm::Triple::systemz,
+ ArchSpec::eCore_s390x_generic, "s390x"},
+
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::sparc,
+ ArchSpec::eCore_sparc_generic, "sparc"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::sparcv9,
+ ArchSpec::eCore_sparc9_generic, "sparcv9"},
+
+ {eByteOrderLittle, 4, 1, 15, llvm::Triple::x86, ArchSpec::eCore_x86_32_i386,
+ "i386"},
+ {eByteOrderLittle, 4, 1, 15, llvm::Triple::x86, ArchSpec::eCore_x86_32_i486,
+ "i486"},
+ {eByteOrderLittle, 4, 1, 15, llvm::Triple::x86,
+ ArchSpec::eCore_x86_32_i486sx, "i486sx"},
+ {eByteOrderLittle, 4, 1, 15, llvm::Triple::x86, ArchSpec::eCore_x86_32_i686,
+ "i686"},
+
+ {eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64,
+ ArchSpec::eCore_x86_64_x86_64, "x86_64"},
+ {eByteOrderLittle, 8, 1, 15, llvm::Triple::x86_64,
+ ArchSpec::eCore_x86_64_x86_64h, "x86_64h"},
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon,
+ ArchSpec::eCore_hexagon_generic, "hexagon"},
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon,
+ ArchSpec::eCore_hexagon_hexagonv4, "hexagonv4"},
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::hexagon,
+ ArchSpec::eCore_hexagon_hexagonv5, "hexagonv5"},
+
+ {eByteOrderLittle, 4, 4, 4, llvm::Triple::UnknownArch,
+ ArchSpec::eCore_uknownMach32, "unknown-mach-32"},
+ {eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch,
+ ArchSpec::eCore_uknownMach64, "unknown-mach-64"},
+
+ {eByteOrderBig, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba3,
+ "kalimba3"},
+ {eByteOrderLittle, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba4,
+ "kalimba4"},
+ {eByteOrderLittle, 4, 1, 1, llvm::Triple::kalimba, ArchSpec::eCore_kalimba5,
+ "kalimba5"}};
-// Ensure that we have an entry in the g_core_definitions for each core. If you comment out an entry above,
+// Ensure that we have an entry in the g_core_definitions for each core. If you
+// comment out an entry above,
// you will need to comment out the corresponding ArchSpec::Core enumeration.
-static_assert(sizeof(g_core_definitions) / sizeof(CoreDefinition) == ArchSpec::kNumCores, "make sure we have one core definition for each core");
-
-struct ArchDefinitionEntry
-{
- ArchSpec::Core core;
- uint32_t cpu;
- uint32_t sub;
- uint32_t cpu_mask;
- uint32_t sub_mask;
+static_assert(sizeof(g_core_definitions) / sizeof(CoreDefinition) ==
+ ArchSpec::kNumCores,
+ "make sure we have one core definition for each core");
+
+struct ArchDefinitionEntry {
+ ArchSpec::Core core;
+ uint32_t cpu;
+ uint32_t sub;
+ uint32_t cpu_mask;
+ uint32_t sub_mask;
};
-struct ArchDefinition
-{
- ArchitectureType type;
- size_t num_entries;
- const ArchDefinitionEntry *entries;
- const char *name;
+struct ArchDefinition {
+ ArchitectureType type;
+ size_t num_entries;
+ const ArchDefinitionEntry *entries;
+ const char *name;
};
-size_t
-ArchSpec::AutoComplete (const char *name, StringList &matches)
-{
- if (name && name[0])
- {
- for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
- {
- if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name))
- matches.AppendString (g_core_definitions[i].name);
- }
- }
- else
- {
- for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i)
- matches.AppendString (g_core_definitions[i].name);
- }
- return matches.GetSize();
+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();
}
#define CPU_ANY (UINT32_MAX)
@@ -203,267 +278,311 @@ ArchSpec::AutoComplete (const char *name
// 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 (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 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()
+ : 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)
+ : 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(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 @@ ArchSpec::~ArchSpec() = default;
//===----------------------------------------------------------------------===//
// Assignment and initialization.
-const ArchSpec&
-ArchSpec::operator= (const ArchSpec& rhs)
-{
- if (this != &rhs)
- {
- m_triple = rhs.m_triple;
- m_core = rhs.m_core;
- m_byte_order = rhs.m_byte_order;
- m_distribution_id = rhs.m_distribution_id;
- m_flags = rhs.m_flags;
- }
- return *this;
-}
-
-void
-ArchSpec::Clear()
-{
- m_triple = llvm::Triple();
- m_core = kCore_invalid;
- m_byte_order = eByteOrderInvalid;
- m_distribution_id.Clear ();
- m_flags = 0;
+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;
}
//===----------------------------------------------------------------------===//
// Predicates.
-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;
-}
-
-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;
- }
+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;
+}
+
+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;
+ }
+ return cpu;
}
-uint32_t
-ArchSpec::GetMachOCPUType () const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- {
- const ArchDefinitionEntry *arch_def = FindArchDefinitionEntry (&g_macho_arch_def, core_def->core);
- if (arch_def)
- {
- return arch_def->cpu;
- }
+uint32_t ArchSpec::GetMachOCPUType() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def) {
+ const ArchDefinitionEntry *arch_def =
+ FindArchDefinitionEntry(&g_macho_arch_def, core_def->core);
+ if (arch_def) {
+ return arch_def->cpu;
}
- return LLDB_INVALID_CPUTYPE;
+ }
+ return LLDB_INVALID_CPUTYPE;
}
-uint32_t
-ArchSpec::GetMachOCPUSubType () const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- {
- const ArchDefinitionEntry *arch_def = FindArchDefinitionEntry (&g_macho_arch_def, core_def->core);
- if (arch_def)
- {
- return arch_def->sub;
- }
+uint32_t ArchSpec::GetMachOCPUSubType() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def) {
+ const ArchDefinitionEntry *arch_def =
+ FindArchDefinitionEntry(&g_macho_arch_def, core_def->core);
+ if (arch_def) {
+ return arch_def->sub;
}
- return LLDB_INVALID_CPUTYPE;
+ }
+ return LLDB_INVALID_CPUTYPE;
}
-uint32_t
-ArchSpec::GetDataByteSize () const
-{
- switch (m_core)
- {
- case eCore_kalimba3:
- return 4;
- case eCore_kalimba4:
- return 1;
- case eCore_kalimba5:
- return 4;
- default:
- return 1;
- }
+uint32_t ArchSpec::GetDataByteSize() const {
+ switch (m_core) {
+ case eCore_kalimba3:
+ return 4;
+ case eCore_kalimba4:
+ return 1;
+ case eCore_kalimba5:
+ return 4;
+ default:
return 1;
+ }
+ return 1;
}
-uint32_t
-ArchSpec::GetCodeByteSize () const
-{
- switch (m_core)
- {
- case eCore_kalimba3:
- return 4;
- case eCore_kalimba4:
- return 1;
- case eCore_kalimba5:
- return 1;
- default:
- return 1;
- }
+uint32_t ArchSpec::GetCodeByteSize() const {
+ switch (m_core) {
+ case eCore_kalimba3:
+ return 4;
+ case eCore_kalimba4:
+ return 1;
+ case eCore_kalimba5:
return 1;
+ default:
+ return 1;
+ }
+ return 1;
}
-llvm::Triple::ArchType
-ArchSpec::GetMachine () const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- return core_def->machine;
-
- 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;
+llvm::Triple::ArchType ArchSpec::GetMachine() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->machine;
- 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;
- }
+ return llvm::Triple::UnknownArch;
}
-lldb::ByteOrder
-ArchSpec::GetByteOrder () const
-{
- if (m_byte_order == eByteOrderInvalid)
- return GetDefaultEndian();
- return m_byte_order;
+const ConstString &ArchSpec::GetDistributionId() const {
+ return m_distribution_id;
}
-//===----------------------------------------------------------------------===//
-// Mutators.
+void ArchSpec::SetDistributionId(const char *distribution_id) {
+ m_distribution_id.SetCString(distribution_id);
+}
-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;
- }
- }
- }
+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;
+ }
}
-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());
- }
+lldb::ByteOrder ArchSpec::GetByteOrder() const {
+ if (m_byte_order == eByteOrderInvalid)
+ return GetDefaultEndian();
+ return m_byte_order;
+}
+
+//===----------------------------------------------------------------------===//
+// Mutators.
+
+bool ArchSpec::SetTriple(const llvm::Triple &triple) {
+ m_triple = triple;
+
+ llvm::StringRef arch_name(m_triple.getArchName());
+ const CoreDefinition *core_def = FindCoreDefinition(arch_name);
+ if (core_def) {
+ m_core = core_def->core;
+ // Set the byte order to the default byte order for an architecture.
+ // This can be modified if needed for cases when cores handle both
+ // big and little endian
+ m_byte_order = core_def->default_byte_order;
+ } else {
+ Clear();
+ }
+
+ 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));
+ }
}
- SetTriple (normalized_triple);
+ }
+ return true;
}
+ }
}
- 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);
- }
+ }
+ return false;
}
-bool
-ArchSpec::SetArchitecture (ArchitectureType arch_type, uint32_t cpu, uint32_t sub, uint32_t os)
-{
- m_core = kCore_invalid;
- bool update_triple = true;
- const ArchDefinition *arch_def = FindArchDefinition(arch_type);
- if (arch_def)
- {
- const ArchDefinitionEntry *arch_def_entry = FindArchDefinitionEntry (arch_def, cpu, sub);
- if (arch_def_entry)
- {
- const CoreDefinition *core_def = FindCoreDefinition (arch_def_entry->core);
- if (core_def)
- {
- m_core = core_def->core;
- update_triple = false;
- // Always use the architecture name because it might be more descriptive
- // than the architecture enum ("armv7" -> llvm::Triple::arm).
- m_triple.setArchName(llvm::StringRef(core_def->name));
- if (arch_type == eArchTypeMachO)
- {
- m_triple.setVendor (llvm::Triple::Apple);
-
- // Don't set the OS. It could be simulator, macosx, ios, watchos, tvos. We could
- // get close with the cpu type - but we can't get it right all of the time. Better
- // to leave this unset so other sections of code will set it when they have more
- // information.
- // NB: don't call m_triple.setOS (llvm::Triple::UnknownOS). That sets the OSName to
- // "unknown" and the ArchSpec::TripleVendorWasSpecified() method says that any
- // OSName setting means it was specified.
- }
- else if (arch_type == eArchTypeELF)
- {
- switch (os)
- {
- case llvm::ELF::ELFOSABI_AIX: m_triple.setOS (llvm::Triple::OSType::AIX); break;
- case llvm::ELF::ELFOSABI_FREEBSD: m_triple.setOS (llvm::Triple::OSType::FreeBSD); break;
- case llvm::ELF::ELFOSABI_GNU: m_triple.setOS (llvm::Triple::OSType::Linux); break;
- case llvm::ELF::ELFOSABI_NETBSD: m_triple.setOS (llvm::Triple::OSType::NetBSD); break;
- case llvm::ELF::ELFOSABI_OPENBSD: m_triple.setOS (llvm::Triple::OSType::OpenBSD); break;
- case llvm::ELF::ELFOSABI_SOLARIS: m_triple.setOS (llvm::Triple::OSType::Solaris); break;
- }
- }
- else
- {
- m_triple.setVendor (llvm::Triple::UnknownVendor);
- m_triple.setOS (llvm::Triple::UnknownOS);
- }
- // Fall back onto setting the machine type if the arch by name failed...
- if (m_triple.getArch () == llvm::Triple::UnknownArch)
- m_triple.setArch (core_def->machine);
+bool ArchSpec::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;
+ 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();
+ }
+ CoreUpdated(update_triple);
+ return IsValid();
}
-uint32_t
-ArchSpec::GetMinimumOpcodeByteSize() const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- return core_def->min_opcode_byte_size;
- return 0;
+uint32_t ArchSpec::GetMinimumOpcodeByteSize() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->min_opcode_byte_size;
+ return 0;
}
-uint32_t
-ArchSpec::GetMaximumOpcodeByteSize() const
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- return core_def->max_opcode_byte_size;
- return 0;
+uint32_t ArchSpec::GetMaximumOpcodeByteSize() const {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def)
+ return core_def->max_opcode_byte_size;
+ return 0;
}
-bool
-ArchSpec::IsExactMatch (const ArchSpec& rhs) const
-{
- return IsEqualTo (rhs, true);
+bool ArchSpec::IsExactMatch(const ArchSpec &rhs) const {
+ return IsEqualTo(rhs, true);
}
-bool
-ArchSpec::IsCompatibleMatch (const ArchSpec& rhs) const
-{
- return IsEqualTo (rhs, false);
+bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const {
+ return IsEqualTo(rhs, false);
}
-static bool
-isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs)
-{
- if (lhs == rhs)
- return true;
+static bool isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
+ llvm::Triple::EnvironmentType rhs) {
+ if (lhs == rhs)
+ return true;
- // If any of the environment is unknown then they are compatible
- if (lhs == llvm::Triple::UnknownEnvironment || rhs == llvm::Triple::UnknownEnvironment)
- return true;
+ // If 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;
+ // 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;
+ return false;
}
-bool
-ArchSpec::IsEqualTo (const ArchSpec& rhs, bool exact_match) const
-{
- // explicitly ignoring m_distribution_id in this method.
+bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
+ // explicitly ignoring m_distribution_id in this method.
+
+ if (GetByteOrder() != rhs.GetByteOrder())
+ return false;
+
+ const ArchSpec::Core lhs_core = GetCore();
+ const ArchSpec::Core rhs_core = rhs.GetCore();
- if (GetByteOrder() != rhs.GetByteOrder())
+ const bool core_match = cores_match(lhs_core, rhs_core, true, exact_match);
+
+ if (core_match) {
+ const llvm::Triple &lhs_triple = GetTriple();
+ const llvm::Triple &rhs_triple = rhs.GetTriple();
+
+ const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
+ const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
+ if (lhs_triple_vendor != rhs_triple_vendor) {
+ const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
+ const bool lhs_vendor_specified = TripleVendorWasSpecified();
+ // Both architectures had the vendor specified, so if they aren't
+ // equal then we return false
+ if (rhs_vendor_specified && lhs_vendor_specified)
return false;
-
- const ArchSpec::Core lhs_core = GetCore ();
- const ArchSpec::Core rhs_core = rhs.GetCore ();
-
- const bool core_match = cores_match (lhs_core, rhs_core, true, exact_match);
-
- if (core_match)
- {
- const llvm::Triple &lhs_triple = GetTriple();
- const llvm::Triple &rhs_triple = rhs.GetTriple();
-
- const llvm::Triple::VendorType lhs_triple_vendor = lhs_triple.getVendor();
- const llvm::Triple::VendorType rhs_triple_vendor = rhs_triple.getVendor();
- if (lhs_triple_vendor != rhs_triple_vendor)
- {
- const bool rhs_vendor_specified = rhs.TripleVendorWasSpecified();
- const bool lhs_vendor_specified = TripleVendorWasSpecified();
- // Both architectures had the vendor specified, so if they aren't
- // equal then we return false
- if (rhs_vendor_specified && lhs_vendor_specified)
- return false;
-
- // Only fail if both vendor types are not unknown
- if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
- rhs_triple_vendor != llvm::Triple::UnknownVendor)
- return false;
- }
-
- const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
- const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
- if (lhs_triple_os != rhs_triple_os)
- {
- const bool rhs_os_specified = rhs.TripleOSWasSpecified();
- const bool lhs_os_specified = TripleOSWasSpecified();
- // Both architectures had the OS specified, so if they aren't
- // equal then we return false
- if (rhs_os_specified && lhs_os_specified)
- return false;
-
- // Only fail if both os types are not unknown
- if (lhs_triple_os != llvm::Triple::UnknownOS &&
- rhs_triple_os != llvm::Triple::UnknownOS)
- return false;
- }
- const llvm::Triple::EnvironmentType lhs_triple_env = lhs_triple.getEnvironment();
- const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment();
-
- if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env))
- return false;
- return true;
+ // Only fail if both vendor types are not unknown
+ if (lhs_triple_vendor != llvm::Triple::UnknownVendor &&
+ rhs_triple_vendor != llvm::Triple::UnknownVendor)
+ return false;
}
- return false;
+
+ const llvm::Triple::OSType lhs_triple_os = lhs_triple.getOS();
+ const llvm::Triple::OSType rhs_triple_os = rhs_triple.getOS();
+ if (lhs_triple_os != rhs_triple_os) {
+ const bool rhs_os_specified = rhs.TripleOSWasSpecified();
+ const bool lhs_os_specified = TripleOSWasSpecified();
+ // Both architectures had the OS specified, so if they aren't
+ // equal then we return false
+ if (rhs_os_specified && lhs_os_specified)
+ return false;
+
+ // Only fail if both os types are not unknown
+ if (lhs_triple_os != llvm::Triple::UnknownOS &&
+ rhs_triple_os != llvm::Triple::UnknownOS)
+ return false;
+ }
+
+ const llvm::Triple::EnvironmentType lhs_triple_env =
+ lhs_triple.getEnvironment();
+ const llvm::Triple::EnvironmentType rhs_triple_env =
+ rhs_triple.getEnvironment();
+
+ if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env))
+ return false;
+ return true;
+ }
+ return false;
}
//===----------------------------------------------------------------------===//
// Helper methods.
-void
-ArchSpec::CoreUpdated (bool update_triple)
-{
- const CoreDefinition *core_def = FindCoreDefinition (m_core);
- if (core_def)
- {
- if (update_triple)
- m_triple = llvm::Triple(core_def->name, "unknown", "unknown");
- m_byte_order = core_def->default_byte_order;
- }
- else
- {
- if (update_triple)
- m_triple = llvm::Triple();
- m_byte_order = eByteOrderInvalid;
- }
+void ArchSpec::CoreUpdated(bool update_triple) {
+ const CoreDefinition *core_def = FindCoreDefinition(m_core);
+ if (core_def) {
+ if (update_triple)
+ m_triple = llvm::Triple(core_def->name, "unknown", "unknown");
+ m_byte_order = core_def->default_byte_order;
+ } else {
+ if (update_triple)
+ m_triple = llvm::Triple();
+ m_byte_order = eByteOrderInvalid;
+ }
}
//===----------------------------------------------------------------------===//
// Operators.
-static bool
-cores_match (const ArchSpec::Core core1, const ArchSpec::Core core2, bool try_inverse, bool enforce_exact_match)
-{
- if (core1 == core2)
+static bool cores_match(const ArchSpec::Core core1, const ArchSpec::Core core2,
+ bool try_inverse, bool enforce_exact_match) {
+ if (core1 == core2)
+ return true;
+
+ switch (core1) {
+ case ArchSpec::kCore_any:
+ return true;
+
+ case ArchSpec::eCore_arm_generic:
+ if (enforce_exact_match)
+ break;
+ LLVM_FALLTHROUGH;
+ case ArchSpec::kCore_arm_any:
+ if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last)
+ return true;
+ if (core2 >= ArchSpec::kCore_thumb_first &&
+ core2 <= ArchSpec::kCore_thumb_last)
+ return true;
+ if (core2 == ArchSpec::kCore_arm_any)
+ return true;
+ break;
+
+ case ArchSpec::kCore_x86_32_any:
+ if ((core2 >= ArchSpec::kCore_x86_32_first &&
+ core2 <= ArchSpec::kCore_x86_32_last) ||
+ (core2 == ArchSpec::kCore_x86_32_any))
+ return true;
+ break;
+
+ case ArchSpec::kCore_x86_64_any:
+ if ((core2 >= ArchSpec::kCore_x86_64_first &&
+ core2 <= ArchSpec::kCore_x86_64_last) ||
+ (core2 == ArchSpec::kCore_x86_64_any))
+ return true;
+ break;
+
+ case ArchSpec::kCore_ppc_any:
+ if ((core2 >= ArchSpec::kCore_ppc_first &&
+ core2 <= ArchSpec::kCore_ppc_last) ||
+ (core2 == ArchSpec::kCore_ppc_any))
+ return true;
+ break;
+
+ case ArchSpec::kCore_ppc64_any:
+ if ((core2 >= ArchSpec::kCore_ppc64_first &&
+ core2 <= ArchSpec::kCore_ppc64_last) ||
+ (core2 == ArchSpec::kCore_ppc64_any))
+ return true;
+ break;
+
+ case ArchSpec::eCore_arm_armv6m:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_generic)
return true;
-
- switch (core1)
- {
- case ArchSpec::kCore_any:
+ try_inverse = false;
+ if (core2 == ArchSpec::eCore_arm_armv7)
return true;
+ if (core2 == ArchSpec::eCore_arm_armv6m)
+ return true;
+ }
+ break;
- case ArchSpec::eCore_arm_generic:
- if (enforce_exact_match)
- break;
- LLVM_FALLTHROUGH;
- case ArchSpec::kCore_arm_any:
- if (core2 >= ArchSpec::kCore_arm_first && core2 <= ArchSpec::kCore_arm_last)
- return true;
- if (core2 >= ArchSpec::kCore_thumb_first && core2 <= ArchSpec::kCore_thumb_last)
- return true;
- if (core2 == ArchSpec::kCore_arm_any)
- return true;
- break;
-
- case ArchSpec::kCore_x86_32_any:
- if ((core2 >= ArchSpec::kCore_x86_32_first && core2 <= ArchSpec::kCore_x86_32_last) || (core2 == ArchSpec::kCore_x86_32_any))
- return true;
- break;
-
- case ArchSpec::kCore_x86_64_any:
- if ((core2 >= ArchSpec::kCore_x86_64_first && core2 <= ArchSpec::kCore_x86_64_last) || (core2 == ArchSpec::kCore_x86_64_any))
- return true;
- break;
-
- case ArchSpec::kCore_ppc_any:
- if ((core2 >= ArchSpec::kCore_ppc_first && core2 <= ArchSpec::kCore_ppc_last) || (core2 == ArchSpec::kCore_ppc_any))
- return true;
- break;
-
- case ArchSpec::kCore_ppc64_any:
- if ((core2 >= ArchSpec::kCore_ppc64_first && core2 <= ArchSpec::kCore_ppc64_last) || (core2 == ArchSpec::kCore_ppc64_any))
- return true;
- break;
-
- case ArchSpec::eCore_arm_armv6m:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_generic)
- return true;
- try_inverse = false;
- if (core2 == ArchSpec::eCore_arm_armv7)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv6m)
- return true;
- }
- break;
-
- case ArchSpec::kCore_hexagon_any:
- if ((core2 >= ArchSpec::kCore_hexagon_first && core2 <= ArchSpec::kCore_hexagon_last) || (core2 == ArchSpec::kCore_hexagon_any))
- return true;
- break;
-
- // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
- // Cortex-M0 - ARMv6-M - armv6m
- // Cortex-M3 - ARMv7-M - armv7m
- // Cortex-M4 - ARMv7E-M - armv7em
- case ArchSpec::eCore_arm_armv7em:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_generic)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7m)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv6m)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7)
- return true;
- try_inverse = true;
- }
- break;
-
- // v. https://en.wikipedia.org/wiki/ARM_Cortex-M#Silicon_customization
- // Cortex-M0 - ARMv6-M - armv6m
- // Cortex-M3 - ARMv7-M - armv7m
- // Cortex-M4 - ARMv7E-M - armv7em
- case ArchSpec::eCore_arm_armv7m:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_arm_generic)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv6m)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7)
- return true;
- if (core2 == ArchSpec::eCore_arm_armv7em)
- return true;
- try_inverse = true;
- }
- break;
+ case ArchSpec::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;
- 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;
+ // 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_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_armv7f:
+ case ArchSpec::eCore_arm_armv7k:
+ case ArchSpec::eCore_arm_armv7s:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_arm_generic)
+ return true;
+ if (core2 == ArchSpec::eCore_arm_armv7)
+ return true;
+ try_inverse = false;
+ }
+ break;
- case ArchSpec::eCore_arm_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_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_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_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_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_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_mips32:
- if (!enforce_exact_match)
- {
- if (core2 >= ArchSpec::kCore_mips32_first && core2 <= ArchSpec::kCore_mips32_last)
- return true;
- try_inverse = false;
- }
- break;
+ case ArchSpec::eCore_arm_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_mips32r6:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32 || core2 == ArchSpec::eCore_mips32r6)
- 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_mips32r6el:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el)
- 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_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_mips32r6el:
+ if (!enforce_exact_match) {
+ if (core2 == ArchSpec::eCore_mips32el ||
+ core2 == ArchSpec::eCore_mips32r6el)
+ return true;
+ }
+ break;
- case ArchSpec::eCore_mips64r6el:
- if (!enforce_exact_match)
- {
- if (core2 == ArchSpec::eCore_mips32el || core2 == ArchSpec::eCore_mips32r6el)
- return true;
- if (core2 == ArchSpec::eCore_mips64el || core2 == ArchSpec::eCore_mips64r6el)
- return true;
- }
- break;
+ case ArchSpec::eCore_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;
- default:
- 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;
}
- if (try_inverse)
- return cores_match (core2, core1, false, enforce_exact_match);
- return false;
-}
+ break;
-bool
-lldb_private::operator<(const ArchSpec& lhs, const ArchSpec& rhs)
-{
- const ArchSpec::Core lhs_core = lhs.GetCore ();
- const ArchSpec::Core rhs_core = rhs.GetCore ();
- return lhs_core < rhs_core;
-}
-
-static void
-StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread)
-{
- // We need to check if we are stopped in Thumb mode in a IT instruction
- // and detect if the condition doesn't pass. If this is the case it means
- // we won't actually execute this instruction. If this happens we need to
- // clear the stop reason to no thread plans think we are stopped for a
- // reason and the plans should keep going.
- //
- // We do this because when single stepping many ARM processes, debuggers
- // often use the BVR/BCR registers that says "stop when the PC is not
- // equal to its current value". This method of stepping means we can end
- // up stopping on instructions inside an if/then block that wouldn't get
- // executed. By fixing this we can stop the debugger from seeming like
- // you stepped through both the "if" _and_ the "else" clause when source
- // level stepping because the debugger stops regardless due to the BVR/BCR
- // triggering a stop.
- //
- // It also means we can set breakpoints on instructions inside an an
- // if/then block and correctly skip them if we use the BKPT instruction.
- // The ARM and Thumb BKPT instructions are unconditional even when executed
- // in a Thumb IT block.
- //
- // If your debugger inserts software traps in ARM/Thumb code, it will
- // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
- // instructions respectively. If your debugger inserts a 16 bit thumb
- // trap on top of a 32 bit thumb instruction for an opcode that is inside
- // an if/then, it will change the it/then to conditionally execute your
- // 16 bit trap and then cause your program to crash if it executes the
- // trailing 16 bits (the second half of the 32 bit thumb instruction you
- // partially overwrote).
-
- RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
- if (reg_ctx_sp)
- {
- const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
- if (cpsr != 0)
- {
- // Read the J and T bits to get the ISETSTATE
- const uint32_t J = Bit32(cpsr, 24);
- const uint32_t T = Bit32(cpsr, 5);
- const uint32_t ISETSTATE = J << 1 | T;
- if (ISETSTATE == 0)
- {
- // NOTE: I am pretty sure we want to enable the code below
- // that detects when we stop on an instruction in ARM mode
- // that is conditional and the condition doesn't pass. This
- // can happen if you set a breakpoint on an instruction that
- // is conditional. We currently will _always_ stop on the
- // instruction which is bad. You can also run into this while
- // single stepping and you could appear to run code in the "if"
- // and in the "else" clause because it would stop at all of the
- // conditional instructions in both.
- // In such cases, we really don't want to stop at this location.
- // I will check with the lldb-dev list first before I enable this.
+ 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;
+}
+
+static void StopInfoOverrideCallbackTypeARM(lldb_private::Thread &thread) {
+ // We need to check if we are stopped in Thumb mode in a IT instruction
+ // and detect if the condition doesn't pass. If this is the case it means
+ // we won't actually execute this instruction. If this happens we need to
+ // clear the stop reason to no thread plans think we are stopped for a
+ // reason and the plans should keep going.
+ //
+ // We do this because when single stepping many ARM processes, debuggers
+ // often use the BVR/BCR registers that says "stop when the PC is not
+ // equal to its current value". This method of stepping means we can end
+ // up stopping on instructions inside an if/then block that wouldn't get
+ // executed. By fixing this we can stop the debugger from seeming like
+ // you stepped through both the "if" _and_ the "else" clause when source
+ // level stepping because the debugger stops regardless due to the BVR/BCR
+ // triggering a stop.
+ //
+ // It also means we can set breakpoints on instructions inside an an
+ // if/then block and correctly skip them if we use the BKPT instruction.
+ // The ARM and Thumb BKPT instructions are unconditional even when executed
+ // in a Thumb IT block.
+ //
+ // If your debugger inserts software traps in ARM/Thumb code, it will
+ // need to use 16 and 32 bit instruction for 16 and 32 bit thumb
+ // instructions respectively. If your debugger inserts a 16 bit thumb
+ // trap on top of a 32 bit thumb instruction for an opcode that is inside
+ // an if/then, it will change the it/then to conditionally execute your
+ // 16 bit trap and then cause your program to crash if it executes the
+ // trailing 16 bits (the second half of the 32 bit thumb instruction you
+ // partially overwrote).
+
+ RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
+ if (reg_ctx_sp) {
+ const uint32_t cpsr = reg_ctx_sp->GetFlags(0);
+ if (cpsr != 0) {
+ // Read the J and T bits to get the ISETSTATE
+ const uint32_t J = Bit32(cpsr, 24);
+ const uint32_t T = Bit32(cpsr, 5);
+ const uint32_t ISETSTATE = J << 1 | T;
+ if (ISETSTATE == 0) {
+// NOTE: I am pretty sure we want to enable the code below
+// that detects when we stop on an instruction in ARM mode
+// that is conditional and the condition doesn't pass. This
+// can happen if you set a breakpoint on an instruction that
+// is conditional. We currently will _always_ stop on the
+// instruction which is bad. You can also run into this while
+// single stepping and you could appear to run code in the "if"
+// and in the "else" clause because it would stop at all of the
+// conditional instructions in both.
+// In such cases, we really don't want to stop at this location.
+// I will check with the lldb-dev list first before I enable this.
#if 0
// ARM mode: check for condition on intsruction
const addr_t pc = reg_ctx_sp->GetPC();
@@ -1492,120 +1533,101 @@ StopInfoOverrideCallbackTypeARM(lldb_pri
}
}
#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());
-}
-
-bool
-ArchSpec::IsAlwaysThumbInstructions () const
-{
- std::string Error;
- if (GetTriple().getArch() == llvm::Triple::arm || GetTriple().getArch() == llvm::Triple::thumb)
- {
- // v. https://en.wikipedia.org/wiki/ARM_Cortex-M
- //
- // Cortex-M0 through Cortex-M7 are ARM processor cores which can only
- // execute thumb instructions. We map the cores to arch names like this:
- //
- // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m
- // Cortex-M3: armv7m
- // Cortex-M4, Cortex-M7: armv7em
-
- if (GetCore() == ArchSpec::Core::eCore_arm_armv7m
- || GetCore() == ArchSpec::Core::eCore_arm_armv7em
- || GetCore() == ArchSpec::Core::eCore_arm_armv6m)
- {
- return true;
- }
- }
- return false;
+void ArchSpec::PiecewiseTripleCompare(
+ const ArchSpec &other, bool &arch_different, bool &vendor_different,
+ bool &os_different, bool &os_version_different, bool &env_different) {
+ const llvm::Triple &me(GetTriple());
+ const llvm::Triple &them(other.GetTriple());
+
+ arch_different = (me.getArch() != them.getArch());
+
+ vendor_different = (me.getVendor() != them.getVendor());
+
+ os_different = (me.getOS() != them.getOS());
+
+ os_version_different = (me.getOSMajorVersion() != them.getOSMajorVersion());
+
+ env_different = (me.getEnvironment() != them.getEnvironment());
}
-void
-ArchSpec::DumpTriple(Stream &s) const
-{
- const llvm::Triple &triple = GetTriple();
- llvm::StringRef arch_str = triple.getArchName();
- llvm::StringRef vendor_str = triple.getVendorName();
- llvm::StringRef os_str = triple.getOSName();
- 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()
- );
+bool ArchSpec::IsAlwaysThumbInstructions() const {
+ std::string Error;
+ if (GetTriple().getArch() == llvm::Triple::arm ||
+ GetTriple().getArch() == llvm::Triple::thumb) {
+ // v. https://en.wikipedia.org/wiki/ARM_Cortex-M
+ //
+ // Cortex-M0 through Cortex-M7 are ARM processor cores which can only
+ // execute thumb instructions. We map the cores to arch names like this:
+ //
+ // Cortex-M0, Cortex-M0+, Cortex-M1: armv6m
+ // Cortex-M3: armv7m
+ // Cortex-M4, Cortex-M7: armv7em
+
+ if (GetCore() == ArchSpec::Core::eCore_arm_armv7m ||
+ GetCore() == ArchSpec::Core::eCore_arm_armv7em ||
+ GetCore() == ArchSpec::Core::eCore_arm_armv6m) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void ArchSpec::DumpTriple(Stream &s) const {
+ const llvm::Triple &triple = GetTriple();
+ llvm::StringRef arch_str = triple.getArchName();
+ llvm::StringRef vendor_str = triple.getVendorName();
+ llvm::StringRef os_str = triple.getOSName();
+ llvm::StringRef environ_str = triple.getEnvironmentName();
+
+ s.Printf("%s-%s-%s", arch_str.empty() ? "*" : arch_str.str().c_str(),
+ vendor_str.empty() ? "*" : vendor_str.str().c_str(),
+ os_str.empty() ? "*" : os_str.str().c_str());
- if (!environ_str.empty())
- s.Printf("-%s", environ_str.str().c_str());
+ if (!environ_str.empty())
+ s.Printf("-%s", environ_str.str().c_str());
}
Modified: lldb/trunk/source/Core/Baton.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Baton.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/Baton.cpp (original)
+++ lldb/trunk/source/Core/Baton.cpp Tue Sep 6 15:57:50 2016
@@ -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 {}
Modified: lldb/trunk/source/Core/Broadcaster.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Broadcaster.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/Broadcaster.cpp (original)
+++ lldb/trunk/source/Core/Broadcaster.cpp Tue Sep 6 15:57:50 2016
@@ -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();
-}
-
-void
-Broadcaster::CheckInWithManager ()
-{
- if (m_manager_sp)
- {
- m_manager_sp->SignUpListenersForBroadcaster(*this);
- }
+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);
+ }
}
llvm::SmallVector<std::pair<ListenerSP, uint32_t &>, 4>
-Broadcaster::BroadcasterImpl::GetListeners()
-{
- llvm::SmallVector<std::pair<ListenerSP, uint32_t &>, 4> listeners;
- listeners.reserve(m_listeners.size());
-
- for (auto it = m_listeners.begin(); it != m_listeners.end();)
- {
- lldb::ListenerSP curr_listener_sp(it->first.lock());
- if (curr_listener_sp && it->second)
- {
- listeners.emplace_back(std::move(curr_listener_sp), it->second);
- ++it;
+Broadcaster::BroadcasterImpl::GetListeners() {
+ llvm::SmallVector<std::pair<ListenerSP, uint32_t &>, 4> listeners;
+ listeners.reserve(m_listeners.size());
+
+ for (auto it = m_listeners.begin(); it != m_listeners.end();) {
+ lldb::ListenerSP curr_listener_sp(it->first.lock());
+ if (curr_listener_sp && it->second) {
+ listeners.emplace_back(std::move(curr_listener_sp), it->second);
+ ++it;
+ } else
+ it = m_listeners.erase(it);
+ }
+
+ return listeners;
+}
+
+void Broadcaster::BroadcasterImpl::Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ // Make sure the listener forgets about this broadcaster. We do
+ // this in the broadcaster in case the broadcaster object initiates
+ // the removal.
+ 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;
- }
- }
- }
+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;
+
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ // See if we already have this listener, and if so, update its mask
+
+ 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;
}
- return num_names_added > 0;
-}
+ }
-void
-Broadcaster::AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events)
-{
+ 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);
+ }
+
+ // Return the event bits that were granted to the listener
+ return event_mask;
}
-uint32_t
-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);
-
- // See if we already have this listener, and if so, update its mask
-
- 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;
- }
- }
+bool Broadcaster::BroadcasterImpl::EventTypeHasListeners(uint32_t event_type) {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- 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);
- }
+ if (!m_hijacking_listeners.empty() && event_type & m_hijacking_masks.back())
+ return true;
- // Return the event bits that were granted to the listener
- return event_mask;
+ for (auto &pair : GetListeners()) {
+ if (pair.second & event_type)
+ return true;
+ }
+ return false;
}
-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;
- }
+bool Broadcaster::BroadcasterImpl::RemoveListener(
+ lldb_private::Listener *listener, uint32_t event_mask) {
+ if (!listener)
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;
- }
+ 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;
+ }
+ return false;
}
-bool
-Broadcaster::BroadcasterImpl::RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask)
-{
- return RemoveListener (listener_sp.get(), event_mask);
+bool Broadcaster::BroadcasterImpl::RemoveListener(
+ const lldb::ListenerSP &listener_sp, uint32_t event_mask) {
+ return RemoveListener(listener_sp.get(), event_mask);
}
-void
-Broadcaster::BroadcasterImpl::BroadcastEvent (EventSP &event_sp)
-{
- return PrivateBroadcastEvent (event_sp, false);
+void Broadcaster::BroadcasterImpl::BroadcastEvent(EventSP &event_sp) {
+ return PrivateBroadcastEvent(event_sp, false);
}
-void
-Broadcaster::BroadcasterImpl::BroadcastEventIfUnique (EventSP &event_sp)
-{
- return PrivateBroadcastEvent (event_sp, true);
+void Broadcaster::BroadcasterImpl::BroadcastEventIfUnique(EventSP &event_sp) {
+ return PrivateBroadcastEvent(event_sp, true);
}
-void
-Broadcaster::BroadcasterImpl::PrivateBroadcastEvent (EventSP &event_sp, bool unique)
-{
- // Can't add a nullptr event...
- if (!event_sp)
- return;
+void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp,
+ bool unique) {
+ // Can't add a nullptr event...
+ if (!event_sp)
+ return;
- // Update the broadcaster on this event
- event_sp->SetBroadcaster (&m_broadcaster);
+ // Update the broadcaster on this event
+ event_sp->SetBroadcaster(&m_broadcaster);
- const uint32_t event_type = event_sp->GetType();
+ const uint32_t event_type = event_sp->GetType();
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
- ListenerSP hijacking_listener_sp;
+ ListenerSP hijacking_listener_sp;
- if (!m_hijacking_listeners.empty())
- {
- assert (!m_hijacking_masks.empty());
- hijacking_listener_sp = m_hijacking_listeners.back();
- if ((event_type & m_hijacking_masks.back()) == 0)
- hijacking_listener_sp.reset();
- }
+ if (!m_hijacking_listeners.empty()) {
+ assert(!m_hijacking_masks.empty());
+ hijacking_listener_sp = m_hijacking_listeners.back();
+ if ((event_type & m_hijacking_masks.back()) == 0)
+ hijacking_listener_sp.reset();
+ }
- Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EVENTS));
- if (log)
- {
- StreamString event_description;
- event_sp->Dump (&event_description);
- log->Printf ("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, unique =%i) hijack = %p",
- static_cast<void*>(this), GetBroadcasterName(),
- event_description.GetData(), unique,
- static_cast<void*>(hijacking_listener_sp.get()));
- }
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log) {
+ StreamString event_description;
+ event_sp->Dump(&event_description);
+ log->Printf("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, "
+ "unique =%i) hijack = %p",
+ static_cast<void *>(this), GetBroadcasterName(),
+ event_description.GetData(), unique,
+ static_cast<void *>(hijacking_listener_sp.get()));
+ }
- if (hijacking_listener_sp)
- {
- if (unique && hijacking_listener_sp->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type))
- return;
- hijacking_listener_sp->AddEvent (event_sp);
- }
- else
- {
- for (auto &pair : GetListeners())
- {
- if (!(pair.second & event_type))
- continue;
- if (unique && pair.first->PeekAtNextEventForBroadcasterWithType (&m_broadcaster, event_type))
- continue;
+ 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);
- }
+ 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;
+void Broadcaster::BroadcasterImpl::BroadcastEvent(uint32_t event_type,
+ EventData *event_data) {
+ EventSP event_sp(new Event(event_type, event_data));
+ PrivateBroadcastEvent(event_sp, false);
}
-bool
-Broadcaster::BroadcasterImpl::IsHijackedForEvent (uint32_t event_mask)
-{
- std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+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);
+}
- if (!m_hijacking_listeners.empty())
- return (event_mask & m_hijacking_masks.back()) != 0;
- return 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);
}
-const char *
-Broadcaster::BroadcasterImpl::GetHijackingListenerName()
-{
- if (m_hijacking_listeners.size())
- {
- return m_hijacking_listeners.back()->GetName();
- }
- else
- {
- return nullptr;
- }
+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;
}
-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();
+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;
}
-ConstString &
-Broadcaster::GetBroadcasterClass() const
-{
- static ConstString class_name ("lldb.anonymous");
- return class_name;
+const char *Broadcaster::BroadcasterImpl::GetHijackingListenerName() {
+ if (m_hijacking_listeners.size()) {
+ return m_hijacking_listeners.back()->GetName();
+ } else {
+ return nullptr;
+ }
}
-BroadcastEventSpec::BroadcastEventSpec(const BroadcastEventSpec &rhs) = default;
+void Broadcaster::BroadcasterImpl::RestoreBroadcaster() {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
-bool
-BroadcastEventSpec::operator< (const BroadcastEventSpec &rhs) const
-{
- if (GetBroadcasterClass() == rhs.GetBroadcasterClass())
- {
- return GetEventBits() < rhs.GetEventBits();
- }
- else
- {
- return GetBroadcasterClass() < rhs.GetBroadcasterClass();
+ 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();
}
-BroadcastEventSpec &
-BroadcastEventSpec::operator=(const BroadcastEventSpec &rhs) = default;
-
-BroadcasterManager::BroadcasterManager() : m_manager_mutex()
-{
+ConstString &Broadcaster::GetBroadcasterClass() const {
+ static ConstString class_name("lldb.anonymous");
+ return class_name;
}
-lldb::BroadcasterManagerSP
-BroadcasterManager::MakeBroadcasterManager()
-{
- return BroadcasterManagerSP(new BroadcasterManager());
+BroadcastEventSpec::BroadcastEventSpec(const BroadcastEventSpec &rhs) = default;
+
+bool BroadcastEventSpec::operator<(const BroadcastEventSpec &rhs) const {
+ if (GetBroadcasterClass() == rhs.GetBroadcasterClass()) {
+ return GetEventBits() < rhs.GetEventBits();
+ } else {
+ return GetBroadcasterClass() < rhs.GetBroadcasterClass();
+ }
}
-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;
+BroadcastEventSpec &BroadcastEventSpec::
+operator=(const BroadcastEventSpec &rhs) = default;
+
+BroadcasterManager::BroadcasterManager() : m_manager_mutex() {}
+
+lldb::BroadcasterManagerSP BroadcasterManager::MakeBroadcasterManager() {
+ return BroadcasterManagerSP(new BroadcasterManager());
}
-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;
+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;
}
-
-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;
+
+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 nullptr;
+ m_event_map.erase(iter);
+ }
}
-void
-BroadcasterManager::RemoveListener(Listener *listener)
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
- ListenerMatchesPointer predicate (listener);
- listener_collection::iterator iter = m_listeners.begin(), end_iter = m_listeners.end();
-
- std::find_if (iter, end_iter, predicate);
- if (iter != end_iter)
- m_listeners.erase(iter);
-
- while (true)
- {
- collection::iterator iter, end_iter = m_event_map.end();
- iter = find_if (m_event_map.begin(), end_iter, predicate);
- if (iter == end_iter)
- break;
- else
- m_event_map.erase(iter);
- }
-}
-
-void
-BroadcasterManager::RemoveListener (const lldb::ListenerSP &listener_sp)
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
- ListenerMatches predicate (listener_sp);
-
- 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::RemoveListener(const lldb::ListenerSP &listener_sp) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ ListenerMatches predicate(listener_sp);
+
+ if (m_listeners.erase(listener_sp) == 0)
+ return;
+
+ while (true) {
+ collection::iterator iter, end_iter = m_event_map.end();
+ iter = find_if(m_event_map.begin(), end_iter, predicate);
+ if (iter == end_iter)
+ break;
+ else
+ m_event_map.erase(iter);
+ }
}
-void
-BroadcasterManager::Clear ()
-{
- std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
- listener_collection::iterator end_iter = m_listeners.end();
-
- for (listener_collection::iterator iter = m_listeners.begin(); iter != end_iter; iter++)
- (*iter)->BroadcasterManagerWillDestruct(this->shared_from_this());
- m_listeners.clear();
- m_event_map.clear();
+void BroadcasterManager::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();
}
Modified: lldb/trunk/source/Core/Communication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Communication.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/Communication.cpp (original)
+++ lldb/trunk/source/Core/Communication.cpp Tue Sep 6 15:57:50 2016
@@ -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)
-
-{
- lldb_private::LogIfAnyCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::Communication (name = %s)", this, name);
-
- SetEventName(eBroadcastBitDisconnected, "disconnected");
- SetEventName(eBroadcastBitReadThreadGotBytes, "got bytes");
- SetEventName(eBroadcastBitReadThreadDidExit, "read thread did exit");
- SetEventName(eBroadcastBitReadThreadShouldExit, "read thread should exit");
- SetEventName(eBroadcastBitPacketAvailable, "packet available");
- SetEventName(eBroadcastBitNoMorePendingInput, "no more pending input");
-
- CheckInWithManager();
-}
-
-Communication::~Communication()
-{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::~Communication (name = %s)",
- this, GetBroadcasterName().AsCString());
- Clear();
-}
-
-void
-Communication::Clear()
-{
- SetReadThreadBytesReceivedCallback(nullptr, nullptr);
- Disconnect(nullptr);
- StopReadThread(nullptr);
-}
-
-ConnectionStatus
-Communication::Connect (const char *url, Error *error_ptr)
-{
- Clear();
-
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION, "%p Communication::Connect (url = %s)", this, url);
-
- lldb::ConnectionSP connection_sp (m_connection_sp);
- if (connection_sp)
- return connection_sp->Connect (url, error_ptr);
- if (error_ptr)
- error_ptr->SetErrorString("Invalid connection.");
- return eConnectionStatusNoConnection;
-}
-
-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;
+ : Broadcaster(nullptr, name), m_connection_sp(),
+ m_read_thread_enabled(false), m_read_thread_did_exit(false), m_bytes(),
+ m_bytes_mutex(), m_write_mutex(), m_synchronize_mutex(),
+ m_callback(nullptr), m_callback_baton(nullptr), m_close_on_eof(true)
+
+{
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::Communication (name = %s)", this, name);
+
+ SetEventName(eBroadcastBitDisconnected, "disconnected");
+ SetEventName(eBroadcastBitReadThreadGotBytes, "got bytes");
+ SetEventName(eBroadcastBitReadThreadDidExit, "read thread did exit");
+ SetEventName(eBroadcastBitReadThreadShouldExit, "read thread should exit");
+ SetEventName(eBroadcastBitPacketAvailable, "packet available");
+ SetEventName(eBroadcastBitNoMorePendingInput, "no more pending input");
+
+ CheckInWithManager();
+}
+
+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);
+}
+
+ConnectionStatus Communication::Connect(const char *url, Error *error_ptr) {
+ Clear();
+
+ lldb_private::LogIfAnyCategoriesSet(LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::Connect (url = %s)",
+ this, url);
+
+ lldb::ConnectionSP connection_sp(m_connection_sp);
+ if (connection_sp)
+ return connection_sp->Connect(url, error_ptr);
+ if (error_ptr)
+ error_ptr->SetErrorString("Invalid connection.");
+ return eConnectionStatusNoConnection;
+}
+
+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;
}
- 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;
+ if (!m_connection_sp) {
+ if (error_ptr)
+ error_ptr->SetErrorString("Invalid connection.");
+ 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);
+ 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;
+ }
}
-
- 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;
+ // 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;
+bool Communication::StopReadThread(Error *error_ptr) {
+ if (!m_read_thread.IsJoinable())
+ return true;
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::StopReadThread ()", this);
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_COMMUNICATION, "%p Communication::StopReadThread ()", this);
- m_read_thread_enabled = false;
+ m_read_thread_enabled = false;
- BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr);
+ BroadcastEvent(eBroadcastBitReadThreadShouldExit, nullptr);
- // error = m_read_thread.Cancel();
+ // error = m_read_thread.Cancel();
- Error error = m_read_thread.Join(nullptr);
- return error.Success();
+ Error error = m_read_thread.Join(nullptr);
+ return error.Success();
}
-bool
-Communication::JoinReadThread (Error *error_ptr)
-{
- if (!m_read_thread.IsJoinable())
- return true;
+bool Communication::JoinReadThread(Error *error_ptr) {
+ if (!m_read_thread.IsJoinable())
+ return true;
- Error error = m_read_thread.Join(nullptr);
- return error.Success();
+ Error error = m_read_thread.Join(nullptr);
+ return error.Success();
}
-size_t
-Communication::GetCachedBytes (void *dst, size_t dst_len)
-{
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
- if (!m_bytes.empty())
- {
- // If DST is nullptr and we have a thread, then return the number
- // of bytes that are available so the caller can call again
- if (dst == nullptr)
- return m_bytes.size();
+size_t Communication::GetCachedBytes(void *dst, size_t dst_len) {
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+ if (!m_bytes.empty()) {
+ // If DST is nullptr and we have a thread, then return the number
+ // of bytes that are available so the caller can call again
+ if (dst == nullptr)
+ return m_bytes.size();
- const size_t len = std::min<size_t>(dst_len, m_bytes.size());
+ const size_t len = std::min<size_t>(dst_len, m_bytes.size());
- ::memcpy (dst, m_bytes.c_str(), len);
- m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len);
+ ::memcpy(dst, m_bytes.c_str(), len);
+ m_bytes.erase(m_bytes.begin(), m_bytes.begin() + len);
- return len;
- }
- return 0;
+ return len;
+ }
+ return 0;
}
-void
-Communication::AppendBytesToCache (const uint8_t * bytes, size_t len, bool broadcast, ConnectionStatus status)
-{
- lldb_private::LogIfAnyCategoriesSet (LIBLLDB_LOG_COMMUNICATION,
- "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64 ", broadcast = %i)",
- this, bytes, (uint64_t)len, broadcast);
- if ((bytes == nullptr || len == 0)
- && (status != lldb::eConnectionStatusEndOfFile))
- return;
- if (m_callback)
- {
- // If the user registered a callback, then call it and do not broadcast
- m_callback (m_callback_baton, bytes, len);
- }
- else if (bytes != nullptr && len > 0)
- {
- std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
- m_bytes.append ((const char *)bytes, len);
- if (broadcast)
- BroadcastEventIfUnique (eBroadcastBitReadThreadGotBytes);
+void Communication::AppendBytesToCache(const uint8_t *bytes, size_t len,
+ bool broadcast,
+ ConnectionStatus status) {
+ lldb_private::LogIfAnyCategoriesSet(
+ LIBLLDB_LOG_COMMUNICATION,
+ "%p Communication::AppendBytesToCache (src = %p, src_len = %" PRIu64
+ ", broadcast = %i)",
+ this, bytes, (uint64_t)len, broadcast);
+ if ((bytes == nullptr || len == 0) &&
+ (status != lldb::eConnectionStatusEndOfFile))
+ return;
+ if (m_callback) {
+ // If the user registered a callback, then call it and do not broadcast
+ m_callback(m_callback_baton, bytes, len);
+ } else if (bytes != nullptr && len > 0) {
+ std::lock_guard<std::recursive_mutex> guard(m_bytes_mutex);
+ m_bytes.append((const char *)bytes, len);
+ if (broadcast)
+ BroadcastEventIfUnique(eBroadcastBitReadThreadGotBytes);
+ }
+}
+
+size_t Communication::ReadFromConnection(void *dst, size_t dst_len,
+ uint32_t timeout_usec,
+ ConnectionStatus &status,
+ Error *error_ptr) {
+ lldb::ConnectionSP connection_sp(m_connection_sp);
+ return (
+ connection_sp
+ ? connection_sp->Read(dst, dst_len, timeout_usec, status, error_ptr)
+ : 0);
+}
+
+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);
}
-}
-
-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;
- }
+ 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;
+ }
+ log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION);
+ if (log)
+ log->Printf("%p Communication::ReadThread () thread exiting...", p);
+
+ comm->m_read_thread_did_exit = true;
+ // Let clients know that this thread is exiting
+ comm->BroadcastEvent(eBroadcastBitNoMorePendingInput);
+ comm->BroadcastEvent(eBroadcastBitReadThreadDidExit);
+ return NULL;
}
-void
-Communication::SetReadThreadBytesReceivedCallback(ReadThreadBytesReceived callback,
- void *callback_baton)
-{
- m_callback = callback;
- m_callback_baton = callback_baton;
+void Communication::SetReadThreadBytesReceivedCallback(
+ ReadThreadBytesReceived callback, void *callback_baton) {
+ m_callback = callback;
+ m_callback_baton = callback_baton;
}
-void
-Communication::SynchronizeWithReadThread ()
-{
- // Only one thread can do the synchronization dance at a time.
- std::lock_guard<std::mutex> guard(m_synchronize_mutex);
+void Communication::SynchronizeWithReadThread() {
+ // Only one thread can do the synchronization dance at a time.
+ std::lock_guard<std::mutex> guard(m_synchronize_mutex);
- // First start listening for the synchronization event.
- ListenerSP listener_sp(Listener::MakeListener("Communication::SyncronizeWithReadThread"));
- listener_sp->StartListeningForEvents(this, eBroadcastBitNoMorePendingInput);
+ // First start listening for the synchronization event.
+ ListenerSP listener_sp(
+ Listener::MakeListener("Communication::SyncronizeWithReadThread"));
+ listener_sp->StartListeningForEvents(this, eBroadcastBitNoMorePendingInput);
- // If the thread is not running, there is no point in synchronizing.
- if (!m_read_thread_enabled || m_read_thread_did_exit)
- return;
+ // If the thread is not running, there is no point in synchronizing.
+ if (!m_read_thread_enabled || m_read_thread_did_exit)
+ return;
- // Notify the read thread.
- m_connection_sp->InterruptRead();
+ // Notify the read thread.
+ m_connection_sp->InterruptRead();
- // Wait for the synchronization event.
- EventSP event_sp;
- listener_sp->WaitForEvent(std::chrono::microseconds(0), event_sp);
+ // 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);
+void Communication::SetConnection(Connection *connection) {
+ Disconnect(nullptr);
+ StopReadThread(nullptr);
+ m_connection_sp.reset(connection);
}
const char *
-Communication::ConnectionStatusAsCString (lldb::ConnectionStatus status)
-{
- switch (status)
- {
- case eConnectionStatusSuccess: return "success";
- case eConnectionStatusError: return "error";
- case eConnectionStatusTimedOut: return "timed out";
- case eConnectionStatusNoConnection: return "no connection";
- case eConnectionStatusLostConnection: return "lost connection";
- case eConnectionStatusEndOfFile: return "end of file";
- case eConnectionStatusInterrupted: return "interrupted";
- }
-
- static char unknown_state_string[64];
- snprintf(unknown_state_string, sizeof (unknown_state_string), "ConnectionStatus = %i", status);
- return unknown_state_string;
+Communication::ConnectionStatusAsCString(lldb::ConnectionStatus status) {
+ switch (status) {
+ case eConnectionStatusSuccess:
+ return "success";
+ case eConnectionStatusError:
+ return "error";
+ case eConnectionStatusTimedOut:
+ return "timed out";
+ case eConnectionStatusNoConnection:
+ return "no connection";
+ case eConnectionStatusLostConnection:
+ return "lost connection";
+ case eConnectionStatusEndOfFile:
+ return "end of file";
+ case eConnectionStatusInterrupted:
+ return "interrupted";
+ }
+
+ static char unknown_state_string[64];
+ snprintf(unknown_state_string, sizeof(unknown_state_string),
+ "ConnectionStatus = %i", status);
+ return unknown_state_string;
}
Modified: lldb/trunk/source/Core/Connection.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Connection.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/Connection.cpp (original)
+++ lldb/trunk/source/Core/Connection.cpp Tue Sep 6 15:57:50 2016
@@ -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();
}
Modified: lldb/trunk/source/Core/ConnectionMachPort.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionMachPort.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionMachPort.cpp (original)
+++ lldb/trunk/source/Core/ConnectionMachPort.cpp Tue Sep 6 15:57:50 2016
@@ -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;
+ }
-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");
- }
+ 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 (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;
}
- else
- {
- if (error_ptr)
- error_ptr->SetErrorStringWithFormat ("unsupported connection URL: '%s'", s);
+ }
+
+ 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;
+ }
- if (status == eConnectionStatusSuccess)
- {
- if (error_ptr)
- error_ptr->Clear();
- m_uri.assign(s);
- }
- else
- {
- Disconnect(NULL);
- }
-
- return status;
+ return eConnectionStatusSuccess;
}
-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::Disconnect(Error *error_ptr) {
+ kern_return_t kret;
-lldb::ConnectionStatus
-ConnectionMachPort::BootstrapLookup (const char *port,
- Error *error_ptr)
-{
- name_t port_name;
+ // 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();
- 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;
- }
+ return eConnectionStatusSuccess;
+}
- 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);
- }
+size_t ConnectionMachPort::Read(void *dst, size_t dst_len,
+ uint32_t timeout_usec, ConnectionStatus &status,
+ Error *error_ptr) {
+ PayloadType payload;
- if (kret != KERN_SUCCESS)
- {
- if (error_ptr)
- error_ptr->SetError (kret, eErrorTypeMachKernel);
- return eConnectionStatusError;
- }
+ kern_return_t kret = Receive(payload);
+ if (kret == KERN_SUCCESS) {
+ memcpy(dst, payload.data, payload.data_length);
+ status = eConnectionStatusSuccess;
+ return payload.data_length;
+ }
- return eConnectionStatusSuccess;
+ if (error_ptr)
+ error_ptr->SetError(kret, eErrorTypeMachKernel);
+ status = eConnectionStatusError;
+ return 0;
}
-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();
+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);
- return eConnectionStatusSuccess;
+ if (Send(payload) == KERN_SUCCESS) {
+ status = eConnectionStatusSuccess;
+ return payload.data_length;
+ }
+ status = eConnectionStatusError;
+ return 0;
}
-size_t
-ConnectionMachPort::Read (void *dst,
- size_t dst_len,
- uint32_t timeout_usec,
- ConnectionStatus &status,
- Error *error_ptr)
-{
- PayloadType payload;
-
- kern_return_t kret = Receive (payload);
- if (kret == KERN_SUCCESS)
- {
- memcpy (dst, payload.data, payload.data_length);
- status = eConnectionStatusSuccess;
- return payload.data_length;
- }
-
- if (error_ptr)
- error_ptr->SetError (kret, eErrorTypeMachKernel);
- status = eConnectionStatusError;
- return 0;
-}
+std::string ConnectionMachPort::GetURI() { return m_uri; }
-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;
+ConnectionStatus ConnectionMachPort::BytesAvailable(uint32_t timeout_usec,
+ Error *error_ptr) {
+ return eConnectionStatusLostConnection;
}
-std::string
-ConnectionMachPort::GetURI()
-{
- return m_uri;
-}
+kern_return_t ConnectionMachPort::Send(const PayloadType &payload) {
+ struct MessageType message;
-ConnectionStatus
-ConnectionMachPort::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
-{
- return eConnectionStatusLostConnection;
-}
+ /* (i) Form the message : */
-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;
-}
+ /* (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 */
-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;
+ /* (i.c) Fill the message with the given integer : */
+ message.payload = payload;
- return kret;
+ /* (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__)
Modified: lldb/trunk/source/Core/ConnectionSharedMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConnectionSharedMemory.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConnectionSharedMemory.cpp (original)
+++ lldb/trunk/source/Core/ConnectionSharedMemory.cpp Tue Sep 6 15:57:50 2016
@@ -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 ()
-{
- 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()
+ : Connection(), m_name(), m_fd(-1), m_mmap() {}
+
+ConnectionSharedMemory::~ConnectionSharedMemory() { Disconnect(nullptr); }
+
+bool ConnectionSharedMemory::IsConnected() const { return m_fd >= 0; }
-ConnectionStatus
-ConnectionSharedMemory::Disconnect (Error *error_ptr)
-{
- m_mmap.Clear();
- if (!m_name.empty())
- {
+ConnectionStatus ConnectionSharedMemory::Connect(const char *s,
+ Error *error_ptr) {
+ // if (s && s[0])
+ // {
+ // if (strstr(s, "shm-create://"))
+ // {
+ // }
+ // else if (strstr(s, "shm-connect://"))
+ // {
+ // }
+ // if (error_ptr)
+ // error_ptr->SetErrorStringWithFormat ("unsupported connection
+ // URL: '%s'", s);
+ // return eConnectionStatusError;
+ // }
+ if (error_ptr)
+ error_ptr->SetErrorString("invalid connect arguments");
+ return eConnectionStatusError;
+}
+
+ConnectionStatus ConnectionSharedMemory::Disconnect(Error *error_ptr) {
+ m_mmap.Clear();
+ if (!m_name.empty()) {
#ifdef _WIN32
- close(m_fd);
- m_fd = -1;
+ close(m_fd);
+ m_fd = -1;
#else
- shm_unlink (m_name.c_str());
+ shm_unlink(m_name.c_str());
#endif
- m_name.clear();
- }
- return eConnectionStatusSuccess;
+ m_name.clear();
+ }
+ return eConnectionStatusSuccess;
}
-size_t
-ConnectionSharedMemory::Read (void *dst,
- size_t dst_len,
- uint32_t timeout_usec,
- ConnectionStatus &status,
- Error *error_ptr)
-{
- status = eConnectionStatusSuccess;
- return 0;
-}
-
-size_t
-ConnectionSharedMemory::Write (const void *src, size_t src_len, ConnectionStatus &status, Error *error_ptr)
-{
- status = eConnectionStatusSuccess;
- return 0;
-}
-
-std::string
-ConnectionSharedMemory::GetURI()
-{
- // TODO: fix when Connect is fixed?
- return "";
-}
-
-ConnectionStatus
-ConnectionSharedMemory::BytesAvailable (uint32_t timeout_usec, Error *error_ptr)
-{
- return eConnectionStatusLostConnection;
-}
-
-ConnectionStatus
-ConnectionSharedMemory::Open (bool create, const char *name, size_t size, Error *error_ptr)
-{
- if (m_fd != -1)
- {
- if (error_ptr)
- error_ptr->SetErrorString("already open");
- return eConnectionStatusError;
- }
-
- m_name.assign (name);
+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());
- }
+ 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);
+ 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);
+ 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);
+ if (create)
+ ::ftruncate(m_fd, size);
#endif
- if (m_mmap.MemoryMapFromFileDescriptor(m_fd, 0, size, true, false) == size)
- return eConnectionStatusSuccess;
+ if (m_mmap.MemoryMapFromFileDescriptor(m_fd, 0, size, true, false) == size)
+ return eConnectionStatusSuccess;
- Disconnect(nullptr);
- return eConnectionStatusError;
+ Disconnect(nullptr);
+ return eConnectionStatusError;
}
#endif // __ANDROID_NDK__
Modified: lldb/trunk/source/Core/ConstString.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ConstString.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/ConstString.cpp (original)
+++ lldb/trunk/source/Core/ConstString.cpp Tue Sep 6 15:57:50 2016
@@ -15,8 +15,8 @@
#include <mutex>
// Other libraries and framework includes
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/Support/RWMutex.h"
// Project includes
@@ -24,180 +24,159 @@
using namespace lldb_private;
-class Pool
-{
+class Pool {
public:
- typedef const char * StringPoolValueType;
- typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator> StringPool;
- typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType;
-
- static StringPoolEntryType &
- GetStringMapEntryFromKeyData (const char *keyData)
- {
- char *ptr = const_cast<char*>(keyData) - sizeof (StringPoolEntryType);
- return *reinterpret_cast<StringPoolEntryType*>(ptr);
- }
-
- size_t
- GetConstCStringLength (const char *ccstr) const
- {
- if (ccstr != nullptr)
- {
- const uint8_t h = hash (llvm::StringRef(ccstr));
- llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
- const StringPoolEntryType& entry = GetStringMapEntryFromKeyData (ccstr);
- return entry.getKey().size();
- }
- return 0;
- }
-
- 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;
- }
-
- 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;
+ typedef const char *StringPoolValueType;
+ typedef llvm::StringMap<StringPoolValueType, llvm::BumpPtrAllocator>
+ StringPool;
+ typedef llvm::StringMapEntry<StringPoolValueType> StringPoolEntryType;
+
+ static StringPoolEntryType &
+ GetStringMapEntryFromKeyData(const char *keyData) {
+ char *ptr = const_cast<char *>(keyData) - sizeof(StringPoolEntryType);
+ return *reinterpret_cast<StringPoolEntryType *>(ptr);
+ }
+
+ size_t GetConstCStringLength(const char *ccstr) const {
+ if (ccstr != nullptr) {
+ const uint8_t h = hash(llvm::StringRef(ccstr));
+ llvm::sys::SmartScopedReader<false> rlock(m_string_pools[h].m_mutex);
+ const StringPoolEntryType &entry = GetStringMapEntryFromKeyData(ccstr);
+ return entry.getKey().size();
+ }
+ return 0;
+ }
+
+ 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;
+ }
- 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;
- }
+ const char *GetConstCString(const char *cstr) {
+ if (cstr != nullptr)
+ return GetConstCStringWithLength(cstr, strlen(cstr));
+ 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;
+ 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 *
+ 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;
+ }
protected:
- 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;
- };
+ 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;
+ };
- std::array<PoolEntry, 256> m_string_pools;
+ std::array<PoolEntry, 256> m_string_pools;
};
//----------------------------------------------------------------------
@@ -211,177 +190,147 @@ protected:
// global destructor chain is run, and trying to make sure no destructors
// touch ConstStrings is difficult. So we leak the pool instead.
//----------------------------------------------------------------------
-static Pool &
-StringPool()
-{
- static std::once_flag g_pool_initialization_flag;
- static Pool *g_string_pool = nullptr;
+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(); });
-ConstString::ConstString (const char *cstr) :
- m_string (StringPool().GetConstCString (cstr))
-{
+ return *g_string_pool;
}
-ConstString::ConstString (const char *cstr, size_t cstr_len) :
- m_string (StringPool().GetConstCStringWithLength (cstr, cstr_len))
-{
-}
+ConstString::ConstString(const char *cstr)
+ : m_string(StringPool().GetConstCString(cstr)) {}
-ConstString::ConstString (const llvm::StringRef &s) :
- m_string (StringPool().GetConstCStringWithLength (s.data(), s.size()))
-{
-}
+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;
+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));
+ 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;
+ // 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;
+ // Else one of them was nullptr, so if LHS is nullptr then it is less than
+ return lhs_string_ref.data() == nullptr;
}
-Stream&
-lldb_private::operator << (Stream& s, const ConstString& str)
-{
- const char *cstr = str.GetCString();
- if (cstr != nullptr)
- s << cstr;
+Stream &lldb_private::operator<<(Stream &s, const ConstString &str) {
+ const char *cstr = str.GetCString();
+ if (cstr != nullptr)
+ s << cstr;
- return s;
+ return s;
}
-size_t
-ConstString::GetLength () const
-{
- return StringPool().GetConstCStringLength (m_string);
-}
-
-bool
-ConstString::Equals(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive)
-{
- if (lhs.m_string == rhs.m_string)
- return true;
-
- // Since the pointers weren't equal, and identical ConstStrings always have identical pointers,
- // the result must be false for case sensitive equality test.
- if (case_sensitive)
- return false;
-
- // perform case insensitive equality test
- llvm::StringRef lhs_string_ref(lhs.m_string, StringPool().GetConstCStringLength(lhs.m_string));
- llvm::StringRef rhs_string_ref(rhs.m_string, StringPool().GetConstCStringLength(rhs.m_string));
- return lhs_string_ref.equals_lower(rhs_string_ref);
-}
-
-int
-ConstString::Compare(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive)
-{
- // If the iterators are the same, this is the same string
- const char *lhs_cstr = lhs.m_string;
- const char *rhs_cstr = rhs.m_string;
- if (lhs_cstr == rhs_cstr)
- return 0;
- if (lhs_cstr && rhs_cstr)
- {
- llvm::StringRef lhs_string_ref (lhs_cstr, StringPool().GetConstCStringLength (lhs_cstr));
- llvm::StringRef rhs_string_ref (rhs_cstr, StringPool().GetConstCStringLength (rhs_cstr));
-
- if (case_sensitive)
- {
- return lhs_string_ref.compare(rhs_string_ref);
- }
- else
- {
- return lhs_string_ref.compare_lower(rhs_string_ref);
- }
- }
+size_t ConstString::GetLength() const {
+ return StringPool().GetConstCStringLength(m_string);
+}
+
+bool ConstString::Equals(const ConstString &lhs, const ConstString &rhs,
+ const bool case_sensitive) {
+ if (lhs.m_string == rhs.m_string)
+ return true;
- if (lhs_cstr)
- return +1; // LHS isn't nullptr but RHS is
- else
- return -1; // LHS is nullptr but RHS isn't
+ // 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::Dump(Stream *s, const char *fail_value) const
-{
- if (s != nullptr)
- {
- const char *cstr = AsCString (fail_value);
- if (cstr != nullptr)
- s->PutCString (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::Dump(Stream *s, const char *fail_value) const {
+ if (s != nullptr) {
+ const char *cstr = AsCString(fail_value);
+ if (cstr != nullptr)
+ s->PutCString(cstr);
+ }
}
-void
-ConstString::DumpDebug(Stream *s) const
-{
- const char *cstr = GetCString ();
- size_t cstr_len = GetLength();
- // Only print the parens if we have a non-nullptr string
- const char *parens = cstr ? "\"" : "";
- s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64,
- static_cast<int>(sizeof(void*) * 2),
- static_cast<const void*>(this), parens, cstr, parens,
- static_cast<uint64_t>(cstr_len));
+void ConstString::DumpDebug(Stream *s) const {
+ const char *cstr = GetCString();
+ size_t cstr_len = GetLength();
+ // Only print the parens if we have a non-nullptr string
+ const char *parens = cstr ? "\"" : "";
+ s->Printf("%*p: ConstString, string = %s%s%s, length = %" PRIu64,
+ static_cast<int>(sizeof(void *) * 2),
+ static_cast<const void *>(this), parens, cstr, parens,
+ static_cast<uint64_t>(cstr_len));
}
-void
-ConstString::SetCString (const char *cstr)
-{
- m_string = StringPool().GetConstCString (cstr);
+void ConstString::SetCString(const char *cstr) {
+ m_string = StringPool().GetConstCString(cstr);
}
-void
-ConstString::SetString (const llvm::StringRef &s)
-{
- m_string = StringPool().GetConstCStringWithLength (s.data(), s.size());
+void ConstString::SetString(const llvm::StringRef &s) {
+ m_string = StringPool().GetConstCStringWithLength(s.data(), s.size());
}
-void
-ConstString::SetCStringWithMangledCounterpart (const char *demangled, const ConstString &mangled)
-{
- m_string = StringPool().GetConstCStringAndSetMangledCounterPart (demangled, mangled.m_string);
+void ConstString::SetCStringWithMangledCounterpart(const char *demangled,
+ const ConstString &mangled) {
+ m_string = StringPool().GetConstCStringAndSetMangledCounterPart(
+ demangled, mangled.m_string);
}
-bool
-ConstString::GetMangledCounterpart (ConstString &counterpart) const
-{
- counterpart.m_string = StringPool().GetMangledCounterpart(m_string);
- return (bool)counterpart;
+bool ConstString::GetMangledCounterpart(ConstString &counterpart) const {
+ counterpart.m_string = StringPool().GetMangledCounterpart(m_string);
+ return (bool)counterpart;
}
-void
-ConstString::SetCStringWithLength (const char *cstr, size_t cstr_len)
-{
- m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len);
+void ConstString::SetCStringWithLength(const char *cstr, size_t cstr_len) {
+ m_string = StringPool().GetConstCStringWithLength(cstr, cstr_len);
}
-void
-ConstString::SetTrimmedCStringWithLength (const char *cstr, size_t cstr_len)
-{
- m_string = StringPool().GetConstTrimmedCStringWithLength (cstr, cstr_len);
+void ConstString::SetTrimmedCStringWithLength(const char *cstr,
+ size_t cstr_len) {
+ m_string = StringPool().GetConstTrimmedCStringWithLength(cstr, cstr_len);
}
-size_t
-ConstString::StaticMemorySize()
-{
- // Get the size of the static string pool
- return StringPool().MemorySize();
+size_t ConstString::StaticMemorySize() {
+ // Get the size of the static string pool
+ return StringPool().MemorySize();
}
Modified: lldb/trunk/source/Core/CxaDemangle.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/CxaDemangle.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/CxaDemangle.cpp (original)
+++ lldb/trunk/source/Core/CxaDemangle.cpp Tue Sep 6 15:57:50 2016
@@ -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;
- }
- fprintf(stderr, "template_param:\n");
- for (auto& t : db.template_param)
- {
- fprintf(stderr, "--\n");
- i = -1;
- for (auto& v : t)
- {
- if (i >= 0)
- fprintf(stderr, "T%i_ = {", i);
- else
- fprintf(stderr, "T_ = {");
- for (auto& s : v)
- fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());
- fprintf(stderr, "}\n");
- ++i;
- }
- }
- fprintf(stderr, "---------\n\n");
+template <class C> void print_stack(const C &db) {
+ fprintf(stderr, "---------\n");
+ fprintf(stderr, "names:\n");
+ for (auto &s : db.names)
+ fprintf(stderr, "{%s#%s}\n", s.first.c_str(), s.second.c_str());
+ int i = -1;
+ fprintf(stderr, "subs:\n");
+ for (auto &v : db.subs) {
+ if (i >= 0)
+ fprintf(stderr, "S%i_ = {", i);
+ else
+ fprintf(stderr, "S_ = {");
+ for (auto &s : v)
+ fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());
+ fprintf(stderr, "}\n");
+ ++i;
+ }
+ fprintf(stderr, "template_param:\n");
+ for (auto &t : db.template_param) {
+ fprintf(stderr, "--\n");
+ i = -1;
+ for (auto &v : t) {
+ if (i >= 0)
+ fprintf(stderr, "T%i_ = {", i);
+ else
+ fprintf(stderr, "T_ = {");
+ for (auto &s : v)
+ fprintf(stderr, "{%s#%s}", s.first.c_str(), s.second.c_str());
+ fprintf(stderr, "}\n");
+ ++i;
+ }
+ }
+ fprintf(stderr, "---------\n\n");
}
template <class C>
-void
-print_state(const char* msg, const char* first, const char* last, const C& db)
-{
- fprintf(stderr, "%s: ", msg);
- for (; first != last; ++first)
- fprintf(stderr, "%c", *first);
- fprintf(stderr, "\n");
- print_stack(db);
+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')
- {
+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);
+ 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;
- }
+ 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;
+ }
+ 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 @@ parse_source_name(const char* first, con
// <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,1203 +343,1066 @@ parse_substitution(const char* first, co
// ::= 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;
+const char *parse_builtin_type(const char *first, const char *last, C &db) {
+ if (first != last) {
+ switch (*first) {
+ case 'v':
+ db.names.push_back("void");
+ ++first;
+ break;
+ case 'w':
+ db.names.push_back("wchar_t");
+ ++first;
+ break;
+ case 'b':
+ db.names.push_back("bool");
+ ++first;
+ break;
+ case 'c':
+ db.names.push_back("char");
+ ++first;
+ break;
+ case 'a':
+ db.names.push_back("signed char");
+ ++first;
+ break;
+ case 'h':
+ db.names.push_back("unsigned char");
+ ++first;
+ break;
+ case 's':
+ db.names.push_back("short");
+ ++first;
+ break;
+ case 't':
+ db.names.push_back("unsigned short");
+ ++first;
+ break;
+ case 'i':
+ db.names.push_back("int");
+ ++first;
+ break;
+ case 'j':
+ db.names.push_back("unsigned int");
+ ++first;
+ break;
+ case 'l':
+ db.names.push_back("long");
+ ++first;
+ break;
+ case 'm':
+ db.names.push_back("unsigned long");
+ ++first;
+ break;
+ case 'x':
+ db.names.push_back("long long");
+ ++first;
+ break;
+ case 'y':
+ db.names.push_back("unsigned long long");
+ ++first;
+ break;
+ case 'n':
+ db.names.push_back("__int128");
+ ++first;
+ break;
+ case 'o':
+ db.names.push_back("unsigned __int128");
+ ++first;
+ break;
+ case 'f':
+ db.names.push_back("float");
+ ++first;
+ break;
+ case 'd':
+ db.names.push_back("double");
+ ++first;
+ break;
+ case 'e':
+ db.names.push_back("long double");
+ ++first;
+ break;
+ case 'g':
+ db.names.push_back("__float128");
+ ++first;
+ break;
+ case 'z':
+ db.names.push_back("...");
+ ++first;
+ break;
+ case 'u': {
+ const char *t = parse_source_name(first + 1, last, db);
+ if (t != first + 1)
+ first = t;
+ } break;
+ case 'D':
+ if (first + 1 != last) {
+ switch (first[1]) {
+ case 'd':
+ db.names.push_back("decimal64");
+ first += 2;
+ break;
+ case 'e':
+ db.names.push_back("decimal128");
+ first += 2;
+ break;
+ case 'f':
+ db.names.push_back("decimal32");
+ first += 2;
+ break;
case 'h':
- db.names.push_back("unsigned char");
- ++first;
- break;
- case 's':
- db.names.push_back("short");
- ++first;
- break;
- case 't':
- db.names.push_back("unsigned short");
- ++first;
- break;
+ db.names.push_back("decimal16");
+ first += 2;
+ 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;
+ 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("__int128");
- ++first;
- break;
- case 'o':
- db.names.push_back("unsigned __int128");
- ++first;
- break;
- case 'f':
- db.names.push_back("float");
- ++first;
- break;
- case 'd':
- db.names.push_back("double");
- ++first;
- break;
- case 'e':
- db.names.push_back("long double");
- ++first;
- break;
- case 'g':
- db.names.push_back("__float128");
- ++first;
- break;
- case 'z':
- db.names.push_back("...");
- ++first;
- break;
- case 'u':
- {
- const char*t = parse_source_name(first+1, last, db);
- if (t != first+1)
- first = t;
- }
- break;
- case 'D':
- if (first+1 != last)
- {
- switch (first[1])
- {
- case 'd':
- db.names.push_back("decimal64");
- first += 2;
- break;
- case 'e':
- db.names.push_back("decimal128");
- first += 2;
- break;
- case 'f':
- db.names.push_back("decimal32");
- first += 2;
- break;
- case 'h':
- db.names.push_back("decimal16");
- first += 2;
- break;
- case 'i':
- db.names.push_back("char32_t");
- first += 2;
- break;
- case 's':
- db.names.push_back("char16_t");
- first += 2;
- break;
- case 'a':
- db.names.push_back("auto");
- first += 2;
- break;
- case 'c':
- db.names.push_back("decltype(auto)");
- first += 2;
- break;
- case 'n':
- db.names.push_back("std::nullptr_t");
- first += 2;
- break;
- }
- }
- break;
+ 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;
+ }
+ if (*first == 'V') {
+ cv |= 2;
+ ++first;
+ }
+ if (*first == 'K') {
+ cv |= 1;
+ ++first;
}
- return first;
+ }
+ return first;
}
// <template-param> ::= T_ # first template parameter
// ::= T <parameter-2 non-negative number> _
template <class C>
-const char*
-parse_template_param(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- if (*first == 'T')
- {
- if (first[1] == '_')
- {
- if (db.template_param.empty())
- return first;
- if (!db.template_param.back().empty())
- {
- for (auto& t : db.template_param.back().front())
- db.names.push_back(t);
- first += 2;
- }
- else
- {
- db.names.push_back("T_");
- first += 2;
- db.fix_forward_references = true;
- }
- }
- else if (isdigit(first[1]))
- {
- const char* t = first+1;
- size_t sub = static_cast<size_t>(*t - '0');
- for (++t; t != last && isdigit(*t); ++t)
- {
- sub *= 10;
- sub += static_cast<size_t>(*t - '0');
- }
- if (t == last || *t != '_' || db.template_param.empty())
- return first;
- ++sub;
- if (sub < db.template_param.back().size())
- {
- for (auto& temp : db.template_param.back()[sub])
- db.names.push_back(temp);
- first = t+1;
- }
- else
- {
- db.names.push_back(typename C::String(first, t+1));
- first = t+1;
- db.fix_forward_references = true;
- }
- }
- }
- }
- return first;
-}
-
-// cc <type> <expression> # const_cast<type> (expression)
-
-template <class C>
-const char*
-parse_const_cast_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'c' && first[1] == 'c')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 != t)
- {
- if (db.names.size() < 2)
- return first;
- auto expr = db.names.back().move_full();
- db.names.pop_back();
- db.names.back() = "const_cast<" + db.names.back().move_full() + ">(" + expr + ")";
- first = t1;
- }
- }
+const char *parse_template_param(const char *first, const char *last, C &db) {
+ if (last - first >= 2) {
+ if (*first == 'T') {
+ if (first[1] == '_') {
+ if (db.template_param.empty())
+ return first;
+ if (!db.template_param.back().empty()) {
+ for (auto &t : db.template_param.back().front())
+ db.names.push_back(t);
+ first += 2;
+ } else {
+ db.names.push_back("T_");
+ first += 2;
+ db.fix_forward_references = true;
+ }
+ } else if (isdigit(first[1])) {
+ const char *t = first + 1;
+ size_t sub = static_cast<size_t>(*t - '0');
+ for (++t; t != last && isdigit(*t); ++t) {
+ sub *= 10;
+ sub += static_cast<size_t>(*t - '0');
+ }
+ if (t == last || *t != '_' || db.template_param.empty())
+ return first;
+ ++sub;
+ if (sub < db.template_param.back().size()) {
+ for (auto &temp : db.template_param.back()[sub])
+ db.names.push_back(temp);
+ first = t + 1;
+ } else {
+ db.names.push_back(typename C::String(first, t + 1));
+ first = t + 1;
+ db.fix_forward_references = true;
+ }
+ }
+ }
+ }
+ return first;
+}
+
+// cc <type> <expression> # const_cast<type>
+// (expression)
+
+template <class C>
+const char *parse_const_cast_expr(const char *first, const char *last, C &db) {
+ if (last - first >= 3 && first[0] == 'c' && first[1] == 'c') {
+ const char *t = parse_type(first + 2, last, db);
+ if (t != first + 2) {
+ const char *t1 = parse_expression(t, last, db);
+ if (t1 != t) {
+ if (db.names.size() < 2)
+ return first;
+ auto expr = db.names.back().move_full();
+ db.names.pop_back();
+ db.names.back() =
+ "const_cast<" + db.names.back().move_full() + ">(" + expr + ")";
+ first = t1;
+ }
}
- return first;
+ }
+ 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;
+}
+
+// sZ <template-param> # size of a parameter
+// pack
+
+template <class C>
+const char *parse_sizeof_param_pack_expr(const char *first, const char *last,
+ C &db) {
+ if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' &&
+ first[2] == 'T') {
+ size_t k0 = db.names.size();
+ const char *t = parse_template_param(first + 2, last, db);
+ size_t k1 = db.names.size();
+ if (t != first + 2) {
+ typename C::String tmp("sizeof...(");
+ size_t k = k0;
+ if (k != k1) {
+ tmp += db.names[k].move_full();
+ for (++k; k != k1; ++k)
+ tmp += ", " + db.names[k].move_full();
+ }
+ tmp += ")";
+ for (; k1 != k0; --k1)
+ db.names.pop_back();
+ db.names.push_back(std::move(tmp));
+ first = t;
+ }
+ }
+ return first;
+}
+
+// <function-param> ::= fp <top-level CV-qualifiers> _ # L == 0, first parameter
+// ::= fp <top-level CV-qualifiers> <parameter-2 non-negative
+// number> _ # L == 0, second and later parameters
+// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers>
+// _ # L > 0, first parameter
+// ::= fL <L-1 non-negative number> p <top-level CV-qualifiers>
+// <parameter-2 non-negative number> _ # L > 0, second and
+// later parameters
+
+template <class C>
+const char *parse_function_param(const char *first, const char *last, C &db) {
+ if (last - first >= 3 && *first == 'f') {
+ if (first[1] == 'p') {
+ unsigned cv;
+ const char *t = parse_cv_qualifiers(first + 2, last, cv);
+ const char *t1 = parse_number(t, last);
+ if (t1 != last && *t1 == '_') {
+ db.names.push_back("fp" + typename C::String(t, t1));
+ first = t1 + 1;
+ }
+ } else if (first[1] == 'L') {
+ unsigned cv;
+ const char *t0 = parse_number(first + 2, last);
+ if (t0 != last && *t0 == 'p') {
+ ++t0;
+ const char *t = parse_cv_qualifiers(t0, last, cv);
+ const char *t1 = parse_number(t, last);
+ if (t1 != last && *t1 == '_') {
+ db.names.push_back("fp" + typename C::String(t, t1));
+ first = t1 + 1;
+ }
+ }
+ }
+ }
+ return first;
+}
+
+// sZ <function-param> # size of a function
+// parameter pack
+
+template <class C>
+const char *parse_sizeof_function_param_pack_expr(const char *first,
+ const char *last, C &db) {
+ if (last - first >= 3 && first[0] == 's' && first[1] == 'Z' &&
+ first[2] == 'f') {
+ const char *t = parse_function_param(first + 2, last, db);
+ if (t != first + 2) {
+ if (db.names.empty())
+ return first;
+ db.names.back() = "sizeof...(" + db.names.back().move_full() + ")";
+ first = t;
}
- return first;
+ }
+ return first;
}
-// sZ <template-param> # size of a parameter pack
+// te <expression> # typeid (expression)
+// ti <type> # typeid (type)
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_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;
}
-// <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
+// tw <expression> # throw expression
template <class C>
-const char*
-parse_function_param(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && *first == 'f')
- {
- if (first[1] == 'p')
- {
- unsigned cv;
- const char* t = parse_cv_qualifiers(first+2, last, cv);
- const char* t1 = parse_number(t, last);
- if (t1 != last && *t1 == '_')
- {
- db.names.push_back("fp" + typename C::String(t, t1));
- first = t1+1;
- }
- }
- else if (first[1] == 'L')
- {
- unsigned cv;
- const char* t0 = parse_number(first+2, last);
- if (t0 != last && *t0 == 'p')
- {
- ++t0;
- const char* t = parse_cv_qualifiers(t0, last, cv);
- const char* t1 = parse_number(t, last);
- if (t1 != last && *t1 == '_')
- {
- db.names.push_back("fp" + typename C::String(t, t1));
- first = t1+1;
- }
- }
- }
+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;
}
-// sZ <function-param> # size of a function parameter pack
+// ds <expression> <expression> # expr.*expr
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_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;
}
-// te <expression> # typeid (expression)
-// ti <type> # typeid (type)
+// <simple-id> ::= <source-name> [ <template-args> ]
template <class C>
-const char*
-parse_typeid_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 't' && (first[1] == 'e' || first[1] == 'i'))
- {
- const char* t;
- if (first[1] == 'e')
- t = parse_expression(first+2, last, db);
- else
- t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back() = "typeid(" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
+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;
}
-// tw <expression> # throw expression
+// <unresolved-type> ::= <template-param>
+// ::= <decltype>
+// ::= <substitution>
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)
- {
+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() = "throw " + db.names.back().move_full();
+ 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;
}
-// 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;
- }
+// <destructor-name> ::= <unresolved-type> # e.g.,
+// ~T or ~decltype(f())
+// ::= <simple-id> # e.g.,
+// ~A<2*N>
+
+template <class C>
+const char *parse_destructor_name(const char *first, const char *last, C &db) {
+ if (first != last) {
+ const char *t = parse_unresolved_type(first, last, db);
+ if (t == first)
+ t = parse_simple_id(first, last, db);
+ if (t != first) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first.insert(0, "~");
+ first = t;
+ }
+ }
+ return first;
+}
+
+// <base-unresolved-name> ::= <simple-id> #
+// unresolved name
+// extension ::= <operator-name> #
+// unresolved operator-function-id
+// extension ::= <operator-name> <template-args> #
+// unresolved operator template-id
+// ::= on <operator-name> #
+// unresolved operator-function-id
+// ::= on <operator-name> <template-args> #
+// unresolved operator template-id
+// ::= dn <destructor-name> #
+// destructor or pseudo-destructor;
+// #
+// e.g.
+// ~X or
+// ~X<N-1>
+
+template <class C>
+const char *parse_base_unresolved_name(const char *first, const char *last,
+ C &db) {
+ if (last - first >= 2) {
+ if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n') {
+ if (first[0] == 'o') {
+ const char *t = parse_operator_name(first + 2, last, db);
+ if (t != first + 2) {
+ first = parse_template_args(t, last, db);
+ if (first != t) {
+ if (db.names.size() < 2)
+ return first;
+ auto args = db.names.back().move_full();
+ db.names.pop_back();
+ db.names.back().first += std::move(args);
+ }
+ }
+ } else {
+ const char *t = parse_destructor_name(first + 2, last, db);
+ if (t != first + 2)
+ first = t;
+ }
+ } else {
+ const char *t = parse_simple_id(first, last, db);
+ if (t == first) {
+ t = parse_operator_name(first, last, db);
+ if (t != first) {
+ first = parse_template_args(t, last, db);
+ if (first != t) {
+ if (db.names.size() < 2)
+ return first;
+ auto args = db.names.back().move_full();
+ db.names.pop_back();
+ db.names.back().first += std::move(args);
+ }
}
+ } else
+ first = t;
}
- return first;
+ }
+ return first;
}
-// <simple-id> ::= <source-name> [ <template-args> ]
+// <unresolved-qualifier-level> ::= <simple-id>
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_unresolved_qualifier_level(const char *first,
+ const char *last, C &db) {
+ return parse_simple_id(first, last, db);
}
-// <unresolved-type> ::= <template-param>
-// ::= <decltype>
-// ::= <substitution>
-
-template <class C>
-const char*
-parse_unresolved_type(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- const char* t = first;
- switch (*first)
- {
- case 'T':
- {
- size_t k0 = db.names.size();
- t = parse_template_param(first, last, db);
- size_t k1 = db.names.size();
- if (t != first && k1 == k0 + 1)
- {
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- else
- {
- for (; k1 != k0; --k1)
- db.names.pop_back();
- }
- break;
+// <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;
}
- case 'D':
- t = parse_decltype(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- break;
- case 'S':
- t = parse_substitution(first, last, db);
- if (t != first)
- first = t;
- else
- {
- if (last - first > 2 && first[1] == 't')
- {
- t = parse_unqualified_name(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "std::");
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- first = t;
- }
- }
- }
- break;
- }
- }
- return first;
-}
-
-// <destructor-name> ::= <unresolved-type> # e.g., ~T or ~decltype(f())
-// ::= <simple-id> # e.g., ~A<2*N>
-
-template <class C>
-const char*
-parse_destructor_name(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- const char* t = parse_unresolved_type(first, last, db);
- if (t == first)
- t = parse_simple_id(first, last, db);
- if (t != first)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "~");
- first = t;
- }
- }
- return first;
-}
-
-// <base-unresolved-name> ::= <simple-id> # unresolved name
-// extension ::= <operator-name> # unresolved operator-function-id
-// extension ::= <operator-name> <template-args> # unresolved operator template-id
-// ::= on <operator-name> # unresolved operator-function-id
-// ::= on <operator-name> <template-args> # unresolved operator template-id
-// ::= dn <destructor-name> # destructor or pseudo-destructor;
-// # e.g. ~X or ~X<N-1>
-
-template <class C>
-const char*
-parse_base_unresolved_name(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- if ((first[0] == 'o' || first[0] == 'd') && first[1] == 'n')
- {
- if (first[0] == 'o')
- {
- const char* t = parse_operator_name(first+2, last, db);
- if (t != first+2)
- {
- first = parse_template_args(t, last, db);
- if (first != t)
- {
- if (db.names.size() < 2)
- return first;
- auto args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += std::move(args);
- }
- }
- }
- else
- {
- const char* t = parse_destructor_name(first+2, last, db);
- if (t != first+2)
- first = t;
- }
- }
- else
- {
- const char* t = parse_simple_id(first, last, db);
- if (t == first)
- {
- t = parse_operator_name(first, last, db);
- if (t != first)
- {
- first = parse_template_args(t, last, db);
- if (first != t)
- {
- if (db.names.size() < 2)
- return first;
- auto args = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += std::move(args);
- }
- }
- }
- else
- first = t;
- }
- }
- return first;
-}
-
-// <unresolved-qualifier-level> ::= <simple-id>
-
-template <class C>
-const char*
-parse_unresolved_qualifier_level(const char* first, const char* last, C& db)
-{
- return parse_simple_id(first, last, db);
-}
-
-// <unresolved-name>
-// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
-// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
-// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
-// # A::x, N::y, A<T>::z; "gs" means leading "::"
-// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
-// extension ::= sr <unresolved-type> <template-args> <base-unresolved-name>
-// # T::N::x /decltype(p)::N::x
-// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
-
-template <class C>
-const char*
-parse_unresolved_name(const char* first, const char* last, C& db)
-{
- if (last - first > 2)
- {
- const char* t = first;
- bool global = false;
- if (t[0] == 'g' && t[1] == 's')
- {
- global = true;
- t += 2;
}
- const char* t2 = parse_base_unresolved_name(t, last, db);
- if (t2 != t)
- {
- if (global)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "::");
- }
- first = t2;
+ 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;
}
- 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;
- }
- }
+ 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;
+ }
+ 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
-
-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;
+// [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;
+ }
}
- if (t[0] == 'n' && (t[1] == 'w' || t[1] == 'a'))
- {
- bool is_array = t[1] == 'a';
- t += 2;
- if (t == last)
+ 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;
- 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;
+ db.names.back().first.append(", ");
+ db.names.back().first.append(tmp);
+ first_expr = false;
}
- ++t;
- const char* t1 = parse_type(t, last, db);
+ }
+ t = t1;
+ }
+ }
+ if (*t != 'E')
+ return first;
+ typename C::String init_list;
+ if (has_init) {
+ if (db.names.empty())
+ return first;
+ init_list = db.names.back().move_full();
+ db.names.pop_back();
+ }
+ if (db.names.empty())
+ return first;
+ auto type = db.names.back().move_full();
+ db.names.pop_back();
+ typename C::String expr_list;
+ if (has_expr_list) {
+ if (db.names.empty())
+ return first;
+ expr_list = db.names.back().move_full();
+ db.names.pop_back();
+ }
+ typename C::String r;
+ if (parsed_gs)
+ r = "::";
+ if (is_array)
+ r += "[] ";
+ else
+ r += " ";
+ if (has_expr_list)
+ r += "(" + expr_list + ") ";
+ r += type;
+ if (has_init)
+ r += " (" + init_list + ")";
+ db.names.push_back(std::move(r));
+ first = t + 1;
+ }
+ }
+ return first;
+}
+
+// cv <type> <expression> # conversion with one
+// argument
+// cv <type> _ <expression>* E # conversion with a
+// different number of arguments
+
+template <class C>
+const char *parse_conversion_expr(const char *first, const char *last, C &db) {
+ if (last - first >= 3 && first[0] == 'c' && first[1] == 'v') {
+ bool try_to_parse_template_args = db.try_to_parse_template_args;
+ db.try_to_parse_template_args = false;
+ const char *t = parse_type(first + 2, last, db);
+ db.try_to_parse_template_args = try_to_parse_template_args;
+ if (t != first + 2 && t != last) {
+ if (*t != '_') {
+ const char *t1 = parse_expression(t, last, db);
+ if (t1 == t)
+ return first;
+ t = t1;
+ } else {
+ ++t;
+ if (t == last)
+ return first;
+ if (*t == 'E')
+ db.names.emplace_back();
+ else {
+ bool first_expr = true;
+ while (*t != 'E') {
+ const char *t1 = parse_expression(t, last, db);
if (t1 == t || t1 == last)
+ return first;
+ if (!first_expr) {
+ if (db.names.empty())
return first;
- 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)
- {
+ auto tmp = db.names.back().move_full();
+ db.names.pop_back();
+ if (!tmp.empty()) {
if (db.names.empty())
- return first;
- expr_list = db.names.back().move_full();
- db.names.pop_back();
- }
- typename C::String r;
- if (parsed_gs)
- r = "::";
- if (is_array)
- r += "[] ";
- else
- r += " ";
- if (has_expr_list)
- r += "(" + expr_list + ") ";
- r += type;
- if (has_init)
- r += " (" + init_list + ")";
- db.names.push_back(std::move(r));
- first = t+1;
- }
- }
- return first;
-}
-
-// cv <type> <expression> # conversion with one argument
-// cv <type> _ <expression>* E # conversion with a different number of arguments
-
-template <class C>
-const char*
-parse_conversion_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'c' && first[1] == 'v')
- {
- bool try_to_parse_template_args = db.try_to_parse_template_args;
- db.try_to_parse_template_args = false;
- const char* t = parse_type(first+2, last, db);
- db.try_to_parse_template_args = try_to_parse_template_args;
- if (t != first+2 && t != last)
- {
- if (*t != '_')
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 == t)
- return first;
- t = t1;
- }
- else
- {
- ++t;
- if (t == last)
- return first;
- if (*t == 'E')
- db.names.emplace_back();
- else
- {
- bool first_expr = true;
- while (*t != 'E')
- {
- const char* t1 = parse_expression(t, last, db);
- if (t1 == t || t1 == last)
- return first;
- if (!first_expr)
- {
- if (db.names.empty())
- return first;
- auto tmp = db.names.back().move_full();
- db.names.pop_back();
- if (!tmp.empty())
- {
- if (db.names.empty())
- return first;
- db.names.back().first.append(", ");
- db.names.back().first.append(tmp);
- first_expr = false;
- }
- }
- t = t1;
- }
- }
- ++t;
+ return first;
+ db.names.back().first.append(", ");
+ db.names.back().first.append(tmp);
+ first_expr = false;
+ }
}
- 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;
+ 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;
+ }
+ 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 @@ parse_arrow_expr(const char* first, cons
// <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;
- }
- }
- 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;
- }
- }
+const char *parse_array_type(const char *first, const char *last, C &db) {
+ if (first != last && *first == 'A' && first + 1 != last) {
+ if (first[1] == '_') {
+ const char *t = parse_type(first + 2, last, db);
+ if (t != first + 2) {
+ if (db.names.empty())
+ return first;
+ if (db.names.back().second.substr(0, 2) == " [")
+ db.names.back().second.erase(0, 1);
+ db.names.back().second.insert(0, " []");
+ first = t;
+ }
+ } else if ('1' <= first[1] && first[1] <= '9') {
+ const char *t = parse_number(first + 1, last);
+ if (t != last && *t == '_') {
+ const char *t2 = parse_type(t + 1, last, db);
+ if (t2 != t + 1) {
+ if (db.names.empty())
+ return first;
+ if (db.names.back().second.substr(0, 2) == " [")
+ db.names.back().second.erase(0, 1);
+ db.names.back().second.insert(
+ 0, " [" + typename C::String(first + 1, t) + "]");
+ first = t2;
+ }
+ }
+ } else {
+ const char *t = parse_expression(first + 1, last, db);
+ if (t != first + 1 && t != last && *t == '_') {
+ const char *t2 = parse_type(++t, last, db);
+ if (t2 != t) {
+ if (db.names.size() < 2)
+ return first;
+ auto type = std::move(db.names.back());
+ db.names.pop_back();
+ auto expr = std::move(db.names.back());
+ db.names.back().first = std::move(type.first);
+ if (type.second.substr(0, 2) == " [")
+ type.second.erase(0, 1);
+ db.names.back().second =
+ " [" + expr.move_full() + "]" + std::move(type.second);
+ first = t2;
}
+ }
}
- return first;
+ }
+ 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 @@ parse_decltype(const char* first, const
// ::= p # AltiVec vector pixel
template <class C>
-const char*
-parse_vector_type(const char* first, const char* last, C& db)
-{
- if (last - first > 3 && first[0] == 'D' && first[1] == 'v')
- {
- if ('1' <= first[2] && first[2] <= '9')
- {
- const char* t = parse_number(first+2, last);
- if (t == last || *t != '_')
- return first;
- const char* num = first + 2;
- size_t sz = static_cast<size_t>(t - num);
- if (++t != last)
- {
- if (*t != 'p')
- {
- const char* t1 = parse_type(t, last, db);
- if (t1 != t)
- {
- if (db.names.empty())
- return first;
- db.names.back().first += " vector[" + typename C::String(num, sz) + "]";
- first = t1;
- }
- }
- else
- {
- ++t;
- db.names.push_back("pixel vector[" + typename C::String(num, sz) + "]");
- first = t;
- }
- }
- }
- else
- {
- typename C::String num;
- const char* t1 = first+2;
- if (*t1 != '_')
- {
- const char* t = parse_expression(t1, last, db);
- if (t != t1)
- {
- if (db.names.empty())
- return first;
- num = db.names.back().move_full();
- db.names.pop_back();
- t1 = t;
- }
- }
- if (t1 != last && *t1 == '_' && ++t1 != last)
- {
- const char* t = parse_type(t1, last, db);
- if (t != t1)
- {
- if (db.names.empty())
- return first;
- db.names.back().first += " vector[" + num + "]";
- first = t;
- }
- }
+const char *parse_vector_type(const char *first, const char *last, C &db) {
+ if (last - first > 3 && first[0] == 'D' && first[1] == 'v') {
+ if ('1' <= first[2] && first[2] <= '9') {
+ const char *t = parse_number(first + 2, last);
+ if (t == last || *t != '_')
+ return first;
+ const char *num = first + 2;
+ size_t sz = static_cast<size_t>(t - num);
+ if (++t != last) {
+ if (*t != 'p') {
+ const char *t1 = parse_type(t, last, db);
+ if (t1 != t) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first +=
+ " vector[" + typename C::String(num, sz) + "]";
+ first = t1;
+ }
+ } else {
+ ++t;
+ db.names.push_back("pixel vector[" + typename C::String(num, sz) +
+ "]");
+ first = t;
+ }
+ }
+ } else {
+ typename C::String num;
+ const char *t1 = first + 2;
+ if (*t1 != '_') {
+ const char *t = parse_expression(t1, last, db);
+ if (t != t1) {
+ if (db.names.empty())
+ return first;
+ num = db.names.back().move_full();
+ db.names.pop_back();
+ t1 = t;
+ }
+ }
+ if (t1 != last && *t1 == '_' && ++t1 != last) {
+ const char *t = parse_type(t1, last, db);
+ if (t != t1) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first += " vector[" + num + "]";
+ first = t;
}
+ }
}
- return first;
+ }
+ return first;
}
// <type> ::= <builtin-type>
@@ -1899,1026 +1669,893 @@ parse_vector_type(const char* first, con
// extension := U <objc-name> <objc-type> # objc-type<identifier>
// extension := <vector-type> # <vector-type> starts with Dv
-// <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 + <number of digits in k1> + k1
-// <objc-type> := <source-name> # PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-name>
-
-template <class C>
-const char*
-parse_type(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- switch (*first)
- {
- case 'r':
- case 'V':
- case 'K':
- {
- unsigned cv = 0;
- const char* t = parse_cv_qualifiers(first, last, cv);
- if (t != first)
- {
- bool is_function = *t == 'F';
- size_t k0 = db.names.size();
- const char* t1 = parse_type(t, last, db);
- size_t k1 = db.names.size();
- if (t1 != t)
- {
- if (is_function)
- db.subs.pop_back();
- db.subs.emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- {
- if (is_function)
- {
- size_t p = db.names[k].second.size();
- if (db.names[k].second[p-2] == '&')
- p -= 3;
- else if (db.names[k].second.back() == '&')
- p -= 2;
- if (cv & 1)
- {
- db.names[k].second.insert(p, " const");
- p += 6;
- }
- if (cv & 2)
- {
- db.names[k].second.insert(p, " volatile");
- p += 9;
- }
- if (cv & 4)
- db.names[k].second.insert(p, " restrict");
- }
- else
- {
- if (cv & 1)
- db.names[k].first.append(" const");
- if (cv & 2)
- db.names[k].first.append(" volatile");
- if (cv & 4)
- db.names[k].first.append(" restrict");
- }
- db.subs.back().push_back(db.names[k]);
- }
- first = t1;
- }
- }
+// <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;
}
- 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;
}
- }
- return first;
-}
-
-// <operator-name>
-// ::= aa # &&
-// ::= ad # & (unary)
-// ::= an # &
-// ::= aN # &=
-// ::= aS # =
-// ::= cl # ()
-// ::= cm # ,
-// ::= co # ~
-// ::= cv <type> # (cast)
-// ::= da # delete[]
-// ::= de # * (unary)
-// ::= dl # delete
-// ::= dv # /
-// ::= dV # /=
-// ::= eo # ^
-// ::= eO # ^=
-// ::= eq # ==
-// ::= ge # >=
-// ::= gt # >
-// ::= ix # []
-// ::= le # <=
-// ::= li <source-name> # operator ""
-// ::= ls # <<
-// ::= lS # <<=
-// ::= lt # <
-// ::= mi # -
-// ::= mI # -=
-// ::= ml # *
-// ::= mL # *=
-// ::= mm # -- (postfix in <expression> context)
-// ::= na # new[]
-// ::= ne # !=
-// ::= ng # - (unary)
-// ::= nt # !
-// ::= nw # new
-// ::= oo # ||
-// ::= or # |
-// ::= oR # |=
-// ::= pm # ->*
-// ::= pl # +
-// ::= pL # +=
-// ::= pp # ++ (postfix in <expression> context)
-// ::= ps # + (unary)
-// ::= pt # ->
-// ::= qu # ?
-// ::= rm # %
-// ::= rM # %=
-// ::= rs # >>
-// ::= rS # >>=
-// ::= v <digit> <source-name> # vendor extended operator
-
-template <class C>
-const char*
-parse_operator_name(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- switch (first[0])
- {
- case 'a':
- switch (first[1])
- {
- case 'a':
- db.names.push_back("operator&&");
- first += 2;
- break;
- case 'd':
- case 'n':
- db.names.push_back("operator&");
- first += 2;
- break;
- case 'N':
- db.names.push_back("operator&=");
- first += 2;
- break;
- case 'S':
- db.names.push_back("operator=");
- first += 2;
- break;
- }
- break;
- case 'c':
- switch (first[1])
- {
- case 'l':
- db.names.push_back("operator()");
- first += 2;
- break;
- case 'm':
- db.names.push_back("operator,");
- first += 2;
- break;
- case 'o':
- db.names.push_back("operator~");
- first += 2;
- break;
- case 'v':
- {
- bool try_to_parse_template_args = db.try_to_parse_template_args;
- db.try_to_parse_template_args = false;
- const char* t = parse_type(first+2, last, db);
- db.try_to_parse_template_args = try_to_parse_template_args;
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "operator ");
- db.parsed_ctor_dtor_cv = true;
- first = t;
- }
- }
- break;
- }
- break;
- case 'd':
- switch (first[1])
- {
- case 'a':
- db.names.push_back("operator delete[]");
- first += 2;
- break;
- case 'e':
- db.names.push_back("operator*");
- first += 2;
- break;
- case 'l':
- db.names.push_back("operator delete");
- first += 2;
- break;
- case 'v':
- db.names.push_back("operator/");
- first += 2;
- break;
- case 'V':
- db.names.push_back("operator/=");
- first += 2;
- break;
- }
- break;
- case 'e':
- switch (first[1])
- {
- case 'o':
- db.names.push_back("operator^");
- first += 2;
- break;
- case 'O':
- db.names.push_back("operator^=");
- first += 2;
- break;
- case 'q':
- db.names.push_back("operator==");
- first += 2;
- break;
- }
- break;
- case 'g':
- switch (first[1])
- {
- case 'e':
- db.names.push_back("operator>=");
- first += 2;
- break;
- case 't':
- db.names.push_back("operator>");
- first += 2;
- break;
- }
- break;
- case 'i':
- if (first[1] == 'x')
- {
- db.names.push_back("operator[]");
- first += 2;
- }
- break;
- case 'l':
- switch (first[1])
- {
- case 'e':
- db.names.push_back("operator<=");
- first += 2;
- break;
- case 'i':
- {
- const char* t = parse_source_name(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "operator\"\" ");
- first = t;
- }
- }
- break;
- case 's':
- db.names.push_back("operator<<");
- first += 2;
- break;
- case 'S':
- db.names.push_back("operator<<=");
- first += 2;
- break;
- case 't':
- db.names.push_back("operator<");
- first += 2;
- break;
- }
- break;
- case 'm':
- switch (first[1])
- {
- case 'i':
- db.names.push_back("operator-");
- first += 2;
- break;
- case 'I':
- db.names.push_back("operator-=");
- first += 2;
- break;
- case 'l':
- db.names.push_back("operator*");
- first += 2;
- break;
- case 'L':
- db.names.push_back("operator*=");
- first += 2;
- break;
- case 'm':
- db.names.push_back("operator--");
- first += 2;
- break;
- }
- break;
- case 'n':
- switch (first[1])
- {
- case 'a':
- db.names.push_back("operator new[]");
- first += 2;
- break;
- case 'e':
- db.names.push_back("operator!=");
- first += 2;
- break;
- case 'g':
- db.names.push_back("operator-");
- first += 2;
- break;
- case 't':
- db.names.push_back("operator!");
- first += 2;
- break;
- case 'w':
- db.names.push_back("operator new");
- first += 2;
- break;
- }
- break;
- case 'o':
- switch (first[1])
- {
- case 'o':
- db.names.push_back("operator||");
- first += 2;
- break;
- case 'r':
- db.names.push_back("operator|");
- first += 2;
- break;
- case 'R':
- db.names.push_back("operator|=");
- first += 2;
- break;
- }
- break;
- case 'p':
- switch (first[1])
- {
- case 'm':
- db.names.push_back("operator->*");
- first += 2;
- break;
- case 'l':
- db.names.push_back("operator+");
- first += 2;
- break;
- case 'L':
- db.names.push_back("operator+=");
- first += 2;
- break;
- case 'p':
- db.names.push_back("operator++");
- first += 2;
- break;
- case 's':
- db.names.push_back("operator+");
- first += 2;
- break;
- case 't':
- db.names.push_back("operator->");
- first += 2;
- break;
- }
- break;
- case 'q':
- if (first[1] == 'u')
- {
- db.names.push_back("operator?");
- first += 2;
- }
- break;
- case 'r':
- switch (first[1])
- {
- case 'm':
- db.names.push_back("operator%");
- first += 2;
- break;
- case 'M':
- db.names.push_back("operator%=");
- first += 2;
- break;
- case 's':
- db.names.push_back("operator>>");
- first += 2;
- break;
- case 'S':
- db.names.push_back("operator>>=");
- first += 2;
- break;
+ }
+ } break;
+ 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]);
}
- 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;
- }
+ 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]);
}
- break;
+ first = t;
+ }
+ break;
}
- }
- return first;
-}
-
-template <class C>
-const char*
-parse_integer_literal(const char* first, const char* last, const typename C::String& lit, C& db)
-{
- const char* t = parse_number(first, last);
- if (t != first && t != last && *t == 'E')
- {
- if (lit.size() > 3)
- db.names.push_back("(" + lit + ")");
- else
- db.names.emplace_back();
- if (*first == 'n')
- {
- db.names.back().first += '-';
- ++first;
+ 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;
}
- db.names.back().first.append(first, t);
- if (lit.size() <= 3)
- db.names.back().first += lit;
- first = t+1;
- }
- return first;
-}
-
-// <expr-primary> ::= L <type> <value number> E # integer literal
-// ::= L <type> <value float> E # floating literal
-// ::= L <string type> E # string literal
-// ::= L <nullptr type> E # nullptr literal (i.e., "LDnE")
-// ::= L <type> <real-part float> _ <imag-part float> E # complex floating point literal (C 2000)
-// ::= L <mangled-name> E # external name
-
-template <class C>
-const char*
-parse_expr_primary(const char* first, const char* last, C& db)
-{
- if (last - first >= 4 && *first == 'L')
- {
- switch (first[1])
- {
- case 'w':
- {
- const char* t = parse_integer_literal(first+2, last, "wchar_t", db);
- if (t != first+2)
- first = t;
+ 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;
+ }
}
- 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;
+ 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 '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 '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;
}
- break;
- case 'o':
- {
- const char* t = parse_integer_literal(first+2, last, "unsigned __int128", db);
- if (t != first+2)
+ } 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 'f':
- {
- const char* t = parse_floating_number<float>(first+2, last, db);
- if (t != first+2)
+ }
+ 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;
}
- break;
- case 'd':
- {
- const char* t = parse_floating_number<double>(first+2, last, db);
- if (t != first+2)
+ 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;
- }
- break;
- case 'e':
- {
- const char* t = parse_floating_number<long double>(first+2, last, db);
- if (t != first+2)
+ 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;
}
- 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;
+ }
+ LLVM_FALLTHROUGH;
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;
- }
- }
+ // 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;
}
-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;
+// <operator-name>
+// ::= aa # &&
+// ::= ad # & (unary)
+// ::= an # &
+// ::= aN # &=
+// ::= aS # =
+// ::= cl # ()
+// ::= cm # ,
+// ::= co # ~
+// ::= cv <type> # (cast)
+// ::= da # delete[]
+// ::= de # * (unary)
+// ::= dl # delete
+// ::= dv # /
+// ::= dV # /=
+// ::= eo # ^
+// ::= eO # ^=
+// ::= eq # ==
+// ::= ge # >=
+// ::= gt # >
+// ::= ix # []
+// ::= le # <=
+// ::= li <source-name> # operator ""
+// ::= ls # <<
+// ::= lS # <<=
+// ::= lt # <
+// ::= mi # -
+// ::= mI # -=
+// ::= ml # *
+// ::= mL # *=
+// ::= mm # -- (postfix in <expression> context)
+// ::= na # new[]
+// ::= ne # !=
+// ::= ng # - (unary)
+// ::= nt # !
+// ::= nw # new
+// ::= oo # ||
+// ::= or # |
+// ::= oR # |=
+// ::= pm # ->*
+// ::= pl # +
+// ::= pL # +=
+// ::= pp # ++ (postfix in <expression> context)
+// ::= ps # + (unary)
+// ::= pt # ->
+// ::= qu # ?
+// ::= rm # %
+// ::= rM # %=
+// ::= rs # >>
+// ::= rS # >>=
+// ::= v <digit> <source-name> # vendor extended
+// operator
+
+template <class C>
+const char *parse_operator_name(const char *first, const char *last, C &db) {
+ if (last - first >= 2) {
+ switch (first[0]) {
+ case 'a':
+ switch (first[1]) {
+ case 'a':
+ db.names.push_back("operator&&");
+ first += 2;
+ break;
+ case 'd':
+ case 'n':
+ db.names.push_back("operator&");
+ first += 2;
+ break;
+ case 'N':
+ db.names.push_back("operator&=");
+ first += 2;
+ break;
+ case 'S':
+ db.names.push_back("operator=");
+ first += 2;
+ break;
+ }
+ break;
+ case 'c':
+ switch (first[1]) {
+ case 'l':
+ db.names.push_back("operator()");
+ first += 2;
+ break;
+ case 'm':
+ db.names.push_back("operator,");
+ first += 2;
+ break;
+ case 'o':
+ db.names.push_back("operator~");
+ first += 2;
+ break;
+ case 'v': {
+ bool try_to_parse_template_args = db.try_to_parse_template_args;
+ db.try_to_parse_template_args = false;
+ const char *t = parse_type(first + 2, last, db);
+ db.try_to_parse_template_args = try_to_parse_template_args;
+ if (t != first + 2) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first.insert(0, "operator ");
+ db.parsed_ctor_dtor_cv = true;
+ first = t;
+ }
+ } break;
+ }
+ break;
+ case 'd':
+ switch (first[1]) {
+ case 'a':
+ db.names.push_back("operator delete[]");
+ first += 2;
+ break;
+ case 'e':
+ db.names.push_back("operator*");
+ first += 2;
+ break;
+ case 'l':
+ db.names.push_back("operator delete");
+ first += 2;
+ break;
+ case 'v':
+ db.names.push_back("operator/");
+ first += 2;
+ break;
+ case 'V':
+ db.names.push_back("operator/=");
+ first += 2;
+ break;
+ }
+ break;
+ case 'e':
+ switch (first[1]) {
+ case 'o':
+ db.names.push_back("operator^");
+ first += 2;
+ break;
+ case 'O':
+ db.names.push_back("operator^=");
+ first += 2;
+ break;
+ case 'q':
+ db.names.push_back("operator==");
+ first += 2;
+ break;
+ }
+ break;
+ case 'g':
+ switch (first[1]) {
+ case 'e':
+ db.names.push_back("operator>=");
+ first += 2;
+ break;
+ case 't':
+ db.names.push_back("operator>");
+ first += 2;
+ break;
+ }
+ break;
+ case 'i':
+ if (first[1] == 'x') {
+ db.names.push_back("operator[]");
+ first += 2;
+ }
+ break;
+ case 'l':
+ switch (first[1]) {
+ case 'e':
+ db.names.push_back("operator<=");
+ first += 2;
+ break;
+ case 'i': {
+ const char *t = parse_source_name(first + 2, last, db);
+ if (t != first + 2) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first.insert(0, "operator\"\" ");
+ first = t;
+ }
+ } break;
+ case 's':
+ db.names.push_back("operator<<");
+ first += 2;
+ break;
+ case 'S':
+ db.names.push_back("operator<<=");
+ first += 2;
+ break;
+ case 't':
+ db.names.push_back("operator<");
+ first += 2;
+ break;
+ }
+ break;
+ case 'm':
+ switch (first[1]) {
+ case 'i':
+ db.names.push_back("operator-");
+ first += 2;
+ break;
+ case 'I':
+ db.names.push_back("operator-=");
+ first += 2;
+ break;
+ case 'l':
+ db.names.push_back("operator*");
+ first += 2;
+ break;
+ case 'L':
+ db.names.push_back("operator*=");
+ first += 2;
+ break;
+ case 'm':
+ db.names.push_back("operator--");
+ first += 2;
+ break;
+ }
+ break;
+ case 'n':
+ switch (first[1]) {
+ case 'a':
+ db.names.push_back("operator new[]");
+ first += 2;
+ break;
+ case 'e':
+ db.names.push_back("operator!=");
+ first += 2;
+ break;
+ case 'g':
+ db.names.push_back("operator-");
+ first += 2;
+ break;
+ case 't':
+ db.names.push_back("operator!");
+ first += 2;
+ break;
+ case 'w':
+ db.names.push_back("operator new");
+ first += 2;
+ break;
+ }
+ break;
+ case 'o':
+ switch (first[1]) {
+ case 'o':
+ db.names.push_back("operator||");
+ first += 2;
+ break;
+ case 'r':
+ db.names.push_back("operator|");
+ first += 2;
+ break;
+ case 'R':
+ db.names.push_back("operator|=");
+ first += 2;
+ break;
+ }
+ break;
+ case 'p':
+ switch (first[1]) {
+ case 'm':
+ db.names.push_back("operator->*");
+ first += 2;
+ break;
+ case 'l':
+ db.names.push_back("operator+");
+ first += 2;
+ break;
+ case 'L':
+ db.names.push_back("operator+=");
+ first += 2;
+ break;
+ case 'p':
+ db.names.push_back("operator++");
+ first += 2;
+ break;
+ case 's':
+ db.names.push_back("operator+");
+ first += 2;
+ break;
+ case 't':
+ db.names.push_back("operator->");
+ first += 2;
+ break;
+ }
+ break;
+ case 'q':
+ if (first[1] == 'u') {
+ db.names.push_back("operator?");
+ first += 2;
+ }
+ break;
+ case 'r':
+ switch (first[1]) {
+ case 'm':
+ db.names.push_back("operator%");
+ first += 2;
+ break;
+ case 'M':
+ db.names.push_back("operator%=");
+ first += 2;
+ break;
+ case 's':
+ db.names.push_back("operator>>");
+ first += 2;
+ break;
+ case 'S':
+ db.names.push_back("operator>>=");
+ first += 2;
+ break;
+ }
+ break;
+ case 'v':
+ if (std::isdigit(first[1])) {
+ const char *t = parse_source_name(first + 2, last, db);
+ if (t != first + 2) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first.insert(0, "operator ");
+ first = t;
}
+ }
+ break;
}
- const char* p0 = pe - 1;
- for (; p0 != pf; --p0)
- {
- if (*p0 == ':')
- {
- ++p0;
+ }
+ return first;
+}
+
+template <class C>
+const char *parse_integer_literal(const char *first, const char *last,
+ const typename C::String &lit, C &db) {
+ const char *t = parse_number(first, last);
+ if (t != first && t != last && *t == 'E') {
+ if (lit.size() > 3)
+ db.names.push_back("(" + lit + ")");
+ else
+ db.names.emplace_back();
+ if (*first == 'n') {
+ db.names.back().first += '-';
+ ++first;
+ }
+ db.names.back().first.append(first, t);
+ if (lit.size() <= 3)
+ db.names.back().first += lit;
+ first = t + 1;
+ }
+ return first;
+}
+
+// <expr-primary> ::= L <type> <value number> E #
+// integer literal
+// ::= L <type> <value float> E #
+// floating literal
+// ::= L <string type> E #
+// string literal
+// ::= L <nullptr type> E #
+// nullptr literal (i.e., "LDnE")
+// ::= L <type> <real-part float> _ <imag-part float> E #
+// complex floating point literal (C 2000)
+// ::= L <mangled-name> E #
+// external name
+
+template <class C>
+const char *parse_expr_primary(const char *first, const char *last, C &db) {
+ if (last - first >= 4 && *first == 'L') {
+ switch (first[1]) {
+ case 'w': {
+ const char *t = parse_integer_literal(first + 2, last, "wchar_t", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'b':
+ if (first[3] == 'E') {
+ switch (first[2]) {
+ case '0':
+ db.names.push_back("false");
+ first += 4;
+ break;
+ case '1':
+ db.names.push_back("true");
+ first += 4;
+ break;
+ }
+ }
+ break;
+ case 'c': {
+ const char *t = parse_integer_literal(first + 2, last, "char", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'a': {
+ const char *t = parse_integer_literal(first + 2, last, "signed char", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'h': {
+ const char *t =
+ parse_integer_literal(first + 2, last, "unsigned char", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 's': {
+ const char *t = parse_integer_literal(first + 2, last, "short", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 't': {
+ const char *t =
+ parse_integer_literal(first + 2, last, "unsigned short", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'i': {
+ const char *t = parse_integer_literal(first + 2, last, "", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'j': {
+ const char *t = parse_integer_literal(first + 2, last, "u", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'l': {
+ const char *t = parse_integer_literal(first + 2, last, "l", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'm': {
+ const char *t = parse_integer_literal(first + 2, last, "ul", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'x': {
+ const char *t = parse_integer_literal(first + 2, last, "ll", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'y': {
+ const char *t = parse_integer_literal(first + 2, last, "ull", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'n': {
+ const char *t = parse_integer_literal(first + 2, last, "__int128", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'o': {
+ const char *t =
+ parse_integer_literal(first + 2, last, "unsigned __int128", db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'f': {
+ const char *t = parse_floating_number<float>(first + 2, last, db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'd': {
+ const char *t = parse_floating_number<double>(first + 2, last, db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case 'e': {
+ const char *t = parse_floating_number<long double>(first + 2, last, db);
+ if (t != first + 2)
+ first = t;
+ } break;
+ case '_':
+ if (first[2] == 'Z') {
+ const char *t = parse_encoding(first + 3, last, db);
+ if (t != first + 3 && t != last && *t == 'E')
+ first = t + 1;
+ }
+ break;
+ case 'T':
+ // Invalid mangled name per
+ // http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
+ break;
+ default: {
+ // might be named type
+ const char *t = parse_type(first + 1, last, db);
+ if (t != first + 1 && t != last) {
+ if (*t != 'E') {
+ const char *n = t;
+ for (; n != last && isdigit(*n); ++n)
+ ;
+ if (n != t && n != last && *n == 'E') {
+ if (db.names.empty())
+ return first;
+ db.names.back() = "(" + db.names.back().move_full() + ")" +
+ typename C::String(t, n);
+ first = n + 1;
break;
- }
+ }
+ } else {
+ first = t + 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return first;
+}
+
+template <class String> String base_name(String &s) {
+ if (s.empty())
+ return s;
+ if (s == "std::string") {
+ s = "std::basic_string<char, std::char_traits<char>, std::allocator<char> "
+ ">";
+ return "basic_string";
+ }
+ if (s == "std::istream") {
+ s = "std::basic_istream<char, std::char_traits<char> >";
+ return "basic_istream";
+ }
+ if (s == "std::ostream") {
+ s = "std::basic_ostream<char, std::char_traits<char> >";
+ return "basic_ostream";
+ }
+ if (s == "std::iostream") {
+ s = "std::basic_iostream<char, std::char_traits<char> >";
+ return "basic_iostream";
+ }
+ const char *const pf = s.data();
+ const char *pe = pf + s.size();
+ if (pe[-1] == '>') {
+ unsigned c = 1;
+ while (true) {
+ if (--pe == pf)
+ return String();
+ if (pe[-1] == '<') {
+ if (--c == 0) {
+ --pe;
+ break;
+ }
+ } else if (pe[-1] == '>')
+ ++c;
+ }
+ }
+ const char *p0 = pe - 1;
+ for (; p0 != pf; --p0) {
+ if (*p0 == ':') {
+ ++p0;
+ break;
}
- return String(p0, pe);
+ }
+ return String(p0, pe);
}
// <ctor-dtor-name> ::= C1 # complete object constructor
@@ -2931,209 +2568,180 @@ base_name(String& s)
// 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;
- }
+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;
- 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;
+ 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);
}
- break;
+ 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 @@ parse_unqualified_name(const char* first
// extension ::= StL<unqualified-name>
template <class C>
-const char*
-parse_unscoped_name(const char* first, const char* last, C& db)
-{
- if (last - first >= 2)
- {
- const char* t0 = first;
- bool St = false;
- if (first[0] == 'S' && first[1] == 't')
- {
- t0 += 2;
- St = true;
- if (t0 != last && *t0 == 'L')
- ++t0;
- }
- const char* t1 = parse_unqualified_name(t0, last, db);
- if (t1 != t0)
- {
- if (St)
- {
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "std::");
- }
- first = t1;
- }
- }
- return first;
-}
-
-// at <type> # alignof (a type)
-
-template <class C>
-const char*
-parse_alignof_type(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'a' && first[1] == 't')
- {
- const char* t = parse_type(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
-}
-
-// az <expression> # alignof (a expression)
-
-template <class C>
-const char*
-parse_alignof_expr(const char* first, const char* last, C& db)
-{
- if (last - first >= 3 && first[0] == 'a' && first[1] == 'z')
- {
- const char* t = parse_expression(first+2, last, db);
- if (t != first+2)
- {
- if (db.names.empty())
- return first;
- db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
- first = t;
- }
- }
- return first;
-}
-
-template <class C>
-const char*
-parse_noexcept_expression(const char* first, const char* last, C& db)
-{
- const char* t1 = parse_expression(first, last, db);
- if (t1 != first)
- {
+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 = "noexcept (" + db.names.back().move_full() + ")";
- first = t1;
+ return first;
+ db.names.back().first.insert(0, "std::");
+ }
+ first = t1;
}
- return first;
+ }
+ 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;
-}
+// at <type> # alignof (a type)
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_alignof_type(const char *first, const char *last, C &db) {
+ if (last - first >= 3 && first[0] == 'a' && first[1] == 't') {
+ const char *t = parse_type(first + 2, last, db);
+ if (t != first + 2) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
+ first = t;
+ }
+ }
+ return first;
+}
+
+// az <expression> # alignof (a
+// expression)
+
+template <class C>
+const char *parse_alignof_expr(const char *first, const char *last, C &db) {
+ if (last - first >= 3 && first[0] == 'a' && first[1] == 'z') {
+ const char *t = parse_expression(first + 2, last, db);
+ if (t != first + 2) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first = "alignof (" + db.names.back().move_full() + ")";
+ first = t;
+ }
+ }
+ return first;
+}
+
+template <class C>
+const char *parse_noexcept_expression(const char *first, const char *last,
+ C &db) {
+ const char *t1 = parse_expression(first, last, db);
+ if (t1 != first) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first = "noexcept (" + db.names.back().move_full() + ")";
+ first = t1;
+ }
+ return first;
+}
+
+template <class C>
+const char *parse_prefix_expression(const char *first, const char *last,
+ const typename C::String &op, C &db) {
+ const char *t1 = parse_expression(first, last, db);
+ if (t1 != first) {
+ if (db.names.empty())
+ return first;
+ db.names.back().first = op + "(" + db.names.back().move_full() + ")";
+ first = t1;
+ }
+ return first;
+}
+
+template <class C>
+const char *parse_binary_expression(const char *first, const char *last,
+ const typename C::String &op, C &db) {
+ const char *t1 = parse_expression(first, last, db);
+ if (t1 != first) {
+ const char *t2 = parse_expression(t1, last, db);
+ if (t2 != t1) {
+ if (db.names.size() < 2)
+ return first;
+ auto op2 = db.names.back().move_full();
+ db.names.pop_back();
+ auto op1 = db.names.back().move_full();
+ auto &nm = db.names.back().first;
+ nm.clear();
+ if (op == ">")
+ nm += '(';
+ nm += "(" + op1 + ") " + op + " (" + op2 + ")";
+ if (op == ">")
+ nm += ')';
+ first = t2;
+ } else
+ db.names.pop_back();
+ }
+ return first;
}
// <expression> ::= <unary operator-name> <expression>
// ::= <binary operator-name> <expression> <expression>
-// ::= <ternary operator-name> <expression> <expression> <expression>
+// ::= <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);
- }
- }
- return first;
-}
-
-// <template-arg> ::= <type> # type or template
-// ::= X <expression> E # expression
-// ::= <expr-primary> # simple expressions
-// ::= J <template-arg>* E # argument pack
-// ::= LZ <encoding> E # extension
-
-template <class C>
-const char*
-parse_template_arg(const char* first, const char* last, C& db)
-{
- if (first != last)
- {
- const char* t;
- switch (*first)
- {
- case 'X':
- t = parse_expression(first+1, last, db);
- if (t != first+1)
- {
- if (t != last && *t == 'E')
- first = t+1;
- }
- break;
- case 'J':
- t = first+1;
- if (t == last)
+
+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;
- 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;
+ 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
- first = parse_expr_primary(first, last, db);
+ } 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;
- default:
- // <type>
- first = parse_type(first, last, db);
+ case 'f':
+ first = parse_sizeof_function_param_pack_expr(first, last, db);
break;
+ }
}
+ break;
+ }
+ break;
+ case 't':
+ switch (t[1]) {
+ case 'e':
+ case 'i':
+ first = parse_typeid_expr(first, last, db);
+ break;
+ case 'r':
+ db.names.push_back("throw");
+ first += 2;
+ break;
+ case 'w':
+ first = parse_throw_expr(first, last, db);
+ break;
+ }
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return parse_unresolved_name(first, last, db);
+ }
+ }
+ return first;
+}
+
+// <template-arg> ::= <type> # type
+// or template
+// ::= X <expression> E #
+// expression
+// ::= <expr-primary> #
+// simple expressions
+// ::= J <template-arg>* E #
+// argument pack
+// ::= LZ <encoding> E #
+// extension
+
+template <class C>
+const char *parse_template_arg(const char *first, const char *last, C &db) {
+ if (first != last) {
+ const char *t;
+ switch (*first) {
+ case 'X':
+ t = parse_expression(first + 1, last, db);
+ if (t != first + 1) {
+ if (t != last && *t == 'E')
+ first = t + 1;
+ }
+ break;
+ case 'J':
+ t = first + 1;
+ if (t == last)
+ return first;
+ while (*t != 'E') {
+ const char *t1 = parse_template_arg(t, last, db);
+ if (t1 == t)
+ return first;
+ t = t1;
+ }
+ first = t + 1;
+ break;
+ case 'L':
+ // <expr-primary> or LZ <encoding> E
+ if (first + 1 != last && first[1] == 'Z') {
+ t = parse_encoding(first + 2, last, db);
+ if (t != first + 2 && t != last && *t == 'E')
+ first = t + 1;
+ } else
+ first = parse_expr_primary(first, last, db);
+ break;
+ default:
+ // <type>
+ first = parse_type(first, last, db);
+ break;
}
- return first;
+ }
+ return first;
}
// <template-args> ::= I <template-arg>* E
// extension, the abi says <template-arg>+
template <class C>
-const char*
-parse_template_args(const char* first, const char* last, C& db)
-{
- if (last - first >= 2 && *first == 'I')
- {
- if (db.tag_templates)
- db.template_param.back().clear();
- const char* t = first+1;
- typename C::String args("<");
- while (*t != 'E')
- {
- if (db.tag_templates)
- db.template_param.emplace_back(db.names.get_allocator());
- size_t k0 = db.names.size();
- const char* t1 = parse_template_arg(t, last, db);
- size_t k1 = db.names.size();
- if (db.tag_templates)
- db.template_param.pop_back();
- if (t1 == t || t1 == last)
- return first;
- if (db.tag_templates)
- {
- db.template_param.back().emplace_back(db.names.get_allocator());
- for (size_t k = k0; k < k1; ++k)
- db.template_param.back().back().push_back(db.names[k]);
- }
- for (size_t k = k0; k < k1; ++k)
- {
- if (args.size() > 1)
- args += ", ";
- args += db.names[k].move_full();
- }
- for (; k1 != k0; --k1)
- db.names.pop_back();
- t = t1;
- }
- first = t + 1;
- if (args.back() != '>')
- args += ">";
- else
- args += " >";
- db.names.push_back(std::move(args));
-
- }
- return first;
+const char *parse_template_args(const char *first, const char *last, C &db) {
+ if (last - first >= 2 && *first == 'I') {
+ if (db.tag_templates)
+ db.template_param.back().clear();
+ const char *t = first + 1;
+ typename C::String args("<");
+ while (*t != 'E') {
+ if (db.tag_templates)
+ db.template_param.emplace_back(db.names.get_allocator());
+ size_t k0 = db.names.size();
+ const char *t1 = parse_template_arg(t, last, db);
+ size_t k1 = db.names.size();
+ if (db.tag_templates)
+ db.template_param.pop_back();
+ if (t1 == t || t1 == last)
+ return first;
+ if (db.tag_templates) {
+ db.template_param.back().emplace_back(db.names.get_allocator());
+ for (size_t k = k0; k < k1; ++k)
+ db.template_param.back().back().push_back(db.names[k]);
+ }
+ for (size_t k = k0; k < k1; ++k) {
+ if (args.size() > 1)
+ args += ", ";
+ args += db.names[k].move_full();
+ }
+ for (; k1 != k0; --k1)
+ db.names.pop_back();
+ t = t1;
+ }
+ first = t + 1;
+ if (args.back() != '>')
+ args += ">";
+ else
+ args += " >";
+ db.names.push_back(std::move(args));
+ }
+ return first;
}
-// <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
-// ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
-//
+// <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 @@ parse_template_args(const char* first, c
// ::= <substitution>
// ::= <prefix> <data-member-prefix>
// extension ::= L
-//
+//
// <template-prefix> ::= <prefix> <template unqualified-name>
// ::= <template-param>
// ::= <substitution>
template <class C>
-const char*
-parse_nested_name(const char* first, const char* last, C& db,
- bool* ends_with_template_args)
-{
- if (first != last && *first == 'N')
- {
- unsigned cv;
- const char* t0 = parse_cv_qualifiers(first+1, last, cv);
- if (t0 == last)
- return first;
- db.ref = 0;
- if (*t0 == 'R')
- {
- db.ref = 1;
- ++t0;
- }
- else if (*t0 == 'O')
- {
- db.ref = 2;
- ++t0;
- }
- db.names.emplace_back();
- if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't')
- {
- t0 += 2;
- db.names.back().first = "std";
- }
- if (t0 == last)
- {
- db.names.pop_back();
- return first;
- }
- bool pop_subs = false;
- bool component_ends_with_template_args = false;
- while (*t0 != 'E')
- {
- component_ends_with_template_args = false;
- const char* t1;
- switch (*t0)
- {
- case 'S':
- if (t0 + 1 != last && t0[1] == 't')
- goto do_parse_unqualified_name;
- t1 = parse_substitution(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- if (!db.names.back().first.empty())
- {
- db.names.back().first += "::" + name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- }
- else
- db.names.back().first = name;
- pop_subs = true;
- t0 = t1;
- }
- else
- return first;
- break;
- case 'T':
- t1 = parse_template_param(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- if (!db.names.back().first.empty())
- db.names.back().first += "::" + name;
- else
- db.names.back().first = name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- pop_subs = true;
- t0 = t1;
- }
- else
- return first;
- break;
- case 'D':
- if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
- goto do_parse_unqualified_name;
- t1 = parse_decltype(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- if (!db.names.back().first.empty())
- db.names.back().first += "::" + name;
- else
- db.names.back().first = name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- pop_subs = true;
- t0 = t1;
- }
- else
- return first;
- break;
- case 'I':
- t1 = parse_template_args(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- db.names.back().first += name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- t0 = t1;
- component_ends_with_template_args = true;
- }
- else
- return first;
- break;
- case 'L':
- if (++t0 == last)
- return first;
- break;
- default:
- do_parse_unqualified_name:
- t1 = parse_unqualified_name(t0, last, db);
- if (t1 != t0 && t1 != last)
- {
- auto name = db.names.back().move_full();
- db.names.pop_back();
- if (!db.names.back().first.empty())
- db.names.back().first += "::" + name;
- else
- db.names.back().first = name;
- db.subs.push_back(typename C::sub_type(1, db.names.back(), db.names.get_allocator()));
- pop_subs = true;
- t0 = t1;
- }
- else
- return first;
- }
- }
- first = t0 + 1;
- db.cv = cv;
- if (pop_subs && !db.subs.empty())
- db.subs.pop_back();
- if (ends_with_template_args)
- *ends_with_template_args = component_ends_with_template_args;
- }
- return first;
+const char *parse_nested_name(const char *first, const char *last, C &db,
+ bool *ends_with_template_args) {
+ if (first != last && *first == 'N') {
+ unsigned cv;
+ const char *t0 = parse_cv_qualifiers(first + 1, last, cv);
+ if (t0 == last)
+ return first;
+ db.ref = 0;
+ if (*t0 == 'R') {
+ db.ref = 1;
+ ++t0;
+ } else if (*t0 == 'O') {
+ db.ref = 2;
+ ++t0;
+ }
+ db.names.emplace_back();
+ if (last - t0 >= 2 && t0[0] == 'S' && t0[1] == 't') {
+ t0 += 2;
+ db.names.back().first = "std";
+ }
+ if (t0 == last) {
+ db.names.pop_back();
+ return first;
+ }
+ bool pop_subs = false;
+ bool component_ends_with_template_args = false;
+ while (*t0 != 'E') {
+ component_ends_with_template_args = false;
+ const char *t1;
+ switch (*t0) {
+ case 'S':
+ if (t0 + 1 != last && t0[1] == 't')
+ goto do_parse_unqualified_name;
+ t1 = parse_substitution(t0, last, db);
+ if (t1 != t0 && t1 != last) {
+ auto name = db.names.back().move_full();
+ db.names.pop_back();
+ if (!db.names.back().first.empty()) {
+ db.names.back().first += "::" + name;
+ db.subs.push_back(typename C::sub_type(1, db.names.back(),
+ db.names.get_allocator()));
+ } else
+ db.names.back().first = name;
+ pop_subs = true;
+ t0 = t1;
+ } else
+ return first;
+ break;
+ case 'T':
+ t1 = parse_template_param(t0, last, db);
+ if (t1 != t0 && t1 != last) {
+ auto name = db.names.back().move_full();
+ db.names.pop_back();
+ if (!db.names.back().first.empty())
+ db.names.back().first += "::" + name;
+ else
+ db.names.back().first = name;
+ db.subs.push_back(typename C::sub_type(1, db.names.back(),
+ db.names.get_allocator()));
+ pop_subs = true;
+ t0 = t1;
+ } else
+ return first;
+ break;
+ case 'D':
+ if (t0 + 1 != last && t0[1] != 't' && t0[1] != 'T')
+ goto do_parse_unqualified_name;
+ t1 = parse_decltype(t0, last, db);
+ if (t1 != t0 && t1 != last) {
+ auto name = db.names.back().move_full();
+ db.names.pop_back();
+ if (!db.names.back().first.empty())
+ db.names.back().first += "::" + name;
+ else
+ db.names.back().first = name;
+ db.subs.push_back(typename C::sub_type(1, db.names.back(),
+ db.names.get_allocator()));
+ pop_subs = true;
+ t0 = t1;
+ } else
+ return first;
+ break;
+ case 'I':
+ t1 = parse_template_args(t0, last, db);
+ if (t1 != t0 && t1 != last) {
+ auto name = db.names.back().move_full();
+ db.names.pop_back();
+ db.names.back().first += name;
+ db.subs.push_back(typename C::sub_type(1, db.names.back(),
+ db.names.get_allocator()));
+ t0 = t1;
+ component_ends_with_template_args = true;
+ } else
+ return first;
+ break;
+ case 'L':
+ if (++t0 == last)
+ return first;
+ break;
+ default:
+ do_parse_unqualified_name:
+ t1 = parse_unqualified_name(t0, last, db);
+ if (t1 != t0 && t1 != last) {
+ auto name = db.names.back().move_full();
+ db.names.pop_back();
+ if (!db.names.back().first.empty())
+ db.names.back().first += "::" + name;
+ else
+ db.names.back().first = name;
+ db.subs.push_back(typename C::sub_type(1, db.names.back(),
+ db.names.get_allocator()));
+ pop_subs = true;
+ t0 = t1;
+ } else
+ return first;
+ }
+ }
+ first = t0 + 1;
+ db.cv = cv;
+ if (pop_subs && !db.subs.empty())
+ db.subs.pop_back();
+ if (ends_with_template_args)
+ *ends_with_template_args = component_ends_with_template_args;
+ }
+ return first;
}
// <discriminator> := _ <non-negative number> # when number < 10
// := __ <non-negative number> _ # when number >= 10
// extension := decimal-digit+
-const char*
-parse_discriminator(const char* first, const char* last)
-{
- // parse but ignore discriminator
- if (first != last)
- {
- if (*first == '_')
- {
- const char* t1 = first+1;
- if (t1 != last)
- {
- if (std::isdigit(*t1))
- first = t1+1;
- else if (*t1 == '_')
- {
- for (++t1; t1 != last && std::isdigit(*t1); ++t1)
- ;
- if (t1 != last && *t1 == '_')
- first = t1 + 1;
- }
- }
- }
- else if (std::isdigit(*first))
- {
- const char* t1 = first+1;
- for (; t1 != last && std::isdigit(*t1); ++t1)
- ;
- first = t1;
- }
+const char *parse_discriminator(const char *first, const char *last) {
+ // parse but ignore discriminator
+ if (first != last) {
+ if (*first == '_') {
+ const char *t1 = first + 1;
+ if (t1 != last) {
+ if (std::isdigit(*t1))
+ first = t1 + 1;
+ else if (*t1 == '_') {
+ for (++t1; t1 != last && std::isdigit(*t1); ++t1)
+ ;
+ if (t1 != last && *t1 == '_')
+ first = t1 + 1;
+ }
+ }
+ } else if (std::isdigit(*first)) {
+ const char *t1 = first + 1;
+ for (; t1 != last && std::isdigit(*t1); ++t1)
+ ;
+ first = t1;
}
- return first;
+ }
+ 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 @@ parse_local_name(const char* first, cons
// ::= <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;
- }
- case 'Z':
- {
- const char* t1 = parse_local_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;
}
- 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 @@ parse_call_offset(const char* first, con
// # 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)
+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>
{
- 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;
- }
+ const char *t0 = parse_call_offset(first + 2, last);
+ if (t0 == first + 2)
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;
+ 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()
- {
- restore_ = std::move(original_value_);
- }
+ save_value(T &restore) : restore_(restore), original_value_(restore) {}
+
+ ~save_value() { restore_ = std::move(original_value_); }
- save_value(const save_value&) = delete;
- save_value& operator=(const save_value&) = delete;
+ save_value(const save_value &) = delete;
+ save_value &operator=(const save_value &) = delete;
};
// <encoding> ::= <function name> <bare-function-type>
@@ -4502,121 +3992,104 @@ public:
// ::= <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;
+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();
}
- else
- first = t;
+ 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;
}
- break;
}
- }
+ 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 @@ parse_encoding(const char* first, const
// _block_invoke_<decimal-digit>+
template <class C>
-const char*
-parse_block_invoke(const char* first, const char* last, C& db)
-{
- if (last - first >= 13)
- {
- const char test[] = "_block_invoke";
- const char* t = first;
- for (int i = 0; i < 13; ++i, ++t)
- {
- if (*t != test[i])
- return first;
- }
- if (t != last)
- {
- if (*t == '_')
- {
- // must have at least 1 decimal digit
- if (++t == last || !std::isdigit(*t))
- return first;
- ++t;
- }
- // parse zero or more digits
- while (t != last && isdigit(*t))
- ++t;
- }
- if (db.names.empty())
- return first;
- db.names.back().first.insert(0, "invocation function for block in ");
- first = t;
- }
- return first;
+const char *parse_block_invoke(const char *first, const char *last, C &db) {
+ if (last - first >= 13) {
+ const char test[] = "_block_invoke";
+ const char *t = first;
+ for (int i = 0; i < 13; ++i, ++t) {
+ if (*t != test[i])
+ return first;
+ }
+ if (t != last) {
+ if (*t == '_') {
+ // must have at least 1 decimal digit
+ if (++t == last || !std::isdigit(*t))
+ return first;
+ ++t;
+ }
+ // parse zero or more digits
+ while (t != last && isdigit(*t))
+ ++t;
+ }
+ if (db.names.empty())
+ return first;
+ db.names.back().first.insert(0, "invocation function for block in ");
+ first = t;
+ }
+ return first;
}
// extension
// <dot-suffix> := .<anything and everything>
template <class C>
-const char*
-parse_dot_suffix(const char* first, const char* last, C& db)
-{
- if (first != last && *first == '.')
- {
- if (db.names.empty())
- return first;
- db.names.back().first += " (" + typename C::String(first, last) + ")";
- first = last;
- }
- return first;
+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 @@ parse_dot_suffix(const char* first, cons
// ::= <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;
-}
-
-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;}
+ } 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_;}
+ 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> char *arena<N>::allocate(std::size_t n) {
+ n = align_up(n);
+ if (static_cast<std::size_t>(buf_ + N - ptr_) >= n) {
+ char *r = ptr_;
+ ptr_ += n;
+ return r;
+ }
+ return static_cast<char *>(std::malloc(n));
}
template <std::size_t N>
-void
-arena<N>::deallocate(char* p, std::size_t n) LLVM_NOEXCEPT
-{
- if (pointer_in_buffer(p))
- {
- n = align_up(n);
- if (p + n == ptr_)
- ptr_ = p;
- }
- else
- std::free(p);
+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_;
+template <class T, std::size_t N> class short_alloc {
+ arena<N> &a_;
+
public:
- typedef T value_type;
+ typedef T value_type;
public:
- template <class _Up> struct rebind {typedef short_alloc<_Up, N> other;};
+ template <class _Up> struct rebind { typedef short_alloc<_Up, N> other; };
- short_alloc(arena<N>& a) LLVM_NOEXCEPT : a_(a) {}
- template <class U>
- short_alloc(const short_alloc<U, N>& a) LLVM_NOEXCEPT
- : a_(a.a_) {}
- short_alloc(const short_alloc&) = default;
- short_alloc& operator=(const short_alloc&) = delete;
-
- T* allocate(std::size_t n)
- {
- return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
- }
- void deallocate(T* p, std::size_t n) LLVM_NOEXCEPT
- {
- a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
- }
-
- template <class T1, std::size_t N1, class U, std::size_t M>
- friend
- bool
- operator==(const short_alloc<T1, N1>& x, const short_alloc<U, M>& y) LLVM_NOEXCEPT;
+ short_alloc(arena<N> &a) LLVM_NOEXCEPT : a_(a) {}
+ template <class U>
+ short_alloc(const short_alloc<U, N> &a) LLVM_NOEXCEPT : a_(a.a_) {}
+ short_alloc(const short_alloc &) = default;
+ short_alloc &operator=(const short_alloc &) = delete;
+
+ T *allocate(std::size_t n) {
+ return reinterpret_cast<T *>(a_.allocate(n * sizeof(T)));
+ }
+ void deallocate(T *p, std::size_t n) LLVM_NOEXCEPT {
+ a_.deallocate(reinterpret_cast<char *>(p), n * sizeof(T));
+ }
+
+ template <class T1, std::size_t N1, class U, std::size_t M>
+ friend bool operator==(const short_alloc<T1, N1> &x,
+ const short_alloc<U, M> &y) LLVM_NOEXCEPT;
- template <class U, std::size_t M> friend class short_alloc;
+ template <class 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;
-
- 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();
- }
+ typedef T value_type;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef T *pointer;
+ typedef const T *const_pointer;
+ typedef T &reference;
+ typedef const T &const_reference;
+
+ malloc_alloc() = default;
+ template <class U> malloc_alloc(const malloc_alloc<U> &) LLVM_NOEXCEPT {}
+
+ T *allocate(std::size_t n) {
+ return static_cast<T *>(std::malloc(n * sizeof(T)));
+ }
+ void deallocate(T *p, std::size_t) LLVM_NOEXCEPT { std::free(p); }
+ template <class Other> struct rebind { typedef malloc_alloc<Other> other; };
+ void construct(T *p) { ::new (p) T(); }
+ void construct(T *p, const T &t) { ::new (p) T(t); }
+ void destroy(T *p) { p->~T(); }
};
template <class T, class U>
-inline
-bool
-operator==(const malloc_alloc<T>&, const malloc_alloc<U>&) LLVM_NOEXCEPT
-{
- return true;
+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;
-
- 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);}
+template <class StrT> struct string_pair {
+ StrT first;
+ StrT second;
+
+ string_pair() = default;
+ string_pair(StrT f) : first(std::move(f)) {}
+ string_pair(StrT f, StrT s) : first(std::move(f)), second(std::move(s)) {}
+ template <size_t N> string_pair(const char (&s)[N]) : first(s, N - 1) {}
+
+ size_t size() const { return first.size() + second.size(); }
+ StrT full() const { return first + second; }
+ StrT move_full() { return std::move(first) + std::move(second); }
};
-struct Db
-{
- typedef std::basic_string<char, std::char_traits<char>,
- malloc_alloc<char>> String;
- typedef Vector<string_pair<String>> sub_type;
- typedef Vector<sub_type> template_param_type;
- sub_type names;
- template_param_type subs;
- Vector<template_param_type> template_param;
- unsigned cv;
- unsigned ref;
- unsigned encoding_depth;
- bool parsed_ctor_dtor_cv;
- bool tag_templates;
- bool fix_forward_references;
- bool try_to_parse_template_args;
-
- template <size_t N>
- Db(arena<N>& ar) :
- names(ar),
- subs(0, names, ar),
- template_param(0, subs, ar)
- {}
+struct Db {
+ typedef std::basic_string<char, std::char_traits<char>, malloc_alloc<char>>
+ String;
+ typedef Vector<string_pair<String>> sub_type;
+ typedef Vector<sub_type> template_param_type;
+ sub_type names;
+ template_param_type subs;
+ Vector<template_param_type> template_param;
+ unsigned cv;
+ unsigned ref;
+ unsigned encoding_depth;
+ bool parsed_ctor_dtor_cv;
+ bool tag_templates;
+ bool fix_forward_references;
+ bool try_to_parse_template_args;
+
+ template <size_t N>
+ Db(arena<N> &ar)
+ : names(ar), subs(0, names, ar), template_param(0, subs, ar) {}
};
-} // unnamed namespace
+} // 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);
+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.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
+ 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;
- if (status)
- *status = internal_status;
- return buf;
+ } 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
Modified: lldb/trunk/source/Core/DataBufferHeap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataBufferHeap.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataBufferHeap.cpp (original)
+++ lldb/trunk/source/Core/DataBufferHeap.cpp Tue Sep 6 15:57:50 2016
@@ -19,30 +19,24 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Default constructor
//----------------------------------------------------------------------
-DataBufferHeap::DataBufferHeap () :
- m_data()
-{
-}
+DataBufferHeap::DataBufferHeap() : m_data() {}
//----------------------------------------------------------------------
// Initialize this class with "n" characters and fill the buffer
// with "ch".
//----------------------------------------------------------------------
-DataBufferHeap::DataBufferHeap (lldb::offset_t n, uint8_t ch) :
- m_data()
-{
- if (n < m_data.max_size())
- m_data.assign (n, ch);
+DataBufferHeap::DataBufferHeap(lldb::offset_t n, uint8_t ch) : m_data() {
+ if (n < m_data.max_size())
+ m_data.assign(n, ch);
}
//----------------------------------------------------------------------
// Initialize this class with a copy of the "n" bytes from the "bytes"
// buffer.
//----------------------------------------------------------------------
-DataBufferHeap::DataBufferHeap (const void *src, lldb::offset_t src_len) :
- m_data()
-{
- CopyData (src, src_len);
+DataBufferHeap::DataBufferHeap(const void *src, lldb::offset_t src_len)
+ : m_data() {
+ CopyData(src, src_len);
}
//----------------------------------------------------------------------
@@ -55,61 +49,46 @@ DataBufferHeap::~DataBufferHeap() = defa
// 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();
-}
-
-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::Clear()
-{
- buffer_t empty;
- m_data.swap(empty);
+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::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);
}
Modified: lldb/trunk/source/Core/DataBufferMemoryMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataBufferMemoryMap.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataBufferMemoryMap.cpp (original)
+++ lldb/trunk/source/Core/DataBufferMemoryMap.cpp Tue Sep 6 15:57:50 2016
@@ -17,7 +17,7 @@
#define MAP_EXTRA_HOST_READ_FLAGS 0
-#if defined (__APPLE__)
+#if defined(__APPLE__)
//----------------------------------------------------------------------
// Newer versions of MacOSX have a flag that will allow us to read from
// binaries whose code signature is invalid without crashing by using
@@ -27,12 +27,12 @@
// MAP_RESILIENT_MEDIA flag.
//----------------------------------------------------------------------
#if defined(MAP_RESILIENT_CODESIGN)
- #undef MAP_EXTRA_HOST_READ_FLAGS
- #if defined(MAP_RESILIENT_MEDIA)
- #define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN | MAP_RESILIENT_MEDIA
- #else
- #define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN
- #endif
+#undef MAP_EXTRA_HOST_READ_FLAGS
+#if defined(MAP_RESILIENT_MEDIA)
+#define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN | MAP_RESILIENT_MEDIA
+#else
+#define MAP_EXTRA_HOST_READ_FLAGS MAP_RESILIENT_CODESIGN
+#endif
#endif // #if defined(MAP_RESILIENT_CODESIGN)
#endif // #if defined (__APPLE__)
@@ -47,10 +47,10 @@
// Project includes
#include "lldb/Core/DataBufferMemoryMap.h"
#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
#include "lldb/Host/File.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Host/HostInfo.h"
-#include "lldb/Core/Log.h"
using namespace lldb;
using namespace lldb_private;
@@ -58,75 +58,53 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// Default Constructor
//----------------------------------------------------------------------
-DataBufferMemoryMap::DataBufferMemoryMap() :
- m_mmap_addr(nullptr),
- m_mmap_size(0),
- m_data(nullptr),
- m_size(0)
-{
-}
+DataBufferMemoryMap::DataBufferMemoryMap()
+ : m_mmap_addr(nullptr), m_mmap_size(0), m_data(nullptr), m_size(0) {}
//----------------------------------------------------------------------
// Virtual destructor since this class inherits from a pure virtual
// base class.
//----------------------------------------------------------------------
-DataBufferMemoryMap::~DataBufferMemoryMap()
-{
- Clear();
-}
+DataBufferMemoryMap::~DataBufferMemoryMap() { Clear(); }
//----------------------------------------------------------------------
// Return a pointer to the bytes owned by this object, or nullptr if
// the object contains no bytes.
//----------------------------------------------------------------------
-uint8_t *
-DataBufferMemoryMap::GetBytes()
-{
- return m_data;
-}
+uint8_t *DataBufferMemoryMap::GetBytes() { return m_data; }
//----------------------------------------------------------------------
// Return a const pointer to the bytes owned by this object, or nullptr
// if the object contains no bytes.
//----------------------------------------------------------------------
-const uint8_t *
-DataBufferMemoryMap::GetBytes() const
-{
- return m_data;
-}
+const uint8_t *DataBufferMemoryMap::GetBytes() const { return m_data; }
//----------------------------------------------------------------------
// Return the number of bytes this object currently contains.
//----------------------------------------------------------------------
-uint64_t
-DataBufferMemoryMap::GetByteSize() const
-{
- return m_size;
-}
+uint64_t DataBufferMemoryMap::GetByteSize() const { return m_size; }
//----------------------------------------------------------------------
// Reverts this object to an empty state by unmapping any memory
// that is currently owned.
//----------------------------------------------------------------------
-void
-DataBufferMemoryMap::Clear()
-{
- if (m_mmap_addr != nullptr)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
- if (log)
- log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size = %" PRIu64 "", (void *)m_mmap_addr,
- (uint64_t)m_mmap_size);
+void DataBufferMemoryMap::Clear() {
+ if (m_mmap_addr != nullptr) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP));
+ if (log)
+ log->Printf("DataBufferMemoryMap::Clear() m_mmap_addr = %p, m_mmap_size "
+ "= %" PRIu64 "",
+ (void *)m_mmap_addr, (uint64_t)m_mmap_size);
#ifdef _WIN32
- UnmapViewOfFile(m_mmap_addr);
+ UnmapViewOfFile(m_mmap_addr);
#else
- ::munmap((void *)m_mmap_addr, m_mmap_size);
+ ::munmap((void *)m_mmap_addr, m_mmap_size);
#endif
- m_mmap_addr = nullptr;
- m_mmap_size = 0;
- m_data = nullptr;
- m_size = 0;
- }
+ m_mmap_addr = nullptr;
+ m_mmap_size = 0;
+ m_data = nullptr;
+ m_size = 0;
+ }
}
//----------------------------------------------------------------------
@@ -137,48 +115,41 @@ DataBufferMemoryMap::Clear()
// Returns the number of bytes mapped starting from the requested
// offset.
//----------------------------------------------------------------------
-size_t
-DataBufferMemoryMap::MemoryMapFromFileSpec (const FileSpec* filespec,
- lldb::offset_t offset,
- size_t length,
- bool writeable)
-{
- if (filespec != nullptr)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP));
- if (log)
- {
- log->Printf("DataBufferMemoryMap::MemoryMapFromFileSpec(file=\"%s\", offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i",
- filespec->GetPath().c_str(),
- offset,
- (uint64_t)length,
- writeable);
- }
- char path[PATH_MAX];
- if (filespec->GetPath(path, sizeof(path)))
- {
- uint32_t options = File::eOpenOptionRead;
- if (writeable)
- options |= File::eOpenOptionWrite;
-
- 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 @@ void LoadWin32MemMapAlignment ()
// RETURNS
// Number of bytes mapped starting from the requested offset.
//----------------------------------------------------------------------
-size_t
-DataBufferMemoryMap::MemoryMapFromFileDescriptor (int fd,
- lldb::offset_t offset,
- size_t length,
- bool writeable,
- bool fd_is_file)
-{
- Clear();
- if (fd >= 0)
- {
- Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_MMAP|LIBLLDB_LOG_VERBOSE));
- if (log)
- {
- log->Printf("DataBufferMemoryMap::MemoryMapFromFileDescriptor(fd=%i, offset=0x%" PRIx64 ", length=0x%" PRIx64 ", writeable=%i, fd_is_file=%i)",
- fd,
- offset,
- (uint64_t)length,
- writeable,
- fd_is_file);
- }
+size_t DataBufferMemoryMap::MemoryMapFromFileDescriptor(int fd,
+ lldb::offset_t offset,
+ size_t length,
+ bool writeable,
+ bool fd_is_file) {
+ Clear();
+ if (fd >= 0) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MMAP |
+ LIBLLDB_LOG_VERBOSE));
+ if (log) {
+ log->Printf("DataBufferMemoryMap::MemoryMapFromFileDescriptor(fd=%i, "
+ "offset=0x%" PRIx64 ", length=0x%" PRIx64
+ ", writeable=%i, fd_is_file=%i)",
+ fd, offset, (uint64_t)length, writeable, fd_is_file);
+ }
#ifdef _WIN32
- HANDLE handle = (HANDLE)_get_osfhandle(fd);
- DWORD file_size_low, file_size_high;
- file_size_low = GetFileSize(handle, &file_size_high);
- const lldb::offset_t file_size = llvm::Make_64(file_size_high, file_size_low);
- const lldb::offset_t max_bytes_available = file_size - offset;
- const size_t max_bytes_mappable = (size_t)std::min<lldb::offset_t>(SIZE_MAX, max_bytes_available);
- if (length == SIZE_MAX || length > max_bytes_mappable)
- {
- // Cap the length if too much data was requested
- length = max_bytes_mappable;
+ HANDLE handle = (HANDLE)_get_osfhandle(fd);
+ DWORD file_size_low, file_size_high;
+ file_size_low = GetFileSize(handle, &file_size_high);
+ const lldb::offset_t file_size =
+ llvm::Make_64(file_size_high, file_size_low);
+ const lldb::offset_t max_bytes_available = file_size - offset;
+ const size_t max_bytes_mappable =
+ (size_t)std::min<lldb::offset_t>(SIZE_MAX, max_bytes_available);
+ if (length == SIZE_MAX || length > max_bytes_mappable) {
+ // Cap the length if too much data was requested
+ length = max_bytes_mappable;
+ }
+
+ if (length > 0) {
+ HANDLE fileMapping = CreateFileMapping(
+ handle, nullptr, writeable ? PAGE_READWRITE : PAGE_READONLY,
+ file_size_high, file_size_low, nullptr);
+ if (fileMapping != nullptr) {
+ if (win32memmapalignment == 0)
+ LoadWin32MemMapAlignment();
+ lldb::offset_t realoffset = offset;
+ lldb::offset_t delta = 0;
+ if (realoffset % win32memmapalignment != 0) {
+ realoffset = realoffset / win32memmapalignment * win32memmapalignment;
+ delta = offset - realoffset;
}
- if (length > 0)
- {
- HANDLE fileMapping = CreateFileMapping(handle, nullptr, writeable ? PAGE_READWRITE : PAGE_READONLY, file_size_high, file_size_low, nullptr);
- if (fileMapping != nullptr)
- {
- if (win32memmapalignment == 0) LoadWin32MemMapAlignment();
- lldb::offset_t realoffset = offset;
- lldb::offset_t delta = 0;
- if (realoffset % win32memmapalignment != 0) {
- realoffset = realoffset / win32memmapalignment * win32memmapalignment;
- delta = offset - realoffset;
- }
-
- LPVOID data = MapViewOfFile(fileMapping, writeable ? FILE_MAP_WRITE : FILE_MAP_READ, 0, realoffset, length + delta);
- m_mmap_addr = (uint8_t *)data;
- if (!data) {
- Error error;
- error.SetErrorToErrno ();
- } else {
- m_data = m_mmap_addr + delta;
- m_size = length;
- }
- CloseHandle(fileMapping);
- }
+ LPVOID data = MapViewOfFile(fileMapping,
+ writeable ? FILE_MAP_WRITE : FILE_MAP_READ,
+ 0, realoffset, length + delta);
+ m_mmap_addr = (uint8_t *)data;
+ if (!data) {
+ Error error;
+ error.SetErrorToErrno();
+ } else {
+ m_data = m_mmap_addr + delta;
+ m_size = length;
}
+ CloseHandle(fileMapping);
+ }
+ }
#else
- struct stat stat;
- if (::fstat(fd, &stat) == 0)
- {
- if (S_ISREG(stat.st_mode) &&
- (stat.st_size > static_cast<off_t>(offset)))
- {
- const size_t max_bytes_available = stat.st_size - offset;
- if (length == SIZE_MAX)
- {
- length = max_bytes_available;
- }
- else if (length > max_bytes_available)
- {
- // Cap the length if too much data was requested
- length = max_bytes_available;
- }
+ struct stat stat;
+ if (::fstat(fd, &stat) == 0) {
+ if (S_ISREG(stat.st_mode) &&
+ (stat.st_size > static_cast<off_t>(offset))) {
+ const size_t max_bytes_available = stat.st_size - offset;
+ if (length == SIZE_MAX) {
+ length = max_bytes_available;
+ } else if (length > max_bytes_available) {
+ // Cap the length if too much data was requested
+ length = max_bytes_available;
+ }
- if (length > 0)
- {
- int prot = PROT_READ;
- int flags = MAP_PRIVATE;
- if (writeable)
- prot |= PROT_WRITE;
- else
- flags |= MAP_EXTRA_HOST_READ_FLAGS;
-
- if (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 (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());
+ }
}
-#endif
+ }
}
- return GetByteSize ();
+#endif
+ }
+ return GetByteSize();
}
Modified: lldb/trunk/source/Core/DataEncoder.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataEncoder.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataEncoder.cpp (original)
+++ lldb/trunk/source/Core/DataEncoder.cpp Tue Sep 6 15:57:50 2016
@@ -24,66 +24,52 @@
using namespace lldb;
using namespace lldb_private;
-static inline void
-WriteInt16(unsigned char* ptr, unsigned offset, uint16_t value)
-{
- *(uint16_t *)(ptr + offset) = value;
+static inline void WriteInt16(unsigned char *ptr, unsigned offset,
+ uint16_t value) {
+ *(uint16_t *)(ptr + offset) = value;
}
-static inline void
-WriteInt32 (unsigned char* ptr, unsigned offset, uint32_t value)
-{
- *(uint32_t *)(ptr + offset) = value;
+static inline void WriteInt32(unsigned char *ptr, unsigned offset,
+ uint32_t value) {
+ *(uint32_t *)(ptr + offset) = value;
}
-static inline void
-WriteInt64(unsigned char* ptr, unsigned offset, uint64_t value)
-{
- *(uint64_t *)(ptr + offset) = value;
+static inline void WriteInt64(unsigned char *ptr, unsigned offset,
+ uint64_t value) {
+ *(uint64_t *)(ptr + offset) = value;
}
-static inline void
-WriteSwappedInt16(unsigned char* ptr, unsigned offset, uint16_t value)
-{
- *(uint16_t *)(ptr + offset) = llvm::ByteSwap_16(value);
+static inline void WriteSwappedInt16(unsigned char *ptr, unsigned offset,
+ uint16_t value) {
+ *(uint16_t *)(ptr + offset) = llvm::ByteSwap_16(value);
}
-static inline void
-WriteSwappedInt32 (unsigned char* ptr, unsigned offset, uint32_t value)
-{
- *(uint32_t *)(ptr + offset) = llvm::ByteSwap_32(value);
+static inline void WriteSwappedInt32(unsigned char *ptr, unsigned offset,
+ uint32_t value) {
+ *(uint32_t *)(ptr + offset) = llvm::ByteSwap_32(value);
}
-static inline void
-WriteSwappedInt64(unsigned char* ptr, unsigned offset, uint64_t value)
-{
- *(uint64_t *)(ptr + offset) = llvm::ByteSwap_64(value);
+static inline void WriteSwappedInt64(unsigned char *ptr, unsigned offset,
+ uint64_t value) {
+ *(uint64_t *)(ptr + offset) = llvm::ByteSwap_64(value);
}
//----------------------------------------------------------------------
// Default constructor.
//----------------------------------------------------------------------
-DataEncoder::DataEncoder () :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(endian::InlHostByteOrder()),
- m_addr_size(sizeof(void*)),
- m_data_sp()
-{
-}
+DataEncoder::DataEncoder()
+ : m_start(nullptr), m_end(nullptr),
+ m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
+ m_data_sp() {}
//----------------------------------------------------------------------
// This constructor allows us to use data that is owned by someone else.
// The data must stay around as long as this object is valid.
//----------------------------------------------------------------------
-DataEncoder::DataEncoder (void* data, uint32_t length, ByteOrder endian, uint8_t addr_size) :
- m_start ((uint8_t*)data),
- m_end ((uint8_t*)data + length),
- m_byte_order(endian),
- m_addr_size (addr_size),
- m_data_sp ()
-{
-}
+DataEncoder::DataEncoder(void *data, uint32_t length, ByteOrder endian,
+ uint8_t addr_size)
+ : m_start((uint8_t *)data), m_end((uint8_t *)data + length),
+ m_byte_order(endian), m_addr_size(addr_size), m_data_sp() {}
//----------------------------------------------------------------------
// Make a shared pointer reference to the shared data in "data_sp" and
@@ -92,14 +78,11 @@ DataEncoder::DataEncoder (void* data, ui
// as long as any DataEncoder objects exist that have a reference to
// this data.
//----------------------------------------------------------------------
-DataEncoder::DataEncoder (const DataBufferSP& data_sp, ByteOrder endian, uint8_t addr_size) :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(endian),
- m_addr_size(addr_size),
- m_data_sp()
-{
- SetData (data_sp);
+DataEncoder::DataEncoder(const DataBufferSP &data_sp, ByteOrder endian,
+ uint8_t addr_size)
+ : m_start(nullptr), m_end(nullptr), m_byte_order(endian),
+ m_addr_size(addr_size), m_data_sp() {
+ SetData(data_sp);
}
DataEncoder::~DataEncoder() = default;
@@ -109,37 +92,30 @@ DataEncoder::~DataEncoder() = default;
// release any references to shared data that this object may
// contain.
//------------------------------------------------------------------
-void
-DataEncoder::Clear ()
-{
- m_start = nullptr;
- m_end = nullptr;
- m_byte_order = endian::InlHostByteOrder();
- m_addr_size = sizeof(void*);
- m_data_sp.reset();
+void DataEncoder::Clear() {
+ m_start = nullptr;
+ m_end = nullptr;
+ m_byte_order = endian::InlHostByteOrder();
+ m_addr_size = sizeof(void *);
+ m_data_sp.reset();
}
//------------------------------------------------------------------
// If this object contains shared data, this function returns the
// offset into that shared data. Else zero is returned.
//------------------------------------------------------------------
-size_t
-DataEncoder::GetSharedDataOffset () const
-{
- if (m_start != nullptr)
- {
- const DataBuffer * data = m_data_sp.get();
- if (data != nullptr)
- {
- const uint8_t * data_bytes = data->GetBytes();
- if (data_bytes != nullptr)
- {
- assert(m_start >= data_bytes);
- return m_start - data_bytes;
- }
- }
+size_t DataEncoder::GetSharedDataOffset() const {
+ if (m_start != nullptr) {
+ const DataBuffer *data = m_data_sp.get();
+ if (data != nullptr) {
+ const uint8_t *data_bytes = data->GetBytes();
+ if (data_bytes != nullptr) {
+ assert(m_start >= data_bytes);
+ return m_start - data_bytes;
+ }
}
- return 0;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -152,22 +128,17 @@ DataEncoder::GetSharedDataOffset () cons
// reference to that data will be released. Is SWAP is set to true,
// any data extracted will be endian swapped.
//----------------------------------------------------------------------
-uint32_t
-DataEncoder::SetData (void *bytes, uint32_t length, ByteOrder endian)
-{
- m_byte_order = endian;
- m_data_sp.reset();
- if (bytes == nullptr || length == 0)
- {
- m_start = nullptr;
- m_end = nullptr;
- }
- else
- {
- m_start = (uint8_t *)bytes;
- m_end = m_start + length;
- }
- return GetByteSize();
+uint32_t DataEncoder::SetData(void *bytes, uint32_t length, ByteOrder endian) {
+ m_byte_order = endian;
+ m_data_sp.reset();
+ if (bytes == nullptr || length == 0) {
+ m_start = nullptr;
+ m_end = nullptr;
+ } else {
+ m_start = (uint8_t *)bytes;
+ m_end = m_start + length;
+ }
+ return GetByteSize();
}
//----------------------------------------------------------------------
@@ -184,38 +155,35 @@ DataEncoder::SetData (void *bytes, uint3
// around as long as it is needed. The address size and endian swap
// settings will remain unchanged from their current settings.
//----------------------------------------------------------------------
-uint32_t
-DataEncoder::SetData (const DataBufferSP& data_sp, uint32_t data_offset, uint32_t data_length)
-{
- m_start = m_end = nullptr;
-
- if (data_length > 0)
- {
- m_data_sp = data_sp;
- if (data_sp)
- {
- const size_t data_size = data_sp->GetByteSize();
- if (data_offset < data_size)
- {
- m_start = data_sp->GetBytes() + data_offset;
- const size_t bytes_left = data_size - data_offset;
- // Cap the length of we asked for too many
- if (data_length <= bytes_left)
- m_end = m_start + data_length; // We got all the bytes we wanted
- else
- m_end = m_start + bytes_left; // Not all the bytes requested were available in the shared data
- }
- }
+uint32_t DataEncoder::SetData(const DataBufferSP &data_sp, uint32_t data_offset,
+ uint32_t data_length) {
+ m_start = m_end = nullptr;
+
+ if (data_length > 0) {
+ m_data_sp = data_sp;
+ if (data_sp) {
+ const size_t data_size = data_sp->GetByteSize();
+ if (data_offset < data_size) {
+ m_start = data_sp->GetBytes() + data_offset;
+ const size_t bytes_left = data_size - data_offset;
+ // Cap the length of we asked for too many
+ if (data_length <= bytes_left)
+ m_end = m_start + data_length; // We got all the bytes we wanted
+ else
+ m_end = m_start + bytes_left; // Not all the bytes requested were
+ // available in the shared data
+ }
}
+ }
- uint32_t new_size = GetByteSize();
+ uint32_t new_size = GetByteSize();
- // Don't hold a shared pointer to the data buffer if we don't share
- // any valid bytes in the shared buffer.
- if (new_size == 0)
- m_data_sp.reset();
+ // Don't hold a shared pointer to the data buffer if we don't share
+ // any valid bytes in the shared buffer.
+ if (new_size == 0)
+ m_data_sp.reset();
- return new_size;
+ return new_size;
}
//----------------------------------------------------------------------
@@ -224,60 +192,48 @@ DataEncoder::SetData (const DataBufferSP
//
// RETURNS the byte that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint32_t
-DataEncoder::PutU8 (uint32_t offset, uint8_t value)
-{
- if (ValidOffset(offset))
- {
- m_start[offset] = value;
- return offset + 1;
- }
- return UINT32_MAX;
+uint32_t DataEncoder::PutU8(uint32_t offset, uint8_t value) {
+ if (ValidOffset(offset)) {
+ m_start[offset] = value;
+ return offset + 1;
+ }
+ return UINT32_MAX;
}
-uint32_t
-DataEncoder::PutU16 (uint32_t offset, uint16_t value)
-{
- if (ValidOffsetForDataOfSize(offset, sizeof(value)))
- {
- if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt16 (m_start, offset, value);
- else
- WriteInt16 (m_start, offset, value);
+uint32_t DataEncoder::PutU16(uint32_t offset, uint16_t value) {
+ if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
+ if (m_byte_order != endian::InlHostByteOrder())
+ WriteSwappedInt16(m_start, offset, value);
+ else
+ WriteInt16(m_start, offset, value);
- return offset + sizeof (value);
- }
- return UINT32_MAX;
+ return offset + sizeof(value);
+ }
+ return UINT32_MAX;
}
-uint32_t
-DataEncoder::PutU32 (uint32_t offset, uint32_t value)
-{
- if (ValidOffsetForDataOfSize(offset, sizeof(value)))
- {
- if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt32 (m_start, offset, value);
- else
- WriteInt32 (m_start, offset, value);
-
- return offset + sizeof (value);
- }
- return UINT32_MAX;
+uint32_t DataEncoder::PutU32(uint32_t offset, uint32_t value) {
+ if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
+ if (m_byte_order != endian::InlHostByteOrder())
+ WriteSwappedInt32(m_start, offset, value);
+ else
+ WriteInt32(m_start, offset, value);
+
+ return offset + sizeof(value);
+ }
+ return UINT32_MAX;
}
-uint32_t
-DataEncoder::PutU64 (uint32_t offset, uint64_t value)
-{
- if (ValidOffsetForDataOfSize(offset, sizeof(value)))
- {
- if (m_byte_order != endian::InlHostByteOrder())
- WriteSwappedInt64 (m_start, offset, value);
- else
- WriteInt64 (m_start, offset, value);
-
- return offset + sizeof (value);
- }
- return UINT32_MAX;
+uint32_t DataEncoder::PutU64(uint32_t offset, uint64_t value) {
+ if (ValidOffsetForDataOfSize(offset, sizeof(value))) {
+ if (m_byte_order != endian::InlHostByteOrder())
+ WriteSwappedInt64(m_start, offset, value);
+ else
+ WriteInt64(m_start, offset, value);
+
+ return offset + sizeof(value);
+ }
+ return UINT32_MAX;
}
//----------------------------------------------------------------------
@@ -290,46 +246,42 @@ DataEncoder::PutU64 (uint32_t offset, ui
//
// 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::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;
-}
-
-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::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;
+
+ 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::PutCString(uint32_t offset, const char *cstr) {
+ if (cstr != nullptr)
+ return PutData(offset, cstr, strlen(cstr) + 1);
+ return UINT32_MAX;
}
Modified: lldb/trunk/source/Core/DataExtractor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/DataExtractor.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/DataExtractor.cpp (original)
+++ lldb/trunk/source/Core/DataExtractor.cpp Tue Sep 6 15:57:50 2016
@@ -11,8 +11,8 @@
// C++ Includes
#include <bitset>
#include <cassert>
-#include <cstddef>
#include <cmath>
+#include <cstddef>
#include <sstream>
#include <string>
@@ -21,15 +21,15 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MD5.h"
+#include "llvm/Support/MathExtras.h"
#include "clang/AST/ASTContext.h"
// Project includes
+#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/DataExtractor.h"
-#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
@@ -46,112 +46,92 @@
using namespace lldb;
using namespace lldb_private;
-static inline uint16_t
-ReadInt16(const unsigned char* ptr, offset_t offset)
-{
- uint16_t value;
- memcpy (&value, ptr + offset, 2);
- return value;
+static inline uint16_t ReadInt16(const unsigned char *ptr, offset_t offset) {
+ uint16_t value;
+ memcpy(&value, ptr + offset, 2);
+ return value;
}
-static inline uint32_t
-ReadInt32 (const unsigned char* ptr, offset_t offset = 0)
-{
- uint32_t value;
- memcpy (&value, ptr + offset, 4);
- return value;
+static inline uint32_t ReadInt32(const unsigned char *ptr,
+ offset_t offset = 0) {
+ uint32_t value;
+ memcpy(&value, ptr + offset, 4);
+ return value;
}
-static inline uint64_t
-ReadInt64(const unsigned char* ptr, offset_t offset = 0)
-{
- uint64_t value;
- memcpy (&value, ptr + offset, 8);
- return value;
+static inline uint64_t ReadInt64(const unsigned char *ptr,
+ offset_t offset = 0) {
+ uint64_t value;
+ memcpy(&value, ptr + offset, 8);
+ return value;
}
-static inline uint16_t
-ReadInt16(const void* ptr)
-{
- uint16_t value;
- memcpy (&value, ptr, 2);
- return value;
+static inline uint16_t ReadInt16(const void *ptr) {
+ uint16_t value;
+ memcpy(&value, ptr, 2);
+ return value;
}
-static inline uint16_t
-ReadSwapInt16(const unsigned char* ptr, offset_t offset)
-{
- uint16_t value;
- memcpy (&value, ptr + offset, 2);
- return llvm::ByteSwap_16(value);
+static inline uint16_t ReadSwapInt16(const unsigned char *ptr,
+ offset_t offset) {
+ uint16_t value;
+ memcpy(&value, ptr + offset, 2);
+ return llvm::ByteSwap_16(value);
}
-static inline uint32_t
-ReadSwapInt32 (const unsigned char* ptr, offset_t offset)
-{
- uint32_t value;
- memcpy (&value, ptr + offset, 4);
- return llvm::ByteSwap_32(value);
+static inline uint32_t ReadSwapInt32(const unsigned char *ptr,
+ offset_t offset) {
+ uint32_t value;
+ memcpy(&value, ptr + offset, 4);
+ return llvm::ByteSwap_32(value);
}
-static inline uint64_t
-ReadSwapInt64(const unsigned char* ptr, offset_t offset)
-{
- uint64_t value;
- memcpy (&value, ptr + offset, 8);
- return llvm::ByteSwap_64(value);
+static inline uint64_t ReadSwapInt64(const unsigned char *ptr,
+ offset_t offset) {
+ uint64_t value;
+ memcpy(&value, ptr + offset, 8);
+ return llvm::ByteSwap_64(value);
}
-static inline uint16_t
-ReadSwapInt16(const void* ptr)
-{
- uint16_t value;
- memcpy (&value, ptr, 2);
- return llvm::ByteSwap_16(value);
+static inline uint16_t ReadSwapInt16(const void *ptr) {
+ uint16_t value;
+ memcpy(&value, ptr, 2);
+ return llvm::ByteSwap_16(value);
}
-static inline uint32_t
-ReadSwapInt32 (const void* ptr)
-{
- uint32_t value;
- memcpy (&value, ptr, 4);
- return llvm::ByteSwap_32(value);
+static inline uint32_t ReadSwapInt32(const void *ptr) {
+ uint32_t value;
+ memcpy(&value, ptr, 4);
+ return llvm::ByteSwap_32(value);
}
-static inline uint64_t
-ReadSwapInt64(const void* ptr)
-{
- uint64_t value;
- memcpy (&value, ptr, 8);
- return llvm::ByteSwap_64(value);
+static inline uint64_t ReadSwapInt64(const void *ptr) {
+ uint64_t value;
+ memcpy(&value, ptr, 8);
+ return llvm::ByteSwap_64(value);
}
#define NON_PRINTABLE_CHAR '.'
-DataExtractor::DataExtractor () :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(endian::InlHostByteOrder()),
- m_addr_size(sizeof(void *)),
- m_data_sp(),
- m_target_byte_size(1)
-{
-}
+DataExtractor::DataExtractor()
+ : m_start(nullptr), m_end(nullptr),
+ m_byte_order(endian::InlHostByteOrder()), m_addr_size(sizeof(void *)),
+ m_data_sp(), m_target_byte_size(1) {}
//----------------------------------------------------------------------
// This constructor allows us to use data that is owned by someone else.
// The data must stay around as long as this object is valid.
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const void* data, offset_t length, ByteOrder endian, uint32_t addr_size, uint32_t target_byte_size/*=1*/) :
- m_start (const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data))),
- m_end (const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data)) + length),
- m_byte_order(endian),
- m_addr_size (addr_size),
- m_data_sp (),
- m_target_byte_size(target_byte_size)
-{
+DataExtractor::DataExtractor(const void *data, offset_t length,
+ ByteOrder endian, uint32_t addr_size,
+ uint32_t target_byte_size /*=1*/)
+ : m_start(const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data))),
+ m_end(const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(data)) +
+ length),
+ m_byte_order(endian), m_addr_size(addr_size), m_data_sp(),
+ m_target_byte_size(target_byte_size) {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (addr_size == 4 || addr_size == 8);
+ assert(addr_size == 4 || addr_size == 8);
#endif
}
@@ -162,18 +142,16 @@ DataExtractor::DataExtractor (const void
// as long as any DataExtractor objects exist that have a reference to
// this data.
//----------------------------------------------------------------------
-DataExtractor::DataExtractor (const DataBufferSP& data_sp, ByteOrder endian, uint32_t addr_size, uint32_t target_byte_size/*=1*/) :
- m_start(nullptr),
- m_end(nullptr),
- m_byte_order(endian),
- m_addr_size(addr_size),
- m_data_sp(),
- m_target_byte_size(target_byte_size)
-{
+DataExtractor::DataExtractor(const DataBufferSP &data_sp, ByteOrder endian,
+ uint32_t addr_size,
+ uint32_t target_byte_size /*=1*/)
+ : m_start(nullptr), m_end(nullptr), m_byte_order(endian),
+ m_addr_size(addr_size), m_data_sp(),
+ m_target_byte_size(target_byte_size) {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (addr_size == 4 || addr_size == 8);
+ assert(addr_size == 4 || addr_size == 8);
#endif
- SetData (data_sp);
+ SetData(data_sp);
}
//----------------------------------------------------------------------
@@ -183,54 +161,43 @@ DataExtractor::DataExtractor (const Data
// 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 @@ DataExtractor::~DataExtractor() = defaul
// release any references to shared data that this object may
// contain.
//------------------------------------------------------------------
-void
-DataExtractor::Clear ()
-{
- m_start = nullptr;
- m_end = nullptr;
- m_byte_order = endian::InlHostByteOrder();
- m_addr_size = sizeof(void *);
- m_data_sp.reset();
+void DataExtractor::Clear() {
+ m_start = nullptr;
+ m_end = nullptr;
+ m_byte_order = endian::InlHostByteOrder();
+ m_addr_size = sizeof(void *);
+ m_data_sp.reset();
}
//------------------------------------------------------------------
// If this object contains shared data, this function returns the
// offset into that shared data. Else zero is returned.
//------------------------------------------------------------------
-size_t
-DataExtractor::GetSharedDataOffset () const
-{
- if (m_start != nullptr)
- {
- const DataBuffer * data = m_data_sp.get();
- if (data != nullptr)
- {
- const uint8_t * data_bytes = data->GetBytes();
- if (data_bytes != nullptr)
- {
- assert(m_start >= data_bytes);
- return m_start - data_bytes;
- }
- }
+size_t DataExtractor::GetSharedDataOffset() const {
+ if (m_start != nullptr) {
+ const DataBuffer *data = m_data_sp.get();
+ if (data != nullptr) {
+ const uint8_t *data_bytes = data->GetBytes();
+ if (data_bytes != nullptr) {
+ assert(m_start >= data_bytes);
+ return m_start - data_bytes;
+ }
}
- return 0;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -283,22 +243,18 @@ DataExtractor::GetSharedDataOffset () co
// reference to that data will be released. Is SWAP is set to true,
// any data extracted will be endian swapped.
//----------------------------------------------------------------------
-lldb::offset_t
-DataExtractor::SetData (const void *bytes, offset_t length, ByteOrder endian)
-{
- m_byte_order = endian;
- m_data_sp.reset();
- if (bytes == nullptr || length == 0)
- {
- m_start = nullptr;
- m_end = nullptr;
- }
- else
- {
- m_start = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(bytes));
- m_end = m_start + length;
- }
- return GetByteSize();
+lldb::offset_t DataExtractor::SetData(const void *bytes, offset_t length,
+ ByteOrder endian) {
+ m_byte_order = endian;
+ m_data_sp.reset();
+ if (bytes == nullptr || length == 0) {
+ m_start = nullptr;
+ m_end = nullptr;
+ } else {
+ m_start = const_cast<uint8_t *>(reinterpret_cast<const uint8_t *>(bytes));
+ m_end = m_start + length;
+ }
+ return GetByteSize();
}
//----------------------------------------------------------------------
@@ -315,28 +271,28 @@ DataExtractor::SetData (const void *byte
// refers to those bytes. The address size and endian swap settings
// are copied from the current values in "data".
//----------------------------------------------------------------------
-lldb::offset_t
-DataExtractor::SetData (const DataExtractor& data, offset_t data_offset, offset_t data_length)
-{
- m_addr_size = data.m_addr_size;
+lldb::offset_t DataExtractor::SetData(const DataExtractor &data,
+ offset_t data_offset,
+ offset_t data_length) {
+ m_addr_size = data.m_addr_size;
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
- // If "data" contains shared pointer to data, then we can use that
- if (data.m_data_sp)
- {
- m_byte_order = data.m_byte_order;
- return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset, data_length);
- }
-
- // We have a DataExtractor object that just has a pointer to bytes
- if (data.ValidOffset(data_offset))
- {
- if (data_length > data.GetByteSize() - data_offset)
- data_length = data.GetByteSize() - data_offset;
- return SetData (data.GetDataStart() + data_offset, data_length, data.GetByteOrder());
- }
- return 0;
+ // If "data" contains shared pointer to data, then we can use that
+ if (data.m_data_sp) {
+ m_byte_order = data.m_byte_order;
+ return SetData(data.m_data_sp, data.GetSharedDataOffset() + data_offset,
+ data_length);
+ }
+
+ // We have a DataExtractor object that just has a pointer to bytes
+ if (data.ValidOffset(data_offset)) {
+ if (data_length > data.GetByteSize() - data_offset)
+ data_length = data.GetByteSize() - data_offset;
+ return SetData(data.GetDataStart() + data_offset, data_length,
+ data.GetByteOrder());
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -353,38 +309,36 @@ DataExtractor::SetData (const DataExtrac
// around as long as it is needed. The address size and endian swap
// settings will remain unchanged from their current settings.
//----------------------------------------------------------------------
-lldb::offset_t
-DataExtractor::SetData (const DataBufferSP& data_sp, offset_t data_offset, offset_t data_length)
-{
- m_start = m_end = nullptr;
-
- if (data_length > 0)
- {
- m_data_sp = data_sp;
- if (data_sp)
- {
- const size_t data_size = data_sp->GetByteSize();
- if (data_offset < data_size)
- {
- m_start = data_sp->GetBytes() + data_offset;
- const size_t bytes_left = data_size - data_offset;
- // Cap the length of we asked for too many
- if (data_length <= bytes_left)
- m_end = m_start + data_length; // We got all the bytes we wanted
- else
- m_end = m_start + bytes_left; // Not all the bytes requested were available in the shared data
- }
- }
+lldb::offset_t DataExtractor::SetData(const DataBufferSP &data_sp,
+ offset_t data_offset,
+ offset_t data_length) {
+ m_start = m_end = nullptr;
+
+ if (data_length > 0) {
+ m_data_sp = data_sp;
+ if (data_sp) {
+ const size_t data_size = data_sp->GetByteSize();
+ if (data_offset < data_size) {
+ m_start = data_sp->GetBytes() + data_offset;
+ const size_t bytes_left = data_size - data_offset;
+ // Cap the length of we asked for too many
+ if (data_length <= bytes_left)
+ m_end = m_start + data_length; // We got all the bytes we wanted
+ else
+ m_end = m_start + bytes_left; // Not all the bytes requested were
+ // available in the shared data
+ }
}
+ }
- size_t new_size = GetByteSize();
+ size_t new_size = GetByteSize();
- // Don't hold a shared pointer to the data buffer if we don't share
- // any valid bytes in the shared buffer.
- if (new_size == 0)
- m_data_sp.reset();
+ // Don't hold a shared pointer to the data buffer if we don't share
+ // any valid bytes in the shared buffer.
+ if (new_size == 0)
+ m_data_sp.reset();
- return new_size;
+ return new_size;
}
//----------------------------------------------------------------------
@@ -393,13 +347,11 @@ DataExtractor::SetData (const DataBuffer
//
// RETURNS the byte that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint8_t
-DataExtractor::GetU8 (offset_t *offset_ptr) const
-{
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, 1);
- if (data)
- return *data;
- return 0;
+uint8_t DataExtractor::GetU8(offset_t *offset_ptr) const {
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, 1);
+ if (data)
+ return *data;
+ return 0;
}
//----------------------------------------------------------------------
@@ -411,18 +363,17 @@ DataExtractor::GetU8 (offset_t *offset_p
// all the requested bytes, or nullptr when the data is not available in
// the buffer due to being out of bounds, or insufficient data.
//----------------------------------------------------------------------
-void *
-DataExtractor::GetU8 (offset_t *offset_ptr, void *dst, uint32_t count) const
-{
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, count);
- if (data)
- {
- // Copy the data into the buffer
- memcpy (dst, data, count);
- // Return a non-nullptr pointer to the converted data as an indicator of success
- return dst;
- }
- return nullptr;
+void *DataExtractor::GetU8(offset_t *offset_ptr, void *dst,
+ uint32_t count) const {
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, count);
+ if (data) {
+ // Copy the data into the buffer
+ memcpy(dst, data, count);
+ // Return a non-nullptr pointer to the converted data as an indicator of
+ // success
+ return dst;
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -431,55 +382,46 @@ DataExtractor::GetU8 (offset_t *offset_p
//
// 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_unchecked (offset_t *offset_ptr) const
-{
- uint16_t val;
- if (m_byte_order == endian::InlHostByteOrder())
- val = ReadInt16 (m_start, *offset_ptr);
+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 = 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;
-}
-
-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;
+ 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;
+}
+
+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;
}
//----------------------------------------------------------------------
@@ -491,33 +433,28 @@ DataExtractor::GetU64_unchecked (offset_
// 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;
- }
- return nullptr;
+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;
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -526,23 +463,17 @@ DataExtractor::GetU16 (offset_t *offset_
//
// RETURNS the uint32_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::GetU32 (offset_t *offset_ptr) const
-{
- uint32_t val = 0;
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
- if (data)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- val = ReadSwapInt32 (data);
- }
- else
- {
- memcpy (&val, data, 4);
- }
+uint32_t DataExtractor::GetU32(offset_t *offset_ptr) const {
+ uint32_t val = 0;
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val));
+ if (data) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ val = ReadSwapInt32(data);
+ } else {
+ memcpy(&val, data, 4);
}
- return val;
+ }
+ return val;
}
//----------------------------------------------------------------------
@@ -554,33 +485,28 @@ DataExtractor::GetU32 (offset_t *offset_
// 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;
- }
- return nullptr;
+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;
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -589,23 +515,17 @@ DataExtractor::GetU32 (offset_t *offset_
//
// RETURNS the uint64_t that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint64_t
-DataExtractor::GetU64 (offset_t *offset_ptr) const
-{
- uint64_t val = 0;
- const uint8_t *data = (const uint8_t *)GetData (offset_ptr, sizeof(val));
- if (data)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- val = ReadSwapInt64 (data);
- }
- else
- {
- memcpy (&val, data, 8);
- }
+uint64_t DataExtractor::GetU64(offset_t *offset_ptr) const {
+ uint64_t val = 0;
+ const uint8_t *data = (const uint8_t *)GetData(offset_ptr, sizeof(val));
+ if (data) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ val = ReadSwapInt64(data);
+ } else {
+ memcpy(&val, data, 8);
}
- return val;
+ }
+ return val;
}
//----------------------------------------------------------------------
@@ -615,33 +535,28 @@ DataExtractor::GetU64 (offset_t *offset_
// 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;
- }
- return nullptr;
+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;
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -654,19 +569,23 @@ DataExtractor::GetU64 (offset_t *offset_
//
// RETURNS the integer value that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::GetMaxU32 (offset_t *offset_ptr, size_t byte_size) const
-{
- switch (byte_size)
- {
- case 1: return GetU8 (offset_ptr); break;
- case 2: return GetU16(offset_ptr); break;
- case 4: return GetU32(offset_ptr); break;
- default:
- assert(false && "GetMaxU32 unhandled case!");
- break;
- }
- return 0;
+uint32_t DataExtractor::GetMaxU32(offset_t *offset_ptr,
+ size_t byte_size) const {
+ switch (byte_size) {
+ case 1:
+ return GetU8(offset_ptr);
+ break;
+ case 2:
+ return GetU16(offset_ptr);
+ break;
+ case 4:
+ return GetU32(offset_ptr);
+ break;
+ default:
+ assert(false && "GetMaxU32 unhandled case!");
+ break;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -679,153 +598,154 @@ DataExtractor::GetMaxU32 (offset_t *offs
//
// RETURNS the integer value that was extracted, or zero on failure.
//----------------------------------------------------------------------
-uint64_t
-DataExtractor::GetMaxU64 (offset_t *offset_ptr, size_t size) const
-{
- switch (size)
- {
- case 1: return GetU8 (offset_ptr); break;
- case 2: return GetU16(offset_ptr); break;
- case 4: return GetU32(offset_ptr); break;
- case 8: return GetU64(offset_ptr); break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
- }
- return 0;
-}
-
-uint64_t
-DataExtractor::GetMaxU64_unchecked (offset_t *offset_ptr, size_t size) const
-{
- switch (size)
- {
- case 1: return GetU8_unchecked (offset_ptr); break;
- case 2: return GetU16_unchecked (offset_ptr); break;
- case 4: return GetU32_unchecked (offset_ptr); break;
- case 8: return GetU64_unchecked (offset_ptr); break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
- }
- return 0;
-}
-
-int64_t
-DataExtractor::GetMaxS64 (offset_t *offset_ptr, size_t size) const
-{
- switch (size)
- {
- case 1: return (int8_t)GetU8 (offset_ptr); break;
- case 2: return (int16_t)GetU16(offset_ptr); break;
- case 4: return (int32_t)GetU32(offset_ptr); break;
- case 8: return (int64_t)GetU64(offset_ptr); break;
- default:
- assert(false && "GetMax64 unhandled case!");
- break;
- }
- return 0;
-}
-
-uint64_t
-DataExtractor::GetMaxU64Bitfield (offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
-{
- uint64_t uval64 = GetMaxU64 (offset_ptr, size);
- if (bitfield_bit_size > 0)
- {
- int32_t lsbcount = bitfield_bit_offset;
- if (m_byte_order == eByteOrderBig)
- lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
- if (lsbcount > 0)
- uval64 >>= lsbcount;
- uint64_t bitfield_mask = ((1ul << bitfield_bit_size) - 1);
- if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64)
- return uval64;
- uval64 &= bitfield_mask;
- }
- return uval64;
-}
-
-int64_t
-DataExtractor::GetMaxS64Bitfield (offset_t *offset_ptr, size_t size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset) const
-{
- int64_t sval64 = GetMaxS64 (offset_ptr, size);
- if (bitfield_bit_size > 0)
- {
- int32_t lsbcount = bitfield_bit_offset;
- if (m_byte_order == eByteOrderBig)
- lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
- if (lsbcount > 0)
- sval64 >>= lsbcount;
- uint64_t bitfield_mask = (((uint64_t)1) << bitfield_bit_size) - 1;
- sval64 &= bitfield_mask;
- // sign extend if needed
- if (sval64 & (((uint64_t)1) << (bitfield_bit_size - 1)))
- sval64 |= ~bitfield_mask;
- }
- return sval64;
-}
-
-
-float
-DataExtractor::GetFloat (offset_t *offset_ptr) const
-{
- typedef float float_type;
- float_type val = 0.0;
- const size_t src_size = sizeof(float_type);
- const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
- if (src)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- const uint8_t *src_data = (const uint8_t *)src;
- uint8_t *dst_data = (uint8_t *)&val;
- for (size_t i = 0; i < sizeof(float_type); ++i)
- dst_data[sizeof(float_type) - 1 - i] = src_data[i];
- }
- else
- {
- val = *src;
- }
- }
- return val;
-}
-
-double
-DataExtractor::GetDouble (offset_t *offset_ptr) const
-{
- typedef double float_type;
- float_type val = 0.0;
- const size_t src_size = sizeof(float_type);
- const float_type *src = (const float_type *)GetData (offset_ptr, src_size);
- if (src)
- {
- if (m_byte_order != endian::InlHostByteOrder())
- {
- const uint8_t *src_data = (const uint8_t *)src;
- uint8_t *dst_data = (uint8_t *)&val;
- for (size_t i = 0; i < sizeof(float_type); ++i)
- dst_data[sizeof(float_type) - 1 - i] = src_data[i];
- }
- else
- {
- val = *src;
- }
- }
- return val;
-}
-
-
-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());
+uint64_t DataExtractor::GetMaxU64(offset_t *offset_ptr, size_t size) const {
+ switch (size) {
+ case 1:
+ return GetU8(offset_ptr);
+ break;
+ case 2:
+ return GetU16(offset_ptr);
+ break;
+ case 4:
+ return GetU32(offset_ptr);
+ break;
+ case 8:
+ return GetU64(offset_ptr);
+ break;
+ default:
+ assert(false && "GetMax64 unhandled case!");
+ break;
+ }
+ return 0;
+}
+
+uint64_t DataExtractor::GetMaxU64_unchecked(offset_t *offset_ptr,
+ size_t size) const {
+ switch (size) {
+ case 1:
+ return GetU8_unchecked(offset_ptr);
+ break;
+ case 2:
+ return GetU16_unchecked(offset_ptr);
+ break;
+ case 4:
+ return GetU32_unchecked(offset_ptr);
+ break;
+ case 8:
+ return GetU64_unchecked(offset_ptr);
+ break;
+ default:
+ assert(false && "GetMax64 unhandled case!");
+ break;
+ }
+ return 0;
+}
+
+int64_t DataExtractor::GetMaxS64(offset_t *offset_ptr, size_t size) const {
+ switch (size) {
+ case 1:
+ return (int8_t)GetU8(offset_ptr);
+ break;
+ case 2:
+ return (int16_t)GetU16(offset_ptr);
+ break;
+ case 4:
+ return (int32_t)GetU32(offset_ptr);
+ break;
+ case 8:
+ return (int64_t)GetU64(offset_ptr);
+ break;
+ default:
+ assert(false && "GetMax64 unhandled case!");
+ break;
+ }
+ return 0;
+}
+
+uint64_t DataExtractor::GetMaxU64Bitfield(offset_t *offset_ptr, size_t size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset) const {
+ uint64_t uval64 = GetMaxU64(offset_ptr, size);
+ if (bitfield_bit_size > 0) {
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ uval64 >>= lsbcount;
+ uint64_t bitfield_mask = ((1ul << bitfield_bit_size) - 1);
+ if (!bitfield_mask && bitfield_bit_offset == 0 && bitfield_bit_size == 64)
+ return uval64;
+ uval64 &= bitfield_mask;
+ }
+ return uval64;
+}
+
+int64_t DataExtractor::GetMaxS64Bitfield(offset_t *offset_ptr, size_t size,
+ uint32_t bitfield_bit_size,
+ uint32_t bitfield_bit_offset) const {
+ int64_t sval64 = GetMaxS64(offset_ptr, size);
+ if (bitfield_bit_size > 0) {
+ int32_t lsbcount = bitfield_bit_offset;
+ if (m_byte_order == eByteOrderBig)
+ lsbcount = size * 8 - bitfield_bit_offset - bitfield_bit_size;
+ if (lsbcount > 0)
+ sval64 >>= lsbcount;
+ uint64_t bitfield_mask = (((uint64_t)1) << bitfield_bit_size) - 1;
+ sval64 &= bitfield_mask;
+ // sign extend if needed
+ if (sval64 & (((uint64_t)1) << (bitfield_bit_size - 1)))
+ sval64 |= ~bitfield_mask;
+ }
+ return sval64;
+}
+
+float DataExtractor::GetFloat(offset_t *offset_ptr) const {
+ typedef float float_type;
+ float_type val = 0.0;
+ const size_t src_size = sizeof(float_type);
+ const float_type *src = (const float_type *)GetData(offset_ptr, src_size);
+ if (src) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ const uint8_t *src_data = (const uint8_t *)src;
+ uint8_t *dst_data = (uint8_t *)&val;
+ for (size_t i = 0; i < sizeof(float_type); ++i)
+ dst_data[sizeof(float_type) - 1 - i] = src_data[i];
+ } else {
+ val = *src;
+ }
+ }
+ return val;
+}
+
+double DataExtractor::GetDouble(offset_t *offset_ptr) const {
+ typedef double float_type;
+ float_type val = 0.0;
+ const size_t src_size = sizeof(float_type);
+ const float_type *src = (const float_type *)GetData(offset_ptr, src_size);
+ if (src) {
+ if (m_byte_order != endian::InlHostByteOrder()) {
+ const uint8_t *src_data = (const uint8_t *)src;
+ uint8_t *dst_data = (uint8_t *)&val;
+ for (size_t i = 0; i < sizeof(float_type); ++i)
+ dst_data[sizeof(float_type) - 1 - i] = src_data[i];
+ } else {
+ val = *src;
+ }
+ }
+ return val;
+}
+
+long double DataExtractor::GetLongDouble(offset_t *offset_ptr) const {
+ long double val = 0.0;
+#if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) || \
+ defined(_M_IX86) || defined(_M_IA64) || defined(_M_X64)
+ *offset_ptr += CopyByteOrderedData(*offset_ptr, 10, &val, sizeof(val),
+ endian::InlHostByteOrder());
#else
- *offset_ptr += CopyByteOrderedData (*offset_ptr, sizeof(val), &val, sizeof(val), endian::InlHostByteOrder());
+ *offset_ptr += CopyByteOrderedData(*offset_ptr, sizeof(val), &val,
+ sizeof(val), endian::InlHostByteOrder());
#endif
- return val;
+ return val;
}
//------------------------------------------------------------------
@@ -836,22 +756,18 @@ DataExtractor::GetLongDouble (offset_t *
//
// RETURNS the address that was extracted, or zero on failure.
//------------------------------------------------------------------
-uint64_t
-DataExtractor::GetAddress (offset_t *offset_ptr) const
-{
+uint64_t DataExtractor::GetAddress(offset_t *offset_ptr) const {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
- return GetMaxU64 (offset_ptr, m_addr_size);
+ return GetMaxU64(offset_ptr, m_addr_size);
}
-uint64_t
-DataExtractor::GetAddress_unchecked (offset_t *offset_ptr) const
-{
+uint64_t DataExtractor::GetAddress_unchecked(offset_t *offset_ptr) const {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
- return GetMaxU64_unchecked (offset_ptr, m_addr_size);
+ return GetMaxU64_unchecked(offset_ptr, m_addr_size);
}
//------------------------------------------------------------------
@@ -862,13 +778,11 @@ DataExtractor::GetAddress_unchecked (off
//
// RETURNS the pointer that was extracted, or zero on failure.
//------------------------------------------------------------------
-uint64_t
-DataExtractor::GetPointer (offset_t *offset_ptr) const
-{
+uint64_t DataExtractor::GetPointer(offset_t *offset_ptr) const {
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (m_addr_size == 4 || m_addr_size == 8);
+ assert(m_addr_size == 4 || m_addr_size == 8);
#endif
- return GetMaxU64 (offset_ptr, m_addr_size);
+ return GetMaxU64(offset_ptr, m_addr_size);
}
//----------------------------------------------------------------------
@@ -878,256 +792,239 @@ DataExtractor::GetPointer (offset_t *off
// 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
-{
- 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 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...
+
+ uint64_t baseAddress = 0;
+ uint64_t addressValue = 0;
+ const uint32_t addr_size = GetAddressByteSize();
#ifdef LLDB_CONFIGURATION_DEBUG
- assert (addr_size == 4 || addr_size == 8);
+ assert(addr_size == 4 || addr_size == 8);
#endif
- bool signExtendValue = false;
- // Decode the base part or adjust our offset
- switch (eh_ptr_enc & 0x70)
- {
- case DW_EH_PE_pcrel:
- signExtendValue = true;
- baseAddress = *offset_ptr;
- if (pc_rel_addr != LLDB_INVALID_ADDRESS)
- baseAddress += pc_rel_addr;
-// else
-// Log::GlobalWarning ("PC relative pointer encoding found with invalid pc relative address.");
- break;
-
- case DW_EH_PE_textrel:
- signExtendValue = true;
- if (text_addr != LLDB_INVALID_ADDRESS)
- baseAddress = text_addr;
-// else
-// Log::GlobalWarning ("text relative pointer encoding being decoded with invalid text section address, setting base address to zero.");
- break;
-
- case DW_EH_PE_datarel:
- signExtendValue = true;
- if (data_addr != LLDB_INVALID_ADDRESS)
- baseAddress = data_addr;
-// else
-// Log::GlobalWarning ("data relative pointer encoding being decoded with invalid data section address, setting base address to zero.");
- break;
-
- case DW_EH_PE_funcrel:
- signExtendValue = true;
- break;
-
- case DW_EH_PE_aligned:
- {
- // SetPointerSize should be called prior to extracting these so the
- // pointer size is cached
- assert(addr_size != 0);
- if (addr_size)
- {
- // Align to a address size boundary first
- uint32_t alignOffset = *offset_ptr % addr_size;
- if (alignOffset)
- offset_ptr += addr_size - alignOffset;
- }
- }
- break;
-
- default:
- break;
- }
-
- // Decode the value part
- switch (eh_ptr_enc & DW_EH_PE_MASK_ENCODING)
- {
- case DW_EH_PE_absptr :
- {
- addressValue = GetAddress (offset_ptr);
-// if (data_relocs)
-// addressValue = data_relocs->Relocate(*offset_ptr - addr_size, *this, addressValue);
- }
- break;
- case DW_EH_PE_uleb128 : addressValue = GetULEB128(offset_ptr); break;
- case DW_EH_PE_udata2 : addressValue = GetU16(offset_ptr); break;
- case DW_EH_PE_udata4 : addressValue = GetU32(offset_ptr); break;
- case DW_EH_PE_udata8 : addressValue = GetU64(offset_ptr); break;
- case DW_EH_PE_sleb128 : addressValue = GetSLEB128(offset_ptr); break;
- case DW_EH_PE_sdata2 : addressValue = (int16_t)GetU16(offset_ptr); break;
- case DW_EH_PE_sdata4 : addressValue = (int32_t)GetU32(offset_ptr); break;
- case DW_EH_PE_sdata8 : addressValue = (int64_t)GetU64(offset_ptr); break;
- default:
- // Unhandled encoding type
- assert(eh_ptr_enc);
- break;
- }
-
- // 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;
-}
-
-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;
+ bool signExtendValue = false;
+ // Decode the base part or adjust our offset
+ switch (eh_ptr_enc & 0x70) {
+ case DW_EH_PE_pcrel:
+ signExtendValue = true;
+ baseAddress = *offset_ptr;
+ if (pc_rel_addr != LLDB_INVALID_ADDRESS)
+ baseAddress += pc_rel_addr;
+ // else
+ // Log::GlobalWarning ("PC relative pointer encoding found with
+ // invalid pc relative address.");
+ break;
+
+ case DW_EH_PE_textrel:
+ signExtendValue = true;
+ if (text_addr != LLDB_INVALID_ADDRESS)
+ baseAddress = text_addr;
+ // else
+ // Log::GlobalWarning ("text relative pointer encoding being
+ // decoded with invalid text section address, setting base address
+ // to zero.");
+ break;
+
+ case DW_EH_PE_datarel:
+ signExtendValue = true;
+ if (data_addr != LLDB_INVALID_ADDRESS)
+ baseAddress = data_addr;
+ // else
+ // Log::GlobalWarning ("data relative pointer encoding being
+ // decoded with invalid data section address, setting base address
+ // to zero.");
+ break;
+
+ case DW_EH_PE_funcrel:
+ signExtendValue = true;
+ break;
+
+ case DW_EH_PE_aligned: {
+ // SetPointerSize should be called prior to extracting these so the
+ // pointer size is cached
+ assert(addr_size != 0);
+ if (addr_size) {
+ // Align to a address size boundary first
+ uint32_t alignOffset = *offset_ptr % addr_size;
+ if (alignOffset)
+ offset_ptr += addr_size - alignOffset;
+ }
+ } break;
+
+ default:
+ break;
+ }
+
+ // Decode the value part
+ switch (eh_ptr_enc & DW_EH_PE_MASK_ENCODING) {
+ case DW_EH_PE_absptr: {
+ addressValue = GetAddress(offset_ptr);
+ // if (data_relocs)
+ // addressValue = data_relocs->Relocate(*offset_ptr -
+ // addr_size, *this, addressValue);
+ } break;
+ case DW_EH_PE_uleb128:
+ addressValue = GetULEB128(offset_ptr);
+ break;
+ case DW_EH_PE_udata2:
+ addressValue = GetU16(offset_ptr);
+ break;
+ case DW_EH_PE_udata4:
+ addressValue = GetU32(offset_ptr);
+ break;
+ case DW_EH_PE_udata8:
+ addressValue = GetU64(offset_ptr);
+ break;
+ case DW_EH_PE_sleb128:
+ addressValue = GetSLEB128(offset_ptr);
+ break;
+ case DW_EH_PE_sdata2:
+ addressValue = (int16_t)GetU16(offset_ptr);
+ break;
+ case DW_EH_PE_sdata4:
+ addressValue = (int32_t)GetU32(offset_ptr);
+ break;
+ case DW_EH_PE_sdata8:
+ addressValue = (int64_t)GetU64(offset_ptr);
+ break;
+ default:
+ // Unhandled encoding type
+ assert(eh_ptr_enc);
+ break;
+ }
+
+ // 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;
+}
+
+size_t DataExtractor::ExtractBytes(offset_t offset, offset_t length,
+ ByteOrder dst_byte_order, void *dst) const {
+ const uint8_t *src = PeekData(offset, length);
+ if (src) {
+ if (dst_byte_order != GetByteOrder()) {
+ // Validate that only a word- or register-sized dst is byte swapped
+ assert(length == 1 || length == 2 || length == 4 || length == 8 ||
+ length == 10 || length == 16 || length == 32);
+
+ for (uint32_t i = 0; i < length; ++i)
+ ((uint8_t *)dst)[i] = src[length - i - 1];
+ } else
+ ::memcpy(dst, src, length);
+ return length;
+ }
+ return 0;
}
// Extract data as it exists in target memory
-lldb::offset_t
-DataExtractor::CopyData (offset_t offset,
- offset_t length,
- void *dst) const
-{
- const uint8_t *src = PeekData (offset, length);
- if (src)
- {
- ::memcpy (dst, src, length);
- return length;
- }
- return 0;
+lldb::offset_t DataExtractor::CopyData(offset_t offset, offset_t length,
+ void *dst) const {
+ const uint8_t *src = PeekData(offset, length);
+ if (src) {
+ ::memcpy(dst, src, length);
+ return length;
+ }
+ return 0;
}
// Extract data and swap if needed when doing the copy
lldb::offset_t
-DataExtractor::CopyByteOrderedData (offset_t src_offset,
- offset_t src_len,
- void *dst_void_ptr,
- offset_t dst_len,
- ByteOrder dst_byte_order) const
-{
- // Validate the source info
- if (!ValidOffsetForDataOfSize(src_offset, src_len))
- assert (ValidOffsetForDataOfSize(src_offset, src_len));
- assert (src_len > 0);
- assert (m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle);
-
- // Validate the destination info
- assert(dst_void_ptr != nullptr);
- assert (dst_len > 0);
- assert (dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle);
-
- // Validate that only a word- or register-sized dst is byte swapped
- assert (dst_byte_order == m_byte_order || dst_len == 1 || dst_len == 2 ||
- dst_len == 4 || dst_len == 8 || dst_len == 10 || dst_len == 16 ||
- dst_len == 32);
-
- // Must have valid byte orders set in this object and for destination
- if (!(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle) ||
- !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle))
- return 0;
-
- uint8_t* dst = (uint8_t*)dst_void_ptr;
- const uint8_t* src = (const uint8_t *)PeekData (src_offset, src_len);
- if (src)
- {
- if (dst_len >= src_len)
- {
- // We are copying the entire value from src into dst.
- // Calculate how many, if any, zeroes we need for the most
- // significant bytes if "dst_len" is greater than "src_len"...
- const size_t num_zeroes = dst_len - src_len;
- if (dst_byte_order == eByteOrderBig)
- {
- // Big endian, so we lead with zeroes...
- if (num_zeroes > 0)
- ::memset (dst, 0, num_zeroes);
- // Then either copy or swap the rest
- if (m_byte_order == eByteOrderBig)
- {
- ::memcpy (dst + num_zeroes, src, src_len);
- }
- else
- {
- for (uint32_t i = 0; i < src_len; ++i)
- dst[i+num_zeroes] = src[src_len - 1 - i];
- }
- }
- else
- {
- // Little endian destination, so we lead the value bytes
- if (m_byte_order == eByteOrderBig)
- {
- for (uint32_t i = 0; i < src_len; ++i)
- dst[i] = src[src_len - 1 - i];
- }
- else
- {
- ::memcpy (dst, src, src_len);
- }
- // And zero the rest...
- if (num_zeroes > 0)
- ::memset (dst + src_len, 0, num_zeroes);
- }
- return src_len;
- }
- else
- {
- // We are only copying some of the value from src into dst..
+DataExtractor::CopyByteOrderedData(offset_t src_offset, offset_t src_len,
+ void *dst_void_ptr, offset_t dst_len,
+ ByteOrder dst_byte_order) const {
+ // Validate the source info
+ if (!ValidOffsetForDataOfSize(src_offset, src_len))
+ assert(ValidOffsetForDataOfSize(src_offset, src_len));
+ assert(src_len > 0);
+ assert(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle);
+
+ // Validate the destination info
+ assert(dst_void_ptr != nullptr);
+ assert(dst_len > 0);
+ assert(dst_byte_order == eByteOrderBig || dst_byte_order == eByteOrderLittle);
+
+ // Validate that only a word- or register-sized dst is byte swapped
+ assert(dst_byte_order == m_byte_order || dst_len == 1 || dst_len == 2 ||
+ dst_len == 4 || dst_len == 8 || dst_len == 10 || dst_len == 16 ||
+ dst_len == 32);
+
+ // Must have valid byte orders set in this object and for destination
+ if (!(dst_byte_order == eByteOrderBig ||
+ dst_byte_order == eByteOrderLittle) ||
+ !(m_byte_order == eByteOrderBig || m_byte_order == eByteOrderLittle))
+ return 0;
- 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;
- }
+ 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;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -1141,32 +1038,28 @@ DataExtractor::CopyByteOrderedData (offs
// bytes, nullptr will be returned and "offset_ptr" will not be
// updated.
//----------------------------------------------------------------------
-const char*
-DataExtractor::GetCStr (offset_t *offset_ptr) const
-{
- const char *cstr = (const char *)PeekData (*offset_ptr, 1);
- if (cstr)
- {
- const char *cstr_end = cstr;
- const char *end = (const char *)m_end;
- while (cstr_end < end && *cstr_end)
- ++cstr_end;
-
- // Now we are either at the end of the data or we point to the
- // NULL C string terminator with cstr_end...
- if (*cstr_end == '\0')
- {
- // Advance the offset with one extra byte for the NULL terminator
- *offset_ptr += (cstr_end - cstr + 1);
- return cstr;
- }
-
- // We reached the end of the data without finding a NULL C string
- // terminator. Fall through and return nullptr otherwise anyone that
- // would have used the result as a C string can wander into
- // unknown memory...
- }
- return nullptr;
+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...
+ }
+ return nullptr;
}
//----------------------------------------------------------------------
@@ -1180,20 +1073,16 @@ DataExtractor::GetCStr (offset_t *offset
// 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;
- }
- return nullptr;
+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;
+ }
+ return nullptr;
}
//------------------------------------------------------------------
@@ -1204,10 +1093,8 @@ DataExtractor::GetCStr (offset_t *offset
// Returns a valid C string pointer if "offset" is a valid offset in
// this object's data, else nullptr is returned.
//------------------------------------------------------------------
-const char *
-DataExtractor::PeekCStr (offset_t offset) const
-{
- return (const char *)PeekData (offset, 1);
+const char *DataExtractor::PeekCStr(offset_t offset) const {
+ return (const char *)PeekData(offset, 1);
}
//----------------------------------------------------------------------
@@ -1218,36 +1105,31 @@ DataExtractor::PeekCStr (offset_t offset
//
// Returned the extracted integer value.
//----------------------------------------------------------------------
-uint64_t
-DataExtractor::GetULEB128 (offset_t *offset_ptr) const
-{
- const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == nullptr)
- return 0;
-
- const uint8_t *end = m_end;
-
- if (src < end)
- {
- uint64_t result = *src++;
- if (result >= 0x80)
- {
- result &= 0x7f;
- int shift = 7;
- while (src < end)
- {
- uint8_t byte = *src++;
- result |= (uint64_t)(byte & 0x7f) << shift;
- if ((byte & 0x80) == 0)
- break;
- shift += 7;
- }
- }
- *offset_ptr = src - m_start;
- return result;
- }
-
+uint64_t DataExtractor::GetULEB128(offset_t *offset_ptr) const {
+ const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
+ if (src == nullptr)
return 0;
+
+ const uint8_t *end = m_end;
+
+ if (src < end) {
+ uint64_t result = *src++;
+ if (result >= 0x80) {
+ result &= 0x7f;
+ int shift = 7;
+ while (src < end) {
+ uint8_t byte = *src++;
+ result |= (uint64_t)(byte & 0x7f) << shift;
+ if ((byte & 0x80) == 0)
+ break;
+ shift += 7;
+ }
+ }
+ *offset_ptr = src - m_start;
+ return result;
+ }
+
+ return 0;
}
//----------------------------------------------------------------------
@@ -1258,42 +1140,38 @@ DataExtractor::GetULEB128 (offset_t *off
//
// Returned the extracted integer value.
//----------------------------------------------------------------------
-int64_t
-DataExtractor::GetSLEB128 (offset_t *offset_ptr) const
-{
- const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == nullptr)
- return 0;
-
- const uint8_t *end = m_end;
-
- if (src < end)
- {
- int64_t result = 0;
- int shift = 0;
- int size = sizeof (int64_t) * 8;
-
- uint8_t byte = 0;
- int bytecount = 0;
-
- while (src < end)
- {
- bytecount++;
- byte = *src++;
- result |= (int64_t)(byte & 0x7f) << shift;
- shift += 7;
- if ((byte & 0x80) == 0)
- break;
- }
+int64_t DataExtractor::GetSLEB128(offset_t *offset_ptr) const {
+ const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
+ if (src == nullptr)
+ return 0;
- // Sign bit of byte is 2nd high order bit (0x40)
- if (shift < size && (byte & 0x40))
- result |= - (1 << shift);
+ const uint8_t *end = m_end;
- *offset_ptr += bytecount;
- return result;
+ if (src < end) {
+ int64_t result = 0;
+ int shift = 0;
+ int size = sizeof(int64_t) * 8;
+
+ uint8_t byte = 0;
+ int bytecount = 0;
+
+ while (src < end) {
+ bytecount++;
+ byte = *src++;
+ result |= (int64_t)(byte & 0x7f) << shift;
+ shift += 7;
+ if ((byte & 0x80) == 0)
+ break;
}
- return 0;
+
+ // Sign bit of byte is 2nd high order bit (0x40)
+ if (shift < size && (byte & 0x40))
+ result |= -(1 << shift);
+
+ *offset_ptr += bytecount;
+ return result;
+ }
+ return 0;
}
//----------------------------------------------------------------------
@@ -1304,761 +1182,774 @@ DataExtractor::GetSLEB128 (offset_t *off
//
// Returns the number of bytes consumed during the extraction.
//----------------------------------------------------------------------
-uint32_t
-DataExtractor::Skip_LEB128 (offset_t *offset_ptr) const
-{
- uint32_t bytes_consumed = 0;
- const uint8_t *src = (const uint8_t *)PeekData (*offset_ptr, 1);
- if (src == nullptr)
- return 0;
-
- const uint8_t *end = m_end;
-
- if (src < end)
- {
- const uint8_t *src_pos = src;
- while ((src_pos < end) && (*src_pos++ & 0x80))
- ++bytes_consumed;
- *offset_ptr += src_pos - src;
- }
- return bytes_consumed;
-}
+uint32_t DataExtractor::Skip_LEB128(offset_t *offset_ptr) const {
+ uint32_t bytes_consumed = 0;
+ const uint8_t *src = (const uint8_t *)PeekData(*offset_ptr, 1);
+ if (src == nullptr)
+ return 0;
-static bool
-GetAPInt (const DataExtractor &data, lldb::offset_t *offset_ptr, lldb::offset_t byte_size, llvm::APInt &result)
-{
- llvm::SmallVector<uint64_t, 2> uint64_array;
- lldb::offset_t bytes_left = byte_size;
- uint64_t u64;
- const lldb::ByteOrder byte_order = data.GetByteOrder();
- if (byte_order == lldb::eByteOrderLittle)
- {
- while (bytes_left > 0)
- {
- if (bytes_left >= 8)
- {
- u64 = data.GetU64(offset_ptr);
- bytes_left -= 8;
- }
- else
- {
- u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
- bytes_left = 0;
- }
- uint64_array.push_back(u64);
- }
- result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
- return true;
- }
- else if (byte_order == lldb::eByteOrderBig)
- {
- lldb::offset_t be_offset = *offset_ptr + byte_size;
- lldb::offset_t temp_offset;
- while (bytes_left > 0)
- {
- if (bytes_left >= 8)
- {
- be_offset -= 8;
- temp_offset = be_offset;
- u64 = data.GetU64(&temp_offset);
- bytes_left -= 8;
- }
- else
- {
- be_offset -= bytes_left;
- temp_offset = be_offset;
- u64 = data.GetMaxU64(&temp_offset, (uint32_t)bytes_left);
- bytes_left = 0;
- }
- uint64_array.push_back(u64);
- }
- *offset_ptr += byte_size;
- result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
- return true;
- }
- return false;
-}
+ const uint8_t *end = m_end;
-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());
+ if (src < end) {
+ const uint8_t *src_pos = src;
+ while ((src_pos < end) && (*src_pos++ & 0x80))
+ ++bytes_consumed;
+ *offset_ptr += src_pos - src;
+ }
+ return bytes_consumed;
+}
+
+static bool GetAPInt(const DataExtractor &data, lldb::offset_t *offset_ptr,
+ lldb::offset_t byte_size, llvm::APInt &result) {
+ llvm::SmallVector<uint64_t, 2> uint64_array;
+ lldb::offset_t bytes_left = byte_size;
+ uint64_t u64;
+ const lldb::ByteOrder byte_order = data.GetByteOrder();
+ if (byte_order == lldb::eByteOrderLittle) {
+ while (bytes_left > 0) {
+ if (bytes_left >= 8) {
+ u64 = data.GetU64(offset_ptr);
+ bytes_left -= 8;
+ } else {
+ u64 = data.GetMaxU64(offset_ptr, (uint32_t)bytes_left);
+ bytes_left = 0;
+ }
+ uint64_array.push_back(u64);
}
- return 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);
+ 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);
}
-
- v <<= 13;
- u.u = v | 0x70000000U;
- return u.f * ldexpf(1, -112);
+ *offset_ptr += byte_size;
+ result = llvm::APInt(byte_size * 8, llvm::ArrayRef<uint64_t>(uint64_array));
+ return true;
+ }
+ return false;
}
-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;
+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");
- 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;
+ }
+ if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) &&
+ item_byte_size > 8)
+ item_format = eFormatHex;
+
+ lldb::offset_t line_start_offset = start_offset;
+ for (uint32_t count = 0; ValidOffset(offset) && count < item_count; ++count) {
+ if ((count % num_per_line) == 0) {
+ if (count > 0) {
+ if (item_format == eFormatBytesWithASCII &&
+ offset > line_start_offset) {
+ s->Printf("%*s",
+ static_cast<int>(
+ (num_per_line - (offset - line_start_offset)) * 3 + 2),
+ "");
+ Dump(s, line_start_offset, eFormatCharPrintable, 1,
+ offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0,
+ 0);
+ }
+ s->EOL();
+ }
+ if (base_addr != LLDB_INVALID_ADDRESS)
+ s->Printf("0x%8.8" PRIx64 ": ",
+ (uint64_t)(base_addr +
+ (offset - start_offset) / m_target_byte_size));
+
+ line_start_offset = offset;
+ } else if (item_format != eFormatChar &&
+ item_format != eFormatCharPrintable &&
+ item_format != eFormatCharArray && count > 0) {
+ s->PutChar(' ');
+ }
+
+ switch (item_format) {
+ case eFormatBoolean:
+ if (item_byte_size <= 8)
+ s->Printf("%s", GetMaxU64Bitfield(&offset, item_byte_size,
+ item_bit_size, item_bit_offset)
+ ? "true"
+ : "false");
+ else {
+ s->Printf("error: unsupported byte size (%" PRIu64
+ ") for boolean format",
+ (uint64_t)item_byte_size);
return offset;
- }
-
- if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && item_byte_size > 8)
- item_format = eFormatHex;
-
- lldb::offset_t line_start_offset = start_offset;
- for (uint32_t count = 0; ValidOffset(offset) && count < item_count; ++count)
- {
- if ((count % num_per_line) == 0)
- {
- if (count > 0)
- {
- if (item_format == eFormatBytesWithASCII && offset > line_start_offset)
- {
- s->Printf("%*s", static_cast<int>((num_per_line - (offset - line_start_offset)) * 3 + 2), "");
- Dump(s, line_start_offset, eFormatCharPrintable, 1, offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0);
- }
- s->EOL();
- }
- if (base_addr != LLDB_INVALID_ADDRESS)
- s->Printf ("0x%8.8" PRIx64 ": ",
- (uint64_t)(base_addr + (offset - start_offset)/m_target_byte_size ));
-
- line_start_offset = offset;
- }
- else if (item_format != eFormatChar &&
- item_format != eFormatCharPrintable &&
- item_format != eFormatCharArray &&
- count > 0)
- {
- s->PutChar(' ');
- }
-
- switch (item_format)
- {
- case eFormatBoolean:
- if (item_byte_size <= 8)
- s->Printf ("%s", GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset) ? "true" : "false");
- else
- {
- s->Printf("error: unsupported byte size (%" PRIu64 ") for boolean format", (uint64_t)item_byte_size);
- return offset;
- }
- break;
-
- case eFormatBinary:
- if (item_byte_size <= 8)
- {
- uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset);
- // Avoid std::bitset<64>::to_string() since it is missing in
- // earlier C++ libraries
- std::string binary_value(64, '0');
- std::bitset<64> bits(uval64);
- for (uint32_t i = 0; i < 64; ++i)
- if (bits[i])
- binary_value[64 - 1 - i] = '1';
- if (item_bit_size > 0)
- s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
- else if (item_byte_size > 0 && item_byte_size <= 8)
- s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
- }
- else
- {
- const bool is_signed = false;
- const unsigned radix = 2;
- offset = DumpAPInt (s, *this, offset, item_byte_size, is_signed, radix);
- }
- break;
-
- case eFormatBytes:
- case eFormatBytesWithASCII:
- for (uint32_t i = 0; i < item_byte_size; ++i)
- {
- s->Printf ("%2.2x", GetU8(&offset));
- }
-
- // Put an extra space between the groups of bytes if more than one
- // is being dumped in a group (item_byte_size is more than 1).
- if (item_byte_size > 1)
- s->PutChar(' ');
- break;
-
- case eFormatChar:
- case eFormatCharPrintable:
- case eFormatCharArray:
- {
- // If we are only printing one character surround it with single
- // quotes
- if (item_count == 1 && item_format == eFormatChar)
- s->PutChar('\'');
-
- const uint64_t ch = GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset);
- if (isprint(ch))
- s->Printf ("%c", (char)ch);
- else if (item_format != eFormatCharPrintable)
- {
- switch (ch)
- {
- case '\033': s->Printf ("\\e"); break;
- case '\a': s->Printf ("\\a"); break;
- case '\b': s->Printf ("\\b"); break;
- case '\f': s->Printf ("\\f"); break;
- case '\n': s->Printf ("\\n"); break;
- case '\r': s->Printf ("\\r"); break;
- case '\t': s->Printf ("\\t"); break;
- case '\v': s->Printf ("\\v"); break;
- case '\0': s->Printf ("\\0"); break;
- default:
- if (item_byte_size == 1)
- s->Printf ("\\x%2.2x", (uint8_t)ch);
- else
- s->Printf ("%" PRIu64, ch);
- break;
- }
- }
- 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;
+ }
+ break;
+ case eFormatBinary:
+ if (item_byte_size <= 8) {
+ uint64_t uval64 = GetMaxU64Bitfield(&offset, item_byte_size,
+ item_bit_size, item_bit_offset);
+ // Avoid std::bitset<64>::to_string() since it is missing in
+ // earlier C++ libraries
+ std::string binary_value(64, '0');
+ std::bitset<64> bits(uval64);
+ for (uint32_t i = 0; i < 64; ++i)
+ if (bits[i])
+ binary_value[64 - 1 - i] = '1';
+ if (item_bit_size > 0)
+ s->Printf("0b%s", binary_value.c_str() + 64 - item_bit_size);
+ else if (item_byte_size > 0 && item_byte_size <= 8)
+ s->Printf("0b%s", binary_value.c_str() + 64 - item_byte_size * 8);
+ } else {
+ const bool is_signed = false;
+ const unsigned radix = 2;
+ offset = DumpAPInt(s, *this, offset, item_byte_size, is_signed, radix);
+ }
+ break;
+
+ case eFormatBytes:
+ case eFormatBytesWithASCII:
+ for (uint32_t i = 0; i < item_byte_size; ++i) {
+ s->Printf("%2.2x", GetU8(&offset));
+ }
+
+ // Put an extra space between the groups of bytes if more than one
+ // is being dumped in a group (item_byte_size is more than 1).
+ if (item_byte_size > 1)
+ s->PutChar(' ');
+ break;
+
+ case eFormatChar:
+ case eFormatCharPrintable:
+ case eFormatCharArray: {
+ // If we are only printing one character surround it with single
+ // quotes
+ if (item_count == 1 && item_format == eFormatChar)
+ s->PutChar('\'');
+
+ const uint64_t ch = GetMaxU64Bitfield(&offset, item_byte_size,
+ item_bit_size, item_bit_offset);
+ if (isprint(ch))
+ s->Printf("%c", (char)ch);
+ else if (item_format != eFormatCharPrintable) {
+ switch (ch) {
+ case '\033':
+ s->Printf("\\e");
+ break;
+ case '\a':
+ s->Printf("\\a");
+ break;
+ case '\b':
+ s->Printf("\\b");
+ break;
+ case '\f':
+ s->Printf("\\f");
+ break;
+ case '\n':
+ s->Printf("\\n");
+ break;
+ case '\r':
+ s->Printf("\\r");
+ break;
+ case '\t':
+ s->Printf("\\t");
+ break;
+ case '\v':
+ s->Printf("\\v");
+ break;
+ case '\0':
+ s->Printf("\\0");
+ break;
default:
- 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;
+ 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 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 eFormatComplex:
+ if (sizeof(float) * 2 == item_byte_size) {
+ float f32_1 = GetFloat(&offset);
+ float f32_2 = GetFloat(&offset);
- 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;
+ s->Printf("%g + %gi", f32_1, f32_2);
+ break;
+ } else if (sizeof(double) * 2 == item_byte_size) {
+ double d64_1 = GetDouble(&offset);
+ double d64_2 = GetDouble(&offset);
- case 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;
+ s->Printf("%lg + %lgi", d64_1, d64_2);
+ break;
+ } else if (sizeof(long double) * 2 == item_byte_size) {
+ long double ld64_1 = GetLongDouble(&offset);
+ long double ld64_2 = GetLongDouble(&offset);
+ s->Printf("%Lg + %Lgi", ld64_1, ld64_2);
+ break;
+ } else {
+ s->Printf("error: unsupported byte size (%" PRIu64
+ ") for complex float format",
+ (uint64_t)item_byte_size);
+ return offset;
+ }
+ break;
- case 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;
- }
- }
+ 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;
- 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
+ // please keep the single-item formats below in sync with
+ // FormatManager::GetSingleItemFormat
+ // if you fail to do so, users will start getting different outputs
+ // depending on internal
+ // implementation details they should not care about ||
+ case eFormatVectorOfChar: // ||
+ s->PutChar('{'); // \/
+ offset = Dump(s, offset, eFormatCharArray, 1, item_byte_size,
+ item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfSInt8:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatDecimal, 1, item_byte_size,
+ item_byte_size, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt8:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatHex, 1, item_byte_size, item_byte_size,
+ LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfSInt16:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatDecimal, sizeof(uint16_t),
+ item_byte_size / sizeof(uint16_t),
+ item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt16:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatHex, sizeof(uint16_t),
+ item_byte_size / sizeof(uint16_t),
+ item_byte_size / sizeof(uint16_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfSInt32:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatDecimal, sizeof(uint32_t),
+ item_byte_size / sizeof(uint32_t),
+ item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt32:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatHex, sizeof(uint32_t),
+ item_byte_size / sizeof(uint32_t),
+ item_byte_size / sizeof(uint32_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfSInt64:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatDecimal, sizeof(uint64_t),
+ item_byte_size / sizeof(uint64_t),
+ item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt64:
+ s->PutChar('{');
+ offset =
+ Dump(s, offset, eFormatHex, sizeof(uint64_t),
+ item_byte_size / sizeof(uint64_t),
+ item_byte_size / sizeof(uint64_t), LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfFloat16:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatFloat, 2, item_byte_size / 2,
+ item_byte_size / 2, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfFloat32:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatFloat, 4, item_byte_size / 4,
+ item_byte_size / 4, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfFloat64:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatFloat, 8, item_byte_size / 8,
+ item_byte_size / 8, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+
+ case eFormatVectorOfUInt128:
+ s->PutChar('{');
+ offset = Dump(s, offset, eFormatHex, 16, item_byte_size / 16,
+ item_byte_size / 16, LLDB_INVALID_ADDRESS, 0, 0);
+ s->PutChar('}');
+ break;
+ }
+ }
+
+ if (item_format == eFormatBytesWithASCII && offset > line_start_offset) {
+ s->Printf("%*s", static_cast<int>(
+ (num_per_line - (offset - line_start_offset)) * 3 + 2),
+ "");
+ Dump(s, line_start_offset, eFormatCharPrintable, 1,
+ offset - line_start_offset, SIZE_MAX, LLDB_INVALID_ADDRESS, 0, 0);
+ }
+ return offset; // Return the offset at which we ended up
}
//----------------------------------------------------------------------
@@ -2073,59 +1964,65 @@ DataExtractor::Dump (Stream *s,
// string will be used for the supplied "type". If the stream "s"
// is nullptr, then the output will be send to Log().
//----------------------------------------------------------------------
-lldb::offset_t
-DataExtractor::PutToLog(Log *log,
- offset_t start_offset,
- offset_t length,
- uint64_t base_addr,
- uint32_t num_per_line,
- DataExtractor::Type type,
- const char *format) const
-{
- if (log == nullptr)
- return start_offset;
-
- offset_t offset;
- offset_t end_offset;
- uint32_t count;
- StreamString sstr;
- for (offset = start_offset, end_offset = offset + length, count = 0; ValidOffset(offset) && offset < end_offset; ++count)
- {
- if ((count % num_per_line) == 0)
- {
- // Print out any previous string
- if (sstr.GetSize() > 0)
- {
- log->Printf("%s", sstr.GetData());
- sstr.Clear();
- }
- // Reset string offset and fill the current line string with address:
- if (base_addr != LLDB_INVALID_ADDRESS)
- sstr.Printf("0x%8.8" PRIx64 ":", (uint64_t)(base_addr + (offset - start_offset)));
- }
-
- 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;
- }
+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;
}
+ }
- if (sstr.GetSize() > 0)
- log->Printf("%s", sstr.GetData());
+ if (sstr.GetSize() > 0)
+ log->Printf("%s", sstr.GetData());
- return offset; // Return the offset at which we ended up
+ return offset; // Return the offset at which we ended up
}
//----------------------------------------------------------------------
@@ -2133,137 +2030,114 @@ DataExtractor::PutToLog(Log *log,
//
// Dump out a UUID starting at 'offset' bytes into the buffer
//----------------------------------------------------------------------
-void
-DataExtractor::DumpUUID (Stream *s, offset_t offset) const
-{
- if (s)
- {
- const uint8_t *uuid_data = PeekData(offset, 16);
- if ( uuid_data )
- {
- lldb_private::UUID uuid(uuid_data, 16);
- uuid.Dump(s);
- }
- else
- {
- s->Printf("<not enough data for UUID at offset 0x%8.8" PRIx64 ">", offset);
- }
- }
-}
-
-void
-DataExtractor::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::DumpUUID(Stream *s, offset_t offset) const {
+ if (s) {
+ const uint8_t *uuid_data = PeekData(offset, 16);
+ if (uuid_data) {
+ lldb_private::UUID uuid(uuid_data, 16);
+ uuid.Dump(s);
+ } else {
+ s->Printf("<not enough data for UUID at offset 0x%8.8" PRIx64 ">",
+ offset);
+ }
+ }
+}
+
+void DataExtractor::DumpHexBytes(Stream *s, const void *src, size_t src_len,
+ uint32_t bytes_per_line, addr_t base_addr) {
+ DataExtractor data(src, src_len, eByteOrderLittle, 4);
+ data.Dump(s,
+ 0, // Offset into "src"
+ eFormatBytes, // Dump as hex bytes
+ 1, // Size of each item is 1 for single bytes
+ src_len, // Number of bytes
+ bytes_per_line, // Num bytes per line
+ base_addr, // Base address
+ 0, 0); // Bitfield info
+}
+
+size_t DataExtractor::Copy(DataExtractor &dest_data) const {
+ if (m_data_sp) {
+ // we can pass along the SP to the data
+ dest_data.SetData(m_data_sp);
+ } else {
+ const uint8_t *base_ptr = m_start;
+ size_t data_size = GetByteSize();
+ dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size)));
+ }
+ return GetByteSize();
}
-size_t
-DataExtractor::Copy (DataExtractor &dest_data) const
-{
- if (m_data_sp)
- {
- // we can pass along the SP to the data
- dest_data.SetData(m_data_sp);
- }
- else
- {
- const uint8_t *base_ptr = m_start;
- size_t data_size = GetByteSize();
- dest_data.SetData(DataBufferSP(new DataBufferHeap(base_ptr, data_size)));
- }
- return GetByteSize();
-}
+bool DataExtractor::Append(DataExtractor &rhs) {
+ if (rhs.GetByteOrder() != GetByteOrder())
+ return false;
-bool
-DataExtractor::Append(DataExtractor& rhs)
-{
- if (rhs.GetByteOrder() != GetByteOrder())
- return false;
-
- if (rhs.GetByteSize() == 0)
- return true;
-
- if (GetByteSize() == 0)
- return (rhs.Copy(*this) > 0);
-
- size_t bytes = GetByteSize() + rhs.GetByteSize();
-
- DataBufferHeap *buffer_heap_ptr = nullptr;
- DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
-
- if (!buffer_sp || buffer_heap_ptr == nullptr)
- return false;
-
- uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes();
-
- memcpy(bytes_ptr, GetDataStart(), GetByteSize());
- memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize());
-
- SetData(buffer_sp);
-
+ if (rhs.GetByteSize() == 0)
return true;
+
+ if (GetByteSize() == 0)
+ return (rhs.Copy(*this) > 0);
+
+ size_t bytes = GetByteSize() + rhs.GetByteSize();
+
+ DataBufferHeap *buffer_heap_ptr = nullptr;
+ DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
+
+ if (!buffer_sp || buffer_heap_ptr == nullptr)
+ return false;
+
+ uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes();
+
+ memcpy(bytes_ptr, GetDataStart(), GetByteSize());
+ memcpy(bytes_ptr + GetByteSize(), rhs.GetDataStart(), rhs.GetByteSize());
+
+ SetData(buffer_sp);
+
+ return true;
}
-bool
-DataExtractor::Append(void* buf, offset_t length)
-{
- if (buf == nullptr)
- return false;
-
- if (length == 0)
- return true;
-
- size_t bytes = GetByteSize() + length;
-
- DataBufferHeap *buffer_heap_ptr = nullptr;
- DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
-
- if (!buffer_sp || buffer_heap_ptr == nullptr)
- return false;
-
- uint8_t* bytes_ptr = buffer_heap_ptr->GetBytes();
-
- if (GetByteSize() > 0)
- memcpy(bytes_ptr, GetDataStart(), GetByteSize());
-
- memcpy(bytes_ptr + GetByteSize(), buf, length);
-
- SetData(buffer_sp);
-
+bool DataExtractor::Append(void *buf, offset_t length) {
+ if (buf == nullptr)
+ return false;
+
+ if (length == 0)
return true;
+
+ size_t bytes = GetByteSize() + length;
+
+ DataBufferHeap *buffer_heap_ptr = nullptr;
+ DataBufferSP buffer_sp(buffer_heap_ptr = new DataBufferHeap(bytes, 0));
+
+ if (!buffer_sp || buffer_heap_ptr == nullptr)
+ return false;
+
+ uint8_t *bytes_ptr = buffer_heap_ptr->GetBytes();
+
+ if (GetByteSize() > 0)
+ memcpy(bytes_ptr, GetDataStart(), GetByteSize());
+
+ memcpy(bytes_ptr + GetByteSize(), buf, length);
+
+ SetData(buffer_sp);
+
+ return true;
}
-void
-DataExtractor::Checksum (llvm::SmallVectorImpl<uint8_t> &dest,
- uint64_t max_data)
-{
- if (max_data == 0)
- max_data = GetByteSize();
- else
- max_data = std::min(max_data, GetByteSize());
+void DataExtractor::Checksum(llvm::SmallVectorImpl<uint8_t> &dest,
+ uint64_t max_data) {
+ if (max_data == 0)
+ max_data = GetByteSize();
+ else
+ max_data = std::min(max_data, GetByteSize());
- llvm::MD5 md5;
+ llvm::MD5 md5;
- const llvm::ArrayRef<uint8_t> data(GetDataStart(),max_data);
- md5.update(data);
+ const llvm::ArrayRef<uint8_t> data(GetDataStart(), max_data);
+ md5.update(data);
- llvm::MD5::MD5Result result;
- md5.final(result);
+ llvm::MD5::MD5Result result;
+ md5.final(result);
- dest.resize(16);
- std::copy(result,
- result+16,
- dest.begin());
+ dest.resize(16);
+ std::copy(result, result + 16, dest.begin());
}
Modified: lldb/trunk/source/Core/Debugger.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Debugger.cpp?rev=280751&r1=280750&r2=280751&view=diff
==============================================================================
--- lldb/trunk/source/Core/Debugger.cpp (original)
+++ lldb/trunk/source/Core/Debugger.cpp Tue Sep 6 15:57:50 2016
@@ -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 @@ static size_t g_debugger_event_thread_st
#pragma mark Static Functions
typedef std::vector<DebuggerSP> DebuggerList;
-static std::recursive_mutex *g_debugger_list_mutex_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
-static DebuggerList *g_debugger_list_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
-
-OptionEnumValueElement
-g_show_disassembly_enum_values[] =
-{
- { Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."},
- { Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", "Show disassembly when there is no debug information."},
- { Debugger::eStopDisassemblyTypeNoSource, "no-source", "Show disassembly when there is no source information, or the source file is missing when displaying a stop context."},
- { Debugger::eStopDisassemblyTypeAlways, "always", "Always show disassembly when displaying a stop context."},
- { 0, nullptr, nullptr }
-};
-
-OptionEnumValueElement
-g_language_enumerators[] =
-{
- { eScriptLanguageNone, "none", "Disable scripting languages."},
- { eScriptLanguagePython, "python", "Select python as the default scripting language."},
- { eScriptLanguageDefault, "default", "Select the lldb default as the default scripting language."},
- { 0, nullptr, nullptr }
-};
-
-#define MODULE_WITH_FUNC "{ ${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
+static std::recursive_mutex *g_debugger_list_mutex_ptr =
+ nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
+static DebuggerList *g_debugger_list_ptr =
+ nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain
+
+OptionEnumValueElement g_show_disassembly_enum_values[] = {
+ {Debugger::eStopDisassemblyTypeNever, "never",
+ "Never show disassembly when displaying a stop context."},
+ {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo",
+ "Show disassembly when there is no debug information."},
+ {Debugger::eStopDisassemblyTypeNoSource, "no-source",
+ "Show disassembly when there is no source information, or the source file "
+ "is missing when displaying a stop context."},
+ {Debugger::eStopDisassemblyTypeAlways, "always",
+ "Always show disassembly when displaying a stop context."},
+ {0, nullptr, nullptr}};
+
+OptionEnumValueElement g_language_enumerators[] = {
+ {eScriptLanguageNone, "none", "Disable scripting languages."},
+ {eScriptLanguagePython, "python",
+ "Select python as the default scripting language."},
+ {eScriptLanguageDefault, "default",
+ "Select the lldb default as the default scripting language."},
+ {0, nullptr, nullptr}};
+
+#define MODULE_WITH_FUNC \
+ "{ " \
+ "${module.file.basename}{`${function.name-with-args}${function.pc-offset}}}"
#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}"
#define IS_OPTIMIZED "{${function.is-optimized} [opt]}"
-#define DEFAULT_THREAD_FORMAT "thread #${thread.index}: tid = ${thread.id%tid}"\
- "{, ${frame.pc}}"\
- MODULE_WITH_FUNC\
- FILE_AND_LINE\
- "{, name = '${thread.name}'}"\
- "{, queue = '${thread.queue}'}"\
- "{, activity = '${thread.info.activity.name}'}" \
- "{, ${thread.info.trace_messages} messages}" \
- "{, stop reason = ${thread.stop-reason}}"\
- "{\\nReturn value: ${thread.return-value}}"\
- "{\\nCompleted expression: ${thread.completed-expression}}"\
- "\\n"
-
-#define DEFAULT_FRAME_FORMAT "frame #${frame.index}: ${frame.pc}"\
- MODULE_WITH_FUNC\
- FILE_AND_LINE\
- IS_OPTIMIZED\
- "\\n"
+#define DEFAULT_THREAD_FORMAT \
+ "thread #${thread.index}: tid = ${thread.id%tid}" \
+ "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \
+ "{, name = '${thread.name}'}" \
+ "{, queue = '${thread.queue}'}" \
+ "{, activity = '${thread.info.activity.name}'}" \
+ "{, ${thread.info.trace_messages} messages}" \
+ "{, stop reason = ${thread.stop-reason}}" \
+ "{\\nReturn value: ${thread.return-value}}" \
+ "{\\nCompleted expression: ${thread.completed-expression}}" \
+ "\\n"
+
+#define DEFAULT_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 }
-};
-
-enum
-{
- ePropertyAutoConfirm = 0,
- ePropertyDisassemblyFormat,
- ePropertyFrameFormat,
- ePropertyNotiftVoid,
- ePropertyPrompt,
- ePropertyScriptLanguage,
- ePropertyStopDisassemblyCount,
- ePropertyStopDisassemblyDisplay,
- ePropertyStopLineCountAfter,
- ePropertyStopLineCountBefore,
- ePropertyTerminalWidth,
- ePropertyThreadFormat,
- ePropertyUseExternalEditor,
- ePropertyUseColor,
- ePropertyAutoOneLineSummaries,
- ePropertyAutoIndent,
- ePropertyPrintDecls,
- ePropertyTabSize,
- ePropertyEscapeNonPrintables
+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
};
LoadPluginCallbackType Debugger::g_load_plugin_callback = nullptr;
-Error
-Debugger::SetPropertyValue (const ExecutionContext *exe_ctx,
- VarSetOperationType op,
- const char *property_path,
- const char *value)
-{
- bool is_load_script = strcmp(property_path,"target.load-script-from-symbol-file") == 0;
- bool is_escape_non_printables = strcmp(property_path, "escape-non-printables") == 0;
- TargetSP target_sp;
- LoadScriptFromSymFile load_script_old_value;
- if (is_load_script && exe_ctx->GetTargetSP())
- {
- target_sp = exe_ctx->GetTargetSP();
- load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile();
- }
- Error error (Properties::SetPropertyValue (exe_ctx, op, property_path, value));
- if (error.Success())
- {
- // FIXME it would be nice to have "on-change" callbacks for properties
- if (strcmp(property_path, g_properties[ePropertyPrompt].name) == 0)
- {
- const char *new_prompt = GetPrompt();
- std::string str = lldb_utility::ansi::FormatAnsiTerminalCodes (new_prompt, GetUseColor());
- if (str.length())
- new_prompt = str.c_str();
- GetCommandInterpreter().UpdatePrompt(new_prompt);
- EventSP prompt_change_event_sp (new Event(CommandInterpreter::eBroadcastBitResetPrompt, new EventDataBytes (new_prompt)));
- GetCommandInterpreter().BroadcastEvent (prompt_change_event_sp);
- }
- else if (strcmp(property_path, g_properties[ePropertyUseColor].name) == 0)
- {
- // use-color changed. Ping the prompt so it can reset the ansi terminal codes.
- SetPrompt (GetPrompt());
- }
- else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn)
- {
- if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == eLoadScriptFromSymFileTrue)
- {
- std::list<Error> errors;
- StreamString feedback_stream;
- if (!target_sp->LoadScriptingResources(errors,&feedback_stream))
- {
- StreamFileSP stream_sp (GetErrorFile());
- if (stream_sp)
- {
- for (auto error : errors)
- {
- stream_sp->Printf("%s\n",error.AsCString());
- }
- if (feedback_stream.GetSize())
- stream_sp->Printf("%s",feedback_stream.GetData());
- }
- }
+Error Debugger::SetPropertyValue(const ExecutionContext *exe_ctx,
+ VarSetOperationType op,
+ 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();
- }
+ }
+ } else if (is_escape_non_printables) {
+ DataVisualization::ForceUpdate();
}
- return error;
+ }
+ return error;
}
-bool
-Debugger::GetAutoConfirm () const
-{
- const uint32_t idx = ePropertyAutoConfirm;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::GetAutoConfirm() const {
+ const uint32_t idx = ePropertyAutoConfirm;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-const FormatEntity::Entry *
-Debugger::GetDisassemblyFormat() const
-{
- const uint32_t idx = ePropertyDisassemblyFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const {
+ const uint32_t idx = ePropertyDisassemblyFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-const FormatEntity::Entry *
-Debugger::GetFrameFormat() const
-{
- const uint32_t idx = ePropertyFrameFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetFrameFormat() const {
+ const uint32_t idx = ePropertyFrameFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-bool
-Debugger::GetNotifyVoid () const
-{
- const uint32_t idx = ePropertyNotiftVoid;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, g_properties[idx].default_uint_value != 0);
+bool Debugger::GetNotifyVoid() const {
+ const uint32_t idx = ePropertyNotiftVoid;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-const char *
-Debugger::GetPrompt() const
-{
- const uint32_t idx = ePropertyPrompt;
- return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, g_properties[idx].default_cstr_value);
+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())
- new_prompt = str.c_str();
- GetCommandInterpreter().UpdatePrompt(new_prompt);
+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);
}
-const FormatEntity::Entry *
-Debugger::GetThreadFormat() const
-{
- const uint32_t idx = ePropertyThreadFormat;
- return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
+const FormatEntity::Entry *Debugger::GetThreadFormat() const {
+ const uint32_t idx = ePropertyThreadFormat;
+ return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx);
}
-lldb::ScriptLanguage
-Debugger::GetScriptLanguage() const
-{
- const uint32_t idx = ePropertyScriptLanguage;
- return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration(nullptr, idx, g_properties[idx].default_uint_value);
+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::SetScriptLanguage (lldb::ScriptLanguage script_lang)
-{
- const uint32_t idx = ePropertyScriptLanguage;
- return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, script_lang);
+bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) {
+ const uint32_t idx = ePropertyScriptLanguage;
+ return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx,
+ script_lang);
}
-uint32_t
-Debugger::GetTerminalWidth () const
-{
- const uint32_t idx = ePropertyTerminalWidth;
- 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);
}
-bool
-Debugger::SetTerminalWidth (uint32_t term_width)
-{
- const uint32_t idx = ePropertyTerminalWidth;
- return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
+bool Debugger::SetTerminalWidth(uint32_t term_width) {
+ const uint32_t idx = ePropertyTerminalWidth;
+ return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width);
}
-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::GetUseExternalEditor() const {
+ const uint32_t idx = ePropertyUseExternalEditor;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-bool
-Debugger::SetUseExternalEditor (bool b)
-{
- const uint32_t idx = ePropertyUseExternalEditor;
- return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+bool Debugger::SetUseExternalEditor(bool b) {
+ const uint32_t idx = ePropertyUseExternalEditor;
+ return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
}
-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::GetUseColor() const {
+ const uint32_t idx = ePropertyUseColor;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(
+ nullptr, idx, g_properties[idx].default_uint_value != 0);
}
-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::SetUseColor(bool b) {
+ const uint32_t idx = ePropertyUseColor;
+ bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b);
+ SetPrompt(GetPrompt());
+ return ret;
}
-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::GetStopSourceLineCount(bool before) const {
+ const uint32_t idx =
+ before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter;
+ 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);
+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);
}
-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::GetDisassemblyLineCount() const {
+ const uint32_t idx = ePropertyStopDisassemblyCount;
+ return m_collection_sp->GetPropertyAtIndexAsSInt64(
+ 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::GetAutoOneLineSummaries() const {
+ const uint32_t idx = ePropertyAutoOneLineSummaries;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
}
-bool
-Debugger::GetEscapeNonPrintables () const
-{
- const uint32_t idx = ePropertyEscapeNonPrintables;
- return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true);
+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::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::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::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);
+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);
+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);
+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::Terminate ()
-{
- assert(g_debugger_list_ptr && "Debugger::Terminate called without a matching Debugger::Initialize!");
-
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- // 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();
- }
- }
-}
-
-void
-Debugger::SettingsInitialize ()
-{
- Target::SettingsInitialize ();
-}
-
-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;
- }
- }
- 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;
+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!");
+
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ // 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();
+ }
+ }
+}
+
+void Debugger::SettingsInitialize() { Target::SettingsInitialize(); }
+
+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;
+ }
+ } else {
+ // The g_load_plugin_callback is registered in SBDebugger::Initialize()
+ // and if the public API layer isn't available (code is linking against
+ // all of the internal LLDB static libraries), then we can't load plugins
+ error.SetErrorString("Public API layer is not available");
+ }
+ return false;
}
static FileSpec::EnumerateDirectoryResult
-LoadPluginCallback(void *baton,
- FileSpec::FileType file_type,
- const FileSpec &file_spec)
-{
- Error error;
-
- static ConstString g_dylibext("dylib");
- static ConstString g_solibext("so");
-
- if (!baton)
- return FileSpec::eEnumerateDirectoryResultQuit;
-
- Debugger *debugger = (Debugger*)baton;
-
- // If we have a regular file, a symbolic link or unknown file type, try
- // and process the file. We must handle unknown as sometimes the directory
- // enumeration might be enumerating a file system that doesn't have correct
- // file type information.
- if (file_type == FileSpec::eFileTypeRegular ||
- file_type == FileSpec::eFileTypeSymbolicLink ||
- file_type == FileSpec::eFileTypeUnknown )
- {
- FileSpec plugin_file_spec (file_spec);
- plugin_file_spec.ResolvePath ();
-
- if (plugin_file_spec.GetFileNameExtension() != g_dylibext &&
- plugin_file_spec.GetFileNameExtension() != g_solibext)
- {
- return FileSpec::eEnumerateDirectoryResultNext;
- }
-
- Error plugin_load_error;
- debugger->LoadPlugin (plugin_file_spec, plugin_load_error);
-
- return FileSpec::eEnumerateDirectoryResultNext;
- }
- else if (file_type == FileSpec::eFileTypeUnknown ||
- file_type == FileSpec::eFileTypeDirectory ||
- file_type == FileSpec::eFileTypeSymbolicLink )
- {
- // Try and recurse into anything that a directory or symbolic link.
- // We must also do this for unknown as sometimes the directory enumeration
- // might be enumerating a file system that doesn't have correct file type
- // information.
- return FileSpec::eEnumerateDirectoryResultEnter;
- }
-
- return FileSpec::eEnumerateDirectoryResultNext;
-}
-
-void
-Debugger::InstanceInitialize ()
-{
- FileSpec dir_spec;
- const bool find_directories = true;
- const bool find_files = true;
- const bool find_other = true;
- char dir_path[PATH_MAX];
- if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec))
- {
- if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
- {
- FileSpec::EnumerateDirectory (dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- this);
- }
- }
-
- if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec))
- {
- if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path)))
- {
- FileSpec::EnumerateDirectory (dir_path,
- find_directories,
- find_files,
- find_other,
- LoadPluginCallback,
- this);
- }
+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;
}
-
- 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;
-}
+ Error plugin_load_error;
+ debugger->LoadPlugin(plugin_file_spec, plugin_load_error);
-void
-Debugger::Destroy (DebuggerSP &debugger_sp)
-{
- if (!debugger_sp)
+ return FileSpec::eEnumerateDirectoryResultNext;
+ } else if (file_type == FileSpec::eFileTypeUnknown ||
+ file_type == FileSpec::eFileTypeDirectory ||
+ file_type == FileSpec::eFileTypeSymbolicLink) {
+ // Try and recurse into anything that a directory or symbolic link.
+ // We must also do this for unknown as sometimes the directory enumeration
+ // might be enumerating a file system that doesn't have correct file type
+ // information.
+ return FileSpec::eEnumerateDirectoryResultEnter;
+ }
+
+ return FileSpec::eEnumerateDirectoryResultNext;
+}
+
+void Debugger::InstanceInitialize() {
+ FileSpec dir_spec;
+ const bool find_directories = true;
+ const bool find_files = true;
+ const bool find_other = true;
+ char dir_path[PATH_MAX];
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBSystemPlugins, dir_spec)) {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
+ FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
+ find_other, LoadPluginCallback, this);
+ }
+ }
+
+ if (HostInfo::GetLLDBPath(ePathTypeLLDBUserPlugins, dir_spec)) {
+ if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) {
+ FileSpec::EnumerateDirectory(dir_path, find_directories, find_files,
+ find_other, LoadPluginCallback, this);
+ }
+ }
+
+ 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;
+}
+
+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;
- }
- }
- }
- return debugger_sp;
-}
-
-TargetSP
-Debugger::FindTargetWithProcessID (lldb::pid_t pid)
-{
- TargetSP target_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- target_sp = (*pos)->GetTargetList().FindTargetWithProcessID (pid);
- if (target_sp)
- break;
- }
- }
- return target_sp;
-}
-
-TargetSP
-Debugger::FindTargetWithProcess (Process *process)
-{
- TargetSP target_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- target_sp = (*pos)->GetTargetList().FindTargetWithProcess (process);
- if (target_sp)
- break;
- }
- }
- return target_sp;
-}
-
-Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) :
- UserID(g_unique_id++),
- Properties(OptionValuePropertiesSP(new OptionValueProperties())),
- m_input_file_sp(new StreamFile(stdin, false)),
- m_output_file_sp(new StreamFile(stdout, false)),
- m_error_file_sp(new StreamFile(stderr, false)),
- m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
- m_terminal_state(),
- m_target_list(*this),
- m_platform_list(),
- m_listener_sp(Listener::MakeListener("lldb.Debugger")),
- m_source_manager_ap(),
- m_source_file_cache(),
- m_command_interpreter_ap(new CommandInterpreter(*this, eScriptLanguageDefault, false)),
- m_input_reader_stack(),
- m_instance_name(),
- m_loaded_plugins(),
- m_event_handler_thread(),
- m_io_handler_thread(),
- m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
- m_forward_listener_sp(),
- m_clear_once()
-{
- char instance_cstr[256];
- snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
- m_instance_name.SetCString(instance_cstr);
- if (log_callback)
- m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
- m_command_interpreter_ap->Initialize ();
- // Always add our default platform to the platform list
- PlatformSP default_platform_sp (Platform::GetHostPlatform());
- assert(default_platform_sp);
- m_platform_list.Append (default_platform_sp, true);
-
- m_collection_sp->Initialize (g_properties);
- m_collection_sp->AppendProperty (ConstString("target"),
- ConstString("Settings specify to debugging targets."),
- true,
- Target::GetGlobalProperties()->GetValueProperties());
- m_collection_sp->AppendProperty (ConstString("platform"),
- ConstString("Platform settings."),
- true,
- Platform::GetGlobalPlatformProperties()->GetValueProperties());
- if (m_command_interpreter_ap)
- {
- m_collection_sp->AppendProperty (ConstString("interpreter"),
- ConstString("Settings specify to the debugger's command interpreter."),
- true,
- m_command_interpreter_ap->GetValueProperties());
- }
- OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(nullptr, ePropertyTerminalWidth);
- term_width->SetMinimumValue(10);
- term_width->SetMaximumValue(1024);
-
- // Turn off use-color if this is a dumb terminal.
- const char *term = getenv ("TERM");
- if (term && !strcmp (term, "dumb"))
- SetUseColor (false);
-}
+Debugger::FindDebuggerWithInstanceName(const ConstString &instance_name) {
+ DebuggerSP debugger_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ if ((*pos)->m_instance_name == instance_name) {
+ debugger_sp = *pos;
+ break;
+ }
+ }
+ }
+ return debugger_sp;
+}
+
+TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) {
+ TargetSP target_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ target_sp = (*pos)->GetTargetList().FindTargetWithProcessID(pid);
+ if (target_sp)
+ break;
+ }
+ }
+ return target_sp;
+}
+
+TargetSP Debugger::FindTargetWithProcess(Process *process) {
+ TargetSP target_sp;
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ target_sp = (*pos)->GetTargetList().FindTargetWithProcess(process);
+ if (target_sp)
+ break;
+ }
+ }
+ return target_sp;
+}
+
+Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton)
+ : UserID(g_unique_id++),
+ Properties(OptionValuePropertiesSP(new OptionValueProperties())),
+ m_input_file_sp(new StreamFile(stdin, false)),
+ m_output_file_sp(new StreamFile(stdout, false)),
+ m_error_file_sp(new StreamFile(stderr, false)),
+ m_broadcaster_manager_sp(BroadcasterManager::MakeBroadcasterManager()),
+ m_terminal_state(), m_target_list(*this), m_platform_list(),
+ m_listener_sp(Listener::MakeListener("lldb.Debugger")),
+ m_source_manager_ap(), m_source_file_cache(),
+ m_command_interpreter_ap(
+ new CommandInterpreter(*this, eScriptLanguageDefault, false)),
+ m_input_reader_stack(), m_instance_name(), m_loaded_plugins(),
+ m_event_handler_thread(), m_io_handler_thread(),
+ m_sync_broadcaster(nullptr, "lldb.debugger.sync"),
+ m_forward_listener_sp(), m_clear_once() {
+ char instance_cstr[256];
+ snprintf(instance_cstr, sizeof(instance_cstr), "debugger_%d", (int)GetID());
+ m_instance_name.SetCString(instance_cstr);
+ if (log_callback)
+ m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton));
+ m_command_interpreter_ap->Initialize();
+ // Always add our default platform to the platform list
+ PlatformSP default_platform_sp(Platform::GetHostPlatform());
+ assert(default_platform_sp);
+ m_platform_list.Append(default_platform_sp, true);
+
+ m_collection_sp->Initialize(g_properties);
+ m_collection_sp->AppendProperty(
+ ConstString("target"),
+ ConstString("Settings specify to debugging targets."), true,
+ Target::GetGlobalProperties()->GetValueProperties());
+ m_collection_sp->AppendProperty(
+ ConstString("platform"), ConstString("Platform settings."), true,
+ Platform::GetGlobalPlatformProperties()->GetValueProperties());
+ if (m_command_interpreter_ap) {
+ m_collection_sp->AppendProperty(
+ ConstString("interpreter"),
+ ConstString("Settings specify to the debugger's command interpreter."),
+ true, m_command_interpreter_ap->GetValueProperties());
+ }
+ OptionValueSInt64 *term_width =
+ m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64(
+ nullptr, ePropertyTerminalWidth);
+ term_width->SetMinimumValue(10);
+ term_width->SetMaximumValue(1024);
+
+ // Turn off use-color if this is a dumb terminal.
+ const char *term = getenv("TERM");
+ if (term && !strcmp(term, "dumb"))
+ SetUseColor(false);
+}
+
+Debugger::~Debugger() { Clear(); }
+
+void Debugger::Clear() {
+ //----------------------------------------------------------------------
+ // Make sure we call this function only once. With the C++ global
+ // destructor chain having a list of debuggers and with code that can be
+ // running on other threads, we need to ensure this doesn't happen
+ // multiple times.
+ //
+ // The following functions call Debugger::Clear():
+ // Debugger::~Debugger();
+ // static void Debugger::Destroy(lldb::DebuggerSP &debugger_sp);
+ // static void Debugger::Terminate();
+ //----------------------------------------------------------------------
+ std::call_once(m_clear_once, [this]() {
+ ClearIOHandlers();
+ StopIOHandlerThread();
+ StopEventHandlerThread();
+ m_listener_sp->Clear();
+ int num_targets = m_target_list.GetNumTargets();
+ for (int i = 0; i < num_targets; i++) {
+ TargetSP target_sp(m_target_list.GetTargetAtIndex(i));
+ if (target_sp) {
+ ProcessSP process_sp(target_sp->GetProcessSP());
+ if (process_sp)
+ process_sp->Finalize();
+ target_sp->Destroy();
+ }
+ }
+ 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();
-Debugger::~Debugger ()
-{
- Clear();
+ m_command_interpreter_ap->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;
+bool Debugger::GetCloseInputOnEOF() const {
+ // return m_input_comm.GetCloseOnEOF();
+ return false;
}
-void
-Debugger::SetCloseInputOnEOF (bool b)
-{
-// m_input_comm.SetCloseOnEOF(b);
+void Debugger::SetCloseInputOnEOF(bool b) {
+ // m_input_comm.SetCloseOnEOF(b);
}
-bool
-Debugger::GetAsyncExecution ()
-{
- return !m_command_interpreter_ap->GetSynchronous();
+bool Debugger::GetAsyncExecution() {
+ return !m_command_interpreter_ap->GetSynchronous();
}
-void
-Debugger::SetAsyncExecution (bool async_execution)
-{
- m_command_interpreter_ap->SetSynchronous (!async_execution);
+void Debugger::SetAsyncExecution(bool async_execution) {
+ m_command_interpreter_ap->SetSynchronous(!async_execution);
}
-void
-Debugger::SetInputFileHandle (FILE *fh, bool tranfer_ownership)
-{
- if (m_input_file_sp)
- m_input_file_sp->GetFile().SetStream (fh, tranfer_ownership);
- else
- m_input_file_sp.reset (new StreamFile (fh, tranfer_ownership));
+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);
+ 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 ();
+ // 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::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));
-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);
-}
+ File &out_file = m_output_file_sp->GetFile();
+ if (!out_file.IsValid())
+ out_file.SetStream(stdout, 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);
- }
+ // 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::RestoreInputTerminalState ()
-{
- m_terminal_state.Restore();
-}
+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));
-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;
+ File &err_file = m_error_file_sp->GetFile();
+ if (!err_file.IsValid())
+ err_file.SetStream(stderr, false);
}
-void
-Debugger::DispatchInputInterrupt()
-{
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+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)
- reader_sp->Interrupt();
+ PopIOHandler(reader_sp);
+ }
}
-void
-Debugger::DispatchInputEndOfFile()
-{
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+void Debugger::ExecuteIOHandlers() {
+ while (true) {
IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (reader_sp)
- reader_sp->GotEOF();
-}
+ if (!reader_sp)
+ break;
-void
-Debugger::ClearIOHandlers()
-{
- // The bottom input reader should be the main debugger input reader. We do not want to close that one here.
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- while (m_input_reader_stack.GetSize() > 1)
- {
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (reader_sp)
- PopIOHandler(reader_sp);
- }
-}
+ reader_sp->Run();
-void
-Debugger::ExecuteIOHandlers()
-{
- while (true)
- {
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (!reader_sp)
- break;
-
- reader_sp->Run();
-
- // Remove all input readers that are done from the top of the stack
- while (true)
- {
- IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
- if (top_reader_sp && top_reader_sp->GetIsDone())
- PopIOHandler (top_reader_sp);
- else
- break;
- }
+ // Remove all input readers that are done from the top of the stack
+ while (true) {
+ IOHandlerSP top_reader_sp = m_input_reader_stack.Top();
+ if (top_reader_sp && top_reader_sp->GetIsDone())
+ PopIOHandler(top_reader_sp);
+ else
+ break;
}
- ClearIOHandlers();
+ }
+ ClearIOHandlers();
}
-bool
-Debugger::IsTopIOHandler (const lldb::IOHandlerSP& reader_sp)
-{
- return m_input_reader_stack.IsTop (reader_sp);
+bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) {
+ return m_input_reader_stack.IsTop(reader_sp);
}
-bool
-Debugger::CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type)
-{
- return m_input_reader_stack.CheckTopIOHandlerTypes (top_type, second_top_type);
+bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type,
+ IOHandler::Type second_top_type) {
+ return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type);
}
-void
-Debugger::PrintAsync (const char *s, size_t len, bool is_stdout)
-{
- lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
- m_input_reader_stack.PrintAsync(stream.get(), s, len);
+void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) {
+ lldb::StreamFileSP stream = is_stdout ? GetOutputFile() : GetErrorFile();
+ m_input_reader_stack.PrintAsync(stream.get(), s, len);
}
-ConstString
-Debugger::GetTopIOHandlerControlSequence(char ch)
-{
- return m_input_reader_stack.GetTopIOHandlerControlSequence (ch);
+ConstString Debugger::GetTopIOHandlerControlSequence(char ch) {
+ return m_input_reader_stack.GetTopIOHandlerControlSequence(ch);
}
-const char *
-Debugger::GetIOHandlerCommandPrefix()
-{
- return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
+const char *Debugger::GetIOHandlerCommandPrefix() {
+ return m_input_reader_stack.GetTopIOHandlerCommandPrefix();
}
-const char *
-Debugger::GetIOHandlerHelpPrologue()
-{
- return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
+const char *Debugger::GetIOHandlerHelpPrologue() {
+ return m_input_reader_stack.GetTopIOHandlerHelpPrologue();
}
-void
-Debugger::RunIOHandler (const IOHandlerSP& reader_sp)
-{
- PushIOHandler (reader_sp);
+void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) {
+ PushIOHandler(reader_sp);
- IOHandlerSP top_reader_sp = reader_sp;
- while (top_reader_sp)
- {
- top_reader_sp->Run();
+ IOHandlerSP top_reader_sp = reader_sp;
+ while (top_reader_sp) {
+ top_reader_sp->Run();
- if (top_reader_sp.get() == reader_sp.get())
- {
- if (PopIOHandler (reader_sp))
- break;
- }
+ if (top_reader_sp.get() == reader_sp.get()) {
+ if (PopIOHandler(reader_sp))
+ break;
+ }
- while (true)
- {
- top_reader_sp = m_input_reader_stack.Top();
- if (top_reader_sp && top_reader_sp->GetIsDone())
- PopIOHandler (top_reader_sp);
- else
- break;
- }
+ while (true) {
+ top_reader_sp = m_input_reader_stack.Top();
+ if (top_reader_sp && top_reader_sp->GetIsDone())
+ PopIOHandler(top_reader_sp);
+ else
+ break;
}
+ }
}
-void
-Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, StreamFileSP &out, StreamFileSP &err)
-{
- // Before an IOHandler runs, it must have in/out/err streams.
- // This function is called when one ore more of the streams
- // are nullptr. We use the top input reader's in/out/err streams,
- // or fall back to the debugger file handles, or we fall back
- // onto stdin/stdout/stderr as a last resort.
-
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
- // If no STDIN has been set, then set it appropriately
+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)
- {
- if (top_reader_sp)
- in = top_reader_sp->GetInputStreamFile();
- else
- in = GetInputFile();
-
- // If there is nothing, use stdin
- if (!in)
- in = StreamFileSP(new StreamFile(stdin, false));
- }
- // If no STDOUT has been set, then set it appropriately
+ in = StreamFileSP(new StreamFile(stdin, false));
+ }
+ // If no STDOUT has been set, then set it appropriately
+ if (!out) {
+ if (top_reader_sp)
+ out = top_reader_sp->GetOutputStreamFile();
+ else
+ out = GetOutputFile();
+
+ // If there is nothing, use stdout
if (!out)
- {
- if (top_reader_sp)
- out = top_reader_sp->GetOutputStreamFile();
- else
- out = GetOutputFile();
-
- // If there is nothing, use stdout
- if (!out)
- out = StreamFileSP(new StreamFile(stdout, false));
- }
- // If no STDERR has been set, then set it appropriately
- if (!err)
- {
- if (top_reader_sp)
- err = top_reader_sp->GetErrorStreamFile();
- else
- err = GetErrorFile();
+ 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));
- }
+ // 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;
+void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) {
+ if (!reader_sp)
+ return;
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- // Get the current top input reader...
- IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
+ // Get the current top input reader...
+ IOHandlerSP top_reader_sp(m_input_reader_stack.Top());
- // Don't push the same IO handler twice...
- if (reader_sp == top_reader_sp)
- return;
+ // Don't push the same IO handler twice...
+ if (reader_sp == top_reader_sp)
+ return;
- // Push our new input reader
- m_input_reader_stack.Push(reader_sp);
- reader_sp->Activate();
+ // Push our new input reader
+ m_input_reader_stack.Push(reader_sp);
+ reader_sp->Activate();
- // Interrupt the top input reader to it will exit its Run() function
- // and let this new input reader take over
- if (top_reader_sp)
- {
- top_reader_sp->Deactivate();
- top_reader_sp->Cancel();
- }
+ // Interrupt the top input reader to it will exit its Run() function
+ // and let this new input reader take over
+ if (top_reader_sp) {
+ top_reader_sp->Deactivate();
+ top_reader_sp->Cancel();
+ }
}
-bool
-Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp)
-{
- if (!pop_reader_sp)
- return false;
+bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) {
+ if (!pop_reader_sp)
+ return false;
- std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
+ std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex());
- // The reader on the stop of the stack is done, so let the next
- // read on the stack refresh its prompt and if there is one...
- if (m_input_reader_stack.IsEmpty())
- return false;
+ // The reader on the stop of the stack is done, so let the next
+ // read on the stack refresh its prompt and if there is one...
+ if (m_input_reader_stack.IsEmpty())
+ return false;
- IOHandlerSP reader_sp(m_input_reader_stack.Top());
+ IOHandlerSP reader_sp(m_input_reader_stack.Top());
- if (pop_reader_sp != reader_sp)
- return false;
+ if (pop_reader_sp != reader_sp)
+ return false;
- reader_sp->Deactivate();
- reader_sp->Cancel();
- m_input_reader_stack.Pop();
+ reader_sp->Deactivate();
+ reader_sp->Cancel();
+ m_input_reader_stack.Pop();
- reader_sp = m_input_reader_stack.Top();
- if (reader_sp)
- reader_sp->Activate();
+ reader_sp = m_input_reader_stack.Top();
+ if (reader_sp)
+ reader_sp->Activate();
- return true;
+ return true;
}
-StreamSP
-Debugger::GetAsyncOutputStream ()
-{
- return StreamSP (new StreamAsynchronousIO (*this, true));
+StreamSP Debugger::GetAsyncOutputStream() {
+ return StreamSP(new StreamAsynchronousIO(*this, true));
}
-StreamSP
-Debugger::GetAsyncErrorStream ()
-{
- return StreamSP (new StreamAsynchronousIO (*this, false));
-}
+StreamSP Debugger::GetAsyncErrorStream() {
+ return StreamSP(new StreamAsynchronousIO(*this, false));
+}
-size_t
-Debugger::GetNumDebuggers()
-{
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- return g_debugger_list_ptr->size();
- }
- return 0;
+size_t Debugger::GetNumDebuggers() {
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ return g_debugger_list_ptr->size();
+ }
+ return 0;
}
-lldb::DebuggerSP
-Debugger::GetDebuggerAtIndex (size_t index)
-{
- DebuggerSP debugger_sp;
-
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- if (index < g_debugger_list_ptr->size())
- debugger_sp = g_debugger_list_ptr->at(index);
- }
+lldb::DebuggerSP Debugger::GetDebuggerAtIndex(size_t index) {
+ DebuggerSP debugger_sp;
+
+ 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;
+ return debugger_sp;
}
-DebuggerSP
-Debugger::FindDebuggerWithID (lldb::user_id_t id)
-{
- DebuggerSP debugger_sp;
+DebuggerSP Debugger::FindDebuggerWithID(lldb::user_id_t id) {
+ DebuggerSP debugger_sp;
- if (g_debugger_list_ptr && g_debugger_list_mutex_ptr)
- {
- std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
- DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
- for (pos = g_debugger_list_ptr->begin (); pos != end; ++pos)
- {
- if ((*pos)->GetID() == id)
- {
- debugger_sp = *pos;
- break;
- }
- }
+ if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) {
+ std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr);
+ DebuggerList::iterator pos, end = g_debugger_list_ptr->end();
+ for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) {
+ if ((*pos)->GetID() == id) {
+ debugger_sp = *pos;
+ break;
+ }
}
- return debugger_sp;
+ }
+ return debugger_sp;
}
#if 0
@@ -1259,626 +1118,534 @@ TestPromptFormats (StackFrame *frame)
}
#endif
-bool
-Debugger::FormatDisassemblerAddress (const FormatEntity::Entry *format,
- const SymbolContext *sc,
- const SymbolContext *prev_sc,
- const ExecutionContext *exe_ctx,
- const Address *addr,
- Stream &s)
-{
- FormatEntity::Entry format_entry;
-
- if (format == nullptr)
- {
- if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
- format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
- if (format == nullptr)
- {
- FormatEntity::Parse("${addr}: ", format_entry);
- format = &format_entry;
- }
- }
- bool function_changed = false;
- bool initial_function = false;
- if (prev_sc && (prev_sc->function || prev_sc->symbol))
- {
- if (sc && (sc->function || sc->symbol))
- {
- if (prev_sc->symbol && sc->symbol)
- {
- if (!sc->symbol->Compare (prev_sc->symbol->GetName(), prev_sc->symbol->GetType()))
- {
- function_changed = true;
- }
- }
- else if (prev_sc->function && sc->function)
- {
- if (prev_sc->function->GetMangled() != sc->function->GetMangled())
- {
- function_changed = true;
- }
- }
- }
- }
- // The first context on a list of instructions will have a prev_sc that
- // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
- // would return false. But we do get a prev_sc pointer.
- if ((sc && (sc->function || sc->symbol))
- && prev_sc && (prev_sc->function == nullptr && prev_sc->symbol == nullptr))
- {
- initial_function = true;
- }
- return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr, function_changed, initial_function);
-}
-
-void
-Debugger::SetLoggingCallback (lldb::LogOutputCallback log_callback, void *baton)
-{
- // For simplicity's sake, I am not going to deal with how to close down any
- // open logging streams, I just redirect everything from here on out to the
- // callback.
- m_log_callback_stream_sp.reset (new StreamCallback (log_callback, baton));
-}
-
-bool
-Debugger::EnableLog (const char *channel, const char **categories, const char *log_file, uint32_t log_options, Stream &error_stream)
-{
- StreamSP log_stream_sp;
- if (m_log_callback_stream_sp)
- {
- log_stream_sp = m_log_callback_stream_sp;
- // For now when using the callback mode you always get thread & timestamp.
- log_options |= LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
- }
- else if (log_file == nullptr || *log_file == '\0')
- {
- log_stream_sp = GetOutputFile();
- }
- else
- {
- LogStreamMap::iterator pos = m_log_streams.find(log_file);
- if (pos != m_log_streams.end())
- log_stream_sp = pos->second.lock();
- if (!log_stream_sp)
- {
- uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate
- | File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
- if (! (log_options & LLDB_LOG_OPTION_APPEND))
- options |= File::eOpenOptionTruncate;
-
- log_stream_sp.reset (new StreamFile (log_file, options));
- m_log_streams[log_file] = log_stream_sp;
- }
- }
- 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;
+bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format,
+ const SymbolContext *sc,
+ const SymbolContext *prev_sc,
+ const ExecutionContext *exe_ctx,
+ const Address *addr, Stream &s) {
+ FormatEntity::Entry format_entry;
+
+ if (format == nullptr) {
+ if (exe_ctx != nullptr && exe_ctx->HasTargetScope())
+ format = exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
+ if (format == nullptr) {
+ FormatEntity::Parse("${addr}: ", format_entry);
+ format = &format_entry;
+ }
+ }
+ bool function_changed = false;
+ bool initial_function = false;
+ if (prev_sc && (prev_sc->function || prev_sc->symbol)) {
+ if (sc && (sc->function || sc->symbol)) {
+ if (prev_sc->symbol && sc->symbol) {
+ if (!sc->symbol->Compare(prev_sc->symbol->GetName(),
+ prev_sc->symbol->GetType())) {
+ function_changed = true;
+ }
+ } else if (prev_sc->function && sc->function) {
+ if (prev_sc->function->GetMangled() != sc->function->GetMangled()) {
+ function_changed = true;
+ }
+ }
+ }
+ }
+ // The first context on a list of instructions will have a prev_sc that
+ // has no Function or Symbol -- if SymbolContext had an IsValid() method, it
+ // would return false. But we do get a prev_sc pointer.
+ if ((sc && (sc->function || sc->symbol)) && prev_sc &&
+ (prev_sc->function == nullptr && prev_sc->symbol == nullptr)) {
+ initial_function = true;
+ }
+ return FormatEntity::Format(*format, s, sc, exe_ctx, addr, nullptr,
+ function_changed, initial_function);
+}
+
+void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
+ void *baton) {
+ // For simplicity's sake, I am not going to deal with how to close down any
+ // open logging streams, I just redirect everything from here on out to the
+ // callback.
+ m_log_callback_stream_sp.reset(new StreamCallback(log_callback, baton));
+}
+
+bool Debugger::EnableLog(const char *channel, const char **categories,
+ const char *log_file, uint32_t log_options,
+ Stream &error_stream) {
+ StreamSP log_stream_sp;
+ if (m_log_callback_stream_sp) {
+ log_stream_sp = m_log_callback_stream_sp;
+ // For now when using the callback mode you always get thread & timestamp.
+ log_options |=
+ LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
+ } else if (log_file == nullptr || *log_file == '\0') {
+ log_stream_sp = GetOutputFile();
+ } else {
+ LogStreamMap::iterator pos = m_log_streams.find(log_file);
+ if (pos != m_log_streams.end())
+ log_stream_sp = pos->second.lock();
+ if (!log_stream_sp) {
+ uint32_t options = File::eOpenOptionWrite | File::eOpenOptionCanCreate |
+ File::eOpenOptionCloseOnExec | File::eOpenOptionAppend;
+ if (!(log_options & LLDB_LOG_OPTION_APPEND))
+ options |= File::eOpenOptionTruncate;
+
+ log_stream_sp.reset(new StreamFile(log_file, options));
+ m_log_streams[log_file] = log_stream_sp;
+ }
+ }
+ 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;
}
// 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();
- }
- }
- }
-// 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.
-// }
+void Debugger::HandleBreakpointEvent(const EventSP &event_sp) {
+ using namespace lldb;
+ const uint32_t event_type =
+ Breakpoint::BreakpointEventData::GetBreakpointEventTypeFromEvent(
+ event_sp);
+
+ // if (event_type & eBreakpointEventTypeAdded
+ // || event_type & eBreakpointEventTypeRemoved
+ // || event_type & eBreakpointEventTypeEnabled
+ // || event_type & eBreakpointEventTypeDisabled
+ // || event_type & eBreakpointEventTypeCommandChanged
+ // || event_type & eBreakpointEventTypeConditionChanged
+ // || event_type & eBreakpointEventTypeIgnoreChanged
+ // || event_type & eBreakpointEventTypeLocationsResolved)
+ // {
+ // // Don't do anything about these events, since the breakpoint
+ // commands already echo these actions.
+ // }
+ //
+ if (event_type & eBreakpointEventTypeLocationsAdded) {
+ uint32_t num_new_locations =
+ Breakpoint::BreakpointEventData::GetNumBreakpointLocationsFromEvent(
+ event_sp);
+ if (num_new_locations > 0) {
+ BreakpointSP breakpoint =
+ Breakpoint::BreakpointEventData::GetBreakpointFromEvent(event_sp);
+ StreamSP output_sp(GetAsyncOutputStream());
+ if (output_sp) {
+ output_sp->Printf("%d location%s added to breakpoint %d\n",
+ num_new_locations, num_new_locations == 1 ? "" : "s",
+ breakpoint->GetID());
+ output_sp->Flush();
+ }
+ }
+ }
+ // else if (event_type & eBreakpointEventTypeLocationsRemoved)
+ // {
+ // // These locations just get disabled, not sure it is worth spamming
+ // folks about this on the command line.
+ // }
+ // else if (event_type & eBreakpointEventTypeLocationsResolved)
+ // {
+ // // This might be an interesting thing to note, but I'm going to
+ // leave it quiet for now, it just looked noisy.
+ // }
+}
+
+size_t Debugger::GetProcessSTDOUT(Process *process, Stream *stream) {
+ size_t total_bytes = 0;
+ if (stream == nullptr)
+ stream = GetOutputFile().get();
+
+ if (stream) {
+ // The process has stuff waiting for stdout; get it and write it out to the
+ // appropriate place.
+ if (process == nullptr) {
+ TargetSP target_sp = GetTargetList().GetSelectedTarget();
+ if (target_sp)
+ process = target_sp->GetProcessSP().get();
+ }
+ if (process) {
+ Error error;
+ size_t len;
+ char stdio_buffer[1024];
+ while ((len = process->GetSTDOUT(stdio_buffer, sizeof(stdio_buffer),
+ error)) > 0) {
+ stream->Write(stdio_buffer, len);
+ total_bytes += len;
+ }
+ }
+ stream->Flush();
+ }
+ 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();
+ }
+ return total_bytes;
}
-size_t
-Debugger::GetProcessSTDOUT (Process *process, Stream *stream)
-{
- size_t total_bytes = 0;
- if (stream == nullptr)
- stream = GetOutputFile().get();
+// 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());
+
+ StreamSP output_stream_sp = GetAsyncOutputStream();
+ StreamSP error_stream_sp = GetAsyncErrorStream();
+ const bool gui_enabled = IsForwardingEvents();
+
+ if (!gui_enabled) {
+ bool pop_process_io_handler = false;
+ assert(process_sp);
+
+ bool state_is_stopped = false;
+ const bool got_state_changed =
+ (event_type & Process::eBroadcastBitStateChanged) != 0;
+ const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
+ const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
+ const bool got_structured_data =
+ (event_type & Process::eBroadcastBitStructuredData) != 0;
+
+ if (got_state_changed) {
+ StateType event_state =
+ Process::ProcessEventData::GetStateFromEvent(event_sp.get());
+ state_is_stopped = StateIsStoppedState(event_state, false);
+ }
+
+ // Display running state changes first before any STDIO
+ if (got_state_changed && !state_is_stopped) {
+ Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(),
+ pop_process_io_handler);
+ }
+
+ // Now display and STDOUT
+ if (got_stdout || got_state_changed) {
+ GetProcessSTDOUT(process_sp.get(), output_stream_sp.get());
+ }
+
+ // Now display and STDERR
+ if (got_stderr || got_state_changed) {
+ GetProcessSTDERR(process_sp.get(), error_stream_sp.get());
+ }
+
+ // 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();
- 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;
+ // Print it.
+ output_stream_sp->PutCString(content_stream.GetString().c_str());
}
- }
- 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;
+ } 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);
+ }
+ }
+}
+
+bool Debugger::IsForwardingEvents() { return (bool)m_forward_listener_sp; }
+
+void Debugger::EnableForwardEvents(const ListenerSP &listener_sp) {
+ m_forward_listener_sp = listener_sp;
+}
+
+void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) {
+ m_forward_listener_sp.reset();
+}
+
+void Debugger::DefaultEventHandler() {
+ ListenerSP listener_sp(GetListener());
+ ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
+ ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
+ ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
+ BroadcastEventSpec target_event_spec(broadcaster_class_target,
+ Target::eBroadcastBitBreakpointChanged);
+
+ BroadcastEventSpec process_event_spec(
+ broadcaster_class_process,
+ Process::eBroadcastBitStateChanged | Process::eBroadcastBitSTDOUT |
+ Process::eBroadcastBitSTDERR | Process::eBroadcastBitStructuredData);
+
+ BroadcastEventSpec thread_event_spec(broadcaster_class_thread,
+ Thread::eBroadcastBitStackChanged |
+ Thread::eBroadcastBitThreadSelected);
+
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ target_event_spec);
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ process_event_spec);
+ listener_sp->StartListeningForEventSpec(m_broadcaster_manager_sp,
+ thread_event_spec);
+ listener_sp->StartListeningForEvents(
+ m_command_interpreter_ap.get(),
+ CommandInterpreter::eBroadcastBitQuitCommandReceived |
+ CommandInterpreter::eBroadcastBitAsynchronousOutputData |
+ CommandInterpreter::eBroadcastBitAsynchronousErrorData);
+
+ // Let the thread that spawned us know that we have started up and
+ // that we are now listening to all required events so no events get missed
+ m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
+
+ bool done = false;
+ while (!done) {
+ EventSP event_sp;
+ if (listener_sp->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);
}
- }
- 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());
-
- StreamSP output_stream_sp = GetAsyncOutputStream();
- StreamSP error_stream_sp = GetAsyncErrorStream();
- const bool gui_enabled = IsForwardingEvents();
-
- if (!gui_enabled)
- {
- bool pop_process_io_handler = false;
- assert (process_sp);
-
- bool state_is_stopped = false;
- const bool got_state_changed = (event_type & Process::eBroadcastBitStateChanged) != 0;
- const bool got_stdout = (event_type & Process::eBroadcastBitSTDOUT) != 0;
- const bool got_stderr = (event_type & Process::eBroadcastBitSTDERR) != 0;
- const bool got_structured_data = (event_type &
- Process::eBroadcastBitStructuredData) != 0;
-
- if (got_state_changed)
- {
- StateType event_state = Process::ProcessEventData::GetStateFromEvent (event_sp.get());
- state_is_stopped = StateIsStoppedState(event_state, false);
- }
-
- // Display running state changes first before any STDIO
- if (got_state_changed && !state_is_stopped)
- {
- Process::HandleProcessStateChangedEvent (event_sp, output_stream_sp.get(), pop_process_io_handler);
- }
-
- // Now display and STDOUT
- if (got_stdout || got_state_changed)
- {
- GetProcessSTDOUT (process_sp.get(), output_stream_sp.get());
- }
-
- // Now display and STDERR
- if (got_stderr || got_state_changed)
- {
- GetProcessSTDERR (process_sp.get(), error_stream_sp.get());
- }
-
- // 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());
- }
+ } 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();
}
+ }
}
+ }
}
- // 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();
+ if (m_forward_listener_sp)
+ m_forward_listener_sp->AddEvent(event_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);
- }
- }
+lldb::thread_result_t Debugger::EventHandlerThread(lldb::thread_arg_t arg) {
+ ((Debugger *)arg)->DefaultEventHandler();
+ return NULL;
}
-bool
-Debugger::IsForwardingEvents ()
-{
- return (bool)m_forward_listener_sp;
-}
+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);
-void
-Debugger::EnableForwardEvents (const ListenerSP &listener_sp)
-{
- m_forward_listener_sp = listener_sp;
-}
+ // 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);
-void
-Debugger::CancelForwardEvents (const ListenerSP &listener_sp)
-{
- m_forward_listener_sp.reset();
+ // 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::DefaultEventHandler()
-{
- ListenerSP listener_sp(GetListener());
- ConstString broadcaster_class_target(Target::GetStaticBroadcasterClass());
- ConstString broadcaster_class_process(Process::GetStaticBroadcasterClass());
- ConstString broadcaster_class_thread(Thread::GetStaticBroadcasterClass());
- BroadcastEventSpec target_event_spec (broadcaster_class_target,
- Target::eBroadcastBitBreakpointChanged);
-
- BroadcastEventSpec process_event_spec (broadcaster_class_process,
- Process::eBroadcastBitStateChanged |
- Process::eBroadcastBitSTDOUT |
- Process::eBroadcastBitSTDERR |
- Process::eBroadcastBitStructuredData);
-
- BroadcastEventSpec thread_event_spec (broadcaster_class_thread,
- Thread::eBroadcastBitStackChanged |
- Thread::eBroadcastBitThreadSelected );
-
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, target_event_spec);
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, process_event_spec);
- listener_sp->StartListeningForEventSpec (m_broadcaster_manager_sp, thread_event_spec);
- listener_sp->StartListeningForEvents (m_command_interpreter_ap.get(),
- CommandInterpreter::eBroadcastBitQuitCommandReceived |
- CommandInterpreter::eBroadcastBitAsynchronousOutputData |
- CommandInterpreter::eBroadcastBitAsynchronousErrorData );
-
- // Let the thread that spawned us know that we have started up and
- // that we are now listening to all required events so no events get missed
- m_sync_broadcaster.BroadcastEvent(eBroadcastBitEventThreadIsListening);
-
- bool done = false;
- while (!done)
- {
- EventSP event_sp;
- if (listener_sp->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);
- }
- }
- }
+void Debugger::StopEventHandlerThread() {
+ if (m_event_handler_thread.IsJoinable()) {
+ GetCommandInterpreter().BroadcastEvent(
+ CommandInterpreter::eBroadcastBitQuitCommandReceived);
+ m_event_handler_thread.Join(nullptr);
+ }
}
-lldb::thread_result_t
-Debugger::EventHandlerThread (lldb::thread_arg_t arg)
-{
- ((Debugger *)arg)->DefaultEventHandler();
- return NULL;
+lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) {
+ Debugger *debugger = (Debugger *)arg;
+ debugger->ExecuteIOHandlers();
+ debugger->StopEventHandlerThread();
+ return NULL;
}
-bool
-Debugger::StartEventHandlerThread()
-{
- if (!m_event_handler_thread.IsJoinable())
- {
- // We must synchronize with the DefaultEventHandler() thread to ensure
- // it is up and running and listening to events before we return from
- // this function. We do this by listening to events for the
- // eBroadcastBitEventThreadIsListening from the m_sync_broadcaster
- ListenerSP listener_sp(Listener::MakeListener("lldb.debugger.event-handler"));
- listener_sp->StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening);
-
- // Use larger 8MB stack for this thread
- m_event_handler_thread = ThreadLauncher::LaunchThread("lldb.debugger.event-handler",
- EventHandlerThread,
- this,
- nullptr,
- g_debugger_event_thread_stack_bytes);
-
- // Make sure DefaultEventHandler() is running and listening to events before we return
- // from this function. We are only listening for events of type
- // eBroadcastBitEventThreadIsListening so we don't need to check the event, we just need
- // to wait an infinite amount of time for it (nullptr timeout as the first parameter)
- lldb::EventSP event_sp;
- listener_sp->WaitForEvent(std::chrono::microseconds(0), event_sp);
- }
- return m_event_handler_thread.IsJoinable();
-}
+bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); }
-void
-Debugger::StopEventHandlerThread()
-{
- if (m_event_handler_thread.IsJoinable())
- {
- GetCommandInterpreter().BroadcastEvent(CommandInterpreter::eBroadcastBitQuitCommandReceived);
- m_event_handler_thread.Join(nullptr);
- }
+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();
}
-lldb::thread_result_t
-Debugger::IOHandlerThread (lldb::thread_arg_t arg)
-{
- Debugger *debugger = (Debugger *)arg;
- debugger->ExecuteIOHandlers();
- debugger->StopEventHandlerThread();
- return NULL;
+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);
+ }
}
-bool
-Debugger::HasIOHandlerThread()
-{
- return m_io_handler_thread.IsJoinable();
+void Debugger::JoinIOHandlerThread() {
+ if (HasIOHandlerThread()) {
+ thread_result_t result;
+ m_io_handler_thread.Join(&result);
+ m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
+ }
}
-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();
+Target *Debugger::GetDummyTarget() {
+ return m_target_list.GetDummyTarget(*this).get();
}
-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);
- }
-}
+Target *Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) {
+ Target *target = nullptr;
+ if (!prefer_dummy) {
+ target = m_target_list.GetSelectedTarget().get();
+ if (target)
+ return target;
+ }
-void
-Debugger::JoinIOHandlerThread()
-{
- if (HasIOHandlerThread())
- {
- thread_result_t result;
- m_io_handler_thread.Join(&result);
- m_io_handler_thread = LLDB_INVALID_HOST_THREAD;
- }
+ return GetDummyTarget();
}
-Target *
-Debugger::GetDummyTarget()
-{
- return m_target_list.GetDummyTarget (*this).get();
-}
+Error Debugger::RunREPL(LanguageType language, const char *repl_options) {
+ Error err;
+ FileSpec repl_executable;
-Target *
-Debugger::GetSelectedOrDummyTarget(bool prefer_dummy)
-{
- Target *target = nullptr;
- if (!prefer_dummy)
- {
- target = m_target_list.GetSelectedTarget().get();
- if (target)
- return target;
- }
-
- return GetDummyTarget();
-}
+ if (language == eLanguageTypeUnknown) {
+ std::set<LanguageType> repl_languages;
-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;
- }
+ 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));
+ Target *const target =
+ nullptr; // passing in an empty target means the REPL must create one
- 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();
-
+ REPLSP repl_sp(REPL::Create(err, language, this, target, repl_options));
+
+ if (!err.Success()) {
+ return err;
+ }
+
+ if (!repl_sp) {
+ err.SetErrorStringWithFormat("couldn't find a REPL for %s",
+ Language::GetNameForLanguageType(language));
return err;
+ }
+
+ repl_sp->SetCompilerOptions(repl_options);
+ repl_sp->RunLoop();
+
+ return err;
}
More information about the lldb-commits
mailing list