From 2f9ef512e606807c6081605853f80e3736baee6a Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Wed, 24 Sep 2025 12:29:23 -0700 Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.7 --- llvm/include/llvm/Support/File.h | 55 +++++++++++++++++++++ llvm/include/llvm/Support/FileSystem.h | 24 +++------ llvm/include/llvm/Support/MemoryBuffer.h | 12 +---- llvm/lib/CAS/MappedFileRegionArena.cpp | 2 +- llvm/lib/Object/ArchiveWriter.cpp | 2 +- llvm/lib/Support/FileUtilities.cpp | 3 +- llvm/lib/Support/Unix/Path.inc | 28 ++++++----- llvm/lib/Support/VirtualFileSystem.cpp | 9 ++-- llvm/lib/Support/Windows/Path.inc | 4 +- llvm/unittests/Support/MemoryBufferTest.cpp | 12 +++-- 10 files changed, 97 insertions(+), 54 deletions(-) create mode 100644 llvm/include/llvm/Support/File.h diff --git a/llvm/include/llvm/Support/File.h b/llvm/include/llvm/Support/File.h new file mode 100644 index 0000000000000..d1ce246cdb554 --- /dev/null +++ b/llvm/include/llvm/Support/File.h @@ -0,0 +1,55 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// This file declares llvm::sys::fs::file_t type. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_SUPPORT_FILE_H +#define LLVM_SUPPORT_FILE_H + +namespace llvm::sys::fs { + +/// This class wraps the platform specific file handle/descriptor type to +/// provide an unified representation. +struct file_t { +#if defined(_WIN32) + // A Win32 HANDLE is a typedef of void* + using value_type = void *; + static const value_type Invalid; +#else + // A file descriptor on UNIX. + using value_type = int; + static constexpr value_type Invalid = -1; +#endif + value_type Value; + + /// Default constructor to invalid file. + file_t() : Value(Invalid) {} + + /// Implicit constructor from underlying value. + // TODO: Make this explicit to flush out type mismatches. + file_t(value_type Value) : Value(Value) {} + + /// Is a valid file. + bool isValid() const { return Value != Invalid; } + + /// Get the underlying value and return a platform specific value. + value_type get() const { return Value; } +}; + +inline bool operator==(file_t LHS, file_t RHS) { + return LHS.get() == RHS.get(); +} + +inline bool operator!=(file_t LHS, file_t RHS) { return !(LHS == RHS); } + +} // namespace llvm::sys::fs + +#endif diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h index c203779307840..72afcc4051854 100644 --- a/llvm/include/llvm/Support/FileSystem.h +++ b/llvm/include/llvm/Support/FileSystem.h @@ -35,6 +35,7 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorOr.h" +#include "llvm/Support/File.h" #include "llvm/Support/FileSystem/UniqueID.h" #include "llvm/Support/MD5.h" #include @@ -49,15 +50,6 @@ namespace llvm { namespace sys { namespace fs { -#if defined(_WIN32) -// A Win32 HANDLE is a typedef of void* -using file_t = void *; -#else -using file_t = int; -#endif - -LLVM_ABI extern const file_t kInvalidFile; - /// An enumeration for the file system's view of the type. enum class file_type { status_error, @@ -645,13 +637,11 @@ LLVM_ABI std::error_code is_other(const Twine &path, bool &result); LLVM_ABI std::error_code status(const Twine &path, file_status &result, bool follow = true); -/// A version for when a file descriptor is already available. -LLVM_ABI std::error_code status(int FD, file_status &Result); +/// A version for when a file is already available. +LLVM_ABI std::error_code status(file_t F, file_status &Result); -#ifdef _WIN32 /// A version for when a file descriptor is already available. -LLVM_ABI std::error_code status(file_t FD, file_status &Result); -#endif +LLVM_ABI std::error_code status(int FD, file_status &Result); /// Get file creation mode mask of the process. /// @@ -1000,15 +990,15 @@ LLVM_ABI Expected openNativeFile(const Twine &Name, LLVM_ABI file_t convertFDToNativeFile(int FD); #ifndef _WIN32 -inline file_t convertFDToNativeFile(int FD) { return FD; } +inline file_t convertFDToNativeFile(int FD) { return file_t(FD); } #endif /// Return an open handle to standard in. On Unix, this is typically FD 0. -/// Returns kInvalidFile when the stream is closed. +/// Returns Invalid file_t when the stream is closed. LLVM_ABI file_t getStdinHandle(); /// Return an open handle to standard out. On Unix, this is typically FD 1. -/// Returns kInvalidFile when the stream is closed. +/// Returns Invalid file_t when the stream is closed. LLVM_ABI file_t getStdoutHandle(); /// Return an open handle to standard error. On Unix, this is typically FD 2. diff --git a/llvm/include/llvm/Support/MemoryBuffer.h b/llvm/include/llvm/Support/MemoryBuffer.h index f092c67265a31..e7f2b2090f453 100644 --- a/llvm/include/llvm/Support/MemoryBuffer.h +++ b/llvm/include/llvm/Support/MemoryBuffer.h @@ -21,23 +21,13 @@ #include "llvm/Support/CBindingWrapping.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorOr.h" +#include "llvm/Support/File.h" #include "llvm/Support/MemoryBufferRef.h" #include #include #include namespace llvm { -namespace sys { -namespace fs { -// Duplicated from FileSystem.h to avoid a dependency. -#if defined(_WIN32) -// A Win32 HANDLE is a typedef of void* -using file_t = void *; -#else -using file_t = int; -#endif -} // namespace fs -} // namespace sys /// This interface provides simple read-only access to a block of memory, and /// provides simple methods for reading files and standard input into a memory diff --git a/llvm/lib/CAS/MappedFileRegionArena.cpp b/llvm/lib/CAS/MappedFileRegionArena.cpp index 472843d78af6e..f5e76056a0698 100644 --- a/llvm/lib/CAS/MappedFileRegionArena.cpp +++ b/llvm/lib/CAS/MappedFileRegionArena.cpp @@ -373,7 +373,7 @@ Expected MappedFileRegionArena::allocateOffset(uint64_t AllocSize) { ErrorOr FileSizeInfo::get(sys::fs::file_t File) { #if LLVM_ON_UNIX && defined(MAPPED_FILE_BSIZE) struct stat Status; - int StatRet = ::fstat(File, &Status); + int StatRet = ::fstat(File.get(), &Status); if (StatRet) return errnoAsErrorCode(); uint64_t AllocatedSize = uint64_t(Status.st_blksize) * MAPPED_FILE_BSIZE; diff --git a/llvm/lib/Object/ArchiveWriter.cpp b/llvm/lib/Object/ArchiveWriter.cpp index 6fc0889afc6a8..efaec82f9b745 100644 --- a/llvm/lib/Object/ArchiveWriter.cpp +++ b/llvm/lib/Object/ArchiveWriter.cpp @@ -132,7 +132,7 @@ Expected NewArchiveMember::getFile(StringRef FileName, if (!FDOrErr) return FDOrErr.takeError(); sys::fs::file_t FD = *FDOrErr; - assert(FD != sys::fs::kInvalidFile); + assert(FD.isValid()); if (auto EC = sys::fs::status(FD, Status)) return errorCodeToError(EC); diff --git a/llvm/lib/Support/FileUtilities.cpp b/llvm/lib/Support/FileUtilities.cpp index dbd6c324cf4dc..b8f92ac763e75 100644 --- a/llvm/lib/Support/FileUtilities.cpp +++ b/llvm/lib/Support/FileUtilities.cpp @@ -306,7 +306,8 @@ Error FilePermissionsApplier::apply( return createFileError(OutputFilename, EC); sys::fs::file_status OStat; - if (std::error_code EC = sys::fs::status(FD, OStat)) + if (std::error_code EC = + sys::fs::status(sys::fs::convertFDToNativeFile(FD), OStat)) return createFileError(OutputFilename, EC); if (OStat.type() == sys::fs::file_type::regular_file) { #ifndef _WIN32 diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index 0d991ead72416..56b998d0d2440 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -120,8 +120,6 @@ namespace llvm { namespace sys { namespace fs { -const file_t kInvalidFile = -1; - #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__FreeBSD_kernel__) || defined(__linux__) || \ defined(__CYGWIN__) || defined(__DragonFly__) || defined(_AIX) || \ @@ -768,6 +766,10 @@ std::error_code status(const Twine &Path, file_status &Result, bool Follow) { return fillStatus(StatRet, Status, Result); } +std::error_code status(file_t F, file_status &Result) { + return status(F.get(), Result); +} + std::error_code status(int FD, file_status &Result) { struct stat Status; int StatRet = ::fstat(FD, &Status); @@ -832,7 +834,7 @@ std::error_code setLastAccessAndModificationTime(int FD, TimePoint<> AccessTime, #endif } -std::error_code mapped_file_region::init(int FD, uint64_t Offset, +std::error_code mapped_file_region::init(file_t FD, uint64_t Offset, mapmode Mode) { assert(Size != 0); @@ -861,13 +863,13 @@ std::error_code mapped_file_region::init(int FD, uint64_t Offset, } #endif // #if defined (__APPLE__) - Mapping = ::mmap(nullptr, Size, prot, flags, FD, Offset); + Mapping = ::mmap(nullptr, Size, prot, flags, FD.get(), Offset); if (Mapping == MAP_FAILED) return errnoAsErrorCode(); return std::error_code(); } -mapped_file_region::mapped_file_region(int fd, mapmode mode, size_t length, +mapped_file_region::mapped_file_region(file_t fd, mapmode mode, size_t length, uint64_t offset, std::error_code &ec) : Size(length), Mode(mode) { (void)Mode; @@ -1128,9 +1130,9 @@ std::error_code openFile(const Twine &Name, int &ResultFD, return std::error_code(); } -Expected openNativeFile(const Twine &Name, CreationDisposition Disp, - FileAccess Access, OpenFlags Flags, - unsigned Mode) { +Expected openNativeFile(const Twine &Name, CreationDisposition Disp, + FileAccess Access, OpenFlags Flags, + unsigned Mode) { int FD; std::error_code EC = openFile(Name, FD, Disp, Access, Flags, Mode); @@ -1183,7 +1185,7 @@ std::error_code openFileForRead(const Twine &Name, int &ResultFD, Expected openNativeFileForRead(const Twine &Name, OpenFlags Flags, SmallVectorImpl *RealPath) { - file_t ResultFD; + int ResultFD; std::error_code EC = openFileForRead(Name, ResultFD, Flags, RealPath); if (EC) return errorCodeToError(EC); @@ -1200,7 +1202,7 @@ Expected readNativeFile(file_t FD, MutableArrayRef Buf) { #else size_t Size = Buf.size(); #endif - ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size); + ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD.get(), Buf.data(), Size); if (NumRead == -1) return errorCodeToError(errnoAsErrorCode()); // The underlying operation on these platforms allow opening directories @@ -1224,7 +1226,7 @@ Expected readNativeFileSlice(file_t FD, MutableArrayRef Buf, #endif #ifdef HAVE_PREAD ssize_t NumRead = - sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Size, Offset); + sys::RetryAfterSignal(-1, ::pread, FD.get(), Buf.data(), Size, Offset); #else if (lseek(FD, Offset, SEEK_SET) == -1) return errorCodeToError(errnoAsErrorCode()); @@ -1297,8 +1299,8 @@ std::error_code unlockFile(int FD) { std::error_code closeFile(file_t &F) { file_t TmpF = F; - F = kInvalidFile; - return Process::SafelyCloseFileDescriptor(TmpF); + F = file_t::Invalid; + return Process::SafelyCloseFileDescriptor(TmpF.get()); } template diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index cf784595c2f1c..e71a5b691f6c5 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -56,7 +56,6 @@ using namespace llvm::vfs; using llvm::sys::fs::file_t; using llvm::sys::fs::file_status; using llvm::sys::fs::file_type; -using llvm::sys::fs::kInvalidFile; using llvm::sys::fs::perms; using llvm::sys::fs::UniqueID; @@ -198,7 +197,7 @@ class RealFile : public File { : FD(RawFD), S(NewName, {}, {}, {}, {}, {}, llvm::sys::fs::file_type::status_error, {}), RealName(NewRealPathName.str()) { - assert(FD != kInvalidFile && "Invalid or inactive file descriptor"); + assert(FD.isValid() && "Invalid or inactive file descriptor"); } public: @@ -219,7 +218,7 @@ class RealFile : public File { RealFile::~RealFile() { close(); } ErrorOr RealFile::status() { - assert(FD != kInvalidFile && "cannot stat closed file"); + assert(FD.isValid() && "cannot stat closed file"); if (!S.isStatusKnown()) { file_status RealStatus; if (std::error_code EC = sys::fs::status(FD, RealStatus)) @@ -236,14 +235,14 @@ ErrorOr RealFile::getName() { ErrorOr> RealFile::getBuffer(const Twine &Name, int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) { - assert(FD != kInvalidFile && "cannot get buffer for closed file"); + assert(FD.isValid() && "cannot get buffer for closed file"); return MemoryBuffer::getOpenFile(FD, Name, FileSize, RequiresNullTerminator, IsVolatile); } std::error_code RealFile::close() { std::error_code EC = sys::fs::closeFile(FD); - FD = kInvalidFile; + FD = file_t::Invalid; return EC; } diff --git a/llvm/lib/Support/Windows/Path.inc b/llvm/lib/Support/Windows/Path.inc index be007b7abdb51..860256a1f865b 100644 --- a/llvm/lib/Support/Windows/Path.inc +++ b/llvm/lib/Support/Windows/Path.inc @@ -130,7 +130,7 @@ std::error_code widenPath(const Twine &Path8, SmallVectorImpl &Path16, namespace fs { -const file_t kInvalidFile = INVALID_HANDLE_VALUE; +const file_t::value_type file_t::Invalid = INVALID_HANDLE_VALUE; std::string getMainExecutable(const char *argv0, void *MainExecAddr) { SmallVector PathName; @@ -1397,7 +1397,7 @@ std::error_code unlockFile(int FD) { std::error_code closeFile(file_t &F) { file_t TmpF = F; - F = kInvalidFile; + F = file_t::Invalid; if (!::CloseHandle(TmpF)) return mapWindowsError(::GetLastError()); return std::error_code(); diff --git a/llvm/unittests/Support/MemoryBufferTest.cpp b/llvm/unittests/Support/MemoryBufferTest.cpp index 2cc20c0ab5f0c..b52b4cabe2488 100644 --- a/llvm/unittests/Support/MemoryBufferTest.cpp +++ b/llvm/unittests/Support/MemoryBufferTest.cpp @@ -170,16 +170,22 @@ TEST_F(MemoryBufferTest, copy) { #if LLVM_ENABLE_THREADS TEST_F(MemoryBufferTest, createFromPipe) { - sys::fs::file_t pipes[2]; + int pipes[2]; #if LLVM_ON_UNIX ASSERT_EQ(::pipe(pipes), 0) << strerror(errno); #else ASSERT_TRUE(::CreatePipe(&pipes[0], &pipes[1], nullptr, 0)) << ::GetLastError(); #endif - auto ReadCloser = make_scope_exit([&] { sys::fs::closeFile(pipes[0]); }); + auto ReadCloser = make_scope_exit([&] { + sys::fs::file_t F(pipes[0]); + sys::fs::closeFile(F); + }); std::thread Writer([&] { - auto WriteCloser = make_scope_exit([&] { sys::fs::closeFile(pipes[1]); }); + auto WriteCloser = make_scope_exit([&] { + sys::fs::file_t F(pipes[1]); + sys::fs::closeFile(F); + }); for (unsigned i = 0; i < 5; ++i) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); #if LLVM_ON_UNIX From 9690e48487c32219620d5e7a5896fc5ae34f7f29 Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Wed, 24 Sep 2025 12:32:26 -0700 Subject: [PATCH 2/3] clang-format Created using spr 1.3.7 --- llvm/lib/Support/Unix/Path.inc | 3 ++- llvm/lib/Support/VirtualFileSystem.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index 56b998d0d2440..49eea46dab55d 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -1202,7 +1202,8 @@ Expected readNativeFile(file_t FD, MutableArrayRef Buf) { #else size_t Size = Buf.size(); #endif - ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD.get(), Buf.data(), Size); + ssize_t NumRead = + sys::RetryAfterSignal(-1, ::read, FD.get(), Buf.data(), Size); if (NumRead == -1) return errorCodeToError(errnoAsErrorCode()); // The underlying operation on these platforms allow opening directories diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp index e71a5b691f6c5..20460213fb0dc 100644 --- a/llvm/lib/Support/VirtualFileSystem.cpp +++ b/llvm/lib/Support/VirtualFileSystem.cpp @@ -53,8 +53,8 @@ using namespace llvm; using namespace llvm::vfs; -using llvm::sys::fs::file_t; using llvm::sys::fs::file_status; +using llvm::sys::fs::file_t; using llvm::sys::fs::file_type; using llvm::sys::fs::perms; using llvm::sys::fs::UniqueID; From 6e9c978c350348b6595cfe0060fbe24a7641213f Mon Sep 17 00:00:00 2001 From: Steven Wu Date: Thu, 27 Nov 2025 11:18:38 +0800 Subject: [PATCH 3/3] fix windows Created using spr 1.3.7 --- llvm/include/llvm/Support/File.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/Support/File.h b/llvm/include/llvm/Support/File.h index 65911f9c9dab8..c7ec0566a0d11 100644 --- a/llvm/include/llvm/Support/File.h +++ b/llvm/include/llvm/Support/File.h @@ -22,17 +22,20 @@ namespace llvm::sys::fs { /// provide an unified representation. struct file_t { #if defined(_WIN32) - // A Win32 HANDLE is a typedef of void* + /// A Win32 HANDLE is a typedef of void* using value_type = void *; #else - // A file descriptor on UNIX. + /// A file descriptor on UNIX. using value_type = int; #endif value_type Value; - // Value for an invalid file descriptor/handle. -1 is used for both Unix and - // Windows platform. + /// Value for an invalid file descriptor/handle. +#if defined(_WIN32) + static constexpr value_type Invalid = INVALID_FILE_HANDLE; +#else static constexpr value_type Invalid = -1; +#endif /// Default constructor to invalid file. file_t() : Value(Invalid) {}