LLVM  7.0.0svn
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 retry_random_path:
194  // Replace '%' with random chars.
195  for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
196  if (ModelStorage[i] == '%')
197  ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
198  }
199 
200  // Try to open + create the file.
201  switch (Type) {
202  case FS_File: {
203  if (std::error_code EC =
204  sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD,
205  Flags | sys::fs::F_Excl, Mode)) {
206  if (EC == errc::file_exists)
207  goto retry_random_path;
208  return EC;
209  }
210 
211  return std::error_code();
212  }
213 
214  case FS_Name: {
215  std::error_code EC =
218  return std::error_code();
219  if (EC)
220  return EC;
221  goto retry_random_path;
222  }
223 
224  case FS_Dir: {
225  if (std::error_code EC =
226  sys::fs::create_directory(ResultPath.begin(), false)) {
227  if (EC == errc::file_exists)
228  goto retry_random_path;
229  return EC;
230  }
231  return std::error_code();
232  }
233  }
234  llvm_unreachable("Invalid Type");
235 }
236 
237 namespace llvm {
238 namespace sys {
239 namespace path {
240 
242  const_iterator i;
243  i.Path = path;
244  i.Component = find_first_component(path, style);
245  i.Position = 0;
246  i.S = style;
247  return i;
248 }
249 
251  const_iterator i;
252  i.Path = path;
253  i.Position = path.size();
254  return i;
255 }
256 
257 const_iterator &const_iterator::operator++() {
258  assert(Position < Path.size() && "Tried to increment past end!");
259 
260  // Increment Position to past the current component
261  Position += Component.size();
262 
263  // Check for end.
264  if (Position == Path.size()) {
265  Component = StringRef();
266  return *this;
267  }
268 
269  // Both POSIX and Windows treat paths that begin with exactly two separators
270  // specially.
271  bool was_net = Component.size() > 2 && is_separator(Component[0], S) &&
272  Component[1] == Component[0] && !is_separator(Component[2], S);
273 
274  // Handle separators.
275  if (is_separator(Path[Position], S)) {
276  // Root dir.
277  if (was_net ||
278  // c:/
279  (real_style(S) == Style::windows && Component.endswith(":"))) {
280  Component = Path.substr(Position, 1);
281  return *this;
282  }
283 
284  // Skip extra separators.
285  while (Position != Path.size() && is_separator(Path[Position], S)) {
286  ++Position;
287  }
288 
289  // Treat trailing '/' as a '.', unless it is the root dir.
290  if (Position == Path.size() && Component != "/") {
291  --Position;
292  Component = ".";
293  return *this;
294  }
295  }
296 
297  // Find next component.
298  size_t end_pos = Path.find_first_of(separators(S), Position);
299  Component = Path.slice(Position, end_pos);
300 
301  return *this;
302 }
303 
305  return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
306 }
307 
309  return Position - RHS.Position;
310 }
311 
314  I.Path = Path;
315  I.Position = Path.size();
316  I.S = style;
317  return ++I;
318 }
319 
322  I.Path = Path;
323  I.Component = Path.substr(0, 0);
324  I.Position = 0;
325  return I;
326 }
327 
328 reverse_iterator &reverse_iterator::operator++() {
329  size_t root_dir_pos = root_dir_start(Path, S);
330 
331  // Skip separators unless it's the root directory.
332  size_t end_pos = Position;
333  while (end_pos > 0 && (end_pos - 1) != root_dir_pos &&
334  is_separator(Path[end_pos - 1], S))
335  --end_pos;
336 
337  // Treat trailing '/' as a '.', unless it is the root dir.
338  if (Position == Path.size() && !Path.empty() &&
339  is_separator(Path.back(), S) &&
340  (root_dir_pos == StringRef::npos || end_pos - 1 > root_dir_pos)) {
341  --Position;
342  Component = ".";
343  return *this;
344  }
345 
346  // Find next separator.
347  size_t start_pos = filename_pos(Path.substr(0, end_pos), S);
348  Component = Path.slice(start_pos, end_pos);
349  Position = start_pos;
350  return *this;
351 }
352 
354  return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
355  Position == RHS.Position;
356 }
357 
359  return Position - RHS.Position;
360 }
361 
363  const_iterator b = begin(path, style), pos = b, e = end(path);
364  if (b != e) {
365  bool has_net =
366  b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
367  bool has_drive = (real_style(style) == Style::windows) && b->endswith(":");
368 
369  if (has_net || has_drive) {
370  if ((++pos != e) && is_separator((*pos)[0], style)) {
371  // {C:/,//net/}, so get the first two components.
372  return path.substr(0, b->size() + pos->size());
373  } else {
374  // just {C:,//net}, return the first component.
375  return *b;
376  }
377  }
378 
379  // POSIX style root directory.
380  if (is_separator((*b)[0], style)) {
381  return *b;
382  }
383  }
384 
385  return StringRef();
386 }
387 
389  const_iterator b = begin(path, style), e = end(path);
390  if (b != e) {
391  bool has_net =
392  b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
393  bool has_drive = (real_style(style) == Style::windows) && b->endswith(":");
394 
395  if (has_net || has_drive) {
396  // just {C:,//net}, return the first component.
397  return *b;
398  }
399  }
400 
401  // No path or no name.
402  return StringRef();
403 }
404 
406  const_iterator b = begin(path, style), pos = b, e = end(path);
407  if (b != e) {
408  bool has_net =
409  b->size() > 2 && is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
410  bool has_drive = (real_style(style) == Style::windows) && b->endswith(":");
411 
412  if ((has_net || has_drive) &&
413  // {C:,//net}, skip to the next component.
414  (++pos != e) && is_separator((*pos)[0], style)) {
415  return *pos;
416  }
417 
418  // POSIX style root directory.
419  if (!has_net && is_separator((*b)[0], style)) {
420  return *b;
421  }
422  }
423 
424  // No path or no root.
425  return StringRef();
426 }
427 
429  StringRef root = root_path(path, style);
430  return path.substr(root.size());
431 }
432 
433 void append(SmallVectorImpl<char> &path, Style style, const Twine &a,
434  const Twine &b, const Twine &c, const Twine &d) {
435  SmallString<32> a_storage;
436  SmallString<32> b_storage;
437  SmallString<32> c_storage;
438  SmallString<32> d_storage;
439 
440  SmallVector<StringRef, 4> components;
441  if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
442  if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
443  if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
444  if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
445 
446  for (auto &component : components) {
447  bool path_has_sep =
448  !path.empty() && is_separator(path[path.size() - 1], style);
449  if (path_has_sep) {
450  // Strip separators from beginning of component.
451  size_t loc = component.find_first_not_of(separators(style));
452  StringRef c = component.substr(loc);
453 
454  // Append it.
455  path.append(c.begin(), c.end());
456  continue;
457  }
458 
459  bool component_has_sep =
460  !component.empty() && is_separator(component[0], style);
461  if (!component_has_sep &&
462  !(path.empty() || has_root_name(component, style))) {
463  // Add a separator.
464  path.push_back(preferred_separator(style));
465  }
466 
467  path.append(component.begin(), component.end());
468  }
469 }
470 
471 void append(SmallVectorImpl<char> &path, const Twine &a, const Twine &b,
472  const Twine &c, const Twine &d) {
473  append(path, Style::native, a, b, c, d);
474 }
475 
477  const_iterator end, Style style) {
478  for (; begin != end; ++begin)
479  path::append(path, style, *begin);
480 }
481 
483  size_t end_pos = parent_path_end(path, style);
484  if (end_pos == StringRef::npos)
485  return StringRef();
486  else
487  return path.substr(0, end_pos);
488 }
489 
491  size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()), style);
492  if (end_pos != StringRef::npos)
493  path.set_size(end_pos);
494 }
495 
497  Style style) {
498  StringRef p(path.begin(), path.size());
499  SmallString<32> ext_storage;
500  StringRef ext = extension.toStringRef(ext_storage);
501 
502  // Erase existing extension.
503  size_t pos = p.find_last_of('.');
504  if (pos != StringRef::npos && pos >= filename_pos(p, style))
505  path.set_size(pos);
506 
507  // Append '.' if needed.
508  if (ext.size() > 0 && ext[0] != '.')
509  path.push_back('.');
510 
511  // Append extension.
512  path.append(ext.begin(), ext.end());
513 }
514 
516  const StringRef &OldPrefix, const StringRef &NewPrefix,
517  Style style) {
518  if (OldPrefix.empty() && NewPrefix.empty())
519  return;
520 
521  StringRef OrigPath(Path.begin(), Path.size());
522  if (!OrigPath.startswith(OldPrefix))
523  return;
524 
525  // If prefixes have the same size we can simply copy the new one over.
526  if (OldPrefix.size() == NewPrefix.size()) {
527  std::copy(NewPrefix.begin(), NewPrefix.end(), Path.begin());
528  return;
529  }
530 
531  StringRef RelPath = OrigPath.substr(OldPrefix.size());
532  SmallString<256> NewPath;
533  path::append(NewPath, style, NewPrefix);
534  path::append(NewPath, style, RelPath);
535  Path.swap(NewPath);
536 }
537 
538 void native(const Twine &path, SmallVectorImpl<char> &result, Style style) {
539  assert((!path.isSingleStringRef() ||
540  path.getSingleStringRef().data() != result.data()) &&
541  "path and result are not allowed to overlap!");
542  // Clear result.
543  result.clear();
544  path.toVector(result);
545  native(result, style);
546 }
547 
548 void native(SmallVectorImpl<char> &Path, Style style) {
549  if (Path.empty())
550  return;
551  if (real_style(style) == Style::windows) {
552  std::replace(Path.begin(), Path.end(), '/', '\\');
553  if (Path[0] == '~' && (Path.size() == 1 || is_separator(Path[1], style))) {
554  SmallString<128> PathHome;
555  home_directory(PathHome);
556  PathHome.append(Path.begin() + 1, Path.end());
557  Path = PathHome;
558  }
559  } else {
560  for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
561  if (*PI == '\\') {
562  auto PN = PI + 1;
563  if (PN < PE && *PN == '\\')
564  ++PI; // increment once, the for loop will move over the escaped slash
565  else
566  *PI = '/';
567  }
568  }
569  }
570 }
571 
572 std::string convert_to_slash(StringRef path, Style style) {
573  if (real_style(style) != Style::windows)
574  return path;
575 
576  std::string s = path.str();
577  std::replace(s.begin(), s.end(), '\\', '/');
578  return s;
579 }
580 
581 StringRef filename(StringRef path, Style style) { return *rbegin(path, style); }
582 
584  StringRef fname = filename(path, style);
585  size_t pos = fname.find_last_of('.');
586  if (pos == StringRef::npos)
587  return fname;
588  else
589  if ((fname.size() == 1 && fname == ".") ||
590  (fname.size() == 2 && fname == ".."))
591  return fname;
592  else
593  return fname.substr(0, pos);
594 }
595 
597  StringRef fname = filename(path, style);
598  size_t pos = fname.find_last_of('.');
599  if (pos == StringRef::npos)
600  return StringRef();
601  else
602  if ((fname.size() == 1 && fname == ".") ||
603  (fname.size() == 2 && fname == ".."))
604  return StringRef();
605  else
606  return fname.substr(pos);
607 }
608 
609 bool is_separator(char value, Style style) {
610  if (value == '/')
611  return true;
612  if (real_style(style) == Style::windows)
613  return value == '\\';
614  return false;
615 }
616 
618  if (real_style(style) == Style::windows)
619  return "\\";
620  return "/";
621 }
622 
623 bool has_root_name(const Twine &path, Style style) {
624  SmallString<128> path_storage;
625  StringRef p = path.toStringRef(path_storage);
626 
627  return !root_name(p, style).empty();
628 }
629 
630 bool has_root_directory(const Twine &path, Style style) {
631  SmallString<128> path_storage;
632  StringRef p = path.toStringRef(path_storage);
633 
634  return !root_directory(p, style).empty();
635 }
636 
637 bool has_root_path(const Twine &path, Style style) {
638  SmallString<128> path_storage;
639  StringRef p = path.toStringRef(path_storage);
640 
641  return !root_path(p, style).empty();
642 }
643 
644 bool has_relative_path(const Twine &path, Style style) {
645  SmallString<128> path_storage;
646  StringRef p = path.toStringRef(path_storage);
647 
648  return !relative_path(p, style).empty();
649 }
650 
651 bool has_filename(const Twine &path, Style style) {
652  SmallString<128> path_storage;
653  StringRef p = path.toStringRef(path_storage);
654 
655  return !filename(p, style).empty();
656 }
657 
658 bool has_parent_path(const Twine &path, Style style) {
659  SmallString<128> path_storage;
660  StringRef p = path.toStringRef(path_storage);
661 
662  return !parent_path(p, style).empty();
663 }
664 
665 bool has_stem(const Twine &path, Style style) {
666  SmallString<128> path_storage;
667  StringRef p = path.toStringRef(path_storage);
668 
669  return !stem(p, style).empty();
670 }
671 
672 bool has_extension(const Twine &path, Style style) {
673  SmallString<128> path_storage;
674  StringRef p = path.toStringRef(path_storage);
675 
676  return !extension(p, style).empty();
677 }
678 
679 bool is_absolute(const Twine &path, Style style) {
680  SmallString<128> path_storage;
681  StringRef p = path.toStringRef(path_storage);
682 
683  bool rootDir = has_root_directory(p, style);
684  bool rootName =
685  (real_style(style) != Style::windows) || has_root_name(p, style);
686 
687  return rootDir && rootName;
688 }
689 
690 bool is_relative(const Twine &path, Style style) {
691  return !is_absolute(path, style);
692 }
693 
695  // Remove leading "./" (or ".//" or "././" etc.)
696  while (Path.size() > 2 && Path[0] == '.' && is_separator(Path[1], style)) {
697  Path = Path.substr(2);
698  while (Path.size() > 0 && is_separator(Path[0], style))
699  Path = Path.substr(1);
700  }
701  return Path;
702 }
703 
704 static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot,
705  Style style) {
706  SmallVector<StringRef, 16> components;
707 
708  // Skip the root path, then look for traversal in the components.
709  StringRef rel = path::relative_path(path, style);
710  for (StringRef C :
711  llvm::make_range(path::begin(rel, style), path::end(rel))) {
712  if (C == ".")
713  continue;
714  // Leading ".." will remain in the path unless it's at the root.
715  if (remove_dot_dot && C == "..") {
716  if (!components.empty() && components.back() != "..") {
717  components.pop_back();
718  continue;
719  }
720  if (path::is_absolute(path, style))
721  continue;
722  }
723  components.push_back(C);
724  }
725 
726  SmallString<256> buffer = path::root_path(path, style);
727  for (StringRef C : components)
728  path::append(buffer, style, C);
729  return buffer;
730 }
731 
732 bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot,
733  Style style) {
734  StringRef p(path.data(), path.size());
735 
736  SmallString<256> result = remove_dots(p, remove_dot_dot, style);
737  if (result == path)
738  return false;
739 
740  path.swap(result);
741  return true;
742 }
743 
744 } // end namespace path
745 
746 namespace fs {
747 
748 std::error_code getUniqueID(const Twine Path, UniqueID &Result) {
749  file_status Status;
750  std::error_code EC = status(Path, Status);
751  if (EC)
752  return EC;
753  Result = Status.getUniqueID();
754  return std::error_code();
755 }
756 
757 std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
758  SmallVectorImpl<char> &ResultPath,
759  unsigned Mode, sys::fs::OpenFlags Flags) {
760  return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File,
761  Flags);
762 }
763 
764 std::error_code createUniqueFile(const Twine &Model,
765  SmallVectorImpl<char> &ResultPath,
766  unsigned Mode) {
767  int FD;
768  auto EC = createUniqueFile(Model, FD, ResultPath, Mode);
769  if (EC)
770  return EC;
771  // FD is only needed to avoid race conditions. Close it right away.
772  close(FD);
773  return EC;
774 }
775 
776 static std::error_code
777 createTemporaryFile(const Twine &Model, int &ResultFD,
779  sys::fs::OpenFlags Flags) {
780  SmallString<128> Storage;
781  StringRef P = Model.toNullTerminatedStringRef(Storage);
783  "Model must be a simple filename.");
784  // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
785  return createUniqueEntity(P.begin(), ResultFD, ResultPath, true,
786  owner_read | owner_write, Type, Flags);
787 }
788 
789 static std::error_code
790 createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
793  const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
794  return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
795  Type, Flags);
796 }
797 
798 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
799  int &ResultFD,
800  SmallVectorImpl<char> &ResultPath,
801  sys::fs::OpenFlags Flags) {
802  return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File,
803  Flags);
804 }
805 
806 std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
807  SmallVectorImpl<char> &ResultPath) {
808  int FD;
809  auto EC = createTemporaryFile(Prefix, Suffix, FD, ResultPath);
810  if (EC)
811  return EC;
812  // FD is only needed to avoid race conditions. Close it right away.
813  close(FD);
814  return EC;
815 }
816 
817 
818 // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
819 // for consistency. We should try using mkdtemp.
820 std::error_code createUniqueDirectory(const Twine &Prefix,
821  SmallVectorImpl<char> &ResultPath) {
822  int Dummy;
823  return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath, true, 0,
824  FS_Dir);
825 }
826 
827 std::error_code
829  SmallVectorImpl<char> &ResultPath) {
830  int Dummy;
831  return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
832 }
833 
834 std::error_code
836  SmallVectorImpl<char> &ResultPath) {
837  int Dummy;
838  return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
839 }
840 
841 static std::error_code make_absolute(const Twine &current_directory,
842  SmallVectorImpl<char> &path,
843  bool use_current_directory) {
844  StringRef p(path.data(), path.size());
845 
846  bool rootDirectory = path::has_root_directory(p);
847  bool rootName =
848  (real_style(Style::native) != Style::windows) || path::has_root_name(p);
849 
850  // Already absolute.
851  if (rootName && rootDirectory)
852  return std::error_code();
853 
854  // All of the following conditions will need the current directory.
855  SmallString<128> current_dir;
856  if (use_current_directory)
857  current_directory.toVector(current_dir);
858  else if (std::error_code ec = current_path(current_dir))
859  return ec;
860 
861  // Relative path. Prepend the current directory.
862  if (!rootName && !rootDirectory) {
863  // Append path to the current directory.
864  path::append(current_dir, p);
865  // Set path to the result.
866  path.swap(current_dir);
867  return std::error_code();
868  }
869 
870  if (!rootName && rootDirectory) {
871  StringRef cdrn = path::root_name(current_dir);
872  SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
873  path::append(curDirRootName, p);
874  // Set path to the result.
875  path.swap(curDirRootName);
876  return std::error_code();
877  }
878 
879  if (rootName && !rootDirectory) {
880  StringRef pRootName = path::root_name(p);
881  StringRef bRootDirectory = path::root_directory(current_dir);
882  StringRef bRelativePath = path::relative_path(current_dir);
883  StringRef pRelativePath = path::relative_path(p);
884 
885  SmallString<128> res;
886  path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
887  path.swap(res);
888  return std::error_code();
889  }
890 
891  llvm_unreachable("All rootName and rootDirectory combinations should have "
892  "occurred above!");
893 }
894 
895 std::error_code make_absolute(const Twine &current_directory,
896  SmallVectorImpl<char> &path) {
897  return make_absolute(current_directory, path, true);
898 }
899 
900 std::error_code make_absolute(SmallVectorImpl<char> &path) {
901  return make_absolute(Twine(), path, false);
902 }
903 
904 std::error_code create_directories(const Twine &Path, bool IgnoreExisting,
905  perms Perms) {
906  SmallString<128> PathStorage;
907  StringRef P = Path.toStringRef(PathStorage);
908 
909  // Be optimistic and try to create the directory
910  std::error_code EC = create_directory(P, IgnoreExisting, Perms);
911  // If we succeeded, or had any error other than the parent not existing, just
912  // return it.
914  return EC;
915 
916  // We failed because of a no_such_file_or_directory, try to create the
917  // parent.
918  StringRef Parent = path::parent_path(P);
919  if (Parent.empty())
920  return EC;
921 
922  if ((EC = create_directories(Parent, IgnoreExisting, Perms)))
923  return EC;
924 
925  return create_directory(P, IgnoreExisting, Perms);
926 }
927 
928 std::error_code copy_file(const Twine &From, const Twine &To) {
929  int ReadFD, WriteFD;
930  if (std::error_code EC = openFileForRead(From, ReadFD))
931  return EC;
932  if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) {
933  close(ReadFD);
934  return EC;
935  }
936 
937  const size_t BufSize = 4096;
938  char *Buf = new char[BufSize];
939  int BytesRead = 0, BytesWritten = 0;
940  for (;;) {
941  BytesRead = read(ReadFD, Buf, BufSize);
942  if (BytesRead <= 0)
943  break;
944  while (BytesRead) {
945  BytesWritten = write(WriteFD, Buf, BytesRead);
946  if (BytesWritten < 0)
947  break;
948  BytesRead -= BytesWritten;
949  }
950  if (BytesWritten < 0)
951  break;
952  }
953  close(ReadFD);
954  close(WriteFD);
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 
963  MD5 Hash;
964 
965  constexpr size_t BufSize = 4096;
966  std::vector<uint8_t> Buf(BufSize);
967  int BytesRead = 0;
968  for (;;) {
969  BytesRead = read(FD, Buf.data(), BufSize);
970  if (BytesRead <= 0)
971  break;
972  Hash.update(makeArrayRef(Buf.data(), BytesRead));
973  }
974 
975  if (BytesRead < 0)
976  return std::error_code(errno, std::generic_category());
977  MD5::MD5Result Result;
978  Hash.final(Result);
979  return Result;
980 }
981 
983  int FD;
984  if (auto EC = openFileForRead(Path, FD))
985  return EC;
986 
987  auto Result = md5_contents(FD);
988  close(FD);
989  return Result;
990 }
991 
993  return status_known(status) && status.type() != file_type::file_not_found;
994 }
995 
997  return s.type() != file_type::status_error;
998 }
999 
1000 file_type get_file_type(const Twine &Path, bool Follow) {
1001  file_status st;
1002  if (status(Path, st, Follow))
1003  return file_type::status_error;
1004  return st.type();
1005 }
1006 
1008  return status.type() == file_type::directory_file;
1009 }
1010 
1011 std::error_code is_directory(const Twine &path, bool &result) {
1012  file_status st;
1013  if (std::error_code ec = status(path, st))
1014  return ec;
1015  result = is_directory(st);
1016  return std::error_code();
1017 }
1018 
1020  return status.type() == file_type::regular_file;
1021 }
1022 
1023 std::error_code is_regular_file(const Twine &path, bool &result) {
1024  file_status st;
1025  if (std::error_code ec = status(path, st))
1026  return ec;
1027  result = is_regular_file(st);
1028  return std::error_code();
1029 }
1030 
1032  return status.type() == file_type::symlink_file;
1033 }
1034 
1035 std::error_code is_symlink_file(const Twine &path, bool &result) {
1036  file_status st;
1037  if (std::error_code ec = status(path, st, false))
1038  return ec;
1039  result = is_symlink_file(st);
1040  return std::error_code();
1041 }
1042 
1044  return exists(status) &&
1045  !is_regular_file(status) &&
1046  !is_directory(status);
1047 }
1048 
1049 std::error_code is_other(const Twine &Path, bool &Result) {
1050  file_status FileStatus;
1051  if (std::error_code EC = status(Path, FileStatus))
1052  return EC;
1053  Result = is_other(FileStatus);
1054  return std::error_code();
1055 }
1056 
1057 void directory_entry::replace_filename(const Twine &filename,
1058  basic_file_status st) {
1059  SmallString<128> path = path::parent_path(Path);
1060  path::append(path, filename);
1061  Path = path.str();
1062  Status = st;
1063 }
1064 
1066  file_status Status;
1067  if (std::error_code EC = status(Path, Status))
1068  return EC;
1069 
1070  return Status.permissions();
1071 }
1072 
1073 } // end namespace fs
1074 } // end namespace sys
1075 } // end namespace llvm
1076 
1077 // Include the truly platform-specific parts.
1078 #if defined(LLVM_ON_UNIX)
1079 #include "Unix/Path.inc"
1080 #endif
1081 #if defined(_WIN32)
1082 #include "Windows/Path.inc"
1083 #endif
1084 
1085 namespace llvm {
1086 namespace sys {
1087 namespace fs {
1088 TempFile::TempFile(StringRef Name, int FD) : TmpName(Name), FD(FD) {}
1089 TempFile::TempFile(TempFile &&Other) { *this = std::move(Other); }
1090 TempFile &TempFile::operator=(TempFile &&Other) {
1091  TmpName = std::move(Other.TmpName);
1092  FD = Other.FD;
1093  Other.Done = true;
1094  return *this;
1095 }
1096 
1097 TempFile::~TempFile() { assert(Done); }
1098 
1099 Error TempFile::discard() {
1100  Done = true;
1101  std::error_code RemoveEC;
1102 // On windows closing will remove the file.
1103 #ifndef _WIN32
1104  // Always try to close and remove.
1105  if (!TmpName.empty()) {
1106  RemoveEC = fs::remove(TmpName);
1107  sys::DontRemoveFileOnSignal(TmpName);
1108  }
1109 #endif
1110 
1111  if (!RemoveEC)
1112  TmpName = "";
1113 
1114  if (FD != -1 && close(FD) == -1) {
1115  std::error_code EC = std::error_code(errno, std::generic_category());
1116  return errorCodeToError(EC);
1117  }
1118  FD = -1;
1119 
1120  return errorCodeToError(RemoveEC);
1121 }
1122 
1123 Error TempFile::keep(const Twine &Name) {
1124  assert(!Done);
1125  Done = true;
1126  // Always try to close and rename.
1127 #ifdef _WIN32
1128  // If we cant't cancel the delete don't rename.
1129  std::error_code RenameEC = cancelDeleteOnClose(FD);
1130  if (!RenameEC)
1131  RenameEC = rename_fd(FD, Name);
1132  // If we can't rename, discard the temporary file.
1133  if (RenameEC)
1134  removeFD(FD);
1135 #else
1136  std::error_code RenameEC = fs::rename(TmpName, Name);
1137  // If we can't rename, discard the temporary file.
1138  if (RenameEC)
1139  remove(TmpName);
1140  sys::DontRemoveFileOnSignal(TmpName);
1141 #endif
1142 
1143  if (!RenameEC)
1144  TmpName = "";
1145 
1146  if (close(FD) == -1) {
1147  std::error_code EC(errno, std::generic_category());
1148  return errorCodeToError(EC);
1149  }
1150  FD = -1;
1151 
1152  return errorCodeToError(RenameEC);
1153 }
1154 
1155 Error TempFile::keep() {
1156  assert(!Done);
1157  Done = true;
1158 
1159 #ifdef _WIN32
1160  if (std::error_code EC = cancelDeleteOnClose(FD))
1161  return errorCodeToError(EC);
1162 #else
1163  sys::DontRemoveFileOnSignal(TmpName);
1164 #endif
1165 
1166  TmpName = "";
1167 
1168  if (close(FD) == -1) {
1169  std::error_code EC(errno, std::generic_category());
1170  return errorCodeToError(EC);
1171  }
1172  FD = -1;
1173 
1174  return Error::success();
1175 }
1176 
1177 Expected<TempFile> TempFile::create(const Twine &Model, unsigned Mode) {
1178  int FD;
1179  SmallString<128> ResultPath;
1180  if (std::error_code EC = createUniqueFile(Model, FD, ResultPath, Mode,
1182  return errorCodeToError(EC);
1183 
1184  TempFile Ret(ResultPath, FD);
1185 #ifndef _WIN32
1186  if (sys::RemoveFileOnSignal(ResultPath)) {
1187  // Make sure we delete the file when RemoveFileOnSignal fails.
1188  consumeError(Ret.discard());
1189  std::error_code EC(errc::operation_not_permitted);
1190  return errorCodeToError(EC);
1191  }
1192 #endif
1193  return std::move(Ret);
1194 }
1195 }
1196 
1197 namespace path {
1198 
1200  const Twine &Path2, const Twine &Path3) {
1201  if (getUserCacheDir(Result)) {
1202  append(Result, Path1, Path2, Path3);
1203  return true;
1204  }
1205  return false;
1206 }
1207 
1208 } // end namespace path
1209 } // end namsspace sys
1210 } // end namespace llvm
uint64_t CallInst * C
void push_back(const T &Elt)
Definition: SmallVector.h:212
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:609
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:904
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:250
Represents either an error or a value T.
Definition: ErrorOr.h:69
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:490
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:241
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:515
SI Whole Quad Mode
bool status_known(const basic_file_status &s)
Is status available?
Definition: Path.cpp:996
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
Definition: SmallVector.h:136
std::error_code openFileForRead(const Twine &Name, int &ResultFD, 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.
F_Excl - When opening a file, this flag makes raw_fd_ostream report an error if the file already exis...
Definition: FileSystem.h:675
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
bool has_extension(const Twine &path, Style style=Style::native)
Has extension?
Definition: Path.cpp:672
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:1007
std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
Definition: Path.cpp:572
bool is_regular_file(const basic_file_status &status)
Does status represent a regular file?
Definition: Path.cpp:1019
StringRef remove_leading_dotslash(StringRef path, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
Definition: Path.cpp:694
Represents the result of a call to sys::fs::status().
Definition: FileSystem.h:220
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:962
ErrorOr< perms > getPermissions(const Twine &Path)
Get file permissions.
Definition: Path.cpp:1065
bool has_stem(const Twine &path, Style style=Style::native)
Has stem?
Definition: Path.cpp:665
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition: Path.cpp:471
reverse_iterator rbegin(StringRef path, Style style=Style::native)
Get reverse begin iterator over path.
Definition: Path.cpp:312
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:737
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition: Path.cpp:679
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:362
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
Definition: Twine.h:437
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:769
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:267
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
Open the file for read and write.
Definition: FileSystem.h:692
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
static std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, llvm::SmallVectorImpl< char > &ResultPath, FSEntity Type, sys::fs::OpenFlags Flags=sys::fs::F_None)
Definition: Path.cpp:790
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:149
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
Definition: Path.cpp:928
#define P(N)
static SmallString< 256 > remove_dots(StringRef path, bool remove_dot_dot, Style style)
Definition: Path.cpp:704
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:694
bool has_parent_path(const Twine &path, Style style=Style::native)
Has parent path?
Definition: Path.cpp:658
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:78
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:116
bool has_filename(const Twine &path, Style style=Style::native)
Has filename?
Definition: Path.cpp:651
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
bool user_cache_directory(SmallVectorImpl< char > &Result, const Twine &Path1, const Twine &Path2="", const Twine &Path3="")
Get the user&#39;s cache directory.
Definition: Path.cpp:1199
std::error_code getUniqueID(const Twine Path, UniqueID &Result)
Definition: Path.cpp:748
file_type get_file_type(const Twine &Path, bool Follow=true)
Does status represent a directory?
Definition: Path.cpp:1000
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:482
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
Definition: Twine.cpp:33
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:962
StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
Definition: Path.cpp:617
#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:313
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:862
StringRef root_directory(StringRef path, Style style=Style::native)
Get root directory.
Definition: Path.cpp:405
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
Definition: Path.cpp:496
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:388
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
Definition: Path.cpp:820
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::F_None)
Definition: Path.cpp:169
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:1043
bool has_root_directory(const Twine &path, Style style=Style::native)
Has root directory?
Definition: Path.cpp:630
Path iterator.
Definition: Path.h:52
iterator begin() const
Definition: StringRef.h:106
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:396
bool has_root_path(const Twine &path, Style style=Style::native)
Has root path?
Definition: Path.cpp:637
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:644
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:120
void set_size(size_type N)
Set the array size to N, which the current array must have enough capacity for.
Definition: SmallVector.h:687
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:143
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:58
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
Definition: Path.cpp:581
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:61
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:690
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:835
APInt operator-(APInt)
Definition: APInt.h:2028
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:320
std::error_code getPotentiallyUniqueFileName(const Twine &Model, SmallVectorImpl< char > &ResultPath)
Get a unique name, not currently exisiting in the filesystem.
Definition: Path.cpp:828
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())
StringRef relative_path(StringRef path, Style style=Style::native)
Get relative path.
Definition: Path.cpp:428
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
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?
Delete the file on close. Only makes a difference on windows.
Definition: FileSystem.h:695
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:583
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static Expected< std::string > replace(StringRef S, StringRef From, StringRef To)
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, unsigned Mode=all_read|all_write, sys::fs::OpenFlags Flags=sys::fs::F_RW)
Create a uniquely named file.
Definition: Path.cpp:757
bool operator==(uint64_t V1, const APInt &V2)
Definition: APInt.h:1951
bool has_root_name(const Twine &path, Style style=Style::native)
Has root name?
Definition: Path.cpp:623
bool is_symlink_file(const basic_file_status &status)
Does status represent a symlink file?
Definition: Path.cpp:1031
bool exists(const basic_file_status &status)
Does file exist?
Definition: Path.cpp:992
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:960
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:596
static std::error_code make_absolute(const Twine &current_directory, SmallVectorImpl< char > &path, bool use_current_directory)
Definition: Path.cpp:841
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, 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...