diff --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h --- a/libcxx/src/filesystem/filesystem_common.h +++ b/libcxx/src/filesystem/filesystem_common.h @@ -42,12 +42,6 @@ # define _LIBCPP_USE_UTIMENSAT #endif -// TODO: Check whether these functions actually need internal linkage, or if they can be made normal header functions -_LIBCPP_DIAGNOSTIC_PUSH -_LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wunused-function") -_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-function") -_LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wunused-template") - #if defined(_LIBCPP_WIN32API) # define PATHSTR(x) (L##x) # define PATH_CSTR_FMT "\"%ls\"" @@ -62,12 +56,10 @@ #if defined(_LIBCPP_WIN32API) // Non anonymous, to allow access from two translation units. -errc __win_err_to_errc(int err); +_LIBCPP_HIDE_FROM_ABI errc __win_err_to_errc(int err); #endif -namespace { - -static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 0) string format_string_impl(const char* msg, va_list ap) { array buf; @@ -91,7 +83,7 @@ return result; } -static _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 1, 2) string format_string(const char* msg, ...) { string ret; va_list ap; @@ -110,41 +102,41 @@ return ret; } -error_code capture_errno() { +inline _LIBCPP_HIDE_FROM_ABI error_code capture_errno() { _LIBCPP_ASSERT(errno != 0, "Expected errno to be non-zero"); return error_code(errno, generic_category()); } #if defined(_LIBCPP_WIN32API) -error_code make_windows_error(int err) { +inline _LIBCPP_HIDE_FROM_ABI error_code make_windows_error(int err) { return make_error_code(__win_err_to_errc(err)); } #endif template -T error_value(); +_LIBCPP_HIDE_FROM_ABI T error_value(); template <> -_LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value() {} +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void error_value() {} template <> -bool error_value() { +inline _LIBCPP_HIDE_FROM_ABI bool error_value() { return false; } #if __SIZEOF_SIZE_T__ != __SIZEOF_LONG_LONG__ template <> -size_t error_value() { +inline _LIBCPP_HIDE_FROM_ABI size_t error_value() { return size_t(-1); } #endif template <> -uintmax_t error_value() { +inline _LIBCPP_HIDE_FROM_ABI uintmax_t error_value() { return uintmax_t(-1); } template <> -_LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value() { +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 file_time_type error_value() { return file_time_type::min(); } template <> -path error_value() { +inline _LIBCPP_HIDE_FROM_ABI path error_value() { return {}; } @@ -155,6 +147,7 @@ const path* p1_ = nullptr; const path* p2_ = nullptr; + _LIBCPP_HIDE_FROM_ABI ErrorHandler(const char* fname, error_code* ec, const path* p1 = nullptr, const path* p2 = nullptr) : func_name_(fname), ec_(ec), p1_(p1), p2_(p2) { @@ -162,6 +155,7 @@ ec_->clear(); } + _LIBCPP_HIDE_FROM_ABI T report(const error_code& ec) const { if (ec_) { *ec_ = ec; @@ -179,7 +173,7 @@ __libcpp_unreachable(); } - _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 0) void report_impl(const error_code& ec, const char* msg, va_list ap) const { if (ec_) { *ec_ = ec; @@ -198,7 +192,7 @@ __libcpp_unreachable(); } - _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) T report(const error_code& ec, const char* msg, ...) const { va_list ap; va_start(ap, msg); @@ -216,11 +210,12 @@ return error_value(); } + _LIBCPP_HIDE_FROM_ABI T report(errc const& err) const { return report(make_error_code(err)); } - _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) + _LIBCPP_HIDE_FROM_ABI _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 3, 4) T report(errc const& err, const char* msg, ...) const { va_list ap; va_start(ap, msg); @@ -265,6 +260,7 @@ uint64_t st_dev; // FILE_ID_INFO::VolumeSerialNumber struct FileIdStruct { unsigned char id[16]; // FILE_ID_INFO::FileId + _LIBCPP_HIDE_FROM_ABI bool operator==(const FileIdStruct &other) const { for (int i = 0; i < 16; i++) if (id[i] != other.id[i]) @@ -309,7 +305,7 @@ .count(); private: - static _LIBCPP_CONSTEXPR_SINCE_CXX14 fs_duration get_min_nsecs() { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 fs_duration get_min_nsecs() { return duration_cast( fs_nanoseconds(min_nsec_timespec) - duration_cast(fs_seconds(1))); @@ -319,7 +315,7 @@ FileTimeT::duration::min(), "value doesn't roundtrip"); - static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool check_range() { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool check_range() { // This kinda sucks, but it's what happens when we don't have __int128_t. if (sizeof(TimeT) == sizeof(rep)) { typedef duration > Years; @@ -385,8 +381,8 @@ public: template - static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool checked_set(CType* out, - ChronoType time) { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool checked_set(CType* out, ChronoType time) { using Lim = numeric_limits; if (time > Lim::max() || time < Lim::min()) return false; @@ -394,7 +390,8 @@ return true; } - static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(TimeSpecT tm) { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool is_representable(TimeSpecT tm) { if (tm.tv_sec >= 0) { return tm.tv_sec < max_seconds || (tm.tv_sec == max_seconds && tm.tv_nsec <= max_nsec); @@ -405,7 +402,8 @@ } } - static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool is_representable(FileTimeT tm) { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool is_representable(FileTimeT tm) { auto secs = duration_cast(tm.time_since_epoch()); auto nsecs = duration_cast(tm.time_since_epoch() - secs); if (nsecs.count() < 0) { @@ -418,8 +416,8 @@ return secs.count() >= TLim::min(); } - static _LIBCPP_CONSTEXPR_SINCE_CXX14 FileTimeT - convert_from_timespec(TimeSpecT tm) { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + FileTimeT convert_from_timespec(TimeSpecT tm) { if (tm.tv_sec >= 0 || tm.tv_nsec == 0) { return FileTimeT(fs_seconds(tm.tv_sec) + duration_cast(fs_nanoseconds(tm.tv_nsec))); @@ -432,8 +430,8 @@ } template - static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool - set_times_checked(TimeT* sec_out, SubSecT* subsec_out, FileTimeT tp) { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool set_times_checked(TimeT* sec_out, SubSecT* subsec_out, FileTimeT tp) { auto dur = tp.time_since_epoch(); auto sec_dur = duration_cast(dur); auto subsec_dur = duration_cast(dur - sec_dur); @@ -449,8 +447,8 @@ return checked_set(sec_out, sec_dur.count()) && checked_set(subsec_out, subsec_dur.count()); } - static _LIBCPP_CONSTEXPR_SINCE_CXX14 bool convert_to_timespec(TimeSpecT& dest, - FileTimeT tp) { + static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 + bool convert_to_timespec(TimeSpecT& dest, FileTimeT tp) { if (!is_representable(tp)) return false; return set_times_checked(&dest.tv_sec, &dest.tv_nsec, tp); @@ -464,33 +462,34 @@ #endif #if defined(__APPLE__) -inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } -inline TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } +inline _LIBCPP_HIDE_FROM_ABI TimeSpec extract_mtime(StatT const& st) { return st.st_mtimespec; } +inline _LIBCPP_HIDE_FROM_ABI TimeSpec extract_atime(StatT const& st) { return st.st_atimespec; } #elif defined(__MVS__) -inline TimeSpec extract_mtime(StatT const& st) { +inline _LIBCPP_HIDE_FROM_ABI TimeSpec extract_mtime(StatT const& st) { TimeSpec TS = {st.st_mtime, 0}; return TS; } -inline TimeSpec extract_atime(StatT const& st) { +inline _LIBCPP_HIDE_FROM_ABI TimeSpec extract_atime(StatT const& st) { TimeSpec TS = {st.st_atime, 0}; return TS; } #elif defined(_AIX) -inline TimeSpec extract_mtime(StatT const& st) { +inline _LIBCPP_HIDE_FROM_ABI TimeSpec extract_mtime(StatT const& st) { TimeSpec TS = {st.st_mtime, st.st_mtime_n}; return TS; } -inline TimeSpec extract_atime(StatT const& st) { +inline _LIBCPP_HIDE_FROM_ABI TimeSpec extract_atime(StatT const& st) { TimeSpec TS = {st.st_atime, st.st_atime_n}; return TS; } #else -inline TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } -inline TimeSpec extract_atime(StatT const& st) { return st.st_atim; } +inline _LIBCPP_HIDE_FROM_ABI TimeSpec extract_mtime(StatT const& st) { return st.st_mtim; } +inline _LIBCPP_HIDE_FROM_ABI TimeSpec extract_atime(StatT const& st) { return st.st_atim; } #endif #if !defined(_LIBCPP_WIN32API) -inline TimeVal make_timeval(TimeSpec const& ts) { +inline _LIBCPP_HIDE_FROM_ABI +TimeVal make_timeval(TimeSpec const& ts) { using namespace chrono; auto Convert = [](long nsec) { using int_type = decltype(std::declval().tv_usec); @@ -503,7 +502,8 @@ return TV; } -inline bool posix_utimes(const path& p, std::array const& TS, +inline _LIBCPP_HIDE_FROM_ABI +bool posix_utimes(const path& p, std::array const& TS, error_code& ec) { TimeVal ConvertedTS[2] = {make_timeval(TS[0]), make_timeval(TS[1])}; if (::utimes(p.c_str(), ConvertedTS) == -1) { @@ -514,6 +514,7 @@ } #if defined(_LIBCPP_USE_UTIMENSAT) +inline _LIBCPP_HIDE_FROM_ABI bool posix_utimensat(const path& p, std::array const& TS, error_code& ec) { if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1) { @@ -524,6 +525,7 @@ } #endif +inline _LIBCPP_HIDE_FROM_ABI bool set_file_times(const path& p, std::array const& TS, error_code& ec) { #if !defined(_LIBCPP_USE_UTIMENSAT) @@ -535,7 +537,7 @@ #if defined(DT_BLK) template -static file_type get_file_type(DirEntT* ent, int) { +_LIBCPP_HIDE_FROM_ABI file_type get_file_type(DirEntT* ent, int) { switch (ent->d_type) { case DT_BLK: return file_type::block; @@ -562,12 +564,13 @@ #endif // defined(DT_BLK) template -static file_type get_file_type(DirEntT*, long) { +_LIBCPP_HIDE_FROM_ABI file_type get_file_type(DirEntT*, long) { return file_type::none; } -static pair posix_readdir(DIR* dir_stream, - error_code& ec) { +inline _LIBCPP_HIDE_FROM_ABI +pair posix_readdir(DIR* dir_stream, + error_code& ec) { struct dirent* dir_entry_ptr = nullptr; errno = 0; // zero errno in order to detect errors ec.clear(); @@ -582,7 +585,8 @@ #else // _LIBCPP_WIN32API -static file_type get_file_type(const WIN32_FIND_DATAW& data) { +inline _LIBCPP_HIDE_FROM_ABI +file_type get_file_type(const WIN32_FIND_DATAW& data) { if (data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && data.dwReserved0 == IO_REPARSE_TAG_SYMLINK) return file_type::symlink; @@ -590,10 +594,12 @@ return file_type::directory; return file_type::regular; } -static uintmax_t get_file_size(const WIN32_FIND_DATAW& data) { +inline _LIBCPP_HIDE_FROM_ABI +uintmax_t get_file_size(const WIN32_FIND_DATAW& data) { return (static_cast(data.nFileSizeHigh) << 32) + data.nFileSizeLow; } -static file_time_type get_write_time(const WIN32_FIND_DATAW& data) { +inline _LIBCPP_HIDE_FROM_ABI +file_time_type get_write_time(const WIN32_FIND_DATAW& data) { ULARGE_INTEGER tmp; const FILETIME& time = data.ftLastWriteTime; tmp.u.LowPart = time.dwLowDateTime; @@ -603,8 +609,9 @@ #endif // !_LIBCPP_WIN32API -file_time_type __extract_last_write_time(const path& p, const StatT& st, - error_code* ec) { +inline file_time_type _LIBCPP_HIDE_FROM_ABI +__extract_last_write_time(const path& p, const StatT& st, + error_code* ec) { using detail::fs_time; ErrorHandler err("last_write_time", ec, &p); @@ -618,8 +625,8 @@ // POSIX HELPERS #if defined(_LIBCPP_WIN32API) -namespace detail { +inline _LIBCPP_HIDE_FROM_ABI errc __win_err_to_errc(int err) { constexpr struct { DWORD win; @@ -682,7 +689,6 @@ return errc::invalid_argument; } -} // namespace detail #endif using value_type = path::value_type; @@ -695,7 +701,8 @@ file_status m_status; template - static FileDescriptor create(const path* p, error_code& ec, Args... args) { + static _LIBCPP_HIDE_FROM_ABI + FileDescriptor create(const path* p, error_code& ec, Args... args) { ec.clear(); int fd; if ((fd = detail::open(p->c_str(), args...)) == -1) { @@ -706,7 +713,8 @@ } template - static FileDescriptor create_with_status(const path* p, error_code& ec, + static _LIBCPP_HIDE_FROM_ABI + FileDescriptor create_with_status(const path* p, error_code& ec, Args... args) { FileDescriptor fd = create(p, ec, args...); if (!ec) @@ -715,19 +723,21 @@ return fd; } - file_status get_status() const { return m_status; } - StatT const& get_stat() const { return m_stat; } + _LIBCPP_HIDE_FROM_ABI file_status get_status() const { return m_status; } + _LIBCPP_HIDE_FROM_ABI StatT const& get_stat() const { return m_stat; } - bool status_known() const { return _VSTD_FS::status_known(m_status); } + _LIBCPP_HIDE_FROM_ABI bool status_known() const { return _VSTD_FS::status_known(m_status); } - file_status refresh_status(error_code& ec); + _LIBCPP_HIDE_FROM_ABI file_status refresh_status(error_code& ec); + _LIBCPP_HIDE_FROM_ABI void close() noexcept { if (fd != -1) detail::close(fd); fd = -1; } + _LIBCPP_HIDE_FROM_ABI FileDescriptor(FileDescriptor&& other) : name(other.name), fd(other.fd), m_stat(other.m_stat), m_status(other.m_status) { @@ -735,19 +745,21 @@ other.m_status = file_status{}; } - ~FileDescriptor() { close(); } + _LIBCPP_HIDE_FROM_ABI ~FileDescriptor() { close(); } FileDescriptor(FileDescriptor const&) = delete; FileDescriptor& operator=(FileDescriptor const&) = delete; private: - explicit FileDescriptor(const path* p, int fd = -1) : name(*p), fd(fd) {} + _LIBCPP_HIDE_FROM_ABI explicit FileDescriptor(const path* p, int fd = -1) : name(*p), fd(fd) {} }; +inline _LIBCPP_HIDE_FROM_ABI perms posix_get_perms(const StatT& st) noexcept { return static_cast(st.st_mode) & perms::mask; } +inline _LIBCPP_HIDE_FROM_ABI file_status create_file_status(error_code& m_ec, path const& p, const StatT& path_stat, error_code* ec) { if (ec) @@ -784,6 +796,7 @@ return fs_tmp; } +inline _LIBCPP_HIDE_FROM_ABI file_status posix_stat(path const& p, StatT& path_stat, error_code* ec) { error_code m_ec; if (detail::stat(p.c_str(), &path_stat) == -1) @@ -791,11 +804,13 @@ return create_file_status(m_ec, p, path_stat, ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status posix_stat(path const& p, error_code* ec) { StatT path_stat; return posix_stat(p, path_stat, ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status posix_lstat(path const& p, StatT& path_stat, error_code* ec) { error_code m_ec; if (detail::lstat(p.c_str(), &path_stat) == -1) @@ -803,12 +818,14 @@ return create_file_status(m_ec, p, path_stat, ec); } +inline _LIBCPP_HIDE_FROM_ABI file_status posix_lstat(path const& p, error_code* ec) { StatT path_stat; return posix_lstat(p, path_stat, ec); } // http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html +inline _LIBCPP_HIDE_FROM_ABI bool posix_ftruncate(const FileDescriptor& fd, off_t to_size, error_code& ec) { if (detail::ftruncate(fd.fd, to_size) == -1) { ec = capture_errno(); @@ -818,6 +835,7 @@ return false; } +inline _LIBCPP_HIDE_FROM_ABI bool posix_fchmod(const FileDescriptor& fd, const StatT& st, error_code& ec) { if (detail::fchmod(fd.fd, st.st_mode) == -1) { ec = capture_errno(); @@ -827,10 +845,12 @@ return false; } +inline _LIBCPP_HIDE_FROM_ABI bool stat_equivalent(const StatT& st1, const StatT& st2) { return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino); } +inline _LIBCPP_HIDE_FROM_ABI file_status FileDescriptor::refresh_status(error_code& ec) { // FD must be open and good. m_status = file_status{}; @@ -842,11 +862,8 @@ return m_status; } -} // namespace } // end namespace detail _LIBCPP_END_NAMESPACE_FILESYSTEM -_LIBCPP_DIAGNOSTIC_POP - #endif // FILESYSTEM_COMMON_H diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp --- a/libcxx/src/filesystem/operations.cpp +++ b/libcxx/src/filesystem/operations.cpp @@ -347,7 +347,7 @@ return err.report(m_ec); } - if (!copy_file_impl(from_fd, to_fd, m_ec)) { + if (!detail::copy_file_impl(from_fd, to_fd, m_ec)) { // FIXME: Remove the dest file if we failed, and it didn't exist previously. return err.report(m_ec); } diff --git a/libcxx/src/filesystem/path_parser.h b/libcxx/src/filesystem/path_parser.h --- a/libcxx/src/filesystem/path_parser.h +++ b/libcxx/src/filesystem/path_parser.h @@ -21,8 +21,7 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM -namespace { - +inline _LIBCPP_HIDE_FROM_ABI bool isSeparator(path::value_type C) { if (C == '/') return true; @@ -33,6 +32,7 @@ return false; } +inline _LIBCPP_HIDE_FROM_ABI bool isDriveLetter(path::value_type C) { return (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z'); } @@ -59,32 +59,38 @@ ParserState State; private: + _LIBCPP_HIDE_FROM_ABI PathParser(string_view_t P, ParserState State) noexcept : Path(P), State(State) {} public: + _LIBCPP_HIDE_FROM_ABI PathParser(string_view_t P, string_view_t E, unsigned char S) : Path(P), RawEntry(E), State(static_cast(S)) { // S cannot be '0' or PS_BeforeBegin. } + _LIBCPP_HIDE_FROM_ABI static PathParser CreateBegin(string_view_t P) noexcept { PathParser PP(P, PS_BeforeBegin); PP.increment(); return PP; } + _LIBCPP_HIDE_FROM_ABI static PathParser CreateEnd(string_view_t P) noexcept { PathParser PP(P, PS_AtEnd); return PP; } + _LIBCPP_HIDE_FROM_ABI PosPtr peek() const noexcept { auto TkEnd = getNextTokenStartPos(); auto End = getAfterBack(); return TkEnd == End ? nullptr : TkEnd; } + _LIBCPP_HIDE_FROM_ABI void increment() noexcept { const PosPtr End = getAfterBack(); const PosPtr Start = getNextTokenStartPos(); @@ -126,6 +132,7 @@ } } + _LIBCPP_HIDE_FROM_ABI void decrement() noexcept { const PosPtr REnd = getBeforeFront(); const PosPtr RStart = getCurrentTokenStartPos() - 1; @@ -176,6 +183,7 @@ /// \brief Return a view with the "preferred representation" of the current /// element. For example trailing separators are represented as a '.' + _LIBCPP_HIDE_FROM_ABI string_view_t operator*() const noexcept { switch (State) { case PS_BeforeBegin: @@ -195,52 +203,62 @@ __libcpp_unreachable(); } + _LIBCPP_HIDE_FROM_ABI explicit operator bool() const noexcept { return State != PS_BeforeBegin && State != PS_AtEnd; } + _LIBCPP_HIDE_FROM_ABI PathParser& operator++() noexcept { increment(); return *this; } + _LIBCPP_HIDE_FROM_ABI PathParser& operator--() noexcept { decrement(); return *this; } + _LIBCPP_HIDE_FROM_ABI bool atEnd() const noexcept { return State == PS_AtEnd; } + _LIBCPP_HIDE_FROM_ABI bool inRootDir() const noexcept { return State == PS_InRootDir; } + _LIBCPP_HIDE_FROM_ABI bool inRootName() const noexcept { return State == PS_InRootName; } + _LIBCPP_HIDE_FROM_ABI bool inRootPath() const noexcept { return inRootName() || inRootDir(); } private: + _LIBCPP_HIDE_FROM_ABI void makeState(ParserState NewState, PosPtr Start, PosPtr End) noexcept { State = NewState; RawEntry = string_view_t(Start, End - Start); } + _LIBCPP_HIDE_FROM_ABI void makeState(ParserState NewState) noexcept { State = NewState; RawEntry = {}; } - PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); } + _LIBCPP_HIDE_FROM_ABI PosPtr getAfterBack() const noexcept { return Path.data() + Path.size(); } - PosPtr getBeforeFront() const noexcept { return Path.data() - 1; } + _LIBCPP_HIDE_FROM_ABI PosPtr getBeforeFront() const noexcept { return Path.data() - 1; } /// \brief Return a pointer to the first character after the currently /// lexed element. + _LIBCPP_HIDE_FROM_ABI PosPtr getNextTokenStartPos() const noexcept { switch (State) { case PS_BeforeBegin: @@ -258,6 +276,7 @@ /// \brief Return a pointer to the first character in the currently lexed /// element. + _LIBCPP_HIDE_FROM_ABI PosPtr getCurrentTokenStartPos() const noexcept { switch (State) { case PS_BeforeBegin: @@ -274,6 +293,7 @@ } // Consume all consecutive separators. + _LIBCPP_HIDE_FROM_ABI PosPtr consumeAllSeparators(PosPtr P, PosPtr End) const noexcept { if (P == nullptr || P == End || !isSeparator(*P)) return nullptr; @@ -285,6 +305,7 @@ } // Consume exactly N separators, or return nullptr. + _LIBCPP_HIDE_FROM_ABI PosPtr consumeNSeparators(PosPtr P, PosPtr End, int N) const noexcept { PosPtr Ret = consumeAllSeparators(P, End); if (Ret == nullptr) @@ -299,6 +320,7 @@ return nullptr; } + _LIBCPP_HIDE_FROM_ABI PosPtr consumeName(PosPtr P, PosPtr End) const noexcept { PosPtr Start = P; if (P == nullptr || P == End || isSeparator(*P)) @@ -318,6 +340,7 @@ return P; } + _LIBCPP_HIDE_FROM_ABI PosPtr consumeDriveLetter(PosPtr P, PosPtr End) const noexcept { if (P == End) return nullptr; @@ -332,6 +355,7 @@ } } + _LIBCPP_HIDE_FROM_ABI PosPtr consumeNetworkRoot(PosPtr P, PosPtr End) const noexcept { if (P == End) return nullptr; @@ -341,6 +365,7 @@ return consumeNSeparators(consumeName(P, End), End, 2); } + _LIBCPP_HIDE_FROM_ABI PosPtr consumeRootName(PosPtr P, PosPtr End) const noexcept { #if defined(_LIBCPP_WIN32API) if (PosPtr Ret = consumeDriveLetter(P, End)) @@ -352,6 +377,7 @@ } }; +inline _LIBCPP_HIDE_FROM_ABI string_view_pair separate_filename(string_view_t const& s) { if (s == PATHSTR(".") || s == PATHSTR("..") || s.empty()) return string_view_pair{s, PATHSTR("")}; @@ -361,12 +387,12 @@ return string_view_pair{s.substr(0, pos), s.substr(pos)}; } +inline _LIBCPP_HIDE_FROM_ABI string_view_t createView(PosPtr S, PosPtr E) noexcept { return {S, static_cast(E - S) + 1}; } } // namespace parser -} // namespace _LIBCPP_END_NAMESPACE_FILESYSTEM diff --git a/libcxx/src/filesystem/posix_compat.h b/libcxx/src/filesystem/posix_compat.h --- a/libcxx/src/filesystem/posix_compat.h +++ b/libcxx/src/filesystem/posix_compat.h @@ -75,7 +75,6 @@ _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM namespace detail { -namespace { #if defined(_LIBCPP_WIN32API) @@ -124,6 +123,7 @@ // (1601) to the Unix epoch (1970). #define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60)) +inline _LIBCPP_HIDE_FROM_ABI TimeSpec filetime_to_timespec(LARGE_INTEGER li) { TimeSpec ret; ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS; @@ -131,6 +131,7 @@ return ret; } +inline _LIBCPP_HIDE_FROM_ABI TimeSpec filetime_to_timespec(FILETIME ft) { LARGE_INTEGER li; li.LowPart = ft.dwLowDateTime; @@ -138,6 +139,7 @@ return filetime_to_timespec(li); } +inline _LIBCPP_HIDE_FROM_ABI FILETIME timespec_to_filetime(TimeSpec ts) { LARGE_INTEGER li; li.QuadPart = @@ -148,6 +150,7 @@ return ft; } +inline _LIBCPP_HIDE_FROM_ABI int set_errno(int e = GetLastError()) { errno = static_cast(__win_err_to_errc(e)); return -1; @@ -155,22 +158,25 @@ class WinHandle { public: + _LIBCPP_HIDE_FROM_ABI WinHandle(const wchar_t *p, DWORD access, DWORD flags) { h = CreateFileW( p, access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | flags, nullptr); } + _LIBCPP_HIDE_FROM_ABI ~WinHandle() { if (h != INVALID_HANDLE_VALUE) CloseHandle(h); } - operator HANDLE() const { return h; } - operator bool() const { return h != INVALID_HANDLE_VALUE; } + _LIBCPP_HIDE_FROM_ABI operator HANDLE() const { return h; } + _LIBCPP_HIDE_FROM_ABI operator bool() const { return h != INVALID_HANDLE_VALUE; } private: HANDLE h; }; +inline _LIBCPP_HIDE_FROM_ABI int stat_handle(HANDLE h, StatT *buf) { FILE_BASIC_INFO basic; if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) @@ -209,6 +215,7 @@ return 0; } +inline _LIBCPP_HIDE_FROM_ABI int stat_file(const wchar_t *path, StatT *buf, DWORD flags) { WinHandle h(path, FILE_READ_ATTRIBUTES, flags); if (!h) @@ -217,22 +224,27 @@ return ret; } +inline _LIBCPP_HIDE_FROM_ABI int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); } +inline _LIBCPP_HIDE_FROM_ABI int lstat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT); } +inline _LIBCPP_HIDE_FROM_ABI int fstat(int fd, StatT *buf) { HANDLE h = reinterpret_cast(_get_osfhandle(fd)); return stat_handle(h, buf); } +inline _LIBCPP_HIDE_FROM_ABI int mkdir(const wchar_t *path, int permissions) { (void)permissions; return _wmkdir(path); } +inline _LIBCPP_HIDE_FROM_ABI int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname, bool is_dir) { path dest(oldname); @@ -250,20 +262,24 @@ return set_errno(); } +inline _LIBCPP_HIDE_FROM_ABI int symlink_file(const wchar_t *oldname, const wchar_t *newname) { return symlink_file_dir(oldname, newname, false); } +inline _LIBCPP_HIDE_FROM_ABI int symlink_dir(const wchar_t *oldname, const wchar_t *newname) { return symlink_file_dir(oldname, newname, true); } +inline _LIBCPP_HIDE_FROM_ABI int link(const wchar_t *oldname, const wchar_t *newname) { if (CreateHardLinkW(newname, oldname, nullptr)) return 0; return set_errno(); } +inline _LIBCPP_HIDE_FROM_ABI int remove(const wchar_t *path) { detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT); if (!h) @@ -275,6 +291,7 @@ return 0; } +inline _LIBCPP_HIDE_FROM_ABI int truncate_handle(HANDLE h, off_t length) { LARGE_INTEGER size_param; size_param.QuadPart = length; @@ -285,11 +302,13 @@ return 0; } +inline _LIBCPP_HIDE_FROM_ABI int ftruncate(int fd, off_t length) { HANDLE h = reinterpret_cast(_get_osfhandle(fd)); return truncate_handle(h, length); } +inline _LIBCPP_HIDE_FROM_ABI int truncate(const wchar_t *path, off_t length) { detail::WinHandle h(path, GENERIC_WRITE, 0); if (!h) @@ -297,6 +316,7 @@ return truncate_handle(h, length); } +inline _LIBCPP_HIDE_FROM_ABI int rename(const wchar_t *from, const wchar_t *to) { if (!(MoveFileExW(from, to, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING | @@ -305,11 +325,12 @@ return 0; } -template int open(const wchar_t *filename, Args... args) { +template +_LIBCPP_HIDE_FROM_ABI int open(const wchar_t *filename, Args... args) { return _wopen(filename, args...); } -int close(int fd) { return _close(fd); } -int chdir(const wchar_t *path) { return _wchdir(path); } +inline _LIBCPP_HIDE_FROM_ABI int close(int fd) { return _close(fd); } +inline _LIBCPP_HIDE_FROM_ABI int chdir(const wchar_t *path) { return _wchdir(path); } struct StatVFS { uint64_t f_frsize; @@ -318,6 +339,7 @@ uint64_t f_bavail; }; +inline _LIBCPP_HIDE_FROM_ABI int statvfs(const wchar_t *p, StatVFS *buf) { path dir = p; while (true) { @@ -344,8 +366,10 @@ return 0; } +inline _LIBCPP_HIDE_FROM_ABI wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); } +inline _LIBCPP_HIDE_FROM_ABI wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) { // Only expected to be used with us allocating the buffer. _LIBCPP_ASSERT(resolved_name == nullptr, @@ -387,6 +411,7 @@ #define AT_SYMLINK_NOFOLLOW 1 using ModeT = int; +inline _LIBCPP_HIDE_FROM_ABI int fchmod_handle(HANDLE h, int perms) { FILE_BASIC_INFO basic; if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic))) @@ -401,6 +426,7 @@ return 0; } +inline _LIBCPP_HIDE_FROM_ABI int fchmodat(int fd, const wchar_t *path, int perms, int flag) { DWORD attributes = GetFileAttributesW(path); if (attributes == INVALID_FILE_ATTRIBUTES) @@ -428,6 +454,7 @@ return 0; } +inline _LIBCPP_HIDE_FROM_ABI int fchmod(int fd, int perms) { HANDLE h = reinterpret_cast(_get_osfhandle(fd)); return fchmod_handle(h, perms); @@ -436,6 +463,7 @@ #define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE using SSizeT = ::int64_t; +inline _LIBCPP_HIDE_FROM_ABI SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) { uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT); @@ -480,9 +508,11 @@ } #else +inline _LIBCPP_HIDE_FROM_ABI int symlink_file(const char *oldname, const char *newname) { return ::symlink(oldname, newname); } +inline _LIBCPP_HIDE_FROM_ABI int symlink_dir(const char *oldname, const char *newname) { return ::symlink(oldname, newname); } @@ -515,7 +545,6 @@ #endif -} // namespace } // end namespace detail _LIBCPP_END_NAMESPACE_FILESYSTEM