@@ -193,6 +193,7 @@ class RealFile : public File {
193
193
bool RequiresNullTerminator,
194
194
bool IsVolatile) override ;
195
195
std::error_code close () override ;
196
+ void setPath (const Twine &Path) override ;
196
197
};
197
198
198
199
} // namespace
@@ -228,6 +229,12 @@ std::error_code RealFile::close() {
228
229
return EC;
229
230
}
230
231
232
+ void RealFile::setPath (const Twine &Path) {
233
+ RealName = Path.str ();
234
+ if (auto Status = status ())
235
+ S = Status.get ().copyWithNewName (Status.get (), Path);
236
+ }
237
+
231
238
namespace {
232
239
233
240
// / A file system according to your operating system.
@@ -638,6 +645,8 @@ class InMemoryFileAdaptor : public File {
638
645
}
639
646
640
647
std::error_code close () override { return {}; }
648
+
649
+ void setPath (const Twine &Path) override { RequestedName = Path.str (); }
641
650
};
642
651
} // namespace
643
652
@@ -1207,7 +1216,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
1207
1216
}
1208
1217
1209
1218
// Use status to make sure the path exists and refers to a directory.
1210
- ErrorOr<Status> S = status (Path, *Result);
1219
+ ErrorOr<Status> S = status (Path, Dir, *Result);
1211
1220
if (!S) {
1212
1221
if (shouldFallBackToExternalFS (S.getError (), Result->E ))
1213
1222
return ExternalFS->dir_begin (Dir, EC);
@@ -1933,47 +1942,68 @@ RedirectingFileSystem::lookupPathImpl(
1933
1942
return make_error_code (llvm::errc::no_such_file_or_directory);
1934
1943
}
1935
1944
1936
- static Status getRedirectedFileStatus (const Twine &Path, bool UseExternalNames,
1945
+ static Status getRedirectedFileStatus (const Twine &OriginalPath,
1946
+ bool UseExternalNames,
1937
1947
Status ExternalStatus) {
1938
1948
Status S = ExternalStatus;
1939
1949
if (!UseExternalNames)
1940
- S = Status::copyWithNewName (S, Path );
1950
+ S = Status::copyWithNewName (S, OriginalPath );
1941
1951
S.IsVFSMapped = true ;
1942
1952
return S;
1943
1953
}
1944
1954
1945
1955
ErrorOr<Status> RedirectingFileSystem::status (
1946
- const Twine &Path, const RedirectingFileSystem::LookupResult &Result) {
1956
+ const Twine &CanonicalPath, const Twine &OriginalPath,
1957
+ const RedirectingFileSystem::LookupResult &Result) {
1947
1958
if (Optional<StringRef> ExtRedirect = Result.getExternalRedirect ()) {
1948
- ErrorOr<Status> S = ExternalFS->status (*ExtRedirect);
1959
+ SmallString<256 > CanonicalRemappedPath ((*ExtRedirect).str ());
1960
+ if (std::error_code EC = makeCanonical (CanonicalRemappedPath))
1961
+ return EC;
1962
+
1963
+ ErrorOr<Status> S = ExternalFS->status (CanonicalRemappedPath);
1949
1964
if (!S)
1950
1965
return S;
1966
+ S = Status::copyWithNewName (*S, *ExtRedirect);
1951
1967
auto *RE = cast<RedirectingFileSystem::RemapEntry>(Result.E );
1952
- return getRedirectedFileStatus (Path, RE-> useExternalName (UseExternalNames) ,
1953
- *S);
1968
+ return getRedirectedFileStatus (OriginalPath ,
1969
+ RE-> useExternalName (UseExternalNames), *S);
1954
1970
}
1955
1971
1956
1972
auto *DE = cast<RedirectingFileSystem::DirectoryEntry>(Result.E );
1957
- return Status::copyWithNewName (DE->getStatus (), Path );
1973
+ return Status::copyWithNewName (DE->getStatus (), CanonicalPath );
1958
1974
}
1959
1975
1960
- ErrorOr<Status> RedirectingFileSystem::status (const Twine &Path_) {
1961
- SmallString<256 > Path;
1962
- Path_.toVector (Path);
1976
+ ErrorOr<Status>
1977
+ RedirectingFileSystem::getExternalStatus (const Twine &CanonicalPath,
1978
+ const Twine &OriginalPath) const {
1979
+ if (auto Result = ExternalFS->status (CanonicalPath)) {
1980
+ return Result.get ().copyWithNewName (Result.get (), OriginalPath);
1981
+ } else {
1982
+ return Result.getError ();
1983
+ }
1984
+ }
1963
1985
1964
- if (std::error_code EC = makeCanonical (Path))
1986
+ ErrorOr<Status> RedirectingFileSystem::status (const Twine &OriginalPath) {
1987
+ SmallString<256 > CanonicalPath;
1988
+ OriginalPath.toVector (CanonicalPath);
1989
+
1990
+ if (std::error_code EC = makeCanonical (CanonicalPath))
1965
1991
return EC;
1966
1992
1967
- ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath (Path);
1993
+ ErrorOr<RedirectingFileSystem::LookupResult> Result =
1994
+ lookupPath (CanonicalPath);
1968
1995
if (!Result) {
1969
- if (shouldFallBackToExternalFS (Result.getError ()))
1970
- return ExternalFS->status (Path);
1996
+ if (shouldFallBackToExternalFS (Result.getError ())) {
1997
+ return getExternalStatus (CanonicalPath, OriginalPath);
1998
+ }
1971
1999
return Result.getError ();
1972
2000
}
1973
2001
1974
- ErrorOr<Status> S = status (Path, *Result);
1975
- if (!S && shouldFallBackToExternalFS (S.getError (), Result->E ))
1976
- S = ExternalFS->status (Path);
2002
+ ErrorOr<Status> S = status (CanonicalPath, OriginalPath, *Result);
2003
+ if (!S && shouldFallBackToExternalFS (S.getError (), Result->E )) {
2004
+ return getExternalStatus (CanonicalPath, OriginalPath);
2005
+ }
2006
+
1977
2007
return S;
1978
2008
}
1979
2009
@@ -1998,35 +2028,58 @@ class FileWithFixedStatus : public File {
1998
2028
}
1999
2029
2000
2030
std::error_code close () override { return InnerFile->close (); }
2031
+
2032
+ void setPath (const Twine &Path) override { S = S.copyWithNewName (S, Path); }
2001
2033
};
2002
2034
2003
2035
} // namespace
2004
2036
2005
2037
ErrorOr<std::unique_ptr<File>>
2006
- RedirectingFileSystem::openFileForRead ( const Twine &Path_ ) {
2007
- SmallString< 256 > Path;
2008
- Path_. toVector (Path) ;
2038
+ File::getWithPath (ErrorOr<std::unique_ptr<File>> Result, const Twine &P ) {
2039
+ if (!Result)
2040
+ return Result ;
2009
2041
2010
- if (std::error_code EC = makeCanonical (Path))
2042
+ ErrorOr<std::unique_ptr<File>> F = std::move (*Result);
2043
+ auto Name = F->get ()->getName ();
2044
+ if (Name && Name.get () != P.str ())
2045
+ F->get ()->setPath (P);
2046
+ return F;
2047
+ }
2048
+
2049
+ ErrorOr<std::unique_ptr<File>>
2050
+ RedirectingFileSystem::openFileForRead (const Twine &OriginalPath) {
2051
+ SmallString<256 > CanonicalPath;
2052
+ OriginalPath.toVector (CanonicalPath);
2053
+
2054
+ if (std::error_code EC = makeCanonical (CanonicalPath))
2011
2055
return EC;
2012
2056
2013
- ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath (Path);
2057
+ ErrorOr<RedirectingFileSystem::LookupResult> Result =
2058
+ lookupPath (CanonicalPath);
2014
2059
if (!Result) {
2015
2060
if (shouldFallBackToExternalFS (Result.getError ()))
2016
- return ExternalFS->openFileForRead (Path);
2061
+ return File::getWithPath (ExternalFS->openFileForRead (CanonicalPath),
2062
+ OriginalPath);
2063
+
2017
2064
return Result.getError ();
2018
2065
}
2019
2066
2020
2067
if (!Result->getExternalRedirect ()) // FIXME: errc::not_a_file?
2021
2068
return make_error_code (llvm::errc::invalid_argument);
2022
2069
2023
2070
StringRef ExtRedirect = *Result->getExternalRedirect ();
2071
+ SmallString<256 > CanonicalRemappedPath (ExtRedirect.str ());
2072
+ if (std::error_code EC = makeCanonical (CanonicalRemappedPath))
2073
+ return EC;
2074
+
2024
2075
auto *RE = cast<RedirectingFileSystem::RemapEntry>(Result->E );
2025
2076
2026
- auto ExternalFile = ExternalFS->openFileForRead (ExtRedirect);
2077
+ auto ExternalFile = File::getWithPath (
2078
+ ExternalFS->openFileForRead (CanonicalRemappedPath), ExtRedirect);
2027
2079
if (!ExternalFile) {
2028
2080
if (shouldFallBackToExternalFS (ExternalFile.getError (), Result->E ))
2029
- return ExternalFS->openFileForRead (Path);
2081
+ return File::getWithPath (ExternalFS->openFileForRead (CanonicalPath),
2082
+ OriginalPath);
2030
2083
return ExternalFile;
2031
2084
}
2032
2085
@@ -2036,7 +2089,7 @@ RedirectingFileSystem::openFileForRead(const Twine &Path_) {
2036
2089
2037
2090
// FIXME: Update the status with the name and VFSMapped.
2038
2091
Status S = getRedirectedFileStatus (
2039
- Path , RE->useExternalName (UseExternalNames), *ExternalStatus);
2092
+ OriginalPath , RE->useExternalName (UseExternalNames), *ExternalStatus);
2040
2093
return std::unique_ptr<File>(
2041
2094
std::make_unique<FileWithFixedStatus>(std::move (*ExternalFile), S));
2042
2095
}
0 commit comments