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
17using namespace mlir;
18using namespace mlir::lsp;
19using llvm::lsp::Logger;
20
21//===----------------------------------------------------------------------===//
22// YamlFileInfo
23//===----------------------------------------------------------------------===//
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} // namespace
33
34//===----------------------------------------------------------------------===//
35// CompilationDatabase
36//===----------------------------------------------------------------------===//
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 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
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 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.
llvm::SetVector< T, Vector, Set, N > SetVector
Definition LLVM.h:131
static void mapping(IO &io, YamlFileInfo &info)
Compilation information for a specific file within the database.