[clang] [llvm] [SystemZ][z/OS] Add new openFileForReadBinary function, and pass IsText parameter to getBufferForFile (PR #111723)
Abhina Sree via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 11 05:46:53 PDT 2024
https://github.com/abhina-sree updated https://github.com/llvm/llvm-project/pull/111723
>From c1676e48a587e10ba54c28e99192fd5e6a36f72e Mon Sep 17 00:00:00 2001
From: Abhina Sreeskantharajan <Abhina.Sreeskantharajan at ibm.com>
Date: Wed, 9 Oct 2024 13:23:41 -0400
Subject: [PATCH 1/2] [SystemZ][z/OS] Add new openFileForReadBinary function,
and pass IsText parameter to getBufferForFile
---
clang/include/clang/Basic/FileManager.h | 8 ++---
clang/lib/Basic/FileManager.cpp | 12 +++----
clang/lib/Lex/HeaderMap.cpp | 4 ++-
clang/lib/Serialization/ASTReader.cpp | 3 +-
llvm/include/llvm/Support/VirtualFileSystem.h | 13 ++++++--
llvm/lib/Support/VirtualFileSystem.cpp | 31 +++++++++++++------
6 files changed, 48 insertions(+), 23 deletions(-)
diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h
index ce4e8c1fbe16eb..d987fb05a94a37 100644
--- a/clang/include/clang/Basic/FileManager.h
+++ b/clang/include/clang/Basic/FileManager.h
@@ -292,21 +292,21 @@ class FileManager : public RefCountedBase<FileManager> {
/// MemoryBuffer if successful, otherwise returning null.
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(FileEntryRef Entry, bool isVolatile = false,
- bool RequiresNullTerminator = true,
+ bool RequiresNullTerminator = true, bool IsText = true,
std::optional<int64_t> MaybeLimit = std::nullopt);
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
getBufferForFile(StringRef Filename, bool isVolatile = false,
- bool RequiresNullTerminator = true,
+ bool RequiresNullTerminator = true, bool IsText = true,
std::optional<int64_t> MaybeLimit = std::nullopt) 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);
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp
index 6097b85a03064b..27075cefafdc2f 100644
--- a/clang/lib/Basic/FileManager.cpp
+++ b/clang/lib/Basic/FileManager.cpp
@@ -530,7 +530,7 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
FileManager::getBufferForFile(FileEntryRef FE, bool isVolatile,
- bool RequiresNullTerminator,
+ bool RequiresNullTerminator, bool IsText,
std::optional<int64_t> MaybeLimit) {
const FileEntry *Entry = &FE.getFileEntry();
// If the content is living on the file entry, return a reference to it.
@@ -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,
diff --git a/clang/lib/Lex/HeaderMap.cpp b/clang/lib/Lex/HeaderMap.cpp
index 00bf880726ee3e..35c68b304a4523 100644
--- a/clang/lib/Lex/HeaderMap.cpp
+++ b/clang/lib/Lex/HeaderMap.cpp
@@ -54,7 +54,9 @@ 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, /*IsText=*/false);
if (!FileBuffer || !*FileBuffer)
return nullptr;
bool NeedsByteSwap;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 5c4f8d0e9c46cd..769b85dc318072 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5333,7 +5333,8 @@ std::string ASTReader::getOriginalSourceFile(
const PCHContainerReader &PCHContainerRdr, DiagnosticsEngine &Diags) {
// Open the AST file.
auto Buffer = FileMgr.getBufferForFile(ASTFileName, /*IsVolatile=*/false,
- /*RequiresNullTerminator=*/false);
+ /*RequiresNullTerminator=*/false,
+ /*IsText=*/false);
if (!Buffer) {
Diags.Report(diag::err_fe_unable_to_read_pch_file)
<< ASTFileName << Buffer.getError().message();
diff --git a/llvm/include/llvm/Support/VirtualFileSystem.h b/llvm/include/llvm/Support/VirtualFileSystem.h
index 2531c075f262d7..a94e285a806f2c 100644
--- a/llvm/include/llvm/Support/VirtualFileSystem.h
+++ b/llvm/include/llvm/Support/VirtualFileSystem.h
@@ -271,15 +271,24 @@ 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 objct for the binary file at \p Path, if one exists.
+ /// This function should be called instead of openFileForRead if the file
+ /// should be opened as a binary file.
+ 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.
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().
diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp
index 928c0b5a24ed65..ca2e1ab2c7de55 100644
--- a/llvm/lib/Support/VirtualFileSystem.cpp
+++ b/llvm/lib/Support/VirtualFileSystem.cpp
@@ -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();
@@ -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;
@@ -302,6 +305,17 @@ class RealFileSystem : public FileSystem {
return Storage;
}
+ ErrorOr<std::unique_ptr<File>> openFileForRead(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;
@@ -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 openFileForRead(Name, sys::fs::OF_Text);
+}
+
+ErrorOr<std::unique_ptr<File>>
+RealFileSystem::openFileForReadBinary(const Twine &Name) {
+ return openFileForRead(Name, sys::fs::OF_None);
}
llvm::ErrorOr<std::string> RealFileSystem::getCurrentWorkingDirectory() const {
>From 72fed0cca8d68923803086480284e7342e5f5777 Mon Sep 17 00:00:00 2001
From: Abhina Sreeskantharajan <Abhina.Sreeskantharajan at ibm.com>
Date: Thu, 10 Oct 2024 16:29:09 -0400
Subject: [PATCH 2/2] address comments
---
clang/include/clang/Basic/FileManager.h | 13 +++++++++----
clang/lib/Basic/FileManager.cpp | 7 ++++---
clang/lib/Lex/HeaderMap.cpp | 3 ++-
clang/lib/Serialization/ASTReader.cpp | 1 +
llvm/include/llvm/Support/VirtualFileSystem.h | 10 +++++++---
llvm/lib/Support/VirtualFileSystem.cpp | 8 ++++----
6 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h
index d987fb05a94a37..7a26c65379ac67 100644
--- a/clang/include/clang/Basic/FileManager.h
+++ b/clang/include/clang/Basic/FileManager.h
@@ -290,14 +290,19 @@ 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, bool IsText = true,
- std::optional<int64_t> MaybeLimit = std::nullopt);
+ bool RequiresNullTerminator = true,
+ 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, bool IsText = true,
- std::optional<int64_t> MaybeLimit = std::nullopt) const {
+ bool RequiresNullTerminator = true,
+ std::optional<int64_t> MaybeLimit = std::nullopt,
+ bool IsText = true) const {
return getBufferForFileImpl(Filename,
/*FileSize=*/MaybeLimit.value_or(-1),
isVolatile, RequiresNullTerminator, IsText);
diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp
index 27075cefafdc2f..7876ff02137735 100644
--- a/clang/lib/Basic/FileManager.cpp
+++ b/clang/lib/Basic/FileManager.cpp
@@ -529,9 +529,10 @@ void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
}
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
-FileManager::getBufferForFile(FileEntryRef FE, bool isVolatile,
- bool RequiresNullTerminator, bool IsText,
- std::optional<int64_t> MaybeLimit) {
+FileManager::getBufferForFile(
+ FileEntryRef FE, bool isVolatile,
+ bool RequiresNullTerminator 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)
diff --git a/clang/lib/Lex/HeaderMap.cpp b/clang/lib/Lex/HeaderMap.cpp
index 35c68b304a4523..b04f67a4b2ed3c 100644
--- a/clang/lib/Lex/HeaderMap.cpp
+++ b/clang/lib/Lex/HeaderMap.cpp
@@ -56,7 +56,8 @@ std::unique_ptr<HeaderMap> HeaderMap::Create(FileEntryRef FE, FileManager &FM) {
auto FileBuffer =
FM.getBufferForFile(FE, /*IsVolatile=*/false,
- /*RequiresNullTerminator=*/true, /*IsText=*/false);
+ /*RequiresNullTerminator=*/true,
+ /*MaybeList=*/std::nullopt, /*IsText=*/false);
if (!FileBuffer || !*FileBuffer)
return nullptr;
bool NeedsByteSwap;
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 769b85dc318072..954bdf207d1725 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5334,6 +5334,7 @@ std::string ASTReader::getOriginalSourceFile(
// Open the AST file.
auto Buffer = FileMgr.getBufferForFile(ASTFileName, /*IsVolatile=*/false,
/*RequiresNullTerminator=*/false,
+ /*MaybeLimit=*/std::nullopt,
/*IsText=*/false);
if (!Buffer) {
Diags.Report(diag::err_fe_unable_to_read_pch_file)
diff --git a/llvm/include/llvm/Support/VirtualFileSystem.h b/llvm/include/llvm/Support/VirtualFileSystem.h
index a94e285a806f2c..1358e880942a1c 100644
--- a/llvm/include/llvm/Support/VirtualFileSystem.h
+++ b/llvm/include/llvm/Support/VirtualFileSystem.h
@@ -275,9 +275,11 @@ class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem>,
virtual llvm::ErrorOr<std::unique_ptr<File>>
openFileForRead(const Twine &Path) = 0;
- /// Get a \p File objct for the binary file at \p Path, if one exists.
- /// This function should be called instead of openFileForRead if the file
- /// should be opened as a binary file.
+ /// 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);
@@ -285,6 +287,8 @@ class FileSystem : public llvm::ThreadSafeRefCountedBase<FileSystem>,
/// 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,
diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp
index ca2e1ab2c7de55..4feb41554fc3c7 100644
--- a/llvm/lib/Support/VirtualFileSystem.cpp
+++ b/llvm/lib/Support/VirtualFileSystem.cpp
@@ -305,8 +305,8 @@ class RealFileSystem : public FileSystem {
return Storage;
}
- ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Name,
- sys::fs::OpenFlags Flags) {
+ 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);
@@ -338,12 +338,12 @@ ErrorOr<Status> RealFileSystem::status(const Twine &Path) {
ErrorOr<std::unique_ptr<File>>
RealFileSystem::openFileForRead(const Twine &Name) {
- return openFileForRead(Name, sys::fs::OF_Text);
+ return openFileForReadWithFlags(Name, sys::fs::OF_Text);
}
ErrorOr<std::unique_ptr<File>>
RealFileSystem::openFileForReadBinary(const Twine &Name) {
- return openFileForRead(Name, sys::fs::OF_None);
+ return openFileForReadWithFlags(Name, sys::fs::OF_None);
}
llvm::ErrorOr<std::string> RealFileSystem::getCurrentWorkingDirectory() const {
More information about the cfe-commits
mailing list