diff options
Diffstat (limited to 'lldb/source/Utility/Reproducer.cpp')
-rw-r--r-- | lldb/source/Utility/Reproducer.cpp | 113 |
1 files changed, 50 insertions, 63 deletions
diff --git a/lldb/source/Utility/Reproducer.cpp b/lldb/source/Utility/Reproducer.cpp index 5b8480fcfec..0048a11970d 100644 --- a/lldb/source/Utility/Reproducer.cpp +++ b/lldb/source/Utility/Reproducer.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/Reproducer.h" -#include "lldb/Host/HostInfo.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Threading.h" @@ -26,145 +25,131 @@ Reproducer &Reproducer::Instance() { const Generator *Reproducer::GetGenerator() const { std::lock_guard<std::mutex> guard(m_mutex); - if (m_generate_reproducer) - return &m_generator; + if (m_generator) + return &(*m_generator); return nullptr; } const Loader *Reproducer::GetLoader() const { std::lock_guard<std::mutex> guard(m_mutex); - if (m_replay_reproducer) - return &m_loader; + if (m_loader) + return &(*m_loader); return nullptr; } Generator *Reproducer::GetGenerator() { std::lock_guard<std::mutex> guard(m_mutex); - if (m_generate_reproducer) - return &m_generator; + if (m_generator) + return &(*m_generator); return nullptr; } Loader *Reproducer::GetLoader() { std::lock_guard<std::mutex> guard(m_mutex); - if (m_replay_reproducer) - return &m_loader; + if (m_loader) + return &(*m_loader); return nullptr; } -llvm::Error Reproducer::SetGenerateReproducer(bool value) { +llvm::Error Reproducer::SetCapture(llvm::Optional<FileSpec> root) { std::lock_guard<std::mutex> guard(m_mutex); - if (value && m_replay_reproducer) + if (root && m_loader) return make_error<StringError>( "cannot generate a reproducer when replay one", inconvertibleErrorCode()); - m_generate_reproducer = value; - m_generator.SetEnabled(value); + if (root) + m_generator.emplace(*root); + else + m_generator.reset(); return Error::success(); } -llvm::Error Reproducer::SetReplayReproducer(bool value) { +llvm::Error Reproducer::SetReplay(llvm::Optional<FileSpec> root) { std::lock_guard<std::mutex> guard(m_mutex); - if (value && m_generate_reproducer) + if (root && m_generator) return make_error<StringError>( "cannot replay a reproducer when generating one", inconvertibleErrorCode()); - m_replay_reproducer = value; - - return Error::success(); -} - -llvm::Error Reproducer::SetReproducerPath(const FileSpec &path) { - // Setting the path implies using the reproducer. - if (auto e = SetReplayReproducer(true)) - return e; - - // Tell the reproducer to load the index form the given path. - if (auto loader = GetLoader()) { - if (auto e = loader->LoadIndex(path)) + if (root) { + m_loader.emplace(*root); + if (auto e = m_loader->LoadIndex()) return e; + } else { + m_loader.reset(); } - return make_error<StringError>("unable to get loader", - inconvertibleErrorCode()); + return Error::success(); } FileSpec Reproducer::GetReproducerPath() const { if (auto g = GetGenerator()) - return g->GetDirectory(); + return g->GetRoot(); + if (auto l = GetLoader()) + return l->GetRoot(); return {}; } -Generator::Generator() : m_enabled(false), m_done(false) { - m_directory = HostInfo::GetReproducerTempDir(); -} +Generator::Generator(const FileSpec &root) : m_root(root), m_done(false) {} Generator::~Generator() {} -Provider &Generator::Register(std::unique_ptr<Provider> provider) { +ProviderBase *Generator::Register(std::unique_ptr<ProviderBase> provider) { std::lock_guard<std::mutex> lock(m_providers_mutex); - - AddProviderToIndex(provider->GetInfo()); - - m_providers.push_back(std::move(provider)); - return *m_providers.back(); + 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; - if (!m_enabled) - return; - for (auto &provider : m_providers) - provider->Keep(); + provider.second->Keep(); + + AddProvidersToIndex(); } void Generator::Discard() { assert(!m_done); m_done = true; - if (!m_enabled) - return; - for (auto &provider : m_providers) - provider->Discard(); - - llvm::sys::fs::remove_directories(m_directory.GetPath()); -} + provider.second->Discard(); -void Generator::ChangeDirectory(const FileSpec &directory) { - assert(m_providers.empty() && "Changing the directory after providers have " - "been registered would invalidate the index."); - m_directory = directory; + llvm::sys::fs::remove_directories(m_root.GetPath()); } -const FileSpec &Generator::GetDirectory() const { return m_directory; } +const FileSpec &Generator::GetRoot() const { return m_root; } -void Generator::AddProviderToIndex(const ProviderInfo &provider_info) { - FileSpec index = m_directory; +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); - yout << const_cast<ProviderInfo &>(provider_info); + + for (auto &provider : m_providers) { + auto &provider_info = provider.second->GetInfo(); + yout << const_cast<ProviderInfo &>(provider_info); + } } -Loader::Loader() : m_loaded(false) {} +Loader::Loader(const FileSpec &root) : m_root(root), m_loaded(false) {} -llvm::Error Loader::LoadIndex(const FileSpec &directory) { +llvm::Error Loader::LoadIndex() { if (m_loaded) return llvm::Error::success(); - FileSpec index = directory.CopyByAppendingPathComponent("index.yaml"); + FileSpec index = m_root.CopyByAppendingPathComponent("index.yaml"); auto error_or_file = MemoryBuffer::getFile(index.GetPath()); if (auto err = error_or_file.getError()) @@ -180,7 +165,6 @@ llvm::Error Loader::LoadIndex(const FileSpec &directory) { for (auto &info : provider_info) m_provider_info[info.name] = info; - m_directory = directory; m_loaded = true; return llvm::Error::success(); @@ -195,3 +179,6 @@ llvm::Optional<ProviderInfo> Loader::GetProviderInfo(StringRef name) { return it->second; } + +void ProviderBase::anchor() {} +char ProviderBase::ID = 0; |