Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
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/ADT/ScopeExit.h"
16#include "llvm/ADT/StringExtras.h"
17#include "llvm/Config/config.h"
18#include "llvm/Config/llvm-config.h"
19#include "llvm/Support/Errc.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/Process.h"
23#include "llvm/Support/Signals.h"
24#include <cctype>
25
26#if !defined(_MSC_VER) && !defined(__MINGW32__)
27#include <unistd.h>
28#else
29#include <io.h>
30#endif
31
32using namespacellvm;
33using namespacellvm::support::endian;
34
35namespace{
36usingllvm::StringRef;
37usingllvm::sys::path::is_separator;
38usingllvm::sys::path::Style;
39
40inlineStyle real_style(Style style) {
41if (style != Style::native)
42return style;
43if (is_style_posix(style))
44return Style::posix;
45return LLVM_WINDOWS_PREFER_FORWARD_SLASH ? Style::windows_slash
46 : Style::windows_backslash;
47 }
48
49inlineconstchar *separators(Style style) {
50if (is_style_windows(style))
51return"\\/";
52return"/";
53 }
54
55inlinechar preferred_separator(Style style) {
56if (real_style(style) == Style::windows)
57return'\\';
58return'/';
59 }
60
61StringRef find_first_component(StringRef path, Style style) {
62// Look for this first component in the following order.
63// * empty (in this case we return an empty string)
64// * either C: or {//,\\}net.
65// * {/,\}
66// * {file,directory}name
67
68if (path.empty())
69return path;
70
71if (is_style_windows(style)) {
72// C:
73if (path.size() >= 2 &&
74 std::isalpha(static_cast<unsignedchar>(path[0])) && path[1] ==':')
75return path.substr(0, 2);
76 }
77
78// //net
79if ((path.size() > 2) &&is_separator(path[0], style) &&
80 path[0] == path[1] && !is_separator(path[2], style)) {
81// Find the next directory separator.
82size_tend = path.find_first_of(separators(style), 2);
83return path.substr(0, end);
84 }
85
86// {/,\}
87if (is_separator(path[0], style))
88return path.substr(0, 1);
89
90// * {file,directory}name
91size_tend = path.find_first_of(separators(style));
92return path.substr(0, end);
93 }
94
95// Returns the first character of the filename in str. For paths ending in
96// '/', it returns the position of the '/'.
97size_t filename_pos(StringRef str, Style style) {
98if (str.size() > 0 &&is_separator(str[str.size() - 1], style))
99return str.size() - 1;
100
101size_t pos = str.find_last_of(separators(style), str.size() - 1);
102
103if (is_style_windows(style)) {
104if (pos ==StringRef::npos)
105 pos = str.find_last_of(':', str.size() - 1);
106 }
107
108if (pos ==StringRef::npos || (pos == 1 &&is_separator(str[0], style)))
109return 0;
110
111return pos + 1;
112 }
113
114// Returns the position of the root directory in str. If there is no root
115// directory in str, it returns StringRef::npos.
116size_t root_dir_start(StringRef str, Style style) {
117// case "c:/"
118if (is_style_windows(style)) {
119if (str.size() > 2 && str[1] ==':' &&is_separator(str[2], style))
120return 2;
121 }
122
123// case "//net"
124if (str.size() > 3 &&is_separator(str[0], style) && str[0] == str[1] &&
125 !is_separator(str[2], style)) {
126return str.find_first_of(separators(style), 2);
127 }
128
129// case "/"
130if (str.size() > 0 &&is_separator(str[0], style))
131return 0;
132
133returnStringRef::npos;
134 }
135
136// Returns the position past the end of the "parent path" of path. The parent
137// path will not end in '/', unless the parent is the root directory. If the
138// path has no parent, 0 is returned.
139size_t parent_path_end(StringRef path, Style style) {
140size_t end_pos = filename_pos(path, style);
141
142bool filename_was_sep =
143 path.size() > 0 &&is_separator(path[end_pos], style);
144
145// Skip separators until we reach root dir (or the start of the string).
146size_t root_dir_pos = root_dir_start(path, style);
147while (end_pos > 0 &&
148 (root_dir_pos ==StringRef::npos || end_pos > root_dir_pos) &&
149is_separator(path[end_pos - 1], style))
150 --end_pos;
151
152if (end_pos == root_dir_pos && !filename_was_sep) {
153// We've reached the root dir and the input path was *not* ending in a
154// sequence of slashes. Include the root dir in the parent path.
155return root_dir_pos + 1;
156 }
157
158// Otherwise, just include before the last slash.
159return end_pos;
160 }
161}// end unnamed namespace
162
163enumFSEntity {
164FS_Dir,
165FS_File,
166FS_Name
167};
168
169static std::error_code
170createUniqueEntity(constTwine &Model,int &ResultFD,
171SmallVectorImpl<char> &ResultPath,bool MakeAbsolute,
172FSEntityType,sys::fs::OpenFlags Flags =sys::fs::OF_None,
173unsigned Mode = 0) {
174
175// Limit the number of attempts we make, so that we don't infinite loop. E.g.
176// "permission denied" could be for a specific file (so we retry with a
177// different name) or for the whole directory (retry would always fail).
178// Checking which is racy, so we try a number of times, then give up.
179 std::error_code EC;
180for (int Retries = 128; Retries > 0; --Retries) {
181sys::fs::createUniquePath(Model, ResultPath, MakeAbsolute);
182// Try to open + create the file.
183switch (Type) {
184caseFS_File: {
185 EC =sys::fs::openFileForReadWrite(Twine(ResultPath.begin()), ResultFD,
186sys::fs::CD_CreateNew, Flags, Mode);
187if (EC) {
188// errc::permission_denied happens on Windows when we try to open a file
189// that has been marked for deletion.
190if (EC == errc::file_exists || EC == errc::permission_denied)
191continue;
192return EC;
193 }
194
195return std::error_code();
196 }
197
198caseFS_Name: {
199 EC =sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist);
200if (EC == errc::no_such_file_or_directory)
201return std::error_code();
202if (EC)
203return EC;
204continue;
205 }
206
207caseFS_Dir: {
208 EC =sys::fs::create_directory(ResultPath.begin(),false);
209if (EC) {
210if (EC == errc::file_exists)
211continue;
212return EC;
213 }
214return std::error_code();
215 }
216 }
217llvm_unreachable("Invalid Type");
218 }
219return EC;
220}
221
222namespacellvm {
223namespacesys {
224namespacepath {
225
226const_iteratorbegin(StringRef path,Style style) {
227const_iterator i;
228 i.Path = path;
229 i.Component = find_first_component(path, style);
230 i.Position = 0;
231 i.S = style;
232return i;
233}
234
235const_iteratorend(StringRef path) {
236const_iterator i;
237 i.Path = path;
238 i.Position = path.size();
239return i;
240}
241
242const_iterator &const_iterator::operator++() {
243assert(Position < Path.size() &&"Tried to increment past end!");
244
245// Increment Position to past the current component
246 Position += Component.size();
247
248// Check for end.
249if (Position == Path.size()) {
250 Component =StringRef();
251return *this;
252 }
253
254// Both POSIX and Windows treat paths that begin with exactly two separators
255// specially.
256bool was_net = Component.size() > 2 &&is_separator(Component[0], S) &&
257 Component[1] == Component[0] && !is_separator(Component[2], S);
258
259// Handle separators.
260if (is_separator(Path[Position], S)) {
261// Root dir.
262if (was_net ||
263// c:/
264 (is_style_windows(S) && Component.ends_with(":"))) {
265 Component = Path.substr(Position, 1);
266return *this;
267 }
268
269// Skip extra separators.
270while (Position != Path.size() &&is_separator(Path[Position], S)) {
271 ++Position;
272 }
273
274// Treat trailing '/' as a '.', unless it is the root dir.
275if (Position == Path.size() && Component !="/") {
276 --Position;
277 Component =".";
278return *this;
279 }
280 }
281
282// Find next component.
283size_t end_pos = Path.find_first_of(separators(S), Position);
284 Component = Path.slice(Position, end_pos);
285
286return *this;
287}
288
289boolconst_iterator::operator==(constconst_iterator &RHS) const{
290return Path.begin() ==RHS.Path.begin() && Position ==RHS.Position;
291}
292
293ptrdiff_tconst_iterator::operator-(constconst_iterator &RHS) const{
294return Position -RHS.Position;
295}
296
297reverse_iteratorrbegin(StringRef Path,Style style) {
298reverse_iteratorI;
299I.Path = Path;
300I.Position = Path.size();
301I.S = style;
302 ++I;
303returnI;
304}
305
306reverse_iteratorrend(StringRef Path) {
307reverse_iteratorI;
308I.Path = Path;
309I.Component = Path.substr(0, 0);
310I.Position = 0;
311returnI;
312}
313
314reverse_iterator &reverse_iterator::operator++() {
315size_t root_dir_pos = root_dir_start(Path, S);
316
317// Skip separators unless it's the root directory.
318size_t end_pos = Position;
319while (end_pos > 0 && (end_pos - 1) != root_dir_pos &&
320is_separator(Path[end_pos - 1], S))
321 --end_pos;
322
323// Treat trailing '/' as a '.', unless it is the root dir.
324if (Position == Path.size() && !Path.empty() &&
325is_separator(Path.back(), S) &&
326 (root_dir_pos ==StringRef::npos || end_pos - 1 > root_dir_pos)) {
327 --Position;
328 Component =".";
329return *this;
330 }
331
332// Find next separator.
333size_t start_pos = filename_pos(Path.substr(0, end_pos), S);
334 Component = Path.slice(start_pos, end_pos);
335 Position = start_pos;
336return *this;
337}
338
339boolreverse_iterator::operator==(constreverse_iterator &RHS) const{
340return Path.begin() ==RHS.Path.begin() && Component ==RHS.Component &&
341 Position ==RHS.Position;
342}
343
344ptrdiff_treverse_iterator::operator-(constreverse_iterator &RHS) const{
345return Position -RHS.Position;
346}
347
348StringRefroot_path(StringRef path,Style style) {
349const_iterator b =begin(path, style), pos = b, e =end(path);
350if (b != e) {
351bool has_net =
352 b->size() > 2 &&is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
353bool has_drive =is_style_windows(style) && b->ends_with(":");
354
355if (has_net || has_drive) {
356if ((++pos != e) &&is_separator((*pos)[0], style)) {
357// {C:/,//net/}, so get the first two components.
358return path.substr(0, b->size() + pos->size());
359 }
360// just {C:,//net}, return the first component.
361return *b;
362 }
363
364// POSIX style root directory.
365if (is_separator((*b)[0], style)) {
366return *b;
367 }
368 }
369
370returnStringRef();
371}
372
373StringRefroot_name(StringRef path,Style style) {
374const_iterator b =begin(path, style), e =end(path);
375if (b != e) {
376bool has_net =
377 b->size() > 2 &&is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
378bool has_drive =is_style_windows(style) && b->ends_with(":");
379
380if (has_net || has_drive) {
381// just {C:,//net}, return the first component.
382return *b;
383 }
384 }
385
386// No path or no name.
387returnStringRef();
388}
389
390StringRefroot_directory(StringRef path,Style style) {
391const_iterator b =begin(path, style), pos = b, e =end(path);
392if (b != e) {
393bool has_net =
394 b->size() > 2 &&is_separator((*b)[0], style) && (*b)[1] == (*b)[0];
395bool has_drive =is_style_windows(style) && b->ends_with(":");
396
397if ((has_net || has_drive) &&
398// {C:,//net}, skip to the next component.
399 (++pos != e) &&is_separator((*pos)[0], style)) {
400return *pos;
401 }
402
403// POSIX style root directory.
404if (!has_net &&is_separator((*b)[0], style)) {
405return *b;
406 }
407 }
408
409// No path or no root.
410returnStringRef();
411}
412
413StringRefrelative_path(StringRef path,Style style) {
414StringRef root =root_path(path, style);
415return path.substr(root.size());
416}
417
418voidappend(SmallVectorImpl<char> &path,Style style,constTwine &a,
419constTwine &b,constTwine &c,constTwine &d) {
420SmallString<32> a_storage;
421SmallString<32> b_storage;
422SmallString<32> c_storage;
423SmallString<32> d_storage;
424
425SmallVector<StringRef, 4> components;
426if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
427if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
428if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
429if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
430
431for (auto &component : components) {
432bool path_has_sep =
433 !path.empty() &&is_separator(path[path.size() - 1], style);
434if (path_has_sep) {
435// Strip separators from beginning of component.
436size_t loc = component.find_first_not_of(separators(style));
437StringRef c = component.substr(loc);
438
439// Append it.
440 path.append(c.begin(), c.end());
441continue;
442 }
443
444bool component_has_sep =
445 !component.empty() &&is_separator(component[0], style);
446if (!component_has_sep &&
447 !(path.empty() ||has_root_name(component, style))) {
448// Add a separator.
449 path.push_back(preferred_separator(style));
450 }
451
452 path.append(component.begin(), component.end());
453 }
454}
455
456voidappend(SmallVectorImpl<char> &path,constTwine &a,constTwine &b,
457constTwine &c,constTwine &d) {
458append(path,Style::native, a, b, c, d);
459}
460
461voidappend(SmallVectorImpl<char> &path,const_iterator begin,
462const_iterator end,Style style) {
463for (;begin !=end; ++begin)
464path::append(path, style, *begin);
465}
466
467StringRefparent_path(StringRef path,Style style) {
468size_t end_pos = parent_path_end(path, style);
469if (end_pos ==StringRef::npos)
470returnStringRef();
471return path.substr(0, end_pos);
472}
473
474voidremove_filename(SmallVectorImpl<char> &path,Style style) {
475size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()), style);
476if (end_pos !=StringRef::npos)
477 path.truncate(end_pos);
478}
479
480voidreplace_extension(SmallVectorImpl<char> &path,constTwine &extension,
481Style style) {
482StringRef p(path.begin(), path.size());
483SmallString<32> ext_storage;
484StringRef ext =extension.toStringRef(ext_storage);
485
486// Erase existing extension.
487size_t pos = p.find_last_of('.');
488if (pos !=StringRef::npos && pos >= filename_pos(p, style))
489 path.truncate(pos);
490
491// Append '.' if needed.
492if (ext.size() > 0 && ext[0] !='.')
493 path.push_back('.');
494
495// Append extension.
496 path.append(ext.begin(), ext.end());
497}
498
499staticboolstarts_with(StringRef Path,StringRef Prefix,
500Style style =Style::native) {
501// Windows prefix matching : case and separator insensitive
502if (is_style_windows(style)) {
503if (Path.size() < Prefix.size())
504returnfalse;
505for (size_tI = 0, E = Prefix.size();I != E; ++I) {
506bool SepPath =is_separator(Path[I], style);
507bool SepPrefix =is_separator(Prefix[I], style);
508if (SepPath != SepPrefix)
509returnfalse;
510if (!SepPath && toLower(Path[I]) != toLower(Prefix[I]))
511returnfalse;
512 }
513returntrue;
514 }
515return Path.starts_with(Prefix);
516}
517
518boolreplace_path_prefix(SmallVectorImpl<char> &Path,StringRef OldPrefix,
519StringRef NewPrefix,Style style) {
520if (OldPrefix.empty() && NewPrefix.empty())
521returnfalse;
522
523StringRef OrigPath(Path.begin(), Path.size());
524if (!starts_with(OrigPath, OldPrefix, style))
525returnfalse;
526
527// If prefixes have the same size we can simply copy the new one over.
528if (OldPrefix.size() == NewPrefix.size()) {
529llvm::copy(NewPrefix, Path.begin());
530returntrue;
531 }
532
533StringRef RelPath = OrigPath.substr(OldPrefix.size());
534SmallString<256> NewPath;
535 (Twine(NewPrefix) + RelPath).toVector(NewPath);
536 Path.swap(NewPath);
537returntrue;
538}
539
540voidnative(constTwine &path,SmallVectorImpl<char> &result,Style style) {
541assert((!path.isSingleStringRef() ||
542 path.getSingleStringRef().data() != result.data()) &&
543"path and result are not allowed to overlap!");
544// Clear result.
545 result.clear();
546 path.toVector(result);
547native(result, style);
548}
549
550voidnative(SmallVectorImpl<char> &Path,Style style) {
551if (Path.empty())
552return;
553if (is_style_windows(style)) {
554for (char &Ch : Path)
555if (is_separator(Ch, style))
556 Ch = preferred_separator(style);
557if (Path[0] =='~' && (Path.size() == 1 ||is_separator(Path[1], style))) {
558SmallString<128> PathHome;
559home_directory(PathHome);
560 PathHome.append(Path.begin() + 1, Path.end());
561 Path = PathHome;
562 }
563 }else {
564 std::replace(Path.begin(), Path.end(),'\\','/');
565 }
566}
567
568std::stringconvert_to_slash(StringRef path,Style style) {
569if (is_style_posix(style))
570return std::string(path);
571
572 std::string s = path.str();
573 std::replace(s.begin(), s.end(),'\\','/');
574return s;
575}
576
577StringReffilename(StringRef path,Style style) {return *rbegin(path, style); }
578
579StringRefstem(StringRef path,Style style) {
580StringRef fname =filename(path, style);
581size_t pos = fname.find_last_of('.');
582if (pos ==StringRef::npos)
583return fname;
584if ((fname.size() == 1 && fname ==".") ||
585 (fname.size() == 2 && fname ==".."))
586return fname;
587return fname.substr(0, pos);
588}
589
590StringRefextension(StringRef path,Style style) {
591StringRef fname =filename(path, style);
592size_t pos = fname.find_last_of('.');
593if (pos ==StringRef::npos)
594returnStringRef();
595if ((fname.size() == 1 && fname ==".") ||
596 (fname.size() == 2 && fname ==".."))
597returnStringRef();
598return fname.substr(pos);
599}
600
601boolis_separator(charvalue,Style style) {
602if (value =='/')
603returntrue;
604if (is_style_windows(style))
605returnvalue =='\\';
606returnfalse;
607}
608
609StringRefget_separator(Style style) {
610if (real_style(style) ==Style::windows)
611return"\\";
612return"/";
613}
614
615boolhas_root_name(constTwine &path,Style style) {
616SmallString<128> path_storage;
617StringRef p = path.toStringRef(path_storage);
618
619return !root_name(p, style).empty();
620}
621
622boolhas_root_directory(constTwine &path,Style style) {
623SmallString<128> path_storage;
624StringRef p = path.toStringRef(path_storage);
625
626return !root_directory(p, style).empty();
627}
628
629boolhas_root_path(constTwine &path,Style style) {
630SmallString<128> path_storage;
631StringRef p = path.toStringRef(path_storage);
632
633return !root_path(p, style).empty();
634}
635
636boolhas_relative_path(constTwine &path,Style style) {
637SmallString<128> path_storage;
638StringRef p = path.toStringRef(path_storage);
639
640return !relative_path(p, style).empty();
641}
642
643boolhas_filename(constTwine &path,Style style) {
644SmallString<128> path_storage;
645StringRef p = path.toStringRef(path_storage);
646
647return !filename(p, style).empty();
648}
649
650boolhas_parent_path(constTwine &path,Style style) {
651SmallString<128> path_storage;
652StringRef p = path.toStringRef(path_storage);
653
654return !parent_path(p, style).empty();
655}
656
657boolhas_stem(constTwine &path,Style style) {
658SmallString<128> path_storage;
659StringRef p = path.toStringRef(path_storage);
660
661return !stem(p, style).empty();
662}
663
664boolhas_extension(constTwine &path,Style style) {
665SmallString<128> path_storage;
666StringRef p = path.toStringRef(path_storage);
667
668return !extension(p, style).empty();
669}
670
671boolis_absolute(constTwine &path,Style style) {
672SmallString<128> path_storage;
673StringRef p = path.toStringRef(path_storage);
674
675bool rootDir =has_root_directory(p, style);
676bool rootName =is_style_posix(style) ||has_root_name(p, style);
677
678return rootDir && rootName;
679}
680
681boolis_absolute_gnu(constTwine &path,Style style) {
682SmallString<128> path_storage;
683StringRef p = path.toStringRef(path_storage);
684
685// Handle '/' which is absolute for both Windows and POSIX systems.
686// Handle '\\' on Windows.
687if (!p.empty() &&is_separator(p.front(), style))
688returntrue;
689
690if (is_style_windows(style)) {
691// Handle drive letter pattern (a character followed by ':') on Windows.
692if (p.size() >= 2 && (p[0] && p[1] ==':'))
693returntrue;
694 }
695
696returnfalse;
697}
698
699boolis_relative(constTwine &path,Style style) {
700return !is_absolute(path, style);
701}
702
703StringRefremove_leading_dotslash(StringRef Path,Style style) {
704// Remove leading "./" (or ".//" or "././" etc.)
705while (Path.size() > 2 && Path[0] =='.' &&is_separator(Path[1], style)) {
706 Path = Path.substr(2);
707while (Path.size() > 0 &&is_separator(Path[0], style))
708 Path = Path.substr(1);
709 }
710return Path;
711}
712
713// Remove path traversal components ("." and "..") when possible, and
714// canonicalize slashes.
715boolremove_dots(SmallVectorImpl<char> &the_path,bool remove_dot_dot,
716Style style) {
717 style = real_style(style);
718StringRef remaining(the_path.data(), the_path.size());
719bool needs_change =false;
720SmallVector<StringRef, 16> components;
721
722// Consume the root path, if present.
723StringRef root =path::root_path(remaining, style);
724bool absolute = !root.empty();
725if (absolute)
726 remaining = remaining.drop_front(root.size());
727
728// Loop over path components manually. This makes it easier to detect
729// non-preferred slashes and double separators that must be canonicalized.
730while (!remaining.empty()) {
731size_t next_slash = remaining.find_first_of(separators(style));
732if (next_slash ==StringRef::npos)
733 next_slash = remaining.size();
734StringRef component = remaining.take_front(next_slash);
735 remaining = remaining.drop_front(next_slash);
736
737// Eat the slash, and check if it is the preferred separator.
738if (!remaining.empty()) {
739 needs_change |= remaining.front() != preferred_separator(style);
740 remaining = remaining.drop_front();
741// The path needs to be rewritten if it has a trailing slash.
742// FIXME: This is emergent behavior that could be removed.
743 needs_change |= remaining.empty();
744 }
745
746// Check for path traversal components or double separators.
747if (component.empty() || component ==".") {
748 needs_change =true;
749 }elseif (remove_dot_dot && component =="..") {
750 needs_change =true;
751// Do not allow ".." to remove the root component. If this is the
752// beginning of a relative path, keep the ".." component.
753if (!components.empty() && components.back() !="..") {
754 components.pop_back();
755 }elseif (!absolute) {
756 components.push_back(component);
757 }
758 }else {
759 components.push_back(component);
760 }
761 }
762
763SmallString<256> buffer = root;
764// "root" could be "/", which may need to be translated into "\".
765make_preferred(buffer, style);
766 needs_change |= root != buffer;
767
768// Avoid rewriting the path unless we have to.
769if (!needs_change)
770returnfalse;
771
772if (!components.empty()) {
773 buffer += components[0];
774for (StringRefC :ArrayRef(components).drop_front()) {
775 buffer += preferred_separator(style);
776 buffer +=C;
777 }
778 }
779 the_path.swap(buffer);
780returntrue;
781}
782
783}// end namespace path
784
785namespacefs {
786
787std::error_codegetUniqueID(constTwine Path,UniqueID &Result) {
788file_statusStatus;
789 std::error_code EC =status(Path,Status);
790if (EC)
791return EC;
792 Result =Status.getUniqueID();
793return std::error_code();
794}
795
796voidcreateUniquePath(constTwine &Model,SmallVectorImpl<char> &ResultPath,
797bool MakeAbsolute) {
798SmallString<128> ModelStorage;
799 Model.toVector(ModelStorage);
800
801if (MakeAbsolute) {
802// Make model absolute by prepending a temp directory if it's not already.
803if (!sys::path::is_absolute(Twine(ModelStorage))) {
804SmallString<128> TDir;
805sys::path::system_temp_directory(true, TDir);
806sys::path::append(TDir,Twine(ModelStorage));
807 ModelStorage.swap(TDir);
808 }
809 }
810
811 ResultPath = ModelStorage;
812 ResultPath.push_back(0);
813 ResultPath.pop_back();
814
815// Replace '%' with random chars.
816for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
817if (ModelStorage[i] =='%')
818 ResultPath[i] ="0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
819 }
820}
821
822std::error_codecreateUniqueFile(constTwine &Model,int &ResultFd,
823SmallVectorImpl<char> &ResultPath,
824OpenFlags Flags,unsigned Mode) {
825returncreateUniqueEntity(Model, ResultFd, ResultPath,false,FS_File, Flags,
826 Mode);
827}
828
829std::error_codecreateUniqueFile(constTwine &Model,
830SmallVectorImpl<char> &ResultPath,
831unsigned Mode) {
832int FD;
833auto EC =createUniqueFile(Model, FD, ResultPath,OF_None, Mode);
834if (EC)
835return EC;
836// FD is only needed to avoid race conditions. Close it right away.
837 close(FD);
838return EC;
839}
840
841static std::error_code
842createTemporaryFile(constTwine &Model,int &ResultFD,
843llvm::SmallVectorImpl<char> &ResultPath,FSEntityType,
844sys::fs::OpenFlags Flags =sys::fs::OF_None) {
845SmallString<128> Storage;
846StringRefP = Model.toNullTerminatedStringRef(Storage);
847assert(P.find_first_of(separators(Style::native)) ==StringRef::npos &&
848"Model must be a simple filename.");
849// Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
850returncreateUniqueEntity(P.begin(), ResultFD, ResultPath,true,Type, Flags,
851all_read |all_write);
852}
853
854static std::error_code
855createTemporaryFile(constTwine &Prefix,StringRef Suffix,int &ResultFD,
856llvm::SmallVectorImpl<char> &ResultPath,FSEntityType,
857sys::fs::OpenFlags Flags =sys::fs::OF_None) {
858constchar *Middle = Suffix.empty() ?"-%%%%%%" :"-%%%%%%.";
859returncreateTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
860Type, Flags);
861}
862
863std::error_codecreateTemporaryFile(constTwine &Prefix,StringRef Suffix,
864int &ResultFD,
865SmallVectorImpl<char> &ResultPath,
866sys::fs::OpenFlags Flags) {
867returncreateTemporaryFile(Prefix, Suffix, ResultFD, ResultPath,FS_File,
868 Flags);
869}
870
871std::error_codecreateTemporaryFile(constTwine &Prefix,StringRef Suffix,
872SmallVectorImpl<char> &ResultPath,
873sys::fs::OpenFlags Flags) {
874int FD;
875auto EC =createTemporaryFile(Prefix, Suffix, FD, ResultPath, Flags);
876if (EC)
877return EC;
878// FD is only needed to avoid race conditions. Close it right away.
879 close(FD);
880return EC;
881}
882
883// This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
884// for consistency. We should try using mkdtemp.
885std::error_codecreateUniqueDirectory(constTwine &Prefix,
886SmallVectorImpl<char> &ResultPath) {
887int Dummy;
888returncreateUniqueEntity(Prefix +"-%%%%%%", Dummy, ResultPath,true,
889FS_Dir);
890}
891
892std::error_code
893getPotentiallyUniqueFileName(constTwine &Model,
894SmallVectorImpl<char> &ResultPath) {
895int Dummy;
896returncreateUniqueEntity(Model, Dummy, ResultPath,false,FS_Name);
897}
898
899std::error_code
900getPotentiallyUniqueTempFileName(constTwine &Prefix,StringRef Suffix,
901SmallVectorImpl<char> &ResultPath) {
902int Dummy;
903returncreateTemporaryFile(Prefix, Suffix, Dummy, ResultPath,FS_Name);
904}
905
906voidmake_absolute(constTwine &current_directory,
907SmallVectorImpl<char> &path) {
908StringRef p(path.data(), path.size());
909
910bool rootDirectory =path::has_root_directory(p);
911bool rootName =path::has_root_name(p);
912
913// Already absolute.
914if ((rootName || is_style_posix(Style::native)) && rootDirectory)
915return;
916
917// All of the following conditions will need the current directory.
918SmallString<128> current_dir;
919 current_directory.toVector(current_dir);
920
921// Relative path. Prepend the current directory.
922if (!rootName && !rootDirectory) {
923// Append path to the current directory.
924path::append(current_dir, p);
925// Set path to the result.
926 path.swap(current_dir);
927return;
928 }
929
930if (!rootName && rootDirectory) {
931StringRef cdrn =path::root_name(current_dir);
932SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
933path::append(curDirRootName, p);
934// Set path to the result.
935 path.swap(curDirRootName);
936return;
937 }
938
939if (rootName && !rootDirectory) {
940StringRef pRootName =path::root_name(p);
941StringRef bRootDirectory =path::root_directory(current_dir);
942StringRef bRelativePath =path::relative_path(current_dir);
943StringRef pRelativePath =path::relative_path(p);
944
945SmallString<128> res;
946path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
947 path.swap(res);
948return;
949 }
950
951llvm_unreachable("All rootName and rootDirectory combinations should have "
952"occurred above!");
953}
954
955std::error_codemake_absolute(SmallVectorImpl<char> &path) {
956if (path::is_absolute(path))
957return {};
958
959SmallString<128> current_dir;
960if (std::error_code ec =current_path(current_dir))
961return ec;
962
963make_absolute(current_dir, path);
964return {};
965}
966
967std::error_codecreate_directories(constTwine &Path,bool IgnoreExisting,
968perms Perms) {
969SmallString<128> PathStorage;
970StringRefP = Path.toStringRef(PathStorage);
971
972// Be optimistic and try to create the directory
973 std::error_code EC =create_directory(P, IgnoreExisting, Perms);
974// If we succeeded, or had any error other than the parent not existing, just
975// return it.
976if (EC !=errc::no_such_file_or_directory)
977return EC;
978
979// We failed because of a no_such_file_or_directory, try to create the
980// parent.
981StringRef Parent =path::parent_path(P);
982if (Parent.empty())
983return EC;
984
985if ((EC =create_directories(Parent, IgnoreExisting, Perms)))
986return EC;
987
988returncreate_directory(P, IgnoreExisting, Perms);
989}
990
991static std::error_codecopy_file_internal(int ReadFD,int WriteFD) {
992constsize_t BufSize = 4096;
993char *Buf =newchar[BufSize];
994int BytesRead = 0, BytesWritten = 0;
995for (;;) {
996 BytesRead =read(ReadFD, Buf, BufSize);
997if (BytesRead <= 0)
998break;
999while (BytesRead) {
1000 BytesWritten =write(WriteFD, Buf, BytesRead);
1001if (BytesWritten < 0)
1002break;
1003 BytesRead -= BytesWritten;
1004 }
1005if (BytesWritten < 0)
1006break;
1007 }
1008delete[] Buf;
1009
1010if (BytesRead < 0 || BytesWritten < 0)
1011returnerrnoAsErrorCode();
1012return std::error_code();
1013}
1014
1015#ifndef __APPLE__
1016std::error_codecopy_file(constTwine &From,constTwine &To) {
1017int ReadFD, WriteFD;
1018if (std::error_code EC =openFileForRead(From, ReadFD,OF_None))
1019return EC;
1020if (std::error_code EC =
1021openFileForWrite(To, WriteFD,CD_CreateAlways,OF_None)) {
1022 close(ReadFD);
1023return EC;
1024 }
1025
1026 std::error_code EC =copy_file_internal(ReadFD, WriteFD);
1027
1028 close(ReadFD);
1029 close(WriteFD);
1030
1031return EC;
1032}
1033#endif
1034
1035std::error_codecopy_file(constTwine &From,int ToFD) {
1036int ReadFD;
1037if (std::error_code EC =openFileForRead(From, ReadFD,OF_None))
1038return EC;
1039
1040 std::error_code EC =copy_file_internal(ReadFD, ToFD);
1041
1042 close(ReadFD);
1043
1044return EC;
1045}
1046
1047ErrorOr<MD5::MD5Result>md5_contents(int FD) {
1048MD5 Hash;
1049
1050constexprsize_t BufSize = 4096;
1051 std::vector<uint8_t> Buf(BufSize);
1052int BytesRead = 0;
1053for (;;) {
1054 BytesRead =read(FD, Buf.data(), BufSize);
1055if (BytesRead <= 0)
1056break;
1057 Hash.update(ArrayRef(Buf.data(), BytesRead));
1058 }
1059
1060if (BytesRead < 0)
1061returnerrnoAsErrorCode();
1062MD5::MD5Result Result;
1063 Hash.final(Result);
1064return Result;
1065}
1066
1067ErrorOr<MD5::MD5Result>md5_contents(constTwine &Path) {
1068int FD;
1069if (auto EC =openFileForRead(Path, FD,OF_None))
1070return EC;
1071
1072auto Result =md5_contents(FD);
1073 close(FD);
1074return Result;
1075}
1076
1077boolexists(constbasic_file_status &status) {
1078returnstatus_known(status) &&status.type() !=file_type::file_not_found;
1079}
1080
1081boolstatus_known(constbasic_file_status &s) {
1082return s.type() !=file_type::status_error;
1083}
1084
1085file_typeget_file_type(constTwine &Path,bool Follow) {
1086file_status st;
1087if (status(Path, st, Follow))
1088returnfile_type::status_error;
1089return st.type();
1090}
1091
1092boolis_directory(constbasic_file_status &status) {
1093returnstatus.type() ==file_type::directory_file;
1094}
1095
1096std::error_codeis_directory(constTwine &path,bool &result) {
1097file_status st;
1098if (std::error_code ec =status(path, st))
1099return ec;
1100 result =is_directory(st);
1101return std::error_code();
1102}
1103
1104boolis_regular_file(constbasic_file_status &status) {
1105returnstatus.type() ==file_type::regular_file;
1106}
1107
1108std::error_codeis_regular_file(constTwine &path,bool &result) {
1109file_status st;
1110if (std::error_code ec =status(path, st))
1111return ec;
1112 result =is_regular_file(st);
1113return std::error_code();
1114}
1115
1116boolis_symlink_file(constbasic_file_status &status) {
1117returnstatus.type() ==file_type::symlink_file;
1118}
1119
1120std::error_codeis_symlink_file(constTwine &path,bool &result) {
1121file_status st;
1122if (std::error_code ec =status(path, st,false))
1123return ec;
1124 result =is_symlink_file(st);
1125return std::error_code();
1126}
1127
1128boolis_other(constbasic_file_status &status) {
1129returnexists(status) &&
1130 !is_regular_file(status) &&
1131 !is_directory(status);
1132}
1133
1134std::error_codeis_other(constTwine &Path,bool &Result) {
1135file_status FileStatus;
1136if (std::error_code EC =status(Path, FileStatus))
1137return EC;
1138 Result =is_other(FileStatus);
1139return std::error_code();
1140}
1141
1142voiddirectory_entry::replace_filename(constTwine &Filename,file_typeType,
1143basic_file_statusStatus) {
1144SmallString<128> PathStr =path::parent_path(Path);
1145path::append(PathStr, Filename);
1146 this->Path = std::string(PathStr);
1147 this->Type =Type;
1148 this->Status =Status;
1149}
1150
1151ErrorOr<perms>getPermissions(constTwine &Path) {
1152file_statusStatus;
1153if (std::error_code EC =status(Path,Status))
1154return EC;
1155
1156returnStatus.permissions();
1157}
1158
1159size_tmapped_file_region::size() const{
1160assert(Mapping &&"Mapping failed but used anyway!");
1161return Size;
1162}
1163
1164char *mapped_file_region::data() const{
1165assert(Mapping &&"Mapping failed but used anyway!");
1166returnreinterpret_cast<char *>(Mapping);
1167}
1168
1169constchar *mapped_file_region::const_data() const{
1170assert(Mapping &&"Mapping failed but used anyway!");
1171returnreinterpret_cast<constchar *>(Mapping);
1172}
1173
1174ErrorreadNativeFileToEOF(file_t FileHandle,SmallVectorImpl<char> &Buffer,
1175 ssize_t ChunkSize) {
1176// Install a handler to truncate the buffer to the correct size on exit.
1177size_tSize = Buffer.size();
1178auto TruncateOnExit =make_scope_exit([&]() { Buffer.truncate(Size); });
1179
1180// Read into Buffer until we hit EOF.
1181for (;;) {
1182 Buffer.resize_for_overwrite(Size + ChunkSize);
1183Expected<size_t> ReadBytes =readNativeFile(
1184 FileHandle,MutableArrayRef(Buffer.begin() +Size, ChunkSize));
1185if (!ReadBytes)
1186return ReadBytes.takeError();
1187if (*ReadBytes == 0)
1188returnError::success();
1189Size += *ReadBytes;
1190 }
1191}
1192
1193}// end namespace fs
1194}// end namespace sys
1195}// end namespace llvm
1196
1197// Include the truly platform-specific parts.
1198#if defined(LLVM_ON_UNIX)
1199#include "Unix/Path.inc"
1200#endif
1201#if defined(_WIN32)
1202#include "Windows/Path.inc"
1203#endif
1204
1205namespacellvm {
1206namespacesys {
1207namespacefs {
1208
1209TempFile::TempFile(StringRefName,int FD)
1210 : TmpName(std::string(Name)), FD(FD) {}
1211TempFile::TempFile(TempFile &&Other) { *this = std::move(Other); }
1212TempFile &TempFile::operator=(TempFile &&Other) {
1213 TmpName = std::move(Other.TmpName);
1214 FD =Other.FD;
1215Other.Done =true;
1216Other.FD = -1;
1217#ifdef _WIN32
1218 RemoveOnClose =Other.RemoveOnClose;
1219Other.RemoveOnClose =false;
1220#endif
1221return *this;
1222}
1223
1224TempFile::~TempFile() {assert(Done); }
1225
1226Error TempFile::discard() {
1227Done =true;
1228if (FD != -1 && close(FD) == -1) {
1229 std::error_code EC =errnoAsErrorCode();
1230returnerrorCodeToError(EC);
1231 }
1232 FD = -1;
1233
1234#ifdef _WIN32
1235// On Windows, closing will remove the file, if we set the delete
1236// disposition. If not, remove it manually.
1237bool Remove = RemoveOnClose;
1238#else
1239// Always try to remove the file.
1240bool Remove =true;
1241#endif
1242 std::error_code RemoveEC;
1243if (Remove && !TmpName.empty()) {
1244 RemoveEC =fs::remove(TmpName);
1245sys::DontRemoveFileOnSignal(TmpName);
1246if (!RemoveEC)
1247 TmpName ="";
1248 }else {
1249 TmpName ="";
1250 }
1251returnerrorCodeToError(RemoveEC);
1252}
1253
1254Error TempFile::keep(constTwine &Name) {
1255assert(!Done);
1256Done =true;
1257// Always try to close and rename.
1258#ifdef _WIN32
1259// If we can't cancel the delete don't rename.
1260autoH =reinterpret_cast<HANDLE>(_get_osfhandle(FD));
1261 std::error_code RenameEC =
1262 RemoveOnClose ? std::error_code() : setDeleteDisposition(H,false);
1263bool ShouldDelete =false;
1264if (!RenameEC) {
1265 RenameEC = rename_handle(H,Name);
1266// If rename failed because it's cross-device, copy instead
1267if (RenameEC ==
1268 std::error_code(ERROR_NOT_SAME_DEVICE, std::system_category())) {
1269 RenameEC =copy_file(TmpName,Name);
1270 ShouldDelete =true;
1271 }
1272 }
1273
1274// If we can't rename or copy, discard the temporary file.
1275if (RenameEC)
1276 ShouldDelete =true;
1277if (ShouldDelete) {
1278if (!RemoveOnClose)
1279 setDeleteDisposition(H,true);
1280else
1281remove(TmpName);
1282 }
1283#else
1284 std::error_code RenameEC =fs::rename(TmpName,Name);
1285if (RenameEC) {
1286// If we can't rename, try to copy to work around cross-device link issues.
1287 RenameEC =sys::fs::copy_file(TmpName,Name);
1288// If we can't rename or copy, discard the temporary file.
1289if (RenameEC)
1290remove(TmpName);
1291 }
1292#endif
1293sys::DontRemoveFileOnSignal(TmpName);
1294
1295if (!RenameEC)
1296 TmpName ="";
1297
1298if (close(FD) == -1)
1299returnerrorCodeToError(errnoAsErrorCode());
1300 FD = -1;
1301
1302returnerrorCodeToError(RenameEC);
1303}
1304
1305Error TempFile::keep() {
1306assert(!Done);
1307Done =true;
1308
1309#ifdef _WIN32
1310autoH =reinterpret_cast<HANDLE>(_get_osfhandle(FD));
1311if (std::error_code EC = setDeleteDisposition(H,false))
1312returnerrorCodeToError(EC);
1313#endif
1314sys::DontRemoveFileOnSignal(TmpName);
1315
1316 TmpName ="";
1317
1318if (close(FD) == -1)
1319returnerrorCodeToError(errnoAsErrorCode());
1320 FD = -1;
1321
1322returnError::success();
1323}
1324
1325Expected<TempFile> TempFile::create(constTwine &Model,unsigned Mode,
1326OpenFlags ExtraFlags) {
1327int FD;
1328SmallString<128> ResultPath;
1329if (std::error_code EC =
1330createUniqueFile(Model, FD, ResultPath,OF_Delete | ExtraFlags, Mode))
1331returnerrorCodeToError(EC);
1332
1333TempFile Ret(ResultPath, FD);
1334#ifdef _WIN32
1335autoH =reinterpret_cast<HANDLE>(_get_osfhandle(FD));
1336bool SetSignalHandler =false;
1337if (std::error_code EC = setDeleteDisposition(H,true)) {
1338 Ret.RemoveOnClose =true;
1339 SetSignalHandler =true;
1340 }
1341#else
1342bool SetSignalHandler =true;
1343#endif
1344if (SetSignalHandler &&sys::RemoveFileOnSignal(ResultPath)) {
1345// Make sure we delete the file when RemoveFileOnSignal fails.
1346consumeError(Ret.discard());
1347 std::error_code EC(errc::operation_not_permitted);
1348returnerrorCodeToError(EC);
1349 }
1350return std::move(Ret);
1351}
1352}// namespace fs
1353
1354}// namespace sys
1355}// namespace llvm
ArrayRef.h
From
BlockVerifier::State From
Definition:BlockVerifier.cpp:57
value
Given that RA is a live value
Definition:DeadArgumentElimination.cpp:716
Name
std::string Name
Definition:ELFObjHandler.cpp:77
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
Errc.h
FileSystem.h
SpecialSubKind::string
@ string
I
#define I(x, y, z)
Definition:MD5.cpp:58
H
#define H(x, y, z)
Definition:MD5.cpp:57
P
#define P(N)
createUniqueEntity
static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute, FSEntity Type, sys::fs::OpenFlags Flags=sys::fs::OF_None, unsigned Mode=0)
Definition:Path.cpp:170
FSEntity
FSEntity
Definition:Path.cpp:163
FS_Dir
@ FS_Dir
Definition:Path.cpp:164
FS_File
@ FS_File
Definition:Path.cpp:165
FS_Name
@ FS_Name
Definition:Path.cpp:166
Path.h
Process.h
Provides a library for accessing information about this process and other processes on the operating ...
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ScopeExit.h
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
Signals.h
StringExtras.h
This file contains some functions that are useful when dealing with strings.
starts_with
DEMANGLE_NAMESPACE_BEGIN bool starts_with(std::string_view self, char C) noexcept
Definition:StringViewExtras.h:24
Path.inc
Path.inc
RHS
Value * RHS
Definition:X86PartialReduction.cpp:74
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition:ArrayRef.h:41
llvm::ErrorOr
Represents either an error or a value T.
Definition:ErrorOr.h:56
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition:Error.h:160
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition:Error.h:337
llvm::Expected
Tagged union holding either a T or a Error.
Definition:Error.h:481
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition:Error.h:608
llvm::MD5
Definition:MD5.h:41
llvm::MD5::update
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition:MD5.cpp:189
llvm::MD5::final
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition:MD5.cpp:234
llvm::MutableArrayRef
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition:ArrayRef.h:310
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::SmallString::append
void append(StringRef RHS)
Append from a StringRef.
Definition:SmallString.h:68
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorImpl::resize_for_overwrite
void resize_for_overwrite(size_type N)
Like resize, but T is POD, the new values won't be initialized.
Definition:SmallVector.h:641
llvm::SmallVectorImpl::append
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition:SmallVector.h:683
llvm::SmallVectorImpl::clear
void clear()
Definition:SmallVector.h:610
llvm::SmallVectorImpl::truncate
void truncate(size_type N)
Like resize, but requires that N is less than size().
Definition:SmallVector.h:644
llvm::SmallVectorImpl::swap
void swap(SmallVectorImpl &RHS)
Definition:SmallVector.h:968
llvm::SmallVectorTemplateBase::pop_back
void pop_back()
Definition:SmallVector.h:425
llvm::SmallVectorTemplateBase::push_back
void push_back(const T &Elt)
Definition:SmallVector.h:413
llvm::SmallVectorTemplateCommon::data
pointer data()
Return a pointer to the vector's buffer, even if empty().
Definition:SmallVector.h:286
llvm::SmallVectorTemplateCommon::begin
iterator begin()
Definition:SmallVector.h:267
llvm::SmallVectorTemplateCommon::back
reference back()
Definition:SmallVector.h:308
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::str
std::string str() const
str - Get the contents as an std::string.
Definition:StringRef.h:229
llvm::StringRef::substr
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition:StringRef.h:571
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::StringRef::drop_front
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition:StringRef.h:609
llvm::StringRef::begin
iterator begin() const
Definition:StringRef.h:116
llvm::StringRef::back
char back() const
back - Get the last character in the string.
Definition:StringRef.h:159
llvm::StringRef::slice
StringRef slice(size_t Start, size_t End) const
Return a reference to the substring from [Start, End).
Definition:StringRef.h:684
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition:StringRef.h:150
llvm::StringRef::front
char front() const
front - Get the first character in the string.
Definition:StringRef.h:153
llvm::StringRef::find_last_of
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:400
llvm::StringRef::data
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition:StringRef.h:144
llvm::StringRef::find_first_of
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:377
llvm::StringRef::end
iterator end() const
Definition:StringRef.h:118
llvm::StringRef::take_front
StringRef take_front(size_t N=1) const
Return a StringRef equal to 'this' but with only the first N elements remaining.
Definition:StringRef.h:580
llvm::StringRef::ends_with
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition:StringRef.h:277
llvm::StringRef::npos
static constexpr size_t npos
Definition:StringRef.h:53
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition:Twine.h:81
llvm::Twine::isSingleStringRef
bool isSingleStringRef() const
Return true if this twine can be dynamically accessed as a single StringRef value with getSingleStrin...
Definition:Twine.h:440
llvm::Twine::isTriviallyEmpty
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:429
llvm::Twine::toStringRef
StringRef toStringRef(SmallVectorImpl< char > &Out) const
This returns the twine as a single StringRef if it can be represented as such.
Definition:Twine.h:492
llvm::Twine::getSingleStringRef
StringRef getSingleStringRef() const
This returns the twine as a single StringRef.
Definition:Twine.h:473
llvm::Twine::toVector
void toVector(SmallVectorImpl< char > &Out) const
Append the concatenated string into the given SmallString or SmallVector.
Definition:Twine.cpp:32
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::sys::Process::GetRandomNumber
static unsigned GetRandomNumber()
Get the result of a process wide random number generator.
llvm::sys::fs::TempFile
Represents a temporary file.
Definition:FileSystem.h:843
llvm::sys::fs::UniqueID
Definition:UniqueID.h:26
llvm::sys::fs::basic_file_status
Represents the result of a call to directory_iterator::status().
Definition:FileSystem.h:132
llvm::sys::fs::basic_file_status::type
file_type type() const
Definition:FileSystem.h:179
llvm::sys::fs::directory_entry::replace_filename
void replace_filename(const Twine &Filename, file_type Type, basic_file_status Status=basic_file_status())
Definition:Path.cpp:1142
llvm::sys::fs::file_status
Represents the result of a call to sys::fs::status().
Definition:FileSystem.h:221
llvm::sys::fs::mapped_file_region::size
size_t size() const
Definition:Path.cpp:1159
llvm::sys::fs::mapped_file_region::const_data
const char * const_data() const
Get a const view of the data.
Definition:Path.cpp:1169
llvm::sys::fs::mapped_file_region::data
char * data() const
Definition:Path.cpp:1164
llvm::sys::path::const_iterator
Path iterator.
Definition:Path.h:75
llvm::sys::path::const_iterator::operator++
const_iterator & operator++()
Definition:Path.cpp:242
llvm::sys::path::const_iterator::operator==
bool operator==(const const_iterator &RHS) const
Definition:Path.cpp:289
llvm::sys::path::const_iterator::operator-
ptrdiff_t operator-(const const_iterator &RHS) const
Difference in bytes between this and RHS.
Definition:Path.cpp:293
llvm::sys::path::reverse_iterator
Reverse path iterator.
Definition:Path.h:101
llvm::sys::path::reverse_iterator::operator==
bool operator==(const reverse_iterator &RHS) const
Definition:Path.cpp:339
llvm::sys::path::reverse_iterator::operator-
ptrdiff_t operator-(const reverse_iterator &RHS) const
Difference in bytes between this and RHS.
Definition:Path.cpp:344
llvm::sys::path::reverse_iterator::operator++
reverse_iterator & operator++()
Definition:Path.cpp:314
ptrdiff_t
ErrorHandling.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::HexStyle::Style
Style
Definition:MCInstPrinter.h:35
llvm::support::endian
Definition:Endian.h:41
llvm::support::endian::read
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
Definition:Endian.h:58
llvm::sys::fs::is_regular_file
bool is_regular_file(const basic_file_status &status)
Does status represent a regular file?
Definition:Path.cpp:1104
llvm::sys::fs::is_symlink_file
bool is_symlink_file(const basic_file_status &status)
Does status represent a symlink file?
Definition:Path.cpp:1116
llvm::sys::fs::make_absolute
void make_absolute(const Twine &current_directory, SmallVectorImpl< char > &path)
Make path an absolute path.
Definition:Path.cpp:906
llvm::sys::fs::openFileForReadWrite
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:1099
llvm::sys::fs::readNativeFileToEOF
Error readNativeFileToEOF(file_t FileHandle, SmallVectorImpl< char > &Buffer, ssize_t ChunkSize=DefaultReadChunkSize)
Reads from FileHandle until EOF, appending to Buffer in chunks of size ChunkSize.
Definition:Path.cpp:1174
llvm::sys::fs::readNativeFile
Expected< size_t > readNativeFile(file_t FileHandle, MutableArrayRef< char > Buf)
Reads Buf.size() bytes from FileHandle into Buf.
llvm::sys::fs::file_t
int file_t
Definition:FileSystem.h:55
llvm::sys::fs::getPermissions
ErrorOr< perms > getPermissions(const Twine &Path)
Get file permissions.
Definition:Path.cpp:1151
llvm::sys::fs::getPotentiallyUniqueFileName
std::error_code getPotentiallyUniqueFileName(const Twine &Model, SmallVectorImpl< char > &ResultPath)
Get a unique name, not currently exisiting in the filesystem.
Definition:Path.cpp:893
llvm::sys::fs::rename
std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
llvm::sys::fs::openFileForRead
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.
llvm::sys::fs::is_other
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:1128
llvm::sys::fs::access
std::error_code access(const Twine &Path, AccessMode Mode)
Can the file be accessed?
llvm::sys::fs::getPotentiallyUniqueTempFileName
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:900
llvm::sys::fs::status
std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
llvm::sys::fs::exists
bool exists(const basic_file_status &status)
Does file exist?
Definition:Path.cpp:1077
llvm::sys::fs::OpenFlags
OpenFlags
Definition:FileSystem.h:749
llvm::sys::fs::OF_Delete
@ OF_Delete
The returned handle can be used for deleting the file.
Definition:FileSystem.h:770
llvm::sys::fs::OF_None
@ OF_None
Definition:FileSystem.h:750
llvm::sys::fs::file_type
file_type
An enumeration for the file system's view of the type.
Definition:FileSystem.h:61
llvm::sys::fs::file_type::directory_file
@ directory_file
llvm::sys::fs::file_type::status_error
@ status_error
llvm::sys::fs::file_type::regular_file
@ regular_file
llvm::sys::fs::file_type::file_not_found
@ file_not_found
llvm::sys::fs::file_type::symlink_file
@ symlink_file
llvm::sys::fs::getUniqueID
std::error_code getUniqueID(const Twine Path, UniqueID &Result)
Definition:Path.cpp:787
llvm::sys::fs::createUniqueFile
std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None, unsigned Mode=all_read|all_write)
Create a uniquely named file.
Definition:Path.cpp:822
llvm::sys::fs::create_directory
std::error_code create_directory(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create the directory in path.
llvm::sys::fs::remove
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
llvm::sys::fs::CD_CreateAlways
@ CD_CreateAlways
CD_CreateAlways - When opening a file:
Definition:FileSystem.h:726
llvm::sys::fs::CD_CreateNew
@ CD_CreateNew
CD_CreateNew - When opening a file:
Definition:FileSystem.h:731
llvm::sys::fs::createUniquePath
void createUniquePath(const Twine &Model, SmallVectorImpl< char > &ResultPath, bool MakeAbsolute)
Create a potentially unique file name but does not create it.
Definition:Path.cpp:796
llvm::sys::fs::openFileForWrite
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:1058
llvm::sys::fs::create_directories
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:967
llvm::sys::fs::status_known
bool status_known(const basic_file_status &s)
Is status available?
Definition:Path.cpp:1081
llvm::sys::fs::createTemporaryFile
std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None)
Create a file in the system temporary directory.
Definition:Path.cpp:863
llvm::sys::fs::get_file_type
file_type get_file_type(const Twine &Path, bool Follow=true)
Does status represent a directory?
Definition:Path.cpp:1085
llvm::sys::fs::copy_file
std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
Definition:Path.cpp:1016
llvm::sys::fs::createUniqueDirectory
std::error_code createUniqueDirectory(const Twine &Prefix, SmallVectorImpl< char > &ResultPath)
Definition:Path.cpp:885
llvm::sys::fs::perms
perms
Definition:FileSystem.h:81
llvm::sys::fs::all_write
@ all_write
Definition:FileSystem.h:96
llvm::sys::fs::all_read
@ all_read
Definition:FileSystem.h:95
llvm::sys::fs::md5_contents
ErrorOr< MD5::MD5Result > md5_contents(int FD)
Compute an MD5 hash of a file's contents.
Definition:Path.cpp:1047
llvm::sys::fs::current_path
std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
llvm::sys::fs::copy_file_internal
static std::error_code copy_file_internal(int ReadFD, int WriteFD)
Definition:Path.cpp:991
llvm::sys::fs::is_directory
bool is_directory(const basic_file_status &status)
Does status represent a directory?
Definition:Path.cpp:1092
llvm::sys::path::get_separator
StringRef get_separator(Style style=Style::native)
Return the preferred separator for this platform.
Definition:Path.cpp:609
llvm::sys::path::root_path
StringRef root_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get root path.
Definition:Path.cpp:348
llvm::sys::path::remove_filename
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::sys::path::has_relative_path
bool has_relative_path(const Twine &path, Style style=Style::native)
Has relative path?
Definition:Path.cpp:636
llvm::sys::path::home_directory
bool home_directory(SmallVectorImpl< char > &result)
Get the user's home directory.
llvm::sys::path::stem
StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get stem.
Definition:Path.cpp:579
llvm::sys::path::has_root_name
bool has_root_name(const Twine &path, Style style=Style::native)
Has root name?
Definition:Path.cpp:615
llvm::sys::path::replace_extension
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
llvm::sys::path::begin
const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get begin iterator over path.
Definition:Path.cpp:226
llvm::sys::path::rend
reverse_iterator rend(StringRef path LLVM_LIFETIME_BOUND)
Get reverse end iterator over path.
llvm::sys::path::remove_dots
bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
In-place remove any '.
Definition:Path.cpp:715
llvm::sys::path::has_root_path
bool has_root_path(const Twine &path, Style style=Style::native)
Has root path?
Definition:Path.cpp:629
llvm::sys::path::is_style_posix
constexpr bool is_style_posix(Style S)
Check if S uses POSIX path rules.
Definition:Path.h:36
llvm::sys::path::parent_path
StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
Definition:Path.cpp:467
llvm::sys::path::has_parent_path
bool has_parent_path(const Twine &path, Style style=Style::native)
Has parent path?
Definition:Path.cpp:650
llvm::sys::path::Style
Style
Definition:Path.h:27
llvm::sys::path::Style::windows
@ windows
llvm::sys::path::Style::native
@ native
llvm::sys::path::make_preferred
void make_preferred(SmallVectorImpl< char > &path, Style style=Style::native)
For Windows path styles, convert path to use the preferred path separators.
Definition:Path.h:272
llvm::sys::path::is_relative
bool is_relative(const Twine &path, Style style=Style::native)
Is path relative?
Definition:Path.cpp:699
llvm::sys::path::remove_leading_dotslash
StringRef remove_leading_dotslash(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Remove redundant leading "./" pieces and consecutive separators.
llvm::sys::path::has_extension
bool has_extension(const Twine &path, Style style=Style::native)
Has extension?
Definition:Path.cpp:664
llvm::sys::path::is_absolute_gnu
bool is_absolute_gnu(const Twine &path, Style style=Style::native)
Is path absolute using GNU rules?
Definition:Path.cpp:681
llvm::sys::path::filename
StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition:Path.cpp:577
llvm::sys::path::system_temp_directory
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::sys::path::convert_to_slash
std::string convert_to_slash(StringRef path, Style style=Style::native)
Replaces backslashes with slashes if Windows.
Definition:Path.cpp:568
llvm::sys::path::is_absolute
bool is_absolute(const Twine &path, Style style=Style::native)
Is path absolute?
Definition:Path.cpp:671
llvm::sys::path::has_stem
bool has_stem(const Twine &path, Style style=Style::native)
Has stem?
Definition:Path.cpp:657
llvm::sys::path::is_style_windows
constexpr bool is_style_windows(Style S)
Check if S uses Windows path rules.
Definition:Path.h:49
llvm::sys::path::root_name
StringRef root_name(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get root name.
Definition:Path.cpp:373
llvm::sys::path::root_directory
StringRef root_directory(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get root directory.
Definition:Path.cpp:390
llvm::sys::path::replace_path_prefix
bool replace_path_prefix(SmallVectorImpl< char > &Path, StringRef OldPrefix, StringRef NewPrefix, Style style=Style::native)
Replace matching path prefix with another path.
Definition:Path.cpp:518
llvm::sys::path::append
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition:Path.cpp:456
llvm::sys::path::extension
StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
Definition:Path.cpp:590
llvm::sys::path::has_filename
bool has_filename(const Twine &path, Style style=Style::native)
Has filename?
Definition:Path.cpp:643
llvm::sys::path::rbegin
reverse_iterator rbegin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get reverse begin iterator over path.
llvm::sys::path::end
const_iterator end(StringRef path LLVM_LIFETIME_BOUND)
Get end iterator over path.
Definition:Path.cpp:235
llvm::sys::path::is_separator
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:601
llvm::sys::path::relative_path
StringRef relative_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get relative path.
Definition:Path.cpp:413
llvm::sys::path::has_root_directory
bool has_root_directory(const Twine &path, Style style=Style::native)
Has root directory?
Definition:Path.cpp:622
llvm::sys::DontRemoveFileOnSignal
void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
llvm::sys::RemoveFileOnSignal
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...
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::make_scope_exit
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
Definition:ScopeExit.h:59
llvm::Done
@ Done
Definition:Threading.h:60
llvm::errc::no_such_file_or_directory
@ no_such_file_or_directory
llvm::errc::operation_not_permitted
@ operation_not_permitted
llvm::write
Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
Definition:DWP.cpp:625
llvm::IRMemLocation::Other
@ Other
Any other memory.
llvm::copy
OutputIt copy(R &&Range, OutputIt Out)
Definition:STLExtras.h:1841
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition:Error.cpp:111
llvm::errnoAsErrorCode
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
Definition:Error.h:1226
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition:Error.h:1069
std
Implement std::hash so that hash_code can be used in STL containers.
Definition:BitVector.h:858
Status
Definition:SIModeRegister.cpp:29
llvm::MD5::MD5Result
Definition:MD5.h:43

Generated on Thu Jul 17 2025 13:50:22 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp