@@ -1073,6 +1073,19 @@ std::error_code RedirectingFileSystem::isLocal(const Twine &Path,
1073
1073
return ExternalFS->isLocal (Path, Result);
1074
1074
}
1075
1075
1076
+ std::error_code RedirectingFileSystem::makeAbsolute (SmallVectorImpl<char > &Path) const {
1077
+ if (llvm::sys::path::is_absolute (Path, llvm::sys::path::Style::posix) ||
1078
+ llvm::sys::path::is_absolute (Path, llvm::sys::path::Style::windows))
1079
+ return {};
1080
+
1081
+ auto WorkingDir = getCurrentWorkingDirectory ();
1082
+ if (!WorkingDir)
1083
+ return WorkingDir.getError ();
1084
+
1085
+ llvm::sys::fs::make_absolute (WorkingDir.get (), Path);
1086
+ return {};
1087
+ }
1088
+
1076
1089
directory_iterator RedirectingFileSystem::dir_begin (const Twine &Dir,
1077
1090
std::error_code &EC) {
1078
1091
ErrorOr<RedirectingFileSystem::Entry *> E = lookupPath (Dir);
@@ -1428,21 +1441,31 @@ class llvm::vfs::RedirectingFileSystemParser {
1428
1441
return nullptr ;
1429
1442
}
1430
1443
1431
- if (IsRootEntry && !sys::path::is_absolute (Name)) {
1432
- assert (NameValueNode && " Name presence should be checked earlier" );
1433
- error (NameValueNode,
1434
- " entry with relative path at the root level is not discoverable" );
1435
- return nullptr ;
1444
+ sys::path::Style path_style = sys::path::Style::native;
1445
+ if (IsRootEntry) {
1446
+ // VFS root entries may be in either Posix or Windows style. Figure out
1447
+ // which style we have, and use it consistently.
1448
+ if (sys::path::is_absolute (Name, sys::path::Style::posix)) {
1449
+ path_style = sys::path::Style::posix;
1450
+ } else if (sys::path::is_absolute (Name, sys::path::Style::windows)) {
1451
+ path_style = sys::path::Style::windows;
1452
+ } else {
1453
+ assert (NameValueNode && " Name presence should be checked earlier" );
1454
+ error (NameValueNode,
1455
+ " entry with relative path at the root level is not discoverable" );
1456
+ return nullptr ;
1457
+ }
1436
1458
}
1437
1459
1438
1460
// Remove trailing slash(es), being careful not to remove the root path
1439
1461
StringRef Trimmed (Name);
1440
- size_t RootPathLen = sys::path::root_path (Trimmed).size ();
1462
+ size_t RootPathLen = sys::path::root_path (Trimmed, path_style ).size ();
1441
1463
while (Trimmed.size () > RootPathLen &&
1442
- sys::path::is_separator (Trimmed.back ()))
1464
+ sys::path::is_separator (Trimmed.back (), path_style ))
1443
1465
Trimmed = Trimmed.slice (0 , Trimmed.size () - 1 );
1466
+
1444
1467
// Get the last component
1445
- StringRef LastComponent = sys::path::filename (Trimmed);
1468
+ StringRef LastComponent = sys::path::filename (Trimmed, path_style );
1446
1469
1447
1470
std::unique_ptr<RedirectingFileSystem::Entry> Result;
1448
1471
switch (Kind) {
@@ -1460,12 +1483,12 @@ class llvm::vfs::RedirectingFileSystemParser {
1460
1483
break ;
1461
1484
}
1462
1485
1463
- StringRef Parent = sys::path::parent_path (Trimmed);
1486
+ StringRef Parent = sys::path::parent_path (Trimmed, path_style );
1464
1487
if (Parent.empty ())
1465
1488
return Result;
1466
1489
1467
1490
// if 'name' contains multiple components, create implicit directory entries
1468
- for (sys::path::reverse_iterator I = sys::path::rbegin (Parent),
1491
+ for (sys::path::reverse_iterator I = sys::path::rbegin (Parent, path_style ),
1469
1492
E = sys::path::rend (Parent);
1470
1493
I != E; ++I) {
1471
1494
std::vector<std::unique_ptr<RedirectingFileSystem::Entry>> Entries;
0 commit comments