@@ -194,6 +194,7 @@ class RealFile : public File {
194
194
bool RequiresNullTerminator,
195
195
bool IsVolatile) override ;
196
196
std::error_code close () override ;
197
+ void setPath (const Twine &Path) override ;
197
198
};
198
199
199
200
} // namespace
@@ -229,6 +230,12 @@ std::error_code RealFile::close() {
229
230
return EC;
230
231
}
231
232
233
+ void RealFile::setPath (const Twine &Path) {
234
+ RealName = Path.str ();
235
+ if (auto Status = status ())
236
+ S = Status.get ().copyWithNewName (Status.get (), Path);
237
+ }
238
+
232
239
namespace {
233
240
234
241
// / A file system according to your operating system.
@@ -639,6 +646,8 @@ class InMemoryFileAdaptor : public File {
639
646
}
640
647
641
648
std::error_code close () override { return {}; }
649
+
650
+ void setPath (const Twine &Path) override { RequestedName = Path.str (); }
642
651
};
643
652
} // namespace
644
653
@@ -1244,7 +1253,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
1244
1253
}
1245
1254
1246
1255
// Use status to make sure the path exists and refers to a directory.
1247
- ErrorOr<Status> S = status (Path, *Result);
1256
+ ErrorOr<Status> S = status (Path, Dir, *Result);
1248
1257
if (!S) {
1249
1258
if (shouldFallBackToExternalFS (S.getError (), Result->E ))
1250
1259
return ExternalFS->dir_begin (Dir, EC);
@@ -1971,47 +1980,68 @@ RedirectingFileSystem::lookupPathImpl(
1971
1980
return make_error_code (llvm::errc::no_such_file_or_directory);
1972
1981
}
1973
1982
1974
- static Status getRedirectedFileStatus (const Twine &Path, bool UseExternalNames,
1983
+ static Status getRedirectedFileStatus (const Twine &OriginalPath,
1984
+ bool UseExternalNames,
1975
1985
Status ExternalStatus) {
1976
1986
Status S = ExternalStatus;
1977
1987
if (!UseExternalNames)
1978
- S = Status::copyWithNewName (S, Path );
1988
+ S = Status::copyWithNewName (S, OriginalPath );
1979
1989
S.IsVFSMapped = true ;
1980
1990
return S;
1981
1991
}
1982
1992
1983
1993
ErrorOr<Status> RedirectingFileSystem::status (
1984
- const Twine &Path, const RedirectingFileSystem::LookupResult &Result) {
1994
+ const Twine &CanonicalPath, const Twine &OriginalPath,
1995
+ const RedirectingFileSystem::LookupResult &Result) {
1985
1996
if (Optional<StringRef> ExtRedirect = Result.getExternalRedirect ()) {
1986
- ErrorOr<Status> S = ExternalFS->status (*ExtRedirect);
1997
+ SmallString<256 > CanonicalRemappedPath ((*ExtRedirect).str ());
1998
+ if (std::error_code EC = makeCanonical (CanonicalRemappedPath))
1999
+ return EC;
2000
+
2001
+ ErrorOr<Status> S = ExternalFS->status (CanonicalRemappedPath);
1987
2002
if (!S)
1988
2003
return S;
2004
+ S = Status::copyWithNewName (*S, *ExtRedirect);
1989
2005
auto *RE = cast<RedirectingFileSystem::RemapEntry>(Result.E );
1990
- return getRedirectedFileStatus (Path, RE-> useExternalName (UseExternalNames) ,
1991
- *S);
2006
+ return getRedirectedFileStatus (OriginalPath ,
2007
+ RE-> useExternalName (UseExternalNames), *S);
1992
2008
}
1993
2009
1994
2010
auto *DE = cast<RedirectingFileSystem::DirectoryEntry>(Result.E );
1995
- return Status::copyWithNewName (DE->getStatus (), Path );
2011
+ return Status::copyWithNewName (DE->getStatus (), CanonicalPath );
1996
2012
}
1997
2013
1998
- ErrorOr<Status> RedirectingFileSystem::status (const Twine &Path_) {
1999
- SmallString<256 > Path;
2000
- Path_.toVector (Path);
2014
+ ErrorOr<Status>
2015
+ RedirectingFileSystem::getExternalStatus (const Twine &CanonicalPath,
2016
+ const Twine &OriginalPath) const {
2017
+ if (auto Result = ExternalFS->status (CanonicalPath)) {
2018
+ return Result.get ().copyWithNewName (Result.get (), OriginalPath);
2019
+ } else {
2020
+ return Result.getError ();
2021
+ }
2022
+ }
2001
2023
2002
- if (std::error_code EC = makeCanonical (Path))
2024
+ ErrorOr<Status> RedirectingFileSystem::status (const Twine &OriginalPath) {
2025
+ SmallString<256 > CanonicalPath;
2026
+ OriginalPath.toVector (CanonicalPath);
2027
+
2028
+ if (std::error_code EC = makeCanonical (CanonicalPath))
2003
2029
return EC;
2004
2030
2005
- ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath (Path);
2031
+ ErrorOr<RedirectingFileSystem::LookupResult> Result =
2032
+ lookupPath (CanonicalPath);
2006
2033
if (!Result) {
2007
- if (shouldFallBackToExternalFS (Result.getError ()))
2008
- return ExternalFS->status (Path);
2034
+ if (shouldFallBackToExternalFS (Result.getError ())) {
2035
+ return getExternalStatus (CanonicalPath, OriginalPath);
2036
+ }
2009
2037
return Result.getError ();
2010
2038
}
2011
2039
2012
- ErrorOr<Status> S = status (Path, *Result);
2013
- if (!S && shouldFallBackToExternalFS (S.getError (), Result->E ))
2014
- S = ExternalFS->status (Path);
2040
+ ErrorOr<Status> S = status (CanonicalPath, OriginalPath, *Result);
2041
+ if (!S && shouldFallBackToExternalFS (S.getError (), Result->E )) {
2042
+ return getExternalStatus (CanonicalPath, OriginalPath);
2043
+ }
2044
+
2015
2045
return S;
2016
2046
}
2017
2047
@@ -2036,35 +2066,58 @@ class FileWithFixedStatus : public File {
2036
2066
}
2037
2067
2038
2068
std::error_code close () override { return InnerFile->close (); }
2069
+
2070
+ void setPath (const Twine &Path) override { S = S.copyWithNewName (S, Path); }
2039
2071
};
2040
2072
2041
2073
} // namespace
2042
2074
2043
2075
ErrorOr<std::unique_ptr<File>>
2044
- RedirectingFileSystem::openFileForRead ( const Twine &Path_ ) {
2045
- SmallString< 256 > Path;
2046
- Path_. toVector (Path) ;
2076
+ File::getWithPath (ErrorOr<std::unique_ptr<File>> Result, const Twine &P ) {
2077
+ if (!Result)
2078
+ return Result ;
2047
2079
2048
- if (std::error_code EC = makeCanonical (Path))
2080
+ auto F = std::move (*Result);
2081
+ auto Name = F->getName ();
2082
+ if (Name && Name.get () != P.str ())
2083
+ F->setPath (P);
2084
+ return F;
2085
+ }
2086
+
2087
+ ErrorOr<std::unique_ptr<File>>
2088
+ RedirectingFileSystem::openFileForRead (const Twine &OriginalPath) {
2089
+ SmallString<256 > CanonicalPath;
2090
+ OriginalPath.toVector (CanonicalPath);
2091
+
2092
+ if (std::error_code EC = makeCanonical (CanonicalPath))
2049
2093
return EC;
2050
2094
2051
- ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath (Path);
2095
+ ErrorOr<RedirectingFileSystem::LookupResult> Result =
2096
+ lookupPath (CanonicalPath);
2052
2097
if (!Result) {
2053
2098
if (shouldFallBackToExternalFS (Result.getError ()))
2054
- return ExternalFS->openFileForRead (Path);
2099
+ return File::getWithPath (ExternalFS->openFileForRead (CanonicalPath),
2100
+ OriginalPath);
2101
+
2055
2102
return Result.getError ();
2056
2103
}
2057
2104
2058
2105
if (!Result->getExternalRedirect ()) // FIXME: errc::not_a_file?
2059
2106
return make_error_code (llvm::errc::invalid_argument);
2060
2107
2061
2108
StringRef ExtRedirect = *Result->getExternalRedirect ();
2109
+ SmallString<256 > CanonicalRemappedPath (ExtRedirect.str ());
2110
+ if (std::error_code EC = makeCanonical (CanonicalRemappedPath))
2111
+ return EC;
2112
+
2062
2113
auto *RE = cast<RedirectingFileSystem::RemapEntry>(Result->E );
2063
2114
2064
- auto ExternalFile = ExternalFS->openFileForRead (ExtRedirect);
2115
+ auto ExternalFile = File::getWithPath (
2116
+ ExternalFS->openFileForRead (CanonicalRemappedPath), ExtRedirect);
2065
2117
if (!ExternalFile) {
2066
2118
if (shouldFallBackToExternalFS (ExternalFile.getError (), Result->E ))
2067
- return ExternalFS->openFileForRead (Path);
2119
+ return File::getWithPath (ExternalFS->openFileForRead (CanonicalPath),
2120
+ OriginalPath);
2068
2121
return ExternalFile;
2069
2122
}
2070
2123
@@ -2074,7 +2127,7 @@ RedirectingFileSystem::openFileForRead(const Twine &Path_) {
2074
2127
2075
2128
// FIXME: Update the status with the name and VFSMapped.
2076
2129
Status S = getRedirectedFileStatus (
2077
- Path , RE->useExternalName (UseExternalNames), *ExternalStatus);
2130
+ OriginalPath , RE->useExternalName (UseExternalNames), *ExternalStatus);
2078
2131
return std::unique_ptr<File>(
2079
2132
std::make_unique<FileWithFixedStatus>(std::move (*ExternalFile), S));
2080
2133
}
0 commit comments