aboutsummaryrefslogtreecommitdiff
path: root/lib/Basic
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Basic')
-rw-r--r--lib/Basic/FileManager.cpp60
-rw-r--r--lib/Basic/SourceManager.cpp7
2 files changed, 53 insertions, 14 deletions
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index 565f8a61de..247ba1b752 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -18,8 +18,10 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/FileSystemOptions.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Path.h"
#include "llvm/Config/config.h"
@@ -197,7 +199,8 @@ void FileManager::removeStatCache(StatSysCallCache *statCache) {
/// \brief Retrieve the directory that the given file name resides in.
static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
const char *NameStart,
- const char *NameEnd) {
+ const char *NameEnd,
+ const FileSystemOptions &FileSystemOpts) {
// Figure out what directory it is in. If the string contains a / in it,
// strip off everything after it.
// FIXME: this logic should be in sys::Path.
@@ -211,18 +214,19 @@ static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
if (SlashPos < NameStart) {
// Use the current directory if file has no path component.
const char *Name = ".";
- return FileMgr.getDirectory(Name, Name+1);
+ return FileMgr.getDirectory(Name, Name+1, FileSystemOpts);
} else if (SlashPos == NameEnd-1)
return 0; // If filename ends with a /, it's a directory.
else
- return FileMgr.getDirectory(NameStart, SlashPos);
+ return FileMgr.getDirectory(NameStart, SlashPos, FileSystemOpts);
}
/// getDirectory - Lookup, cache, and verify the specified directory. This
/// returns null if the directory doesn't exist.
///
const DirectoryEntry *FileManager::getDirectory(const char *NameStart,
- const char *NameEnd) {
+ const char *NameEnd,
+ const FileSystemOptions &FileSystemOpts) {
// stat doesn't like trailing separators (at least on Windows).
if (((NameEnd - NameStart) > 1) &&
((*(NameEnd - 1) == '/') || (*(NameEnd - 1) == '\\')))
@@ -248,7 +252,7 @@ const DirectoryEntry *FileManager::getDirectory(const char *NameStart,
// Check to see if the directory exists.
struct stat StatBuf;
- if (stat_cached(InterndDirName, &StatBuf) || // Error stat'ing.
+ if (stat_cached(InterndDirName, &StatBuf, FileSystemOpts) || // Error stat'ing.
!S_ISDIR(StatBuf.st_mode)) // Not a directory?
return 0;
@@ -274,7 +278,8 @@ const DirectoryEntry *FileManager::getDirectory(const char *NameStart,
/// if the file doesn't exist.
///
const FileEntry *FileManager::getFile(const char *NameStart,
- const char *NameEnd) {
+ const char *NameEnd,
+ const FileSystemOptions &FileSystemOpts) {
++NumFileLookups;
// See if there is already an entry in the map.
@@ -297,7 +302,7 @@ const FileEntry *FileManager::getFile(const char *NameStart,
const char *InterndFileName = NamedFileEnt.getKeyData();
const DirectoryEntry *DirInfo
- = getDirectoryFromFile(*this, NameStart, NameEnd);
+ = getDirectoryFromFile(*this, NameStart, NameEnd, FileSystemOpts);
if (DirInfo == 0) // Directory doesn't exist, file can't exist.
return 0;
@@ -307,7 +312,7 @@ const FileEntry *FileManager::getFile(const char *NameStart,
// Nope, there isn't. Check to see if the file exists.
struct stat StatBuf;
//llvm::errs() << "STATING: " << Filename;
- if (stat_cached(InterndFileName, &StatBuf) || // Error stat'ing.
+ if (stat_cached(InterndFileName, &StatBuf, FileSystemOpts) || // Error stat'ing.
S_ISDIR(StatBuf.st_mode)) { // A directory?
// If this file doesn't exist, we leave a null in FileEntries for this path.
//llvm::errs() << ": Not existing\n";
@@ -336,7 +341,8 @@ const FileEntry *FileManager::getFile(const char *NameStart,
const FileEntry *
FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,
- time_t ModificationTime) {
+ time_t ModificationTime,
+ const FileSystemOptions &FileSystemOpts) {
const char *NameStart = Filename.begin(), *NameEnd = Filename.end();
++NumFileLookups;
@@ -356,7 +362,7 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,
NamedFileEnt.setValue(NON_EXISTENT_FILE);
const DirectoryEntry *DirInfo
- = getDirectoryFromFile(*this, NameStart, NameEnd);
+ = getDirectoryFromFile(*this, NameStart, NameEnd, FileSystemOpts);
if (DirInfo == 0) // Directory doesn't exist, file can't exist.
return 0;
@@ -374,7 +380,7 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,
// newly-created file entry.
const char *InterndFileName = NamedFileEnt.getKeyData();
struct stat StatBuf;
- if (!stat_cached(InterndFileName, &StatBuf) &&
+ if (!stat_cached(InterndFileName, &StatBuf, FileSystemOpts) &&
!S_ISDIR(StatBuf.st_mode)) {
llvm::sys::Path FilePath(InterndFileName);
FilePath.makeAbsolute();
@@ -384,6 +390,38 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,
return UFE;
}
+llvm::MemoryBuffer *FileManager::getBufferForFile(const char *FilenameStart,
+ const char *FilenameEnd,
+ const FileSystemOptions &FileSystemOpts,
+ std::string *ErrorStr,
+ int64_t FileSize,
+ struct stat *FileInfo) {
+ llvm::sys::Path FilePath(llvm::StringRef(FilenameStart,
+ FilenameEnd-FilenameStart));
+ FixupRelativePath(FilePath, FileSystemOpts);
+
+ return llvm::MemoryBuffer::getFile(FilePath.c_str(), ErrorStr,
+ FileSize, FileInfo);
+}
+
+int FileManager::stat_cached(const char* path, struct stat* buf,
+ const FileSystemOptions &FileSystemOpts) {
+ llvm::sys::Path FilePath(path);
+ FixupRelativePath(FilePath, FileSystemOpts);
+
+ return StatCache.get() ? StatCache->stat(FilePath.c_str(), buf)
+ : stat(FilePath.c_str(), buf);
+}
+
+void FileManager::FixupRelativePath(llvm::sys::Path &path,
+ const FileSystemOptions &FSOpts) {
+ if (!FSOpts.WorkingDir.empty() && !path.isAbsolute()) {
+ llvm::sys::Path NewPath(FSOpts.WorkingDir);
+ NewPath.appendComponent(path.str());
+ path = NewPath;
+ }
+}
+
void FileManager::PrintStats() const {
llvm::errs() << "\n*** File Manager Stats:\n";
llvm::errs() << UniqueFiles.size() << " files found, "
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index 7127e80018..97af0d6fe3 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -73,9 +73,10 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
if (!Buffer.getPointer() && Entry) {
std::string ErrorStr;
struct stat FileInfo;
- Buffer.setPointer(MemoryBuffer::getFile(Entry->getName(), &ErrorStr,
- Entry->getSize(), &FileInfo));
-
+ Buffer.setPointer(SM.getFileManager().getBufferForFile(Entry,
+ SM.getFileSystemOpts(),
+ &ErrorStr, &FileInfo));
+
// If we were unable to open the file, then we are in an inconsistent
// situation where the content cache referenced a file which no longer
// exists. Most likely, we were using a stat cache with an invalid entry but