1 //===- llvm/Support/FileSystem.h - File System OS Concept -------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file declares the llvm::sys::fs namespace. It is designed after 11 // TR2/boost filesystem (v3), but modified to remove exception handling and the 12 // path class. 13 // 14 // All functions return an error_code and their actual work via the last out 15 // argument. The out argument is defined if and only if errc::success is 16 // returned. A function may return any error code in the generic or system 17 // category. However, they shall be equivalent to any error conditions listed 18 // in each functions respective documentation if the condition applies. [ note: 19 // this does not guarantee that error_code will be in the set of explicitly 20 // listed codes, but it does guarantee that if any of the explicitly listed 21 // errors occur, the correct error_code will be used ]. All functions may 22 // return errc::not_enough_memory if there is not enough memory to complete the 23 // operation. 24 // 25 //===----------------------------------------------------------------------===// 26 27 #ifndef LLVM_SUPPORT_FILESYSTEM_H 28 #define LLVM_SUPPORT_FILESYSTEM_H 29 30 #include "llvm/ADT/SmallString.h" 31 #include "llvm/ADT/StringRef.h" 32 #include "llvm/ADT/Twine.h" 33 #include "llvm/Config/llvm-config.h" 34 #include "llvm/Support/Chrono.h" 35 #include "llvm/Support/Error.h" 36 #include "llvm/Support/ErrorHandling.h" 37 #include "llvm/Support/ErrorOr.h" 38 #include "llvm/Support/MD5.h" 39 #include <cassert> 40 #include <cstdint> 41 #include <ctime> 42 #include <memory> 43 #include <stack> 44 #include <string> 45 #include <system_error> 46 #include <tuple> 47 #include <vector> 48 49 #ifdef HAVE_SYS_STAT_H 50 #include <sys/stat.h> 51 #endif 52 53 namespace llvm { 54 namespace sys { 55 namespace fs { 56 57 #if defined(_WIN32) 58 // A Win32 HANDLE is a typedef of void* 59 using file_t = void *; 60 #else 61 using file_t = int; 62 #endif 63 64 extern const file_t kInvalidFile; 65 66 /// An enumeration for the file system's view of the type. 67 enum class file_type { 68 status_error, 69 file_not_found, 70 regular_file, 71 directory_file, 72 symlink_file, 73 block_file, 74 character_file, 75 fifo_file, 76 socket_file, 77 type_unknown 78 }; 79 80 /// space_info - Self explanatory. 81 struct space_info { 82 uint64_t capacity; 83 uint64_t free; 84 uint64_t available; 85 }; 86 87 enum perms { 88 no_perms = 0, 89 owner_read = 0400, 90 owner_write = 0200, 91 owner_exe = 0100, 92 owner_all = owner_read | owner_write | owner_exe, 93 group_read = 040, 94 group_write = 020, 95 group_exe = 010, 96 group_all = group_read | group_write | group_exe, 97 others_read = 04, 98 others_write = 02, 99 others_exe = 01, 100 others_all = others_read | others_write | others_exe, 101 all_read = owner_read | group_read | others_read, 102 all_write = owner_write | group_write | others_write, 103 all_exe = owner_exe | group_exe | others_exe, 104 all_all = owner_all | group_all | others_all, 105 set_uid_on_exe = 04000, 106 set_gid_on_exe = 02000, 107 sticky_bit = 01000, 108 all_perms = all_all | set_uid_on_exe | set_gid_on_exe | sticky_bit, 109 perms_not_known = 0xFFFF 110 }; 111 112 // Helper functions so that you can use & and | to manipulate perms bits: 113 inline perms operator|(perms l, perms r) { 114 return static_cast<perms>(static_cast<unsigned short>(l) | 115 static_cast<unsigned short>(r)); 116 } 117 inline perms operator&(perms l, perms r) { 118 return static_cast<perms>(static_cast<unsigned short>(l) & 119 static_cast<unsigned short>(r)); 120 } 121 inline perms &operator|=(perms &l, perms r) { 122 l = l | r; 123 return l; 124 } 125 inline perms &operator&=(perms &l, perms r) { 126 l = l & r; 127 return l; 128 } 129 inline perms operator~(perms x) { 130 // Avoid UB by explicitly truncating the (unsigned) ~ result. 131 return static_cast<perms>( 132 static_cast<unsigned short>(~static_cast<unsigned short>(x))); 133 } 134 135 class UniqueID { 136 uint64_t Device; 137 uint64_t File; 138 139 public: 140 UniqueID() = default; 141 UniqueID(uint64_t Device, uint64_t File) : Device(Device), File(File) {} 142 143 bool operator==(const UniqueID &Other) const { 144 return Device == Other.Device && File == Other.File; 145 } 146 bool operator!=(const UniqueID &Other) const { return !(*this == Other); } 147 bool operator<(const UniqueID &Other) const { 148 return std::tie(Device, File) < std::tie(Other.Device, Other.File); 149 } 150 151 uint64_t getDevice() const { return Device; } 152 uint64_t getFile() const { return File; } 153 }; 154 155 /// Represents the result of a call to directory_iterator::status(). This is a 156 /// subset of the information returned by a regular sys::fs::status() call, and 157 /// represents the information provided by Windows FileFirstFile/FindNextFile. 158 class basic_file_status { 159 protected: 160 #if defined(LLVM_ON_UNIX) 161 time_t fs_st_atime = 0; 162 time_t fs_st_mtime = 0; 163 uid_t fs_st_uid = 0; 164 gid_t fs_st_gid = 0; 165 off_t fs_st_size = 0; 166 #elif defined (_WIN32) 167 uint32_t LastAccessedTimeHigh = 0; 168 uint32_t LastAccessedTimeLow = 0; 169 uint32_t LastWriteTimeHigh = 0; 170 uint32_t LastWriteTimeLow = 0; 171 uint32_t FileSizeHigh = 0; 172 uint32_t FileSizeLow = 0; 173 #endif 174 file_type Type = file_type::status_error; 175 perms Perms = perms_not_known; 176 177 public: 178 basic_file_status() = default; 179 180 explicit basic_file_status(file_type Type) : Type(Type) {} 181 182 #if defined(LLVM_ON_UNIX) 183 basic_file_status(file_type Type, perms Perms, time_t ATime, time_t MTime, 184 uid_t UID, gid_t GID, off_t Size) 185 : fs_st_atime(ATime), fs_st_mtime(MTime), fs_st_uid(UID), fs_st_gid(GID), 186 fs_st_size(Size), Type(Type), Perms(Perms) {} 187 #elif defined(_WIN32) 188 basic_file_status(file_type Type, perms Perms, uint32_t LastAccessTimeHigh, 189 uint32_t LastAccessTimeLow, uint32_t LastWriteTimeHigh, 190 uint32_t LastWriteTimeLow, uint32_t FileSizeHigh, 191 uint32_t FileSizeLow) 192 : LastAccessedTimeHigh(LastAccessTimeHigh), 193 LastAccessedTimeLow(LastAccessTimeLow), 194 LastWriteTimeHigh(LastWriteTimeHigh), 195 LastWriteTimeLow(LastWriteTimeLow), FileSizeHigh(FileSizeHigh), 196 FileSizeLow(FileSizeLow), Type(Type), Perms(Perms) {} 197 #endif 198 199 // getters 200 file_type type() const { return Type; } 201 perms permissions() const { return Perms; } 202 TimePoint<> getLastAccessedTime() const; 203 TimePoint<> getLastModificationTime() const; 204 205 #if defined(LLVM_ON_UNIX) 206 uint32_t getUser() const { return fs_st_uid; } 207 uint32_t getGroup() const { return fs_st_gid; } 208 uint64_t getSize() const { return fs_st_size; } 209 #elif defined (_WIN32) 210 uint32_t getUser() const { 211 return 9999; // Not applicable to Windows, so... 212 } 213 214 uint32_t getGroup() const { 215 return 9999; // Not applicable to Windows, so... 216 } 217 218 uint64_t getSize() const { 219 return (uint64_t(FileSizeHigh) << 32) + FileSizeLow; 220 } 221 #endif 222 223 // setters 224 void type(file_type v) { Type = v; } 225 void permissions(perms p) { Perms = p; } 226 }; 227 228 /// Represents the result of a call to sys::fs::status(). 229 class file_status : public basic_file_status { 230 friend bool equivalent(file_status A, file_status B); 231 232 #if defined(LLVM_ON_UNIX) 233 dev_t fs_st_dev = 0; 234 nlink_t fs_st_nlinks = 0; 235 ino_t fs_st_ino = 0; 236 #elif defined (_WIN32) 237 uint32_t NumLinks = 0; 238 uint32_t VolumeSerialNumber = 0; 239 uint32_t FileIndexHigh = 0; 240 uint32_t FileIndexLow = 0; 241 #endif 242 243 public: 244 file_status() = default; 245 246 explicit file_status(file_type Type) : basic_file_status(Type) {} 247 248 #if defined(LLVM_ON_UNIX) 249 file_status(file_type Type, perms Perms, dev_t Dev, nlink_t Links, ino_t Ino, 250 time_t ATime, time_t MTime, uid_t UID, gid_t GID, off_t Size) 251 : basic_file_status(Type, Perms, ATime, MTime, UID, GID, Size), 252 fs_st_dev(Dev), fs_st_nlinks(Links), fs_st_ino(Ino) {} 253 #elif defined(_WIN32) 254 file_status(file_type Type, perms Perms, uint32_t LinkCount, 255 uint32_t LastAccessTimeHigh, uint32_t LastAccessTimeLow, 256 uint32_t LastWriteTimeHigh, uint32_t LastWriteTimeLow, 257 uint32_t VolumeSerialNumber, uint32_t FileSizeHigh, 258 uint32_t FileSizeLow, uint32_t FileIndexHigh, 259 uint32_t FileIndexLow) 260 : basic_file_status(Type, Perms, LastAccessTimeHigh, LastAccessTimeLow, 261 LastWriteTimeHigh, LastWriteTimeLow, FileSizeHigh, 262 FileSizeLow), 263 NumLinks(LinkCount), VolumeSerialNumber(VolumeSerialNumber), 264 FileIndexHigh(FileIndexHigh), FileIndexLow(FileIndexLow) {} 265 #endif 266 267 UniqueID getUniqueID() const; 268 uint32_t getLinkCount() const; 269 }; 270 271 /// @} 272 /// @name Physical Operators 273 /// @{ 274 275 /// Make \a path an absolute path. 276 /// 277 /// Makes \a path absolute using the \a current_directory if it is not already. 278 /// An empty \a path will result in the \a current_directory. 279 /// 280 /// /absolute/path => /absolute/path 281 /// relative/../path => <current-directory>/relative/../path 282 /// 283 /// @param path A path that is modified to be an absolute path. 284 /// @returns errc::success if \a path has been made absolute, otherwise a 285 /// platform-specific error_code. 286 std::error_code make_absolute(const Twine ¤t_directory, 287 SmallVectorImpl<char> &path); 288 289 /// Make \a path an absolute path. 290 /// 291 /// Makes \a path absolute using the current directory if it is not already. An 292 /// empty \a path will result in the current directory. 293 /// 294 /// /absolute/path => /absolute/path 295 /// relative/../path => <current-directory>/relative/../path 296 /// 297 /// @param path A path that is modified to be an absolute path. 298 /// @returns errc::success if \a path has been made absolute, otherwise a 299 /// platform-specific error_code. 300 std::error_code make_absolute(SmallVectorImpl<char> &path); 301 302 /// Create all the non-existent directories in path. 303 /// 304 /// @param path Directories to create. 305 /// @returns errc::success if is_directory(path), otherwise a platform 306 /// specific error_code. If IgnoreExisting is false, also returns 307 /// error if the directory already existed. 308 std::error_code create_directories(const Twine &path, 309 bool IgnoreExisting = true, 310 perms Perms = owner_all | group_all); 311 312 /// Create the directory in path. 313 /// 314 /// @param path Directory to create. 315 /// @returns errc::success if is_directory(path), otherwise a platform 316 /// specific error_code. If IgnoreExisting is false, also returns 317 /// error if the directory already existed. 318 std::error_code create_directory(const Twine &path, bool IgnoreExisting = true, 319 perms Perms = owner_all | group_all); 320 321 /// Create a link from \a from to \a to. 322 /// 323 /// The link may be a soft or a hard link, depending on the platform. The caller 324 /// may not assume which one. Currently on windows it creates a hard link since 325 /// soft links require extra privileges. On unix, it creates a soft link since 326 /// hard links don't work on SMB file systems. 327 /// 328 /// @param to The path to hard link to. 329 /// @param from The path to hard link from. This is created. 330 /// @returns errc::success if the link was created, otherwise a platform 331 /// specific error_code. 332 std::error_code create_link(const Twine &to, const Twine &from); 333 334 /// Create a hard link from \a from to \a to, or return an error. 335 /// 336 /// @param to The path to hard link to. 337 /// @param from The path to hard link from. This is created. 338 /// @returns errc::success if the link was created, otherwise a platform 339 /// specific error_code. 340 std::error_code create_hard_link(const Twine &to, const Twine &from); 341 342 /// Collapse all . and .. patterns, resolve all symlinks, and optionally 343 /// expand ~ expressions to the user's home directory. 344 /// 345 /// @param path The path to resolve. 346 /// @param output The location to store the resolved path. 347 /// @param expand_tilde If true, resolves ~ expressions to the user's home 348 /// directory. 349 std::error_code real_path(const Twine &path, SmallVectorImpl<char> &output, 350 bool expand_tilde = false); 351 352 /// Get the current path. 353 /// 354 /// @param result Holds the current path on return. 355 /// @returns errc::success if the current path has been stored in result, 356 /// otherwise a platform-specific error_code. 357 std::error_code current_path(SmallVectorImpl<char> &result); 358 359 /// Set the current path. 360 /// 361 /// @param path The path to set. 362 /// @returns errc::success if the current path was successfully set, 363 /// otherwise a platform-specific error_code. 364 std::error_code set_current_path(const Twine &path); 365 366 /// Remove path. Equivalent to POSIX remove(). 367 /// 368 /// @param path Input path. 369 /// @returns errc::success if path has been removed or didn't exist, otherwise a 370 /// platform-specific error code. If IgnoreNonExisting is false, also 371 /// returns error if the file didn't exist. 372 std::error_code remove(const Twine &path, bool IgnoreNonExisting = true); 373 374 /// Recursively delete a directory. 375 /// 376 /// @param path Input path. 377 /// @returns errc::success if path has been removed or didn't exist, otherwise a 378 /// platform-specific error code. 379 std::error_code remove_directories(const Twine &path, bool IgnoreErrors = true); 380 381 /// Rename \a from to \a to. 382 /// 383 /// Files are renamed as if by POSIX rename(), except that on Windows there may 384 /// be a short interval of time during which the destination file does not 385 /// exist. 386 /// 387 /// @param from The path to rename from. 388 /// @param to The path to rename to. This is created. 389 std::error_code rename(const Twine &from, const Twine &to); 390 391 /// Copy the contents of \a From to \a To. 392 /// 393 /// @param From The path to copy from. 394 /// @param To The path to copy to. This is created. 395 std::error_code copy_file(const Twine &From, const Twine &To); 396 397 /// Copy the contents of \a From to \a To. 398 /// 399 /// @param From The path to copy from. 400 /// @param ToFD The open file descriptor of the destination file. 401 std::error_code copy_file(const Twine &From, int ToFD); 402 403 /// Resize path to size. File is resized as if by POSIX truncate(). 404 /// 405 /// @param FD Input file descriptor. 406 /// @param Size Size to resize to. 407 /// @returns errc::success if \a path has been resized to \a size, otherwise a 408 /// platform-specific error_code. 409 std::error_code resize_file(int FD, uint64_t Size); 410 411 /// Compute an MD5 hash of a file's contents. 412 /// 413 /// @param FD Input file descriptor. 414 /// @returns An MD5Result with the hash computed, if successful, otherwise a 415 /// std::error_code. 416 ErrorOr<MD5::MD5Result> md5_contents(int FD); 417 418 /// Version of compute_md5 that doesn't require an open file descriptor. 419 ErrorOr<MD5::MD5Result> md5_contents(const Twine &Path); 420 421 /// @} 422 /// @name Physical Observers 423 /// @{ 424 425 /// Does file exist? 426 /// 427 /// @param status A basic_file_status previously returned from stat. 428 /// @returns True if the file represented by status exists, false if it does 429 /// not. 430 bool exists(const basic_file_status &status); 431 432 enum class AccessMode { Exist, Write, Execute }; 433 434 /// Can the file be accessed? 435 /// 436 /// @param Path Input path. 437 /// @returns errc::success if the path can be accessed, otherwise a 438 /// platform-specific error_code. 439 std::error_code access(const Twine &Path, AccessMode Mode); 440 441 /// Does file exist? 442 /// 443 /// @param Path Input path. 444 /// @returns True if it exists, false otherwise. 445 inline bool exists(const Twine &Path) { 446 return !access(Path, AccessMode::Exist); 447 } 448 449 /// Can we execute this file? 450 /// 451 /// @param Path Input path. 452 /// @returns True if we can execute it, false otherwise. 453 bool can_execute(const Twine &Path); 454 455 /// Can we write this file? 456 /// 457 /// @param Path Input path. 458 /// @returns True if we can write to it, false otherwise. 459 inline bool can_write(const Twine &Path) { 460 return !access(Path, AccessMode::Write); 461 } 462 463 /// Do file_status's represent the same thing? 464 /// 465 /// @param A Input file_status. 466 /// @param B Input file_status. 467 /// 468 /// assert(status_known(A) || status_known(B)); 469 /// 470 /// @returns True if A and B both represent the same file system entity, false 471 /// otherwise. 472 bool equivalent(file_status A, file_status B); 473 474 /// Do paths represent the same thing? 475 /// 476 /// assert(status_known(A) || status_known(B)); 477 /// 478 /// @param A Input path A. 479 /// @param B Input path B. 480 /// @param result Set to true if stat(A) and stat(B) have the same device and 481 /// inode (or equivalent). 482 /// @returns errc::success if result has been successfully set, otherwise a 483 /// platform-specific error_code. 484 std::error_code equivalent(const Twine &A, const Twine &B, bool &result); 485 486 /// Simpler version of equivalent for clients that don't need to 487 /// differentiate between an error and false. 488 inline bool equivalent(const Twine &A, const Twine &B) { 489 bool result; 490 return !equivalent(A, B, result) && result; 491 } 492 493 /// Is the file mounted on a local filesystem? 494 /// 495 /// @param path Input path. 496 /// @param result Set to true if \a path is on fixed media such as a hard disk, 497 /// false if it is not. 498 /// @returns errc::success if result has been successfully set, otherwise a 499 /// platform specific error_code. 500 std::error_code is_local(const Twine &path, bool &result); 501 502 /// Version of is_local accepting an open file descriptor. 503 std::error_code is_local(int FD, bool &result); 504 505 /// Simpler version of is_local for clients that don't need to 506 /// differentiate between an error and false. 507 inline bool is_local(const Twine &Path) { 508 bool Result; 509 return !is_local(Path, Result) && Result; 510 } 511 512 /// Simpler version of is_local accepting an open file descriptor for 513 /// clients that don't need to differentiate between an error and false. 514 inline bool is_local(int FD) { 515 bool Result; 516 return !is_local(FD, Result) && Result; 517 } 518 519 /// Does status represent a directory? 520 /// 521 /// @param Path The path to get the type of. 522 /// @param Follow For symbolic links, indicates whether to return the file type 523 /// of the link itself, or of the target. 524 /// @returns A value from the file_type enumeration indicating the type of file. 525 file_type get_file_type(const Twine &Path, bool Follow = true); 526 527 /// Does status represent a directory? 528 /// 529 /// @param status A basic_file_status previously returned from status. 530 /// @returns status.type() == file_type::directory_file. 531 bool is_directory(const basic_file_status &status); 532 533 /// Is path a directory? 534 /// 535 /// @param path Input path. 536 /// @param result Set to true if \a path is a directory (after following 537 /// symlinks, false if it is not. Undefined otherwise. 538 /// @returns errc::success if result has been successfully set, otherwise a 539 /// platform-specific error_code. 540 std::error_code is_directory(const Twine &path, bool &result); 541 542 /// Simpler version of is_directory for clients that don't need to 543 /// differentiate between an error and false. 544 inline bool is_directory(const Twine &Path) { 545 bool Result; 546 return !is_directory(Path, Result) && Result; 547 } 548 549 /// Does status represent a regular file? 550 /// 551 /// @param status A basic_file_status previously returned from status. 552 /// @returns status_known(status) && status.type() == file_type::regular_file. 553 bool is_regular_file(const basic_file_status &status); 554 555 /// Is path a regular file? 556 /// 557 /// @param path Input path. 558 /// @param result Set to true if \a path is a regular file (after following 559 /// symlinks), false if it is not. Undefined otherwise. 560 /// @returns errc::success if result has been successfully set, otherwise a 561 /// platform-specific error_code. 562 std::error_code is_regular_file(const Twine &path, bool &result); 563 564 /// Simpler version of is_regular_file for clients that don't need to 565 /// differentiate between an error and false. 566 inline bool is_regular_file(const Twine &Path) { 567 bool Result; 568 if (is_regular_file(Path, Result)) 569 return false; 570 return Result; 571 } 572 573 /// Does status represent a symlink file? 574 /// 575 /// @param status A basic_file_status previously returned from status. 576 /// @returns status_known(status) && status.type() == file_type::symlink_file. 577 bool is_symlink_file(const basic_file_status &status); 578 579 /// Is path a symlink file? 580 /// 581 /// @param path Input path. 582 /// @param result Set to true if \a path is a symlink file, false if it is not. 583 /// Undefined otherwise. 584 /// @returns errc::success if result has been successfully set, otherwise a 585 /// platform-specific error_code. 586 std::error_code is_symlink_file(const Twine &path, bool &result); 587 588 /// Simpler version of is_symlink_file for clients that don't need to 589 /// differentiate between an error and false. 590 inline bool is_symlink_file(const Twine &Path) { 591 bool Result; 592 if (is_symlink_file(Path, Result)) 593 return false; 594 return Result; 595 } 596 597 /// Does this status represent something that exists but is not a 598 /// directory or regular file? 599 /// 600 /// @param status A basic_file_status previously returned from status. 601 /// @returns exists(s) && !is_regular_file(s) && !is_directory(s) 602 bool is_other(const basic_file_status &status); 603 604 /// Is path something that exists but is not a directory, 605 /// regular file, or symlink? 606 /// 607 /// @param path Input path. 608 /// @param result Set to true if \a path exists, but is not a directory, regular 609 /// file, or a symlink, false if it does not. Undefined otherwise. 610 /// @returns errc::success if result has been successfully set, otherwise a 611 /// platform-specific error_code. 612 std::error_code is_other(const Twine &path, bool &result); 613 614 /// Get file status as if by POSIX stat(). 615 /// 616 /// @param path Input path. 617 /// @param result Set to the file status. 618 /// @param follow When true, follows symlinks. Otherwise, the symlink itself is 619 /// statted. 620 /// @returns errc::success if result has been successfully set, otherwise a 621 /// platform-specific error_code. 622 std::error_code status(const Twine &path, file_status &result, 623 bool follow = true); 624 625 /// A version for when a file descriptor is already available. 626 std::error_code status(int FD, file_status &Result); 627 628 /// Set file permissions. 629 /// 630 /// @param Path File to set permissions on. 631 /// @param Permissions New file permissions. 632 /// @returns errc::success if the permissions were successfully set, otherwise 633 /// a platform-specific error_code. 634 /// @note On Windows, all permissions except *_write are ignored. Using any of 635 /// owner_write, group_write, or all_write will make the file writable. 636 /// Otherwise, the file will be marked as read-only. 637 std::error_code setPermissions(const Twine &Path, perms Permissions); 638 639 /// Get file permissions. 640 /// 641 /// @param Path File to get permissions from. 642 /// @returns the permissions if they were successfully retrieved, otherwise a 643 /// platform-specific error_code. 644 /// @note On Windows, if the file does not have the FILE_ATTRIBUTE_READONLY 645 /// attribute, all_all will be returned. Otherwise, all_read | all_exe 646 /// will be returned. 647 ErrorOr<perms> getPermissions(const Twine &Path); 648 649 /// Get file size. 650 /// 651 /// @param Path Input path. 652 /// @param Result Set to the size of the file in \a Path. 653 /// @returns errc::success if result has been successfully set, otherwise a 654 /// platform-specific error_code. 655 inline std::error_code file_size(const Twine &Path, uint64_t &Result) { 656 file_status Status; 657 std::error_code EC = status(Path, Status); 658 if (EC) 659 return EC; 660 Result = Status.getSize(); 661 return std::error_code(); 662 } 663 664 /// Set the file modification and access time. 665 /// 666 /// @returns errc::success if the file times were successfully set, otherwise a 667 /// platform-specific error_code or errc::function_not_supported on 668 /// platforms where the functionality isn't available. 669 std::error_code setLastModificationAndAccessTime(int FD, TimePoint<> Time); 670 671 /// Is status available? 672 /// 673 /// @param s Input file status. 674 /// @returns True if status() != status_error. 675 bool status_known(const basic_file_status &s); 676 677 /// Is status available? 678 /// 679 /// @param path Input path. 680 /// @param result Set to true if status() != status_error. 681 /// @returns errc::success if result has been successfully set, otherwise a 682 /// platform-specific error_code. 683 std::error_code status_known(const Twine &path, bool &result); 684 685 enum CreationDisposition : unsigned { 686 /// CD_CreateAlways - When opening a file: 687 /// * If it already exists, truncate it. 688 /// * If it does not already exist, create a new file. 689 CD_CreateAlways = 0, 690 691 /// CD_CreateNew - When opening a file: 692 /// * If it already exists, fail. 693 /// * If it does not already exist, create a new file. 694 CD_CreateNew = 1, 695 696 /// CD_OpenAlways - When opening a file: 697 /// * If it already exists, open the file with the offset set to 0. 698 /// * If it does not already exist, fail. 699 CD_OpenExisting = 2, 700 701 /// CD_OpenAlways - When opening a file: 702 /// * If it already exists, open the file with the offset set to 0. 703 /// * If it does not already exist, create a new file. 704 CD_OpenAlways = 3, 705 }; 706 707 enum FileAccess : unsigned { 708 FA_Read = 1, 709 FA_Write = 2, 710 }; 711 712 enum OpenFlags : unsigned { 713 OF_None = 0, 714 F_None = 0, // For compatibility 715 716 /// The file should be opened in text mode on platforms that make this 717 /// distinction. 718 OF_Text = 1, 719 F_Text = 1, // For compatibility 720 721 /// The file should be opened in append mode. 722 OF_Append = 2, 723 F_Append = 2, // For compatibility 724 725 /// Delete the file on close. Only makes a difference on windows. 726 OF_Delete = 4, 727 728 /// When a child process is launched, this file should remain open in the 729 /// child process. 730 OF_ChildInherit = 8, 731 732 /// Force files Atime to be updated on access. Only makes a difference on windows. 733 OF_UpdateAtime = 16, 734 }; 735 736 /// Create a uniquely named file. 737 /// 738 /// Generates a unique path suitable for a temporary file and then opens it as a 739 /// file. The name is based on \a model with '%' replaced by a random char in 740 /// [0-9a-f]. If \a model is not an absolute path, the temporary file will be 741 /// created in the current directory. 742 /// 743 /// Example: clang-%%-%%-%%-%%-%%.s => clang-a0-b1-c2-d3-e4.s 744 /// 745 /// This is an atomic operation. Either the file is created and opened, or the 746 /// file system is left untouched. 747 /// 748 /// The intended use is for files that are to be kept, possibly after 749 /// renaming them. For example, when running 'clang -c foo.o', the file can 750 /// be first created as foo-abc123.o and then renamed. 751 /// 752 /// @param Model Name to base unique path off of. 753 /// @param ResultFD Set to the opened file's file descriptor. 754 /// @param ResultPath Set to the opened file's absolute path. 755 /// @returns errc::success if Result{FD,Path} have been successfully set, 756 /// otherwise a platform-specific error_code. 757 std::error_code createUniqueFile(const Twine &Model, int &ResultFD, 758 SmallVectorImpl<char> &ResultPath, 759 unsigned Mode = all_read | all_write); 760 761 /// Simpler version for clients that don't want an open file. An empty 762 /// file will still be created. 763 std::error_code createUniqueFile(const Twine &Model, 764 SmallVectorImpl<char> &ResultPath, 765 unsigned Mode = all_read | all_write); 766 767 /// Represents a temporary file. 768 /// 769 /// The temporary file must be eventually discarded or given a final name and 770 /// kept. 771 /// 772 /// The destructor doesn't implicitly discard because there is no way to 773 /// properly handle errors in a destructor. 774 class TempFile { 775 bool Done = false; 776 TempFile(StringRef Name, int FD); 777 778 public: 779 /// This creates a temporary file with createUniqueFile and schedules it for 780 /// deletion with sys::RemoveFileOnSignal. 781 static Expected<TempFile> create(const Twine &Model, 782 unsigned Mode = all_read | all_write); 783 TempFile(TempFile &&Other); 784 TempFile &operator=(TempFile &&Other); 785 786 // Name of the temporary file. 787 std::string TmpName; 788 789 // The open file descriptor. 790 int FD = -1; 791 792 // Keep this with the given name. 793 Error keep(const Twine &Name); 794 795 // Keep this with the temporary name. 796 Error keep(); 797 798 // Delete the file. 799 Error discard(); 800 801 // This checks that keep or delete was called. 802 ~TempFile(); 803 }; 804 805 /// Create a file in the system temporary directory. 806 /// 807 /// The filename is of the form prefix-random_chars.suffix. Since the directory 808 /// is not know to the caller, Prefix and Suffix cannot have path separators. 809 /// The files are created with mode 0600. 810 /// 811 /// This should be used for things like a temporary .s that is removed after 812 /// running the assembler. 813 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, 814 int &ResultFD, 815 SmallVectorImpl<char> &ResultPath); 816 817 /// Simpler version for clients that don't want an open file. An empty 818 /// file will still be created. 819 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, 820 SmallVectorImpl<char> &ResultPath); 821 822 std::error_code createUniqueDirectory(const Twine &Prefix, 823 SmallVectorImpl<char> &ResultPath); 824 825 /// Get a unique name, not currently exisiting in the filesystem. Subject 826 /// to race conditions, prefer to use createUniqueFile instead. 827 /// 828 /// Similar to createUniqueFile, but instead of creating a file only 829 /// checks if it exists. This function is subject to race conditions, if you 830 /// want to use the returned name to actually create a file, use 831 /// createUniqueFile instead. 832 std::error_code getPotentiallyUniqueFileName(const Twine &Model, 833 SmallVectorImpl<char> &ResultPath); 834 835 /// Get a unique temporary file name, not currently exisiting in the 836 /// filesystem. Subject to race conditions, prefer to use createTemporaryFile 837 /// instead. 838 /// 839 /// Similar to createTemporaryFile, but instead of creating a file only 840 /// checks if it exists. This function is subject to race conditions, if you 841 /// want to use the returned name to actually create a file, use 842 /// createTemporaryFile instead. 843 std::error_code 844 getPotentiallyUniqueTempFileName(const Twine &Prefix, StringRef Suffix, 845 SmallVectorImpl<char> &ResultPath); 846 847 inline OpenFlags operator|(OpenFlags A, OpenFlags B) { 848 return OpenFlags(unsigned(A) | unsigned(B)); 849 } 850 851 inline OpenFlags &operator|=(OpenFlags &A, OpenFlags B) { 852 A = A | B; 853 return A; 854 } 855 856 inline FileAccess operator|(FileAccess A, FileAccess B) { 857 return FileAccess(unsigned(A) | unsigned(B)); 858 } 859 860 inline FileAccess &operator|=(FileAccess &A, FileAccess B) { 861 A = A | B; 862 return A; 863 } 864 865 /// @brief Opens a file with the specified creation disposition, access mode, 866 /// and flags and returns a file descriptor. 867 /// 868 /// The caller is responsible for closing the file descriptor once they are 869 /// finished with it. 870 /// 871 /// @param Name The path of the file to open, relative or absolute. 872 /// @param ResultFD If the file could be opened successfully, its descriptor 873 /// is stored in this location. Otherwise, this is set to -1. 874 /// @param Disp Value specifying the existing-file behavior. 875 /// @param Access Value specifying whether to open the file in read, write, or 876 /// read-write mode. 877 /// @param Flags Additional flags. 878 /// @param Mode The access permissions of the file, represented in octal. 879 /// @returns errc::success if \a Name has been opened, otherwise a 880 /// platform-specific error_code. 881 std::error_code openFile(const Twine &Name, int &ResultFD, 882 CreationDisposition Disp, FileAccess Access, 883 OpenFlags Flags, unsigned Mode = 0666); 884 885 /// @brief Opens a file with the specified creation disposition, access mode, 886 /// and flags and returns a platform-specific file object. 887 /// 888 /// The caller is responsible for closing the file object once they are 889 /// finished with it. 890 /// 891 /// @param Name The path of the file to open, relative or absolute. 892 /// @param Disp Value specifying the existing-file behavior. 893 /// @param Access Value specifying whether to open the file in read, write, or 894 /// read-write mode. 895 /// @param Flags Additional flags. 896 /// @param Mode The access permissions of the file, represented in octal. 897 /// @returns errc::success if \a Name has been opened, otherwise a 898 /// platform-specific error_code. 899 Expected<file_t> openNativeFile(const Twine &Name, CreationDisposition Disp, 900 FileAccess Access, OpenFlags Flags, 901 unsigned Mode = 0666); 902 903 /// @brief Opens the file with the given name in a write-only or read-write 904 /// mode, returning its open file descriptor. If the file does not exist, it 905 /// is created. 906 /// 907 /// The caller is responsible for closing the file descriptor once they are 908 /// finished with it. 909 /// 910 /// @param Name The path of the file to open, relative or absolute. 911 /// @param ResultFD If the file could be opened successfully, its descriptor 912 /// is stored in this location. Otherwise, this is set to -1. 913 /// @param Flags Additional flags used to determine whether the file should be 914 /// opened in, for example, read-write or in write-only mode. 915 /// @param Mode The access permissions of the file, represented in octal. 916 /// @returns errc::success if \a Name has been opened, otherwise a 917 /// platform-specific error_code. 918 inline std::error_code 919 openFileForWrite(const Twine &Name, int &ResultFD, 920 CreationDisposition Disp = CD_CreateAlways, 921 OpenFlags Flags = OF_None, unsigned Mode = 0666) { 922 return openFile(Name, ResultFD, Disp, FA_Write, Flags, Mode); 923 } 924 925 /// @brief Opens the file with the given name in a write-only or read-write 926 /// mode, returning its open file descriptor. If the file does not exist, it 927 /// is created. 928 /// 929 /// The caller is responsible for closing the freeing the file once they are 930 /// finished with it. 931 /// 932 /// @param Name The path of the file to open, relative or absolute. 933 /// @param Flags Additional flags used to determine whether the file should be 934 /// opened in, for example, read-write or in write-only mode. 935 /// @param Mode The access permissions of the file, represented in octal. 936 /// @returns a platform-specific file descriptor if \a Name has been opened, 937 /// otherwise an error object. 938 inline Expected<file_t> openNativeFileForWrite(const Twine &Name, 939 CreationDisposition Disp, 940 OpenFlags Flags, 941 unsigned Mode = 0666) { 942 return openNativeFile(Name, Disp, FA_Write, Flags, Mode); 943 } 944 945 /// @brief Opens the file with the given name in a write-only or read-write 946 /// mode, returning its open file descriptor. If the file does not exist, it 947 /// is created. 948 /// 949 /// The caller is responsible for closing the file descriptor once they are 950 /// finished with it. 951 /// 952 /// @param Name The path of the file to open, relative or absolute. 953 /// @param ResultFD If the file could be opened successfully, its descriptor 954 /// is stored in this location. Otherwise, this is set to -1. 955 /// @param Flags Additional flags used to determine whether the file should be 956 /// opened in, for example, read-write or in write-only mode. 957 /// @param Mode The access permissions of the file, represented in octal. 958 /// @returns errc::success if \a Name has been opened, otherwise a 959 /// platform-specific error_code. 960 inline std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, 961 CreationDisposition Disp, 962 OpenFlags Flags, 963 unsigned Mode = 0666) { 964 return openFile(Name, ResultFD, Disp, FA_Write | FA_Read, Flags, Mode); 965 } 966 967 /// @brief Opens the file with the given name in a write-only or read-write 968 /// mode, returning its open file descriptor. If the file does not exist, it 969 /// is created. 970 /// 971 /// The caller is responsible for closing the freeing the file once they are 972 /// finished with it. 973 /// 974 /// @param Name The path of the file to open, relative or absolute. 975 /// @param Flags Additional flags used to determine whether the file should be 976 /// opened in, for example, read-write or in write-only mode. 977 /// @param Mode The access permissions of the file, represented in octal. 978 /// @returns a platform-specific file descriptor if \a Name has been opened, 979 /// otherwise an error object. 980 inline Expected<file_t> openNativeFileForReadWrite(const Twine &Name, 981 CreationDisposition Disp, 982 OpenFlags Flags, 983 unsigned Mode = 0666) { 984 return openNativeFile(Name, Disp, FA_Write | FA_Read, Flags, Mode); 985 } 986 987 /// @brief Opens the file with the given name in a read-only mode, returning 988 /// its open file descriptor. 989 /// 990 /// The caller is responsible for closing the file descriptor once they are 991 /// finished with it. 992 /// 993 /// @param Name The path of the file to open, relative or absolute. 994 /// @param ResultFD If the file could be opened successfully, its descriptor 995 /// is stored in this location. Otherwise, this is set to -1. 996 /// @param RealPath If nonnull, extra work is done to determine the real path 997 /// of the opened file, and that path is stored in this 998 /// location. 999 /// @returns errc::success if \a Name has been opened, otherwise a 1000 /// platform-specific error_code. 1001 std::error_code openFileForRead(const Twine &Name, int &ResultFD, 1002 OpenFlags Flags = OF_None, 1003 SmallVectorImpl<char> *RealPath = nullptr); 1004 1005 /// @brief Opens the file with the given name in a read-only mode, returning 1006 /// its open file descriptor. 1007 /// 1008 /// The caller is responsible for closing the freeing the file once they are 1009 /// finished with it. 1010 /// 1011 /// @param Name The path of the file to open, relative or absolute. 1012 /// @param RealPath If nonnull, extra work is done to determine the real path 1013 /// of the opened file, and that path is stored in this 1014 /// location. 1015 /// @returns a platform-specific file descriptor if \a Name has been opened, 1016 /// otherwise an error object. 1017 Expected<file_t> 1018 openNativeFileForRead(const Twine &Name, OpenFlags Flags = OF_None, 1019 SmallVectorImpl<char> *RealPath = nullptr); 1020 1021 /// @brief Close the file object. This should be used instead of ::close for 1022 /// portability. 1023 /// 1024 /// @param F On input, this is the file to close. On output, the file is 1025 /// set to kInvalidFile. 1026 void closeFile(file_t &F); 1027 1028 std::error_code getUniqueID(const Twine Path, UniqueID &Result); 1029 1030 /// Get disk space usage information. 1031 /// 1032 /// Note: Users must be careful about "Time Of Check, Time Of Use" kind of bug. 1033 /// Note: Windows reports results according to the quota allocated to the user. 1034 /// 1035 /// @param Path Input path. 1036 /// @returns a space_info structure filled with the capacity, free, and 1037 /// available space on the device \a Path is on. A platform specific error_code 1038 /// is returned on error. 1039 ErrorOr<space_info> disk_space(const Twine &Path); 1040 1041 /// This class represents a memory mapped file. It is based on 1042 /// boost::iostreams::mapped_file. 1043 class mapped_file_region { 1044 public: 1045 enum mapmode { 1046 readonly, ///< May only access map via const_data as read only. 1047 readwrite, ///< May access map via data and modify it. Written to path. 1048 priv ///< May modify via data, but changes are lost on destruction. 1049 }; 1050 1051 private: 1052 /// Platform-specific mapping state. 1053 size_t Size; 1054 void *Mapping; 1055 #ifdef _WIN32 1056 void *FileHandle; 1057 #endif 1058 mapmode Mode; 1059 1060 std::error_code init(int FD, uint64_t Offset, mapmode Mode); 1061 1062 public: 1063 mapped_file_region() = delete; 1064 mapped_file_region(mapped_file_region&) = delete; 1065 mapped_file_region &operator =(mapped_file_region&) = delete; 1066 1067 /// \param fd An open file descriptor to map. mapped_file_region takes 1068 /// ownership if closefd is true. It must have been opended in the correct 1069 /// mode. 1070 mapped_file_region(int fd, mapmode mode, size_t length, uint64_t offset, 1071 std::error_code &ec); 1072 1073 ~mapped_file_region(); 1074 1075 size_t size() const; 1076 char *data() const; 1077 1078 /// Get a const view of the data. Modifying this memory has undefined 1079 /// behavior. 1080 const char *const_data() const; 1081 1082 /// \returns The minimum alignment offset must be. 1083 static int alignment(); 1084 }; 1085 1086 /// Return the path to the main executable, given the value of argv[0] from 1087 /// program startup and the address of main itself. In extremis, this function 1088 /// may fail and return an empty path. 1089 std::string getMainExecutable(const char *argv0, void *MainExecAddr); 1090 1091 /// @} 1092 /// @name Iterators 1093 /// @{ 1094 1095 /// directory_entry - A single entry in a directory. Caches the status either 1096 /// from the result of the iteration syscall, or the first time status is 1097 /// called. 1098 class directory_entry { 1099 std::string Path; 1100 bool FollowSymlinks; 1101 basic_file_status Status; 1102 1103 public: 1104 explicit directory_entry(const Twine &path, bool follow_symlinks = true, 1105 basic_file_status st = basic_file_status()) 1106 : Path(path.str()), FollowSymlinks(follow_symlinks), Status(st) {} 1107 1108 directory_entry() = default; 1109 1110 void assign(const Twine &path, basic_file_status st = basic_file_status()) { 1111 Path = path.str(); 1112 Status = st; 1113 } 1114 1115 void replace_filename(const Twine &filename, 1116 basic_file_status st = basic_file_status()); 1117 1118 const std::string &path() const { return Path; } 1119 ErrorOr<basic_file_status> status() const; 1120 1121 bool operator==(const directory_entry& rhs) const { return Path == rhs.Path; } 1122 bool operator!=(const directory_entry& rhs) const { return !(*this == rhs); } 1123 bool operator< (const directory_entry& rhs) const; 1124 bool operator<=(const directory_entry& rhs) const; 1125 bool operator> (const directory_entry& rhs) const; 1126 bool operator>=(const directory_entry& rhs) const; 1127 }; 1128 1129 namespace detail { 1130 1131 struct DirIterState; 1132 1133 std::error_code directory_iterator_construct(DirIterState &, StringRef, bool); 1134 std::error_code directory_iterator_increment(DirIterState &); 1135 std::error_code directory_iterator_destruct(DirIterState &); 1136 1137 /// Keeps state for the directory_iterator. 1138 struct DirIterState { 1139 ~DirIterState() { 1140 directory_iterator_destruct(*this); 1141 } 1142 1143 intptr_t IterationHandle = 0; 1144 directory_entry CurrentEntry; 1145 }; 1146 1147 } // end namespace detail 1148 1149 /// directory_iterator - Iterates through the entries in path. There is no 1150 /// operator++ because we need an error_code. If it's really needed we can make 1151 /// it call report_fatal_error on error. 1152 class directory_iterator { 1153 std::shared_ptr<detail::DirIterState> State; 1154 bool FollowSymlinks = true; 1155 1156 public: 1157 explicit directory_iterator(const Twine &path, std::error_code &ec, 1158 bool follow_symlinks = true) 1159 : FollowSymlinks(follow_symlinks) { 1160 State = std::make_shared<detail::DirIterState>(); 1161 SmallString<128> path_storage; 1162 ec = detail::directory_iterator_construct( 1163 *State, path.toStringRef(path_storage), FollowSymlinks); 1164 update_error_code_for_current_entry(ec); 1165 } 1166 1167 explicit directory_iterator(const directory_entry &de, std::error_code &ec, 1168 bool follow_symlinks = true) 1169 : FollowSymlinks(follow_symlinks) { 1170 State = std::make_shared<detail::DirIterState>(); 1171 ec = detail::directory_iterator_construct( 1172 *State, de.path(), FollowSymlinks); 1173 update_error_code_for_current_entry(ec); 1174 } 1175 1176 /// Construct end iterator. 1177 directory_iterator() = default; 1178 1179 // No operator++ because we need error_code. 1180 directory_iterator &increment(std::error_code &ec) { 1181 ec = directory_iterator_increment(*State); 1182 update_error_code_for_current_entry(ec); 1183 return *this; 1184 } 1185 1186 const directory_entry &operator*() const { return State->CurrentEntry; } 1187 const directory_entry *operator->() const { return &State->CurrentEntry; } 1188 1189 bool operator==(const directory_iterator &RHS) const { 1190 if (State == RHS.State) 1191 return true; 1192 if (!RHS.State) 1193 return State->CurrentEntry == directory_entry(); 1194 if (!State) 1195 return RHS.State->CurrentEntry == directory_entry(); 1196 return State->CurrentEntry == RHS.State->CurrentEntry; 1197 } 1198 1199 bool operator!=(const directory_iterator &RHS) const { 1200 return !(*this == RHS); 1201 } 1202 // Other members as required by 1203 // C++ Std, 24.1.1 Input iterators [input.iterators] 1204 1205 private: 1206 // Checks if current entry is valid and populates error code. For example, 1207 // current entry may not exist due to broken symbol links. 1208 void update_error_code_for_current_entry(std::error_code &ec) { 1209 // Bail out if error has already occured earlier to avoid overwriting it. 1210 if (ec) 1211 return; 1212 1213 // Empty directory entry is used to mark the end of an interation, it's not 1214 // an error. 1215 if (State->CurrentEntry == directory_entry()) 1216 return; 1217 1218 ErrorOr<basic_file_status> status = State->CurrentEntry.status(); 1219 if (!status) 1220 ec = status.getError(); 1221 } 1222 }; 1223 1224 namespace detail { 1225 1226 /// Keeps state for the recursive_directory_iterator. 1227 struct RecDirIterState { 1228 std::stack<directory_iterator, std::vector<directory_iterator>> Stack; 1229 uint16_t Level = 0; 1230 bool HasNoPushRequest = false; 1231 }; 1232 1233 } // end namespace detail 1234 1235 /// recursive_directory_iterator - Same as directory_iterator except for it 1236 /// recurses down into child directories. 1237 class recursive_directory_iterator { 1238 std::shared_ptr<detail::RecDirIterState> State; 1239 bool Follow; 1240 1241 public: 1242 recursive_directory_iterator() = default; 1243 explicit recursive_directory_iterator(const Twine &path, std::error_code &ec, 1244 bool follow_symlinks = true) 1245 : State(std::make_shared<detail::RecDirIterState>()), 1246 Follow(follow_symlinks) { 1247 State->Stack.push(directory_iterator(path, ec, Follow)); 1248 if (State->Stack.top() == directory_iterator()) 1249 State.reset(); 1250 } 1251 1252 // No operator++ because we need error_code. 1253 recursive_directory_iterator &increment(std::error_code &ec) { 1254 const directory_iterator end_itr = {}; 1255 1256 if (State->HasNoPushRequest) 1257 State->HasNoPushRequest = false; 1258 else { 1259 ErrorOr<basic_file_status> status = State->Stack.top()->status(); 1260 if (status && is_directory(*status)) { 1261 State->Stack.push(directory_iterator(*State->Stack.top(), ec, Follow)); 1262 if (State->Stack.top() != end_itr) { 1263 ++State->Level; 1264 return *this; 1265 } 1266 State->Stack.pop(); 1267 } 1268 } 1269 1270 while (!State->Stack.empty() 1271 && State->Stack.top().increment(ec) == end_itr) { 1272 State->Stack.pop(); 1273 --State->Level; 1274 } 1275 1276 // Check if we are done. If so, create an end iterator. 1277 if (State->Stack.empty()) 1278 State.reset(); 1279 1280 return *this; 1281 } 1282 1283 const directory_entry &operator*() const { return *State->Stack.top(); } 1284 const directory_entry *operator->() const { return &*State->Stack.top(); } 1285 1286 // observers 1287 /// Gets the current level. Starting path is at level 0. 1288 int level() const { return State->Level; } 1289 1290 /// Returns true if no_push has been called for this directory_entry. 1291 bool no_push_request() const { return State->HasNoPushRequest; } 1292 1293 // modifiers 1294 /// Goes up one level if Level > 0. 1295 void pop() { 1296 assert(State && "Cannot pop an end iterator!"); 1297 assert(State->Level > 0 && "Cannot pop an iterator with level < 1"); 1298 1299 const directory_iterator end_itr = {}; 1300 std::error_code ec; 1301 do { 1302 if (ec) 1303 report_fatal_error("Error incrementing directory iterator."); 1304 State->Stack.pop(); 1305 --State->Level; 1306 } while (!State->Stack.empty() 1307 && State->Stack.top().increment(ec) == end_itr); 1308 1309 // Check if we are done. If so, create an end iterator. 1310 if (State->Stack.empty()) 1311 State.reset(); 1312 } 1313 1314 /// Does not go down into the current directory_entry. 1315 void no_push() { State->HasNoPushRequest = true; } 1316 1317 bool operator==(const recursive_directory_iterator &RHS) const { 1318 return State == RHS.State; 1319 } 1320 1321 bool operator!=(const recursive_directory_iterator &RHS) const { 1322 return !(*this == RHS); 1323 } 1324 // Other members as required by 1325 // C++ Std, 24.1.1 Input iterators [input.iterators] 1326 }; 1327 1328 /// @} 1329 1330 } // end namespace fs 1331 } // end namespace sys 1332 } // end namespace llvm 1333 1334 #endif // LLVM_SUPPORT_FILESYSTEM_H 1335