25 #if !defined(_MSC_VER) && !defined(__MINGW32__)
32 using namespace llvm::support::endian;
39 const char *separators =
"\\/";
40 const char preferred_separator =
'\\';
42 const char separators =
'/';
43 const char preferred_separator =
'/';
58 if (path.
size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
64 if ((path.
size() > 2) &&
70 return path.
substr(0, end);
79 return path.
substr(0, end);
83 if (str.
size() == 2 &&
89 return str.
size() - 1;
108 if (str.
size() > 2 &&
115 if (str.
size() == 2 &&
121 if (str.
size() > 3 &&
136 size_t end_pos = filename_pos(path);
141 size_t root_dir_pos = root_dir_start(path.
substr(0, end_pos));
144 (end_pos - 1) != root_dir_pos &&
148 if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
163 bool MakeAbsolute,
unsigned Mode,
174 ModelStorage.
swap(TDir);
180 ResultPath = ModelStorage;
187 for (
unsigned i = 0, e = ModelStorage.
size();
i != e; ++
i) {
188 if (ModelStorage[
i] ==
'%')
195 if (std::error_code EC =
199 goto retry_random_path;
203 return std::error_code();
210 return std::error_code();
213 goto retry_random_path;
217 if (std::error_code EC =
220 goto retry_random_path;
223 return std::error_code();
236 i.Component = find_first_component(path);
244 i.Position = path.
size();
249 assert(Position < Path.size() &&
"Tried to increment past end!");
252 Position += Component.size();
255 if (Position == Path.size()) {
262 bool was_net = Component.size() > 2 &&
264 Component[1] == Component[0] &&
273 || Component.endswith(
":")
276 Component = Path.substr(Position, 1);
281 while (Position != Path.size() &&
287 if (Position == Path.size()) {
295 size_t end_pos = Path.find_first_of(separators, Position);
296 Component = Path.slice(Position, end_pos);
302 return Path.begin() == RHS.Path.
begin() && Position == RHS.Position;
306 return Position - RHS.Position;
312 I.Position = Path.
size();
319 I.Component = Path.
substr(0, 0);
327 size_t root_dir_pos = root_dir_start(Path);
328 if (Position == Path.size() &&
329 Path.size() > root_dir_pos + 1 &&
337 size_t end_pos = Position;
340 (end_pos - 1) != root_dir_pos &&
345 size_t start_pos = filename_pos(Path.substr(0, end_pos));
346 Component = Path.slice(start_pos, end_pos);
347 Position = start_pos;
352 return Path.begin() == RHS.Path.
begin() && Component == RHS.Component &&
353 Position == RHS.Position;
357 return Position - RHS.Position;
365 bool has_net = b->size() > 2 &&
is_separator((*b)[0]) && (*b)[1] == (*b)[0];
373 if (has_net || has_drive) {
376 return path.
substr(0, b->size() + pos->size());
396 bool has_net = b->size() > 2 &&
is_separator((*b)[0]) && (*b)[1] == (*b)[0];
404 if (has_net || has_drive) {
419 bool has_net = b->size() > 2 &&
is_separator((*b)[0]) && (*b)[1] == (*b)[0];
427 if ((has_net || has_drive) &&
463 for (
auto &component : components) {
465 bool component_has_sep = !component.empty() &&
is_separator(component[0]);
470 size_t loc = component.find_first_not_of(separators);
478 if (!component_has_sep && !(path.
empty() || is_root_name)) {
483 path.
append(component.begin(), component.end());
494 size_t end_pos = parent_path_end(path);
498 return path.
substr(0, end_pos);
518 if (ext.
size() > 0 && ext[0] !=
'.')
532 if (!OrigPath.startswith(OldPrefix))
536 if (OldPrefix.
size() == NewPrefix.
size()) {
551 "path and result are not allowed to overlap!");
560 std::replace(Path.
begin(), Path.
end(),
'/',
'\\');
562 for (
auto PI = Path.
begin(), PE = Path.
end(); PI < PE; ++PI) {
565 if (PN < PE && *PN ==
'\\')
576 std::string s = path.
str();
577 std::replace(s.begin(), s.end(),
'\\',
'/');
594 if ((fname.
size() == 1 && fname ==
".") ||
595 (fname.
size() == 2 && fname ==
".."))
598 return fname.
substr(0, pos);
607 if ((fname.
size() == 1 && fname ==
".") ||
608 (fname.
size() == 2 && fname ==
".."))
619 case '/':
return true;
620 default:
return false;
697 return rootDir && rootName;
721 if (remove_dot_dot &&
C ==
"..") {
722 if (!components.
empty() && components.
back() !=
"..") {
755 std::error_code EC =
status(Path, Status);
759 return std::error_code();
774 static std::error_code
780 "Model must be a simple filename.");
786 static std::error_code
789 const char *Middle = Suffix.
empty() ?
"-%%%%%%" :
"-%%%%%%.";
818 bool use_current_directory) {
829 if (rootName && rootDirectory)
830 return std::error_code();
834 if (use_current_directory)
835 current_directory.
toVector(current_dir);
836 else if (std::error_code ec =
current_path(current_dir))
840 if (!rootName && !rootDirectory) {
844 path.
swap(current_dir);
845 return std::error_code();
848 if (!rootName && rootDirectory) {
853 path.
swap(curDirRootName);
854 return std::error_code();
857 if (rootName && !rootDirectory) {
864 path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
866 return std::error_code();
915 const size_t BufSize = 4096;
916 char *Buf =
new char[BufSize];
917 int BytesRead = 0, BytesWritten = 0;
919 BytesRead =
read(ReadFD, Buf, BufSize);
923 BytesWritten =
write(WriteFD, Buf, BytesRead);
924 if (BytesWritten < 0)
926 BytesRead -= BytesWritten;
928 if (BytesWritten < 0)
935 if (BytesRead < 0 || BytesWritten < 0)
936 return std::error_code(errno, std::generic_category());
937 return std::error_code();
945 return s.
type() != file_type::status_error;
949 return status.
type() == file_type::directory_file;
954 if (std::error_code ec =
status(path, st))
957 return std::error_code();
961 return status.
type() == file_type::regular_file;
966 if (std::error_code ec =
status(path, st))
969 return std::error_code();
980 if (std::error_code EC =
status(Path, FileStatus))
983 return std::error_code();
1000 if (Magic.
size() < 4)
1001 return file_magic::unknown;
1002 switch ((
unsigned char)Magic[0]) {
1007 if (Magic.
size() < MinSize)
1008 return file_magic::coff_import_library;
1012 return file_magic::coff_object;
1014 return file_magic::coff_cl_gl_object;
1015 return file_magic::coff_import_library;
1018 if (
startswith(Magic,
"\0\0\0\0\x20\0\0\0\xFF"))
1019 return file_magic::windows_resource;
1022 return file_magic::coff_object;
1024 return file_magic::wasm_object;
1037 return file_magic::archive;
1042 bool Data2MSB = Magic[5] == 2;
1043 unsigned high = Data2MSB ? 16 : 17;
1044 unsigned low = Data2MSB ? 17 : 16;
1045 if (Magic[high] == 0) {
1046 switch (Magic[low]) {
1047 default:
return file_magic::elf;
1048 case 1:
return file_magic::elf_relocatable;
1049 case 2:
return file_magic::elf_executable;
1050 case 3:
return file_magic::elf_shared_object;
1051 case 4:
return file_magic::elf_core;
1055 return file_magic::elf;
1064 if (Magic.
size() >= 8 && Magic[7] < 43)
1065 return file_magic::macho_universal_binary;
1080 if (Magic[3] ==
char(0xCE))
1084 if (Magic.
size() >= MinSize)
1085 type = Magic[12] << 24 | Magic[13] << 12 | Magic[14] << 8 | Magic[15];
1086 }
else if (
startswith(Magic,
"\xCE\xFA\xED\xFE") ||
1090 if (Magic[0] ==
char(0xCE))
1094 if (Magic.
size() >= MinSize)
1095 type = Magic[15] << 24 | Magic[14] << 12 |Magic[13] << 8 | Magic[12];
1099 case 1:
return file_magic::macho_object;
1100 case 2:
return file_magic::macho_executable;
1101 case 3:
return file_magic::macho_fixed_virtual_memory_shared_lib;
1102 case 4:
return file_magic::macho_core;
1103 case 5:
return file_magic::macho_preload_executable;
1104 case 6:
return file_magic::macho_dynamically_linked_shared_lib;
1105 case 7:
return file_magic::macho_dynamic_linker;
1106 case 8:
return file_magic::macho_bundle;
1107 case 9:
return file_magic::macho_dynamically_linked_shared_lib_stub;
1108 case 10:
return file_magic::macho_dsym_companion;
1109 case 11:
return file_magic::macho_kext_bundle;
1120 if (Magic[1] == 0x01)
1121 return file_magic::coff_object;
1125 if (Magic[1] == 0x02)
1126 return file_magic::coff_object;
1133 if (off < Magic.
size() &&
1135 return file_magic::pecoff_executable;
1140 if (Magic[1] ==
char(0x86))
1141 return file_magic::coff_object;
1147 return file_magic::unknown;
1156 int Length =
read(FD, Buffer,
sizeof(Buffer));
1157 if (close(FD) != 0 || Length < 0)
1158 return std::error_code(errno, std::generic_category());
1161 return std::error_code();
1173 #if defined(LLVM_ON_UNIX)
1176 #if defined(LLVM_ON_WIN32)
1186 if (getUserCacheDir(Result)) {
1187 append(Result, Path1, Path2, Path3);
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
void push_back(const T &Elt)
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.
const_iterator end(StringRef path)
Get end iterator over path.
bool isSingleStringRef() const
Return true if this twine can be dynamically accessed as a single StringRef value with getSingleStrin...
StringRef root_name(StringRef path)
Get root name.
StringRef stem(StringRef path)
Get stem.
value_type read(const void *memory)
Read a value of a particular endianness from memory.
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, unsigned Mode=all_read|all_write)
Create a uniquely named file.
std::error_code openFileForRead(const Twine &Name, int &ResultFD, SmallVectorImpl< char > *RealPath=nullptr)
F_Excl - When opening a file, this flag makes raw_fd_ostream report an error if the file already exis...
bool is_relative(const Twine &path)
Is path relative?
static std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, llvm::SmallVectorImpl< char > &ResultPath, FSEntity Type)
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension)
Replace the file extension of path with extension.
UniqueID getUniqueID() const
bool has_stem(const Twine &path)
Has stem?
StringRef root_directory(StringRef path)
Get root directory.
std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
const_iterator begin(StringRef path)
Get begin iterator over path.
static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute, unsigned Mode, FSEntity Type)
bool has_root_directory(const Twine &path)
Has root directory?
file_status - Represents the result of a call to stat and friends.
static const char BigObjMagic[]
bool status_known(file_status s)
Is status available?
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
void remove_filename(SmallVectorImpl< char > &path)
Remove the last component from path unless it is the root dir.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool is_absolute(const Twine &path)
Is path absolute?
StringRef extension(StringRef path)
Get extension.
LLVM_NODISCARD bool empty() const
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
bool is_separator(char value)
Check whether the given char is a path separator on the host OS.
static const char preferred_separator_string[]
StringRef root_path(StringRef path)
Get root path.
bool has_relative_path(const Twine &path)
Has relative path?
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
Open the file for read and write.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static const char ClGlObjMagic[]
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
StringRef filename(StringRef path)
Get filename.
static SmallString< 256 > remove_dots(StringRef path, bool remove_dot_dot)
The instances of the Type class are immutable: once they are created, they are never changed...
void swap(SmallVectorImpl &RHS)
bool has_filename(const Twine &path)
Has filename?
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
LLVM_NODISCARD 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.
bool is_other(file_status status)
Does this status represent something that exists but is not a directory, regular file, or symlink?
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool user_cache_directory(SmallVectorImpl< char > &Result, const Twine &Path1, const Twine &Path2="", const Twine &Path3="")
Get the user's cache directory.
void replace_path_prefix(SmallVectorImpl< char > &Path, const StringRef &OldPrefix, const StringRef &NewPrefix)
Replace matching path prefix with another path.
std::error_code getUniqueID(const Twine Path, UniqueID &Result)
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool is_directory(file_status status)
Does status represent a directory?
StringRef remove_leading_dotslash(StringRef path)
Remove redundant leading "./" pieces and consecutive separators.
static const char *const Magic
file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
StringRef relative_path(StringRef path)
Get relative path.
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
StringRef parent_path(StringRef path)
Get parent path.
StringRef str() const
Explicit conversion to StringRef.
bool is_regular_file(file_status status)
Does status represent a regular file?
StringRef get_separator()
Return the preferred separator for this platform.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
void write(void *memory, value_type value)
Write a value to memory with a particular endianness.
static bool startswith(StringRef Magic, const char(&S)[N])
static unsigned GetRandomNumber()
Get the result of a process wide random number generator.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
void set_size(size_type N)
Set the array size to N, which the current array must have enough capacity for.
Provides a library for accessing information about this process and other processes on the operating ...
file_magic - An "enum class" enumeration of file types based on magic (the first N bytes of the file)...
pointer data()
Return a pointer to the vector's buffer, even if empty().
reverse_iterator rbegin(StringRef path)
Get reverse begin iterator over path.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
uint32_t read32le(const void *P)
static const char PEMagic[]
std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
bool has_root_path(const Twine &path)
Has root path?
bool has_root_name(const Twine &path)
Has root name?
reverse_iterator rend(StringRef path)
Get reverse end iterator over path.
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl< char > &result)
Get the typical temporary directory for the system, e.g., "/var/tmp" or "C:/TEMP".
LLVM_NODISCARD 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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef toNullTerminatedStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single null terminated StringRef if it can be represented as such...
bool isTriviallyEmpty() const
Check if this twine is trivially empty; a false return value does not necessarily mean the twine is e...
bool has_extension(const Twine &path)
Has extension?
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
StringRef - Represent a constant reference to a string, i.e.
bool operator==(uint64_t V1, const APInt &V2)
std::error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
bool exists(file_status status)
Does file exist?
std::string convert_to_slash(StringRef path)
Replaces backslashes with slashes if Windows.
bool has_parent_path(const Twine &path)
Has parent path?
static std::error_code make_absolute(const Twine ¤t_directory, SmallVectorImpl< char > &path, bool use_current_directory)
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, OpenFlags Flags, unsigned Mode=0666)