Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 16fe853

Browse files
committedOct 28, 2019
Merge commit 'refs/am/changes/f77cf422e7ade423f73209d65ccf94bd1aa6f21c_swift/master' into HEAD
2 parents 3e6fcef + f77cf42 commit 16fe853

File tree

9 files changed

+327
-38
lines changed

9 files changed

+327
-38
lines changed
 

‎clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -536,11 +536,11 @@ void CGDebugInfo::CreateCompileUnit() {
536536
// file to determine the real absolute path for the file.
537537
std::string MainFileDir;
538538
if (const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
539-
MainFileDir = remapDIPath(MainFile->getDir()->getName());
540-
if (MainFileDir != ".") {
539+
MainFileDir = MainFile->getDir()->getName();
540+
if (!llvm::sys::path::is_absolute(MainFileName)) {
541541
llvm::SmallString<1024> MainFileDirSS(MainFileDir);
542542
llvm::sys::path::append(MainFileDirSS, MainFileName);
543-
MainFileName = MainFileDirSS.str();
543+
MainFileName = llvm::sys::path::remove_leading_dotslash(MainFileDirSS);
544544
}
545545
// If the main file name provided is identical to the input file name, and
546546
// if the input file is a preprocessed source, use the module name for

‎clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3400,7 +3400,6 @@ static void RenderDebugOptions(const ToolChain &TC, const Driver &D,
34003400
Args.getLastArg(options::OPT_ggnu_pubnames, options::OPT_gno_gnu_pubnames,
34013401
options::OPT_gpubnames, options::OPT_gno_pubnames);
34023402
if (DwarfFission != DwarfFissionKind::None ||
3403-
DebuggerTuning == llvm::DebuggerKind::LLDB ||
34043403
(PubnamesArg && checkDebugInfoOption(PubnamesArg, Args, D, TC)))
34053404
if (!PubnamesArg ||
34063405
(!PubnamesArg->getOption().matches(options::OPT_gno_gnu_pubnames) &&

‎clang/test/Driver/debug-options.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@
193193
// RUN: %clang -### -c %s 2>&1 | FileCheck -check-prefix=NORNGBSE %s
194194
// RUN: %clang -### -c -fdebug-ranges-base-address -fno-debug-ranges-base-address %s 2>&1 | FileCheck -check-prefix=NORNGBSE %s
195195
//
196-
// RUN: %clang -### -c -glldb %s 2>&1 | FileCheck -check-prefix=GPUB %s
196+
// RUN: %clang -### -c -glldb %s 2>&1 | FileCheck -check-prefix=NOPUB %s
197197
// RUN: %clang -### -c -glldb -gno-pubnames %s 2>&1 | FileCheck -check-prefix=NOPUB %s
198198
//
199199
// RUN: %clang -### -c -gdwarf-aranges %s 2>&1 | FileCheck -check-prefix=GARANGE %s
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// REQUIRES: asserts
2+
3+
// Modules:
4+
// RUN: rm -rf %t
5+
// RUN: mkdir %t
6+
// RUN: cd %t
7+
8+
// RUN: %clang_cc1 -fmodule-format=obj -emit-pch \
9+
// RUN: -triple %itanium_abi_triple \
10+
// RUN: -fdebug-prefix-map=%t=BUILD \
11+
// RUN: -fdebug-prefix-map=%S=SOURCE \
12+
// RUN: -o %t/prefix.ll %S/debug-info-limited-struct.h \
13+
// RUN: -mllvm -debug-only=pchcontainer &>%t-container.ll
14+
// RUN: cat %t-container.ll | FileCheck %s
15+
16+
// CHECK: distinct !DICompileUnit(
17+
// CHECK-SAME: language: DW_LANG_C99,
18+
// CHECK-SAME: file: ![[FILE:[0-9]+]],
19+
// CHECK: ![[FILE]] = !DIFile(
20+
// CHECK-SAME: filename: "SOURCE/debug-info-limited-struct.h",
21+
// CHECK-SAME: directory: "BUILD"
22+

‎llvm/include/llvm/Support/VirtualFileSystem.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,15 +343,24 @@ class OverlayFileSystem : public FileSystem {
343343

344344
using iterator = FileSystemList::reverse_iterator;
345345
using const_iterator = FileSystemList::const_reverse_iterator;
346+
using reverse_iterator = FileSystemList::iterator;
347+
using const_reverse_iterator = FileSystemList::const_iterator;
346348

347349
/// Get an iterator pointing to the most recently added file system.
348350
iterator overlays_begin() { return FSList.rbegin(); }
349351
const_iterator overlays_begin() const { return FSList.rbegin(); }
350352

351-
/// Get an iterator pointing one-past the least recently added file
352-
/// system.
353+
/// Get an iterator pointing one-past the least recently added file system.
353354
iterator overlays_end() { return FSList.rend(); }
354355
const_iterator overlays_end() const { return FSList.rend(); }
356+
357+
/// Get an iterator pointing to the least recently added file system.
358+
reverse_iterator overlays_rbegin() { return FSList.begin(); }
359+
const_reverse_iterator overlays_rbegin() const { return FSList.begin(); }
360+
361+
/// Get an iterator pointing one-past the most recently added file system.
362+
reverse_iterator overlays_rend() { return FSList.end(); }
363+
const_reverse_iterator overlays_rend() const { return FSList.end(); }
355364
};
356365

357366
/// By default, this delegates all calls to the underlying file system. This
@@ -638,9 +647,19 @@ class RedirectingFileSystem : public vfs::FileSystem {
638647
friend class VFSFromYamlDirIterImpl;
639648
friend class RedirectingFileSystemParser;
640649

650+
bool shouldUseExternalFS() const {
651+
return ExternalFSValidWD && IsFallthrough;
652+
}
653+
641654
/// The root(s) of the virtual file system.
642655
std::vector<std::unique_ptr<Entry>> Roots;
643656

657+
/// The current working directory of the file system.
658+
std::string WorkingDirectory;
659+
660+
/// Whether the current working directory is valid for the external FS.
661+
bool ExternalFSValidWD = false;
662+
644663
/// The file system to use for external references.
645664
IntrusiveRefCntPtr<FileSystem> ExternalFS;
646665

@@ -680,8 +699,7 @@ class RedirectingFileSystem : public vfs::FileSystem {
680699
true;
681700
#endif
682701

683-
RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS)
684-
: ExternalFS(std::move(ExternalFS)) {}
702+
RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> ExternalFS);
685703

686704
/// Looks up the path <tt>[Start, End)</tt> in \p From, possibly
687705
/// recursing into the contents of \p From if it is a directory.

‎llvm/lib/Support/Path.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -855,11 +855,11 @@ void make_absolute(const Twine &current_directory,
855855
StringRef p(path.data(), path.size());
856856

857857
bool rootDirectory = path::has_root_directory(p);
858-
bool rootName =
859-
(real_style(Style::native) != Style::windows) || path::has_root_name(p);
858+
bool rootName = path::has_root_name(p);
860859

861860
// Already absolute.
862-
if (rootName && rootDirectory)
861+
if ((rootName || real_style(Style::native) != Style::windows) &&
862+
rootDirectory)
863863
return;
864864

865865
// All of the following conditions will need the current directory.

‎llvm/lib/Support/VirtualFileSystem.cpp

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,16 @@ std::error_code InMemoryFileSystem::isLocal(const Twine &Path, bool &Result) {
986986
// RedirectingFileSystem implementation
987987
//===-----------------------------------------------------------------------===/
988988

989+
RedirectingFileSystem::RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> FS)
990+
: ExternalFS(std::move(FS)) {
991+
if (ExternalFS)
992+
if (auto ExternalWorkingDirectory =
993+
ExternalFS->getCurrentWorkingDirectory()) {
994+
WorkingDirectory = *ExternalWorkingDirectory;
995+
ExternalFSValidWD = true;
996+
}
997+
}
998+
989999
// FIXME: reuse implementation common with OverlayFSDirIterImpl as these
9901000
// iterators are conceptually similar.
9911001
class llvm::vfs::VFSFromYamlDirIterImpl
@@ -1032,12 +1042,27 @@ class llvm::vfs::VFSFromYamlDirIterImpl
10321042

10331043
llvm::ErrorOr<std::string>
10341044
RedirectingFileSystem::getCurrentWorkingDirectory() const {
1035-
return ExternalFS->getCurrentWorkingDirectory();
1045+
return WorkingDirectory;
10361046
}
10371047

10381048
std::error_code
10391049
RedirectingFileSystem::setCurrentWorkingDirectory(const Twine &Path) {
1040-
return ExternalFS->setCurrentWorkingDirectory(Path);
1050+
// Don't change the working directory if the path doesn't exist.
1051+
if (!exists(Path))
1052+
return errc::no_such_file_or_directory;
1053+
1054+
// Always change the external FS but ignore its result.
1055+
if (ExternalFS) {
1056+
auto EC = ExternalFS->setCurrentWorkingDirectory(Path);
1057+
ExternalFSValidWD = !static_cast<bool>(EC);
1058+
}
1059+
1060+
SmallString<128> AbsolutePath;
1061+
Path.toVector(AbsolutePath);
1062+
if (std::error_code EC = makeAbsolute(AbsolutePath))
1063+
return EC;
1064+
WorkingDirectory = AbsolutePath.str();
1065+
return {};
10411066
}
10421067

10431068
std::error_code RedirectingFileSystem::isLocal(const Twine &Path,
@@ -1050,7 +1075,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
10501075
ErrorOr<RedirectingFileSystem::Entry *> E = lookupPath(Dir);
10511076
if (!E) {
10521077
EC = E.getError();
1053-
if (IsFallthrough && EC == errc::no_such_file_or_directory)
1078+
if (shouldUseExternalFS() && EC == errc::no_such_file_or_directory)
10541079
return ExternalFS->dir_begin(Dir, EC);
10551080
return {};
10561081
}
@@ -1068,7 +1093,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
10681093
auto *D = cast<RedirectingFileSystem::RedirectingDirectoryEntry>(*E);
10691094
return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>(
10701095
Dir, D->contents_begin(), D->contents_end(),
1071-
/*IterateExternalFS=*/IsFallthrough, *ExternalFS, EC));
1096+
/*IterateExternalFS=*/shouldUseExternalFS(), *ExternalFS, EC));
10721097
}
10731098

10741099
void RedirectingFileSystem::setExternalContentsPrefixDir(StringRef PrefixDir) {
@@ -1218,7 +1243,7 @@ class llvm::vfs::RedirectingFileSystemParser {
12181243
}
12191244

12201245
auto *DE =
1221-
dyn_cast<RedirectingFileSystem::RedirectingDirectoryEntry>(ParentEntry);
1246+
cast<RedirectingFileSystem::RedirectingDirectoryEntry>(ParentEntry);
12221247
DE->addContent(std::move(E));
12231248
return DE->getLastContent();
12241249
}
@@ -1229,9 +1254,7 @@ class llvm::vfs::RedirectingFileSystemParser {
12291254
StringRef Name = SrcE->getName();
12301255
switch (SrcE->getKind()) {
12311256
case RedirectingFileSystem::EK_Directory: {
1232-
auto *DE =
1233-
dyn_cast<RedirectingFileSystem::RedirectingDirectoryEntry>(SrcE);
1234-
assert(DE && "Must be a directory");
1257+
auto *DE = cast<RedirectingFileSystem::RedirectingDirectoryEntry>(SrcE);
12351258
// Empty directories could be present in the YAML as a way to
12361259
// describe a file for a current directory after some of its subdir
12371260
// is parsed. This only leads to redundant walks, ignore it.
@@ -1243,11 +1266,10 @@ class llvm::vfs::RedirectingFileSystemParser {
12431266
break;
12441267
}
12451268
case RedirectingFileSystem::EK_File: {
1246-
auto *FE = dyn_cast<RedirectingFileSystem::RedirectingFileEntry>(SrcE);
1247-
assert(FE && "Must be a file");
12481269
assert(NewParentE && "Parent entry must exist");
1249-
auto *DE = dyn_cast<RedirectingFileSystem::RedirectingDirectoryEntry>(
1250-
NewParentE);
1270+
auto *FE = cast<RedirectingFileSystem::RedirectingFileEntry>(SrcE);
1271+
auto *DE =
1272+
cast<RedirectingFileSystem::RedirectingDirectoryEntry>(NewParentE);
12511273
DE->addContent(
12521274
llvm::make_unique<RedirectingFileSystem::RedirectingFileEntry>(
12531275
Name, FE->getExternalContentsPath(), FE->getUseName()));
@@ -1570,7 +1592,7 @@ RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer,
15701592
RedirectingFileSystemParser P(Stream);
15711593

15721594
std::unique_ptr<RedirectingFileSystem> FS(
1573-
new RedirectingFileSystem(std::move(ExternalFS)));
1595+
new RedirectingFileSystem(ExternalFS));
15741596

15751597
if (!YAMLFilePath.empty()) {
15761598
// Use the YAML path from -ivfsoverlay to compute the dir to be prefixed
@@ -1699,7 +1721,7 @@ ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path,
16991721
ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path) {
17001722
ErrorOr<RedirectingFileSystem::Entry *> Result = lookupPath(Path);
17011723
if (!Result) {
1702-
if (IsFallthrough &&
1724+
if (shouldUseExternalFS() &&
17031725
Result.getError() == llvm::errc::no_such_file_or_directory) {
17041726
return ExternalFS->status(Path);
17051727
}
@@ -1737,7 +1759,7 @@ ErrorOr<std::unique_ptr<File>>
17371759
RedirectingFileSystem::openFileForRead(const Twine &Path) {
17381760
ErrorOr<RedirectingFileSystem::Entry *> E = lookupPath(Path);
17391761
if (!E) {
1740-
if (IsFallthrough &&
1762+
if (shouldUseExternalFS() &&
17411763
E.getError() == llvm::errc::no_such_file_or_directory) {
17421764
return ExternalFS->openFileForRead(Path);
17431765
}
@@ -1768,7 +1790,7 @@ RedirectingFileSystem::getRealPath(const Twine &Path,
17681790
SmallVectorImpl<char> &Output) const {
17691791
ErrorOr<RedirectingFileSystem::Entry *> Result = lookupPath(Path);
17701792
if (!Result) {
1771-
if (IsFallthrough &&
1793+
if (shouldUseExternalFS() &&
17721794
Result.getError() == llvm::errc::no_such_file_or_directory) {
17731795
return ExternalFS->getRealPath(Path, Output);
17741796
}
@@ -1781,8 +1803,8 @@ RedirectingFileSystem::getRealPath(const Twine &Path,
17811803
}
17821804
// Even if there is a directory entry, fall back to ExternalFS if allowed,
17831805
// because directories don't have a single external contents path.
1784-
return IsFallthrough ? ExternalFS->getRealPath(Path, Output)
1785-
: llvm::errc::invalid_argument;
1806+
return shouldUseExternalFS() ? ExternalFS->getRealPath(Path, Output)
1807+
: llvm::errc::invalid_argument;
17861808
}
17871809

17881810
IntrusiveRefCntPtr<FileSystem>

‎llvm/unittests/Support/Path.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,19 @@ TEST(Support, Path) {
185185
path::native(*i, temp_store);
186186
}
187187

188-
SmallString<32> Relative("foo.cpp");
189-
sys::fs::make_absolute("/root", Relative);
190-
Relative[5] = '/'; // Fix up windows paths.
191-
ASSERT_EQ("/root/foo.cpp", Relative);
188+
{
189+
SmallString<32> Relative("foo.cpp");
190+
sys::fs::make_absolute("/root", Relative);
191+
Relative[5] = '/'; // Fix up windows paths.
192+
ASSERT_EQ("/root/foo.cpp", Relative);
193+
}
194+
195+
{
196+
SmallString<32> Relative("foo.cpp");
197+
sys::fs::make_absolute("//root", Relative);
198+
Relative[6] = '/'; // Fix up windows paths.
199+
ASSERT_EQ("//root/foo.cpp", Relative);
200+
}
192201
}
193202

194203
TEST(Support, FilenameParent) {

‎llvm/unittests/Support/VirtualFileSystemTest.cpp

Lines changed: 223 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ struct DummyFile : public vfs::File {
4141
class DummyFileSystem : public vfs::FileSystem {
4242
int FSID; // used to produce UniqueIDs
4343
int FileID; // used to produce UniqueIDs
44+
std::string WorkingDirectory;
4445
std::map<std::string, vfs::Status> FilesAndDirs;
46+
typedef std::map<std::string, vfs::Status>::const_iterator const_iterator;
4547

4648
static int getNextFSID() {
4749
static int Count = 0;
@@ -52,8 +54,7 @@ class DummyFileSystem : public vfs::FileSystem {
5254
DummyFileSystem() : FSID(getNextFSID()), FileID(0) {}
5355

5456
ErrorOr<vfs::Status> status(const Twine &Path) override {
55-
std::map<std::string, vfs::Status>::iterator I =
56-
FilesAndDirs.find(Path.str());
57+
auto I = findEntry(Path);
5758
if (I == FilesAndDirs.end())
5859
return make_error_code(llvm::errc::no_such_file_or_directory);
5960
return I->second;
@@ -66,15 +67,16 @@ class DummyFileSystem : public vfs::FileSystem {
6667
return S.getError();
6768
}
6869
llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override {
69-
return std::string();
70+
return WorkingDirectory;
7071
}
7172
std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
73+
WorkingDirectory = Path.str();
7274
return std::error_code();
7375
}
7476
// Map any symlink to "/symlink".
7577
std::error_code getRealPath(const Twine &Path,
7678
SmallVectorImpl<char> &Output) const override {
77-
auto I = FilesAndDirs.find(Path.str());
79+
auto I = findEntry(Path);
7880
if (I == FilesAndDirs.end())
7981
return make_error_code(llvm::errc::no_such_file_or_directory);
8082
if (I->second.isSymlink()) {
@@ -136,6 +138,15 @@ class DummyFileSystem : public vfs::FileSystem {
136138
FilesAndDirs[Path] = Status;
137139
}
138140

141+
const_iterator findEntry(const Twine &Path) const {
142+
SmallString<128> P;
143+
Path.toVector(P);
144+
std::error_code EC = makeAbsolute(P);
145+
assert(!EC);
146+
(void)EC;
147+
return FilesAndDirs.find(P.str());
148+
}
149+
139150
void addRegularFile(StringRef Path, sys::fs::perms Perms = sys::fs::all_all) {
140151
vfs::Status S(Path, UniqueID(FSID, FileID++),
141152
std::chrono::system_clock::now(), 0, 0, 1024,
@@ -158,6 +169,12 @@ class DummyFileSystem : public vfs::FileSystem {
158169
}
159170
};
160171

172+
class ErrorDummyFileSystem : public DummyFileSystem {
173+
std::error_code setCurrentWorkingDirectory(const Twine &Path) override {
174+
return llvm::errc::no_such_file_or_directory;
175+
}
176+
};
177+
161178
/// Replace back-slashes by front-slashes.
162179
std::string getPosixPath(std::string S) {
163180
SmallString<128> Result;
@@ -342,6 +359,57 @@ TEST(VirtualFileSystemTest, MergedDirPermissions) {
342359
EXPECT_EQ(0200, Status->getPermissions());
343360
}
344361

362+
TEST(VirtualFileSystemTest, OverlayIterator) {
363+
IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
364+
Lower->addRegularFile("/foo");
365+
IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem());
366+
367+
IntrusiveRefCntPtr<vfs::OverlayFileSystem> O(
368+
new vfs::OverlayFileSystem(Lower));
369+
O->pushOverlay(Upper);
370+
371+
ErrorOr<vfs::Status> Status((std::error_code()));
372+
{
373+
auto it = O->overlays_begin();
374+
auto end = O->overlays_end();
375+
376+
EXPECT_NE(it, end);
377+
378+
Status = (*it)->status("/foo");
379+
ASSERT_TRUE(Status.getError());
380+
381+
it++;
382+
EXPECT_NE(it, end);
383+
384+
Status = (*it)->status("/foo");
385+
ASSERT_FALSE(Status.getError());
386+
EXPECT_TRUE(Status->exists());
387+
388+
it++;
389+
EXPECT_EQ(it, end);
390+
}
391+
392+
{
393+
auto it = O->overlays_rbegin();
394+
auto end = O->overlays_rend();
395+
396+
EXPECT_NE(it, end);
397+
398+
Status = (*it)->status("/foo");
399+
ASSERT_FALSE(Status.getError());
400+
EXPECT_TRUE(Status->exists());
401+
402+
it++;
403+
EXPECT_NE(it, end);
404+
405+
Status = (*it)->status("/foo");
406+
ASSERT_TRUE(Status.getError());
407+
408+
it++;
409+
EXPECT_EQ(it, end);
410+
}
411+
}
412+
345413
namespace {
346414
struct ScopedDir {
347415
SmallString<128> Path;
@@ -1943,3 +2011,154 @@ TEST_F(VFSFromYAMLTest, GetRealPath) {
19432011
EXPECT_EQ(FS->getRealPath("/non_existing", RealPath),
19442012
errc::no_such_file_or_directory);
19452013
}
2014+
2015+
TEST_F(VFSFromYAMLTest, WorkingDirectory) {
2016+
IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
2017+
Lower->addDirectory("//root/");
2018+
Lower->addDirectory("//root/foo");
2019+
Lower->addRegularFile("//root/foo/a");
2020+
Lower->addRegularFile("//root/foo/b");
2021+
IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
2022+
"{ 'use-external-names': false,\n"
2023+
" 'roots': [\n"
2024+
"{\n"
2025+
" 'type': 'directory',\n"
2026+
" 'name': '//root/bar',\n"
2027+
" 'contents': [ {\n"
2028+
" 'type': 'file',\n"
2029+
" 'name': 'a',\n"
2030+
" 'external-contents': '//root/foo/a'\n"
2031+
" }\n"
2032+
" ]\n"
2033+
"}\n"
2034+
"]\n"
2035+
"}",
2036+
Lower);
2037+
ASSERT_TRUE(FS.get() != nullptr);
2038+
std::error_code EC = FS->setCurrentWorkingDirectory("//root/bar");
2039+
ASSERT_FALSE(EC);
2040+
2041+
llvm::ErrorOr<std::string> WorkingDir = FS->getCurrentWorkingDirectory();
2042+
ASSERT_TRUE(WorkingDir);
2043+
EXPECT_EQ(*WorkingDir, "//root/bar");
2044+
2045+
llvm::ErrorOr<vfs::Status> Status = FS->status("./a");
2046+
ASSERT_FALSE(Status.getError());
2047+
EXPECT_TRUE(Status->isStatusKnown());
2048+
EXPECT_FALSE(Status->isDirectory());
2049+
EXPECT_TRUE(Status->isRegularFile());
2050+
EXPECT_FALSE(Status->isSymlink());
2051+
EXPECT_FALSE(Status->isOther());
2052+
EXPECT_TRUE(Status->exists());
2053+
2054+
EC = FS->setCurrentWorkingDirectory("bogus");
2055+
ASSERT_TRUE(EC);
2056+
WorkingDir = FS->getCurrentWorkingDirectory();
2057+
ASSERT_TRUE(WorkingDir);
2058+
EXPECT_EQ(*WorkingDir, "//root/bar");
2059+
2060+
EC = FS->setCurrentWorkingDirectory("//root/");
2061+
ASSERT_FALSE(EC);
2062+
WorkingDir = FS->getCurrentWorkingDirectory();
2063+
ASSERT_TRUE(WorkingDir);
2064+
EXPECT_EQ(*WorkingDir, "//root/");
2065+
2066+
EC = FS->setCurrentWorkingDirectory("bar");
2067+
ASSERT_FALSE(EC);
2068+
WorkingDir = FS->getCurrentWorkingDirectory();
2069+
ASSERT_TRUE(WorkingDir);
2070+
EXPECT_EQ(*WorkingDir, "//root/bar");
2071+
}
2072+
2073+
TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthrough) {
2074+
IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem());
2075+
Lower->addDirectory("//root/");
2076+
Lower->addDirectory("//root/foo");
2077+
Lower->addRegularFile("//root/foo/a");
2078+
Lower->addRegularFile("//root/foo/b");
2079+
Lower->addRegularFile("//root/c");
2080+
IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
2081+
"{ 'use-external-names': false,\n"
2082+
" 'roots': [\n"
2083+
"{\n"
2084+
" 'type': 'directory',\n"
2085+
" 'name': '//root/bar',\n"
2086+
" 'contents': [ {\n"
2087+
" 'type': 'file',\n"
2088+
" 'name': 'a',\n"
2089+
" 'external-contents': '//root/foo/a'\n"
2090+
" }\n"
2091+
" ]\n"
2092+
"}\n"
2093+
"]\n"
2094+
"}",
2095+
Lower);
2096+
ASSERT_TRUE(FS.get() != nullptr);
2097+
std::error_code EC = FS->setCurrentWorkingDirectory("//root/");
2098+
ASSERT_FALSE(EC);
2099+
ASSERT_TRUE(FS.get() != nullptr);
2100+
2101+
llvm::ErrorOr<vfs::Status> Status = FS->status("bar/a");
2102+
ASSERT_FALSE(Status.getError());
2103+
EXPECT_TRUE(Status->exists());
2104+
2105+
Status = FS->status("foo/a");
2106+
ASSERT_FALSE(Status.getError());
2107+
EXPECT_TRUE(Status->exists());
2108+
2109+
EC = FS->setCurrentWorkingDirectory("//root/bar");
2110+
ASSERT_FALSE(EC);
2111+
2112+
Status = FS->status("./a");
2113+
ASSERT_FALSE(Status.getError());
2114+
EXPECT_TRUE(Status->exists());
2115+
2116+
Status = FS->status("./b");
2117+
ASSERT_TRUE(Status.getError());
2118+
2119+
Status = FS->status("./c");
2120+
ASSERT_TRUE(Status.getError());
2121+
2122+
EC = FS->setCurrentWorkingDirectory("//root/");
2123+
ASSERT_FALSE(EC);
2124+
2125+
Status = FS->status("c");
2126+
ASSERT_FALSE(Status.getError());
2127+
EXPECT_TRUE(Status->exists());
2128+
}
2129+
2130+
TEST_F(VFSFromYAMLTest, WorkingDirectoryFallthroughInvalid) {
2131+
IntrusiveRefCntPtr<ErrorDummyFileSystem> Lower(new ErrorDummyFileSystem());
2132+
Lower->addDirectory("//root/");
2133+
Lower->addDirectory("//root/foo");
2134+
Lower->addRegularFile("//root/foo/a");
2135+
Lower->addRegularFile("//root/foo/b");
2136+
Lower->addRegularFile("//root/c");
2137+
IntrusiveRefCntPtr<vfs::FileSystem> FS = getFromYAMLString(
2138+
"{ 'use-external-names': false,\n"
2139+
" 'roots': [\n"
2140+
"{\n"
2141+
" 'type': 'directory',\n"
2142+
" 'name': '//root/bar',\n"
2143+
" 'contents': [ {\n"
2144+
" 'type': 'file',\n"
2145+
" 'name': 'a',\n"
2146+
" 'external-contents': '//root/foo/a'\n"
2147+
" }\n"
2148+
" ]\n"
2149+
"}\n"
2150+
"]\n"
2151+
"}",
2152+
Lower);
2153+
ASSERT_TRUE(FS.get() != nullptr);
2154+
std::error_code EC = FS->setCurrentWorkingDirectory("//root/");
2155+
ASSERT_FALSE(EC);
2156+
ASSERT_TRUE(FS.get() != nullptr);
2157+
2158+
llvm::ErrorOr<vfs::Status> Status = FS->status("bar/a");
2159+
ASSERT_FALSE(Status.getError());
2160+
EXPECT_TRUE(Status->exists());
2161+
2162+
Status = FS->status("foo/a");
2163+
ASSERT_TRUE(Status.getError());
2164+
}

0 commit comments

Comments
 (0)
Please sign in to comment.