-
Notifications
You must be signed in to change notification settings - Fork 20
/
validate-index.cpp
101 lines (86 loc) · 3.15 KB
/
validate-index.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "clang/Index/IndexDataStore.h"
#include "clang/Index/IndexUnitReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include <string>
#include <utility>
#include <vector>
using namespace llvm;
using namespace llvm::sys;
using namespace clang;
using namespace clang::index;
static cl::opt<std::string> IndexStore(cl::Positional, cl::Required,
cl::desc("<indexstore>"));
// Helper function to use consistent output. Uses `stdout` to ensure the output
// is greppable, or redirectable to file (separate from API/system errors).
static void logMissingFile(StringRef unitName, StringRef key, StringRef path) {
outs() << unitName << ": " << key << ": " << path << "\n";
}
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv);
PathRemapper clangPathRemapper;
std::string storeError{};
auto store =
IndexDataStore::create(IndexStore, clangPathRemapper, storeError);
if (not store) {
errs() << "error: failed to open indexstore " << IndexStore << " -- "
<< storeError << "\n";
return EXIT_FAILURE;
}
std::vector<std::string> unitNames{};
store->foreachUnitName(false, [&](StringRef unitName) {
unitNames.push_back(unitName.str());
return true;
});
auto exitStatus = EXIT_SUCCESS;
for (const auto &unitName : unitNames) {
std::string readerError;
auto reader = IndexUnitReader::createWithUnitFilename(
unitName, IndexStore, store->getPathRemapper(), readerError);
if (not reader) {
exitStatus = EXIT_FAILURE;
errs() << "error: failed to read unit file " << unitName << " -- "
<< readerError << "\n";
continue;
}
const std::vector<std::pair<std::string, llvm::StringRef>> unitPaths = {
{"MainFilePath", reader->getMainFilePath()},
{"SysrootPath", reader->getSysrootPath()},
{"WorkingDirectory", reader->getWorkingDirectory()},
// TODO: OutputFile does not need to exist, but its path needs to match
// the format expected by Xcode. Check the format instead of the
// existence of the file.
// {"OutputFile", reader->getOutputFile()},
};
for (const auto &pair : unitPaths) {
const auto &key = pair.first;
const auto &path = pair.second;
if (path.empty()) {
continue;
}
if (not fs::exists(path)) {
exitStatus = EXIT_FAILURE;
logMissingFile(unitName, key, path);
}
}
reader->foreachDependency([&](const IndexUnitReader::DependencyInfo &info) {
if (not fs::exists(info.FilePath)) {
exitStatus = EXIT_FAILURE;
logMissingFile(unitName, "DependencyPath", info.FilePath);
}
return true;
});
reader->foreachInclude([&](const IndexUnitReader::IncludeInfo &info) {
if (not fs::exists(info.SourcePath)) {
exitStatus = EXIT_FAILURE;
logMissingFile(unitName, "IncludeSourcePath", info.SourcePath);
}
if (not fs::exists(info.TargetPath)) {
exitStatus = EXIT_FAILURE;
logMissingFile(unitName, "IncludeTargetPath", info.TargetPath);
}
return true;
});
}
return exitStatus;
}