Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions clang/include/clang/Basic/FileManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,23 +290,28 @@ class FileManager : public RefCountedBase<FileManager> {

/// Open the specified file as a MemoryBuffer, returning a new
/// MemoryBuffer if successful, otherwise returning null.
/// The IsText parameter controls whether the file should be opened as a text
/// or binary file, and should be set to false if the file contents should be
/// treated as binary.
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(FileEntryRef Entry, bool isVolatile = false,
bool RequiresNullTerminator = true,
std::optional<int64_t> MaybeLimit = std::nullopt);
std::optional<int64_t> MaybeLimit = std::nullopt,
bool IsText = true);
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(StringRef Filename, bool isVolatile = false,
bool RequiresNullTerminator = true,
std::optional<int64_t> MaybeLimit = std::nullopt) const {
std::optional<int64_t> MaybeLimit = std::nullopt,
bool IsText = true) const {
return getBufferForFileImpl(Filename,
/*FileSize=*/MaybeLimit.value_or(-1),
isVolatile, RequiresNullTerminator);
isVolatile, RequiresNullTerminator, IsText);
}

private:
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFileImpl(StringRef Filename, int64_t FileSize, bool isVolatile,
bool RequiresNullTerminator) const;
bool RequiresNullTerminator, bool IsText) const;

DirectoryEntry *&getRealDirEntry(const llvm::vfs::Status &Status);

Expand Down
12 changes: 6 additions & 6 deletions clang/lib/Basic/FileManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
FileManager::getBufferForFile(FileEntryRef FE, bool isVolatile,
bool RequiresNullTerminator,
std::optional<int64_t> MaybeLimit) {
std::optional<int64_t> MaybeLimit, bool IsText) {
const FileEntry *Entry = &FE.getFileEntry();
// If the content is living on the file entry, return a reference to it.
if (Entry->Content)
Expand All @@ -558,21 +558,21 @@ FileManager::getBufferForFile(FileEntryRef FE, bool isVolatile,

// Otherwise, open the file.
return getBufferForFileImpl(Filename, FileSize, isVolatile,
RequiresNullTerminator);
RequiresNullTerminator, IsText);
}

llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
FileManager::getBufferForFileImpl(StringRef Filename, int64_t FileSize,
bool isVolatile,
bool RequiresNullTerminator) const {
bool isVolatile, bool RequiresNullTerminator,
bool IsText) const {
if (FileSystemOpts.WorkingDir.empty())
return FS->getBufferForFile(Filename, FileSize, RequiresNullTerminator,
isVolatile);
isVolatile, IsText);

SmallString<128> FilePath(Filename);
FixupRelativePath(FilePath);
return FS->getBufferForFile(FilePath, FileSize, RequiresNullTerminator,
isVolatile);
isVolatile, IsText);
}

/// getStatValue - Get the 'stat' information for the specified path,
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Lex/HeaderMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ std::unique_ptr<HeaderMap> HeaderMap::Create(FileEntryRef FE, FileManager &FM) {
unsigned FileSize = FE.getSize();
if (FileSize <= sizeof(HMapHeader)) return nullptr;

auto FileBuffer = FM.getBufferForFile(FE);
auto FileBuffer =
FM.getBufferForFile(FE, /*IsVolatile=*/false,
/*RequiresNullTerminator=*/true,
/*MaybeList=*/std::nullopt, /*IsText=*/false);
if (!FileBuffer || !*FileBuffer)
return nullptr;
bool NeedsByteSwap;
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5333,7 +5333,9 @@ std::string ASTReader::getOriginalSourceFile(
const PCHContainerReader &PCHContainerRdr, DiagnosticsEngine &Diags) {
// Open the AST file.
auto Buffer = FileMgr.getBufferForFile(ASTFileName, /*IsVolatile=*/false,
/*RequiresNullTerminator=*/false);
/*RequiresNullTerminator=*/false,
/*MaybeLimit=*/std::nullopt,
/*IsText=*/false);
if (!Buffer) {
Diags.Report(diag::err_fe_unable_to_read_pch_file)
<< ASTFileName << Buffer.getError().message();
Expand Down
17 changes: 15 additions & 2 deletions llvm/include/llvm/Support/VirtualFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,28 @@ class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem>,
/// Get the status of the entry at \p Path, if one exists.
virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0;

/// Get a \p File object for the file at \p Path, if one exists.
/// Get a \p File object for the text file at \p Path, if one exists.
virtual llvm::ErrorOr<std::unique_ptr<File>>
openFileForRead(const Twine &Path) = 0;

/// Get a \p File object for the binary file at \p Path, if one exists.
/// Some non-ascii based file systems perform encoding conversions
/// when reading as a text file, and this function should be used if
/// a file's bytes should be read as-is. On most filesystems, this
/// is the same behaviour as openFileForRead.
virtual llvm::ErrorOr<std::unique_ptr<File>>
openFileForReadBinary(const Twine &Path) {
return openFileForRead(Path);
}

/// This is a convenience method that opens a file, gets its content and then
/// closes the file.
/// The IsText parameter is used to distinguish whether the file should be
/// opened as a binary or text file.
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(const Twine &Name, int64_t FileSize = -1,
bool RequiresNullTerminator = true, bool IsVolatile = false);
bool RequiresNullTerminator = true, bool IsVolatile = false,
bool IsText = true);

/// Get a directory_iterator for \p Dir.
/// \note The 'end' iterator is directory_iterator().
Expand Down
31 changes: 22 additions & 9 deletions llvm/lib/Support/VirtualFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,9 @@ FileSystem::~FileSystem() = default;

ErrorOr<std::unique_ptr<MemoryBuffer>>
FileSystem::getBufferForFile(const llvm::Twine &Name, int64_t FileSize,
bool RequiresNullTerminator, bool IsVolatile) {
auto F = openFileForRead(Name);
bool RequiresNullTerminator, bool IsVolatile,
bool IsText) {
auto F = IsText ? openFileForRead(Name) : openFileForReadBinary(Name);
if (!F)
return F.getError();

Expand Down Expand Up @@ -279,6 +280,8 @@ class RealFileSystem : public FileSystem {

ErrorOr<Status> status(const Twine &Path) override;
ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override;
ErrorOr<std::unique_ptr<File>>
openFileForReadBinary(const Twine &Path) override;
directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;

llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override;
Expand All @@ -302,6 +305,17 @@ class RealFileSystem : public FileSystem {
return Storage;
}

ErrorOr<std::unique_ptr<File>>
openFileForReadWithFlags(const Twine &Name, sys::fs::OpenFlags Flags) {
SmallString<256> RealName, Storage;
Expected<file_t> FDOrErr = sys::fs::openNativeFileForRead(
adjustPath(Name, Storage), Flags, &RealName);
if (!FDOrErr)
return errorToErrorCode(FDOrErr.takeError());
return std::unique_ptr<File>(
new RealFile(*FDOrErr, Name.str(), RealName.str()));
}

struct WorkingDirectory {
// The current working directory, without symlinks resolved. (echo $PWD).
SmallString<128> Specified;
Expand All @@ -324,13 +338,12 @@ ErrorOr<Status> RealFileSystem::status(const Twine &Path) {

ErrorOr<std::unique_ptr<File>>
RealFileSystem::openFileForRead(const Twine &Name) {
SmallString<256> RealName, Storage;
Expected<file_t> FDOrErr = sys::fs::openNativeFileForRead(
adjustPath(Name, Storage), sys::fs::OF_None, &RealName);
if (!FDOrErr)
return errorToErrorCode(FDOrErr.takeError());
return std::unique_ptr<File>(
new RealFile(*FDOrErr, Name.str(), RealName.str()));
return openFileForReadWithFlags(Name, sys::fs::OF_Text);
}

ErrorOr<std::unique_ptr<File>>
RealFileSystem::openFileForReadBinary(const Twine &Name) {
return openFileForReadWithFlags(Name, sys::fs::OF_None);
}

llvm::ErrorOr<std::string> RealFileSystem::getCurrentWorkingDirectory() const {
Expand Down
Loading