aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Lex/HeaderSearch.cpp
diff options
context:
space:
mode:
authorSam McCall <sam.mccall@gmail.com>2022-11-25 14:19:04 +0100
committerSam McCall <sam.mccall@gmail.com>2022-11-28 10:09:13 +0100
commit2c1fa734598c9470139720565fbf624a5156ec03 (patch)
tree11b57bcd16102c2a28786d4a797e12e73a040f03 /clang/lib/Lex/HeaderSearch.cpp
parent10d183b889daab4512d476c1645d24d4e8946e8c (diff)
downloadllvm-2c1fa734598c9470139720565fbf624a5156ec03.zip
llvm-2c1fa734598c9470139720565fbf624a5156ec03.tar.gz
llvm-2c1fa734598c9470139720565fbf624a5156ec03.tar.bz2
Reland "[Lex] Fix suggested spelling of /usr/bin/../include/foo"
This reverts commit 1dc0a1e5d220b83c1074204bd3afd54f3bac4270. Failures were caused by unintentional conversion to native slashes by remove_dots, so undo that: we always suggest posix slashes for includes. This could potentially be a change in behavior on windows if people were spelling headers with backslashes and headermaps contained backslashes, but that's all underspecified and I don't think anyone uses headermaps on windows. Differential Revision: https://reviews.llvm.org/D138709
Diffstat (limited to 'clang/lib/Lex/HeaderSearch.cpp')
-rw-r--r--clang/lib/Lex/HeaderSearch.cpp30
1 files changed, 13 insertions, 17 deletions
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index e6af122..7bf278c 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -1928,32 +1928,28 @@ std::string HeaderSearch::suggestPathToFileForDiagnostics(
llvm::StringRef File, llvm::StringRef WorkingDir, llvm::StringRef MainFile,
bool *IsSystem) {
using namespace llvm::sys;
+
+ llvm::SmallString<32> FilePath = File;
+ // remove_dots switches to backslashes on windows as a side-effect!
+ // We always want to suggest forward slashes for includes.
+ // (not remove_dots(..., posix) as that misparses windows paths).
+ path::remove_dots(FilePath, /*remove_dot_dot=*/true);
+ path::native(FilePath, path::Style::posix);
+ File = FilePath;
unsigned BestPrefixLength = 0;
// Checks whether `Dir` is a strict path prefix of `File`. If so and that's
// the longest prefix we've seen so for it, returns true and updates the
// `BestPrefixLength` accordingly.
- auto CheckDir = [&](llvm::StringRef Dir) -> bool {
- llvm::SmallString<32> DirPath(Dir.begin(), Dir.end());
+ auto CheckDir = [&](llvm::SmallString<32> Dir) -> bool {
if (!WorkingDir.empty() && !path::is_absolute(Dir))
- fs::make_absolute(WorkingDir, DirPath);
- path::remove_dots(DirPath, /*remove_dot_dot=*/true);
- Dir = DirPath;
+ fs::make_absolute(WorkingDir, Dir);
+ path::remove_dots(Dir, /*remove_dot_dot=*/true);
for (auto NI = path::begin(File), NE = path::end(File),
DI = path::begin(Dir), DE = path::end(Dir);
- /*termination condition in loop*/; ++NI, ++DI) {
- // '.' components in File are ignored.
- while (NI != NE && *NI == ".")
- ++NI;
- if (NI == NE)
- break;
-
- // '.' components in Dir are ignored.
- while (DI != DE && *DI == ".")
- ++DI;
+ NI != NE; ++NI, ++DI) {
if (DI == DE) {
- // Dir is a prefix of File, up to '.' components and choice of path
- // separators.
+ // Dir is a prefix of File, up to choice of path separators.
unsigned PrefixLength = NI - path::begin(File);
if (PrefixLength > BestPrefixLength) {
BestPrefixLength = PrefixLength;