LLVM  8.0.1
Path.cpp
Go to the documentation of this file.
1 //===-- Path.cpp - Implement OS Path Concept ------------------------------===//
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 implements the operating system Path API.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/Support/Path.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/Config/llvm-config.h"
17 #include "llvm/Support/Endian.h"
18 #include "llvm/Support/Errc.h"
21 #include "llvm/Support/Process.h"
22 #include "llvm/Support/Signals.h"
23 #include <cctype>
24 #include <cstring>
25 
26 #if !defined(_MSC_VER) && !defined(__MINGW32__)
27 #include <unistd.h>
28 #else
29 #include <io.h>
30 #endif
31 
32 using namespace llvm;
33 using namespace llvm::support::endian;
34 
35 namespace {
36  using llvm::StringRef;
39 
40  inline Style real_style(Style style) {
41 #ifdef _WIN32
42  return (style == Style::posix) ? Style::posix : Style::windows;
43 #else
44  return (style == Style::windows) ? Style::windows : Style::posix;
45 #endif
46  }
47 
48  inline const char *separators(Style style) {
49  if (real_style(style) == Style::windows)
50  return "\\/";
51  return "/";
52  }
53 
54  inline char preferred_separator(Style style) {
55  if (real_style(style) == Style::windows)
56  return '\\';
57  return '/';
58  }
59 
60  StringRef find_first_component(StringRef path, Style style) {
61  // Look for this first component in the following order.
62  // * empty (in this case we return an empty string)
63  // * either C: or {//,\\}net.
64  // * {/,\}
65  // * {file,directory}name
66 
67  if (path.empty())
68  return path;
69 
70  if (real_style(style) == Style::windows) {
71  // C:
72  if (path.size() >= 2 &&
73  std::isalpha(static_cast<unsigned char>(path[0])) && path[1] == ':')
74  return path.substr(0, 2);
75  }
76 
77  // //net
78  if ((path.size() > 2) && is_separator(path[0], style) &&
79  path[0] == path[1] && !is_separator(path[2], style)) {
80  // Find the next directory separator.
81  size_t end = path.find_first_of(separators(style), 2);
82  return path.substr(0, end);
83  }
84 
85  // {/,\}
86  if (is_separator(path[0], style))
87  return path.substr(0, 1);
88 
89  // * {file,directory}name
90  size_t end = path.find_first_of(separators(style));
91  return path.substr(0, end);
92  }
93 
94  // Returns the first character of the filename in str. For paths ending in
95  // '/', it returns the position of the '/'.
96  size_t filename_pos(StringRef str, Style style) {
97  if (str.size() > 0 && is_separator(str[str.size() - 1], style))
98  return str.size() - 1;
99 
100  size_t pos = str.find_last_of(separators(style), str.size() - 1);
101 
102  if (real_style(style) == Style::windows) {
103  if (pos == StringRef::npos)
104  pos = str.find_last_of(':', str.size() - 2);
105  }
106 
107  if (pos == StringRef::npos || (pos == 1 && is_separator(str[0], style)))
108  return 0;
109 
110  return pos + 1;
111  }
112 
113  // Returns the position of the root directory in str. If there is no root
114  // directory in str, it returns StringRef::npos.
115  size_t root_dir_start(StringRef str, Style style) {
116  // case "c:/"
117  if (real_style(style) == Style::windows) {
118  if (str.size() > 2 && str[1] == ':' && is_separator(str[2], style))
119  return 2;
120  }
121 
122  // case "//net"
123  if (str.size() > 3 && is_separator(str[0], style) && str[0] == str[1] &&
124  !is_separator(str[2], style)) {
125  return str.find_first_of(separators(style), 2);
126  }
127 
128  // case "/"
129  if (str.size() > 0 && is_separator(str[0], style))
130  return 0;
131 
132  return StringRef::npos;
133  }
134 
135  // Returns the position past the end of the "parent path" of path. The parent
136  // path will not end in '/', unless the parent is the root directory. If the
137  // path has no parent, 0 is returned.
138  size_t parent_path_end(StringRef path, Style style) {
139  size_t end_pos = filename_pos(path, style);
140 
141  bool filename_was_sep =
142  path.size() > 0 && is_separator(path[end_pos], style);
143 
144  // Skip separators until we reach root dir (or the start of the string).
145  size_t root_dir_pos = root_dir_start(path, style);
146  while (end_pos > 0 &&
147  (root_dir_pos == StringRef::npos || end_pos > root_dir_pos) &&
148  is_separator(path[end_pos - 1], style))
149  --end_pos;
150 
151  if (end_pos == root_dir_pos && !filename_was_sep) {
152  // We've reached the root dir and the input path was *not* ending in a
153  // sequence of slashes. Include the root dir in the parent path.
154  return root_dir_pos + 1;
155  }
156 
157  // Otherwise, just include before the last slash.
158  return end_pos;
159  }
160 } // end unnamed namespace
161 
162 enum FSEntity {
166 };
167 
168 static std::error_code
169 createUniqueEntity(const Twine &Model, int &ResultFD,
170  SmallVectorImpl<char> &ResultPath, bool MakeAbsolute,
171  unsigned Mode, FSEntity Type,
173  SmallString<128> ModelStorage;
174  Model.toVector(ModelStorage);
175 
176  if (MakeAbsolute) {
177  // Make model absolute by prepending a temp directory if it's not already.
178  if (!sys::path::is_absolute(Twine(ModelStorage))) {
179  SmallString<128> TDir;
181  sys::path::append(TDir, Twine(ModelStorage));
182  ModelStorage.swap(TDir);
183  }
184  }
185 
186  // From here on, DO NOT modify model. It may be needed if the randomly chosen
187  // path already exists.
188  ResultPath = ModelStorage;
189  // Null terminate.
190  ResultPath.push_back(0);
191  ResultPath.pop_back();
192 
193  // Limit the number of attempts we make, so that we don't infinite loop. E.g.
194  // "permission denied" could be for a specific file (so we retry with a
195  // different name) or for the whole directory (retry would always fail).
196  // Checking which is racy, so we try a number of times, then give up.
197  std::error_code EC;
198  for (int Retries = 128; Retries > 0; --Retries) {
199  // Replace '%' with random chars.
200  for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
201  if (ModelStorage[i] == '%')
202  ResultPath[i] =
203  "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
204  }
205 
206  // Try to open + create the file.
207  switch (Type) {
208  case FS_File: {
209  EC = sys::fs::openFileForReadWrite(Twine(ResultPath.begin()), ResultFD,
210  sys::fs::CD_CreateNew, Flags, Mode);
211  if (EC) {
212  // errc::permission_denied happens on Windows when we try to open a file
213  // that has been marked for deletion.
214  if (EC == errc::file_exists || EC == errc::permission_denied)
215  continue;
216  return EC;
217  }
218 
219  return std::error_code();
220  }
221 
222  case FS_Name: {
225  return std::error_code();
226  if (EC)
227  return EC;
228  continue;
229  }
230 
231  case FS_Dir: {
232  EC = sys::fs::create_directory(ResultPath.begin(), false);
233  if (EC) {
234  if (EC == errc::file_exists)
235  continue;
236  return EC;
237  }
238  return std::error_code();
239  }
240  }
241  llvm_unreachable("Invalid Type");
242  }
243  return EC;
244 }
245 
246 namespace llvm {
247 namespace sys {
248 namespace path {
249 
251  const_iterator i;
252  i.Path = path;
253  i.Component = find_first_component(path, style);
254  i.Position = 0;
255  i.S = style;
256  return i;
257 }
258 
260  const_iterator i;
261  i.Path = path;
262  i.Position = path.size();
263  return i;
264 }
265 
266 const_iterator &const_iterator::operator++() {
267  assert(Position < Path.size() && "Tried to increment past end!");
268 
269  // Increment Position to past the current component
270  Position += Component.size();
271 
272  // Check for end.
273  if (Position == Path.size()) {
274  Component = StringRef();
275  return *this;
276  }
277 
278  // Both POSIX and Windows treat paths that begin with exactly two separators
279  // specially.
280  bool was_net = Component.size() > 2 && is_separator(Component[0], S) &&
281  Component[1] == Component[0] && !is_separator(Component[2], S);
282 
283  // Handle separators.
284  if (is_separator(Path[Position], S)) {
285  // Root dir.
286  if (was_net ||
287  // c:/
288  (real_style(S) == Style::windows && Component.endswith(":"))) {
289  Component = Path.substr(Position, 1);
290  return *this;
291  }
292 
293  // Skip extra separators.
294  while (Position != Path.size() && is_separator(Path[Position], S)) {
295  ++Position;
296  }
297 
298  // Treat trailing '/' as a '.', unless it is the root dir.
299  if (Position == Path.size() && Component != "/") {
300  --Position;
301  Component = ".";
302  return *this;
303  }
304  }
305 
306  // Find next component.
307  size_t end_pos = Path.find_first_of(separators(S), Position);
308  Component = Path.slice(Position, end_pos);
309 
310  return *this;
311 }
312 
314  return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
315 }
316 
318  return Position - RHS.Position;
319 }
320 
323  I.Path = Path;
324  I.Position = Path.size();
325  I.S = style;
326  return ++I;
327 }
328 
331  I.Path = Path;
332  I.Component = Path.substr(0, 0);
333  I.Position = 0;
334  return I;
335 }
336 
337 reverse_iterator &reverse_iterator::operator++() {
338  size_t root_dir_pos = root_dir_start(Path, S);
339 
340  // Skip separators unless it's the root directory.
341  size_t end_pos = Position;
342  while (end_pos > 0 && (end_pos - 1) != root_dir_pos &&
343  is_separator(Path[end_pos - 1], S))
344  --end_pos;
345 
346  // Treat trailing '/' as a '.', unless it is the root dir.
347  if (Position == Path.size() && !Path.empty() &&
348  is_separator(Path.back(), S) &&
349  (root_dir_pos == StringRef::npos || end_pos - 1 > root_dir_pos)) {
350  --Position;
351  Component = ".";
352  return *this;
353  }
354 
355  // Find next separator.
356  size_t start_pos = filename_pos(Path.substr(0, end_pos), S);
357  Component = Path.slice(start_pos, end_pos);
358  Position = start_pos;
359  return *this;
360 }
361 
363  return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
364  Position == RHS.Position;
365 }
366 
368  return Position - RHS.Position;
369 }
370 
372  const_iterator b = begin(path, style), pos = b, e = end(path);
373  if (b != e) {
374  bool has_net =
375  b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
376  bool has_drive = (real_style(style) == Style::windows) && b->endswith(":");
377 
378  if (has_net || has_drive) {
379  if ((++pos != e) && is_separator((*pos)[0], style)) {
380  // {C:/,//net/}, so get the first two components.
381  return path.substr(0, b->size() + pos->size());
382  } else {
383  // just {C:,//net}, return the first component.
384  return *b;
385  }
386  }
387 
388  // POSIX style root directory.
389  if (is_separator((*b)[0], style)) {
390  return *b;
391  }
392  }
393 
394  return StringRef();
395 }
396 
398  const_iterator b = begin(path, style), e = end(path);
399  if (b != e) {
400  bool has_net =
401  b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
402  bool has_drive = (real_style(style) == Style::windows) && b->endswith(":");
403 
404  if (has_net || has_drive) {
405  // just {C:,//net}, return the first component.
406  return *b;
407  }
408  }
409 
410  // No path or no name.
411  return StringRef();
412 }
413 
415  const_iterator b = begin(path, style), pos = b, e = end(path);
416  if (b != e) {
417  bool has_net =
418  b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
419  bool has_drive = (real_style(style) == Style::windows) && b->endswith(":");
420 
421  if ((has_net || has_drive) &&
422  // {C:,//net}, skip to the next component.
423  (++pos != e) && is_separator((*pos)[0], style)) {
424  return *pos;
425  }
426 
427  // POSIX style root directory.
428  if (!has_net && is_separator((*b)[0], style)) {
429  return *b;
430  }
431  }
432 
433  // No path or no root.
434  return StringRef();
435 }
436 
438  StringRef root = root_path(path, style);
439  return path.substr(root.size());
440 }
441 
442 void append(SmallVectorImpl<char> &path, Style style, const Twine &a,
443  const Twine &b, const Twine &c, const Twine &d) {
444  SmallString<32> a_storage;
445  SmallString<32> b_storage;
446  SmallString<32> c_storage;
447  SmallString<32> d_storage;
448 
449  SmallVector<StringRef, 4> components;
450  if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
451  if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
452  if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
453  if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
454 
455  for (auto &component : components) {
456  bool path_has_sep =
457  !path.empty() && is_separator(path[path.size() - 1], style);
458  if (path_has_sep) {
459  // Strip separators from beginning of component.
460  size_t loc = component.find_first_not_of(separators(style));
461  StringRef c = component.substr(loc);
462 
463  // Append it.
464  path.append(c.begin(), c.end());
465  continue;
466  }
467 
468  bool component_has_sep =
469  !component.empty() && is_separator(component[0], style);
470  if (!component_has_sep &&
471  !(path.empty() || has_root_name(component, style))) {
472  // Add a separator.
473  path.push_back(preferred_separator(style));
474  }
475 
476  path.append(component.begin(), component.end());
477  }
478 }
479 
480 void append(SmallVectorImpl<char> &path, const Twine &a, const Twine &b,
481  const Twine &c, const Twine &d) {
482  append(path, Style::native, a, b, c, d);
483 }
484 
486  const_iterator end, Style style) {
487  for (; begin != end; ++begin)
488  path::append(path, style, *begin);
489 }
490 
492  size_t end_pos = parent_path_end(path, style);
493  if (end_pos == StringRef::npos)
494  return StringRef();
495  else
496  return path.substr(0, end_pos);
497 }
498 
500  size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()), style);
501  if (end_pos != StringRef::npos)
502  path.set_size(end_pos);
503 }
504 
506  Style style) {
507  StringRef p(path.begin(), path.size());
508  SmallString<32> ext_storage;
509  StringRef ext = extension.toStringRef(ext_storage);
510 
511  // Erase existing extension.
512  size_t pos = p.find_last_of('.');
513  if (pos != StringRef::npos && pos >= filename_pos(p, style))
514  path.set_size(pos);
515 
516  // Append '.' if needed.
517  if (ext.size() > 0 && ext[0] != '.')
518  path.push_back('.');
519 
520  // Append extension.
521  path.append(ext.begin(), ext.end());
522 }
523 
525  const StringRef &OldPrefix, const StringRef &NewPrefix,
526  Style style) {
527  if (OldPrefix.empty() && NewPrefix.empty())
528  return;
529 
530  StringRef OrigPath(Path.begin(), Path.size());
531  if (!OrigPath.startswith(OldPrefix))
532  return;
533 
534  // If prefixes have the same size we can simply copy the new one over.
535  if (OldPrefix.size() == NewPrefix.size()) {
536  llvm::copy(NewPrefix, Path.begin());
537  return;
538  }
539 
540  StringRef RelPath = OrigPath.substr(OldPrefix.size());
541  SmallString<256> NewPath;
542  path::append(NewPath, style, NewPrefix);
543  path::append(NewPath, style, RelPath);
544  Path.swap(NewPath);
545 }
546 
547 void native(const Twine &path, SmallVectorImpl<char> &result, Style style) {
548  assert((!path.isSingleStringRef() ||
549  path.getSingleStringRef().data() != result.data()) &&
550  "path and result are not allowed to overlap!");
551  // Clear result.
552  result.clear();
553  path.toVector(result);
554  native(result, style);
555 }
556 
557 void native(SmallVectorImpl<char> &Path, Style style) {
558  if (Path.empty())
559  return;
560  if (real_style(style) == Style::windows) {
561  std::replace(Path.begin(), Path.end(), '/', '\\');
562  if (Path[0] == '~' && (Path.size() == 1 || is_separator(Path[1], style))) {
563  SmallString<128> PathHome;
564  home_directory(PathHome);
565  PathHome.append(Path.begin() + 1, Path.end());
566  Path = PathHome;
567  }
568  } else {
569  for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
570  if (*PI == '\\') {
571  auto PN = PI + 1;
572  if (PN < PE && *PN == '\\')
573  ++PI; // increment once, the for loop will move over the escaped slash
574  else
575  *PI = '/';
576  }
577  }
578  }
579 }
580 
581 std::string convert_to_slash(StringRef path, Style style) {
582  if (real_style(style) != Style::windows)
583  return path;
584 
585  std::string s = path.str();
586  std::replace(s.begin(), s.end(), '\\', '/');
587  return s;
588 }
589 
590 StringRef filename(StringRef path, Style style) { return *rbegin(path, style); }
591 
593  StringRef fname = filename(path, style);
594  size_t pos = fname.find_last_of('.');
595  if (pos == StringRef::npos)
596  return fname;
597  else
598  if ((fname.size() == 1 && fname == ".") ||
599  (fname.size() == 2 && fname == ".."))
600  return fname;
601  else
602  return fname.substr(0, pos);
603 }
604 
606  StringRef fname = filename(path, style);
607  size_t pos = fname.find_last_of('.');
608  if (pos == StringRef::npos)
609  return StringRef();
610  else
611  if ((fname.size() == 1 && fname == ".") ||
612  (fname.size() == 2 && fname == ".."))
613  return StringRef();
614  else
615  return fname.substr(pos);
616 }
617 
618 bool is_separator(char value, Style style) {
619  if (value == '/')
620  return true;
621  if (real_style(style) == Style::windows)
622  return value == '\\';
623  return false;
624 }
625 
627  if (real_style(style) == Style::windows)
628  return "\\";
629  return "/";
630 }
631 
632 bool has_root_name(const Twine &path, Style style) {
633  SmallString<128> path_storage;
634  StringRef p = path.toStringRef(path_storage);
635 
636  return !root_name(p, style).empty();
637 }
638 
639 bool has_root_directory(const Twine &path, Style style) {
640  SmallString<128> path_storage;
641  StringRef p = path.toStringRef(path_storage);
642 
643  return !root_directory(p, style).empty();
644 }
645 
646 bool has_root_path(const Twine &path, Style style) {
647  SmallString<128> path_storage;
648  StringRef p = path.toStringRef(path_storage);
649 
650  return !root_path(p, style).empty();
651 }
652 
653 bool has_relative_path(const Twine &path, Style style) {
654  SmallString<128> path_storage;
655  StringRef p = path.toStringRef(path_storage);
656 
657  return !relative_path(p, style).empty();
658 }
659 
660 bool has_filename(const Twine &path, Style style) {
661  SmallString<128> path_storage;
662  StringRef p = path.toStringRef(path_storage);
663 
664  return !filename(p, style).empty();
665 }
666 
667 bool has_parent_path(const Twine &path, Style style) {
668  SmallString<128> path_storage;
669  StringRef p = path.toStringRef(path_storage);
670 
671  return !parent_path(p, style).empty();
672 }
673 
674 bool has_stem(const Twine &path, Style style) {
675  SmallString<128> path_storage;
676  StringRef p = path.toStringRef(path_storage);
677 
678  return !stem(p, style).empty();
679 }
680 
681 bool has_extension(const Twine &path, Style style) {
682  SmallString<128> path_storage;
683  StringRef p = path.toStringRef(path_storage);
684 
685  return !extension(p, style).empty();
686 }
687 
688 bool is_absolute(const Twine &path, Style style) {
689  SmallString<128> path_storage;
690  StringRef p = path.toStringRef(path_storage);
691 
692  bool rootDir = has_root_directory(p, style);
693  bool rootName =
694  (real_style(style) != Style::windows) || has_root_name(p, style);
695 
696  return rootDir && rootName;
697 }
698 
699 bool is_relative(const Twine &path, Style style) {
700  return !is_absolute(path, style);
701 }
702 
704  // Remove leading "./" (or ".//" or "././" etc.)
705  while (Path.size() > 2 && Path[0] == '.' && is_separator(Path[1], style)) {
706  Path = Path.substr(2);
707  while (Path.size() > 0 && is_separator(Path[0], style))
708  Path = Path.substr(1);
709  }
710  return Path;
711 }
712 
713 static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot,
714  Style style) {
715  SmallVector<StringRef, 16> components;
716 
717  // Skip the root path, then look for traversal in the components.
718  StringRef rel = path::relative_path(path, style);
719  for (StringRef C :
720  llvm::make_range(path::begin(rel, style), path::end(rel))) {
721  if (C == ".")
722  continue;
723  // Leading ".." will remain in the path unless it's at the root.
724  if (remove_dot_dot && C == "..") {
725  if (!components.empty() && components.back() != "..") {
726  components.pop_back();
727  continue;
728  }
729  if (path::is_absolute(path, style))
730  continue;
731  }
732  components.push_back(C);
733  }
734 
735  SmallString<256> buffer = path::root_path(path, style);
736  for (StringRef C : components)
737  path::append(buffer, style, C);
738  return buffer;
739 }
740 
741 bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot,
742  Style style) {
743  StringRef p(path.data(), path.size());
744 
745  SmallString<256> result = remove_dots(p, remove_dot_dot, style);
746  if (result == path)
747  return false;
748 
749  path.swap(result);
750  return true;
751 }
752 
753 } // end namespace path
754 
755 namespace fs {
756 
757 std::error_code getUniqueID(const Twine Path, UniqueID &Result) {
759  std::error_code EC = status(Path, Status);
760  if (EC)
761  return EC;
762  Result = Status.getUniqueID();
763  return std::error_code();
764 }
765 
766 std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
767  SmallVectorImpl<char> &ResultPath,
768  unsigned Mode) {
769  return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
770 }
771 
772 static std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
773  SmallVectorImpl<char> &ResultPath,
774  unsigned Mode, OpenFlags Flags) {
775  return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File,
776  Flags);
777 }
778 
779 std::error_code createUniqueFile(const Twine &Model,
780  SmallVectorImpl<char> &ResultPath,
781  unsigned Mode) {
782  int FD;
783  auto EC = createUniqueFile(Model, FD, ResultPath, Mode);
784  if (EC)
785  return EC;
786  // FD is only needed to avoid race conditions. Close it right away.
787  close(FD);
788  return EC;
789 }
790 
791 static std::error_code
792 createTemporaryFile(const Twine &Model, int &ResultFD,
794  SmallString<128> Storage;
795  StringRef P = Model.toNullTerminatedStringRef(Storage);
797  "Model must be a simple filename.");
798  // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
799  return createUniqueEntity(P.begin(), ResultFD, ResultPath, true,
800  owner_read | owner_write, Type);
801 }
802 
803 static std::error_code
804 createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
806  const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
807  return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
808  Type);
809 }
810 
811 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
812  int &ResultFD,
813  SmallVectorImpl<char> &ResultPath) {
814  return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
815 }
816 
817 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
818  SmallVectorImpl<char> &ResultPath) {
819  int FD;
820  auto EC = createTemporaryFile(Prefix, Suffix, FD, ResultPath);
821  if (EC)
822  return EC;
823  // FD is only needed to avoid race conditions. Close it right away.
824  close(FD);
825  return EC;
826 }
827 
828 
829 // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
830 // for consistency. We should try using mkdtemp.
831 std::error_code createUniqueDirectory(const Twine &Prefix,
832  SmallVectorImpl<char> &ResultPath) {
833  int Dummy;
834  return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath, true, 0,
835  FS_Dir);
836 }
837 
838 std::error_code
840  SmallVectorImpl<char> &ResultPath) {
841  int Dummy;
842  return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
843 }
844 
845 std::error_code
847  SmallVectorImpl<char> &ResultPath) {
848  int Dummy;
849  return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
850 }
851 
852 void make_absolute(const Twine &current_directory,
853  SmallVectorImpl<char> &path) {
854  StringRef p(path.data(), path.size());
855 
856  bool rootDirectory = path::has_root_directory(p);
857  bool rootName =
858  (real_style(Style::native) != Style::windows) || path::has_root_name(p);
859 
860  // Already absolute.
861  if (rootName && rootDirectory)
862  return;
863 
864  // All of the following conditions will need the current directory.
865  SmallString<128> current_dir;
866  current_directory.toVector(current_dir);
867 
868  // Relative path. Prepend the current directory.
869  if (!rootName && !rootDirectory) {
870  // Append path to the current directory.
871  path::append(current_dir, p);
872  // Set path to the result.
873  path.swap(current_dir);
874  return;
875  }
876 
877  if (!rootName && rootDirectory) {
878  StringRef cdrn = path::root_name(current_dir);
879  SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
880  path::append(curDirRootName, p);
881  // Set path to the result.
882  path.swap(curDirRootName);
883  return;
884  }
885 
886  if (rootName && !rootDirectory) {
887  StringRef pRootName = path::root_name(p);
888  StringRef bRootDirectory = path::root_directory(current_dir);
889  StringRef bRelativePath = path::relative_path(current_dir);
890  StringRef pRelativePath = path::relative_path(p);
891 
892  SmallString<128> res;
893  path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
894  path.swap(res);
895  return;
896  }
897 
898  llvm_unreachable("All rootName and rootDirectory combinations should have "
899  "occurred above!");
900 }
901 
902 std::error_code make_absolute(SmallVectorImpl<char> &path) {
903  if (path::is_absolute(path))
904  return {};
905 
906  SmallString<128> current_dir;
907  if (std::error_code ec = current_path(current_dir))
908  return ec;
909 
910  make_absolute(current_dir, path);
911  return {};
912 }
913 
914 std::error_code create_directories(const Twine &Path, bool IgnoreExisting,
915  perms Perms) {
916  SmallString<128> PathStorage;
917  StringRef P = Path.toStringRef(PathStorage);
918 
919  // Be optimistic and try to create the directory
920  std::error_code EC = create_directory(P, IgnoreExisting, Perms);
921  // If we succeeded, or had any error other than the parent not existing, just
922  // return it.
924  return EC;
925 
926  // We failed because of a no_such_file_or_directory, try to create the
927  // parent.
928  StringRef Parent = path::parent_path(P);
929  if (Parent.empty())
930  return EC;
931 
932  if ((EC = create_directories(Parent, IgnoreExisting, Perms)))
933  return EC;
934 
935  return create_directory(P, IgnoreExisting, Perms);
936 }
937 
938 static std::error_code copy_file_internal(int ReadFD, int WriteFD) {
939  const size_t BufSize = 4096;
940  char *Buf = new char[BufSize];
941  int BytesRead = 0, BytesWritten = 0;
942  for (;;) {
943  BytesRead = read(ReadFD, Buf, BufSize);
944  if (BytesRead <= 0)
945  break;
946  while (BytesRead) {
947  BytesWritten = write(WriteFD, Buf, BytesRead);
948  if (BytesWritten < 0)
949  break;
950  BytesRead -= BytesWritten;
951  }
952  if (BytesWritten < 0)
953  break;
954  }
955  delete[] Buf;
956 
957  if (BytesRead < 0 || BytesWritten < 0)
958  return std::error_code(errno, std::generic_category());
959  return std::error_code();
960 }
961 
962 std::error_code copy_file(const Twine &From, const Twine &To) {
963  int ReadFD, WriteFD;
964  if (std::error_code EC = openFileForRead(From, ReadFD, OF_None))
965  return EC;
966  if (std::error_code EC =
967  openFileForWrite(To, WriteFD, CD_CreateAlways, OF_None)) {
968  close(ReadFD);
969  return EC;
970  }
971 
972  std::error_code EC = copy_file_internal(ReadFD, WriteFD);
973 
974  close(ReadFD);
975  close(WriteFD);
976 
977  return EC;
978 }
979 
980 std::error_code copy_file(const Twine &From, int ToFD) {
981  int ReadFD;
982  if (std::error_code EC = openFileForRead(From, ReadFD, OF_None))
983  return EC;
984 
985  std::error_code EC = copy_file_internal(ReadFD, ToFD);
986 
987  close(ReadFD);
988 
989  return EC;
990 }
991 
993  MD5 Hash;
994 
995  constexpr size_t BufSize = 4096;
996  std::vector<uint8_t> Buf(BufSize);
997  int BytesRead = 0;
998  for (;;) {
999  BytesRead = read(FD, Buf.data(), BufSize);
1000  if (BytesRead <= 0)
1001  break;
1002  Hash.update(makeArrayRef(Buf.data(), BytesRead));
1003  }
1004 
1005  if (BytesRead < 0)
1006  return std::error_code(errno, std::generic_category());
1007  MD5::MD5Result Result;
1008  Hash.final(Result);
1009  return Result;
1010 }
1011 
1013  int FD;
1014  if (auto EC = openFileForRead(Path, FD, OF_None))
1015  return EC;
1016 
1017  auto Result = md5_contents(FD);
1018  close(FD);
1019  return Result;
1020 }
1021 
1023  return status_known(status) && status.type() != file_type::file_not_found;
1024 }
1025 
1027  return s.type() != file_type::status_error;
1028 }
1029 
1030 file_type get_file_type(const Twine &Path, bool Follow) {
1031  file_status st;
1032  if (status(Path, st, Follow))
1033  return file_type::status_error;
1034  return st.type();
1035 }
1036 
1038  return status.type() == file_type::directory_file;
1039 }
1040 
1041 std::error_code is_directory(const Twine &path, bool &result) {
1042  file_status st;
1043  if (std::error_code ec = status(path, st))
1044  return ec;
1045  result = is_directory(st);
1046  return std::error_code();
1047 }
1048 
1050  return status.type() == file_type::regular_file;
1051 }
1052 
1053 std::error_code is_regular_file(const Twine &path, bool &result) {
1054  file_status st;
1055  if (std::error_code ec = status(path, st))
1056  return ec;
1057  result = is_regular_file(st);
1058  return std::error_code();
1059 }
1060 
1062  return status.type() == file_type::symlink_file;
1063 }
1064 
1065 std::error_code is_symlink_file(const Twine &path, bool &result) {
1066  file_status st;
1067  if (std::error_code ec = status(path, st, false))
1068  return ec;
1069  result = is_symlink_file(st);
1070  return std::error_code();
1071 }
1072 
1074  return exists(status) &&
1075  !is_regular_file(status) &&
1076  !is_directory(status);
1077 }
1078 
1079 std::error_code is_other(const Twine &Path, bool &Result) {
1080  file_status FileStatus;
1081  if (std::error_code EC = status(Path, FileStatus))
1082  return EC;
1083  Result = is_other(FileStatus);
1084  return std::error_code();
1085 }
1086 
1087 void directory_entry::replace_filename(const Twine &Filename, file_type Type,
1089  SmallString<128> PathStr = path::parent_path(Path);
1090  path::append(PathStr, Filename);
1091  this->Path = PathStr.str();
1092  this->Type = Type;
1093  this->Status = Status;
1094 }
1095 
1098  if (std::error_code EC = status(Path, Status))
1099  return EC;
1100 
1101  return Status.permissions();
1102 }
1103 
1104 } // end namespace fs
1105 } // end namespace sys
1106 } // end namespace llvm
1107 
1108 // Include the truly platform-specific parts.
1109 #if defined(LLVM_ON_UNIX)
1110 #include "Unix/Path.inc"
1111 #endif
1112 #if defined(_WIN32)
1113 #include "Windows/Path.inc"
1114 #endif
1115 
1116 namespace llvm {
1117 namespace sys {
1118 namespace fs {
1119 TempFile::TempFile(StringRef Name, int FD) : TmpName(Name), FD(FD) {}
1120 TempFile::TempFile(TempFile &&Other) { *this = std::move(Other); }
1121 TempFile &TempFile::operator=(TempFile &&Other) {
1122  TmpName = std::move(Other.TmpName);
1123  FD = Other.FD;
1124  Other.Done = true;
1125  return *this;
1126 }
1127 
1128 TempFile::~TempFile() { assert(Done); }
1129 
1130 Error TempFile::discard() {
1131  Done = true;
1132  std::error_code RemoveEC;
1133 // On windows closing will remove the file.
1134 #ifndef _WIN32
1135  // Always try to close and remove.
1136  if (!TmpName.empty()) {
1137  RemoveEC = fs::remove(TmpName);
1138  sys::DontRemoveFileOnSignal(TmpName);
1139  }
1140 #endif
1141 
1142  if (!RemoveEC)
1143  TmpName = "";
1144 
1145  if (FD != -1 && close(FD) == -1) {
1146  std::error_code EC = std::error_code(errno, std::generic_category());
1147  return errorCodeToError(EC);
1148  }
1149  FD = -1;
1150 
1151  return errorCodeToError(RemoveEC);
1152 }
1153 
1154 Error TempFile::keep(const Twine &Name) {
1155  assert(!Done);
1156  Done = true;
1157  // Always try to close and rename.
1158 #ifdef _WIN32
1159  // If we can't cancel the delete don't rename.
1160  auto H = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
1161  std::error_code RenameEC = setDeleteDisposition(H, false);
1162  if (!RenameEC) {
1163  RenameEC = rename_fd(FD, Name);
1164  // If rename failed because it's cross-device, copy instead
1165  if (RenameEC ==
1166  std::error_code(ERROR_NOT_SAME_DEVICE, std::system_category())) {
1167  RenameEC = copy_file(TmpName, Name);
1168  setDeleteDisposition(H, true);
1169  }
1170  }
1171 
1172  // If we can't rename, discard the temporary file.
1173  if (RenameEC)
1174  setDeleteDisposition(H, true);
1175 #else
1176  std::error_code RenameEC = fs::rename(TmpName, Name);
1177  if (RenameEC) {
1178  // If we can't rename, try to copy to work around cross-device link issues.
1179  RenameEC = sys::fs::copy_file(TmpName, Name);
1180  // If we can't rename or copy, discard the temporary file.
1181  if (RenameEC)
1182  remove(TmpName);
1183  }
1184  sys::DontRemoveFileOnSignal(TmpName);
1185 #endif
1186 
1187  if (!RenameEC)
1188  TmpName = "";
1189 
1190  if (close(FD) == -1) {
1191  std::error_code EC(errno, std::generic_category());
1192  return errorCodeToError(EC);
1193  }
1194  FD = -1;
1195 
1196  return errorCodeToError(RenameEC);
1197 }
1198 
1199 Error TempFile::keep() {
1200  assert(!Done);
1201  Done = true;
1202 
1203 #ifdef _WIN32
1204  auto H = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
1205  if (std::error_code EC = setDeleteDisposition(H, false))
1206  return errorCodeToError(EC);
1207 #else
1208  sys::DontRemoveFileOnSignal(TmpName);
1209 #endif
1210 
1211  TmpName = "";
1212 
1213  if (close(FD) == -1) {
1214  std::error_code EC(errno, std::generic_category());
1215  return errorCodeToError(EC);
1216  }
1217  FD = -1;
1218 
1219  return Error::success();
1220 }
1221 
1222 Expected<TempFile> TempFile::create(const Twine &Model, unsigned Mode) {
1223  int FD;
1224  SmallString<128> ResultPath;
1225  if (std::error_code EC =
1226  createUniqueFile(Model, FD, ResultPath, Mode, OF_Delete))
1227  return errorCodeToError(EC);
1228 
1229  TempFile Ret(ResultPath, FD);
1230 #ifndef _WIN32
1231  if (sys::RemoveFileOnSignal(ResultPath)) {
1232  // Make sure we delete the file when RemoveFileOnSignal fails.
1233  consumeError(Ret.discard());
1234  std::error_code EC(errc::operation_not_permitted);
1235  return errorCodeToError(EC);
1236  }
1237 #endif
1238  return std::move(Ret);
1239 }
1240 }
1241 
1242 } // end namsspace sys
1243 } // end namespace llvm
uint64_t CallInst * C
bool is_separator(char value, Style style=Style::native)
Check whether the given char is a path separator on the host OS.
Definition: Path.cpp:618
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.
Definition: Path.cpp:914
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:259
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...
Definition: FileSystem.h:992
Represents either an error or a value T.
Definition: ErrorOr.h:57
void remove_filename(SmallVectorImpl< char > &path, Style style=Style::native)
Remove the last component from path unless it is the root dir.
Definition: Path.cpp:499
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:228
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:250
void replace_path_prefix(SmallVectorImpl< char > &Path, const StringRef &OldPrefix, const StringRef &NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
Definition: Path.cpp:524
SI Whole Quad Mode
bool status_known(const basic_file_status &s)
Is status available?
Definition: Path.cpp:1026
This class represents lattice values for constants.
Definition: AllocatorList.h:24
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.
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
void push_back(const T &Elt)
Definition: SmallVector.h:218
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
bool isTriviallyEmpty() const
Check if this twine is trivially empty; a false return value does not necessarily mean the twine is e...
Definition: Twine.h:398
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
Definition: Twine.h:453
static std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, llvm::SmallVectorImpl< char > &ResultPath, FSEntity Type)
Definition: Path.cpp:804
bool has_extension(const Twine &path, Style style=Style::native)
Has extension?
Definition: Path.cpp:681
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.
Definition: StringRef.h:421
std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
bool is_directory(const basic_file_status &status)
Does status represent a directory?
Definition: Path.cpp:1037
std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
Definition: Path.cpp:581
bool is_regular_file(const basic_file_status &status)
Does status represent a regular file?
Definition: Path.cpp:1049
StringRef remove_leading_dotslash(StringRef path, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
Definition: Path.cpp:703
Represents the result of a call to sys::fs::status().
Definition: FileSystem.h:247
Definition: Path.cpp:163
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).
Definition: StringRef.h:128
ErrorOr< MD5::MD5Result > md5_contents(int FD)
Compute an MD5 hash of a file&#39;s contents.
Definition: Path.cpp:992
ErrorOr< perms > getPermissions(const Twine &Path)
Get file permissions.
Definition: Path.cpp:1096
bool has_stem(const Twine &path, Style style=Style::native)
Has stem?
Definition: Path.cpp:674
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:480
amdgpu Simplify well known AMD library false Value Value const Twine & Name
reverse_iterator rbegin(StringRef path, Style style=Style::native)
Get reverse begin iterator over path.
Definition: Path.cpp:321
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:451
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition: MD5.cpp:189
Represents a temporary file.
Definition: FileSystem.h:806
void make_absolute(const Twine &current_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
Definition: Path.cpp:852
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:688
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
StringRef root_path(StringRef path, Style style=Style::native)
Get root path.
Definition: Path.cpp:371
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
Definition: Twine.h:437
Position
Position to insert a new instruction relative to an existing instruction.
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:784
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:267
CD_CreateNew - When opening a file:
Definition: FileSystem.h:726
bool isSingleStringRef() const
Return true if this twine can be dynamically accessed as a single StringRef value with getSingleStrin...
Definition: Twine.h:404
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
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).
Definition: StringRef.h:598
Delete the file on close. Only makes a difference on windows.
Definition: FileSystem.h:758
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition: Endian.h:100
void append(in_iter S, in_iter E)
Append from an iterator pair.
Definition: SmallString.h:75
Represents the result of a call to directory_iterator::status().
Definition: FileSystem.h:158
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
Definition: Path.cpp:962
#define P(N)
static SmallString< 256 > remove_dots(StringRef path, bool remove_dot_dot, Style style)
Definition: Path.cpp:713
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
void swap(SmallVectorImpl &RHS)
Definition: SmallVector.h:678
bool has_parent_path(const Twine &path, Style style=Style::native)
Has parent path?
Definition: Path.cpp:667
UniqueID getUniqueID() const
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:88
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:129
#define H(x, y, z)
Definition: MD5.cpp:57
bool has_filename(const Twine &path, Style style=Style::native)
Has filename?
Definition: Path.cpp:660
StringRef toNullTerminatedStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single null terminated StringRef if it can be represented as such...
Definition: Twine.cpp:38
std::error_code getUniqueID(const Twine Path, UniqueID &Result)
Definition: Path.cpp:757
static void replace(Module &M, GlobalVariable *Old, GlobalVariable *New)
file_type get_file_type(const Twine &Path, bool Follow=true)
Does status represent a directory?
Definition: Path.cpp:1030
void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
StringRef parent_path(StringRef path, Style style=Style::native)
Get parent path.
Definition: Path.cpp:491
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
Definition: Twine.cpp:33
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...
Definition: FileSystem.h:951
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:982
size_t size() const
Definition: SmallVector.h:53
StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
Definition: Path.cpp:626
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
BlockVerifier::State From
static std::error_code createUniqueFile(const Twine &Model, int &ResultFd, SmallVectorImpl< char > &ResultPath, unsigned Mode, OpenFlags Flags)
Definition: Path.cpp:772
static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute, unsigned Mode, FSEntity Type, sys::fs::OpenFlags Flags=sys::fs::OF_None)
Definition: Path.cpp:169
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
StringRef root_directory(StringRef path, Style style=Style::native)
Get root directory.
Definition: Path.cpp:414
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
Definition: Path.cpp:505
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...
StringRef root_name(StringRef path, Style style=Style::native)
Get root name.
Definition: Path.cpp:397
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
Definition: Path.cpp:831
bool is_other(const basic_file_status &status)
Does this status represent something that exists but is not a directory or regular file...
Definition: Path.cpp:1073
bool has_root_directory(const Twine &path, Style style=Style::native)
Has root directory?
Definition: Path.cpp:639
Path iterator.
Definition: Path.h:53
iterator begin() const
Definition: StringRef.h:106
Reverse path iterator.
Definition: Path.h:79
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:394
bool has_root_path(const Twine &path, Style style=Style::native)
Has root path?
Definition: Path.cpp:646
static unsigned GetRandomNumber()
Get the result of a process wide random number generator.
bool has_relative_path(const Twine &path, Style style=Style::native)
Has relative path?
Definition: Path.cpp:653
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:133
Provides a library for accessing information about this process and other processes on the operating ...
pointer data()
Return a pointer to the vector&#39;s buffer, even if empty().
Definition: SmallVector.h:149
static const size_t npos
Definition: StringRef.h:51
file_type
An enumeration for the file system&#39;s view of the type.
Definition: FileSystem.h:67
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:590
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
Definition: Endian.h:66
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.
Definition: StringRef.h:395
#define I(x, y, z)
Definition: MD5.cpp:58
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition: Path.cpp:699
std::error_code getPotentiallyUniqueTempFileName(const Twine &Prefix, StringRef Suffix, SmallVectorImpl< char > &ResultPath)
Get a unique temporary file name, not currently exisiting in the filesystem.
Definition: Path.cpp:846
APInt operator-(APInt)
Definition: APInt.h:2044
Definition: MD5.h:41
static void rename(GlobalValue *GV)
Definition: AutoUpgrade.cpp:34
std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
reverse_iterator rend(StringRef path)
Get reverse end iterator over path.
Definition: Path.cpp:329
std::error_code getPotentiallyUniqueFileName(const Twine &Model, SmallVectorImpl< char > &ResultPath)
Get a unique name, not currently exisiting in the filesystem.
Definition: Path.cpp:839
void system_temp_directory(bool erasedOnReboot, SmallVectorImpl< char > &result)
Get the typical temporary directory for the system, e.g., "/var/tmp" or "C:/TEMP".
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
CD_CreateAlways - When opening a file:
Definition: FileSystem.h:721
StringRef relative_path(StringRef path, Style style=Style::native)
Get relative path.
Definition: Path.cpp:437
void set_size(size_t Size)
Set the array size to N, which the current array must have enough capacity for.
Definition: SmallVector.h:67
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
bool home_directory(SmallVectorImpl< char > &result)
Get the user&#39;s home directory.
std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition: MD5.cpp:234
StringRef stem(StringRef path, Style style=Style::native)
Get stem.
Definition: Path.cpp:592
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1967
bool has_root_name(const Twine &path, Style style=Style::native)
Has root name?
Definition: Path.cpp:632
bool is_symlink_file(const basic_file_status &status)
Does status represent a symlink file?
Definition: Path.cpp:1061
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:1022
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1238
iterator end() const
Definition: StringRef.h:108
FSEntity
Definition: Path.cpp:162
StringRef extension(StringRef path, Style style=Style::native)
Get extension.
Definition: Path.cpp:605
static std::error_code copy_file_internal(int ReadFD, int WriteFD)
Definition: Path.cpp:938