summaryrefslogtreecommitdiffstats
path: root/lldb/source/Utility/Reproducer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Utility/Reproducer.cpp')
-rw-r--r--lldb/source/Utility/Reproducer.cpp113
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;
OpenPOWER on IntegriCloud