aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/lldb/source/Utility
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-20 15:00:15 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-20 15:00:15 +0000
commit763d4102c9736544f95a61d4d0a9a5be8c5a5df1 (patch)
treeb4a2965a49e80461fb52cd69d55f966058e7ef4d /contrib/llvm/tools/lldb/source/Utility
parent0e23b2ff8c430cd1145afb7bd55917c326bb1d06 (diff)
parent94994d372d014ce4c8758b9605d63fae651bd8aa (diff)
downloadsrc-763d4102c9736544f95a61d4d0a9a5be8c5a5df1.tar.gz
src-763d4102c9736544f95a61d4d0a9a5be8c5a5df1.zip
Merge lldb trunk r351319, resolve conflicts, and update FREEBSD-Xlist.
Notes
Notes: svn path=/projects/clang800-import/; revision=343218
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Utility')
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp42
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Broadcaster.cpp479
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp43
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/ConstString.cpp66
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp4
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp32
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp20
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Event.cpp301
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/FastDemangle.cpp2393
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/FileSpec.cpp220
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/JSON.cpp8
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/LLDBAssert.cpp20
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Listener.cpp468
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Log.cpp14
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Logging.cpp4
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Range.cpp76
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/RegisterValue.cpp877
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Reproducer.cpp225
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Scalar.cpp2695
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/SelectHelper.cpp10
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/State.cpp111
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Status.cpp43
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Stream.cpp140
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/StreamGDBRemote.cpp4
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/StreamString.cpp7
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp4
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp2
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/StringList.cpp12
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/StructuredData.cpp19
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/TildeExpressionResolver.cpp12
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/Timer.cpp8
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/UUID.cpp7
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/VASprintf.cpp10
-rw-r--r--contrib/llvm/tools/lldb/source/Utility/VMRange.cpp10
35 files changed, 5449 insertions, 2939 deletions
diff --git a/contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp b/contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp
index 1c50c313e0d1..752fb182d79a 100644
--- a/contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp
@@ -11,15 +11,15 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/NameMatches.h"
-#include "lldb/Utility/Stream.h" // for Stream
+#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
-#include "lldb/lldb-defines.h" // for LLDB_INVALID_C...
+#include "lldb/lldb-defines.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Twine.h" // for Twine
+#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/BinaryFormat/MachO.h" // for CPUType::CPU_T...
-#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH
+#include "llvm/BinaryFormat/MachO.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Host.h"
using namespace lldb;
@@ -610,10 +610,8 @@ const char *ArchSpec::GetArchitectureName() const {
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;
+ return machine == llvm::Triple::mips || machine == llvm::Triple::mipsel ||
+ machine == llvm::Triple::mips64 || machine == llvm::Triple::mips64el;
}
std::string ArchSpec::GetTargetABI() const {
@@ -815,6 +813,7 @@ bool ArchSpec::CharIsSignedByDefault() const {
case llvm::Triple::ppc64le:
case llvm::Triple::systemz:
case llvm::Triple::xcore:
+ case llvm::Triple::arc:
return false;
}
}
@@ -946,13 +945,13 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu,
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.
+ // tvos, bridgeos. 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:
@@ -1018,7 +1017,7 @@ bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const {
return IsEqualTo(rhs, false);
}
-static bool isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
+static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs,
llvm::Triple::EnvironmentType rhs) {
if (lhs == rhs)
return true;
@@ -1095,9 +1094,7 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const {
const llvm::Triple::EnvironmentType rhs_triple_env =
rhs_triple.getEnvironment();
- if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env))
- return false;
- return true;
+ return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env);
}
return false;
}
@@ -1477,7 +1474,10 @@ bool ArchSpec::IsAlwaysThumbInstructions() const {
if (GetCore() == ArchSpec::Core::eCore_arm_armv7m ||
GetCore() == ArchSpec::Core::eCore_arm_armv7em ||
- GetCore() == ArchSpec::Core::eCore_arm_armv6m) {
+ GetCore() == ArchSpec::Core::eCore_arm_armv6m ||
+ GetCore() == ArchSpec::Core::eCore_thumbv7m ||
+ GetCore() == ArchSpec::Core::eCore_thumbv7em ||
+ GetCore() == ArchSpec::Core::eCore_thumbv6m) {
return true;
}
}
diff --git a/contrib/llvm/tools/lldb/source/Utility/Broadcaster.cpp b/contrib/llvm/tools/lldb/source/Utility/Broadcaster.cpp
new file mode 100644
index 000000000000..5b9b99801b22
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Utility/Broadcaster.cpp
@@ -0,0 +1,479 @@
+//===-- Broadcaster.cpp -----------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Broadcaster.h"
+
+#include "lldb/Utility/Event.h"
+#include "lldb/Utility/Listener.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StreamString.h"
+
+#include <algorithm>
+#include <memory>
+#include <type_traits>
+
+#include <assert.h>
+#include <stddef.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name)
+ : m_broadcaster_sp(std::make_shared<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() {}
+
+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;
+ } 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);
+ ++num_names_added;
+ }
+ }
+ }
+ }
+ return num_names_added > 0;
+}
+
+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;
+ }
+ }
+
+ 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;
+}
+
+bool Broadcaster::BroadcasterImpl::EventTypeHasListeners(uint32_t event_type) {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ if (!m_hijacking_listeners.empty() && event_type & m_hijacking_masks.back())
+ return true;
+
+ for (auto &pair : GetListeners()) {
+ if (pair.second & event_type)
+ return true;
+ }
+ return false;
+}
+
+bool Broadcaster::BroadcasterImpl::RemoveListener(
+ lldb_private::Listener *listener, uint32_t event_mask) {
+ if (!listener)
+ return false;
+
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+ for (auto &pair : GetListeners()) {
+ if (pair.first.get() == listener) {
+ pair.second &= ~event_mask;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool Broadcaster::BroadcasterImpl::RemoveListener(
+ const lldb::ListenerSP &listener_sp, uint32_t event_mask) {
+ return RemoveListener(listener_sp.get(), event_mask);
+}
+
+void Broadcaster::BroadcasterImpl::BroadcastEvent(EventSP &event_sp) {
+ return PrivateBroadcastEvent(event_sp, false);
+}
+
+void Broadcaster::BroadcasterImpl::BroadcastEventIfUnique(EventSP &event_sp) {
+ return PrivateBroadcastEvent(event_sp, true);
+}
+
+void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp,
+ bool unique) {
+ // Can't add a nullptr event...
+ if (!event_sp)
+ return;
+
+ // Update the broadcaster on this event
+ event_sp->SetBroadcaster(&m_broadcaster);
+
+ const uint32_t event_type = event_sp->GetType();
+
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ ListenerSP hijacking_listener_sp;
+
+ if (!m_hijacking_listeners.empty()) {
+ assert(!m_hijacking_masks.empty());
+ hijacking_listener_sp = m_hijacking_listeners.back();
+ if ((event_type & m_hijacking_masks.back()) == 0)
+ hijacking_listener_sp.reset();
+ }
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log) {
+ StreamString event_description;
+ event_sp->Dump(&event_description);
+ log->Printf("%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, "
+ "unique =%i) hijack = %p",
+ static_cast<void *>(this), GetBroadcasterName(),
+ event_description.GetData(), unique,
+ static_cast<void *>(hijacking_listener_sp.get()));
+ }
+
+ if (hijacking_listener_sp) {
+ if (unique &&
+ hijacking_listener_sp->PeekAtNextEventForBroadcasterWithType(
+ &m_broadcaster, event_type))
+ return;
+ hijacking_listener_sp->AddEvent(event_sp);
+ } else {
+ for (auto &pair : GetListeners()) {
+ if (!(pair.second & event_type))
+ continue;
+ if (unique &&
+ pair.first->PeekAtNextEventForBroadcasterWithType(&m_broadcaster,
+ event_type))
+ continue;
+
+ pair.first->AddEvent(event_sp);
+ }
+ }
+}
+
+void Broadcaster::BroadcasterImpl::BroadcastEvent(uint32_t event_type,
+ EventData *event_data) {
+ auto event_sp = std::make_shared<Event>(event_type, event_data);
+ PrivateBroadcastEvent(event_sp, false);
+}
+
+void Broadcaster::BroadcasterImpl::BroadcastEvent(
+ uint32_t event_type, const lldb::EventDataSP &event_data_sp) {
+ auto event_sp = std::make_shared<Event>(event_type, event_data_sp);
+ PrivateBroadcastEvent(event_sp, false);
+}
+
+void Broadcaster::BroadcasterImpl::BroadcastEventIfUnique(
+ uint32_t event_type, EventData *event_data) {
+ auto event_sp = std::make_shared<Event>(event_type, event_data);
+ PrivateBroadcastEvent(event_sp, true);
+}
+
+bool Broadcaster::BroadcasterImpl::HijackBroadcaster(
+ const lldb::ListenerSP &listener_sp, uint32_t event_mask) {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log)
+ log->Printf(
+ "%p Broadcaster(\"%s\")::HijackBroadcaster (listener(\"%s\")=%p)",
+ static_cast<void *>(this), GetBroadcasterName(),
+ listener_sp->m_name.c_str(), static_cast<void *>(listener_sp.get()));
+ m_hijacking_listeners.push_back(listener_sp);
+ m_hijacking_masks.push_back(event_mask);
+ return true;
+}
+
+bool Broadcaster::BroadcasterImpl::IsHijackedForEvent(uint32_t event_mask) {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ if (!m_hijacking_listeners.empty())
+ return (event_mask & m_hijacking_masks.back()) != 0;
+ return false;
+}
+
+const char *Broadcaster::BroadcasterImpl::GetHijackingListenerName() {
+ if (m_hijacking_listeners.size()) {
+ return m_hijacking_listeners.back()->GetName();
+ } else {
+ return nullptr;
+ }
+}
+
+void Broadcaster::BroadcasterImpl::RestoreBroadcaster() {
+ std::lock_guard<std::recursive_mutex> guard(m_listeners_mutex);
+
+ if (!m_hijacking_listeners.empty()) {
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log) {
+ ListenerSP listener_sp = m_hijacking_listeners.back();
+ log->Printf("%p Broadcaster(\"%s\")::RestoreBroadcaster (about to pop "
+ "listener(\"%s\")=%p)",
+ static_cast<void *>(this), GetBroadcasterName(),
+ listener_sp->m_name.c_str(),
+ static_cast<void *>(listener_sp.get()));
+ }
+ m_hijacking_listeners.pop_back();
+ }
+ if (!m_hijacking_masks.empty())
+ m_hijacking_masks.pop_back();
+}
+
+ConstString &Broadcaster::GetBroadcasterClass() const {
+ static ConstString class_name("lldb.anonymous");
+ return class_name;
+}
+
+BroadcastEventSpec::BroadcastEventSpec(const BroadcastEventSpec &rhs) = default;
+
+bool BroadcastEventSpec::operator<(const BroadcastEventSpec &rhs) const {
+ if (GetBroadcasterClass() == rhs.GetBroadcasterClass()) {
+ return GetEventBits() < rhs.GetEventBits();
+ } else {
+ return GetBroadcasterClass() < rhs.GetBroadcasterClass();
+ }
+}
+
+BroadcastEventSpec &BroadcastEventSpec::
+operator=(const BroadcastEventSpec &rhs) = default;
+
+BroadcasterManager::BroadcasterManager() : m_manager_mutex() {}
+
+lldb::BroadcasterManagerSP BroadcasterManager::MakeBroadcasterManager() {
+ return lldb::BroadcasterManagerSP(new BroadcasterManager());
+}
+
+uint32_t BroadcasterManager::RegisterListenerForEvents(
+ const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+
+ collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end();
+ uint32_t available_bits = event_spec.GetEventBits();
+
+ while (iter != end_iter &&
+ (iter = find_if(iter, end_iter,
+ BroadcasterClassMatches(
+ event_spec.GetBroadcasterClass()))) != end_iter) {
+ available_bits &= ~((*iter).first.GetEventBits());
+ iter++;
+ }
+
+ if (available_bits != 0) {
+ m_event_map.insert(event_listener_key(
+ BroadcastEventSpec(event_spec.GetBroadcasterClass(), available_bits),
+ listener_sp));
+ m_listeners.insert(listener_sp);
+ }
+
+ return available_bits;
+}
+
+bool BroadcasterManager::UnregisterListenerForEvents(
+ const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ bool removed_some = false;
+
+ if (m_listeners.erase(listener_sp) == 0)
+ return false;
+
+ ListenerMatchesAndSharedBits predicate(event_spec, listener_sp);
+ std::vector<BroadcastEventSpec> to_be_readded;
+ uint32_t event_bits_to_remove = event_spec.GetEventBits();
+
+ // Go through the map and delete the exact matches, and build a list of
+ // matches that weren't exact to re-add:
+ while (true) {
+ collection::iterator iter, end_iter = m_event_map.end();
+ iter = find_if(m_event_map.begin(), end_iter, predicate);
+ if (iter == end_iter) {
+ break;
+ } else {
+ uint32_t iter_event_bits = (*iter).first.GetEventBits();
+ removed_some = true;
+
+ if (event_bits_to_remove != iter_event_bits) {
+ uint32_t new_event_bits = iter_event_bits & ~event_bits_to_remove;
+ to_be_readded.push_back(BroadcastEventSpec(
+ event_spec.GetBroadcasterClass(), new_event_bits));
+ }
+ m_event_map.erase(iter);
+ }
+ }
+
+ // Okay now add back the bits that weren't completely removed:
+ for (size_t i = 0; i < to_be_readded.size(); i++) {
+ m_event_map.insert(event_listener_key(to_be_readded[i], listener_sp));
+ }
+
+ return removed_some;
+}
+
+ListenerSP BroadcasterManager::GetListenerForEventSpec(
+ BroadcastEventSpec event_spec) const {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+
+ collection::const_iterator iter, end_iter = m_event_map.end();
+ iter = find_if(m_event_map.begin(), end_iter,
+ BroadcastEventSpecMatches(event_spec));
+ if (iter != end_iter)
+ return (*iter).second;
+ else
+ return nullptr;
+}
+
+void BroadcasterManager::RemoveListener(Listener *listener) {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ ListenerMatchesPointer predicate(listener);
+ listener_collection::iterator iter = m_listeners.begin(),
+ end_iter = m_listeners.end();
+
+ std::find_if(iter, end_iter, predicate);
+ if (iter != end_iter)
+ m_listeners.erase(iter);
+
+ while (true) {
+ collection::iterator iter, end_iter = m_event_map.end();
+ iter = find_if(m_event_map.begin(), end_iter, predicate);
+ if (iter == end_iter)
+ break;
+ else
+ 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::Clear() {
+ std::lock_guard<std::recursive_mutex> guard(m_manager_mutex);
+ listener_collection::iterator end_iter = m_listeners.end();
+
+ for (listener_collection::iterator iter = m_listeners.begin();
+ iter != end_iter; iter++)
+ (*iter)->BroadcasterManagerWillDestruct(this->shared_from_this());
+ m_listeners.clear();
+ m_event_map.clear();
+}
diff --git a/contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp b/contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp
index c88747e2abe3..096661b7e99f 100644
--- a/contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp
@@ -16,11 +16,10 @@ CompletionRequest::CompletionRequest(llvm::StringRef command_line,
unsigned raw_cursor_pos,
int match_start_point,
int max_return_elements,
- StringList &matches)
+ CompletionResult &result)
: m_command(command_line), m_raw_cursor_pos(raw_cursor_pos),
m_match_start_point(match_start_point),
- m_max_return_elements(max_return_elements), m_matches(&matches) {
- matches.Clear();
+ m_max_return_elements(max_return_elements), m_result(result) {
// We parse the argument up to the cursor, so the last argument in
// parsed_line is the one containing the cursor, and the cursor is after the
@@ -36,8 +35,6 @@ CompletionRequest::CompletionRequest(llvm::StringRef command_line,
m_cursor_char_position =
strlen(m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index));
- matches.Clear();
-
const char *cursor = command_line.data() + raw_cursor_pos;
if (raw_cursor_pos > 0 && cursor[-1] == ' ') {
// We are just after a space. If we are in an argument, then we will
@@ -58,3 +55,39 @@ CompletionRequest::CompletionRequest(llvm::StringRef command_line,
}
}
}
+
+std::string CompletionResult::Completion::GetUniqueKey() const {
+
+ // We build a unique key for this pair of completion:description. We
+ // prefix the key with the length of the completion string. This prevents
+ // that we could get any collisions from completions pairs such as these:
+ // "foo:", "bar" would be "foo:bar", but will now be: "4foo:bar"
+ // "foo", ":bar" would be "foo:bar", but will now be: "3foo:bar"
+
+ std::string result;
+ result.append(std::to_string(m_completion.size()));
+ result.append(m_completion);
+ result.append(m_descripton);
+ return result;
+}
+
+void CompletionResult::AddResult(llvm::StringRef completion,
+ llvm::StringRef description) {
+ Completion r(completion, description);
+
+ // Add the completion if we haven't seen the same value before.
+ if (m_added_values.insert(r.GetUniqueKey()).second)
+ m_results.push_back(r);
+}
+
+void CompletionResult::GetMatches(StringList &matches) const {
+ matches.Clear();
+ for (const Completion &completion : m_results)
+ matches.AppendString(completion.m_completion);
+}
+
+void CompletionResult::GetDescriptions(StringList &descriptions) const {
+ descriptions.Clear();
+ for (const Completion &completion : m_results)
+ descriptions.AppendString(completion.m_descripton);
+}
diff --git a/contrib/llvm/tools/lldb/source/Utility/ConstString.cpp b/contrib/llvm/tools/lldb/source/Utility/ConstString.cpp
index 5ef4b2faa3b8..9b8bea71e2ad 100644
--- a/contrib/llvm/tools/lldb/source/Utility/ConstString.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/ConstString.cpp
@@ -12,20 +12,20 @@
#include "lldb/Utility/Stream.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/iterator.h" // for iterator_facade_base
-#include "llvm/Support/Allocator.h" // for BumpPtrAllocator
-#include "llvm/Support/DJB.h" // for djbHash
-#include "llvm/Support/FormatProviders.h" // for format_provider
+#include "llvm/ADT/iterator.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/DJB.h"
+#include "llvm/Support/FormatProviders.h"
#include "llvm/Support/RWMutex.h"
#include "llvm/Support/Threading.h"
-#include <algorithm> // for min
+#include <algorithm>
#include <array>
-#include <utility> // for make_pair, pair
+#include <utility>
-#include <inttypes.h> // for PRIu64
-#include <stdint.h> // for uint8_t, uint32_t, uint64_t
-#include <string.h> // for size_t, strlen
+#include <inttypes.h>
+#include <stdint.h>
+#include <string.h>
using namespace lldb_private;
@@ -111,38 +111,34 @@ public:
}
const char *
- GetConstCStringAndSetMangledCounterPart(const char *demangled_cstr,
+ GetConstCStringAndSetMangledCounterPart(llvm::StringRef demangled,
const char *mangled_ccstr) {
- if (demangled_cstr != nullptr) {
- const char *demangled_ccstr = 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);
+ {
+ const uint8_t h = hash(demangled);
+ 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;
+ // Make or update string pool entry with the mangled counterpart
+ StringPool &map = m_string_pools[h].m_string_map;
+ StringPoolEntryType &entry = *map.try_emplace(demangled).first;
- // Extract the const version of the demangled_cstr
- demangled_ccstr = entry.getKeyData();
- }
+ entry.second = mangled_ccstr;
- {
- // 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);
- }
+ // Extract the const version of the demangled_cstr
+ demangled_ccstr = entry.getKeyData();
+ }
- // Return the constant demangled C string
- return demangled_ccstr;
+ {
+ // 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 nullptr;
+
+ // Return the constant demangled C string
+ return demangled_ccstr;
}
const char *GetConstTrimmedCStringWithLength(const char *cstr,
@@ -306,7 +302,7 @@ void ConstString::SetString(const llvm::StringRef &s) {
m_string = StringPool().GetConstCStringWithLength(s.data(), s.size());
}
-void ConstString::SetCStringWithMangledCounterpart(const char *demangled,
+void ConstString::SetStringWithMangledCounterpart(llvm::StringRef demangled,
const ConstString &mangled) {
m_string = StringPool().GetConstCStringAndSetMangledCounterPart(
demangled, mangled.m_string);
diff --git a/contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp b/contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp
index e686ee8d35e5..36cac0079ac0 100644
--- a/contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp
@@ -9,10 +9,6 @@
#include "lldb/Utility/DataBufferHeap.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
using namespace lldb_private;
diff --git a/contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp b/contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp
index 713c3c2814ea..0ab3fe5afd46 100644
--- a/contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp
@@ -13,8 +13,8 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
-#include <assert.h> // for assert
-#include <type_traits> // for move
+#include <assert.h>
+#include <type_traits>
using namespace lldb_private;
@@ -27,34 +27,6 @@ DataBufferLLVM::DataBufferLLVM(
DataBufferLLVM::~DataBufferLLVM() {}
-std::shared_ptr<DataBufferLLVM>
-DataBufferLLVM::CreateSliceFromPath(const llvm::Twine &Path, uint64_t Size,
- uint64_t Offset) {
- // If the file resides non-locally, pass the volatile flag so that we don't
- // mmap it.
- bool IsVolatile = !llvm::sys::fs::is_local(Path);
-
- auto Buffer =
- llvm::WritableMemoryBuffer::getFileSlice(Path, Size, Offset, IsVolatile);
- if (!Buffer)
- return nullptr;
- return std::shared_ptr<DataBufferLLVM>(
- new DataBufferLLVM(std::move(*Buffer)));
-}
-
-std::shared_ptr<DataBufferLLVM>
-DataBufferLLVM::CreateFromPath(const llvm::Twine &Path) {
- // If the file resides non-locally, pass the volatile flag so that we don't
- // mmap it.
- bool IsVolatile = !llvm::sys::fs::is_local(Path);
-
- auto Buffer = llvm::WritableMemoryBuffer::getFile(Path, -1, IsVolatile);
- if (!Buffer)
- return nullptr;
- return std::shared_ptr<DataBufferLLVM>(
- new DataBufferLLVM(std::move(*Buffer)));
-}
-
uint8_t *DataBufferLLVM::GetBytes() {
return reinterpret_cast<uint8_t *>(Buffer->getBufferStart());
}
diff --git a/contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp b/contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp
index 7edee3c2f279..c26c0fa63ab3 100644
--- a/contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp
@@ -13,7 +13,7 @@
#include "lldb/Utility/Endian.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/ErrorHandling.h" // for llvm_unreachable
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
diff --git a/contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp b/contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp
index 947232943aa7..ae5a3f9b7d8f 100644
--- a/contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp
@@ -9,10 +9,10 @@
#include "lldb/Utility/DataExtractor.h"
-#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS
-#include "lldb/lldb-enumerations.h" // for ByteOrder::eByteOrderBig
-#include "lldb/lldb-forward.h" // for DataBufferSP
-#include "lldb/lldb-types.h" // for offset_t
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/lldb-types.h"
#include "lldb/Utility/DataBuffer.h"
#include "lldb/Utility/DataBufferHeap.h"
@@ -28,15 +28,15 @@
#include "llvm/Support/MD5.h"
#include "llvm/Support/MathExtras.h"
-#include <algorithm> // for min
-#include <array> // for array
+#include <algorithm>
+#include <array>
#include <cassert>
-#include <cstdint> // for uint8_t, uint32_t, uint64_t
+#include <cstdint>
#include <string>
-#include <ctype.h> // for isprint
-#include <inttypes.h> // for PRIx64, PRId64
-#include <string.h> // for memcpy, memset, memchr
+#include <ctype.h>
+#include <inttypes.h>
+#include <string.h>
using namespace lldb;
using namespace lldb_private;
diff --git a/contrib/llvm/tools/lldb/source/Utility/Event.cpp b/contrib/llvm/tools/lldb/source/Utility/Event.cpp
new file mode 100644
index 000000000000..ad9f6e340f8c
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Utility/Event.cpp
@@ -0,0 +1,301 @@
+//===-- Event.cpp -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Event.h"
+
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/lldb-enumerations.h"
+
+#include <algorithm>
+
+#include <ctype.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+#pragma mark -
+#pragma mark Event
+
+//------------------------------------------------------------------
+// Event functions
+//------------------------------------------------------------------
+
+Event::Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data)
+ : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type),
+ m_data_sp(data) {}
+
+Event::Event(Broadcaster *broadcaster, uint32_t event_type,
+ const EventDataSP &event_data_sp)
+ : m_broadcaster_wp(broadcaster->GetBroadcasterImpl()), m_type(event_type),
+ m_data_sp(event_data_sp) {}
+
+Event::Event(uint32_t event_type, EventData *data)
+ : m_broadcaster_wp(), m_type(event_type), m_data_sp(data) {}
+
+Event::Event(uint32_t event_type, const EventDataSP &event_data_sp)
+ : m_broadcaster_wp(), m_type(event_type), m_data_sp(event_data_sp) {}
+
+Event::~Event() = default;
+
+void Event::Dump(Stream *s) const {
+ Broadcaster *broadcaster;
+ Broadcaster::BroadcasterImplSP broadcaster_impl_sp(m_broadcaster_wp.lock());
+ if (broadcaster_impl_sp)
+ broadcaster = broadcaster_impl_sp->GetBroadcaster();
+ else
+ broadcaster = nullptr;
+
+ if (broadcaster) {
+ StreamString event_name;
+ if (broadcaster->GetEventNames(event_name, m_type, false))
+ s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ",
+ static_cast<const void *>(this),
+ static_cast<void *>(broadcaster),
+ broadcaster->GetBroadcasterName().GetCString(), m_type,
+ event_name.GetData());
+ else
+ s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ",
+ static_cast<const void *>(this),
+ static_cast<void *>(broadcaster),
+ broadcaster->GetBroadcasterName().GetCString(), m_type);
+ } else
+ s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ",
+ static_cast<const void *>(this), m_type);
+
+ if (m_data_sp) {
+ s->PutChar('{');
+ m_data_sp->Dump(s);
+ s->PutChar('}');
+ } else
+ s->Printf("<NULL>");
+}
+
+void Event::DoOnRemoval() {
+ if (m_data_sp)
+ m_data_sp->DoOnRemoval(this);
+}
+
+#pragma mark -
+#pragma mark EventData
+
+//------------------------------------------------------------------
+// EventData functions
+//------------------------------------------------------------------
+
+EventData::EventData() = default;
+
+EventData::~EventData() = default;
+
+void EventData::Dump(Stream *s) const { s->PutCString("Generic Event Data"); }
+
+#pragma mark -
+#pragma mark EventDataBytes
+
+//------------------------------------------------------------------
+// EventDataBytes functions
+//------------------------------------------------------------------
+
+EventDataBytes::EventDataBytes() : m_bytes() {}
+
+EventDataBytes::EventDataBytes(const char *cstr) : m_bytes() {
+ SetBytesFromCString(cstr);
+}
+
+EventDataBytes::EventDataBytes(llvm::StringRef str) : m_bytes() {
+ SetBytes(str.data(), str.size());
+}
+
+EventDataBytes::EventDataBytes(const void *src, size_t src_len) : m_bytes() {
+ SetBytes(src, src_len);
+}
+
+EventDataBytes::~EventDataBytes() = default;
+
+const ConstString &EventDataBytes::GetFlavorString() {
+ static ConstString g_flavor("EventDataBytes");
+ return g_flavor;
+}
+
+const ConstString &EventDataBytes::GetFlavor() const {
+ return EventDataBytes::GetFlavorString();
+}
+
+void EventDataBytes::Dump(Stream *s) const {
+ size_t num_printable_chars =
+ std::count_if(m_bytes.begin(), m_bytes.end(), isprint);
+ if (num_printable_chars == m_bytes.size())
+ s->Format("\"{0}\"", m_bytes);
+ else
+ s->Format("{0:$[ ]@[x-2]}", llvm::make_range(
+ reinterpret_cast<const uint8_t *>(m_bytes.data()),
+ reinterpret_cast<const uint8_t *>(m_bytes.data() +
+ m_bytes.size())));
+}
+
+const void *EventDataBytes::GetBytes() const {
+ return (m_bytes.empty() ? nullptr : m_bytes.data());
+}
+
+size_t EventDataBytes::GetByteSize() const { return m_bytes.size(); }
+
+void EventDataBytes::SetBytes(const void *src, size_t src_len) {
+ if (src != nullptr && src_len > 0)
+ m_bytes.assign((const char *)src, src_len);
+ else
+ m_bytes.clear();
+}
+
+void EventDataBytes::SetBytesFromCString(const char *cstr) {
+ if (cstr != nullptr && cstr[0])
+ m_bytes.assign(cstr);
+ else
+ m_bytes.clear();
+}
+
+const void *EventDataBytes::GetBytesFromEvent(const Event *event_ptr) {
+ const EventDataBytes *e = GetEventDataFromEvent(event_ptr);
+ if (e != nullptr)
+ return e->GetBytes();
+ return nullptr;
+}
+
+size_t EventDataBytes::GetByteSizeFromEvent(const Event *event_ptr) {
+ const EventDataBytes *e = GetEventDataFromEvent(event_ptr);
+ if (e != nullptr)
+ return e->GetByteSize();
+ return 0;
+}
+
+const EventDataBytes *
+EventDataBytes::GetEventDataFromEvent(const Event *event_ptr) {
+ if (event_ptr != nullptr) {
+ const EventData *event_data = event_ptr->GetData();
+ if (event_data &&
+ event_data->GetFlavor() == EventDataBytes::GetFlavorString())
+ return static_cast<const EventDataBytes *>(event_data);
+ }
+ return nullptr;
+}
+
+void EventDataBytes::SwapBytes(std::string &new_bytes) {
+ m_bytes.swap(new_bytes);
+}
+
+#pragma mark -
+#pragma mark EventStructuredData
+
+//------------------------------------------------------------------
+// EventDataStructuredData definitions
+//------------------------------------------------------------------
+
+EventDataStructuredData::EventDataStructuredData()
+ : EventData(), m_process_sp(), m_object_sp(), m_plugin_sp() {}
+
+EventDataStructuredData::EventDataStructuredData(
+ const ProcessSP &process_sp, const StructuredData::ObjectSP &object_sp,
+ const lldb::StructuredDataPluginSP &plugin_sp)
+ : EventData(), m_process_sp(process_sp), m_object_sp(object_sp),
+ m_plugin_sp(plugin_sp) {}
+
+EventDataStructuredData::~EventDataStructuredData() {}
+
+//------------------------------------------------------------------
+// EventDataStructuredData member functions
+//------------------------------------------------------------------
+
+const ConstString &EventDataStructuredData::GetFlavor() const {
+ return EventDataStructuredData::GetFlavorString();
+}
+
+void EventDataStructuredData::Dump(Stream *s) const {
+ if (!s)
+ return;
+
+ if (m_object_sp)
+ m_object_sp->Dump(*s);
+}
+
+const ProcessSP &EventDataStructuredData::GetProcess() const {
+ return m_process_sp;
+}
+
+const StructuredData::ObjectSP &EventDataStructuredData::GetObject() const {
+ return m_object_sp;
+}
+
+const lldb::StructuredDataPluginSP &
+EventDataStructuredData::GetStructuredDataPlugin() const {
+ return m_plugin_sp;
+}
+
+void EventDataStructuredData::SetProcess(const ProcessSP &process_sp) {
+ m_process_sp = process_sp;
+}
+
+void EventDataStructuredData::SetObject(
+ const StructuredData::ObjectSP &object_sp) {
+ m_object_sp = object_sp;
+}
+
+void EventDataStructuredData::SetStructuredDataPlugin(
+ const lldb::StructuredDataPluginSP &plugin_sp) {
+ m_plugin_sp = plugin_sp;
+}
+
+//------------------------------------------------------------------
+// EventDataStructuredData static functions
+//------------------------------------------------------------------
+
+const EventDataStructuredData *
+EventDataStructuredData::GetEventDataFromEvent(const Event *event_ptr) {
+ if (event_ptr == nullptr)
+ return nullptr;
+
+ const EventData *event_data = event_ptr->GetData();
+ if (!event_data ||
+ event_data->GetFlavor() != EventDataStructuredData::GetFlavorString())
+ return nullptr;
+
+ return static_cast<const EventDataStructuredData *>(event_data);
+}
+
+ProcessSP EventDataStructuredData::GetProcessFromEvent(const Event *event_ptr) {
+ auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
+ if (event_data)
+ return event_data->GetProcess();
+ else
+ return ProcessSP();
+}
+
+StructuredData::ObjectSP
+EventDataStructuredData::GetObjectFromEvent(const Event *event_ptr) {
+ auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
+ if (event_data)
+ return event_data->GetObject();
+ else
+ return StructuredData::ObjectSP();
+}
+
+lldb::StructuredDataPluginSP
+EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr) {
+ auto event_data = EventDataStructuredData::GetEventDataFromEvent(event_ptr);
+ if (event_data)
+ return event_data->GetStructuredDataPlugin();
+ else
+ return StructuredDataPluginSP();
+}
+
+const ConstString &EventDataStructuredData::GetFlavorString() {
+ static ConstString s_flavor("EventDataStructuredData");
+ return s_flavor;
+}
diff --git a/contrib/llvm/tools/lldb/source/Utility/FastDemangle.cpp b/contrib/llvm/tools/lldb/source/Utility/FastDemangle.cpp
deleted file mode 100644
index d92670a9199b..000000000000
--- a/contrib/llvm/tools/lldb/source/Utility/FastDemangle.cpp
+++ /dev/null
@@ -1,2393 +0,0 @@
-//===-- FastDemangle.cpp ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/FastDemangle.h"
-
-#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH
-
-#include <functional>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-//#define DEBUG_FAILURES 1
-//#define DEBUG_SUBSTITUTIONS 1
-//#define DEBUG_TEMPLATE_ARGS 1
-//#define DEBUG_HIGHWATER 1
-//#define DEBUG_REORDERING 1
-
-namespace {
-
-/// Represents the collection of qualifiers on a type
-
-enum Qualifiers {
- QualifierNone = 0,
- QualifierConst = 1,
- QualifierRestrict = 2,
- QualifierVolatile = 4,
- QualifierReference = 8,
- QualifierRValueReference = 16,
- QualifierPointer = 32
-};
-
-/// Categorizes the recognized operators
-
-enum class OperatorKind {
- Unary,
- Postfix,
- Binary,
- Ternary,
- Other,
- ConversionOperator,
- Vendor,
- NoMatch
-};
-
-/// Represents one of the recognized two-character operator abbreviations used
-/// when parsing operators as names and expressions
-
-struct Operator {
- const char *name;
- OperatorKind kind;
-};
-
-/// Represents a range of characters in the output buffer, typically for use
-/// with RewriteRange()
-
-struct BufferRange {
- int offset;
- int length;
-};
-
-/// Transient state required while parsing a name
-
-struct NameState {
- bool parse_function_params;
- bool is_last_generic;
- bool has_no_return_type;
- BufferRange last_name_range;
-};
-
-/// LLDB's fast C++ demangler
-///
-/// This is an incomplete implementation designed to speed up the demangling
-/// process that is often a bottleneck when LLDB stops a process for the first
-/// time. Where the implementation doesn't know how to demangle a symbol it
-/// fails gracefully to allow the caller to fall back to the existing
-/// demangler.
-///
-/// Over time the full mangling spec should be supported without compromising
-/// performance for the most common cases.
-
-class SymbolDemangler {
-public:
- //----------------------------------------------------
- // Public API
- //----------------------------------------------------
-
- /// Create a SymbolDemangler
- ///
- /// The newly created demangler allocates and owns scratch memory sufficient
- /// for demangling typical symbols. Additional memory will be allocated if
- /// needed and managed by the demangler instance.
-
- SymbolDemangler() {
- m_buffer = (char *)malloc(8192);
- m_buffer_end = m_buffer + 8192;
- m_owns_buffer = true;
-
- m_rewrite_ranges = (BufferRange *)malloc(128 * sizeof(BufferRange));
- m_rewrite_ranges_size = 128;
- m_owns_m_rewrite_ranges = true;
- }
-
- /// Create a SymbolDemangler that uses provided scratch memory
- ///
- /// The provided memory is not owned by the demangler. It will be
- /// overwritten during calls to GetDemangledCopy() but can be used for other
- /// purposes between calls. The provided memory will not be freed when this
- /// instance is destroyed.
- ///
- /// If demangling a symbol requires additional space it will be allocated
- /// and managed by the demangler instance.
- ///
- /// @param storage_ptr Valid pointer to at least storage_size bytes of space
- /// that the SymbolDemangler can use during demangling
- ///
- /// @param storage_size Number of bytes of space available scratch memory
- /// referenced by storage_ptr
-
- SymbolDemangler(void *storage_ptr, size_t storage_size,
- std::function<void(const char *)> builtins_hook = nullptr)
- : m_builtins_hook(builtins_hook) {
- // Use up to 1/8th of the provided space for rewrite ranges
- m_rewrite_ranges_size = (storage_size >> 3) / sizeof(BufferRange);
- m_rewrite_ranges = (BufferRange *)storage_ptr;
- m_owns_m_rewrite_ranges = false;
-
- // Use the rest for the character buffer
- m_buffer =
- (char *)storage_ptr + m_rewrite_ranges_size * sizeof(BufferRange);
- m_buffer_end = (const char *)storage_ptr + storage_size;
- m_owns_buffer = false;
- }
-
- /// Destroys the SymbolDemangler and deallocates any scratch memory that it
- /// owns
-
- ~SymbolDemangler() {
- if (m_owns_buffer)
- free(m_buffer);
- if (m_owns_m_rewrite_ranges)
- free(m_rewrite_ranges);
- }
-
-#ifdef DEBUG_HIGHWATER
- int highwater_store = 0;
- int highwater_buffer = 0;
-#endif
-
- /// Parses the provided mangled name and returns a newly allocated
- /// demangling
- ///
- /// @param mangled_name Valid null-terminated C++ mangled name following the
- /// Itanium C++ ABI mangling specification as implemented by Clang
- ///
- /// @result Newly allocated null-terminated demangled name when demangling
- /// is successful, and nullptr when demangling fails. The caller is
- /// responsible for freeing the allocated memory.
-
- char *GetDemangledCopy(const char *mangled_name,
- long mangled_name_length = 0) {
- if (!ParseMangling(mangled_name, mangled_name_length))
- return nullptr;
-
-#ifdef DEBUG_HIGHWATER
- int rewrite_count = m_next_substitute_index +
- (m_rewrite_ranges_size - 1 - m_next_template_arg_index);
- int buffer_size = (int)(m_write_ptr - m_buffer);
- if (rewrite_count > highwater_store)
- highwater_store = rewrite_count;
- if (buffer_size > highwater_buffer)
- highwater_buffer = buffer_size;
-#endif
-
- int length = (int)(m_write_ptr - m_buffer);
- char *copy = (char *)malloc(length + 1);
- memcpy(copy, m_buffer, length);
- copy[length] = '\0';
- return copy;
- }
-
-private:
- //----------------------------------------------------
- // Grow methods
- //
- // Manage the storage used during demangling
- //----------------------------------------------------
-
- void GrowBuffer(long min_growth = 0) {
- // By default, double the size of the buffer
- long growth = m_buffer_end - m_buffer;
-
- // Avoid growing by more than 1MB at a time
- if (growth > 1 << 20)
- growth = 1 << 20;
-
- // ... but never grow by less than requested, or 1K, whichever is greater
- if (min_growth < 1024)
- min_growth = 1024;
- if (growth < min_growth)
- growth = min_growth;
-
- // Allocate the new m_buffer and migrate content
- long new_size = (m_buffer_end - m_buffer) + growth;
- char *new_buffer = (char *)malloc(new_size);
- memcpy(new_buffer, m_buffer, m_write_ptr - m_buffer);
- if (m_owns_buffer)
- free(m_buffer);
- m_owns_buffer = true;
-
- // Update references to the new buffer
- m_write_ptr = new_buffer + (m_write_ptr - m_buffer);
- m_buffer = new_buffer;
- m_buffer_end = m_buffer + new_size;
- }
-
- void GrowRewriteRanges() {
- // By default, double the size of the array
- int growth = m_rewrite_ranges_size;
-
- // Apply reasonable minimum and maximum sizes for growth
- if (growth > 128)
- growth = 128;
- if (growth < 16)
- growth = 16;
-
- // Allocate the new array and migrate content
- int bytes = (m_rewrite_ranges_size + growth) * sizeof(BufferRange);
- BufferRange *new_ranges = (BufferRange *)malloc(bytes);
- for (int index = 0; index < m_next_substitute_index; index++) {
- new_ranges[index] = m_rewrite_ranges[index];
- }
- for (int index = m_rewrite_ranges_size - 1;
- index > m_next_template_arg_index; index--) {
- new_ranges[index + growth] = m_rewrite_ranges[index];
- }
- if (m_owns_m_rewrite_ranges)
- free(m_rewrite_ranges);
- m_owns_m_rewrite_ranges = true;
-
- // Update references to the new array
- m_rewrite_ranges = new_ranges;
- m_rewrite_ranges_size += growth;
- m_next_template_arg_index += growth;
- }
-
- //----------------------------------------------------
- // Range and state management
- //----------------------------------------------------
-
- int GetStartCookie() { return (int)(m_write_ptr - m_buffer); }
-
- BufferRange EndRange(int start_cookie) {
- return {start_cookie, (int)(m_write_ptr - (m_buffer + start_cookie))};
- }
-
- void ReorderRange(BufferRange source_range, int insertion_point_cookie) {
- // Ensure there's room the preserve the source range
- if (m_write_ptr + source_range.length > m_buffer_end) {
- GrowBuffer(m_write_ptr + source_range.length - m_buffer_end);
- }
-
- // Reorder the content
- memcpy(m_write_ptr, m_buffer + source_range.offset, source_range.length);
- memmove(m_buffer + insertion_point_cookie + source_range.length,
- m_buffer + insertion_point_cookie,
- source_range.offset - insertion_point_cookie);
- memcpy(m_buffer + insertion_point_cookie, m_write_ptr, source_range.length);
-
- // Fix up rewritable ranges, covering both substitutions and templates
- int index = 0;
- while (true) {
- if (index == m_next_substitute_index)
- index = m_next_template_arg_index + 1;
- if (index == m_rewrite_ranges_size)
- break;
-
- // Affected ranges are either shuffled forward when after the insertion
- // but before the source, or backward when inside the source
- int candidate_offset = m_rewrite_ranges[index].offset;
- if (candidate_offset >= insertion_point_cookie) {
- if (candidate_offset < source_range.offset) {
- m_rewrite_ranges[index].offset += source_range.length;
- } else if (candidate_offset >= source_range.offset) {
- m_rewrite_ranges[index].offset -=
- (source_range.offset - insertion_point_cookie);
- }
- }
- ++index;
- }
- }
-
- void EndSubstitution(int start_cookie) {
- if (m_next_substitute_index == m_next_template_arg_index)
- GrowRewriteRanges();
-
- int index = m_next_substitute_index++;
- m_rewrite_ranges[index] = EndRange(start_cookie);
-#ifdef DEBUG_SUBSTITUTIONS
- printf("Saved substitution # %d = %.*s\n", index,
- m_rewrite_ranges[index].length, m_buffer + start_cookie);
-#endif
- }
-
- void EndTemplateArg(int start_cookie) {
- if (m_next_substitute_index == m_next_template_arg_index)
- GrowRewriteRanges();
-
- int index = m_next_template_arg_index--;
- m_rewrite_ranges[index] = EndRange(start_cookie);
-#ifdef DEBUG_TEMPLATE_ARGS
- printf("Saved template arg # %d = %.*s\n",
- m_rewrite_ranges_size - index - 1, m_rewrite_ranges[index].length,
- m_buffer + start_cookie);
-#endif
- }
-
- void ResetTemplateArgs() {
- // TODO: this works, but is it the right thing to do?
- // Should we push/pop somehow at the call sites?
- m_next_template_arg_index = m_rewrite_ranges_size - 1;
- }
-
- //----------------------------------------------------
- // Write methods
- //
- // Appends content to the existing output buffer
- //----------------------------------------------------
-
- void Write(char character) {
- if (m_write_ptr == m_buffer_end)
- GrowBuffer();
- *m_write_ptr++ = character;
- }
-
- void Write(const char *content) { Write(content, strlen(content)); }
-
- void Write(const char *content, long content_length) {
- char *end_m_write_ptr = m_write_ptr + content_length;
- if (end_m_write_ptr > m_buffer_end) {
- if (content >= m_buffer && content < m_buffer_end) {
- long offset = content - m_buffer;
- GrowBuffer(end_m_write_ptr - m_buffer_end);
- content = m_buffer + offset;
- } else {
- GrowBuffer(end_m_write_ptr - m_buffer_end);
- }
- end_m_write_ptr = m_write_ptr + content_length;
- }
- memcpy(m_write_ptr, content, content_length);
- m_write_ptr = end_m_write_ptr;
- }
-#define WRITE(x) Write(x, sizeof(x) - 1)
-
- void WriteTemplateStart() { Write('<'); }
-
- void WriteTemplateEnd() {
- // Put a space between terminal > characters when nesting templates
- if (m_write_ptr != m_buffer && *(m_write_ptr - 1) == '>')
- WRITE(" >");
- else
- Write('>');
- }
-
- void WriteCommaSpace() { WRITE(", "); }
-
- void WriteNamespaceSeparator() { WRITE("::"); }
-
- void WriteStdPrefix() { WRITE("std::"); }
-
- void WriteQualifiers(int qualifiers, bool space_before_reference = true) {
- if (qualifiers & QualifierPointer)
- Write('*');
- if (qualifiers & QualifierConst)
- WRITE(" const");
- if (qualifiers & QualifierVolatile)
- WRITE(" volatile");
- if (qualifiers & QualifierRestrict)
- WRITE(" restrict");
- if (qualifiers & QualifierReference) {
- if (space_before_reference)
- WRITE(" &");
- else
- Write('&');
- }
- if (qualifiers & QualifierRValueReference) {
- if (space_before_reference)
- WRITE(" &&");
- else
- WRITE("&&");
- }
- }
-
- //----------------------------------------------------
- // Rewrite methods
- //
- // Write another copy of content already present earlier in the output buffer
- //----------------------------------------------------
-
- void RewriteRange(BufferRange range) {
- Write(m_buffer + range.offset, range.length);
- }
-
- bool RewriteSubstitution(int index) {
- if (index < 0 || index >= m_next_substitute_index) {
-#ifdef DEBUG_FAILURES
- printf("*** Invalid substitution #%d\n", index);
-#endif
- return false;
- }
- RewriteRange(m_rewrite_ranges[index]);
- return true;
- }
-
- bool RewriteTemplateArg(int template_index) {
- int index = m_rewrite_ranges_size - 1 - template_index;
- if (template_index < 0 || index <= m_next_template_arg_index) {
-#ifdef DEBUG_FAILURES
- printf("*** Invalid template arg reference #%d\n", template_index);
-#endif
- return false;
- }
- RewriteRange(m_rewrite_ranges[index]);
- return true;
- }
-
- //----------------------------------------------------
- // TryParse methods
- //
- // Provide information with return values instead of writing to the output
- // buffer
- //
- // Values indicating failure guarantee that the pre- call m_read_ptr is
- // unchanged
- //----------------------------------------------------
-
- int TryParseNumber() {
- unsigned char digit = *m_read_ptr - '0';
- if (digit > 9)
- return -1;
-
- int count = digit;
- while (true) {
- digit = *++m_read_ptr - '0';
- if (digit > 9)
- break;
-
- count = count * 10 + digit;
- }
- return count;
- }
-
- int TryParseBase36Number() {
- char digit = *m_read_ptr;
- int count;
- if (digit >= '0' && digit <= '9')
- count = digit -= '0';
- else if (digit >= 'A' && digit <= 'Z')
- count = digit -= ('A' - 10);
- else
- return -1;
-
- while (true) {
- digit = *++m_read_ptr;
- if (digit >= '0' && digit <= '9')
- digit -= '0';
- else if (digit >= 'A' && digit <= 'Z')
- digit -= ('A' - 10);
- else
- break;
-
- count = count * 36 + digit;
- }
- return count;
- }
-
- // <builtin-type> ::= v # void
- // ::= w # wchar_t
- // ::= b # bool
- // ::= c # char
- // ::= a # signed char
- // ::= h # unsigned char
- // ::= s # short
- // ::= t # unsigned short
- // ::= i # int
- // ::= j # unsigned int
- // ::= l # long
- // ::= m # unsigned long
- // ::= x # long long, __int64
- // ::= y # unsigned long long, __int64
- // ::= n # __int128
- // ::= o # unsigned __int128
- // ::= f # float
- // ::= d # double
- // ::= e # long double, __float80
- // ::= g # __float128
- // ::= z # ellipsis
- // ::= Dd # IEEE 754r decimal floating point (64 bits)
- // ::= De # IEEE 754r decimal floating point (128 bits)
- // ::= Df # IEEE 754r decimal floating point (32 bits)
- // ::= Dh # IEEE 754r half-precision floating point (16 bits)
- // ::= Di # char32_t
- // ::= Ds # char16_t
- // ::= Da # auto (in dependent new-expressions)
- // ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
- // ::= u <source-name> # vendor extended type
-
- const char *TryParseBuiltinType() {
- if (m_builtins_hook)
- m_builtins_hook(m_read_ptr);
-
- switch (*m_read_ptr++) {
- case 'v':
- return "void";
- case 'w':
- return "wchar_t";
- case 'b':
- return "bool";
- case 'c':
- return "char";
- case 'a':
- return "signed char";
- case 'h':
- return "unsigned char";
- case 's':
- return "short";
- case 't':
- return "unsigned short";
- case 'i':
- return "int";
- case 'j':
- return "unsigned int";
- case 'l':
- return "long";
- case 'm':
- return "unsigned long";
- case 'x':
- return "long long";
- case 'y':
- return "unsigned long long";
- case 'n':
- return "__int128";
- case 'o':
- return "unsigned __int128";
- case 'f':
- return "float";
- case 'd':
- return "double";
- case 'e':
- return "long double";
- case 'g':
- return "__float128";
- case 'z':
- return "...";
- case 'D': {
- switch (*m_read_ptr++) {
- case 'd':
- return "decimal64";
- case 'e':
- return "decimal128";
- case 'f':
- return "decimal32";
- case 'h':
- return "decimal16";
- case 'i':
- return "char32_t";
- case 's':
- return "char16_t";
- case 'a':
- return "auto";
- case 'c':
- return "decltype(auto)";
- case 'n':
- return "std::nullptr_t";
- default:
- --m_read_ptr;
- }
- }
- }
- --m_read_ptr;
- return nullptr;
- }
-
- // <operator-name>
- // ::= aa # &&
- // ::= ad # & (unary)
- // ::= an # &
- // ::= aN # &=
- // ::= aS # =
- // ::= cl # ()
- // ::= cm # ,
- // ::= co # ~
- // ::= da # delete[]
- // ::= de # * (unary)
- // ::= dl # delete
- // ::= dv # /
- // ::= dV # /=
- // ::= eo # ^
- // ::= eO # ^=
- // ::= eq # ==
- // ::= ge # >=
- // ::= gt # >
- // ::= ix # []
- // ::= le # <=
- // ::= ls # <<
- // ::= lS # <<=
- // ::= lt # <
- // ::= mi # -
- // ::= mI # -=
- // ::= ml # *
- // ::= mL # *=
- // ::= mm # -- (postfix in <expression> context)
- // ::= na # new[]
- // ::= ne # !=
- // ::= ng # - (unary)
- // ::= nt # !
- // ::= nw # new
- // ::= oo # ||
- // ::= or # |
- // ::= oR # |=
- // ::= pm # ->*
- // ::= pl # +
- // ::= pL # +=
- // ::= pp # ++ (postfix in <expression> context)
- // ::= ps # + (unary)
- // ::= pt # ->
- // ::= qu # ?
- // ::= rm # %
- // ::= rM # %=
- // ::= rs # >>
- // ::= rS # >>=
- // ::= cv <type> # (cast)
- // ::= v <digit> <source-name> # vendor extended
- // operator
-
- Operator TryParseOperator() {
- switch (*m_read_ptr++) {
- case 'a':
- switch (*m_read_ptr++) {
- case 'a':
- return {"&&", OperatorKind::Binary};
- case 'd':
- return {"&", OperatorKind::Unary};
- case 'n':
- return {"&", OperatorKind::Binary};
- case 'N':
- return {"&=", OperatorKind::Binary};
- case 'S':
- return {"=", OperatorKind::Binary};
- }
- --m_read_ptr;
- break;
- case 'c':
- switch (*m_read_ptr++) {
- case 'l':
- return {"()", OperatorKind::Other};
- case 'm':
- return {",", OperatorKind::Other};
- case 'o':
- return {"~", OperatorKind::Unary};
- case 'v':
- return {nullptr, OperatorKind::ConversionOperator};
- }
- --m_read_ptr;
- break;
- case 'd':
- switch (*m_read_ptr++) {
- case 'a':
- return {" delete[]", OperatorKind::Other};
- case 'e':
- return {"*", OperatorKind::Unary};
- case 'l':
- return {" delete", OperatorKind::Other};
- case 'v':
- return {"/", OperatorKind::Binary};
- case 'V':
- return {"/=", OperatorKind::Binary};
- }
- --m_read_ptr;
- break;
- case 'e':
- switch (*m_read_ptr++) {
- case 'o':
- return {"^", OperatorKind::Binary};
- case 'O':
- return {"^=", OperatorKind::Binary};
- case 'q':
- return {"==", OperatorKind::Binary};
- }
- --m_read_ptr;
- break;
- case 'g':
- switch (*m_read_ptr++) {
- case 'e':
- return {">=", OperatorKind::Binary};
- case 't':
- return {">", OperatorKind::Binary};
- }
- --m_read_ptr;
- break;
- case 'i':
- switch (*m_read_ptr++) {
- case 'x':
- return {"[]", OperatorKind::Other};
- }
- --m_read_ptr;
- break;
- case 'l':
- switch (*m_read_ptr++) {
- case 'e':
- return {"<=", OperatorKind::Binary};
- case 's':
- return {"<<", OperatorKind::Binary};
- case 'S':
- return {"<<=", OperatorKind::Binary};
- case 't':
- return {"<", OperatorKind::Binary};
- // case 'i': return { "?", OperatorKind::Binary };
- }
- --m_read_ptr;
- break;
- case 'm':
- switch (*m_read_ptr++) {
- case 'i':
- return {"-", OperatorKind::Binary};
- case 'I':
- return {"-=", OperatorKind::Binary};
- case 'l':
- return {"*", OperatorKind::Binary};
- case 'L':
- return {"*=", OperatorKind::Binary};
- case 'm':
- return {"--", OperatorKind::Postfix};
- }
- --m_read_ptr;
- break;
- case 'n':
- switch (*m_read_ptr++) {
- case 'a':
- return {" new[]", OperatorKind::Other};
- case 'e':
- return {"!=", OperatorKind::Binary};
- case 'g':
- return {"-", OperatorKind::Unary};
- case 't':
- return {"!", OperatorKind::Unary};
- case 'w':
- return {" new", OperatorKind::Other};
- }
- --m_read_ptr;
- break;
- case 'o':
- switch (*m_read_ptr++) {
- case 'o':
- return {"||", OperatorKind::Binary};
- case 'r':
- return {"|", OperatorKind::Binary};
- case 'R':
- return {"|=", OperatorKind::Binary};
- }
- --m_read_ptr;
- break;
- case 'p':
- switch (*m_read_ptr++) {
- case 'm':
- return {"->*", OperatorKind::Binary};
- case 's':
- return {"+", OperatorKind::Unary};
- case 'l':
- return {"+", OperatorKind::Binary};
- case 'L':
- return {"+=", OperatorKind::Binary};
- case 'p':
- return {"++", OperatorKind::Postfix};
- case 't':
- return {"->", OperatorKind::Binary};
- }
- --m_read_ptr;
- break;
- case 'q':
- switch (*m_read_ptr++) {
- case 'u':
- return {"?", OperatorKind::Ternary};
- }
- --m_read_ptr;
- break;
- case 'r':
- switch (*m_read_ptr++) {
- case 'm':
- return {"%", OperatorKind::Binary};
- case 'M':
- return {"%=", OperatorKind::Binary};
- case 's':
- return {">>", OperatorKind::Binary};
- case 'S':
- return {">=", OperatorKind::Binary};
- }
- --m_read_ptr;
- break;
- case 'v':
- char digit = *m_read_ptr;
- if (digit >= '0' && digit <= '9') {
- m_read_ptr++;
- return {nullptr, OperatorKind::Vendor};
- }
- --m_read_ptr;
- break;
- }
- --m_read_ptr;
- return {nullptr, OperatorKind::NoMatch};
- }
-
- // <CV-qualifiers> ::= [r] [V] [K]
- // <ref-qualifier> ::= R # & ref-qualifier <ref-qualifier>
- // ::= O # && ref-qualifier
-
- int TryParseQualifiers(bool allow_cv, bool allow_ro) {
- int qualifiers = QualifierNone;
- char next = *m_read_ptr;
- if (allow_cv) {
- if (next == 'r') // restrict
- {
- qualifiers |= QualifierRestrict;
- next = *++m_read_ptr;
- }
- if (next == 'V') // volatile
- {
- qualifiers |= QualifierVolatile;
- next = *++m_read_ptr;
- }
- if (next == 'K') // const
- {
- qualifiers |= QualifierConst;
- next = *++m_read_ptr;
- }
- }
- if (allow_ro) {
- if (next == 'R') {
- ++m_read_ptr;
- qualifiers |= QualifierReference;
- } else if (next == 'O') {
- ++m_read_ptr;
- qualifiers |= QualifierRValueReference;
- }
- }
- return qualifiers;
- }
-
- // <discriminator> := _ <non-negative number> # when number < 10
- // := __ <non-negative number> _ # when number >= 10
- // extension := decimal-digit+
-
- int TryParseDiscriminator() {
- const char *discriminator_start = m_read_ptr;
-
- // Test the extension first, since it's what Clang uses
- int discriminator_value = TryParseNumber();
- if (discriminator_value != -1)
- return discriminator_value;
-
- char next = *m_read_ptr;
- if (next == '_') {
- next = *++m_read_ptr;
- if (next == '_') {
- ++m_read_ptr;
- discriminator_value = TryParseNumber();
- if (discriminator_value != -1 && *m_read_ptr++ != '_') {
- return discriminator_value;
- }
- } else if (next >= '0' && next <= '9') {
- ++m_read_ptr;
- return next - '0';
- }
- }
-
- // Not a valid discriminator
- m_read_ptr = discriminator_start;
- return -1;
- }
-
- //----------------------------------------------------
- // Parse methods
- //
- // Consume input starting from m_read_ptr and produce buffered output at
- // m_write_ptr
- //
- // Failures return false and may leave m_read_ptr in an indeterminate state
- //----------------------------------------------------
-
- bool Parse(char character) {
- if (*m_read_ptr++ == character)
- return true;
-#ifdef DEBUG_FAILURES
- printf("*** Expected '%c'\n", character);
-#endif
- return false;
- }
-
- // <number> ::= [n] <non-negative decimal integer>
-
- bool ParseNumber(bool allow_negative = false) {
- if (allow_negative && *m_read_ptr == 'n') {
- Write('-');
- ++m_read_ptr;
- }
- const char *before_digits = m_read_ptr;
- while (true) {
- unsigned char digit = *m_read_ptr - '0';
- if (digit > 9)
- break;
- ++m_read_ptr;
- }
- if (int digit_count = (int)(m_read_ptr - before_digits)) {
- Write(before_digits, digit_count);
- return true;
- }
-#ifdef DEBUG_FAILURES
- printf("*** Expected number\n");
-#endif
- return false;
- }
-
- // <substitution> ::= S <seq-id> _
- // ::= S_
- // <substitution> ::= Sa # ::std::allocator <substitution> ::= Sb #
- // ::std::basic_string <substitution> ::= Ss # ::std::basic_string < char,
- // ::std::char_traits<char>,
- // ::std::allocator<char> >
- // <substitution> ::= Si # ::std::basic_istream<char, std::char_traits<char>
- // > <substitution> ::= So # ::std::basic_ostream<char,
- // std::char_traits<char> > <substitution> ::= Sd #
- // ::std::basic_iostream<char, std::char_traits<char> >
-
- bool ParseSubstitution() {
- const char *substitution;
- switch (*m_read_ptr) {
- case 'a':
- substitution = "std::allocator";
- break;
- case 'b':
- substitution = "std::basic_string";
- break;
- case 's':
- substitution = "std::string";
- break;
- case 'i':
- substitution = "std::istream";
- break;
- case 'o':
- substitution = "std::ostream";
- break;
- case 'd':
- substitution = "std::iostream";
- break;
- default:
- // A failed attempt to parse a number will return -1 which turns out to be
- // perfect here as S_ is the first substitution, S0_ the next and so
- // forth
- int substitution_index = TryParseBase36Number();
- if (*m_read_ptr++ != '_') {
-#ifdef DEBUG_FAILURES
- printf("*** Expected terminal _ in substitution\n");
-#endif
- return false;
- }
- return RewriteSubstitution(substitution_index + 1);
- }
- Write(substitution);
- ++m_read_ptr;
- return true;
- }
-
- // <function-type> ::= F [Y] <bare-function-type> [<ref-qualifier>] E
- //
- // <bare-function-type> ::= <signature type>+ # types are possible
- // return type, then parameter types
-
- bool ParseFunctionType(int inner_qualifiers = QualifierNone) {
-#ifdef DEBUG_FAILURES
- printf("*** Function types not supported\n");
-#endif
- // TODO: first steps toward an implementation follow, but they're far
- // from complete. Function types tend to bracket other types eg: int (*)()
- // when used as the type for "name" becomes int (*name)(). This makes
- // substitution et al ... interesting.
- return false;
-
-#if 0 // TODO
- if (*m_read_ptr == 'Y')
- ++m_read_ptr;
-
- int return_type_start_cookie = GetStartCookie();
- if (!ParseType())
- return false;
- Write(' ');
-
- int insert_cookie = GetStartCookie();
- Write('(');
- bool first_param = true;
- int qualifiers = QualifierNone;
- while (true)
- {
- switch (*m_read_ptr)
- {
- case 'E':
- ++m_read_ptr;
- Write(')');
- break;
- case 'v':
- ++m_read_ptr;
- continue;
- case 'R':
- case 'O':
- if (*(m_read_ptr + 1) == 'E')
- {
- qualifiers = TryParseQualifiers (false, true);
- Parse('E');
- break;
- }
- // fallthrough
- default:
- {
- if (first_param)
- first_param = false;
- else WriteCommaSpace();
-
- if (!ParseType())
- return false;
- continue;
- }
- }
- break;
- }
-
- if (qualifiers)
- {
- WriteQualifiers (qualifiers);
- EndSubstitution (return_type_start_cookie);
- }
-
- if (inner_qualifiers)
- {
- int qualifier_start_cookie = GetStartCookie();
- Write ('(');
- WriteQualifiers (inner_qualifiers);
- Write (')');
- ReorderRange (EndRange (qualifier_start_cookie), insert_cookie);
- }
- return true;
-#endif // TODO
- }
-
- // <array-type> ::= A <positive dimension number> _ <element type>
- // ::= A [<dimension expression>] _ <element type>
-
- bool ParseArrayType(int qualifiers = QualifierNone) {
-#ifdef DEBUG_FAILURES
- printf("*** Array type unsupported\n");
-#endif
- // TODO: We fail horribly when recalling these as substitutions or
- // templates and trying to constify them eg:
- // _ZN4llvm2cl5applyIA28_cNS0_3optIbLb0ENS0_6parserIbEEEEEEvRKT_PT0_
- //
- // TODO: Chances are we don't do any better with references and pointers
- // that should be type (&) [] instead of type & []
-
- return false;
-
-#if 0 // TODO
- if (*m_read_ptr == '_')
- {
- ++m_read_ptr;
- if (!ParseType())
- return false;
- if (qualifiers)
- WriteQualifiers(qualifiers);
- WRITE(" []");
- return true;
- }
- else
- {
- const char *before_digits = m_read_ptr;
- if (TryParseNumber() != -1)
- {
- const char *after_digits = m_read_ptr;
- if (!Parse('_'))
- return false;
- if (!ParseType())
- return false;
- if (qualifiers)
- WriteQualifiers(qualifiers);
- Write(' ');
- Write('[');
- Write(before_digits, after_digits - before_digits);
- }
- else
- {
- int type_insertion_cookie = GetStartCookie();
- if (!ParseExpression())
- return false;
- if (!Parse('_'))
- return false;
-
- int type_start_cookie = GetStartCookie();
- if (!ParseType())
- return false;
- if (qualifiers)
- WriteQualifiers(qualifiers);
- Write(' ');
- Write('[');
- ReorderRange (EndRange (type_start_cookie), type_insertion_cookie);
- }
- Write(']');
- return true;
- }
-#endif // TODO
- }
-
- // <pointer-to-member-type> ::= M <class type> <member type>
-
- // TODO: Determine how to handle pointers to function members correctly,
- // currently not an issue because we don't have function types at all...
- bool ParsePointerToMemberType() {
- int insertion_cookie = GetStartCookie();
- Write(' ');
- if (!ParseType())
- return false;
- WRITE("::*");
-
- int type_cookie = GetStartCookie();
- if (!ParseType())
- return false;
- ReorderRange(EndRange(type_cookie), insertion_cookie);
- return true;
- }
-
- // <template-param> ::= T_ # first template parameter
- // ::= T <parameter-2 non-negative number> _
-
- bool ParseTemplateParam() {
- int count = TryParseNumber();
- if (!Parse('_'))
- return false;
-
- // When no number is present we get -1, which is convenient since T_ is the
- // zeroth element T0_ is element 1, and so on
- return RewriteTemplateArg(count + 1);
- }
-
- // <vector-type>
- // Dv <dimension number> _ <vector type>
- bool TryParseVectorType() {
- const int dimension = TryParseNumber();
- if (dimension == -1)
- return false;
-
- if (*m_read_ptr++ != '_')
- return false;
-
- char vec_dimens[32] = {'\0'};
- ::snprintf(vec_dimens, sizeof vec_dimens - 1, " __vector(%d)", dimension);
- ParseType();
- Write(vec_dimens);
- return true;
- }
-
- // <type> ::= <builtin-type>
- // ::= <function-type>
- // ::= <class-enum-type>
- // ::= <array-type>
- // ::= <pointer-to-member-type>
- // ::= <template-param>
- // ::= <template-template-param> <template-args>
- // ::= <decltype>
- // ::= <substitution>
- // ::= <CV-qualifiers> <type>
- // ::= P <type> # pointer-to
- // ::= R <type> # reference-to
- // ::= O <type> # rvalue reference-to (C++0x)
- // ::= C <type> # complex pair (C 2000)
- // ::= G <type> # imaginary (C 2000)
- // ::= Dp <type> # pack expansion (C++0x)
- // ::= U <source-name> <type> # vendor extended type qualifier
- // extension := U <objc-name> <objc-type> # objc-type<identifier> extension
- // := <vector-type> # <vector-type> starts with Dv
-
- // <objc-name> ::= <k0 number> objcproto <k1 number> <identifier> # k0 = 9 +
- // <number of digits in k1> + k1 <objc-type> := <source-name> #
- // PU<11+>objcproto 11objc_object<source-name> 11objc_object -> id<source-
- // name>
-
- bool ParseType() {
-#ifdef DEBUG_FAILURES
- const char *failed_type = m_read_ptr;
-#endif
- int type_start_cookie = GetStartCookie();
- bool suppress_substitution = false;
-
- int qualifiers = TryParseQualifiers(true, false);
- switch (*m_read_ptr) {
- case 'D':
- ++m_read_ptr;
- switch (*m_read_ptr++) {
- case 'p':
- if (!ParseType())
- return false;
- break;
- case 'v':
- if (!TryParseVectorType())
- return false;
- break;
- case 'T':
- case 't':
- default:
-#ifdef DEBUG_FAILURES
- printf("*** Unsupported type: %.3s\n", failed_type);
-#endif
- return false;
- }
- break;
- case 'T':
- ++m_read_ptr;
- if (!ParseTemplateParam())
- return false;
- break;
- case 'M':
- ++m_read_ptr;
- if (!ParsePointerToMemberType())
- return false;
- break;
- case 'A':
- ++m_read_ptr;
- if (!ParseArrayType())
- return false;
- break;
- case 'F':
- ++m_read_ptr;
- if (!ParseFunctionType())
- return false;
- break;
- case 'S':
- if (*++m_read_ptr == 't') {
- ++m_read_ptr;
- WriteStdPrefix();
- if (!ParseName())
- return false;
- } else {
- suppress_substitution = true;
- if (!ParseSubstitution())
- return false;
- }
- break;
- case 'P': {
- switch (*++m_read_ptr) {
- case 'F':
- ++m_read_ptr;
- if (!ParseFunctionType(QualifierPointer))
- return false;
- break;
- default:
- if (!ParseType())
- return false;
- Write('*');
- break;
- }
- break;
- }
- case 'R': {
- ++m_read_ptr;
- if (!ParseType())
- return false;
- Write('&');
- break;
- }
- case 'O': {
- ++m_read_ptr;
- if (!ParseType())
- return false;
- Write('&');
- Write('&');
- break;
- }
- case 'C':
- case 'G':
- case 'U':
-#ifdef DEBUG_FAILURES
- printf("*** Unsupported type: %.3s\n", failed_type);
-#endif
- return false;
- // Test for common cases to avoid TryParseBuiltinType() overhead
- case 'N':
- case 'Z':
- case 'L':
- if (!ParseName())
- return false;
- break;
- default:
- if (const char *builtin = TryParseBuiltinType()) {
- Write(builtin);
- suppress_substitution = true;
- } else {
- if (!ParseName())
- return false;
- }
- break;
- }
-
- // Allow base substitutions to be suppressed, but always record
- // substitutions for the qualified variant
- if (!suppress_substitution)
- EndSubstitution(type_start_cookie);
- if (qualifiers) {
- WriteQualifiers(qualifiers, false);
- EndSubstitution(type_start_cookie);
- }
- return true;
- }
-
- // <unnamed-type-name> ::= Ut [ <nonnegative number> ] _
- // ::= <closure-type-name>
- //
- // <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
- //
- // <lambda-sig> ::= <parameter type>+ # Parameter types or "v" if the lambda
- // has no parameters
-
- bool ParseUnnamedTypeName(NameState &name_state) {
- switch (*m_read_ptr++) {
- case 't': {
- int cookie = GetStartCookie();
- WRITE("'unnamed");
- const char *before_digits = m_read_ptr;
- if (TryParseNumber() != -1)
- Write(before_digits, m_read_ptr - before_digits);
- if (!Parse('_'))
- return false;
- Write('\'');
- name_state.last_name_range = EndRange(cookie);
- return true;
- }
- case 'b': {
- int cookie = GetStartCookie();
- WRITE("'block");
- const char *before_digits = m_read_ptr;
- if (TryParseNumber() != -1)
- Write(before_digits, m_read_ptr - before_digits);
- if (!Parse('_'))
- return false;
- Write('\'');
- name_state.last_name_range = EndRange(cookie);
- return true;
- }
- case 'l':
-#ifdef DEBUG_FAILURES
- printf("*** Lambda type names unsupported\n");
-#endif
- return false;
- }
-#ifdef DEBUG_FAILURES
- printf("*** Unknown unnamed type %.3s\n", m_read_ptr - 2);
-#endif
- return false;
- }
-
- // <ctor-dtor-name> ::= C1 # complete object constructor
- // ::= C2 # base object constructor
- // ::= C3 # complete object allocating constructor
-
- bool ParseCtor(NameState &name_state) {
- char next = *m_read_ptr;
- if (next == '1' || next == '2' || next == '3' || next == '5') {
- RewriteRange(name_state.last_name_range);
- name_state.has_no_return_type = true;
- ++m_read_ptr;
- return true;
- }
-#ifdef DEBUG_FAILURES
- printf("*** Broken constructor\n");
-#endif
- return false;
- }
-
- // <ctor-dtor-name> ::= D0 # deleting destructor
- // ::= D1 # complete object destructor
- // ::= D2 # base object destructor
-
- bool ParseDtor(NameState &name_state) {
- char next = *m_read_ptr;
- if (next == '0' || next == '1' || next == '2' || next == '5') {
- Write('~');
- RewriteRange(name_state.last_name_range);
- name_state.has_no_return_type = true;
- ++m_read_ptr;
- return true;
- }
-#ifdef DEBUG_FAILURES
- printf("*** Broken destructor\n");
-#endif
- return false;
- }
-
- // See TryParseOperator()
-
- bool ParseOperatorName(NameState &name_state) {
-#ifdef DEBUG_FAILURES
- const char *operator_ptr = m_read_ptr;
-#endif
- Operator parsed_operator = TryParseOperator();
- if (parsed_operator.name) {
- WRITE("operator");
- Write(parsed_operator.name);
- return true;
- }
-
- // Handle special operators
- switch (parsed_operator.kind) {
- case OperatorKind::Vendor:
- WRITE("operator ");
- return ParseSourceName();
- case OperatorKind::ConversionOperator:
- ResetTemplateArgs();
- name_state.has_no_return_type = true;
- WRITE("operator ");
- return ParseType();
- default:
-#ifdef DEBUG_FAILURES
- printf("*** Unknown operator: %.2s\n", operator_ptr);
-#endif
- return false;
- }
- }
-
- // <source-name> ::= <positive length number> <identifier>
-
- bool ParseSourceName() {
- int count = TryParseNumber();
- if (count == -1) {
-#ifdef DEBUG_FAILURES
- printf("*** Malformed source name, missing length count\n");
-#endif
- return false;
- }
-
- const char *next_m_read_ptr = m_read_ptr + count;
- if (next_m_read_ptr > m_read_end) {
-#ifdef DEBUG_FAILURES
- printf("*** Malformed source name, premature termination\n");
-#endif
- return false;
- }
-
- if (count >= 10 && strncmp(m_read_ptr, "_GLOBAL__N", 10) == 0)
- WRITE("(anonymous namespace)");
- else
- Write(m_read_ptr, count);
-
- m_read_ptr = next_m_read_ptr;
- return true;
- }
-
- // <unqualified-name> ::= <operator-name>
- // ::= <ctor-dtor-name>
- // ::= <source-name>
- // ::= <unnamed-type-name>
-
- bool ParseUnqualifiedName(NameState &name_state) {
- // Note that these are detected directly in ParseNestedName for performance
- // rather than switching on the same options twice
- char next = *m_read_ptr;
- switch (next) {
- case 'C':
- ++m_read_ptr;
- return ParseCtor(name_state);
- case 'D':
- ++m_read_ptr;
- return ParseDtor(name_state);
- case 'U':
- ++m_read_ptr;
- return ParseUnnamedTypeName(name_state);
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- int name_start_cookie = GetStartCookie();
- if (!ParseSourceName())
- return false;
- name_state.last_name_range = EndRange(name_start_cookie);
- return true;
- }
- default:
- return ParseOperatorName(name_state);
- };
- }
-
- // <unscoped-name> ::= <unqualified-name>
- // ::= St <unqualified-name> # ::std::
- // extension ::= StL<unqualified-name>
-
- bool ParseUnscopedName(NameState &name_state) {
- if (*m_read_ptr == 'S' && *(m_read_ptr + 1) == 't') {
- WriteStdPrefix();
- if (*(m_read_ptr += 2) == 'L')
- ++m_read_ptr;
- }
- return ParseUnqualifiedName(name_state);
- }
-
- bool ParseIntegerLiteral(const char *prefix, const char *suffix,
- bool allow_negative) {
- if (prefix)
- Write(prefix);
- if (!ParseNumber(allow_negative))
- return false;
- if (suffix)
- Write(suffix);
- return Parse('E');
- }
-
- bool ParseBooleanLiteral() {
- switch (*m_read_ptr++) {
- case '0':
- WRITE("false");
- break;
- case '1':
- WRITE("true");
- break;
- default:
-#ifdef DEBUG_FAILURES
- printf("*** Boolean literal not 0 or 1\n");
-#endif
- return false;
- }
- return Parse('E');
- }
-
- // <expr-primary> ::= L <type> <value number> E #
- // integer literal
- // ::= L <type> <value float> E #
- // floating literal
- // ::= L <string type> E #
- // string literal
- // ::= L <nullptr type> E #
- // nullptr literal (i.e., "LDnE")
- // ::= L <type> <real-part float> _ <imag-part float> E #
- // complex floating point literal (C 2000)
- // ::= L <mangled-name> E #
- // external name
-
- bool ParseExpressionPrimary() {
- switch (*m_read_ptr++) {
- case 'b':
- return ParseBooleanLiteral();
- case 'x':
- return ParseIntegerLiteral(nullptr, "ll", true);
- case 'l':
- return ParseIntegerLiteral(nullptr, "l", true);
- case 'i':
- return ParseIntegerLiteral(nullptr, nullptr, true);
- case 'n':
- return ParseIntegerLiteral("(__int128)", nullptr, true);
- case 'j':
- return ParseIntegerLiteral(nullptr, "u", false);
- case 'm':
- return ParseIntegerLiteral(nullptr, "ul", false);
- case 'y':
- return ParseIntegerLiteral(nullptr, "ull", false);
- case 'o':
- return ParseIntegerLiteral("(unsigned __int128)", nullptr, false);
- case '_':
- if (*m_read_ptr++ == 'Z') {
- if (!ParseEncoding())
- return false;
- return Parse('E');
- }
- --m_read_ptr;
- LLVM_FALLTHROUGH;
- case 'w':
- case 'c':
- case 'a':
- case 'h':
- case 's':
- case 't':
- case 'f':
- case 'd':
- case 'e':
-#ifdef DEBUG_FAILURES
- printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1);
-#endif
- return false;
- case 'T':
-// Invalid mangled name per
-// http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html
-#ifdef DEBUG_FAILURES
- printf("*** Invalid primary expr encoding\n");
-#endif
- return false;
- default:
- --m_read_ptr;
- Write('(');
- if (!ParseType())
- return false;
- Write(')');
- if (!ParseNumber())
- return false;
- return Parse('E');
- }
- }
-
- // <unresolved-type> ::= <template-param>
- // ::= <decltype>
- // ::= <substitution>
-
- bool ParseUnresolvedType() {
- int type_start_cookie = GetStartCookie();
- switch (*m_read_ptr++) {
- case 'T':
- if (!ParseTemplateParam())
- return false;
- EndSubstitution(type_start_cookie);
- return true;
- case 'S': {
- if (*m_read_ptr != 't')
- return ParseSubstitution();
-
- ++m_read_ptr;
- WriteStdPrefix();
- NameState type_name = {};
- if (!ParseUnqualifiedName(type_name))
- return false;
- EndSubstitution(type_start_cookie);
- return true;
- }
- case 'D':
- default:
-#ifdef DEBUG_FAILURES
- printf("*** Unsupported unqualified type: %3s\n", m_read_ptr - 1);
-#endif
- return false;
- }
- }
-
- // <base-unresolved-name> ::= <simple-id> #
- // unresolved name
- // extension ::= <operator-name> #
- // unresolved operator-function-id
- // extension ::= <operator-name> <template-args> #
- // unresolved operator template-id
- // ::= on <operator-name> #
- // unresolved operator-function-id
- // ::= on <operator-name> <template-args> #
- // unresolved operator template-id
- // ::= dn <destructor-name> #
- // destructor or pseudo-destructor;
- // #
- // e.g.
- // ~X
- // or
- // ~X<N-1>
-
- bool ParseBaseUnresolvedName() {
-#ifdef DEBUG_FAILURES
- printf("*** Base unresolved name unsupported\n");
-#endif
- return false;
- }
-
- // <unresolved-name>
- // extension ::= srN <unresolved-type> [<template-args>]
- // <unresolved-qualifier-level>* E <base-unresolved-name>
- // ::= [gs] <base-unresolved-name> # x
- // or (with "gs") ::x
- // ::= [gs] sr <unresolved-qualifier-level>+ E
- // <base-unresolved-name>
- // #
- // A::x,
- // N::y,
- // A<T>::z;
- // "gs"
- // means
- // leading
- // "::"
- // ::= sr <unresolved-type> <base-unresolved-name> #
- // T::x / decltype(p)::x
- // extension ::= sr <unresolved-type> <template-args>
- // <base-unresolved-name>
- // #
- // T::N::x
- // /decltype(p)::N::x
- // (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+
- // E <base-unresolved-name>
-
- bool ParseUnresolvedName() {
-#ifdef DEBUG_FAILURES
- printf("*** Unresolved names not supported\n");
-#endif
- // TODO: grammar for all of this seems unclear...
- return false;
-
-#if 0 // TODO
- if (*m_read_ptr == 'g' && *(m_read_ptr + 1) == 's')
- {
- m_read_ptr += 2;
- WriteNamespaceSeparator();
- }
-#endif // TODO
- }
-
- // <expression> ::= <unary operator-name> <expression>
- // ::= <binary operator-name> <expression> <expression>
- // ::= <ternary operator-name> <expression> <expression>
- // <expression>
- // ::= cl <expression>+ E #
- // call
- // ::= cv <type> <expression> #
- // conversion with one argument
- // ::= cv <type> _ <expression>* E #
- // conversion with a different number of arguments
- // ::= [gs] nw <expression>* _ <type> E # new
- // (expr-list) type
- // ::= [gs] nw <expression>* _ <type> <initializer> # new
- // (expr-list) type (init)
- // ::= [gs] na <expression>* _ <type> E #
- // new[] (expr-list) type
- // ::= [gs] na <expression>* _ <type> <initializer> #
- // new[] (expr-list) type (init)
- // ::= [gs] dl <expression> #
- // delete expression
- // ::= [gs] da <expression> #
- // delete[] expression
- // ::= pp_ <expression> #
- // prefix ++
- // ::= mm_ <expression> #
- // prefix --
- // ::= ti <type> #
- // typeid (type)
- // ::= te <expression> #
- // typeid (expression)
- // ::= dc <type> <expression> #
- // dynamic_cast<type> (expression)
- // ::= sc <type> <expression> #
- // static_cast<type> (expression)
- // ::= cc <type> <expression> #
- // const_cast<type> (expression)
- // ::= rc <type> <expression> #
- // reinterpret_cast<type> (expression)
- // ::= st <type> #
- // sizeof (a type)
- // ::= sz <expression> #
- // sizeof (an expression)
- // ::= at <type> #
- // alignof (a type)
- // ::= az <expression> #
- // alignof (an expression)
- // ::= nx <expression> #
- // noexcept (expression)
- // ::= <template-param>
- // ::= <function-param>
- // ::= dt <expression> <unresolved-name> #
- // expr.name
- // ::= pt <expression> <unresolved-name> #
- // expr->name
- // ::= ds <expression> <expression> #
- // expr.*expr
- // ::= sZ <template-param> #
- // size of a parameter pack
- // ::= sZ <function-param> #
- // size of a function parameter pack
- // ::= sp <expression> #
- // pack expansion
- // ::= tw <expression> #
- // throw expression
- // ::= tr #
- // throw with no operand (rethrow)
- // ::= <unresolved-name> #
- // f(p), N::f(p), ::f(p),
- // #
- // freestanding
- // dependent
- // name
- // (e.g.,
- // T::x),
- // #
- // objectless
- // nonstatic
- // member
- // reference
- // ::= <expr-primary>
-
- bool ParseExpression() {
- Operator expression_operator = TryParseOperator();
- switch (expression_operator.kind) {
- case OperatorKind::Unary:
- Write(expression_operator.name);
- Write('(');
- if (!ParseExpression())
- return false;
- Write(')');
- return true;
- case OperatorKind::Binary:
- if (!ParseExpression())
- return false;
- Write(expression_operator.name);
- return ParseExpression();
- case OperatorKind::Ternary:
- if (!ParseExpression())
- return false;
- Write('?');
- if (!ParseExpression())
- return false;
- Write(':');
- return ParseExpression();
- case OperatorKind::NoMatch:
- break;
- case OperatorKind::Other:
- default:
-#ifdef DEBUG_FAILURES
- printf("*** Unsupported operator: %s\n", expression_operator.name);
-#endif
- return false;
- }
-
- switch (*m_read_ptr++) {
- case 'T':
- return ParseTemplateParam();
- case 'L':
- return ParseExpressionPrimary();
- case 's':
- if (*m_read_ptr++ == 'r')
- return ParseUnresolvedName();
- --m_read_ptr;
- LLVM_FALLTHROUGH;
- default:
- return ParseExpressionPrimary();
- }
- }
-
- // <template-arg> ::= <type> #
- // type or template
- // ::= X <expression> E #
- // expression
- // ::= <expr-primary> #
- // simple expressions
- // ::= J <template-arg>* E #
- // argument pack
- // ::= LZ <encoding> E #
- // extension
-
- bool ParseTemplateArg() {
- switch (*m_read_ptr) {
- case 'J':
-#ifdef DEBUG_FAILURES
- printf("*** Template argument packs unsupported\n");
-#endif
- return false;
- case 'X':
- ++m_read_ptr;
- if (!ParseExpression())
- return false;
- return Parse('E');
- case 'L':
- ++m_read_ptr;
- return ParseExpressionPrimary();
- default:
- return ParseType();
- }
- }
-
- // <template-args> ::= I <template-arg>* E
- // extension, the abi says <template-arg>+
-
- bool ParseTemplateArgs(bool record_template_args = false) {
- if (record_template_args)
- ResetTemplateArgs();
-
- bool first_arg = true;
- while (*m_read_ptr != 'E') {
- if (first_arg)
- first_arg = false;
- else
- WriteCommaSpace();
-
- int template_start_cookie = GetStartCookie();
- if (!ParseTemplateArg())
- return false;
- if (record_template_args)
- EndTemplateArg(template_start_cookie);
- }
- ++m_read_ptr;
- return true;
- }
-
- // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix>
- // <unqualified-name> E
- // ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix>
- // <template-args> E
- //
- // <prefix> ::= <prefix> <unqualified-name>
- // ::= <template-prefix> <template-args>
- // ::= <template-param>
- // ::= <decltype>
- // ::= # empty
- // ::= <substitution>
- // ::= <prefix> <data-member-prefix>
- // extension ::= L
- //
- // <template-prefix> ::= <prefix> <template unqualified-name>
- // ::= <template-param>
- // ::= <substitution>
- //
- // <unqualified-name> ::= <operator-name>
- // ::= <ctor-dtor-name>
- // ::= <source-name>
- // ::= <unnamed-type-name>
-
- bool ParseNestedName(NameState &name_state,
- bool parse_discriminator = false) {
- int qualifiers = TryParseQualifiers(true, true);
- bool first_part = true;
- bool suppress_substitution = true;
- int name_start_cookie = GetStartCookie();
- while (true) {
- char next = *m_read_ptr;
- if (next == 'E') {
- ++m_read_ptr;
- break;
- }
-
- // Record a substitution candidate for all prefixes, but not the full
- // name
- if (suppress_substitution)
- suppress_substitution = false;
- else
- EndSubstitution(name_start_cookie);
-
- if (next == 'I') {
- ++m_read_ptr;
- name_state.is_last_generic = true;
- WriteTemplateStart();
- if (!ParseTemplateArgs(name_state.parse_function_params))
- return false;
- WriteTemplateEnd();
- continue;
- }
-
- if (first_part)
- first_part = false;
- else
- WriteNamespaceSeparator();
-
- name_state.is_last_generic = false;
- switch (next) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': {
- int name_start_cookie = GetStartCookie();
- if (!ParseSourceName())
- return false;
- name_state.last_name_range = EndRange(name_start_cookie);
- continue;
- }
- case 'S':
- if (*++m_read_ptr == 't') {
- WriteStdPrefix();
- ++m_read_ptr;
- if (!ParseUnqualifiedName(name_state))
- return false;
- } else {
- if (!ParseSubstitution())
- return false;
- suppress_substitution = true;
- }
- continue;
- case 'T':
- ++m_read_ptr;
- if (!ParseTemplateParam())
- return false;
- continue;
- case 'C':
- ++m_read_ptr;
- if (!ParseCtor(name_state))
- return false;
- continue;
- case 'D': {
- switch (*(m_read_ptr + 1)) {
- case 't':
- case 'T':
-#ifdef DEBUG_FAILURES
- printf("*** Decltype unsupported\n");
-#endif
- return false;
- }
- ++m_read_ptr;
- if (!ParseDtor(name_state))
- return false;
- continue;
- }
- case 'U':
- ++m_read_ptr;
- if (!ParseUnnamedTypeName(name_state))
- return false;
- continue;
- case 'L':
- ++m_read_ptr;
- if (!ParseUnqualifiedName(name_state))
- return false;
- continue;
- default:
- if (!ParseOperatorName(name_state))
- return false;
- }
- }
-
- if (parse_discriminator)
- TryParseDiscriminator();
- if (name_state.parse_function_params &&
- !ParseFunctionArgs(name_state, name_start_cookie)) {
- return false;
- }
- if (qualifiers)
- WriteQualifiers(qualifiers);
- return true;
- }
-
- // <local-name> := Z <function encoding> E <entity name> [<discriminator>]
- // := Z <function encoding> E s [<discriminator>]
- // := Z <function encoding> Ed [ <parameter number> ] _ <entity
- // name>
-
- bool ParseLocalName(bool parse_function_params) {
- if (!ParseEncoding())
- return false;
- if (!Parse('E'))
- return false;
-
- switch (*m_read_ptr) {
- case 's':
- ++m_read_ptr;
- TryParseDiscriminator(); // Optional and ignored
- WRITE("::string literal");
- break;
- case 'd':
- ++m_read_ptr;
- TryParseNumber(); // Optional and ignored
- if (!Parse('_'))
- return false;
- WriteNamespaceSeparator();
- if (!ParseName())
- return false;
- break;
- default:
- WriteNamespaceSeparator();
- if (!ParseName(parse_function_params, true))
- return false;
- TryParseDiscriminator(); // Optional and ignored
- }
- return true;
- }
-
- // <name> ::= <nested-name>
- // ::= <local-name>
- // ::= <unscoped-template-name> <template-args>
- // ::= <unscoped-name>
-
- // <unscoped-template-name> ::= <unscoped-name>
- // ::= <substitution>
-
- bool ParseName(bool parse_function_params = false,
- bool parse_discriminator = false) {
- NameState name_state = {parse_function_params, false, false, {0, 0}};
- int name_start_cookie = GetStartCookie();
-
- switch (*m_read_ptr) {
- case 'N':
- ++m_read_ptr;
- return ParseNestedName(name_state, parse_discriminator);
- case 'Z': {
- ++m_read_ptr;
- if (!ParseLocalName(parse_function_params))
- return false;
- break;
- }
- case 'L':
- ++m_read_ptr;
- LLVM_FALLTHROUGH;
- default: {
- if (!ParseUnscopedName(name_state))
- return false;
-
- if (*m_read_ptr == 'I') {
- EndSubstitution(name_start_cookie);
-
- ++m_read_ptr;
- name_state.is_last_generic = true;
- WriteTemplateStart();
- if (!ParseTemplateArgs(parse_function_params))
- return false;
- WriteTemplateEnd();
- }
- break;
- }
- }
- if (parse_discriminator)
- TryParseDiscriminator();
- if (parse_function_params &&
- !ParseFunctionArgs(name_state, name_start_cookie)) {
- return false;
- }
- return true;
- }
-
- // <call-offset> ::= h <nv-offset> _
- // ::= v <v-offset> _
- //
- // <nv-offset> ::= <offset number>
- // # non-virtual base override
- //
- // <v-offset> ::= <offset number> _ <virtual offset number>
- // # virtual base override, with vcall offset
-
- bool ParseCallOffset() {
- switch (*m_read_ptr++) {
- case 'h':
- if (*m_read_ptr == 'n')
- ++m_read_ptr;
- if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
- break;
- return true;
- case 'v':
- if (*m_read_ptr == 'n')
- ++m_read_ptr;
- if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
- break;
- if (*m_read_ptr == 'n')
- ++m_read_ptr;
- if (TryParseNumber() == -1 || *m_read_ptr++ != '_')
- break;
- return true;
- }
-#ifdef DEBUG_FAILURES
- printf("*** Malformed call offset\n");
-#endif
- return false;
- }
-
- // <special-name> ::= TV <type> # virtual table
- // ::= TT <type> # VTT structure (construction vtable index)
- // ::= TI <type> # typeinfo structure
- // ::= TS <type> # typeinfo name (null-terminated byte
- // string)
- // ::= Tc <call-offset> <call-offset> <base encoding>
- // # base is the nominal target function of thunk
- // # first call-offset is 'this' adjustment
- // # second call-offset is result adjustment
- // ::= T <call-offset> <base encoding>
- // # base is the nominal target function of thunk
- // extension ::= TC <first type> <number> _ <second type> # construction
- // vtable for second-in-first
-
- bool ParseSpecialNameT() {
- switch (*m_read_ptr++) {
- case 'V':
- WRITE("vtable for ");
- return ParseType();
- case 'T':
- WRITE("VTT for ");
- return ParseType();
- case 'I':
- WRITE("typeinfo for ");
- return ParseType();
- case 'S':
- WRITE("typeinfo name for ");
- return ParseType();
- case 'c':
- case 'C':
-#ifdef DEBUG_FAILURES
- printf("*** Unsupported thunk or construction vtable name: %.3s\n",
- m_read_ptr - 1);
-#endif
- return false;
- default:
- if (*--m_read_ptr == 'v') {
- WRITE("virtual thunk to ");
- } else {
- WRITE("non-virtual thunk to ");
- }
- if (!ParseCallOffset())
- return false;
- return ParseEncoding();
- }
- }
-
- // <special-name> ::= GV <object name> # Guard variable for one-time
- // initialization
- // # No <type>
- // extension ::= GR <object name> # reference temporary for object
-
- bool ParseSpecialNameG() {
- switch (*m_read_ptr++) {
- case 'V':
- WRITE("guard variable for ");
- if (!ParseName(true))
- return false;
- break;
- case 'R':
- WRITE("reference temporary for ");
- if (!ParseName(true))
- return false;
- break;
- default:
-#ifdef DEBUG_FAILURES
- printf("*** Unknown G encoding\n");
-#endif
- return false;
- }
- return true;
- }
-
- // <bare-function-type> ::= <signature type>+ # types are possible
- // return type, then parameter types
-
- bool ParseFunctionArgs(NameState &name_state, int return_insert_cookie) {
- char next = *m_read_ptr;
- if (next == 'E' || next == '\0' || next == '.')
- return true;
-
- // Clang has a bad habit of making unique manglings by just sticking
- // numbers on the end of a symbol, which is ambiguous with malformed source
- // name manglings
- const char *before_clang_uniquing_test = m_read_ptr;
- if (TryParseNumber()) {
- if (*m_read_ptr == '\0')
- return true;
- m_read_ptr = before_clang_uniquing_test;
- }
-
- if (name_state.is_last_generic && !name_state.has_no_return_type) {
- int return_type_start_cookie = GetStartCookie();
- if (!ParseType())
- return false;
- Write(' ');
- ReorderRange(EndRange(return_type_start_cookie), return_insert_cookie);
- }
-
- Write('(');
- bool first_param = true;
- while (true) {
- switch (*m_read_ptr) {
- case '\0':
- case 'E':
- case '.':
- break;
- case 'v':
- ++m_read_ptr;
- continue;
- case '_':
- // Not a formal part of the mangling specification, but clang emits
- // suffixes starting with _block_invoke
- if (strncmp(m_read_ptr, "_block_invoke", 13) == 0) {
- m_read_ptr += strlen(m_read_ptr);
- break;
- }
- LLVM_FALLTHROUGH;
- default:
- if (first_param)
- first_param = false;
- else
- WriteCommaSpace();
-
- if (!ParseType())
- return false;
- continue;
- }
- break;
- }
- Write(')');
- return true;
- }
-
- // <encoding> ::= <function name> <bare-function-type>
- // ::= <data name>
- // ::= <special-name>
-
- bool ParseEncoding() {
- switch (*m_read_ptr) {
- case 'T':
- ++m_read_ptr;
- if (!ParseSpecialNameT())
- return false;
- break;
- case 'G':
- ++m_read_ptr;
- if (!ParseSpecialNameG())
- return false;
- break;
- default:
- if (!ParseName(true))
- return false;
- break;
- }
- return true;
- }
-
- bool ParseMangling(const char *mangled_name, long mangled_name_length = 0) {
- if (!mangled_name_length)
- mangled_name_length = strlen(mangled_name);
- m_read_end = mangled_name + mangled_name_length;
- m_read_ptr = mangled_name;
- m_write_ptr = m_buffer;
- m_next_substitute_index = 0;
- m_next_template_arg_index = m_rewrite_ranges_size - 1;
-
- if (*m_read_ptr++ != '_' || *m_read_ptr++ != 'Z') {
-#ifdef DEBUG_FAILURES
- printf("*** Missing _Z prefix\n");
-#endif
- return false;
- }
- if (!ParseEncoding())
- return false;
- switch (*m_read_ptr) {
- case '.':
- Write(' ');
- Write('(');
- Write(m_read_ptr, m_read_end - m_read_ptr);
- Write(')');
- LLVM_FALLTHROUGH;
- case '\0':
- return true;
- default:
-#ifdef DEBUG_FAILURES
- printf("*** Unparsed mangled content\n");
-#endif
- return false;
- }
- }
-
-private:
- // External scratch storage used during demanglings
-
- char *m_buffer;
- const char *m_buffer_end;
- BufferRange *m_rewrite_ranges;
- int m_rewrite_ranges_size;
- bool m_owns_buffer;
- bool m_owns_m_rewrite_ranges;
-
- // Internal state used during demangling
-
- const char *m_read_ptr;
- const char *m_read_end;
- char *m_write_ptr;
- int m_next_template_arg_index;
- int m_next_substitute_index;
- std::function<void(const char *s)> m_builtins_hook;
-};
-
-} // Anonymous namespace
-
-// Public entry points referenced from Mangled.cpp
-namespace lldb_private {
-char *FastDemangle(const char *mangled_name) {
- char buffer[16384];
- SymbolDemangler demangler(buffer, sizeof(buffer));
- return demangler.GetDemangledCopy(mangled_name);
-}
-
-char *FastDemangle(const char *mangled_name, size_t mangled_name_length,
- std::function<void(const char *s)> builtins_hook) {
- char buffer[16384];
- SymbolDemangler demangler(buffer, sizeof(buffer), builtins_hook);
- return demangler.GetDemangledCopy(mangled_name, mangled_name_length);
-}
-} // lldb_private namespace
diff --git a/contrib/llvm/tools/lldb/source/Utility/FileSpec.cpp b/contrib/llvm/tools/lldb/source/Utility/FileSpec.cpp
index b6952f7e3eb0..954968b7a8af 100644
--- a/contrib/llvm/tools/lldb/source/Utility/FileSpec.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/FileSpec.cpp
@@ -10,7 +10,6 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/Stream.h"
-#include "lldb/Utility/TildeExpressionResolver.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -22,13 +21,14 @@
#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
-#include <algorithm> // for replace, min, unique
-#include <system_error> // for error_code
-#include <vector> // for vector
+#include <algorithm>
+#include <system_error>
+#include <vector>
-#include <assert.h> // for assert
-#include <stdio.h> // for size_t, NULL, snpr...
-#include <string.h> // for strcmp
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
using namespace lldb;
using namespace lldb_private;
@@ -66,38 +66,17 @@ void Denormalize(llvm::SmallVectorImpl<char> &path, FileSpec::Style style) {
} // end anonymous namespace
-void FileSpec::Resolve(llvm::SmallVectorImpl<char> &path) {
- if (path.empty())
- return;
-
- llvm::SmallString<32> Source(path.begin(), path.end());
- StandardTildeExpressionResolver Resolver;
- Resolver.ResolveFullPath(Source, path);
-
- // Save a copy of the original path that's passed in
- llvm::SmallString<128> original_path(path.begin(), path.end());
-
- llvm::sys::fs::make_absolute(path);
- if (!llvm::sys::fs::exists(path)) {
- path.clear();
- path.append(original_path.begin(), original_path.end());
- }
-}
-
FileSpec::FileSpec() : m_style(GetNativeStyle()) {}
//------------------------------------------------------------------
// Default constructor that can take an optional full path to a file on disk.
//------------------------------------------------------------------
-FileSpec::FileSpec(llvm::StringRef path, bool resolve_path, Style style)
- : m_style(style) {
- SetFile(path, resolve_path, style);
+FileSpec::FileSpec(llvm::StringRef path, Style style) : m_style(style) {
+ SetFile(path, style);
}
-FileSpec::FileSpec(llvm::StringRef path, bool resolve_path,
- const llvm::Triple &Triple)
- : FileSpec{path, resolve_path,
- Triple.isOSWindows() ? Style::windows : Style::posix} {}
+FileSpec::FileSpec(llvm::StringRef path, const llvm::Triple &Triple)
+ : FileSpec{path, Triple.isOSWindows() ? Style::windows : Style::posix} {}
//------------------------------------------------------------------
// Copy constructor
@@ -226,16 +205,14 @@ const FileSpec &FileSpec::operator=(const FileSpec &rhs) {
return *this;
}
-void FileSpec::SetFile(llvm::StringRef pathname, bool resolve) {
- SetFile(pathname, resolve, m_style);
-}
+void FileSpec::SetFile(llvm::StringRef pathname) { SetFile(pathname, m_style); }
//------------------------------------------------------------------
// Update the contents of this object with a new path. The path will be split
// up into a directory and filename and stored as uniqued string values for
// quick comparison and efficient memory usage.
//------------------------------------------------------------------
-void FileSpec::SetFile(llvm::StringRef pathname, bool resolve, Style style) {
+void FileSpec::SetFile(llvm::StringRef pathname, Style style) {
m_filename.Clear();
m_directory.Clear();
m_is_resolved = false;
@@ -244,12 +221,7 @@ void FileSpec::SetFile(llvm::StringRef pathname, bool resolve, Style style) {
if (pathname.empty())
return;
- llvm::SmallString<64> resolved(pathname);
-
- if (resolve) {
- FileSpec::Resolve(resolved);
- m_is_resolved = true;
- }
+ llvm::SmallString<128> resolved(pathname);
// Normalize the path by removing ".", ".." and other redundant components.
if (needsNormalization(resolved))
@@ -272,15 +244,14 @@ void FileSpec::SetFile(llvm::StringRef pathname, bool resolve, Style style) {
llvm::StringRef filename = llvm::sys::path::filename(resolved, m_style);
if(!filename.empty())
m_filename.SetString(filename);
+
llvm::StringRef directory = llvm::sys::path::parent_path(resolved, m_style);
if(!directory.empty())
m_directory.SetString(directory);
}
-void FileSpec::SetFile(llvm::StringRef path, bool resolve,
- const llvm::Triple &Triple) {
- return SetFile(path, resolve,
- Triple.isOSWindows() ? Style::windows : Style::posix);
+void FileSpec::SetFile(llvm::StringRef path, const llvm::Triple &Triple) {
+ return SetFile(path, Triple.isOSWindows() ? Style::windows : Style::posix);
}
//----------------------------------------------------------------------
@@ -315,49 +286,7 @@ bool FileSpec::FileEquals(const FileSpec &rhs) const {
// Equal to operator
//------------------------------------------------------------------
bool FileSpec::operator==(const FileSpec &rhs) const {
- if (!FileEquals(rhs))
- return false;
- if (DirectoryEquals(rhs))
- return true;
-
- // TODO: determine if we want to keep this code in here.
- // The code below was added to handle a case where we were trying to set a
- // file and line breakpoint and one path was resolved, and the other not and
- // the directory was in a mount point that resolved to a more complete path:
- // "/tmp/a.c" == "/private/tmp/a.c". I might end up pulling this out...
- if (IsResolved() && rhs.IsResolved()) {
- // Both paths are resolved, no need to look further...
- return false;
- }
-
- FileSpec resolved_lhs(*this);
-
- // If "this" isn't resolved, resolve it
- if (!IsResolved()) {
- if (resolved_lhs.ResolvePath()) {
- // This path wasn't resolved but now it is. Check if the resolved
- // directory is the same as our unresolved directory, and if so, we can
- // mark this object as resolved to avoid more future resolves
- m_is_resolved = (m_directory == resolved_lhs.m_directory);
- } else
- return false;
- }
-
- FileSpec resolved_rhs(rhs);
- if (!rhs.IsResolved()) {
- if (resolved_rhs.ResolvePath()) {
- // rhs's path wasn't resolved but now it is. Check if the resolved
- // directory is the same as rhs's unresolved directory, and if so, we can
- // mark this object as resolved to avoid more future resolves
- rhs.m_is_resolved = (rhs.m_directory == resolved_rhs.m_directory);
- } else
- return false;
- }
-
- // If we reach this point in the code we were able to resolve both paths and
- // since we only resolve the paths if the basenames are equal, then we can
- // just check if both directories are equal...
- return DirectoryEquals(rhs);
+ return FileEquals(rhs) && DirectoryEquals(rhs);
}
//------------------------------------------------------------------
@@ -452,78 +381,8 @@ void FileSpec::Dump(Stream *s) const {
}
}
-//------------------------------------------------------------------
-// Returns true if the file exists.
-//------------------------------------------------------------------
-bool FileSpec::Exists() const { return llvm::sys::fs::exists(GetPath()); }
-
-bool FileSpec::Readable() const {
- return GetPermissions() & llvm::sys::fs::perms::all_read;
-}
-
-bool FileSpec::ResolveExecutableLocation() {
- // CLEANUP: Use StringRef for string handling.
- if (!m_directory) {
- const char *file_cstr = m_filename.GetCString();
- if (file_cstr) {
- const std::string file_str(file_cstr);
- llvm::ErrorOr<std::string> error_or_path =
- llvm::sys::findProgramByName(file_str);
- if (!error_or_path)
- return false;
- std::string path = error_or_path.get();
- llvm::StringRef dir_ref = llvm::sys::path::parent_path(path);
- if (!dir_ref.empty()) {
- // FindProgramByName returns "." if it can't find the file.
- if (strcmp(".", dir_ref.data()) == 0)
- return false;
-
- m_directory.SetCString(dir_ref.data());
- if (Exists())
- return true;
- else {
- // If FindProgramByName found the file, it returns the directory +
- // filename in its return results. We need to separate them.
- FileSpec tmp_file(dir_ref.data(), false);
- if (tmp_file.Exists()) {
- m_directory = tmp_file.m_directory;
- return true;
- }
- }
- }
- }
- }
-
- return false;
-}
-
-bool FileSpec::ResolvePath() {
- if (m_is_resolved)
- return true; // We have already resolved this path
-
- // SetFile(...) will set m_is_resolved correctly if it can resolve the path
- SetFile(GetPath(false), true);
- return m_is_resolved;
-}
-
-uint64_t FileSpec::GetByteSize() const {
- uint64_t Size = 0;
- if (llvm::sys::fs::file_size(GetPath(), Size))
- return 0;
- return Size;
-}
-
FileSpec::Style FileSpec::GetPathStyle() const { return m_style; }
-uint32_t FileSpec::GetPermissions() const {
- namespace fs = llvm::sys::fs;
- fs::file_status st;
- if (fs::status(GetPath(), st, false))
- return fs::perms::perms_not_known;
-
- return st.permissions();
-}
-
//------------------------------------------------------------------
// Directory string get accessor.
//------------------------------------------------------------------
@@ -565,7 +424,7 @@ std::string FileSpec::GetPath(bool denormalize) const {
}
const char *FileSpec::GetCString(bool denormalize) const {
- return ConstString{GetPath(denormalize)}.AsCString(NULL);
+ return ConstString{GetPath(denormalize)}.AsCString(nullptr);
}
void FileSpec::GetPath(llvm::SmallVectorImpl<char> &path,
@@ -601,39 +460,6 @@ size_t FileSpec::MemorySize() const {
return m_filename.MemorySize() + m_directory.MemorySize();
}
-void FileSpec::EnumerateDirectory(llvm::StringRef dir_path,
- bool find_directories, bool find_files,
- bool find_other,
- EnumerateDirectoryCallbackType callback,
- void *callback_baton) {
- namespace fs = llvm::sys::fs;
- std::error_code EC;
- fs::recursive_directory_iterator Iter(dir_path, EC);
- fs::recursive_directory_iterator End;
- for (; Iter != End && !EC; Iter.increment(EC)) {
- const auto &Item = *Iter;
- llvm::ErrorOr<fs::basic_file_status> Status = Item.status();
- if (!Status)
- break;
- if (!find_files && fs::is_regular_file(*Status))
- continue;
- if (!find_directories && fs::is_directory(*Status))
- continue;
- if (!find_other && fs::is_other(*Status))
- continue;
-
- FileSpec Spec(Item.path(), false);
- auto Result = callback(callback_baton, Status->type(), Spec);
- if (Result == eEnumerateDirectoryResultQuit)
- return;
- if (Result == eEnumerateDirectoryResultNext) {
- // Default behavior is to recurse. Opt out if the callback doesn't want
- // this behavior.
- Iter.no_push();
- }
- }
-}
-
FileSpec
FileSpec::CopyByAppendingPathComponent(llvm::StringRef component) const {
FileSpec ret = *this;
@@ -645,7 +471,7 @@ FileSpec FileSpec::CopyByRemovingLastPathComponent() const {
llvm::SmallString<64> current_path;
GetPath(current_path, false);
if (llvm::sys::path::has_parent_path(current_path, m_style))
- return FileSpec(llvm::sys::path::parent_path(current_path, m_style), false,
+ return FileSpec(llvm::sys::path::parent_path(current_path, m_style),
m_style);
return *this;
}
@@ -663,7 +489,7 @@ void FileSpec::PrependPathComponent(llvm::StringRef component) {
llvm::sys::path::append(new_path,
llvm::sys::path::begin(current_path, m_style),
llvm::sys::path::end(current_path), m_style);
- SetFile(new_path, false, m_style);
+ SetFile(new_path, m_style);
}
void FileSpec::PrependPathComponent(const FileSpec &new_path) {
@@ -674,7 +500,7 @@ void FileSpec::AppendPathComponent(llvm::StringRef component) {
llvm::SmallString<64> current_path;
GetPath(current_path, false);
llvm::sys::path::append(current_path, m_style, component);
- SetFile(current_path, false, m_style);
+ SetFile(current_path, m_style);
}
void FileSpec::AppendPathComponent(const FileSpec &new_path) {
@@ -685,7 +511,7 @@ bool FileSpec::RemoveLastPathComponent() {
llvm::SmallString<64> current_path;
GetPath(current_path, false);
if (llvm::sys::path::has_parent_path(current_path, m_style)) {
- SetFile(llvm::sys::path::parent_path(current_path, m_style), false);
+ SetFile(llvm::sys::path::parent_path(current_path, m_style));
return true;
}
return false;
diff --git a/contrib/llvm/tools/lldb/source/Utility/JSON.cpp b/contrib/llvm/tools/lldb/source/Utility/JSON.cpp
index 7d70034ccabd..725ea97955c6 100644
--- a/contrib/llvm/tools/lldb/source/Utility/JSON.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/JSON.cpp
@@ -9,15 +9,15 @@
#include "lldb/Utility/JSON.h"
-#include "lldb/Utility/Stream.h" // for Stream
+#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
-#include <inttypes.h> // for PRIu64, PRId64
+#include <inttypes.h>
#include <limits.h>
-#include <stddef.h> // for size_t
-#include <utility> // for pair
+#include <stddef.h>
+#include <utility>
using namespace lldb_private;
diff --git a/contrib/llvm/tools/lldb/source/Utility/LLDBAssert.cpp b/contrib/llvm/tools/lldb/source/Utility/LLDBAssert.cpp
index 48c1b69e8947..3902c89b2c83 100644
--- a/contrib/llvm/tools/lldb/source/Utility/LLDBAssert.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/LLDBAssert.cpp
@@ -19,14 +19,14 @@ using namespace lldb_private;
void lldb_private::lldb_assert(bool expression, const char *expr_text,
const char *func, const char *file,
unsigned int line) {
- if (expression)
- ;
- else {
- errs() << format("Assertion failed: (%s), function %s, file %s, line %u\n",
- expr_text, func, file, line);
- errs() << "backtrace leading to the failure:\n";
- llvm::sys::PrintStackTrace(errs());
- errs() << "please file a bug report against lldb reporting this failure "
- "log, and as many details as possible\n";
- }
+ if (LLVM_LIKELY(expression))
+ return;
+
+ errs() << format("Assertion failed: (%s), function %s, file %s, line %u\n",
+ expr_text, func, file, line);
+ errs() << "backtrace leading to the failure:\n";
+ llvm::sys::PrintStackTrace(errs());
+ errs() << "please file a bug report against lldb reporting this failure "
+ "log, and as many details as possible\n";
+ abort();
}
diff --git a/contrib/llvm/tools/lldb/source/Utility/Listener.cpp b/contrib/llvm/tools/lldb/source/Utility/Listener.cpp
new file mode 100644
index 000000000000..a20859e53eeb
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Utility/Listener.cpp
@@ -0,0 +1,468 @@
+//===-- Listener.cpp --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Listener.h"
+
+#include "lldb/Utility/Broadcaster.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/Event.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Logging.h"
+
+#include "llvm/ADT/Optional.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace {
+class BroadcasterManagerWPMatcher {
+public:
+ BroadcasterManagerWPMatcher(BroadcasterManagerSP manager_sp)
+ : m_manager_sp(manager_sp) {}
+ bool operator()(const BroadcasterManagerWP input_wp) const {
+ BroadcasterManagerSP input_sp = input_wp.lock();
+ return (input_sp && input_sp == m_manager_sp);
+ }
+
+ BroadcasterManagerSP m_manager_sp;
+};
+} // anonymous namespace
+
+Listener::Listener(const char *name)
+ : m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(),
+ m_events_mutex() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ if (log != nullptr)
+ log->Printf("%p Listener::Listener('%s')", static_cast<void *>(this),
+ m_name.c_str());
+}
+
+Listener::~Listener() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+
+ Clear();
+
+ if (log)
+ log->Printf("%p Listener::%s('%s')", static_cast<void *>(this),
+ __FUNCTION__, m_name.c_str());
+}
+
+void Listener::Clear() {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ broadcaster_collection::iterator pos, end = m_broadcasters.end();
+ for (pos = m_broadcasters.begin(); pos != end; ++pos) {
+ Broadcaster::BroadcasterImplSP broadcaster_sp(pos->first.lock());
+ if (broadcaster_sp)
+ broadcaster_sp->RemoveListener(this, pos->second.event_mask);
+ }
+ m_broadcasters.clear();
+
+ std::lock_guard<std::mutex> events_guard(m_events_mutex);
+ m_events.clear();
+ size_t num_managers = m_broadcaster_managers.size();
+
+ for (size_t i = 0; i < num_managers; i++) {
+ BroadcasterManagerSP manager_sp(m_broadcaster_managers[i].lock());
+ if (manager_sp)
+ manager_sp->RemoveListener(this);
+ }
+
+ if (log)
+ log->Printf("%p Listener::%s('%s')", static_cast<void *>(this),
+ __FUNCTION__, m_name.c_str());
+}
+
+uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
+ uint32_t event_mask) {
+ if (broadcaster) {
+ // Scope for "locker"
+ // Tell the broadcaster to add this object as a listener
+ {
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
+ m_broadcasters.insert(
+ std::make_pair(impl_wp, BroadcasterInfo(event_mask)));
+ }
+
+ uint32_t acquired_mask =
+ broadcaster->AddListener(this->shared_from_this(), event_mask);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log != nullptr)
+ log->Printf("%p Listener::StartListeningForEvents (broadcaster = %p, "
+ "mask = 0x%8.8x) acquired_mask = 0x%8.8x for %s",
+ static_cast<void *>(this), static_cast<void *>(broadcaster),
+ event_mask, acquired_mask, m_name.c_str());
+
+ return acquired_mask;
+ }
+ return 0;
+}
+
+uint32_t Listener::StartListeningForEvents(Broadcaster *broadcaster,
+ uint32_t event_mask,
+ HandleBroadcastCallback callback,
+ void *callback_user_data) {
+ if (broadcaster) {
+ // Scope for "locker"
+ // Tell the broadcaster to add this object as a listener
+ {
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ Broadcaster::BroadcasterImplWP impl_wp(broadcaster->GetBroadcasterImpl());
+ m_broadcasters.insert(std::make_pair(
+ impl_wp, BroadcasterInfo(event_mask, callback, callback_user_data)));
+ }
+
+ uint32_t acquired_mask =
+ broadcaster->AddListener(this->shared_from_this(), event_mask);
+
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log != nullptr) {
+ void **pointer = reinterpret_cast<void **>(&callback);
+ log->Printf("%p Listener::StartListeningForEvents (broadcaster = %p, "
+ "mask = 0x%8.8x, callback = %p, user_data = %p) "
+ "acquired_mask = 0x%8.8x for %s",
+ static_cast<void *>(this), static_cast<void *>(broadcaster),
+ event_mask, *pointer, static_cast<void *>(callback_user_data),
+ acquired_mask, m_name.c_str());
+ }
+
+ return acquired_mask;
+ }
+ return 0;
+}
+
+bool Listener::StopListeningForEvents(Broadcaster *broadcaster,
+ uint32_t event_mask) {
+ if (broadcaster) {
+ // Scope for "locker"
+ {
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ m_broadcasters.erase(broadcaster->GetBroadcasterImpl());
+ }
+ // Remove the broadcaster from our set of broadcasters
+ return broadcaster->RemoveListener(this->shared_from_this(), event_mask);
+ }
+
+ return false;
+}
+
+// Called when a Broadcaster is in its destructor. We need to remove all
+// knowledge of this broadcaster and any events that it may have queued up
+void Listener::BroadcasterWillDestruct(Broadcaster *broadcaster) {
+ // Scope for "broadcasters_locker"
+ {
+ std::lock_guard<std::recursive_mutex> broadcasters_guard(
+ m_broadcasters_mutex);
+ m_broadcasters.erase(broadcaster->GetBroadcasterImpl());
+ }
+
+ // Scope for "event_locker"
+ {
+ std::lock_guard<std::mutex> events_guard(m_events_mutex);
+ // Remove all events for this broadcaster object.
+ event_collection::iterator pos = m_events.begin();
+ while (pos != m_events.end()) {
+ if ((*pos)->GetBroadcaster() == broadcaster)
+ pos = m_events.erase(pos);
+ else
+ ++pos;
+ }
+ }
+}
+
+void Listener::BroadcasterManagerWillDestruct(BroadcasterManagerSP manager_sp) {
+ // Just need to remove this broadcast manager from the list of managers:
+ broadcaster_manager_collection::iterator iter,
+ end_iter = m_broadcaster_managers.end();
+ BroadcasterManagerWP manager_wp;
+
+ BroadcasterManagerWPMatcher matcher(manager_sp);
+ iter = std::find_if<broadcaster_manager_collection::iterator,
+ BroadcasterManagerWPMatcher>(
+ m_broadcaster_managers.begin(), end_iter, matcher);
+ if (iter != end_iter)
+ m_broadcaster_managers.erase(iter);
+}
+
+void Listener::AddEvent(EventSP &event_sp) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ if (log != nullptr)
+ log->Printf("%p Listener('%s')::AddEvent (event_sp = {%p})",
+ static_cast<void *>(this), m_name.c_str(),
+ static_cast<void *>(event_sp.get()));
+
+ std::lock_guard<std::mutex> guard(m_events_mutex);
+ m_events.push_back(event_sp);
+ m_events_condition.notify_all();
+}
+
+class EventBroadcasterMatches {
+public:
+ EventBroadcasterMatches(Broadcaster *broadcaster)
+ : m_broadcaster(broadcaster) {}
+
+ bool operator()(const EventSP &event_sp) const {
+ return event_sp->BroadcasterIs(m_broadcaster);
+ }
+
+private:
+ Broadcaster *m_broadcaster;
+};
+
+class EventMatcher {
+public:
+ EventMatcher(Broadcaster *broadcaster, const ConstString *broadcaster_names,
+ uint32_t num_broadcaster_names, uint32_t event_type_mask)
+ : m_broadcaster(broadcaster), m_broadcaster_names(broadcaster_names),
+ m_num_broadcaster_names(num_broadcaster_names),
+ m_event_type_mask(event_type_mask) {}
+
+ bool operator()(const EventSP &event_sp) const {
+ if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster))
+ return false;
+
+ if (m_broadcaster_names) {
+ bool found_source = false;
+ const ConstString &event_broadcaster_name =
+ event_sp->GetBroadcaster()->GetBroadcasterName();
+ for (uint32_t i = 0; i < m_num_broadcaster_names; ++i) {
+ if (m_broadcaster_names[i] == event_broadcaster_name) {
+ found_source = true;
+ break;
+ }
+ }
+ if (!found_source)
+ return false;
+ }
+
+ return m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType();
+ }
+
+private:
+ Broadcaster *m_broadcaster;
+ const ConstString *m_broadcaster_names;
+ const uint32_t m_num_broadcaster_names;
+ const uint32_t m_event_type_mask;
+};
+
+bool Listener::FindNextEventInternal(
+ std::unique_lock<std::mutex> &lock,
+ Broadcaster *broadcaster, // nullptr for any broadcaster
+ const ConstString *broadcaster_names, // nullptr for any event
+ uint32_t num_broadcaster_names, uint32_t event_type_mask, EventSP &event_sp,
+ bool remove) {
+ // NOTE: callers of this function must lock m_events_mutex using a
+ // Mutex::Locker
+ // and pass the locker as the first argument. m_events_mutex is no longer
+ // recursive.
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+
+ if (m_events.empty())
+ return false;
+
+ Listener::event_collection::iterator pos = m_events.end();
+
+ if (broadcaster == nullptr && broadcaster_names == nullptr &&
+ event_type_mask == 0) {
+ pos = m_events.begin();
+ } else {
+ pos = std::find_if(m_events.begin(), m_events.end(),
+ EventMatcher(broadcaster, broadcaster_names,
+ num_broadcaster_names, event_type_mask));
+ }
+
+ if (pos != m_events.end()) {
+ event_sp = *pos;
+
+ if (log != nullptr)
+ log->Printf("%p '%s' Listener::FindNextEventInternal(broadcaster=%p, "
+ "broadcaster_names=%p[%u], event_type_mask=0x%8.8x, "
+ "remove=%i) event %p",
+ static_cast<void *>(this), GetName(),
+ static_cast<void *>(broadcaster),
+ static_cast<const void *>(broadcaster_names),
+ num_broadcaster_names, event_type_mask, remove,
+ static_cast<void *>(event_sp.get()));
+
+ if (remove) {
+ m_events.erase(pos);
+ // Unlock the event queue here. We've removed this event and are about
+ // to return it so it should be okay to get the next event off the queue
+ // here - and it might be useful to do that in the "DoOnRemoval".
+ lock.unlock();
+ event_sp->DoOnRemoval();
+ }
+ return true;
+ }
+
+ event_sp.reset();
+ return false;
+}
+
+Event *Listener::PeekAtNextEvent() {
+ std::unique_lock<std::mutex> guard(m_events_mutex);
+ EventSP event_sp;
+ if (FindNextEventInternal(guard, nullptr, nullptr, 0, 0, event_sp, false))
+ return event_sp.get();
+ return nullptr;
+}
+
+Event *Listener::PeekAtNextEventForBroadcaster(Broadcaster *broadcaster) {
+ std::unique_lock<std::mutex> guard(m_events_mutex);
+ EventSP event_sp;
+ if (FindNextEventInternal(guard, broadcaster, nullptr, 0, 0, event_sp, false))
+ return event_sp.get();
+ return nullptr;
+}
+
+Event *
+Listener::PeekAtNextEventForBroadcasterWithType(Broadcaster *broadcaster,
+ uint32_t event_type_mask) {
+ std::unique_lock<std::mutex> guard(m_events_mutex);
+ EventSP event_sp;
+ if (FindNextEventInternal(guard, broadcaster, nullptr, 0, event_type_mask,
+ event_sp, false))
+ return event_sp.get();
+ return nullptr;
+}
+
+bool Listener::GetEventInternal(
+ const Timeout<std::micro> &timeout,
+ Broadcaster *broadcaster, // nullptr for any broadcaster
+ const ConstString *broadcaster_names, // nullptr for any event
+ uint32_t num_broadcaster_names, uint32_t event_type_mask,
+ EventSP &event_sp) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS));
+ LLDB_LOG(log, "this = {0}, timeout = {1} for {2}", this, timeout, m_name);
+
+ std::unique_lock<std::mutex> lock(m_events_mutex);
+
+ while (true) {
+ if (FindNextEventInternal(lock, broadcaster, broadcaster_names,
+ num_broadcaster_names, event_type_mask, event_sp,
+ true)) {
+ return true;
+ } else {
+ std::cv_status result = std::cv_status::no_timeout;
+ if (!timeout)
+ m_events_condition.wait(lock);
+ else
+ result = m_events_condition.wait_for(lock, *timeout);
+
+ if (result == std::cv_status::timeout) {
+ log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
+ if (log)
+ log->Printf("%p Listener::GetEventInternal() timed out for %s",
+ static_cast<void *>(this), m_name.c_str());
+ return false;
+ } else if (result != std::cv_status::no_timeout) {
+ log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EVENTS);
+ if (log)
+ log->Printf("%p Listener::GetEventInternal() unknown error for %s",
+ static_cast<void *>(this), m_name.c_str());
+ return false;
+ }
+ }
+ }
+
+ return false;
+}
+
+bool Listener::GetEventForBroadcasterWithType(
+ Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp,
+ const Timeout<std::micro> &timeout) {
+ return GetEventInternal(timeout, broadcaster, nullptr, 0, event_type_mask,
+ event_sp);
+}
+
+bool Listener::GetEventForBroadcaster(Broadcaster *broadcaster,
+ EventSP &event_sp,
+ const Timeout<std::micro> &timeout) {
+ return GetEventInternal(timeout, broadcaster, nullptr, 0, 0, event_sp);
+}
+
+bool Listener::GetEvent(EventSP &event_sp, const Timeout<std::micro> &timeout) {
+ return GetEventInternal(timeout, nullptr, nullptr, 0, 0, event_sp);
+}
+
+size_t Listener::HandleBroadcastEvent(EventSP &event_sp) {
+ size_t num_handled = 0;
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ Broadcaster *broadcaster = event_sp->GetBroadcaster();
+ if (!broadcaster)
+ return 0;
+ broadcaster_collection::iterator pos;
+ broadcaster_collection::iterator end = m_broadcasters.end();
+ Broadcaster::BroadcasterImplSP broadcaster_impl_sp(
+ broadcaster->GetBroadcasterImpl());
+ for (pos = m_broadcasters.find(broadcaster_impl_sp);
+ pos != end && pos->first.lock() == broadcaster_impl_sp; ++pos) {
+ BroadcasterInfo info = pos->second;
+ if (event_sp->GetType() & info.event_mask) {
+ if (info.callback != nullptr) {
+ info.callback(event_sp, info.callback_user_data);
+ ++num_handled;
+ }
+ }
+ }
+ return num_handled;
+}
+
+uint32_t
+Listener::StartListeningForEventSpec(BroadcasterManagerSP manager_sp,
+ const BroadcastEventSpec &event_spec) {
+ if (!manager_sp)
+ return 0;
+
+ // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to
+ // avoid violating the lock hierarchy (manager before broadcasters).
+ std::lock_guard<std::recursive_mutex> manager_guard(
+ manager_sp->m_manager_mutex);
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+
+ uint32_t bits_acquired = manager_sp->RegisterListenerForEvents(
+ this->shared_from_this(), event_spec);
+ if (bits_acquired) {
+ broadcaster_manager_collection::iterator iter,
+ end_iter = m_broadcaster_managers.end();
+ BroadcasterManagerWP manager_wp(manager_sp);
+ BroadcasterManagerWPMatcher matcher(manager_sp);
+ iter = std::find_if<broadcaster_manager_collection::iterator,
+ BroadcasterManagerWPMatcher>(
+ m_broadcaster_managers.begin(), end_iter, matcher);
+ if (iter == end_iter)
+ m_broadcaster_managers.push_back(manager_wp);
+ }
+
+ return bits_acquired;
+}
+
+bool Listener::StopListeningForEventSpec(BroadcasterManagerSP manager_sp,
+ const BroadcastEventSpec &event_spec) {
+ if (!manager_sp)
+ return false;
+
+ std::lock_guard<std::recursive_mutex> guard(m_broadcasters_mutex);
+ return manager_sp->UnregisterListenerForEvents(this->shared_from_this(),
+ event_spec);
+}
+
+ListenerSP Listener::MakeListener(const char *name) {
+ return ListenerSP(new Listener(name));
+}
diff --git a/contrib/llvm/tools/lldb/source/Utility/Log.cpp b/contrib/llvm/tools/lldb/source/Utility/Log.cpp
index eb026fb04752..2e8570b762af 100644
--- a/contrib/llvm/tools/lldb/source/Utility/Log.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/Log.cpp
@@ -12,24 +12,24 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/Twine.h" // for operator+, Twine
-#include "llvm/ADT/iterator.h" // for iterator_facade_base
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/Support/Chrono.h"
-#include "llvm/Support/ManagedStatic.h" // for ManagedStatic
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/raw_ostream.h"
-#include <chrono> // for duration, system_clock, syst...
+#include <chrono>
#include <cstdarg>
#include <mutex>
-#include <utility> // for pair
+#include <utility>
-#include <assert.h> // for assert
+#include <assert.h>
#if defined(_WIN32)
-#include <process.h> // for getpid
+#include <process.h>
#else
#include <unistd.h>
#include <pthread.h>
diff --git a/contrib/llvm/tools/lldb/source/Utility/Logging.cpp b/contrib/llvm/tools/lldb/source/Utility/Logging.cpp
index c9a6ef1bd1ea..b97a88b5edcb 100644
--- a/contrib/llvm/tools/lldb/source/Utility/Logging.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/Logging.cpp
@@ -10,9 +10,9 @@
#include "lldb/Utility/Logging.h"
#include "lldb/Utility/Log.h"
-#include "llvm/ADT/ArrayRef.h" // for ArrayRef
+#include "llvm/ADT/ArrayRef.h"
-#include <stdarg.h> // for va_end, va_list, va_start
+#include <stdarg.h>
using namespace lldb_private;
diff --git a/contrib/llvm/tools/lldb/source/Utility/Range.cpp b/contrib/llvm/tools/lldb/source/Utility/Range.cpp
deleted file mode 100644
index 9d1d28ea484b..000000000000
--- a/contrib/llvm/tools/lldb/source/Utility/Range.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-//===--------------------- Range.cpp -----------------------------*- C++-*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Utility/Range.h"
-
-#include <algorithm>
-#include <utility>
-
-using namespace lldb_utility;
-
-Range::Range(const Range &rng) : m_low(rng.m_low), m_high(rng.m_high) {
- InitRange();
-}
-
-Range::Range(Range::ValueType low, Range::ValueType high)
- : m_low(low), m_high(high) {
- InitRange();
-}
-
-void Range::InitRange() {
- if (m_low == OPEN_END) {
- if (m_high == OPEN_END)
- m_low = 0;
- else {
- // make an empty range
- m_low = 1;
- m_high = 0;
- }
- }
-}
-
-Range &Range::operator=(const Range &rhs) {
- if (&rhs != this) {
- this->m_low = rhs.m_low;
- this->m_high = rhs.m_high;
- }
- return *this;
-}
-
-void Range::Flip() { std::swap(m_high, m_low); }
-
-void Range::Intersection(const Range &other) {
- m_low = std::max(m_low, other.m_low);
- m_high = std::min(m_high, other.m_high);
-}
-
-void Range::Union(const Range &other) {
- m_low = std::min(m_low, other.m_low);
- m_high = std::max(m_high, other.m_high);
-}
-
-void Range::Iterate(RangeCallback callback) {
- ValueType counter = m_low;
- while (counter <= m_high) {
- bool should_continue = callback(counter);
- if (!should_continue)
- return;
- counter++;
- }
-}
-
-bool Range::IsEmpty() { return (m_low > m_high); }
-
-Range::ValueType Range::GetSize() {
- if (m_high == OPEN_END)
- return OPEN_END;
- if (m_high >= m_low)
- return m_high - m_low + 1;
- return 0;
-}
diff --git a/contrib/llvm/tools/lldb/source/Utility/RegisterValue.cpp b/contrib/llvm/tools/lldb/source/Utility/RegisterValue.cpp
new file mode 100644
index 000000000000..27bffde637fb
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Utility/RegisterValue.cpp
@@ -0,0 +1,877 @@
+//===-- RegisterValue.cpp ---------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/RegisterValue.h"
+
+#include "lldb/Utility/Args.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Scalar.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Utility/StreamString.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-private-types.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <cstdint>
+#include <string>
+#include <tuple>
+#include <vector>
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+
+using namespace lldb;
+using namespace lldb_private;
+
+bool RegisterValue::GetData(DataExtractor &data) const {
+ return data.SetData(GetBytes(), GetByteSize(), GetByteOrder()) > 0;
+}
+
+uint32_t RegisterValue::GetAsMemoryData(const RegisterInfo *reg_info, void *dst,
+ uint32_t dst_len,
+ lldb::ByteOrder dst_byte_order,
+ Status &error) const {
+ if (reg_info == nullptr) {
+ error.SetErrorString("invalid register info argument.");
+ return 0;
+ }
+
+ // ReadRegister should have already been called on this object prior to
+ // calling this.
+ if (GetType() == eTypeInvalid) {
+ // No value has been read into this object...
+ error.SetErrorStringWithFormat(
+ "invalid register value type for register %s", reg_info->name);
+ return 0;
+ }
+
+ if (dst_len > kMaxRegisterByteSize) {
+ error.SetErrorString("destination is too big");
+ return 0;
+ }
+
+ const uint32_t src_len = reg_info->byte_size;
+
+ // Extract the register data into a data extractor
+ DataExtractor reg_data;
+ if (!GetData(reg_data)) {
+ error.SetErrorString("invalid register value to copy into");
+ return 0;
+ }
+
+ // Prepare a memory buffer that contains some or all of the register value
+ const uint32_t bytes_copied =
+ reg_data.CopyByteOrderedData(0, // src offset
+ src_len, // src length
+ dst, // dst buffer
+ dst_len, // dst length
+ dst_byte_order); // dst byte order
+ if (bytes_copied == 0)
+ error.SetErrorStringWithFormat(
+ "failed to copy data for register write of %s", reg_info->name);
+
+ return bytes_copied;
+}
+
+uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo *reg_info,
+ const void *src, uint32_t src_len,
+ lldb::ByteOrder src_byte_order,
+ Status &error) {
+ if (reg_info == nullptr) {
+ error.SetErrorString("invalid register info argument.");
+ return 0;
+ }
+
+ // Moving from addr into a register
+ //
+ // Case 1: src_len == dst_len
+ //
+ // |AABBCCDD| Address contents
+ // |AABBCCDD| Register contents
+ //
+ // Case 2: src_len > dst_len
+ //
+ // Status! (The register should always be big enough to hold the data)
+ //
+ // Case 3: src_len < dst_len
+ //
+ // |AABB| Address contents
+ // |AABB0000| Register contents [on little-endian hardware]
+ // |0000AABB| Register contents [on big-endian hardware]
+ if (src_len > kMaxRegisterByteSize) {
+ error.SetErrorStringWithFormat(
+ "register buffer is too small to receive %u bytes of data.", src_len);
+ return 0;
+ }
+
+ const uint32_t dst_len = reg_info->byte_size;
+
+ if (src_len > dst_len) {
+ error.SetErrorStringWithFormat(
+ "%u bytes is too big to store in register %s (%u bytes)", src_len,
+ reg_info->name, dst_len);
+ return 0;
+ }
+
+ // Use a data extractor to correctly copy and pad the bytes read into the
+ // register value
+ DataExtractor src_data(src, src_len, src_byte_order, 4);
+
+ error = SetValueFromData(reg_info, src_data, 0, true);
+ if (error.Fail())
+ return 0;
+
+ // If SetValueFromData succeeded, we must have copied all of src_len
+ return src_len;
+}
+
+bool RegisterValue::GetScalarValue(Scalar &scalar) const {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ case 1:
+ scalar = *(const uint8_t *)buffer.bytes;
+ return true;
+ case 2:
+ scalar = *(const uint16_t *)buffer.bytes;
+ return true;
+ case 4:
+ scalar = *(const uint32_t *)buffer.bytes;
+ return true;
+ case 8:
+ scalar = *(const uint64_t *)buffer.bytes;
+ return true;
+ case 16:
+ case 32:
+ if (buffer.length % sizeof(uint64_t) == 0) {
+ const auto length_in_bits = buffer.length * 8;
+ const auto length_in_uint64 = buffer.length / sizeof(uint64_t);
+ scalar =
+ llvm::APInt(length_in_bits,
+ llvm::ArrayRef<uint64_t>((const uint64_t *)buffer.bytes,
+ length_in_uint64));
+ return true;
+ }
+ break;
+ }
+ } break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ scalar = m_scalar;
+ return true;
+ }
+ return false;
+}
+
+void RegisterValue::Clear() { m_type = eTypeInvalid; }
+
+RegisterValue::Type RegisterValue::SetType(const RegisterInfo *reg_info) {
+ // To change the type, we simply copy the data in again, using the new format
+ RegisterValue copy;
+ DataExtractor copy_data;
+ if (copy.CopyValue(*this) && copy.GetData(copy_data))
+ SetValueFromData(reg_info, copy_data, 0, true);
+
+ return m_type;
+}
+
+Status RegisterValue::SetValueFromData(const RegisterInfo *reg_info,
+ DataExtractor &src,
+ lldb::offset_t src_offset,
+ bool partial_data_ok) {
+ Status error;
+
+ if (src.GetByteSize() == 0) {
+ error.SetErrorString("empty data.");
+ return error;
+ }
+
+ if (reg_info->byte_size == 0) {
+ error.SetErrorString("invalid register info.");
+ return error;
+ }
+
+ uint32_t src_len = src.GetByteSize() - src_offset;
+
+ if (!partial_data_ok && (src_len < reg_info->byte_size)) {
+ error.SetErrorString("not enough data.");
+ return error;
+ }
+
+ // Cap the data length if there is more than enough bytes for this register
+ // value
+ if (src_len > reg_info->byte_size)
+ src_len = reg_info->byte_size;
+
+ // Zero out the value in case we get partial data...
+ memset(buffer.bytes, 0, sizeof(buffer.bytes));
+
+ type128 int128;
+
+ m_type = eTypeInvalid;
+ switch (reg_info->encoding) {
+ case eEncodingInvalid:
+ break;
+ case eEncodingUint:
+ case eEncodingSint:
+ if (reg_info->byte_size == 1)
+ SetUInt8(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 2)
+ SetUInt16(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 4)
+ SetUInt32(src.GetMaxU32(&src_offset, src_len));
+ else if (reg_info->byte_size <= 8)
+ SetUInt64(src.GetMaxU64(&src_offset, src_len));
+ else if (reg_info->byte_size <= 16) {
+ uint64_t data1 = src.GetU64(&src_offset);
+ uint64_t data2 = src.GetU64(&src_offset);
+ if (src.GetByteSize() == eByteOrderBig) {
+ int128.x[0] = data1;
+ int128.x[1] = data2;
+ } else {
+ int128.x[0] = data2;
+ int128.x[1] = data1;
+ }
+ SetUInt128(llvm::APInt(128, 2, int128.x));
+ }
+ break;
+ case eEncodingIEEE754:
+ if (reg_info->byte_size == sizeof(float))
+ SetFloat(src.GetFloat(&src_offset));
+ else if (reg_info->byte_size == sizeof(double))
+ SetDouble(src.GetDouble(&src_offset));
+ else if (reg_info->byte_size == sizeof(long double))
+ SetLongDouble(src.GetLongDouble(&src_offset));
+ break;
+ case eEncodingVector: {
+ m_type = eTypeBytes;
+ buffer.length = reg_info->byte_size;
+ buffer.byte_order = src.GetByteOrder();
+ assert(buffer.length <= kMaxRegisterByteSize);
+ if (buffer.length > kMaxRegisterByteSize)
+ buffer.length = kMaxRegisterByteSize;
+ if (src.CopyByteOrderedData(
+ src_offset, // offset within "src" to start extracting data
+ src_len, // src length
+ buffer.bytes, // dst buffer
+ buffer.length, // dst length
+ buffer.byte_order) == 0) // dst byte order
+ {
+ error.SetErrorStringWithFormat(
+ "failed to copy data for register write of %s", reg_info->name);
+ return error;
+ }
+ }
+ }
+
+ if (m_type == eTypeInvalid)
+ error.SetErrorStringWithFormat(
+ "invalid register value type for register %s", reg_info->name);
+ return error;
+}
+
+// Helper function for RegisterValue::SetValueFromString()
+static bool ParseVectorEncoding(const RegisterInfo *reg_info,
+ llvm::StringRef vector_str,
+ const uint32_t byte_size,
+ RegisterValue *reg_value) {
+ // Example: vector_str = "{0x2c 0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a
+ // 0x2a 0x3e 0x84 0x4f 0x2a 0x3e}".
+ vector_str = vector_str.trim();
+ vector_str.consume_front("{");
+ vector_str.consume_back("}");
+ vector_str = vector_str.trim();
+
+ char Sep = ' ';
+
+ // The first split should give us:
+ // ('0x2c', '0x4b 0x2a 0x3e 0xd0 0x4f 0x2a 0x3e 0xac 0x4a 0x2a 0x3e 0x84 0x4f
+ // 0x2a 0x3e').
+ llvm::StringRef car;
+ llvm::StringRef cdr = vector_str;
+ std::tie(car, cdr) = vector_str.split(Sep);
+ std::vector<uint8_t> bytes;
+ unsigned byte = 0;
+
+ // Using radix auto-sensing by passing 0 as the radix. Keep on processing the
+ // vector elements as long as the parsing succeeds and the vector size is <
+ // byte_size.
+ while (!car.getAsInteger(0, byte) && bytes.size() < byte_size) {
+ bytes.push_back(byte);
+ std::tie(car, cdr) = cdr.split(Sep);
+ }
+
+ // Check for vector of exact byte_size elements.
+ if (bytes.size() != byte_size)
+ return false;
+
+ reg_value->SetBytes(&(bytes.front()), byte_size, eByteOrderLittle);
+ return true;
+}
+
+Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info,
+ llvm::StringRef value_str) {
+ Status error;
+ if (reg_info == nullptr) {
+ error.SetErrorString("Invalid register info argument.");
+ return error;
+ }
+
+ m_type = eTypeInvalid;
+ if (value_str.empty()) {
+ error.SetErrorString("Invalid c-string value string.");
+ return error;
+ }
+ const uint32_t byte_size = reg_info->byte_size;
+
+ uint64_t uval64;
+ int64_t ival64;
+ float flt_val;
+ double dbl_val;
+ long double ldbl_val;
+ switch (reg_info->encoding) {
+ case eEncodingInvalid:
+ error.SetErrorString("Invalid encoding.");
+ break;
+
+ case eEncodingUint:
+ if (byte_size > sizeof(uint64_t)) {
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %u", byte_size);
+ break;
+ }
+ if (value_str.getAsInteger(0, uval64)) {
+ error.SetErrorStringWithFormat(
+ "'%s' is not a valid unsigned integer string value",
+ value_str.str().c_str());
+ break;
+ }
+
+ if (!Args::UInt64ValueIsValidForByteSize(uval64, byte_size)) {
+ error.SetErrorStringWithFormat(
+ "value 0x%" PRIx64
+ " is too large to fit in a %u byte unsigned integer value",
+ uval64, byte_size);
+ break;
+ }
+
+ if (!SetUInt(uval64, reg_info->byte_size)) {
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %u", byte_size);
+ break;
+ }
+ break;
+
+ case eEncodingSint:
+ if (byte_size > sizeof(long long)) {
+ error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
+ byte_size);
+ break;
+ }
+
+ if (value_str.getAsInteger(0, ival64)) {
+ error.SetErrorStringWithFormat(
+ "'%s' is not a valid signed integer string value",
+ value_str.str().c_str());
+ break;
+ }
+
+ if (!Args::SInt64ValueIsValidForByteSize(ival64, byte_size)) {
+ error.SetErrorStringWithFormat(
+ "value 0x%" PRIx64
+ " is too large to fit in a %u byte signed integer value",
+ ival64, byte_size);
+ break;
+ }
+
+ if (!SetUInt(ival64, reg_info->byte_size)) {
+ error.SetErrorStringWithFormat("unsupported signed integer byte size: %u",
+ byte_size);
+ break;
+ }
+ break;
+
+ case eEncodingIEEE754: {
+ std::string value_string = value_str;
+ if (byte_size == sizeof(float)) {
+ if (::sscanf(value_string.c_str(), "%f", &flt_val) != 1) {
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_string.c_str());
+ break;
+ }
+ m_scalar = flt_val;
+ m_type = eTypeFloat;
+ } else if (byte_size == sizeof(double)) {
+ if (::sscanf(value_string.c_str(), "%lf", &dbl_val) != 1) {
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_string.c_str());
+ break;
+ }
+ m_scalar = dbl_val;
+ m_type = eTypeDouble;
+ } else if (byte_size == sizeof(long double)) {
+ if (::sscanf(value_string.c_str(), "%Lf", &ldbl_val) != 1) {
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_string.c_str());
+ break;
+ }
+ m_scalar = ldbl_val;
+ m_type = eTypeLongDouble;
+ } else {
+ error.SetErrorStringWithFormat("unsupported float byte size: %u",
+ byte_size);
+ return error;
+ }
+ break;
+ }
+ case eEncodingVector:
+ if (!ParseVectorEncoding(reg_info, value_str, byte_size, this))
+ error.SetErrorString("unrecognized vector encoding string value.");
+ break;
+ }
+
+ return error;
+}
+
+bool RegisterValue::SignExtend(uint32_t sign_bitpos) {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ return m_scalar.SignExtend(sign_bitpos);
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ case eTypeBytes:
+ break;
+ }
+ return false;
+}
+
+bool RegisterValue::CopyValue(const RegisterValue &rhs) {
+ if (this == &rhs)
+ return rhs.m_type != eTypeInvalid;
+
+ m_type = rhs.m_type;
+ switch (m_type) {
+ case eTypeInvalid:
+ return false;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ m_scalar = rhs.m_scalar;
+ break;
+ case eTypeBytes:
+ assert(rhs.buffer.length <= kMaxRegisterByteSize);
+ ::memcpy(buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize);
+ buffer.length = rhs.buffer.length;
+ buffer.byte_order = rhs.buffer.byte_order;
+ break;
+ }
+ return true;
+}
+
+uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value,
+ bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+
+ switch (m_type) {
+ default:
+ break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ return m_scalar.UShort(fail_value);
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ case 1:
+ case 2:
+ return *(const uint16_t *)buffer.bytes;
+ }
+ } break;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value,
+ bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.UInt(fail_value);
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ case 1:
+ case 2:
+ case 4:
+ return *(const uint32_t *)buffer.bytes;
+ }
+ } break;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value,
+ bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.ULongLong(fail_value);
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ case 1:
+ return *(const uint8_t *)buffer.bytes;
+ case 2:
+ return *(const uint16_t *)buffer.bytes;
+ case 4:
+ return *(const uint32_t *)buffer.bytes;
+ case 8:
+ return *(const uint64_t *)buffer.bytes;
+ }
+ } break;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value,
+ bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.UInt128(fail_value);
+ case eTypeBytes: {
+ switch (buffer.length) {
+ default:
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16:
+ return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
+ ((const type128 *)buffer.bytes)->x);
+ }
+ } break;
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+float RegisterValue::GetAsFloat(float fail_value, bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.Float(fail_value);
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+double RegisterValue::GetAsDouble(double fail_value, bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.Double(fail_value);
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+long double RegisterValue::GetAsLongDouble(long double fail_value,
+ bool *success_ptr) const {
+ if (success_ptr)
+ *success_ptr = true;
+ switch (m_type) {
+ default:
+ break;
+
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.LongDouble();
+ }
+ if (success_ptr)
+ *success_ptr = false;
+ return fail_value;
+}
+
+const void *RegisterValue::GetBytes() const {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.GetBytes();
+ case eTypeBytes:
+ return buffer.bytes;
+ }
+ return nullptr;
+}
+
+uint32_t RegisterValue::GetByteSize() const {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+ case eTypeUInt8:
+ return 1;
+ case eTypeUInt16:
+ return 2;
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar.GetByteSize();
+ case eTypeBytes:
+ return buffer.length;
+ }
+ return 0;
+}
+
+bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) {
+ if (byte_size == 0) {
+ SetUInt64(uint);
+ } else if (byte_size == 1) {
+ SetUInt8(uint);
+ } else if (byte_size <= 2) {
+ SetUInt16(uint);
+ } else if (byte_size <= 4) {
+ SetUInt32(uint);
+ } else if (byte_size <= 8) {
+ SetUInt64(uint);
+ } else if (byte_size <= 16) {
+ SetUInt128(llvm::APInt(128, uint));
+ } else
+ return false;
+ return true;
+}
+
+void RegisterValue::SetBytes(const void *bytes, size_t length,
+ lldb::ByteOrder byte_order) {
+ // If this assertion fires off we need to increase the size of buffer.bytes,
+ // or make it something that is allocated on the heap. Since the data buffer
+ // is in a union, we can't make it a collection class like SmallVector...
+ if (bytes && length > 0) {
+ assert(length <= sizeof(buffer.bytes) &&
+ "Storing too many bytes in a RegisterValue.");
+ m_type = eTypeBytes;
+ buffer.length = length;
+ memcpy(buffer.bytes, bytes, length);
+ buffer.byte_order = byte_order;
+ } else {
+ m_type = eTypeInvalid;
+ buffer.length = 0;
+ }
+}
+
+bool RegisterValue::operator==(const RegisterValue &rhs) const {
+ if (m_type == rhs.m_type) {
+ switch (m_type) {
+ case eTypeInvalid:
+ return true;
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ return m_scalar == rhs.m_scalar;
+ case eTypeBytes:
+ if (buffer.length != rhs.buffer.length)
+ return false;
+ else {
+ uint8_t length = buffer.length;
+ if (length > kMaxRegisterByteSize)
+ length = kMaxRegisterByteSize;
+ return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0;
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+bool RegisterValue::operator!=(const RegisterValue &rhs) const {
+ return !(*this == rhs);
+}
+
+bool RegisterValue::ClearBit(uint32_t bit) {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ if (bit < (GetByteSize() * 8)) {
+ return m_scalar.ClearBit(bit);
+ }
+ break;
+
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ break;
+
+ case eTypeBytes:
+ if (buffer.byte_order == eByteOrderBig ||
+ buffer.byte_order == eByteOrderLittle) {
+ uint32_t byte_idx;
+ if (buffer.byte_order == eByteOrderBig)
+ byte_idx = buffer.length - (bit / 8) - 1;
+ else
+ byte_idx = bit / 8;
+
+ const uint32_t byte_bit = bit % 8;
+ if (byte_idx < buffer.length) {
+ buffer.bytes[byte_idx] &= ~(1u << byte_bit);
+ return true;
+ }
+ }
+ break;
+ }
+ return false;
+}
+
+bool RegisterValue::SetBit(uint32_t bit) {
+ switch (m_type) {
+ case eTypeInvalid:
+ break;
+
+ case eTypeUInt8:
+ case eTypeUInt16:
+ case eTypeUInt32:
+ case eTypeUInt64:
+ case eTypeUInt128:
+ if (bit < (GetByteSize() * 8)) {
+ return m_scalar.SetBit(bit);
+ }
+ break;
+
+ case eTypeFloat:
+ case eTypeDouble:
+ case eTypeLongDouble:
+ break;
+
+ case eTypeBytes:
+ if (buffer.byte_order == eByteOrderBig ||
+ buffer.byte_order == eByteOrderLittle) {
+ uint32_t byte_idx;
+ if (buffer.byte_order == eByteOrderBig)
+ byte_idx = buffer.length - (bit / 8) - 1;
+ else
+ byte_idx = bit / 8;
+
+ const uint32_t byte_bit = bit % 8;
+ if (byte_idx < buffer.length) {
+ buffer.bytes[byte_idx] |= (1u << byte_bit);
+ return true;
+ }
+ }
+ break;
+ }
+ return false;
+}
diff --git a/contrib/llvm/tools/lldb/source/Utility/Reproducer.cpp b/contrib/llvm/tools/lldb/source/Utility/Reproducer.cpp
new file mode 100644
index 000000000000..6e85ba41767a
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Utility/Reproducer.cpp
@@ -0,0 +1,225 @@
+//===-- Reproducer.cpp ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Reproducer.h"
+#include "lldb/Utility/LLDBAssert.h"
+
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Threading.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace lldb_private;
+using namespace lldb_private::repro;
+using namespace llvm;
+using namespace llvm::yaml;
+
+Reproducer &Reproducer::Instance() { return *InstanceImpl(); }
+
+llvm::Error Reproducer::Initialize(ReproducerMode mode,
+ llvm::Optional<FileSpec> root) {
+ lldbassert(!InstanceImpl() && "Already initialized.");
+ InstanceImpl().emplace();
+
+ switch (mode) {
+ case ReproducerMode::Capture: {
+ if (!root) {
+ SmallString<128> repro_dir;
+ auto ec = sys::fs::createUniqueDirectory("reproducer", repro_dir);
+ if (ec)
+ return make_error<StringError>(
+ "unable to create unique reproducer directory", ec);
+ root.emplace(repro_dir);
+ } else {
+ auto ec = sys::fs::create_directory(root->GetPath());
+ if (ec)
+ return make_error<StringError>("unable to create reproducer directory",
+ ec);
+ }
+ return Instance().SetCapture(root);
+ } break;
+ case ReproducerMode::Replay:
+ return Instance().SetReplay(root);
+ case ReproducerMode::Off:
+ break;
+ };
+
+ return Error::success();
+}
+
+void Reproducer::Terminate() {
+ lldbassert(InstanceImpl() && "Already terminated.");
+ InstanceImpl().reset();
+}
+
+Optional<Reproducer> &Reproducer::InstanceImpl() {
+ static Optional<Reproducer> g_reproducer;
+ return g_reproducer;
+}
+
+const Generator *Reproducer::GetGenerator() const {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ if (m_generator)
+ return &(*m_generator);
+ return nullptr;
+}
+
+const Loader *Reproducer::GetLoader() const {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ if (m_loader)
+ return &(*m_loader);
+ return nullptr;
+}
+
+Generator *Reproducer::GetGenerator() {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ if (m_generator)
+ return &(*m_generator);
+ return nullptr;
+}
+
+Loader *Reproducer::GetLoader() {
+ std::lock_guard<std::mutex> guard(m_mutex);
+ if (m_loader)
+ return &(*m_loader);
+ return nullptr;
+}
+
+llvm::Error Reproducer::SetCapture(llvm::Optional<FileSpec> root) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+
+ if (root && m_loader)
+ return make_error<StringError>(
+ "cannot generate a reproducer when replay one",
+ inconvertibleErrorCode());
+
+ if (!root) {
+ m_generator.reset();
+ return Error::success();
+ }
+
+ m_generator.emplace(*root);
+ return Error::success();
+}
+
+llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root) {
+ std::lock_guard<std::mutex> guard(m_mutex);
+
+ if (root && m_generator)
+ return make_error<StringError>(
+ "cannot replay a reproducer when generating one",
+ inconvertibleErrorCode());
+
+ if (!root) {
+ m_loader.reset();
+ return Error::success();
+ }
+
+ m_loader.emplace(*root);
+ if (auto e = m_loader->LoadIndex())
+ return e;
+
+ return Error::success();
+}
+
+FileSpec Reproducer::GetReproducerPath() const {
+ if (auto g = GetGenerator())
+ return g->GetRoot();
+ if (auto l = GetLoader())
+ return l->GetRoot();
+ return {};
+}
+
+Generator::Generator(const FileSpec &root) : m_root(root), m_done(false) {}
+
+Generator::~Generator() {}
+
+ProviderBase *Generator::Register(std::unique_ptr<ProviderBase> provider) {
+ std::lock_guard<std::mutex> lock(m_providers_mutex);
+ std::pair<const void *, std::unique_ptr<ProviderBase>> key_value(
+ provider->DynamicClassID(), std::move(provider));
+ auto e = m_providers.insert(std::move(key_value));
+ return e.first->getSecond().get();
+}
+
+void Generator::Keep() {
+ assert(!m_done);
+ m_done = true;
+
+ for (auto &provider : m_providers)
+ provider.second->Keep();
+
+ AddProvidersToIndex();
+}
+
+void Generator::Discard() {
+ assert(!m_done);
+ m_done = true;
+
+ for (auto &provider : m_providers)
+ provider.second->Discard();
+
+ llvm::sys::fs::remove_directories(m_root.GetPath());
+}
+
+const FileSpec &Generator::GetRoot() const { return m_root; }
+
+void Generator::AddProvidersToIndex() {
+ FileSpec index = m_root;
+ index.AppendPathComponent("index.yaml");
+
+ std::error_code EC;
+ auto strm = llvm::make_unique<raw_fd_ostream>(index.GetPath(), EC,
+ sys::fs::OpenFlags::F_None);
+ yaml::Output yout(*strm);
+
+ for (auto &provider : m_providers) {
+ auto &provider_info = provider.second->GetInfo();
+ yout << const_cast<ProviderInfo &>(provider_info);
+ }
+}
+
+Loader::Loader(const FileSpec &root) : m_root(root), m_loaded(false) {}
+
+llvm::Error Loader::LoadIndex() {
+ if (m_loaded)
+ return llvm::Error::success();
+
+ FileSpec index = m_root.CopyByAppendingPathComponent("index.yaml");
+
+ auto error_or_file = MemoryBuffer::getFile(index.GetPath());
+ if (auto err = error_or_file.getError())
+ return make_error<StringError>("unable to load reproducer index", err);
+
+ std::vector<ProviderInfo> provider_info;
+ yaml::Input yin((*error_or_file)->getBuffer());
+ yin >> provider_info;
+
+ if (auto err = yin.error())
+ return make_error<StringError>("unable to read reproducer index", err);
+
+ for (auto &info : provider_info)
+ m_provider_info[info.name] = info;
+
+ m_loaded = true;
+
+ return llvm::Error::success();
+}
+
+llvm::Optional<ProviderInfo> Loader::GetProviderInfo(StringRef name) {
+ assert(m_loaded);
+
+ auto it = m_provider_info.find(name);
+ if (it == m_provider_info.end())
+ return llvm::None;
+
+ return it->second;
+}
+
+void ProviderBase::anchor() {}
+char ProviderBase::ID = 0;
diff --git a/contrib/llvm/tools/lldb/source/Utility/Scalar.cpp b/contrib/llvm/tools/lldb/source/Utility/Scalar.cpp
new file mode 100644
index 000000000000..a2bb86ffdb15
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Utility/Scalar.cpp
@@ -0,0 +1,2695 @@
+//===-- Scalar.cpp ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Scalar.h"
+
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/Status.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/lldb-types.h"
+
+#include "llvm/ADT/SmallString.h"
+
+#include <cinttypes>
+#include <cstdio>
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// Promote to max type currently follows the ANSI C rule for type promotion in
+// expressions.
+//----------------------------------------------------------------------
+static Scalar::Type PromoteToMaxType(
+ const Scalar &lhs, // The const left hand side object
+ const Scalar &rhs, // The const right hand side object
+ Scalar &temp_value, // A modifiable temp value than can be used to hold
+ // either the promoted lhs or rhs object
+ const Scalar *&promoted_lhs_ptr, // Pointer to the resulting possibly
+ // promoted value of lhs (at most one of
+ // lhs/rhs will get promoted)
+ const Scalar *&promoted_rhs_ptr // Pointer to the resulting possibly
+ // promoted value of rhs (at most one of
+ // lhs/rhs will get promoted)
+) {
+ Scalar result;
+ // Initialize the promoted values for both the right and left hand side
+ // values to be the objects themselves. If no promotion is needed (both right
+ // and left have the same type), then the temp_value will not get used.
+ promoted_lhs_ptr = &lhs;
+ promoted_rhs_ptr = &rhs;
+ // Extract the types of both the right and left hand side values
+ Scalar::Type lhs_type = lhs.GetType();
+ Scalar::Type rhs_type = rhs.GetType();
+
+ if (lhs_type > rhs_type) {
+ // Right hand side need to be promoted
+ temp_value = rhs; // Copy right hand side into the temp value
+ if (temp_value.Promote(lhs_type)) // Promote it
+ promoted_rhs_ptr =
+ &temp_value; // Update the pointer for the promoted right hand side
+ } else if (lhs_type < rhs_type) {
+ // Left hand side need to be promoted
+ temp_value = lhs; // Copy left hand side value into the temp value
+ if (temp_value.Promote(rhs_type)) // Promote it
+ promoted_lhs_ptr =
+ &temp_value; // Update the pointer for the promoted left hand side
+ }
+
+ // Make sure our type promotion worked as expected
+ if (promoted_lhs_ptr->GetType() == promoted_rhs_ptr->GetType())
+ return promoted_lhs_ptr->GetType(); // Return the resulting max type
+
+ // Return the void type (zero) if we fail to promote either of the values.
+ return Scalar::e_void;
+}
+
+Scalar::Scalar() : m_type(e_void), m_float((float)0) {}
+
+Scalar::Scalar(const Scalar &rhs)
+ : m_type(rhs.m_type), m_integer(rhs.m_integer), m_float(rhs.m_float) {}
+
+bool Scalar::GetData(DataExtractor &data, size_t limit_byte_size) const {
+ size_t byte_size = GetByteSize();
+ if (byte_size > 0) {
+ const uint8_t *bytes = reinterpret_cast<const uint8_t *>(GetBytes());
+
+ if (limit_byte_size < byte_size) {
+ if (endian::InlHostByteOrder() == eByteOrderLittle) {
+ // On little endian systems if we want fewer bytes from the current
+ // type we just specify fewer bytes since the LSByte is first...
+ byte_size = limit_byte_size;
+ } else if (endian::InlHostByteOrder() == eByteOrderBig) {
+ // On big endian systems if we want fewer bytes from the current type
+ // have to advance our initial byte pointer and trim down the number of
+ // bytes since the MSByte is first
+ bytes += byte_size - limit_byte_size;
+ byte_size = limit_byte_size;
+ }
+ }
+
+ data.SetData(bytes, byte_size, endian::InlHostByteOrder());
+ return true;
+ }
+ data.Clear();
+ return false;
+}
+
+const void *Scalar::GetBytes() const {
+ const uint64_t *apint_words;
+ const uint8_t *bytes;
+ static float_t flt_val;
+ static double_t dbl_val;
+ static uint64_t swapped_words[4];
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ bytes = reinterpret_cast<const uint8_t *>(m_integer.getRawData());
+ // getRawData always returns a pointer to an uint64_t. If we have a
+ // smaller type, we need to update the pointer on big-endian systems.
+ if (endian::InlHostByteOrder() == eByteOrderBig) {
+ size_t byte_size = m_integer.getBitWidth() / 8;
+ if (byte_size < 8)
+ bytes += 8 - byte_size;
+ }
+ return bytes;
+ case e_sint128:
+ case e_uint128:
+ apint_words = m_integer.getRawData();
+ // getRawData always returns a pointer to an array of two uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the two words.
+ if (endian::InlHostByteOrder() == eByteOrderBig) {
+ swapped_words[0] = apint_words[1];
+ swapped_words[1] = apint_words[0];
+ apint_words = swapped_words;
+ }
+ return reinterpret_cast<const void *>(apint_words);
+ case e_sint256:
+ case e_uint256:
+ apint_words = m_integer.getRawData();
+ // getRawData always returns a pointer to an array of four uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the four words.
+ if (endian::InlHostByteOrder() == eByteOrderBig) {
+ swapped_words[0] = apint_words[3];
+ swapped_words[1] = apint_words[2];
+ swapped_words[2] = apint_words[1];
+ swapped_words[3] = apint_words[0];
+ apint_words = swapped_words;
+ }
+ return reinterpret_cast<const void *>(apint_words);
+ case e_float:
+ flt_val = m_float.convertToFloat();
+ return reinterpret_cast<const void *>(&flt_val);
+ case e_double:
+ dbl_val = m_float.convertToDouble();
+ return reinterpret_cast<const void *>(&dbl_val);
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ apint_words = ldbl_val.getRawData();
+ // getRawData always returns a pointer to an array of two uint64_t values,
+ // where the least-significant word always comes first. On big-endian
+ // systems we need to swap the two words.
+ if (endian::InlHostByteOrder() == eByteOrderBig) {
+ swapped_words[0] = apint_words[1];
+ swapped_words[1] = apint_words[0];
+ apint_words = swapped_words;
+ }
+ return reinterpret_cast<const void *>(apint_words);
+ }
+ return nullptr;
+}
+
+size_t Scalar::GetByteSize() const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (m_integer.getBitWidth() / 8);
+ case e_float:
+ return sizeof(float_t);
+ case e_double:
+ return sizeof(double_t);
+ case e_long_double:
+ return sizeof(long_double_t);
+ }
+ return 0;
+}
+
+bool Scalar::IsZero() const {
+ llvm::APInt zero_int = llvm::APInt::getNullValue(m_integer.getBitWidth() / 8);
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return llvm::APInt::isSameValue(zero_int, m_integer);
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.isZero();
+ }
+ return false;
+}
+
+void Scalar::GetValue(Stream *s, bool show_type) const {
+ if (show_type)
+ s->Printf("(%s) ", GetTypeAsCString());
+
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_slong:
+ case e_slonglong:
+ case e_sint128:
+ case e_sint256:
+ s->PutCString(m_integer.toString(10, true));
+ break;
+ case e_uint:
+ case e_ulong:
+ case e_ulonglong:
+ case e_uint128:
+ case e_uint256:
+ s->PutCString(m_integer.toString(10, false));
+ break;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ llvm::SmallString<24> string;
+ m_float.toString(string);
+ s->Printf("%s", string.c_str());
+ break;
+ }
+}
+
+const char *Scalar::GetTypeAsCString() const {
+ switch (m_type) {
+ case e_void:
+ return "void";
+ case e_sint:
+ return "int";
+ case e_uint:
+ return "unsigned int";
+ case e_slong:
+ return "long";
+ case e_ulong:
+ return "unsigned long";
+ case e_slonglong:
+ return "long long";
+ case e_ulonglong:
+ return "unsigned long long";
+ case e_sint128:
+ return "int128_t";
+ case e_uint128:
+ return "unsigned int128_t";
+ case e_sint256:
+ return "int256_t";
+ case e_uint256:
+ return "unsigned int256_t";
+ case e_float:
+ return "float";
+ case e_double:
+ return "double";
+ case e_long_double:
+ return "long double";
+ }
+ return "<invalid Scalar type>";
+}
+
+Scalar &Scalar::operator=(const Scalar &rhs) {
+ if (this != &rhs) {
+ m_type = rhs.m_type;
+ m_integer = llvm::APInt(rhs.m_integer);
+ m_float = rhs.m_float;
+ }
+ return *this;
+}
+
+Scalar &Scalar::operator=(const int v) {
+ m_type = e_sint;
+ m_integer = llvm::APInt(sizeof(int) * 8, v, true);
+ return *this;
+}
+
+Scalar &Scalar::operator=(unsigned int v) {
+ m_type = e_uint;
+ m_integer = llvm::APInt(sizeof(int) * 8, v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(long v) {
+ m_type = e_slong;
+ m_integer = llvm::APInt(sizeof(long) * 8, v, true);
+ return *this;
+}
+
+Scalar &Scalar::operator=(unsigned long v) {
+ m_type = e_ulong;
+ m_integer = llvm::APInt(sizeof(long) * 8, v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(long long v) {
+ m_type = e_slonglong;
+ m_integer = llvm::APInt(sizeof(long) * 8, v, true);
+ return *this;
+}
+
+Scalar &Scalar::operator=(unsigned long long v) {
+ m_type = e_ulonglong;
+ m_integer = llvm::APInt(sizeof(long long) * 8, v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(float v) {
+ m_type = e_float;
+ m_float = llvm::APFloat(v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(double v) {
+ m_type = e_double;
+ m_float = llvm::APFloat(v);
+ return *this;
+}
+
+Scalar &Scalar::operator=(long double v) {
+ m_type = e_long_double;
+ if (m_ieee_quad)
+ m_float = llvm::APFloat(
+ llvm::APFloat::IEEEquad(),
+ llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&v)->x));
+ else
+ m_float = llvm::APFloat(
+ llvm::APFloat::x87DoubleExtended(),
+ llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, ((type128 *)&v)->x));
+ return *this;
+}
+
+Scalar &Scalar::operator=(llvm::APInt rhs) {
+ m_integer = llvm::APInt(rhs);
+ switch (m_integer.getBitWidth()) {
+ case 8:
+ case 16:
+ case 32:
+ if (m_integer.isSignedIntN(sizeof(sint_t) * 8))
+ m_type = e_sint;
+ else
+ m_type = e_uint;
+ break;
+ case 64:
+ if (m_integer.isSignedIntN(sizeof(slonglong_t) * 8))
+ m_type = e_slonglong;
+ else
+ m_type = e_ulonglong;
+ break;
+ case 128:
+ if (m_integer.isSignedIntN(BITWIDTH_INT128))
+ m_type = e_sint128;
+ else
+ m_type = e_uint128;
+ break;
+ case 256:
+ if (m_integer.isSignedIntN(BITWIDTH_INT256))
+ m_type = e_sint256;
+ else
+ m_type = e_uint256;
+ break;
+ }
+ return *this;
+}
+
+Scalar::~Scalar() = default;
+
+bool Scalar::Promote(Scalar::Type type) {
+ bool success = false;
+ switch (m_type) {
+ case e_void:
+ break;
+
+ case e_sint:
+ switch (type) {
+ case e_void:
+ break;
+ case e_sint:
+ success = true;
+ break;
+ case e_uint:
+ m_integer = m_integer.sextOrTrunc(sizeof(uint_t) * 8);
+ success = true;
+ break;
+
+ case e_slong:
+ m_integer = m_integer.sextOrTrunc(sizeof(slong_t) * 8);
+ success = true;
+ break;
+
+ case e_ulong:
+ m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8);
+ success = true;
+ break;
+
+ case e_slonglong:
+ m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_ulonglong:
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_sint128:
+ case e_uint128:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_uint:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ break;
+ case e_uint:
+ success = true;
+ break;
+ case e_slong:
+ m_integer = m_integer.zextOrTrunc(sizeof(slong_t) * 8);
+ success = true;
+ break;
+
+ case e_ulong:
+ m_integer = m_integer.zextOrTrunc(sizeof(ulong_t) * 8);
+ success = true;
+ break;
+
+ case e_slonglong:
+ m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_ulonglong:
+ m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_sint128:
+ case e_uint128:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_slong:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ break;
+ case e_slong:
+ success = true;
+ break;
+ case e_ulong:
+ m_integer = m_integer.sextOrTrunc(sizeof(ulong_t) * 8);
+ success = true;
+ break;
+
+ case e_slonglong:
+ m_integer = m_integer.sextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_ulonglong:
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_sint128:
+ case e_uint128:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_ulong:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ break;
+ case e_ulong:
+ success = true;
+ break;
+ case e_slonglong:
+ m_integer = m_integer.zextOrTrunc(sizeof(slonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_ulonglong:
+ m_integer = m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_sint128:
+ case e_uint128:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_slonglong:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ break;
+ case e_slonglong:
+ success = true;
+ break;
+ case e_ulonglong:
+ m_integer = m_integer.sextOrTrunc(sizeof(ulonglong_t) * 8);
+ success = true;
+ break;
+
+ case e_sint128:
+ case e_uint128:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_ulonglong:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ break;
+ case e_ulonglong:
+ success = true;
+ break;
+ case e_sint128:
+ case e_uint128:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_sint128:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ break;
+ case e_sint128:
+ success = true;
+ break;
+ case e_uint128:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT128);
+ success = true;
+ break;
+
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_uint128:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ break;
+ case e_uint128:
+ success = true;
+ break;
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.zextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_sint256:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ break;
+ case e_sint256:
+ success = true;
+ break;
+ case e_uint256:
+ m_integer = m_integer.sextOrTrunc(BITWIDTH_INT256);
+ success = true;
+ break;
+
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, true,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_uint256:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ break;
+ case e_uint256:
+ success = true;
+ break;
+ case e_float:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEsingle());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_double:
+ m_float = llvm::APFloat(llvm::APFloat::IEEEdouble());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+
+ case e_long_double:
+ m_float = llvm::APFloat(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended());
+ m_float.convertFromAPInt(m_integer, false,
+ llvm::APFloat::rmNearestTiesToEven);
+ success = true;
+ break;
+ }
+ break;
+
+ case e_float:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ break;
+ case e_float:
+ success = true;
+ break;
+ case e_double:
+ m_float = llvm::APFloat((double_t)m_float.convertToFloat());
+ success = true;
+ break;
+
+ case e_long_double: {
+ bool ignore;
+ m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended(),
+ llvm::APFloat::rmNearestTiesToEven, &ignore);
+ success = true;
+ break;
+ }
+ }
+ break;
+
+ case e_double:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ case e_float:
+ break;
+ case e_double:
+ success = true;
+ break;
+ case e_long_double: {
+ bool ignore;
+ m_float.convert(m_ieee_quad ? llvm::APFloat::IEEEquad()
+ : llvm::APFloat::x87DoubleExtended(),
+ llvm::APFloat::rmNearestTiesToEven, &ignore);
+ success = true;
+ break;
+ }
+ }
+ break;
+
+ case e_long_double:
+ switch (type) {
+ case e_void:
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ case e_float:
+ case e_double:
+ break;
+ case e_long_double:
+ success = true;
+ break;
+ }
+ break;
+ }
+
+ if (success)
+ m_type = type;
+ return success;
+}
+
+const char *Scalar::GetValueTypeAsCString(Scalar::Type type) {
+ switch (type) {
+ case e_void:
+ return "void";
+ case e_sint:
+ return "int";
+ case e_uint:
+ return "unsigned int";
+ case e_slong:
+ return "long";
+ case e_ulong:
+ return "unsigned long";
+ case e_slonglong:
+ return "long long";
+ case e_ulonglong:
+ return "unsigned long long";
+ case e_float:
+ return "float";
+ case e_double:
+ return "double";
+ case e_long_double:
+ return "long double";
+ case e_sint128:
+ return "int128_t";
+ case e_uint128:
+ return "uint128_t";
+ case e_sint256:
+ return "int256_t";
+ case e_uint256:
+ return "uint256_t";
+ }
+ return "???";
+}
+
+Scalar::Type
+Scalar::GetValueTypeForSignedIntegerWithByteSize(size_t byte_size) {
+ if (byte_size <= sizeof(sint_t))
+ return e_sint;
+ if (byte_size <= sizeof(slong_t))
+ return e_slong;
+ if (byte_size <= sizeof(slonglong_t))
+ return e_slonglong;
+ return e_void;
+}
+
+Scalar::Type
+Scalar::GetValueTypeForUnsignedIntegerWithByteSize(size_t byte_size) {
+ if (byte_size <= sizeof(uint_t))
+ return e_uint;
+ if (byte_size <= sizeof(ulong_t))
+ return e_ulong;
+ if (byte_size <= sizeof(ulonglong_t))
+ return e_ulonglong;
+ return e_void;
+}
+
+Scalar::Type Scalar::GetValueTypeForFloatWithByteSize(size_t byte_size) {
+ if (byte_size == sizeof(float_t))
+ return e_float;
+ if (byte_size == sizeof(double_t))
+ return e_double;
+ if (byte_size == sizeof(long_double_t))
+ return e_long_double;
+ return e_void;
+}
+
+bool Scalar::MakeSigned() {
+ bool success = false;
+
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ success = true;
+ break;
+ case e_uint:
+ m_type = e_sint;
+ success = true;
+ break;
+ case e_slong:
+ success = true;
+ break;
+ case e_ulong:
+ m_type = e_slong;
+ success = true;
+ break;
+ case e_slonglong:
+ success = true;
+ break;
+ case e_ulonglong:
+ m_type = e_slonglong;
+ success = true;
+ break;
+ case e_sint128:
+ success = true;
+ break;
+ case e_uint128:
+ m_type = e_sint128;
+ success = true;
+ break;
+ case e_sint256:
+ success = true;
+ break;
+ case e_uint256:
+ m_type = e_sint256;
+ success = true;
+ break;
+ case e_float:
+ success = true;
+ break;
+ case e_double:
+ success = true;
+ break;
+ case e_long_double:
+ success = true;
+ break;
+ }
+
+ return success;
+}
+
+bool Scalar::MakeUnsigned() {
+ bool success = false;
+
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ m_type = e_uint;
+ success = true;
+ break;
+ case e_uint:
+ success = true;
+ break;
+ case e_slong:
+ m_type = e_ulong;
+ success = true;
+ break;
+ case e_ulong:
+ success = true;
+ break;
+ case e_slonglong:
+ m_type = e_ulonglong;
+ success = true;
+ break;
+ case e_ulonglong:
+ success = true;
+ break;
+ case e_sint128:
+ m_type = e_uint128;
+ success = true;
+ break;
+ case e_uint128:
+ success = true;
+ break;
+ case e_sint256:
+ m_type = e_uint256;
+ success = true;
+ break;
+ case e_uint256:
+ success = true;
+ break;
+ case e_float:
+ success = true;
+ break;
+ case e_double:
+ success = true;
+ break;
+ case e_long_double:
+ success = true;
+ break;
+ }
+
+ return success;
+}
+
+signed char Scalar::SChar(char fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (schar_t)(m_integer.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
+ case e_float:
+ return (schar_t)m_float.convertToFloat();
+ case e_double:
+ return (schar_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (schar_t)(ldbl_val.sextOrTrunc(sizeof(schar_t) * 8)).getSExtValue();
+ }
+ return fail_value;
+}
+
+unsigned char Scalar::UChar(unsigned char fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (uchar_t)(m_integer.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
+ case e_float:
+ return (uchar_t)m_float.convertToFloat();
+ case e_double:
+ return (uchar_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (uchar_t)(ldbl_val.zextOrTrunc(sizeof(uchar_t) * 8)).getZExtValue();
+ }
+ return fail_value;
+}
+
+short Scalar::SShort(short fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (sshort_t)(m_integer.sextOrTrunc(sizeof(sshort_t) * 8))
+ .getSExtValue();
+ case e_float:
+ return (sshort_t)m_float.convertToFloat();
+ case e_double:
+ return (sshort_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (sshort_t)(ldbl_val.sextOrTrunc(sizeof(sshort_t) * 8))
+ .getSExtValue();
+ }
+ return fail_value;
+}
+
+unsigned short Scalar::UShort(unsigned short fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (ushort_t)(m_integer.zextOrTrunc(sizeof(ushort_t) * 8))
+ .getZExtValue();
+ case e_float:
+ return (ushort_t)m_float.convertToFloat();
+ case e_double:
+ return (ushort_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (ushort_t)(ldbl_val.zextOrTrunc(sizeof(ushort_t) * 8))
+ .getZExtValue();
+ }
+ return fail_value;
+}
+
+int Scalar::SInt(int fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (sint_t)(m_integer.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
+ case e_float:
+ return (sint_t)m_float.convertToFloat();
+ case e_double:
+ return (sint_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (sint_t)(ldbl_val.sextOrTrunc(sizeof(sint_t) * 8)).getSExtValue();
+ }
+ return fail_value;
+}
+
+unsigned int Scalar::UInt(unsigned int fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (uint_t)(m_integer.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
+ case e_float:
+ return (uint_t)m_float.convertToFloat();
+ case e_double:
+ return (uint_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (uint_t)(ldbl_val.zextOrTrunc(sizeof(uint_t) * 8)).getZExtValue();
+ }
+ return fail_value;
+}
+
+long Scalar::SLong(long fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (slong_t)(m_integer.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
+ case e_float:
+ return (slong_t)m_float.convertToFloat();
+ case e_double:
+ return (slong_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (slong_t)(ldbl_val.sextOrTrunc(sizeof(slong_t) * 8)).getSExtValue();
+ }
+ return fail_value;
+}
+
+unsigned long Scalar::ULong(unsigned long fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (ulong_t)(m_integer.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
+ case e_float:
+ return (ulong_t)m_float.convertToFloat();
+ case e_double:
+ return (ulong_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (ulong_t)(ldbl_val.zextOrTrunc(sizeof(ulong_t) * 8)).getZExtValue();
+ }
+ return fail_value;
+}
+
+long long Scalar::SLongLong(long long fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (slonglong_t)(m_integer.sextOrTrunc(sizeof(slonglong_t) * 8))
+ .getSExtValue();
+ case e_float:
+ return (slonglong_t)m_float.convertToFloat();
+ case e_double:
+ return (slonglong_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (slonglong_t)(ldbl_val.sextOrTrunc(sizeof(slonglong_t) * 8))
+ .getSExtValue();
+ }
+ return fail_value;
+}
+
+unsigned long long Scalar::ULongLong(unsigned long long fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (ulonglong_t)(m_integer.zextOrTrunc(sizeof(ulonglong_t) * 8))
+ .getZExtValue();
+ case e_float:
+ return (ulonglong_t)m_float.convertToFloat();
+ case e_double: {
+ double d_val = m_float.convertToDouble();
+ llvm::APInt rounded_double =
+ llvm::APIntOps::RoundDoubleToAPInt(d_val, sizeof(ulonglong_t) * 8);
+ return (ulonglong_t)(rounded_double.zextOrTrunc(sizeof(ulonglong_t) * 8))
+ .getZExtValue();
+ }
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (ulonglong_t)(ldbl_val.zextOrTrunc(sizeof(ulonglong_t) * 8))
+ .getZExtValue();
+ }
+ return fail_value;
+}
+
+llvm::APInt Scalar::SInt128(llvm::APInt &fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
+ }
+ return fail_value;
+}
+
+llvm::APInt Scalar::UInt128(const llvm::APInt &fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
+ }
+ return fail_value;
+}
+
+llvm::APInt Scalar::SInt256(llvm::APInt &fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
+ }
+ return fail_value;
+}
+
+llvm::APInt Scalar::UInt256(const llvm::APInt &fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return m_integer;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ return m_float.bitcastToAPInt();
+ }
+ return fail_value;
+}
+
+float Scalar::Float(float fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return llvm::APIntOps::RoundAPIntToFloat(m_integer);
+ case e_float:
+ return m_float.convertToFloat();
+ case e_double:
+ return (float_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return ldbl_val.bitsToFloat();
+ }
+ return fail_value;
+}
+
+double Scalar::Double(double fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return llvm::APIntOps::RoundAPIntToDouble(m_integer);
+ case e_float:
+ return (double_t)m_float.convertToFloat();
+ case e_double:
+ return m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return ldbl_val.bitsToFloat();
+ }
+ return fail_value;
+}
+
+long double Scalar::LongDouble(long double fail_value) const {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ return (long_double_t)llvm::APIntOps::RoundAPIntToDouble(m_integer);
+ case e_float:
+ return (long_double_t)m_float.convertToFloat();
+ case e_double:
+ return (long_double_t)m_float.convertToDouble();
+ case e_long_double:
+ llvm::APInt ldbl_val = m_float.bitcastToAPInt();
+ return (long_double_t)ldbl_val.bitsToDouble();
+ }
+ return fail_value;
+}
+
+Scalar &Scalar::operator+=(const Scalar &rhs) {
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((m_type = PromoteToMaxType(*this, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = a->m_integer + b->m_integer;
+ break;
+
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_float = a->m_float + b->m_float;
+ break;
+ }
+ }
+ return *this;
+}
+
+Scalar &Scalar::operator<<=(const Scalar &rhs) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (rhs.m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer << rhs.m_integer;
+ break;
+ }
+ break;
+ }
+ return *this;
+}
+
+bool Scalar::ShiftRightLogical(const Scalar &rhs) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (rhs.m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.lshr(rhs.m_integer);
+ break;
+ }
+ break;
+ }
+ return m_type != e_void;
+}
+
+Scalar &Scalar::operator>>=(const Scalar &rhs) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (rhs.m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = m_integer.ashr(rhs.m_integer);
+ break;
+ }
+ break;
+ }
+ return *this;
+}
+
+Scalar &Scalar::operator&=(const Scalar &rhs) {
+ switch (m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ switch (rhs.m_type) {
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_type = e_void;
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer &= rhs.m_integer;
+ break;
+ }
+ break;
+ }
+ return *this;
+}
+
+bool Scalar::AbsoluteValue() {
+ switch (m_type) {
+ case e_void:
+ break;
+
+ case e_sint:
+ case e_slong:
+ case e_slonglong:
+ case e_sint128:
+ case e_sint256:
+ if (m_integer.isNegative())
+ m_integer = -m_integer;
+ return true;
+
+ case e_uint:
+ case e_ulong:
+ case e_ulonglong:
+ return true;
+ case e_uint128:
+ case e_uint256:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_float.clearSign();
+ return true;
+ }
+ return false;
+}
+
+bool Scalar::UnaryNegate() {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = -m_integer;
+ return true;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ m_float.changeSign();
+ return true;
+ }
+ return false;
+}
+
+bool Scalar::OnesComplement() {
+ switch (m_type) {
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer = ~m_integer;
+ return true;
+
+ case e_void:
+ case e_float:
+ case e_double:
+ case e_long_double:
+ break;
+ }
+ return false;
+}
+
+const Scalar lldb_private::operator+(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
+ break;
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ result.m_integer = a->m_integer + b->m_integer;
+ break;
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ result.m_float = a->m_float + b->m_float;
+ break;
+ }
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator-(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
+ break;
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ result.m_integer = a->m_integer - b->m_integer;
+ break;
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ result.m_float = a->m_float - b->m_float;
+ break;
+ }
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator/(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
+ break;
+ case Scalar::e_sint:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ if (b->m_integer != 0) {
+ result.m_integer = a->m_integer.sdiv(b->m_integer);
+ return result;
+ }
+ break;
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ if (b->m_integer != 0) {
+ result.m_integer = a->m_integer.udiv(b->m_integer);
+ return result;
+ }
+ break;
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ if (!b->m_float.isZero()) {
+ result.m_float = a->m_float / b->m_float;
+ return result;
+ }
+ break;
+ }
+ }
+ // For division only, the only way it should make it here is if a promotion
+ // failed, or if we are trying to do a divide by zero.
+ result.m_type = Scalar::e_void;
+ return result;
+}
+
+const Scalar lldb_private::operator*(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_void:
+ break;
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ result.m_integer = a->m_integer * b->m_integer;
+ break;
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ result.m_float = a->m_float * b->m_float;
+ break;
+ }
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator&(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ result.m_integer = a->m_integer & b->m_integer;
+ break;
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ // No bitwise AND on floats, doubles of long doubles
+ result.m_type = Scalar::e_void;
+ break;
+ }
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator|(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ result.m_integer = a->m_integer | b->m_integer;
+ break;
+
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ // No bitwise AND on floats, doubles of long doubles
+ result.m_type = Scalar::e_void;
+ break;
+ }
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator%(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ default:
+ break;
+ case Scalar::e_void:
+ break;
+ case Scalar::e_sint:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ if (b->m_integer != 0) {
+ result.m_integer = a->m_integer.srem(b->m_integer);
+ return result;
+ }
+ break;
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ if (b->m_integer != 0) {
+ result.m_integer = a->m_integer.urem(b->m_integer);
+ return result;
+ }
+ break;
+ }
+ }
+ result.m_type = Scalar::e_void;
+ return result;
+}
+
+const Scalar lldb_private::operator^(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result;
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ if ((result.m_type = PromoteToMaxType(lhs, rhs, temp_value, a, b)) !=
+ Scalar::e_void) {
+ switch (result.m_type) {
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ result.m_integer = a->m_integer ^ b->m_integer;
+ break;
+
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ // No bitwise AND on floats, doubles of long doubles
+ result.m_type = Scalar::e_void;
+ break;
+ }
+ }
+ return result;
+}
+
+const Scalar lldb_private::operator<<(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result = lhs;
+ result <<= rhs;
+ return result;
+}
+
+const Scalar lldb_private::operator>>(const Scalar &lhs, const Scalar &rhs) {
+ Scalar result = lhs;
+ result >>= rhs;
+ return result;
+}
+
+Status Scalar::SetValueFromCString(const char *value_str, Encoding encoding,
+ size_t byte_size) {
+ Status error;
+ if (value_str == nullptr || value_str[0] == '\0') {
+ error.SetErrorString("Invalid c-string value string.");
+ return error;
+ }
+ switch (encoding) {
+ case eEncodingInvalid:
+ error.SetErrorString("Invalid encoding.");
+ break;
+
+ case eEncodingUint:
+ if (byte_size <= sizeof(uint64_t)) {
+ uint64_t uval64;
+ if (!llvm::to_integer(value_str, uval64))
+ error.SetErrorStringWithFormat(
+ "'%s' is not a valid unsigned integer string value", value_str);
+ else if (!UIntValueIsValidForSize(uval64, byte_size))
+ error.SetErrorStringWithFormat("value 0x%" PRIx64
+ " is too large to fit in a %" PRIu64
+ " byte unsigned integer value",
+ uval64, (uint64_t)byte_size);
+ else {
+ m_type = Scalar::GetValueTypeForUnsignedIntegerWithByteSize(byte_size);
+ switch (m_type) {
+ case e_uint:
+ m_integer = llvm::APInt(sizeof(uint_t) * 8, uval64, false);
+ break;
+ case e_ulong:
+ m_integer = llvm::APInt(sizeof(ulong_t) * 8, uval64, false);
+ break;
+ case e_ulonglong:
+ m_integer = llvm::APInt(sizeof(ulonglong_t) * 8, uval64, false);
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ break;
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ return error;
+ }
+ break;
+
+ case eEncodingSint:
+ if (byte_size <= sizeof(int64_t)) {
+ int64_t sval64;
+ if (!llvm::to_integer(value_str, sval64))
+ error.SetErrorStringWithFormat(
+ "'%s' is not a valid signed integer string value", value_str);
+ else if (!SIntValueIsValidForSize(sval64, byte_size))
+ error.SetErrorStringWithFormat("value 0x%" PRIx64
+ " is too large to fit in a %" PRIu64
+ " byte signed integer value",
+ sval64, (uint64_t)byte_size);
+ else {
+ m_type = Scalar::GetValueTypeForSignedIntegerWithByteSize(byte_size);
+ switch (m_type) {
+ case e_sint:
+ m_integer = llvm::APInt(sizeof(sint_t) * 8, sval64, true);
+ break;
+ case e_slong:
+ m_integer = llvm::APInt(sizeof(slong_t) * 8, sval64, true);
+ break;
+ case e_slonglong:
+ m_integer = llvm::APInt(sizeof(slonglong_t) * 8, sval64, true);
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "unsupported signed integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ break;
+ }
+ }
+ } else {
+ error.SetErrorStringWithFormat(
+ "unsupported signed integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ return error;
+ }
+ break;
+
+ case eEncodingIEEE754:
+ static float f_val;
+ static double d_val;
+ static long double l_val;
+ if (byte_size == sizeof(float)) {
+ if (::sscanf(value_str, "%f", &f_val) == 1) {
+ m_float = llvm::APFloat(f_val);
+ m_type = e_float;
+ } else
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_str);
+ } else if (byte_size == sizeof(double)) {
+ if (::sscanf(value_str, "%lf", &d_val) == 1) {
+ m_float = llvm::APFloat(d_val);
+ m_type = e_double;
+ } else
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_str);
+ } else if (byte_size == sizeof(long double)) {
+ if (::sscanf(value_str, "%Lf", &l_val) == 1) {
+ m_float =
+ llvm::APFloat(llvm::APFloat::x87DoubleExtended(),
+ llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128,
+ ((type128 *)&l_val)->x));
+ m_type = e_long_double;
+ } else
+ error.SetErrorStringWithFormat("'%s' is not a valid float string value",
+ value_str);
+ } else {
+ error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ return error;
+ }
+ break;
+
+ case eEncodingVector:
+ error.SetErrorString("vector encoding unsupported.");
+ break;
+ }
+ if (error.Fail())
+ m_type = e_void;
+
+ return error;
+}
+
+Status Scalar::SetValueFromData(DataExtractor &data, lldb::Encoding encoding,
+ size_t byte_size) {
+ Status error;
+
+ type128 int128;
+ type256 int256;
+ switch (encoding) {
+ case lldb::eEncodingInvalid:
+ error.SetErrorString("invalid encoding");
+ break;
+ case lldb::eEncodingVector:
+ error.SetErrorString("vector encoding unsupported");
+ break;
+ case lldb::eEncodingUint: {
+ lldb::offset_t offset = 0;
+
+ switch (byte_size) {
+ case 1:
+ operator=((uint8_t)data.GetU8(&offset));
+ break;
+ case 2:
+ operator=((uint16_t)data.GetU16(&offset));
+ break;
+ case 4:
+ operator=((uint32_t)data.GetU32(&offset));
+ break;
+ case 8:
+ operator=((uint64_t)data.GetU64(&offset));
+ break;
+ case 16:
+ if (data.GetByteOrder() == eByteOrderBig) {
+ int128.x[1] = (uint64_t)data.GetU64(&offset);
+ int128.x[0] = (uint64_t)data.GetU64(&offset);
+ } else {
+ int128.x[0] = (uint64_t)data.GetU64(&offset);
+ int128.x[1] = (uint64_t)data.GetU64(&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
+ break;
+ case 32:
+ if (data.GetByteOrder() == eByteOrderBig) {
+ int256.x[3] = (uint64_t)data.GetU64(&offset);
+ int256.x[2] = (uint64_t)data.GetU64(&offset);
+ int256.x[1] = (uint64_t)data.GetU64(&offset);
+ int256.x[0] = (uint64_t)data.GetU64(&offset);
+ } else {
+ int256.x[0] = (uint64_t)data.GetU64(&offset);
+ int256.x[1] = (uint64_t)data.GetU64(&offset);
+ int256.x[2] = (uint64_t)data.GetU64(&offset);
+ int256.x[3] = (uint64_t)data.GetU64(&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "unsupported unsigned integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ break;
+ }
+ } break;
+ case lldb::eEncodingSint: {
+ lldb::offset_t offset = 0;
+
+ switch (byte_size) {
+ case 1:
+ operator=((int8_t)data.GetU8(&offset));
+ break;
+ case 2:
+ operator=((int16_t)data.GetU16(&offset));
+ break;
+ case 4:
+ operator=((int32_t)data.GetU32(&offset));
+ break;
+ case 8:
+ operator=((int64_t)data.GetU64(&offset));
+ break;
+ case 16:
+ if (data.GetByteOrder() == eByteOrderBig) {
+ int128.x[1] = (uint64_t)data.GetU64(&offset);
+ int128.x[0] = (uint64_t)data.GetU64(&offset);
+ } else {
+ int128.x[0] = (uint64_t)data.GetU64(&offset);
+ int128.x[1] = (uint64_t)data.GetU64(&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, int128.x));
+ break;
+ case 32:
+ if (data.GetByteOrder() == eByteOrderBig) {
+ int256.x[3] = (uint64_t)data.GetU64(&offset);
+ int256.x[2] = (uint64_t)data.GetU64(&offset);
+ int256.x[1] = (uint64_t)data.GetU64(&offset);
+ int256.x[0] = (uint64_t)data.GetU64(&offset);
+ } else {
+ int256.x[0] = (uint64_t)data.GetU64(&offset);
+ int256.x[1] = (uint64_t)data.GetU64(&offset);
+ int256.x[2] = (uint64_t)data.GetU64(&offset);
+ int256.x[3] = (uint64_t)data.GetU64(&offset);
+ }
+ operator=(llvm::APInt(BITWIDTH_INT256, NUM_OF_WORDS_INT256, int256.x));
+ break;
+ default:
+ error.SetErrorStringWithFormat(
+ "unsupported signed integer byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ break;
+ }
+ } break;
+ case lldb::eEncodingIEEE754: {
+ lldb::offset_t offset = 0;
+
+ if (byte_size == sizeof(float))
+ operator=((float)data.GetFloat(&offset));
+ else if (byte_size == sizeof(double))
+ operator=((double)data.GetDouble(&offset));
+ else if (byte_size == sizeof(long double))
+ operator=((long double)data.GetLongDouble(&offset));
+ else
+ error.SetErrorStringWithFormat("unsupported float byte size: %" PRIu64 "",
+ (uint64_t)byte_size);
+ } break;
+ }
+
+ return error;
+}
+
+bool Scalar::SignExtend(uint32_t sign_bit_pos) {
+ const uint32_t max_bit_pos = GetByteSize() * 8;
+
+ if (sign_bit_pos < max_bit_pos) {
+ switch (m_type) {
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ return false;
+
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ if (max_bit_pos == sign_bit_pos)
+ return true;
+ else if (sign_bit_pos < (max_bit_pos - 1)) {
+ llvm::APInt sign_bit = llvm::APInt::getSignMask(sign_bit_pos + 1);
+ llvm::APInt bitwize_and = m_integer & sign_bit;
+ if (bitwize_and.getBoolValue()) {
+ const llvm::APInt mask =
+ ~(sign_bit) + llvm::APInt(m_integer.getBitWidth(), 1);
+ m_integer |= mask;
+ }
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+size_t Scalar::GetAsMemoryData(void *dst, size_t dst_len,
+ lldb::ByteOrder dst_byte_order,
+ Status &error) const {
+ // Get a data extractor that points to the native scalar data
+ DataExtractor data;
+ if (!GetData(data)) {
+ error.SetErrorString("invalid scalar value");
+ return 0;
+ }
+
+ const size_t src_len = data.GetByteSize();
+
+ // Prepare a memory buffer that contains some or all of the register value
+ const size_t bytes_copied =
+ data.CopyByteOrderedData(0, // src offset
+ src_len, // src length
+ dst, // dst buffer
+ dst_len, // dst length
+ dst_byte_order); // dst byte order
+ if (bytes_copied == 0)
+ error.SetErrorString("failed to copy data");
+
+ return bytes_copied;
+}
+
+bool Scalar::ExtractBitfield(uint32_t bit_size, uint32_t bit_offset) {
+ if (bit_size == 0)
+ return true;
+
+ switch (m_type) {
+ case Scalar::e_void:
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ break;
+
+ case Scalar::e_sint:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ m_integer = m_integer.ashr(bit_offset)
+ .sextOrTrunc(bit_size)
+ .sextOrSelf(8 * GetByteSize());
+ return true;
+
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ m_integer = m_integer.lshr(bit_offset)
+ .zextOrTrunc(bit_size)
+ .zextOrSelf(8 * GetByteSize());
+ return true;
+ }
+ return false;
+}
+
+bool lldb_private::operator==(const Scalar &lhs, const Scalar &rhs) {
+ // If either entry is void then we can just compare the types
+ if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
+ return lhs.m_type == rhs.m_type;
+
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ llvm::APFloat::cmpResult result;
+ switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) {
+ case Scalar::e_void:
+ break;
+ case Scalar::e_sint:
+ case Scalar::e_uint:
+ case Scalar::e_slong:
+ case Scalar::e_ulong:
+ case Scalar::e_slonglong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_uint128:
+ case Scalar::e_sint256:
+ case Scalar::e_uint256:
+ return a->m_integer == b->m_integer;
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ result = a->m_float.compare(b->m_float);
+ if (result == llvm::APFloat::cmpEqual)
+ return true;
+ }
+ return false;
+}
+
+bool lldb_private::operator!=(const Scalar &lhs, const Scalar &rhs) {
+ return !(lhs == rhs);
+}
+
+bool lldb_private::operator<(const Scalar &lhs, const Scalar &rhs) {
+ if (lhs.m_type == Scalar::e_void || rhs.m_type == Scalar::e_void)
+ return false;
+
+ Scalar temp_value;
+ const Scalar *a;
+ const Scalar *b;
+ llvm::APFloat::cmpResult result;
+ switch (PromoteToMaxType(lhs, rhs, temp_value, a, b)) {
+ case Scalar::e_void:
+ break;
+ case Scalar::e_sint:
+ case Scalar::e_slong:
+ case Scalar::e_slonglong:
+ case Scalar::e_sint128:
+ case Scalar::e_sint256:
+ return a->m_integer.slt(b->m_integer);
+ case Scalar::e_uint:
+ case Scalar::e_ulong:
+ case Scalar::e_ulonglong:
+ case Scalar::e_uint128:
+ case Scalar::e_uint256:
+ return a->m_integer.ult(b->m_integer);
+ case Scalar::e_float:
+ case Scalar::e_double:
+ case Scalar::e_long_double:
+ result = a->m_float.compare(b->m_float);
+ if (result == llvm::APFloat::cmpLessThan)
+ return true;
+ }
+ return false;
+}
+
+bool lldb_private::operator<=(const Scalar &lhs, const Scalar &rhs) {
+ return !(rhs < lhs);
+}
+
+bool lldb_private::operator>(const Scalar &lhs, const Scalar &rhs) {
+ return rhs < lhs;
+}
+
+bool lldb_private::operator>=(const Scalar &lhs, const Scalar &rhs) {
+ return !(lhs < rhs);
+}
+
+bool Scalar::ClearBit(uint32_t bit) {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer.clearBit(bit);
+ return true;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ break;
+ }
+ return false;
+}
+
+bool Scalar::SetBit(uint32_t bit) {
+ switch (m_type) {
+ case e_void:
+ break;
+ case e_sint:
+ case e_uint:
+ case e_slong:
+ case e_ulong:
+ case e_slonglong:
+ case e_ulonglong:
+ case e_sint128:
+ case e_uint128:
+ case e_sint256:
+ case e_uint256:
+ m_integer.setBit(bit);
+ return true;
+ case e_float:
+ case e_double:
+ case e_long_double:
+ break;
+ }
+ return false;
+}
diff --git a/contrib/llvm/tools/lldb/source/Utility/SelectHelper.cpp b/contrib/llvm/tools/lldb/source/Utility/SelectHelper.cpp
index 0f6a96309504..2979a67dc182 100644
--- a/contrib/llvm/tools/lldb/source/Utility/SelectHelper.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/SelectHelper.cpp
@@ -17,14 +17,14 @@
#include "lldb/Utility/SelectHelper.h"
#include "lldb/Utility/LLDBAssert.h"
#include "lldb/Utility/Status.h"
-#include "lldb/lldb-enumerations.h" // for ErrorType::eErrorTypePOSIX
-#include "lldb/lldb-types.h" // for socket_t
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-types.h"
-#include "llvm/ADT/DenseMap.h" // for DenseMapPair, DenseMap, Dense...
-#include "llvm/ADT/Optional.h" // for Optional
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
#include <algorithm>
-#include <chrono> // for microseconds, seconds, steady...
+#include <chrono>
#include <errno.h>
#if defined(_WIN32)
diff --git a/contrib/llvm/tools/lldb/source/Utility/State.cpp b/contrib/llvm/tools/lldb/source/Utility/State.cpp
new file mode 100644
index 000000000000..6ff8a4940b0f
--- /dev/null
+++ b/contrib/llvm/tools/lldb/source/Utility/State.cpp
@@ -0,0 +1,111 @@
+//===-- State.cpp -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/State.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+const char *lldb_private::StateAsCString(StateType state) {
+ switch (state) {
+ case eStateInvalid:
+ return "invalid";
+ case eStateUnloaded:
+ return "unloaded";
+ case eStateConnected:
+ return "connected";
+ case eStateAttaching:
+ return "attaching";
+ case eStateLaunching:
+ return "launching";
+ case eStateStopped:
+ return "stopped";
+ case eStateRunning:
+ return "running";
+ case eStateStepping:
+ return "stepping";
+ case eStateCrashed:
+ return "crashed";
+ case eStateDetached:
+ return "detached";
+ case eStateExited:
+ return "exited";
+ case eStateSuspended:
+ return "suspended";
+ }
+ return "unknown";
+}
+
+const char *lldb_private::GetPermissionsAsCString(uint32_t permissions) {
+ switch (permissions) {
+ case 0:
+ return "---";
+ case ePermissionsWritable:
+ return "-w-";
+ case ePermissionsReadable:
+ return "r--";
+ case ePermissionsExecutable:
+ return "--x";
+ case ePermissionsReadable | ePermissionsWritable:
+ return "rw-";
+ case ePermissionsReadable | ePermissionsExecutable:
+ return "r-x";
+ case ePermissionsWritable | ePermissionsExecutable:
+ return "-wx";
+ case ePermissionsReadable | ePermissionsWritable | ePermissionsExecutable:
+ return "rwx";
+ default:
+ break;
+ }
+ return "???";
+}
+
+bool lldb_private::StateIsRunningState(StateType state) {
+ switch (state) {
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ return true;
+
+ case eStateConnected:
+ case eStateDetached:
+ case eStateInvalid:
+ case eStateUnloaded:
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateExited:
+ case eStateSuspended:
+ break;
+ }
+ return false;
+}
+
+bool lldb_private::StateIsStoppedState(StateType state, bool must_exist) {
+ switch (state) {
+ case eStateInvalid:
+ case eStateConnected:
+ case eStateAttaching:
+ case eStateLaunching:
+ case eStateRunning:
+ case eStateStepping:
+ case eStateDetached:
+ break;
+
+ case eStateUnloaded:
+ case eStateExited:
+ return !must_exist;
+
+ case eStateStopped:
+ case eStateCrashed:
+ case eStateSuspended:
+ return true;
+ }
+ return false;
+}
diff --git a/contrib/llvm/tools/lldb/source/Utility/Status.cpp b/contrib/llvm/tools/lldb/source/Utility/Status.cpp
index f6dc228391b3..062bd261ea8b 100644
--- a/contrib/llvm/tools/lldb/source/Utility/Status.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/Status.cpp
@@ -11,23 +11,26 @@
#include "lldb/Utility/Status.h"
#include "lldb/Utility/VASPrintf.h"
-#include "lldb/lldb-defines.h" // for LLDB_GENERIC_ERROR
-#include "lldb/lldb-enumerations.h" // for ErrorType, ErrorType::eErr...
-#include "llvm/ADT/SmallString.h" // for SmallString
-#include "llvm/ADT/StringRef.h" // for StringRef
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Errno.h"
-#include "llvm/Support/FormatProviders.h" // for format_provider
+#include "llvm/Support/FormatProviders.h"
#include <cerrno>
#include <cstdarg>
-#include <string> // for string
+#include <string>
#include <system_error>
#ifdef __APPLE__
#include <mach/mach.h>
#endif
-#include <stdint.h> // for uint32_t
+#ifdef _WIN32
+#include <windows.h>
+#endif
+#include <stdint.h>
namespace llvm {
class raw_ostream;
@@ -87,7 +90,8 @@ llvm::Error Status::ToError() const {
if (Success())
return llvm::Error::success();
if (m_type == ErrorType::eErrorTypePOSIX)
- return llvm::errorCodeToError(std::error_code(m_code, std::generic_category()));
+ return llvm::errorCodeToError(
+ std::error_code(m_code, std::generic_category()));
return llvm::make_error<llvm::StringError>(AsCString(),
llvm::inconvertibleErrorCode());
}
@@ -106,6 +110,23 @@ const Status &Status::operator=(const Status &rhs) {
Status::~Status() = default;
+#ifdef _WIN32
+static std::string RetrieveWin32ErrorString(uint32_t error_code) {
+ char *buffer = nullptr;
+ std::string message;
+ // Retrieve win32 system error.
+ if (::FormatMessageA(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPSTR)&buffer, 0, NULL)) {
+ message.assign(buffer);
+ ::LocalFree(buffer);
+ }
+ return message;
+}
+#endif
+
//----------------------------------------------------------------------
// Get the error value as a NULL C string. The error string will be fetched and
// cached on demand. The cached error string value will remain until the error
@@ -128,6 +149,12 @@ const char *Status::AsCString(const char *default_error_str) const {
m_string = llvm::sys::StrError(m_code);
break;
+ case eErrorTypeWin32:
+#if defined(_WIN32)
+ m_string = RetrieveWin32ErrorString(m_code);
+#endif
+ break;
+
default:
break;
}
diff --git a/contrib/llvm/tools/lldb/source/Utility/Stream.cpp b/contrib/llvm/tools/lldb/source/Utility/Stream.cpp
index 7df7f7008084..54691c7066db 100644
--- a/contrib/llvm/tools/lldb/source/Utility/Stream.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/Stream.cpp
@@ -11,7 +11,8 @@
#include "lldb/Utility/Endian.h"
#include "lldb/Utility/VASPrintf.h"
-#include "llvm/ADT/SmallString.h" // for SmallString
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/LEB128.h"
#include <string>
@@ -23,11 +24,11 @@ using namespace lldb_private;
Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
: m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order),
- m_indent_level(0) {}
+ m_indent_level(0), m_forwarder(*this) {}
Stream::Stream()
: m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()),
- m_indent_level(0) {}
+ m_indent_level(0), m_forwarder(*this) {}
//------------------------------------------------------------------
// Destructor
@@ -49,47 +50,20 @@ void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); }
// Put an SLEB128 "uval" out to the stream using the printf format in "format".
//------------------------------------------------------------------
size_t Stream::PutSLEB128(int64_t sval) {
- size_t bytes_written = 0;
- if (m_flags.Test(eBinary)) {
- bool more = true;
- while (more) {
- uint8_t byte = sval & 0x7fu;
- sval >>= 7;
- /* sign bit of byte is 2nd high order bit (0x40) */
- if ((sval == 0 && !(byte & 0x40)) || (sval == -1 && (byte & 0x40)))
- more = false;
- else
- // more bytes to come
- byte |= 0x80u;
- bytes_written += Write(&byte, 1);
- }
- } else {
- bytes_written = Printf("0x%" PRIi64, sval);
- }
-
- return bytes_written;
+ if (m_flags.Test(eBinary))
+ return llvm::encodeSLEB128(sval, m_forwarder);
+ else
+ return Printf("0x%" PRIi64, sval);
}
//------------------------------------------------------------------
// Put an ULEB128 "uval" out to the stream using the printf format in "format".
//------------------------------------------------------------------
size_t Stream::PutULEB128(uint64_t uval) {
- size_t bytes_written = 0;
- if (m_flags.Test(eBinary)) {
- do {
-
- uint8_t byte = uval & 0x7fu;
- uval >>= 7;
- if (uval != 0) {
- // more bytes to come
- byte |= 0x80u;
- }
- bytes_written += Write(&byte, 1);
- } while (uval != 0);
- } else {
- bytes_written = Printf("0x%" PRIx64, uval);
- }
- return bytes_written;
+ if (m_flags.Test(eBinary))
+ return llvm::encodeULEB128(uval, m_forwarder);
+ else
+ return Printf("0x%" PRIx64, uval);
}
//------------------------------------------------------------------
@@ -119,9 +93,9 @@ void Stream::QuotedCString(const char *cstr, const char *format) {
//------------------------------------------------------------------
void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
const char *suffix) {
- if (prefix == NULL)
+ if (prefix == nullptr)
prefix = "";
- if (suffix == NULL)
+ if (suffix == nullptr)
suffix = "";
// int addr_width = m_addr_size << 1;
// Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
@@ -339,26 +313,25 @@ size_t Stream::PrintfAsRawHex8(const char *format, ...) {
llvm::SmallString<1024> buf;
VASprintf(buf, format, args);
- size_t length = 0;
+ ByteDelta delta(*this);
for (char C : buf)
- length += _PutHex8(C, false);
+ _PutHex8(C, false);
va_end(args);
- return length;
+ return *delta;
}
size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
- size_t bytes_written = 0;
+ ByteDelta delta(*this);
for (size_t i = 0; i < n; ++i)
- bytes_written += _PutHex8(uvalue, false);
- return bytes_written;
+ _PutHex8(uvalue, false);
+ return *delta;
}
-size_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
- size_t bytes_written = 0;
+void Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
if (m_flags.Test(eBinary)) {
- bytes_written = Write(&uvalue, 1);
+ Write(&uvalue, 1);
} else {
if (add_prefix)
PutCString("0x");
@@ -369,56 +342,62 @@ size_t Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
char nibble_chars[2];
nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
- bytes_written = Write(nibble_chars, sizeof(nibble_chars));
+ Write(nibble_chars, sizeof(nibble_chars));
}
- return bytes_written;
}
-size_t Stream::PutHex8(uint8_t uvalue) { return _PutHex8(uvalue, false); }
+size_t Stream::PutHex8(uint8_t uvalue) {
+ ByteDelta delta(*this);
+ _PutHex8(uvalue, false);
+ return *delta;
+}
size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
+ ByteDelta delta(*this);
+
if (byte_order == eByteOrderInvalid)
byte_order = m_byte_order;
- size_t bytes_written = 0;
if (byte_order == eByteOrderLittle) {
for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
- bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
+ _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
} else {
for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
- bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
+ _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
}
- return bytes_written;
+ return *delta;
}
size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
+ ByteDelta delta(*this);
+
if (byte_order == eByteOrderInvalid)
byte_order = m_byte_order;
- size_t bytes_written = 0;
if (byte_order == eByteOrderLittle) {
for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
- bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
+ _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
} else {
for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
- bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
+ _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
}
- return bytes_written;
+ return *delta;
}
size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
+ ByteDelta delta(*this);
+
if (byte_order == eByteOrderInvalid)
byte_order = m_byte_order;
- size_t bytes_written = 0;
if (byte_order == eByteOrderLittle) {
for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
- bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
+ _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
} else {
for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
- bytes_written += _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
+ _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
}
- return bytes_written;
+ return *delta;
}
size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
@@ -427,11 +406,11 @@ size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
case 1:
return PutHex8((uint8_t)uvalue);
case 2:
- return PutHex16((uint16_t)uvalue);
+ return PutHex16((uint16_t)uvalue, byte_order);
case 4:
- return PutHex32((uint32_t)uvalue);
+ return PutHex32((uint32_t)uvalue, byte_order);
case 8:
- return PutHex64(uvalue);
+ return PutHex64(uvalue, byte_order);
}
return 0;
}
@@ -464,65 +443,66 @@ size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
size_t Stream::PutRawBytes(const void *s, size_t src_len,
ByteOrder src_byte_order, ByteOrder dst_byte_order) {
+ ByteDelta delta(*this);
+
if (src_byte_order == eByteOrderInvalid)
src_byte_order = m_byte_order;
if (dst_byte_order == eByteOrderInvalid)
dst_byte_order = m_byte_order;
- size_t bytes_written = 0;
const uint8_t *src = (const uint8_t *)s;
bool binary_was_set = m_flags.Test(eBinary);
if (!binary_was_set)
m_flags.Set(eBinary);
if (src_byte_order == dst_byte_order) {
for (size_t i = 0; i < src_len; ++i)
- bytes_written += _PutHex8(src[i], false);
+ _PutHex8(src[i], false);
} else {
for (size_t i = src_len - 1; i < src_len; --i)
- bytes_written += _PutHex8(src[i], false);
+ _PutHex8(src[i], false);
}
if (!binary_was_set)
m_flags.Clear(eBinary);
- return bytes_written;
+ return *delta;
}
size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
ByteOrder src_byte_order,
ByteOrder dst_byte_order) {
+ ByteDelta delta(*this);
if (src_byte_order == eByteOrderInvalid)
src_byte_order = m_byte_order;
if (dst_byte_order == eByteOrderInvalid)
dst_byte_order = m_byte_order;
- size_t bytes_written = 0;
const uint8_t *src = (const uint8_t *)s;
bool binary_is_set = m_flags.Test(eBinary);
m_flags.Clear(eBinary);
if (src_byte_order == dst_byte_order) {
for (size_t i = 0; i < src_len; ++i)
- bytes_written += _PutHex8(src[i], false);
+ _PutHex8(src[i], false);
} else {
for (size_t i = src_len - 1; i < src_len; --i)
- bytes_written += _PutHex8(src[i], false);
+ _PutHex8(src[i], false);
}
if (binary_is_set)
m_flags.Set(eBinary);
- return bytes_written;
+ return *delta;
}
size_t Stream::PutCStringAsRawHex8(const char *s) {
- size_t bytes_written = 0;
+ ByteDelta delta(*this);
bool binary_is_set = m_flags.Test(eBinary);
m_flags.Clear(eBinary);
- do {
- bytes_written += _PutHex8(*s, false);
+ while(*s) {
+ _PutHex8(*s, false);
++s;
- } while (*s);
+ }
if (binary_is_set)
m_flags.Set(eBinary);
- return bytes_written;
+ return *delta;
}
diff --git a/contrib/llvm/tools/lldb/source/Utility/StreamGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Utility/StreamGDBRemote.cpp
index 2620e3786d29..9304d84f58a0 100644
--- a/contrib/llvm/tools/lldb/source/Utility/StreamGDBRemote.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/StreamGDBRemote.cpp
@@ -9,8 +9,8 @@
#include "lldb/Utility/StreamGDBRemote.h"
-#include "lldb/Utility/Flags.h" // for Flags
-#include "lldb/Utility/Stream.h" // for Stream::::eBinary
+#include "lldb/Utility/Flags.h"
+#include "lldb/Utility/Stream.h"
#include <stdio.h>
diff --git a/contrib/llvm/tools/lldb/source/Utility/StreamString.cpp b/contrib/llvm/tools/lldb/source/Utility/StreamString.cpp
index 75f58de28b97..152096198858 100644
--- a/contrib/llvm/tools/lldb/source/Utility/StreamString.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/StreamString.cpp
@@ -24,12 +24,15 @@ void StreamString::Flush() {
// Nothing to do when flushing a buffer based stream...
}
-size_t StreamString::Write(const void *s, size_t length) {
+size_t StreamString::WriteImpl(const void *s, size_t length) {
m_packet.append(reinterpret_cast<const char *>(s), length);
return length;
}
-void StreamString::Clear() { m_packet.clear(); }
+void StreamString::Clear() {
+ m_packet.clear();
+ m_bytes_written = 0;
+}
bool StreamString::Empty() const { return GetSize() == 0; }
diff --git a/contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp b/contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp
index 7528350cf759..ddf414702d8c 100644
--- a/contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/StringExtractor.cpp
@@ -11,9 +11,9 @@
#include <tuple>
-#include <ctype.h> // for isxdigit, isspace
+#include <ctype.h>
#include <stdlib.h>
-#include <string.h> // for memset
+#include <string.h>
static inline int xdigit_to_sint(char ch) {
if (ch >= 'a' && ch <= 'f')
diff --git a/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp
index 3cae06df3b1e..2a8bd785576b 100644
--- a/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/StringExtractorGDBRemote.cpp
@@ -9,7 +9,7 @@
#include "lldb/Utility/StringExtractorGDBRemote.h"
-#include <ctype.h> // for isxdigit
+#include <ctype.h>
#include <string.h>
StringExtractorGDBRemote::ResponseType
diff --git a/contrib/llvm/tools/lldb/source/Utility/StringList.cpp b/contrib/llvm/tools/lldb/source/Utility/StringList.cpp
index 190cb9d682c9..20bde1a39ac1 100644
--- a/contrib/llvm/tools/lldb/source/Utility/StringList.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/StringList.cpp
@@ -10,13 +10,13 @@
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/Log.h"
-#include "lldb/Utility/Stream.h" // for Stream
+#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
-#include "llvm/ADT/ArrayRef.h" // for ArrayRef, makeArrayRef
+#include "llvm/ADT/ArrayRef.h"
-#include <algorithm> // for min
-#include <stdint.h> // for SIZE_MAX, uint32_t
-#include <string.h> // for size_t, strcspn, NULL
+#include <algorithm>
+#include <stdint.h>
+#include <string.h>
using namespace lldb_private;
@@ -83,7 +83,7 @@ size_t StringList::GetMaxStringLength() const {
const char *StringList::GetStringAtIndex(size_t idx) const {
if (idx < m_strings.size())
return m_strings[idx].c_str();
- return NULL;
+ return nullptr;
}
void StringList::Join(const char *separator, Stream &strm) {
diff --git a/contrib/llvm/tools/lldb/source/Utility/StructuredData.cpp b/contrib/llvm/tools/lldb/source/Utility/StructuredData.cpp
index 55f003f245bf..76a141af40b6 100644
--- a/contrib/llvm/tools/lldb/source/Utility/StructuredData.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/StructuredData.cpp
@@ -12,14 +12,14 @@
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/JSON.h"
#include "lldb/Utility/Status.h"
-#include "lldb/Utility/Stream.h" // for Stream
+#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StreamString.h"
-#include "llvm/ADT/STLExtras.h" // for make_unique
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include <cerrno>
#include <cstdlib>
#include <inttypes.h>
-#include <limits> // for numeric_limits
+#include <limits>
using namespace lldb_private;
@@ -33,11 +33,6 @@ static StructuredData::ObjectSP ParseJSONArray(JSONParser &json_parser);
StructuredData::ObjectSP
StructuredData::ParseJSONFromFile(const FileSpec &input_spec, Status &error) {
StructuredData::ObjectSP return_sp;
- if (!input_spec.Exists()) {
- error.SetErrorStringWithFormatv("input file {0} does not exist.",
- input_spec);
- return return_sp;
- }
auto buffer_or_error = llvm::MemoryBuffer::getFile(input_spec.GetPath());
if (!buffer_or_error) {
@@ -149,7 +144,7 @@ static StructuredData::ObjectSP ParseJSONValue(JSONParser &json_parser) {
}
StructuredData::ObjectSP StructuredData::ParseJSON(std::string json_text) {
- JSONParser json_parser(json_text.c_str());
+ JSONParser json_parser(json_text);
StructuredData::ObjectSP object_sp = ParseJSONValue(json_parser);
return object_sp;
}
@@ -174,11 +169,11 @@ StructuredData::Object::GetObjectForDotSeparatedPath(llvm::StringRef path) {
if (this->GetType() == lldb::eStructuredDataTypeArray) {
std::pair<llvm::StringRef, llvm::StringRef> match = path.split('[');
- if (match.second.size() == 0) {
+ if (match.second.empty()) {
return this->shared_from_this();
}
errno = 0;
- uint64_t val = strtoul(match.second.str().c_str(), NULL, 10);
+ uint64_t val = strtoul(match.second.str().c_str(), nullptr, 10);
if (errno == 0) {
return this->GetAsArray()->GetItemAtIndex(val);
}
@@ -231,7 +226,7 @@ void StructuredData::Float::Dump(Stream &s, bool pretty_print) const {
}
void StructuredData::Boolean::Dump(Stream &s, bool pretty_print) const {
- if (m_value == true)
+ if (m_value)
s.PutCString("true");
else
s.PutCString("false");
diff --git a/contrib/llvm/tools/lldb/source/Utility/TildeExpressionResolver.cpp b/contrib/llvm/tools/lldb/source/Utility/TildeExpressionResolver.cpp
index ae947059d8b9..4e2be77c49cb 100644
--- a/contrib/llvm/tools/lldb/source/Utility/TildeExpressionResolver.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/TildeExpressionResolver.cpp
@@ -9,14 +9,14 @@
#include "lldb/Utility/TildeExpressionResolver.h"
-#include <assert.h> // for assert
-#include <system_error> // for error_code
+#include <assert.h>
+#include <system_error>
-#include "llvm/ADT/STLExtras.h" // for any_of
-#include "llvm/ADT/SmallVector.h" // for SmallVectorImpl
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
-#include "llvm/Support/raw_ostream.h" // for fs
+#include "llvm/Support/raw_ostream.h"
#if !defined(_WIN32)
#include <pwd.h>
@@ -59,7 +59,7 @@ bool StandardTildeExpressionResolver::ResolvePartial(StringRef Expr,
struct passwd *user_entry;
Expr = Expr.drop_front();
- while ((user_entry = getpwent()) != NULL) {
+ while ((user_entry = getpwent()) != nullptr) {
StringRef ThisName(user_entry->pw_name);
if (!ThisName.startswith(Expr))
continue;
diff --git a/contrib/llvm/tools/lldb/source/Utility/Timer.cpp b/contrib/llvm/tools/lldb/source/Utility/Timer.cpp
index fe7787458fa6..c56ac2192b33 100644
--- a/contrib/llvm/tools/lldb/source/Utility/Timer.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/Timer.cpp
@@ -12,11 +12,11 @@
#include <algorithm>
#include <map>
#include <mutex>
-#include <utility> // for pair
+#include <utility>
#include <vector>
-#include <assert.h> // for assert
-#include <stdarg.h> // for va_end, va_list, va_start
+#include <assert.h>
+#include <stdarg.h>
#include <stdio.h>
using namespace lldb_private;
@@ -125,7 +125,7 @@ void Timer::DumpCategoryTimes(Stream *s) {
return; // Later code will break without any elements.
// Sort by time
- std::sort(sorted.begin(), sorted.end(), CategoryMapIteratorSortCriterion);
+ llvm::sort(sorted.begin(), sorted.end(), CategoryMapIteratorSortCriterion);
for (const auto &timer : sorted)
s->Printf("%.9f sec for %s\n", timer.second / 1000000000., timer.first);
diff --git a/contrib/llvm/tools/lldb/source/Utility/UUID.cpp b/contrib/llvm/tools/lldb/source/Utility/UUID.cpp
index 623ad69ddc76..b00878792c7e 100644
--- a/contrib/llvm/tools/lldb/source/Utility/UUID.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/UUID.cpp
@@ -9,13 +9,10 @@
#include "lldb/Utility/UUID.h"
-// Other libraries and framework includes
-// Project includes
#include "lldb/Utility/Stream.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Format.h"
-// C Includes
#include <ctype.h>
#include <stdio.h>
#include <string.h>
@@ -54,9 +51,7 @@ std::string UUID::GetAsString(llvm::StringRef separator) const {
return result;
}
-void UUID::Dump(Stream *s) const {
- s->PutCString(GetAsString().c_str());
-}
+void UUID::Dump(Stream *s) const { s->PutCString(GetAsString()); }
static inline int xdigit_to_int(char ch) {
ch = tolower(ch);
diff --git a/contrib/llvm/tools/lldb/source/Utility/VASprintf.cpp b/contrib/llvm/tools/lldb/source/Utility/VASprintf.cpp
index 900d9754a9b4..4368a3738307 100644
--- a/contrib/llvm/tools/lldb/source/Utility/VASprintf.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/VASprintf.cpp
@@ -10,12 +10,12 @@
#include "lldb/Utility/VASPrintf.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h" // for SmallVectorImpl
-#include "llvm/ADT/StringRef.h" // for StringRef
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
-#include <assert.h> // for assert
-#include <stdarg.h> // for va_end, va_list, va_copy
-#include <stdio.h> // for vsnprintf, size_t
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
bool lldb_private::VASprintf(llvm::SmallVectorImpl<char> &buf, const char *fmt,
va_list args) {
diff --git a/contrib/llvm/tools/lldb/source/Utility/VMRange.cpp b/contrib/llvm/tools/lldb/source/Utility/VMRange.cpp
index 7e35d3ef0c65..20dc7dbbe757 100644
--- a/contrib/llvm/tools/lldb/source/Utility/VMRange.cpp
+++ b/contrib/llvm/tools/lldb/source/Utility/VMRange.cpp
@@ -10,14 +10,14 @@
#include "lldb/Utility/VMRange.h"
#include "lldb/Utility/Stream.h"
-#include "lldb/lldb-types.h" // for addr_t
+#include "lldb/lldb-types.h"
#include <algorithm>
-#include <iterator> // for distance
-#include <vector> // for const_iterator
+#include <iterator>
+#include <vector>
-#include <stddef.h> // for size_t
-#include <stdint.h> // for UINT32_MAX, uint32_t
+#include <stddef.h>
+#include <stdint.h>
using namespace lldb;
using namespace lldb_private;