Untitled
unknown
plain_text
3 years ago
3.6 kB
10
Indexable
llvm::Expected<Corpus>
buildCorpus(
tooling::ToolExecutor& executor,
Config const& cfg,
Reporter& R)
{
Corpus corpus;
// Traverse the AST for all translation
// units and emit serializd bitcode into
// tool results. This operation happens
// on a thread pool.
//
llvm::outs() << "Mapping declarations\n";
llvm::Error err = executor.execute(
newMapperActionFactory(corpus, cfg),
cfg.ArgAdjuster);
if(err)
{
if(! cfg.IgnoreMappingFailures)
{
llvm::errs() <<
"Mapping failure: " << err << "\n";
return std::move(err);
}
llvm::errs() <<
"Error mapping decls in files. mrdox will ignore "
"these files and continue:\n" << err << "\n";
}
// Collect the symbols. Each symbol will have
// a vector of one or more bitcodes. These will
// be merged later.
llvm::outs() << "Collecting symbols\n";
llvm::StringMap<std::vector<StringRef>> USRToBitcode;
executor.getToolResults()->forEachResult(
[&](StringRef Key, StringRef Value)
{
auto R = USRToBitcode.try_emplace(Key, std::vector<StringRef>());
R.first->second.emplace_back(Value);
});
// Collects all Infos according to their unique
// USR value. This map is added to from the thread
// pool below and is protected by this mutex.
llvm::sys::Mutex USRToInfoMutex;
// First reducing phase (reduce all decls into one info per decl).
llvm::outs() << "Reducing " << USRToBitcode.size() << " declarations\n";
std::atomic<bool> GotFailure;
GotFailure = false;
llvm::sys::Mutex IndexMutex;
// EAUGUSTE Should this concurrency be a command line option?
llvm::ThreadPool Pool(llvm::hardware_concurrency(tooling::ExecutorConcurrency));
for (auto& Group : USRToBitcode)
{
Pool.async([&]()
{
std::vector<std::unique_ptr<Info>> Infos;
for (auto& Bitcode : Group.getValue())
{
llvm::BitstreamCursor Stream(Bitcode);
ClangDocBitcodeReader Reader(Stream);
auto ReadInfos = Reader.readBitcode();
if (!ReadInfos)
{
llvm::errs() << toString(ReadInfos.takeError()) << "\n";
GotFailure = true;
return;
}
std::move(
ReadInfos->begin(),
ReadInfos->end(),
std::back_inserter(Infos));
}
auto Reduced = mergeInfos(Infos);
if (!Reduced)
{
// EAUGUSTE What about GotFailure?
llvm::errs() << llvm::toString(Reduced.takeError());
return;
}
// Add a reference to this Info in the Index
{
std::lock_guard<llvm::sys::Mutex> Guard(IndexMutex);
Generator::addInfoToIndex(corpus.Idx, Reduced.get().get());
}
// Save in the result map (needs a lock due to threaded access).
{
std::lock_guard<llvm::sys::Mutex> Guard(USRToInfoMutex);
corpus.USRToInfo[Group.getKey()] = std::move(Reduced.get());
}
});
}
Pool.wait();
if (GotFailure)
return llvm::createStringError(
llvm::inconvertibleErrorCode(),
"an error occurred");
return corpus;
}
Editor is loading...