brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.0 KiB · 67b8ef6 Raw
119 lines · cpp
1//===- CompilationDatabase.cpp - LSP Compilation Database -----------------===//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 "mlir/Tools/lsp-server-support/CompilationDatabase.h"10#include "mlir/Support/FileUtilities.h"11#include "llvm/ADT/SetVector.h"12#include "llvm/ADT/StringRef.h"13#include "llvm/Support/LSP/Logging.h"14#include "llvm/Support/LSP/Protocol.h"15#include "llvm/Support/YAMLTraits.h"16 17using namespace mlir;18using namespace mlir::lsp;19using llvm::lsp::Logger;20 21//===----------------------------------------------------------------------===//22// YamlFileInfo23//===----------------------------------------------------------------------===//24 25namespace {26struct YamlFileInfo {27  /// The absolute path to the file.28  std::string filename;29  /// The include directories available for the file.30  std::vector<std::string> includeDirs;31};32} // namespace33 34//===----------------------------------------------------------------------===//35// CompilationDatabase36//===----------------------------------------------------------------------===//37 38LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlFileInfo)39 40namespace llvm {41namespace yaml {42template <>43struct MappingTraits<YamlFileInfo> {44  static void mapping(IO &io, YamlFileInfo &info) {45    // Parse the filename and normalize it to the form we will expect from46    // incoming URIs.47    io.mapRequired("filepath", info.filename);48 49    // Normalize the filename to avoid incompatability with incoming URIs.50    if (Expected<lsp::URIForFile> uri =51            lsp::URIForFile::fromFile(info.filename))52      info.filename = uri->file().str();53 54    // Parse the includes from the yaml stream. These are in the form of a55    // semi-colon delimited list.56    std::string combinedIncludes;57    io.mapRequired("includes", combinedIncludes);58    for (StringRef include : llvm::split(combinedIncludes, ";")) {59      if (!include.empty())60        info.includeDirs.push_back(include.str());61    }62  }63};64} // end namespace yaml65} // end namespace llvm66 67CompilationDatabase::CompilationDatabase(ArrayRef<std::string> databases) {68  for (StringRef filename : databases)69    loadDatabase(filename);70}71 72const CompilationDatabase::FileInfo &73CompilationDatabase::getFileInfo(StringRef filename) const {74  auto it = files.find(filename);75  return it == files.end() ? defaultFileInfo : it->second;76}77 78void CompilationDatabase::loadDatabase(StringRef filename) {79  if (filename.empty())80    return;81 82  // Set up the input file.83  std::string errorMessage;84  std::unique_ptr<llvm::MemoryBuffer> inputFile =85      openInputFile(filename, &errorMessage);86  if (!inputFile) {87    Logger::error("Failed to open compilation database: {0}", errorMessage);88    return;89  }90  llvm::yaml::Input yaml(inputFile->getBuffer());91 92  // Parse the yaml description and add any new files to the database.93  std::vector<YamlFileInfo> parsedFiles;94  yaml >> parsedFiles;95 96  SetVector<StringRef> knownIncludes;97  for (auto &file : parsedFiles) {98    auto it = files.try_emplace(file.filename, std::move(file.includeDirs));99 100    // If we encounter a duplicate file, log a warning and ignore it.101    if (!it.second) {102      Logger::info("Duplicate file in compilation database: {0}",103                   file.filename);104      continue;105    }106 107    // Track the includes for the file.108    knownIncludes.insert_range(it.first->second.includeDirs);109  }110 111  // Add all of the known includes to the default file info. We don't know any112  // information about how to treat these files, but these may be project files113  // that we just don't yet have information for. In these cases, providing some114  // heuristic information provides a better user experience, and generally115  // shouldn't lead to any negative side effects.116  for (StringRef include : knownIncludes)117    defaultFileInfo.includeDirs.push_back(include.str());118}119