summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-05-23 18:15:47 +0000
committerBen Langmuir <blangmuir@apple.com>2014-05-23 18:15:47 +0000
commit5de00f3b56805c7e980f049ceb3f166f8c69cec0 (patch)
tree1ae1c0ee9e452f85526ef0334ecd4b115b315c0b /clang/lib
parent8651081bbe4b8e798a06b4e5b429098b58a1435d (diff)
downloadbcm5719-llvm-5de00f3b56805c7e980f049ceb3f166f8c69cec0.tar.gz
bcm5719-llvm-5de00f3b56805c7e980f049ceb3f166f8c69cec0.zip
Stopgap fix for finding module for a file mapped in the VFS
If we lookup a path using its 'real' path first, we need to ensure that when we run header search we still use the VFS-mapped path or we will not be able to find the corresponding module for the header. The real problem is that we tie the name of a file to its underlying FileEntry, which is uniqued by inode, so we only ever get the first name it is looked up by. This doesn't work with modules, which rely on a specific file system structure. I'm hoping to have time to write up a proposal for fixing this more permanently soon, but as a stopgap this patch updates the name of the file's directory if it comes from a VFS mapping. llvm-svn: 209534
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/FileManager.cpp10
-rw-r--r--clang/lib/Basic/FileSystemStatCache.cpp1
-rw-r--r--clang/lib/Basic/VirtualFileSystem.cpp6
3 files changed, 15 insertions, 2 deletions
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp
index 940fcaf4174..14731f6b09c 100644
--- a/clang/lib/Basic/FileManager.cpp
+++ b/clang/lib/Basic/FileManager.cpp
@@ -274,6 +274,16 @@ const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
NamedFileEnt.setValue(&UFE);
if (UFE.isValid()) { // Already have an entry with this inode, return it.
+
+ // FIXME: this hack ensures that if we look up a file by a virtual path in
+ // the VFS that the getDir() will have the virtual path, even if we found
+ // the file by a 'real' path first. This is required in order to find a
+ // module's structure when its headers/module map are mapped in the VFS.
+ // We should remove this as soon as we can properly support a file having
+ // multiple names.
+ if (DirInfo != UFE.Dir && Data.IsVFSMapped)
+ UFE.Dir = DirInfo;
+
// If the stat process opened the file, close it to avoid a FD leak.
if (F)
delete F;
diff --git a/clang/lib/Basic/FileSystemStatCache.cpp b/clang/lib/Basic/FileSystemStatCache.cpp
index 44ba48aa2fc..0f16e94a05e 100644
--- a/clang/lib/Basic/FileSystemStatCache.cpp
+++ b/clang/lib/Basic/FileSystemStatCache.cpp
@@ -39,6 +39,7 @@ static void copyStatusToFileData(const vfs::Status &Status,
Data.IsDirectory = Status.isDirectory();
Data.IsNamedPipe = Status.getType() == llvm::sys::fs::file_type::fifo_file;
Data.InPCH = false;
+ Data.IsVFSMapped = Status.IsVFSMapped;
}
/// FileSystemStatCache::get - Get the 'stat' information for the specified
diff --git a/clang/lib/Basic/VirtualFileSystem.cpp b/clang/lib/Basic/VirtualFileSystem.cpp
index c89b071a773..a469c9abc39 100644
--- a/clang/lib/Basic/VirtualFileSystem.cpp
+++ b/clang/lib/Basic/VirtualFileSystem.cpp
@@ -31,13 +31,13 @@ using llvm::sys::fs::UniqueID;
Status::Status(const file_status &Status)
: UID(Status.getUniqueID()), MTime(Status.getLastModificationTime()),
User(Status.getUser()), Group(Status.getGroup()), Size(Status.getSize()),
- Type(Status.type()), Perms(Status.permissions()) {}
+ Type(Status.type()), Perms(Status.permissions()), IsVFSMapped(false) {}
Status::Status(StringRef Name, StringRef ExternalName, UniqueID UID,
sys::TimeValue MTime, uint32_t User, uint32_t Group,
uint64_t Size, file_type Type, perms Perms)
: Name(Name), UID(UID), MTime(MTime), User(User), Group(Group), Size(Size),
- Type(Type), Perms(Perms) {}
+ Type(Type), Perms(Perms), IsVFSMapped(false) {}
bool Status::equivalent(const Status &Other) const {
return getUniqueID() == Other.getUniqueID();
@@ -801,6 +801,8 @@ ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
assert(!S || S->getName() == F->getExternalContentsPath());
if (S && !F->useExternalName(UseExternalNames))
S->setName(PathStr);
+ if (S)
+ S->IsVFSMapped = true;
return S;
} else { // directory
DirectoryEntry *DE = cast<DirectoryEntry>(*Result);
OpenPOWER on IntegriCloud