MLIR  22.0.0git
CompilationDatabase.cpp
Go to the documentation of this file.
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
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 
17 using namespace mlir;
18 using namespace mlir::lsp;
19 using llvm::lsp::Logger;
20 
21 //===----------------------------------------------------------------------===//
22 // YamlFileInfo
23 //===----------------------------------------------------------------------===//
24 
25 namespace {
26 struct 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 } // namespace
33 
34 //===----------------------------------------------------------------------===//
35 // CompilationDatabase
36 //===----------------------------------------------------------------------===//
37 
38 LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(YamlFileInfo)
39 
40 namespace llvm {
41 namespace yaml {
42 template <>
43 struct MappingTraits<YamlFileInfo> {
44  static void mapping(IO &io, YamlFileInfo &info) {
45  // Parse the filename and normalize it to the form we will expect from
46  // incoming URIs.
47  io.mapRequired("filepath", info.filename);
48 
49  // Normalize the filename to avoid incompatability with incoming URIs.
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 a
55  // 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 yaml
65 } // end namespace llvm
66 
68  for (StringRef filename : databases)
69  loadDatabase(filename);
70 }
71 
73 CompilationDatabase::getFileInfo(StringRef filename) const {
74  auto it = files.find(filename);
75  return it == files.end() ? defaultFileInfo : it->second;
76 }
77 
78 void 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 any
112  // information about how to treat these files, but these may be project files
113  // that we just don't yet have information for. In these cases, providing some
114  // heuristic information provides a better user experience, and generally
115  // shouldn't lead to any negative side effects.
116  for (StringRef include : knownIncludes)
117  defaultFileInfo.includeDirs.push_back(include.str());
118 }
const FileInfo & getFileInfo(StringRef filename) const
Get the compilation information for the provided file.
CompilationDatabase(ArrayRef< std::string > databases)
Construct a compilation database from the provided files containing YAML descriptions of the database...
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
Include the generated interface declarations.
std::unique_ptr< llvm::MemoryBuffer > openInputFile(llvm::StringRef inputFilename, std::string *errorMessage=nullptr)
Open the file specified by its name for reading.
static void mapping(IO &io, YamlFileInfo &info)
Compilation information for a specific file within the database.
std::vector< std::string > includeDirs
The include directories available for the file.