Skip to content

Commit 0f129c4

Browse files
committed
chore: Improve headers search
1 parent 1f6eebb commit 0f129c4

File tree

1 file changed

+74
-47
lines changed

1 file changed

+74
-47
lines changed

src/parser/cxx/preprocessor.cc

Lines changed: 74 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,62 +1035,86 @@ struct Preprocessor::Private {
10351035

10361036
[[nodiscard]] auto checkPragmaOnceProtected(TokList *ts) const -> bool;
10371037

1038-
[[nodiscard]] auto resolve(const Include &include, bool next) const
1039-
-> std::optional<fs::path> {
1040-
if (!canResolveFiles_) return std::nullopt;
1038+
struct Resolve {
1039+
const Private *d;
1040+
bool wantNextInlude;
1041+
bool didFindCurrentPath = false;
1042+
std::optional<fs::path> firstMatch;
10411043

1042-
struct Resolve {
1043-
const Private *d;
1044-
bool next;
1045-
1046-
Resolve(const Private *d, bool next) : d(d), next(next) {}
1047-
1048-
[[nodiscard]] auto operator()(const SystemInclude &include) const
1049-
-> std::optional<fs::path> {
1050-
bool hit = false;
1051-
for (const auto &includePath :
1052-
d->systemIncludePaths_ | std::views::reverse) {
1053-
const auto path = fs::path(includePath) / include.fileName;
1054-
if (d->fileExists(path)) {
1055-
if (!next || hit) return path;
1056-
hit = true;
1057-
}
1058-
}
1059-
return {};
1060-
}
1044+
Resolve(const Private *d, bool next) : d(d), wantNextInlude(next) {}
10611045

1062-
[[nodiscard]] auto operator()(const QuoteInclude &include) const
1063-
-> std::optional<fs::path> {
1064-
bool hit = false;
1046+
[[nodiscard]] auto search(auto view, const std::string &headerName)
1047+
-> std::optional<fs::path> {
1048+
auto transformToIncludePath = std::views::transform(
1049+
[&](const fs::path &path) { return path / headerName; });
10651050

1066-
if (auto path = d->currentPath_ / include.fileName;
1067-
d->fileExists(path)) {
1068-
if (!next) return path;
1069-
hit = true;
1070-
}
1051+
auto filterExistingFiles = std::views::filter(
1052+
[&](const fs::path &path) { return d->fileExists(path); });
10711053

1072-
for (const auto &includePath :
1073-
d->quoteIncludePaths_ | std::views::reverse) {
1074-
const auto path = fs::path(includePath) / include.fileName;
1075-
if (d->fileExists(path)) {
1076-
if (!next || hit) return path;
1077-
hit = true;
1078-
}
1054+
for (const auto &path : view | transformToIncludePath |
1055+
filterExistingFiles | std::views::reverse) {
1056+
firstMatch = path;
1057+
1058+
if (wantNextInlude && path == d->currentPath_) {
1059+
didFindCurrentPath = true;
1060+
continue;
10791061
}
10801062

1081-
for (const auto &includePath :
1082-
d->systemIncludePaths_ | std::views::reverse) {
1083-
const auto path = fs::path(includePath) / include.fileName;
1084-
if (d->fileExists(path)) {
1085-
if (!next || hit) return path;
1086-
hit = true;
1087-
}
1063+
if (wantNextInlude && !didFindCurrentPath) {
1064+
continue;
10881065
}
1089-
return {};
1066+
1067+
return path;
1068+
}
1069+
1070+
return std::nullopt;
1071+
}
1072+
1073+
[[nodiscard]] auto operator()(const QuoteInclude &include)
1074+
-> std::optional<fs::path> {
1075+
const auto &headerName = include.fileName;
1076+
1077+
// search in the current path
1078+
if (auto p = search(std::views::single(d->currentPath_), headerName)) {
1079+
return p;
1080+
}
1081+
1082+
// search in the quote include paths
1083+
if (auto p = search(d->quoteIncludePaths_, headerName)) {
1084+
return p;
10901085
}
1091-
};
10921086

1093-
return std::visit(Resolve(this, next), include);
1087+
// fallback to system include paths
1088+
if (auto p = search(d->systemIncludePaths_, headerName)) {
1089+
return p;
1090+
}
1091+
1092+
if (wantNextInlude && !didFindCurrentPath) {
1093+
return firstMatch;
1094+
}
1095+
1096+
return std::nullopt;
1097+
}
1098+
1099+
[[nodiscard]] auto operator()(const SystemInclude &include)
1100+
-> std::optional<fs::path> {
1101+
if (auto p = search(d->systemIncludePaths_, include.fileName)) {
1102+
return p;
1103+
}
1104+
1105+
if (wantNextInlude && !didFindCurrentPath) {
1106+
return firstMatch;
1107+
}
1108+
1109+
return std::nullopt;
1110+
}
1111+
};
1112+
1113+
[[nodiscard]] auto resolve(const Include &include, bool next) const
1114+
-> std::optional<fs::path> {
1115+
if (!canResolveFiles_) return std::nullopt;
1116+
1117+
return std::visit(Resolve{this, next}, include);
10941118
}
10951119

10961120
[[nodiscard]] auto isDefined(const std::string_view &id) const -> bool {
@@ -2979,6 +3003,9 @@ auto Preprocessor::systemIncludePaths() const
29793003
}
29803004

29813005
void Preprocessor::addSystemIncludePath(std::string path) {
3006+
while (path.length() > 1 && path.ends_with(fs::path::preferred_separator)) {
3007+
path.pop_back();
3008+
}
29823009
d->systemIncludePaths_.push_back(std::move(path));
29833010
}
29843011

0 commit comments

Comments
 (0)