brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.2 KiB · c09a5c3 Raw
133 lines · cpp
1//===-- BackgroundIndexLoader.cpp - ---------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "index/BackgroundIndexLoader.h"10#include "GlobalCompilationDatabase.h"11#include "index/Background.h"12#include "support/Logger.h"13#include "support/Path.h"14#include "llvm/ADT/StringMap.h"15#include "llvm/Support/Path.h"16#include <string>17#include <utility>18#include <vector>19 20namespace clang {21namespace clangd {22namespace {23 24/// A helper class to cache BackgroundIndexStorage operations and keep the25/// inverse dependency mapping.26class BackgroundIndexLoader {27public:28  BackgroundIndexLoader(BackgroundIndexStorage::Factory &IndexStorageFactory)29      : IndexStorageFactory(IndexStorageFactory) {}30  /// Load the shards for \p MainFile and all of its dependencies.31  void load(PathRef MainFile);32 33  /// Consumes the loader and returns all shards.34  std::vector<LoadedShard> takeResult() &&;35 36private:37  /// Returns the Shard for \p StartSourceFile from cache or loads it from \p38  /// Storage. Also returns paths for dependencies of \p StartSourceFile if it39  /// wasn't cached yet.40  std::pair<const LoadedShard &, std::vector<Path>>41  loadShard(PathRef StartSourceFile, PathRef DependentTU);42 43  /// Cache for Storage lookups.44  llvm::StringMap<LoadedShard> LoadedShards;45 46  BackgroundIndexStorage::Factory &IndexStorageFactory;47};48 49std::pair<const LoadedShard &, std::vector<Path>>50BackgroundIndexLoader::loadShard(PathRef StartSourceFile, PathRef DependentTU) {51  auto It = LoadedShards.try_emplace(StartSourceFile);52  LoadedShard &LS = It.first->getValue();53  std::vector<Path> Edges = {};54  // Return the cached shard.55  if (!It.second)56    return {LS, Edges};57 58  LS.AbsolutePath = StartSourceFile.str();59  LS.DependentTU = std::string(DependentTU);60  BackgroundIndexStorage *Storage = IndexStorageFactory(LS.AbsolutePath);61  auto Shard = Storage->loadShard(StartSourceFile);62  if (!Shard || !Shard->Sources) {63    vlog("Failed to load shard: {0}", StartSourceFile);64    return {LS, Edges};65  }66 67  LS.Shard = std::move(Shard);68  for (const auto &It : *LS.Shard->Sources) {69    auto AbsPath = URI::resolve(It.getKey(), StartSourceFile);70    if (!AbsPath) {71      elog("Failed to resolve URI: {0}", AbsPath.takeError());72      continue;73    }74    // A shard contains only edges for non main-file sources.75    if (*AbsPath != StartSourceFile) {76      Edges.push_back(*AbsPath);77      continue;78    }79 80    // Fill in shard metadata.81    const IncludeGraphNode &IGN = It.getValue();82    LS.Digest = IGN.Digest;83    LS.CountReferences = IGN.Flags & IncludeGraphNode::SourceFlag::IsTU;84    LS.HadErrors = IGN.Flags & IncludeGraphNode::SourceFlag::HadErrors;85  }86  assert(LS.Digest != FileDigest{{0}} && "Digest is empty?");87  return {LS, Edges};88}89 90void BackgroundIndexLoader::load(PathRef MainFile) {91  llvm::StringSet<> InQueue;92  // Following containers points to strings inside InQueue.93  std::queue<PathRef> ToVisit;94  InQueue.insert(MainFile);95  ToVisit.push(MainFile);96 97  while (!ToVisit.empty()) {98    PathRef SourceFile = ToVisit.front();99    ToVisit.pop();100 101    auto ShardAndEdges = loadShard(SourceFile, MainFile);102    for (PathRef Edge : ShardAndEdges.second) {103      auto It = InQueue.insert(Edge);104      if (It.second)105        ToVisit.push(It.first->getKey());106    }107  }108}109 110std::vector<LoadedShard> BackgroundIndexLoader::takeResult() && {111  std::vector<LoadedShard> Result;112  Result.reserve(LoadedShards.size());113  for (auto &It : LoadedShards)114    Result.push_back(std::move(It.getValue()));115  return Result;116}117} // namespace118 119std::vector<LoadedShard>120loadIndexShards(llvm::ArrayRef<Path> MainFiles,121                BackgroundIndexStorage::Factory &IndexStorageFactory,122                const GlobalCompilationDatabase &CDB) {123  BackgroundIndexLoader Loader(IndexStorageFactory);124  for (llvm::StringRef MainFile : MainFiles) {125    assert(llvm::sys::path::is_absolute(MainFile));126    Loader.load(MainFile);127  }128  return std::move(Loader).takeResult();129}130 131} // namespace clangd132} // namespace clang133