1//===-- Path.cpp - Implement OS Path Concept ------------------------------===// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7//===----------------------------------------------------------------------===// 9// This file implements the operating system Path API. 11//===----------------------------------------------------------------------===// 17#include "llvm/Config/config.h" 18#include "llvm/Config/llvm-config.h" 26#if !defined(_MSC_VER) && !defined(__MINGW32__) 40inlineStyle real_style(Style style) {
41if (style != Style::native)
45return LLVM_WINDOWS_PREFER_FORWARD_SLASH ? Style::windows_slash
46 : Style::windows_backslash;
49inlineconstchar *separators(Style style) {
55inlinechar preferred_separator(Style style) {
56if (real_style(style) == Style::windows)
62// Look for this first component in the following order. 63// * empty (in this case we return an empty string) 64// * either C: or {//,\\}net. 66// * {file,directory}name 73if (path.
size() >= 2 &&
74 std::isalpha(
static_cast<unsignedchar>(path[0])) && path[1] ==
':')
81// Find the next directory separator. 90// * {file,directory}name 95// Returns the first character of the filename in str. For paths ending in 96// '/', it returns the position of the '/'. 97size_t filename_pos(
StringRef str, Style style) {
114// Returns the position of the root directory in str. If there is no root 115// directory in str, it returns StringRef::npos. 116size_t root_dir_start(
StringRef str, Style style) {
136// Returns the position past the end of the "parent path" of path. The parent 137// path will not end in '/', unless the parent is the root directory. If the 138// path has no parent, 0 is returned. 139size_t parent_path_end(
StringRef path, Style style) {
140size_t end_pos = filename_pos(path, style);
142bool filename_was_sep =
145// Skip separators until we reach root dir (or the start of the string). 146size_t root_dir_pos = root_dir_start(path, style);
152if (end_pos == root_dir_pos && !filename_was_sep) {
153// We've reached the root dir and the input path was *not* ending in a 154// sequence of slashes. Include the root dir in the parent path. 155return root_dir_pos + 1;
158// Otherwise, just include before the last slash. 161}
// end unnamed namespace 169static std::error_code
175// Limit the number of attempts we make, so that we don't infinite loop. E.g. 176// "permission denied" could be for a specific file (so we retry with a 177// different name) or for the whole directory (retry would always fail). 178// Checking which is racy, so we try a number of times, then give up. 180for (
int Retries = 128; Retries > 0; --Retries) {
182// Try to open + create the file. 188// errc::permission_denied happens on Windows when we try to open a file 189// that has been marked for deletion. 190if (EC == errc::file_exists || EC == errc::permission_denied)
195return std::error_code();
200if (EC == errc::no_such_file_or_directory)
201return std::error_code();
210if (EC == errc::file_exists)
214return std::error_code();
229 i.Component = find_first_component(path, style);
238 i.Position = path.
size();
243assert(Position < Path.
size() &&
"Tried to increment past end!");
245// Increment Position to past the current component 246 Position += Component.
size();
249if (Position == Path.
size()) {
254// Both POSIX and Windows treat paths that begin with exactly two separators 257 Component[1] == Component[0] && !
is_separator(Component[2], S);
265 Component = Path.
substr(Position, 1);
269// Skip extra separators. 274// Treat trailing '/' as a '.', unless it is the root dir. 275if (Position == Path.
size() && Component !=
"/") {
282// Find next component. 284 Component = Path.
slice(Position, end_pos);
290return Path.
begin() ==
RHS.Path.begin() && Position ==
RHS.Position;
294return Position -
RHS.Position;
300I.Position = Path.size();
309I.Component = Path.substr(0, 0);
315size_t root_dir_pos = root_dir_start(Path, S);
317// Skip separators unless it's the root directory. 318size_t end_pos = Position;
319while (end_pos > 0 && (end_pos - 1) != root_dir_pos &&
323// Treat trailing '/' as a '.', unless it is the root dir. 324if (Position == Path.
size() && !Path.
empty() &&
332// Find next separator. 333size_t start_pos = filename_pos(Path.
substr(0, end_pos), S);
334 Component = Path.
slice(start_pos, end_pos);
335 Position = start_pos;
340return Path.
begin() ==
RHS.Path.begin() && Component ==
RHS.Component &&
341 Position ==
RHS.Position;
345return Position -
RHS.Position;
352 b->size() > 2 &&
is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
355if (has_net || has_drive) {
357// {C:/,//net/}, so get the first two components. 358return path.
substr(0, b->size() + pos->size());
360// just {C:,//net}, return the first component. 364// POSIX style root directory. 377 b->size() > 2 &&
is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
380if (has_net || has_drive) {
381// just {C:,//net}, return the first component. 386// No path or no name. 394 b->size() > 2 &&
is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
397if ((has_net || has_drive) &&
398// {C:,//net}, skip to the next component. 403// POSIX style root directory. 409// No path or no root. 427if (!b.isTriviallyEmpty()) components.
push_back(b.toStringRef(b_storage));
431for (
auto &component : components) {
435// Strip separators from beginning of component. 436size_t loc = component.find_first_not_of(separators(style));
444bool component_has_sep =
446if (!component_has_sep &&
449 path.
push_back(preferred_separator(style));
452 path.
append(component.begin(), component.end());
468size_t end_pos = parent_path_end(path, style);
471return path.
substr(0, end_pos);
486// Erase existing extension. 487size_t pos = p.find_last_of(
'.');
491// Append '.' if needed. 492if (ext.
size() > 0 && ext[0] !=
'.')
501// Windows prefix matching : case and separator insensitive 503if (Path.size() < Prefix.size())
505for (
size_tI = 0, E = Prefix.size();
I != E; ++
I) {
508if (SepPath != SepPrefix)
510if (!SepPath && toLower(Path[
I]) != toLower(Prefix[
I]))
515return Path.starts_with(Prefix);
523StringRef OrigPath(Path.begin(), Path.size());
527// If prefixes have the same size we can simply copy the new one over. 528if (OldPrefix.
size() == NewPrefix.
size()) {
535 (
Twine(NewPrefix) + RelPath).toVector(NewPath);
543"path and result are not allowed to overlap!");
556 Ch = preferred_separator(style);
557if (Path[0] ==
'~' && (Path.size() == 1 ||
is_separator(Path[1], style))) {
560 PathHome.
append(Path.begin() + 1, Path.end());
564 std::replace(Path.begin(), Path.end(),
'\\',
'/');
570return std::string(path);
572 std::string s = path.
str();
573 std::replace(s.begin(), s.end(),
'\\',
'/');
584if ((fname.
size() == 1 && fname ==
".") ||
585 (fname.
size() == 2 && fname ==
".."))
587return fname.
substr(0, pos);
595if ((fname.
size() == 1 && fname ==
".") ||
596 (fname.
size() == 2 && fname ==
".."))
678return rootDir && rootName;
685// Handle '/' which is absolute for both Windows and POSIX systems. 686// Handle '\\' on Windows. 691// Handle drive letter pattern (a character followed by ':') on Windows. 692if (p.size() >= 2 && (p[0] && p[1] ==
':'))
704// Remove leading "./" (or ".//" or "././" etc.) 705while (Path.size() > 2 && Path[0] ==
'.' &&
is_separator(Path[1], style)) {
706 Path = Path.substr(2);
708 Path = Path.substr(1);
713// Remove path traversal components ("." and "..") when possible, and 714// canonicalize slashes. 717 style = real_style(style);
719bool needs_change =
false;
722// Consume the root path, if present. 724bool absolute = !root.
empty();
728// Loop over path components manually. This makes it easier to detect 729// non-preferred slashes and double separators that must be canonicalized. 730while (!remaining.
empty()) {
731size_t next_slash = remaining.
find_first_of(separators(style));
733 next_slash = remaining.
size();
737// Eat the slash, and check if it is the preferred separator. 738if (!remaining.
empty()) {
739 needs_change |= remaining.
front() != preferred_separator(style);
741// The path needs to be rewritten if it has a trailing slash. 742// FIXME: This is emergent behavior that could be removed. 743 needs_change |= remaining.
empty();
746// Check for path traversal components or double separators. 747if (component.
empty() || component ==
".") {
749 }
elseif (remove_dot_dot && component ==
"..") {
751// Do not allow ".." to remove the root component. If this is the 752// beginning of a relative path, keep the ".." component. 753if (!components.
empty() && components.
back() !=
"..") {
755 }
elseif (!absolute) {
764// "root" could be "/", which may need to be translated into "\". 766 needs_change |= root != buffer;
768// Avoid rewriting the path unless we have to. 772if (!components.
empty()) {
773 buffer += components[0];
775 buffer += preferred_separator(style);
779 the_path.
swap(buffer);
783}
// end namespace path 792 Result =
Status.getUniqueID();
793return std::error_code();
799 Model.toVector(ModelStorage);
802// Make model absolute by prepending a temp directory if it's not already. 807 ModelStorage.
swap(TDir);
811 ResultPath = ModelStorage;
815// Replace '%' with random chars. 816for (
unsigned i = 0, e = ModelStorage.
size(); i != e; ++i) {
817if (ModelStorage[i] ==
'%')
836// FD is only needed to avoid race conditions. Close it right away. 841static std::error_code
846StringRefP = Model.toNullTerminatedStringRef(Storage);
848"Model must be a simple filename.");
849// Use P.begin() so that createUniqueEntity doesn't need to recreate Storage. 854static std::error_code
858constchar *Middle = Suffix.
empty() ?
"-%%%%%%" :
"-%%%%%%.";
878// FD is only needed to avoid race conditions. Close it right away. 883// This is a mkdtemp with a different pattern. We use createUniqueEntity mostly 884// for consistency. We should try using mkdtemp. 914if ((rootName || is_style_posix(Style::native)) && rootDirectory)
917// All of the following conditions will need the current directory. 919 current_directory.
toVector(current_dir);
921// Relative path. Prepend the current directory. 922if (!rootName && !rootDirectory) {
923// Append path to the current directory. 925// Set path to the result. 926 path.
swap(current_dir);
930if (!rootName && rootDirectory) {
934// Set path to the result. 935 path.
swap(curDirRootName);
939if (rootName && !rootDirectory) {
946path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
972// Be optimistic and try to create the directory 974// If we succeeded, or had any error other than the parent not existing, just 979// We failed because of a no_such_file_or_directory, try to create the 992constsize_t BufSize = 4096;
993char *Buf =
newchar[BufSize];
994int BytesRead = 0, BytesWritten = 0;
996 BytesRead =
read(ReadFD, Buf, BufSize);
1000 BytesWritten =
write(WriteFD, Buf, BytesRead);
1001if (BytesWritten < 0)
1003 BytesRead -= BytesWritten;
1005if (BytesWritten < 0)
1010if (BytesRead < 0 || BytesWritten < 0)
1012return std::error_code();
1020if (std::error_code EC =
1050constexprsize_t BufSize = 4096;
1051 std::vector<uint8_t> Buf(BufSize);
1054 BytesRead =
read(FD, Buf.data(), BufSize);
1087if (
status(Path, st, Follow))
1098if (std::error_code ec =
status(path, st))
1101return std::error_code();
1110if (std::error_code ec =
status(path, st))
1113return std::error_code();
1122if (std::error_code ec =
status(path, st,
false))
1125return std::error_code();
1136if (std::error_code EC =
status(Path, FileStatus))
1139return std::error_code();
1146 this->Path = std::string(PathStr);
1156returnStatus.permissions();
1160assert(Mapping &&
"Mapping failed but used anyway!");
1165assert(Mapping &&
"Mapping failed but used anyway!");
1166returnreinterpret_cast<char *
>(Mapping);
1170assert(Mapping &&
"Mapping failed but used anyway!");
1171returnreinterpret_cast<constchar *
>(Mapping);
1175 ssize_t ChunkSize) {
1176// Install a handler to truncate the buffer to the correct size on exit. 1180// Read into Buffer until we hit EOF. 1194}
// end namespace sys 1195}
// end namespace llvm 1197// Include the truly platform-specific parts. 1198#if defined(LLVM_ON_UNIX) 1213 TmpName = std::move(
Other.TmpName);
1218 RemoveOnClose =
Other.RemoveOnClose;
1219Other.RemoveOnClose =
false;
1228if (FD != -1 && close(FD) == -1) {
1235// On Windows, closing will remove the file, if we set the delete 1236// disposition. If not, remove it manually. 1237bool Remove = RemoveOnClose;
1239// Always try to remove the file. 1242 std::error_code RemoveEC;
1243if (Remove && !TmpName.empty()) {
1257// Always try to close and rename. 1259// If we can't cancel the delete don't rename. 1260autoH =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
1261 std::error_code RenameEC =
1262 RemoveOnClose ? std::error_code() : setDeleteDisposition(
H,
false);
1263bool ShouldDelete =
false;
1265 RenameEC = rename_handle(
H,
Name);
1266// If rename failed because it's cross-device, copy instead 1268 std::error_code(ERROR_NOT_SAME_DEVICE, std::system_category())) {
1274// If we can't rename or copy, discard the temporary file. 1279 setDeleteDisposition(
H,
true);
1286// If we can't rename, try to copy to work around cross-device link issues. 1288// If we can't rename or copy, discard the temporary file. 1310autoH =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
1311if (std::error_code EC = setDeleteDisposition(
H,
false))
1329if (std::error_code EC =
1335autoH =
reinterpret_cast<HANDLE
>(_get_osfhandle(FD));
1336bool SetSignalHandler =
false;
1337if (std::error_code EC = setDeleteDisposition(
H,
true)) {
1338 Ret.RemoveOnClose =
true;
1339 SetSignalHandler =
true;
1342bool SetSignalHandler =
true;
1345// Make sure we delete the file when RemoveFileOnSignal fails. 1350return std::move(Ret);
BlockVerifier::State From
Given that RA is a live value
static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute, FSEntity Type, sys::fs::OpenFlags Flags=sys::fs::OF_None, unsigned Mode=0)
Provides a library for accessing information about this process and other processes on the operating ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file contains some functions that are useful when dealing with strings.
DEMANGLE_NAMESPACE_BEGIN bool starts_with(std::string_view self, char C) noexcept
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Represents either an error or a value T.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
void append(StringRef RHS)
Append from a StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void truncate(size_type N)
Like resize, but requires that N is less than size().
void swap(SmallVectorImpl &RHS)
void push_back(const T &Elt)
pointer data()
Return a pointer to the vector's buffer, even if empty().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
char back() const
back - Get the last character in the string.
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
constexpr size_t size() const
size - Get the string size.
char front() const
front - Get the first character in the string.
size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
static constexpr size_t npos
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool isSingleStringRef() const
Return true if this twine can be dynamically accessed as a single StringRef value with getSingleStrin...
bool isTriviallyEmpty() const
Check if this twine is trivially empty; a false return value does not necessarily mean the twine is e...
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
The instances of the Type class are immutable: once they are created, they are never changed.
static unsigned GetRandomNumber()
Get the result of a process wide random number generator.
Represents a temporary file.
Represents the result of a call to directory_iterator::status().
void replace_filename(const Twine &Filename, file_type Type, basic_file_status Status=basic_file_status())
Represents the result of a call to sys::fs::status().
const char * const_data() const
Get a const view of the data.
const_iterator & operator++()
bool operator==(const const_iterator &RHS) const
ptrdiff_t operator-(const const_iterator &RHS) const
Difference in bytes between this and RHS.
bool operator==(const reverse_iterator &RHS) const
ptrdiff_t operator-(const reverse_iterator &RHS) const
Difference in bytes between this and RHS.
reverse_iterator & operator++()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
bool is_regular_file(const basic_file_status &status)
Does status represent a regular file?
bool is_symlink_file(const basic_file_status &status)
Does status represent a symlink file?
void make_absolute(const Twine ¤t_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
std::error_code openFileForReadWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp, OpenFlags Flags, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
Error readNativeFileToEOF(file_t FileHandle, SmallVectorImpl< char > &Buffer, ssize_t ChunkSize=DefaultReadChunkSize)
Reads from FileHandle until EOF, appending to Buffer in chunks of size ChunkSize.
Expected< size_t > readNativeFile(file_t FileHandle, MutableArrayRef< char > Buf)
Reads Buf.size() bytes from FileHandle into Buf.
ErrorOr< perms > getPermissions(const Twine &Path)
Get file permissions.
std::error_code getPotentiallyUniqueFileName(const Twine &Model, SmallVectorImpl< char > &ResultPath)
Get a unique name, not currently exisiting in the filesystem.
std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
bool is_other(const basic_file_status &status)
Does this status represent something that exists but is not a directory or regular file?
std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
std::error_code getPotentiallyUniqueTempFileName(const Twine &Prefix, StringRef Suffix, SmallVectorImpl< char > &ResultPath)
Get a unique temporary file name, not currently exisiting in the filesystem.
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
bool exists(const basic_file_status &status)
Does file exist?
@ OF_Delete
The returned handle can be used for deleting the file.
file_type
An enumeration for the file system's view of the type.
std::error_code getUniqueID(const Twine Path, UniqueID &Result)
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None, unsigned Mode=all_read|all_write)
Create a uniquely named file.
std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
@ CD_CreateAlways
CD_CreateAlways - When opening a file:
@ CD_CreateNew
CD_CreateNew - When opening a file:
void createUniquePath(const Twine &Model, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute)
Create a potentially unique file name but does not create it.
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp=CD_CreateAlways, OpenFlags Flags=OF_None, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
bool status_known(const basic_file_status &s)
Is status available?
std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None)
Create a file in the system temporary directory.
file_type get_file_type(const Twine &Path, bool Follow=true)
Does status represent a directory?
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
ErrorOr< MD5::MD5Result > md5_contents(int FD)
Compute an MD5 hash of a file's contents.
std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
static std::error_code copy_file_internal(int ReadFD, int WriteFD)
bool is_directory(const basic_file_status &status)
Does status represent a directory?
StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
StringRef root_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get root path.
void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
bool has_relative_path(const Twine &path, Style style=Style::native)
Has relative path?
bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get stem.
bool has_root_name(const Twine &path, Style style=Style::native)
Has root name?
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get begin iterator over path.
reverse_iterator rend(StringRef path LLVM_LIFETIME_BOUND)
Get reverse end iterator over path.
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
bool has_root_path(const Twine &path, Style style=Style::native)
Has root path?
constexpr bool is_style_posix(Style S)
Check if S uses POSIX path rules.
StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
bool has_parent_path(const Twine &path, Style style=Style::native)
Has parent path?
void make_preferred(SmallVectorImpl< char > &path, Style style=Style::native)
For Windows path styles, convert path to use the preferred path separators.
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
StringRef remove_leading_dotslash(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
bool has_extension(const Twine &path, Style style=Style::native)
Has extension?
bool is_absolute_gnu(const Twine &path, Style style=Style::native)
Is path absolute using GNU rules?
StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl< char > &result)
Get the typical temporary directory for the system, e.g., "/var/tmp" or "C:/TEMP".
std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
bool has_stem(const Twine &path, Style style=Style::native)
Has stem?
constexpr bool is_style_windows(Style S)
Check if S uses Windows path rules.
StringRef root_name(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get root name.
StringRef root_directory(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get root directory.
bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
bool has_filename(const Twine &path, Style style=Style::native)
Has filename?
reverse_iterator rbegin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get reverse begin iterator over path.
const_iterator end(StringRef path LLVM_LIFETIME_BOUND)
Get end iterator over path.
bool is_separator(char value, Style style=Style::native)
Check whether the given char is a path separator on the host OS.
StringRef relative_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get relative path.
bool has_root_directory(const Twine &path, Style style=Style::native)
Has root directory?
void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
bool RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg=nullptr)
This function registers signal handlers to ensure that if a signal gets delivered that the named file...
This is an optimization pass for GlobalISel generic memory operations.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
@ no_such_file_or_directory
@ operation_not_permitted
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
OutputIt copy(R &&Range, OutputIt Out)
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
void consumeError(Error Err)
Consume a Error without doing anything.
Implement std::hash so that hash_code can be used in STL containers.