Mercurial > hg > CbC > CbC_llvm
view clang-tools-extra/clangd/index/BackgroundIndexLoader.cpp @ 221:79ff65ed7e25
LLVM12 Original
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 15 Jun 2021 19:15:29 +0900 |
parents | 0572611fdcc8 |
children | c4bab56944e8 |
line wrap: on
line source
//===-- BackgroundIndexLoader.cpp - ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "index/BackgroundIndexLoader.h" #include "GlobalCompilationDatabase.h" #include "index/Background.h" #include "support/Logger.h" #include "support/Path.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Path.h" #include <string> #include <utility> #include <vector> namespace clang { namespace clangd { namespace { /// A helper class to cache BackgroundIndexStorage operations and keep the /// inverse dependency mapping. class BackgroundIndexLoader { public: BackgroundIndexLoader(BackgroundIndexStorage::Factory &IndexStorageFactory) : IndexStorageFactory(IndexStorageFactory) {} /// Load the shards for \p MainFile and all of its dependencies. void load(PathRef MainFile); /// Consumes the loader and returns all shards. std::vector<LoadedShard> takeResult() &&; private: /// Returns the Shard for \p StartSourceFile from cache or loads it from \p /// Storage. Also returns paths for dependencies of \p StartSourceFile if it /// wasn't cached yet. std::pair<const LoadedShard &, std::vector<Path>> loadShard(PathRef StartSourceFile, PathRef DependentTU); /// Cache for Storage lookups. llvm::StringMap<LoadedShard> LoadedShards; BackgroundIndexStorage::Factory &IndexStorageFactory; }; std::pair<const LoadedShard &, std::vector<Path>> BackgroundIndexLoader::loadShard(PathRef StartSourceFile, PathRef DependentTU) { auto It = LoadedShards.try_emplace(StartSourceFile); LoadedShard &LS = It.first->getValue(); std::vector<Path> Edges = {}; // Return the cached shard. if (!It.second) return {LS, Edges}; LS.AbsolutePath = StartSourceFile.str(); LS.DependentTU = std::string(DependentTU); BackgroundIndexStorage *Storage = IndexStorageFactory(LS.AbsolutePath); auto Shard = Storage->loadShard(StartSourceFile); if (!Shard || !Shard->Sources) { vlog("Failed to load shard: {0}", StartSourceFile); return {LS, Edges}; } LS.Shard = std::move(Shard); for (const auto &It : *LS.Shard->Sources) { auto AbsPath = URI::resolve(It.getKey(), StartSourceFile); if (!AbsPath) { elog("Failed to resolve URI: {0}", AbsPath.takeError()); continue; } // A shard contains only edges for non main-file sources. if (*AbsPath != StartSourceFile) { Edges.push_back(*AbsPath); continue; } // Fill in shard metadata. const IncludeGraphNode &IGN = It.getValue(); LS.Digest = IGN.Digest; LS.CountReferences = IGN.Flags & IncludeGraphNode::SourceFlag::IsTU; LS.HadErrors = IGN.Flags & IncludeGraphNode::SourceFlag::HadErrors; } assert(LS.Digest != FileDigest{{0}} && "Digest is empty?"); return {LS, Edges}; } void BackgroundIndexLoader::load(PathRef MainFile) { llvm::StringSet<> InQueue; // Following containers points to strings inside InQueue. std::queue<PathRef> ToVisit; InQueue.insert(MainFile); ToVisit.push(MainFile); while (!ToVisit.empty()) { PathRef SourceFile = ToVisit.front(); ToVisit.pop(); auto ShardAndEdges = loadShard(SourceFile, MainFile); for (PathRef Edge : ShardAndEdges.second) { auto It = InQueue.insert(Edge); if (It.second) ToVisit.push(It.first->getKey()); } } } std::vector<LoadedShard> BackgroundIndexLoader::takeResult() && { std::vector<LoadedShard> Result; Result.reserve(LoadedShards.size()); for (auto &It : LoadedShards) Result.push_back(std::move(It.getValue())); return Result; } } // namespace std::vector<LoadedShard> loadIndexShards(llvm::ArrayRef<Path> MainFiles, BackgroundIndexStorage::Factory &IndexStorageFactory, const GlobalCompilationDatabase &CDB) { BackgroundIndexLoader Loader(IndexStorageFactory); for (llvm::StringRef MainFile : MainFiles) { assert(llvm::sys::path::is_absolute(MainFile)); Loader.load(MainFile); } return std::move(Loader).takeResult(); } } // namespace clangd } // namespace clang