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