xref: /aosp_15_r20/external/llvm/lib/Support/Path.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- Path.cpp - Implement OS Path Concept ------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker //  This file implements the operating system Path API.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/COFF.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MachO.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Endian.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Errc.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/FileSystem.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Path.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Process.h"
22*9880d681SAndroid Build Coastguard Worker #include <cctype>
23*9880d681SAndroid Build Coastguard Worker #include <cstring>
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker #if !defined(_MSC_VER) && !defined(__MINGW32__)
26*9880d681SAndroid Build Coastguard Worker #include <unistd.h>
27*9880d681SAndroid Build Coastguard Worker #else
28*9880d681SAndroid Build Coastguard Worker #include <io.h>
29*9880d681SAndroid Build Coastguard Worker #endif
30*9880d681SAndroid Build Coastguard Worker 
31*9880d681SAndroid Build Coastguard Worker using namespace llvm;
32*9880d681SAndroid Build Coastguard Worker using namespace llvm::support::endian;
33*9880d681SAndroid Build Coastguard Worker 
34*9880d681SAndroid Build Coastguard Worker namespace {
35*9880d681SAndroid Build Coastguard Worker   using llvm::StringRef;
36*9880d681SAndroid Build Coastguard Worker   using llvm::sys::path::is_separator;
37*9880d681SAndroid Build Coastguard Worker 
38*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
39*9880d681SAndroid Build Coastguard Worker   const char *separators = "\\/";
40*9880d681SAndroid Build Coastguard Worker   const char preferred_separator = '\\';
41*9880d681SAndroid Build Coastguard Worker #else
42*9880d681SAndroid Build Coastguard Worker   const char  separators = '/';
43*9880d681SAndroid Build Coastguard Worker   const char preferred_separator = '/';
44*9880d681SAndroid Build Coastguard Worker #endif
45*9880d681SAndroid Build Coastguard Worker 
find_first_component(StringRef path)46*9880d681SAndroid Build Coastguard Worker   StringRef find_first_component(StringRef path) {
47*9880d681SAndroid Build Coastguard Worker     // Look for this first component in the following order.
48*9880d681SAndroid Build Coastguard Worker     // * empty (in this case we return an empty string)
49*9880d681SAndroid Build Coastguard Worker     // * either C: or {//,\\}net.
50*9880d681SAndroid Build Coastguard Worker     // * {/,\}
51*9880d681SAndroid Build Coastguard Worker     // * {file,directory}name
52*9880d681SAndroid Build Coastguard Worker 
53*9880d681SAndroid Build Coastguard Worker     if (path.empty())
54*9880d681SAndroid Build Coastguard Worker       return path;
55*9880d681SAndroid Build Coastguard Worker 
56*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
57*9880d681SAndroid Build Coastguard Worker     // C:
58*9880d681SAndroid Build Coastguard Worker     if (path.size() >= 2 && std::isalpha(static_cast<unsigned char>(path[0])) &&
59*9880d681SAndroid Build Coastguard Worker         path[1] == ':')
60*9880d681SAndroid Build Coastguard Worker       return path.substr(0, 2);
61*9880d681SAndroid Build Coastguard Worker #endif
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker     // //net
64*9880d681SAndroid Build Coastguard Worker     if ((path.size() > 2) &&
65*9880d681SAndroid Build Coastguard Worker         is_separator(path[0]) &&
66*9880d681SAndroid Build Coastguard Worker         path[0] == path[1] &&
67*9880d681SAndroid Build Coastguard Worker         !is_separator(path[2])) {
68*9880d681SAndroid Build Coastguard Worker       // Find the next directory separator.
69*9880d681SAndroid Build Coastguard Worker       size_t end = path.find_first_of(separators, 2);
70*9880d681SAndroid Build Coastguard Worker       return path.substr(0, end);
71*9880d681SAndroid Build Coastguard Worker     }
72*9880d681SAndroid Build Coastguard Worker 
73*9880d681SAndroid Build Coastguard Worker     // {/,\}
74*9880d681SAndroid Build Coastguard Worker     if (is_separator(path[0]))
75*9880d681SAndroid Build Coastguard Worker       return path.substr(0, 1);
76*9880d681SAndroid Build Coastguard Worker 
77*9880d681SAndroid Build Coastguard Worker     // * {file,directory}name
78*9880d681SAndroid Build Coastguard Worker     size_t end = path.find_first_of(separators);
79*9880d681SAndroid Build Coastguard Worker     return path.substr(0, end);
80*9880d681SAndroid Build Coastguard Worker   }
81*9880d681SAndroid Build Coastguard Worker 
filename_pos(StringRef str)82*9880d681SAndroid Build Coastguard Worker   size_t filename_pos(StringRef str) {
83*9880d681SAndroid Build Coastguard Worker     if (str.size() == 2 &&
84*9880d681SAndroid Build Coastguard Worker         is_separator(str[0]) &&
85*9880d681SAndroid Build Coastguard Worker         str[0] == str[1])
86*9880d681SAndroid Build Coastguard Worker       return 0;
87*9880d681SAndroid Build Coastguard Worker 
88*9880d681SAndroid Build Coastguard Worker     if (str.size() > 0 && is_separator(str[str.size() - 1]))
89*9880d681SAndroid Build Coastguard Worker       return str.size() - 1;
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker     size_t pos = str.find_last_of(separators, str.size() - 1);
92*9880d681SAndroid Build Coastguard Worker 
93*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
94*9880d681SAndroid Build Coastguard Worker     if (pos == StringRef::npos)
95*9880d681SAndroid Build Coastguard Worker       pos = str.find_last_of(':', str.size() - 2);
96*9880d681SAndroid Build Coastguard Worker #endif
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker     if (pos == StringRef::npos ||
99*9880d681SAndroid Build Coastguard Worker         (pos == 1 && is_separator(str[0])))
100*9880d681SAndroid Build Coastguard Worker       return 0;
101*9880d681SAndroid Build Coastguard Worker 
102*9880d681SAndroid Build Coastguard Worker     return pos + 1;
103*9880d681SAndroid Build Coastguard Worker   }
104*9880d681SAndroid Build Coastguard Worker 
root_dir_start(StringRef str)105*9880d681SAndroid Build Coastguard Worker   size_t root_dir_start(StringRef str) {
106*9880d681SAndroid Build Coastguard Worker     // case "c:/"
107*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
108*9880d681SAndroid Build Coastguard Worker     if (str.size() > 2 &&
109*9880d681SAndroid Build Coastguard Worker         str[1] == ':' &&
110*9880d681SAndroid Build Coastguard Worker         is_separator(str[2]))
111*9880d681SAndroid Build Coastguard Worker       return 2;
112*9880d681SAndroid Build Coastguard Worker #endif
113*9880d681SAndroid Build Coastguard Worker 
114*9880d681SAndroid Build Coastguard Worker     // case "//"
115*9880d681SAndroid Build Coastguard Worker     if (str.size() == 2 &&
116*9880d681SAndroid Build Coastguard Worker         is_separator(str[0]) &&
117*9880d681SAndroid Build Coastguard Worker         str[0] == str[1])
118*9880d681SAndroid Build Coastguard Worker       return StringRef::npos;
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker     // case "//net"
121*9880d681SAndroid Build Coastguard Worker     if (str.size() > 3 &&
122*9880d681SAndroid Build Coastguard Worker         is_separator(str[0]) &&
123*9880d681SAndroid Build Coastguard Worker         str[0] == str[1] &&
124*9880d681SAndroid Build Coastguard Worker         !is_separator(str[2])) {
125*9880d681SAndroid Build Coastguard Worker       return str.find_first_of(separators, 2);
126*9880d681SAndroid Build Coastguard Worker     }
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker     // case "/"
129*9880d681SAndroid Build Coastguard Worker     if (str.size() > 0 && is_separator(str[0]))
130*9880d681SAndroid Build Coastguard Worker       return 0;
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker     return StringRef::npos;
133*9880d681SAndroid Build Coastguard Worker   }
134*9880d681SAndroid Build Coastguard Worker 
parent_path_end(StringRef path)135*9880d681SAndroid Build Coastguard Worker   size_t parent_path_end(StringRef path) {
136*9880d681SAndroid Build Coastguard Worker     size_t end_pos = filename_pos(path);
137*9880d681SAndroid Build Coastguard Worker 
138*9880d681SAndroid Build Coastguard Worker     bool filename_was_sep = path.size() > 0 && is_separator(path[end_pos]);
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker     // Skip separators except for root dir.
141*9880d681SAndroid Build Coastguard Worker     size_t root_dir_pos = root_dir_start(path.substr(0, end_pos));
142*9880d681SAndroid Build Coastguard Worker 
143*9880d681SAndroid Build Coastguard Worker     while(end_pos > 0 &&
144*9880d681SAndroid Build Coastguard Worker           (end_pos - 1) != root_dir_pos &&
145*9880d681SAndroid Build Coastguard Worker           is_separator(path[end_pos - 1]))
146*9880d681SAndroid Build Coastguard Worker       --end_pos;
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker     if (end_pos == 1 && root_dir_pos == 0 && filename_was_sep)
149*9880d681SAndroid Build Coastguard Worker       return StringRef::npos;
150*9880d681SAndroid Build Coastguard Worker 
151*9880d681SAndroid Build Coastguard Worker     return end_pos;
152*9880d681SAndroid Build Coastguard Worker   }
153*9880d681SAndroid Build Coastguard Worker } // end unnamed namespace
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker enum FSEntity {
156*9880d681SAndroid Build Coastguard Worker   FS_Dir,
157*9880d681SAndroid Build Coastguard Worker   FS_File,
158*9880d681SAndroid Build Coastguard Worker   FS_Name
159*9880d681SAndroid Build Coastguard Worker };
160*9880d681SAndroid Build Coastguard Worker 
createUniqueEntity(const Twine & Model,int & ResultFD,SmallVectorImpl<char> & ResultPath,bool MakeAbsolute,unsigned Mode,FSEntity Type)161*9880d681SAndroid Build Coastguard Worker static std::error_code createUniqueEntity(const Twine &Model, int &ResultFD,
162*9880d681SAndroid Build Coastguard Worker                                           SmallVectorImpl<char> &ResultPath,
163*9880d681SAndroid Build Coastguard Worker                                           bool MakeAbsolute, unsigned Mode,
164*9880d681SAndroid Build Coastguard Worker                                           FSEntity Type) {
165*9880d681SAndroid Build Coastguard Worker   SmallString<128> ModelStorage;
166*9880d681SAndroid Build Coastguard Worker   Model.toVector(ModelStorage);
167*9880d681SAndroid Build Coastguard Worker 
168*9880d681SAndroid Build Coastguard Worker   if (MakeAbsolute) {
169*9880d681SAndroid Build Coastguard Worker     // Make model absolute by prepending a temp directory if it's not already.
170*9880d681SAndroid Build Coastguard Worker     if (!sys::path::is_absolute(Twine(ModelStorage))) {
171*9880d681SAndroid Build Coastguard Worker       SmallString<128> TDir;
172*9880d681SAndroid Build Coastguard Worker       sys::path::system_temp_directory(true, TDir);
173*9880d681SAndroid Build Coastguard Worker       sys::path::append(TDir, Twine(ModelStorage));
174*9880d681SAndroid Build Coastguard Worker       ModelStorage.swap(TDir);
175*9880d681SAndroid Build Coastguard Worker     }
176*9880d681SAndroid Build Coastguard Worker   }
177*9880d681SAndroid Build Coastguard Worker 
178*9880d681SAndroid Build Coastguard Worker   // From here on, DO NOT modify model. It may be needed if the randomly chosen
179*9880d681SAndroid Build Coastguard Worker   // path already exists.
180*9880d681SAndroid Build Coastguard Worker   ResultPath = ModelStorage;
181*9880d681SAndroid Build Coastguard Worker   // Null terminate.
182*9880d681SAndroid Build Coastguard Worker   ResultPath.push_back(0);
183*9880d681SAndroid Build Coastguard Worker   ResultPath.pop_back();
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker retry_random_path:
186*9880d681SAndroid Build Coastguard Worker   // Replace '%' with random chars.
187*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = ModelStorage.size(); i != e; ++i) {
188*9880d681SAndroid Build Coastguard Worker     if (ModelStorage[i] == '%')
189*9880d681SAndroid Build Coastguard Worker       ResultPath[i] = "0123456789abcdef"[sys::Process::GetRandomNumber() & 15];
190*9880d681SAndroid Build Coastguard Worker   }
191*9880d681SAndroid Build Coastguard Worker 
192*9880d681SAndroid Build Coastguard Worker   // Try to open + create the file.
193*9880d681SAndroid Build Coastguard Worker   switch (Type) {
194*9880d681SAndroid Build Coastguard Worker   case FS_File: {
195*9880d681SAndroid Build Coastguard Worker     if (std::error_code EC =
196*9880d681SAndroid Build Coastguard Worker             sys::fs::openFileForWrite(Twine(ResultPath.begin()), ResultFD,
197*9880d681SAndroid Build Coastguard Worker                                       sys::fs::F_RW | sys::fs::F_Excl, Mode)) {
198*9880d681SAndroid Build Coastguard Worker       if (EC == errc::file_exists)
199*9880d681SAndroid Build Coastguard Worker         goto retry_random_path;
200*9880d681SAndroid Build Coastguard Worker       return EC;
201*9880d681SAndroid Build Coastguard Worker     }
202*9880d681SAndroid Build Coastguard Worker 
203*9880d681SAndroid Build Coastguard Worker     return std::error_code();
204*9880d681SAndroid Build Coastguard Worker   }
205*9880d681SAndroid Build Coastguard Worker 
206*9880d681SAndroid Build Coastguard Worker   case FS_Name: {
207*9880d681SAndroid Build Coastguard Worker     std::error_code EC =
208*9880d681SAndroid Build Coastguard Worker         sys::fs::access(ResultPath.begin(), sys::fs::AccessMode::Exist);
209*9880d681SAndroid Build Coastguard Worker     if (EC == errc::no_such_file_or_directory)
210*9880d681SAndroid Build Coastguard Worker       return std::error_code();
211*9880d681SAndroid Build Coastguard Worker     if (EC)
212*9880d681SAndroid Build Coastguard Worker       return EC;
213*9880d681SAndroid Build Coastguard Worker     goto retry_random_path;
214*9880d681SAndroid Build Coastguard Worker   }
215*9880d681SAndroid Build Coastguard Worker 
216*9880d681SAndroid Build Coastguard Worker   case FS_Dir: {
217*9880d681SAndroid Build Coastguard Worker     if (std::error_code EC =
218*9880d681SAndroid Build Coastguard Worker             sys::fs::create_directory(ResultPath.begin(), false)) {
219*9880d681SAndroid Build Coastguard Worker       if (EC == errc::file_exists)
220*9880d681SAndroid Build Coastguard Worker         goto retry_random_path;
221*9880d681SAndroid Build Coastguard Worker       return EC;
222*9880d681SAndroid Build Coastguard Worker     }
223*9880d681SAndroid Build Coastguard Worker     return std::error_code();
224*9880d681SAndroid Build Coastguard Worker   }
225*9880d681SAndroid Build Coastguard Worker   }
226*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Invalid Type");
227*9880d681SAndroid Build Coastguard Worker }
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker namespace llvm {
230*9880d681SAndroid Build Coastguard Worker namespace sys  {
231*9880d681SAndroid Build Coastguard Worker namespace path {
232*9880d681SAndroid Build Coastguard Worker 
begin(StringRef path)233*9880d681SAndroid Build Coastguard Worker const_iterator begin(StringRef path) {
234*9880d681SAndroid Build Coastguard Worker   const_iterator i;
235*9880d681SAndroid Build Coastguard Worker   i.Path      = path;
236*9880d681SAndroid Build Coastguard Worker   i.Component = find_first_component(path);
237*9880d681SAndroid Build Coastguard Worker   i.Position  = 0;
238*9880d681SAndroid Build Coastguard Worker   return i;
239*9880d681SAndroid Build Coastguard Worker }
240*9880d681SAndroid Build Coastguard Worker 
end(StringRef path)241*9880d681SAndroid Build Coastguard Worker const_iterator end(StringRef path) {
242*9880d681SAndroid Build Coastguard Worker   const_iterator i;
243*9880d681SAndroid Build Coastguard Worker   i.Path      = path;
244*9880d681SAndroid Build Coastguard Worker   i.Position  = path.size();
245*9880d681SAndroid Build Coastguard Worker   return i;
246*9880d681SAndroid Build Coastguard Worker }
247*9880d681SAndroid Build Coastguard Worker 
operator ++()248*9880d681SAndroid Build Coastguard Worker const_iterator &const_iterator::operator++() {
249*9880d681SAndroid Build Coastguard Worker   assert(Position < Path.size() && "Tried to increment past end!");
250*9880d681SAndroid Build Coastguard Worker 
251*9880d681SAndroid Build Coastguard Worker   // Increment Position to past the current component
252*9880d681SAndroid Build Coastguard Worker   Position += Component.size();
253*9880d681SAndroid Build Coastguard Worker 
254*9880d681SAndroid Build Coastguard Worker   // Check for end.
255*9880d681SAndroid Build Coastguard Worker   if (Position == Path.size()) {
256*9880d681SAndroid Build Coastguard Worker     Component = StringRef();
257*9880d681SAndroid Build Coastguard Worker     return *this;
258*9880d681SAndroid Build Coastguard Worker   }
259*9880d681SAndroid Build Coastguard Worker 
260*9880d681SAndroid Build Coastguard Worker   // Both POSIX and Windows treat paths that begin with exactly two separators
261*9880d681SAndroid Build Coastguard Worker   // specially.
262*9880d681SAndroid Build Coastguard Worker   bool was_net = Component.size() > 2 &&
263*9880d681SAndroid Build Coastguard Worker     is_separator(Component[0]) &&
264*9880d681SAndroid Build Coastguard Worker     Component[1] == Component[0] &&
265*9880d681SAndroid Build Coastguard Worker     !is_separator(Component[2]);
266*9880d681SAndroid Build Coastguard Worker 
267*9880d681SAndroid Build Coastguard Worker   // Handle separators.
268*9880d681SAndroid Build Coastguard Worker   if (is_separator(Path[Position])) {
269*9880d681SAndroid Build Coastguard Worker     // Root dir.
270*9880d681SAndroid Build Coastguard Worker     if (was_net
271*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
272*9880d681SAndroid Build Coastguard Worker         // c:/
273*9880d681SAndroid Build Coastguard Worker         || Component.endswith(":")
274*9880d681SAndroid Build Coastguard Worker #endif
275*9880d681SAndroid Build Coastguard Worker         ) {
276*9880d681SAndroid Build Coastguard Worker       Component = Path.substr(Position, 1);
277*9880d681SAndroid Build Coastguard Worker       return *this;
278*9880d681SAndroid Build Coastguard Worker     }
279*9880d681SAndroid Build Coastguard Worker 
280*9880d681SAndroid Build Coastguard Worker     // Skip extra separators.
281*9880d681SAndroid Build Coastguard Worker     while (Position != Path.size() &&
282*9880d681SAndroid Build Coastguard Worker            is_separator(Path[Position])) {
283*9880d681SAndroid Build Coastguard Worker       ++Position;
284*9880d681SAndroid Build Coastguard Worker     }
285*9880d681SAndroid Build Coastguard Worker 
286*9880d681SAndroid Build Coastguard Worker     // Treat trailing '/' as a '.'.
287*9880d681SAndroid Build Coastguard Worker     if (Position == Path.size()) {
288*9880d681SAndroid Build Coastguard Worker       --Position;
289*9880d681SAndroid Build Coastguard Worker       Component = ".";
290*9880d681SAndroid Build Coastguard Worker       return *this;
291*9880d681SAndroid Build Coastguard Worker     }
292*9880d681SAndroid Build Coastguard Worker   }
293*9880d681SAndroid Build Coastguard Worker 
294*9880d681SAndroid Build Coastguard Worker   // Find next component.
295*9880d681SAndroid Build Coastguard Worker   size_t end_pos = Path.find_first_of(separators, Position);
296*9880d681SAndroid Build Coastguard Worker   Component = Path.slice(Position, end_pos);
297*9880d681SAndroid Build Coastguard Worker 
298*9880d681SAndroid Build Coastguard Worker   return *this;
299*9880d681SAndroid Build Coastguard Worker }
300*9880d681SAndroid Build Coastguard Worker 
operator ==(const const_iterator & RHS) const301*9880d681SAndroid Build Coastguard Worker bool const_iterator::operator==(const const_iterator &RHS) const {
302*9880d681SAndroid Build Coastguard Worker   return Path.begin() == RHS.Path.begin() && Position == RHS.Position;
303*9880d681SAndroid Build Coastguard Worker }
304*9880d681SAndroid Build Coastguard Worker 
operator -(const const_iterator & RHS) const305*9880d681SAndroid Build Coastguard Worker ptrdiff_t const_iterator::operator-(const const_iterator &RHS) const {
306*9880d681SAndroid Build Coastguard Worker   return Position - RHS.Position;
307*9880d681SAndroid Build Coastguard Worker }
308*9880d681SAndroid Build Coastguard Worker 
rbegin(StringRef Path)309*9880d681SAndroid Build Coastguard Worker reverse_iterator rbegin(StringRef Path) {
310*9880d681SAndroid Build Coastguard Worker   reverse_iterator I;
311*9880d681SAndroid Build Coastguard Worker   I.Path = Path;
312*9880d681SAndroid Build Coastguard Worker   I.Position = Path.size();
313*9880d681SAndroid Build Coastguard Worker   return ++I;
314*9880d681SAndroid Build Coastguard Worker }
315*9880d681SAndroid Build Coastguard Worker 
rend(StringRef Path)316*9880d681SAndroid Build Coastguard Worker reverse_iterator rend(StringRef Path) {
317*9880d681SAndroid Build Coastguard Worker   reverse_iterator I;
318*9880d681SAndroid Build Coastguard Worker   I.Path = Path;
319*9880d681SAndroid Build Coastguard Worker   I.Component = Path.substr(0, 0);
320*9880d681SAndroid Build Coastguard Worker   I.Position = 0;
321*9880d681SAndroid Build Coastguard Worker   return I;
322*9880d681SAndroid Build Coastguard Worker }
323*9880d681SAndroid Build Coastguard Worker 
operator ++()324*9880d681SAndroid Build Coastguard Worker reverse_iterator &reverse_iterator::operator++() {
325*9880d681SAndroid Build Coastguard Worker   // If we're at the end and the previous char was a '/', return '.' unless
326*9880d681SAndroid Build Coastguard Worker   // we are the root path.
327*9880d681SAndroid Build Coastguard Worker   size_t root_dir_pos = root_dir_start(Path);
328*9880d681SAndroid Build Coastguard Worker   if (Position == Path.size() &&
329*9880d681SAndroid Build Coastguard Worker       Path.size() > root_dir_pos + 1 &&
330*9880d681SAndroid Build Coastguard Worker       is_separator(Path[Position - 1])) {
331*9880d681SAndroid Build Coastguard Worker     --Position;
332*9880d681SAndroid Build Coastguard Worker     Component = ".";
333*9880d681SAndroid Build Coastguard Worker     return *this;
334*9880d681SAndroid Build Coastguard Worker   }
335*9880d681SAndroid Build Coastguard Worker 
336*9880d681SAndroid Build Coastguard Worker   // Skip separators unless it's the root directory.
337*9880d681SAndroid Build Coastguard Worker   size_t end_pos = Position;
338*9880d681SAndroid Build Coastguard Worker 
339*9880d681SAndroid Build Coastguard Worker   while(end_pos > 0 &&
340*9880d681SAndroid Build Coastguard Worker         (end_pos - 1) != root_dir_pos &&
341*9880d681SAndroid Build Coastguard Worker         is_separator(Path[end_pos - 1]))
342*9880d681SAndroid Build Coastguard Worker     --end_pos;
343*9880d681SAndroid Build Coastguard Worker 
344*9880d681SAndroid Build Coastguard Worker   // Find next separator.
345*9880d681SAndroid Build Coastguard Worker   size_t start_pos = filename_pos(Path.substr(0, end_pos));
346*9880d681SAndroid Build Coastguard Worker   Component = Path.slice(start_pos, end_pos);
347*9880d681SAndroid Build Coastguard Worker   Position = start_pos;
348*9880d681SAndroid Build Coastguard Worker   return *this;
349*9880d681SAndroid Build Coastguard Worker }
350*9880d681SAndroid Build Coastguard Worker 
operator ==(const reverse_iterator & RHS) const351*9880d681SAndroid Build Coastguard Worker bool reverse_iterator::operator==(const reverse_iterator &RHS) const {
352*9880d681SAndroid Build Coastguard Worker   return Path.begin() == RHS.Path.begin() && Component == RHS.Component &&
353*9880d681SAndroid Build Coastguard Worker          Position == RHS.Position;
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker 
operator -(const reverse_iterator & RHS) const356*9880d681SAndroid Build Coastguard Worker ptrdiff_t reverse_iterator::operator-(const reverse_iterator &RHS) const {
357*9880d681SAndroid Build Coastguard Worker   return Position - RHS.Position;
358*9880d681SAndroid Build Coastguard Worker }
359*9880d681SAndroid Build Coastguard Worker 
root_path(StringRef path)360*9880d681SAndroid Build Coastguard Worker StringRef root_path(StringRef path) {
361*9880d681SAndroid Build Coastguard Worker   const_iterator b = begin(path),
362*9880d681SAndroid Build Coastguard Worker                  pos = b,
363*9880d681SAndroid Build Coastguard Worker                  e = end(path);
364*9880d681SAndroid Build Coastguard Worker   if (b != e) {
365*9880d681SAndroid Build Coastguard Worker     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
366*9880d681SAndroid Build Coastguard Worker     bool has_drive =
367*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
368*9880d681SAndroid Build Coastguard Worker       b->endswith(":");
369*9880d681SAndroid Build Coastguard Worker #else
370*9880d681SAndroid Build Coastguard Worker       false;
371*9880d681SAndroid Build Coastguard Worker #endif
372*9880d681SAndroid Build Coastguard Worker 
373*9880d681SAndroid Build Coastguard Worker     if (has_net || has_drive) {
374*9880d681SAndroid Build Coastguard Worker       if ((++pos != e) && is_separator((*pos)[0])) {
375*9880d681SAndroid Build Coastguard Worker         // {C:/,//net/}, so get the first two components.
376*9880d681SAndroid Build Coastguard Worker         return path.substr(0, b->size() + pos->size());
377*9880d681SAndroid Build Coastguard Worker       } else {
378*9880d681SAndroid Build Coastguard Worker         // just {C:,//net}, return the first component.
379*9880d681SAndroid Build Coastguard Worker         return *b;
380*9880d681SAndroid Build Coastguard Worker       }
381*9880d681SAndroid Build Coastguard Worker     }
382*9880d681SAndroid Build Coastguard Worker 
383*9880d681SAndroid Build Coastguard Worker     // POSIX style root directory.
384*9880d681SAndroid Build Coastguard Worker     if (is_separator((*b)[0])) {
385*9880d681SAndroid Build Coastguard Worker       return *b;
386*9880d681SAndroid Build Coastguard Worker     }
387*9880d681SAndroid Build Coastguard Worker   }
388*9880d681SAndroid Build Coastguard Worker 
389*9880d681SAndroid Build Coastguard Worker   return StringRef();
390*9880d681SAndroid Build Coastguard Worker }
391*9880d681SAndroid Build Coastguard Worker 
root_name(StringRef path)392*9880d681SAndroid Build Coastguard Worker StringRef root_name(StringRef path) {
393*9880d681SAndroid Build Coastguard Worker   const_iterator b = begin(path),
394*9880d681SAndroid Build Coastguard Worker                  e = end(path);
395*9880d681SAndroid Build Coastguard Worker   if (b != e) {
396*9880d681SAndroid Build Coastguard Worker     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
397*9880d681SAndroid Build Coastguard Worker     bool has_drive =
398*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
399*9880d681SAndroid Build Coastguard Worker       b->endswith(":");
400*9880d681SAndroid Build Coastguard Worker #else
401*9880d681SAndroid Build Coastguard Worker       false;
402*9880d681SAndroid Build Coastguard Worker #endif
403*9880d681SAndroid Build Coastguard Worker 
404*9880d681SAndroid Build Coastguard Worker     if (has_net || has_drive) {
405*9880d681SAndroid Build Coastguard Worker       // just {C:,//net}, return the first component.
406*9880d681SAndroid Build Coastguard Worker       return *b;
407*9880d681SAndroid Build Coastguard Worker     }
408*9880d681SAndroid Build Coastguard Worker   }
409*9880d681SAndroid Build Coastguard Worker 
410*9880d681SAndroid Build Coastguard Worker   // No path or no name.
411*9880d681SAndroid Build Coastguard Worker   return StringRef();
412*9880d681SAndroid Build Coastguard Worker }
413*9880d681SAndroid Build Coastguard Worker 
root_directory(StringRef path)414*9880d681SAndroid Build Coastguard Worker StringRef root_directory(StringRef path) {
415*9880d681SAndroid Build Coastguard Worker   const_iterator b = begin(path),
416*9880d681SAndroid Build Coastguard Worker                  pos = b,
417*9880d681SAndroid Build Coastguard Worker                  e = end(path);
418*9880d681SAndroid Build Coastguard Worker   if (b != e) {
419*9880d681SAndroid Build Coastguard Worker     bool has_net = b->size() > 2 && is_separator((*b)[0]) && (*b)[1] == (*b)[0];
420*9880d681SAndroid Build Coastguard Worker     bool has_drive =
421*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
422*9880d681SAndroid Build Coastguard Worker       b->endswith(":");
423*9880d681SAndroid Build Coastguard Worker #else
424*9880d681SAndroid Build Coastguard Worker       false;
425*9880d681SAndroid Build Coastguard Worker #endif
426*9880d681SAndroid Build Coastguard Worker 
427*9880d681SAndroid Build Coastguard Worker     if ((has_net || has_drive) &&
428*9880d681SAndroid Build Coastguard Worker         // {C:,//net}, skip to the next component.
429*9880d681SAndroid Build Coastguard Worker         (++pos != e) && is_separator((*pos)[0])) {
430*9880d681SAndroid Build Coastguard Worker       return *pos;
431*9880d681SAndroid Build Coastguard Worker     }
432*9880d681SAndroid Build Coastguard Worker 
433*9880d681SAndroid Build Coastguard Worker     // POSIX style root directory.
434*9880d681SAndroid Build Coastguard Worker     if (!has_net && is_separator((*b)[0])) {
435*9880d681SAndroid Build Coastguard Worker       return *b;
436*9880d681SAndroid Build Coastguard Worker     }
437*9880d681SAndroid Build Coastguard Worker   }
438*9880d681SAndroid Build Coastguard Worker 
439*9880d681SAndroid Build Coastguard Worker   // No path or no root.
440*9880d681SAndroid Build Coastguard Worker   return StringRef();
441*9880d681SAndroid Build Coastguard Worker }
442*9880d681SAndroid Build Coastguard Worker 
relative_path(StringRef path)443*9880d681SAndroid Build Coastguard Worker StringRef relative_path(StringRef path) {
444*9880d681SAndroid Build Coastguard Worker   StringRef root = root_path(path);
445*9880d681SAndroid Build Coastguard Worker   return path.substr(root.size());
446*9880d681SAndroid Build Coastguard Worker }
447*9880d681SAndroid Build Coastguard Worker 
append(SmallVectorImpl<char> & path,const Twine & a,const Twine & b,const Twine & c,const Twine & d)448*9880d681SAndroid Build Coastguard Worker void append(SmallVectorImpl<char> &path, const Twine &a,
449*9880d681SAndroid Build Coastguard Worker                                          const Twine &b,
450*9880d681SAndroid Build Coastguard Worker                                          const Twine &c,
451*9880d681SAndroid Build Coastguard Worker                                          const Twine &d) {
452*9880d681SAndroid Build Coastguard Worker   SmallString<32> a_storage;
453*9880d681SAndroid Build Coastguard Worker   SmallString<32> b_storage;
454*9880d681SAndroid Build Coastguard Worker   SmallString<32> c_storage;
455*9880d681SAndroid Build Coastguard Worker   SmallString<32> d_storage;
456*9880d681SAndroid Build Coastguard Worker 
457*9880d681SAndroid Build Coastguard Worker   SmallVector<StringRef, 4> components;
458*9880d681SAndroid Build Coastguard Worker   if (!a.isTriviallyEmpty()) components.push_back(a.toStringRef(a_storage));
459*9880d681SAndroid Build Coastguard Worker   if (!b.isTriviallyEmpty()) components.push_back(b.toStringRef(b_storage));
460*9880d681SAndroid Build Coastguard Worker   if (!c.isTriviallyEmpty()) components.push_back(c.toStringRef(c_storage));
461*9880d681SAndroid Build Coastguard Worker   if (!d.isTriviallyEmpty()) components.push_back(d.toStringRef(d_storage));
462*9880d681SAndroid Build Coastguard Worker 
463*9880d681SAndroid Build Coastguard Worker   for (auto &component : components) {
464*9880d681SAndroid Build Coastguard Worker     bool path_has_sep = !path.empty() && is_separator(path[path.size() - 1]);
465*9880d681SAndroid Build Coastguard Worker     bool component_has_sep = !component.empty() && is_separator(component[0]);
466*9880d681SAndroid Build Coastguard Worker     bool is_root_name = has_root_name(component);
467*9880d681SAndroid Build Coastguard Worker 
468*9880d681SAndroid Build Coastguard Worker     if (path_has_sep) {
469*9880d681SAndroid Build Coastguard Worker       // Strip separators from beginning of component.
470*9880d681SAndroid Build Coastguard Worker       size_t loc = component.find_first_not_of(separators);
471*9880d681SAndroid Build Coastguard Worker       StringRef c = component.substr(loc);
472*9880d681SAndroid Build Coastguard Worker 
473*9880d681SAndroid Build Coastguard Worker       // Append it.
474*9880d681SAndroid Build Coastguard Worker       path.append(c.begin(), c.end());
475*9880d681SAndroid Build Coastguard Worker       continue;
476*9880d681SAndroid Build Coastguard Worker     }
477*9880d681SAndroid Build Coastguard Worker 
478*9880d681SAndroid Build Coastguard Worker     if (!component_has_sep && !(path.empty() || is_root_name)) {
479*9880d681SAndroid Build Coastguard Worker       // Add a separator.
480*9880d681SAndroid Build Coastguard Worker       path.push_back(preferred_separator);
481*9880d681SAndroid Build Coastguard Worker     }
482*9880d681SAndroid Build Coastguard Worker 
483*9880d681SAndroid Build Coastguard Worker     path.append(component.begin(), component.end());
484*9880d681SAndroid Build Coastguard Worker   }
485*9880d681SAndroid Build Coastguard Worker }
486*9880d681SAndroid Build Coastguard Worker 
append(SmallVectorImpl<char> & path,const_iterator begin,const_iterator end)487*9880d681SAndroid Build Coastguard Worker void append(SmallVectorImpl<char> &path,
488*9880d681SAndroid Build Coastguard Worker             const_iterator begin, const_iterator end) {
489*9880d681SAndroid Build Coastguard Worker   for (; begin != end; ++begin)
490*9880d681SAndroid Build Coastguard Worker     path::append(path, *begin);
491*9880d681SAndroid Build Coastguard Worker }
492*9880d681SAndroid Build Coastguard Worker 
parent_path(StringRef path)493*9880d681SAndroid Build Coastguard Worker StringRef parent_path(StringRef path) {
494*9880d681SAndroid Build Coastguard Worker   size_t end_pos = parent_path_end(path);
495*9880d681SAndroid Build Coastguard Worker   if (end_pos == StringRef::npos)
496*9880d681SAndroid Build Coastguard Worker     return StringRef();
497*9880d681SAndroid Build Coastguard Worker   else
498*9880d681SAndroid Build Coastguard Worker     return path.substr(0, end_pos);
499*9880d681SAndroid Build Coastguard Worker }
500*9880d681SAndroid Build Coastguard Worker 
remove_filename(SmallVectorImpl<char> & path)501*9880d681SAndroid Build Coastguard Worker void remove_filename(SmallVectorImpl<char> &path) {
502*9880d681SAndroid Build Coastguard Worker   size_t end_pos = parent_path_end(StringRef(path.begin(), path.size()));
503*9880d681SAndroid Build Coastguard Worker   if (end_pos != StringRef::npos)
504*9880d681SAndroid Build Coastguard Worker     path.set_size(end_pos);
505*9880d681SAndroid Build Coastguard Worker }
506*9880d681SAndroid Build Coastguard Worker 
replace_extension(SmallVectorImpl<char> & path,const Twine & extension)507*9880d681SAndroid Build Coastguard Worker void replace_extension(SmallVectorImpl<char> &path, const Twine &extension) {
508*9880d681SAndroid Build Coastguard Worker   StringRef p(path.begin(), path.size());
509*9880d681SAndroid Build Coastguard Worker   SmallString<32> ext_storage;
510*9880d681SAndroid Build Coastguard Worker   StringRef ext = extension.toStringRef(ext_storage);
511*9880d681SAndroid Build Coastguard Worker 
512*9880d681SAndroid Build Coastguard Worker   // Erase existing extension.
513*9880d681SAndroid Build Coastguard Worker   size_t pos = p.find_last_of('.');
514*9880d681SAndroid Build Coastguard Worker   if (pos != StringRef::npos && pos >= filename_pos(p))
515*9880d681SAndroid Build Coastguard Worker     path.set_size(pos);
516*9880d681SAndroid Build Coastguard Worker 
517*9880d681SAndroid Build Coastguard Worker   // Append '.' if needed.
518*9880d681SAndroid Build Coastguard Worker   if (ext.size() > 0 && ext[0] != '.')
519*9880d681SAndroid Build Coastguard Worker     path.push_back('.');
520*9880d681SAndroid Build Coastguard Worker 
521*9880d681SAndroid Build Coastguard Worker   // Append extension.
522*9880d681SAndroid Build Coastguard Worker   path.append(ext.begin(), ext.end());
523*9880d681SAndroid Build Coastguard Worker }
524*9880d681SAndroid Build Coastguard Worker 
replace_path_prefix(SmallVectorImpl<char> & Path,const StringRef & OldPrefix,const StringRef & NewPrefix)525*9880d681SAndroid Build Coastguard Worker void replace_path_prefix(SmallVectorImpl<char> &Path,
526*9880d681SAndroid Build Coastguard Worker                          const StringRef &OldPrefix,
527*9880d681SAndroid Build Coastguard Worker                          const StringRef &NewPrefix) {
528*9880d681SAndroid Build Coastguard Worker   if (OldPrefix.empty() && NewPrefix.empty())
529*9880d681SAndroid Build Coastguard Worker     return;
530*9880d681SAndroid Build Coastguard Worker 
531*9880d681SAndroid Build Coastguard Worker   StringRef OrigPath(Path.begin(), Path.size());
532*9880d681SAndroid Build Coastguard Worker   if (!OrigPath.startswith(OldPrefix))
533*9880d681SAndroid Build Coastguard Worker     return;
534*9880d681SAndroid Build Coastguard Worker 
535*9880d681SAndroid Build Coastguard Worker   // If prefixes have the same size we can simply copy the new one over.
536*9880d681SAndroid Build Coastguard Worker   if (OldPrefix.size() == NewPrefix.size()) {
537*9880d681SAndroid Build Coastguard Worker     std::copy(NewPrefix.begin(), NewPrefix.end(), Path.begin());
538*9880d681SAndroid Build Coastguard Worker     return;
539*9880d681SAndroid Build Coastguard Worker   }
540*9880d681SAndroid Build Coastguard Worker 
541*9880d681SAndroid Build Coastguard Worker   StringRef RelPath = OrigPath.substr(OldPrefix.size());
542*9880d681SAndroid Build Coastguard Worker   SmallString<256> NewPath;
543*9880d681SAndroid Build Coastguard Worker   path::append(NewPath, NewPrefix);
544*9880d681SAndroid Build Coastguard Worker   path::append(NewPath, RelPath);
545*9880d681SAndroid Build Coastguard Worker   Path.swap(NewPath);
546*9880d681SAndroid Build Coastguard Worker }
547*9880d681SAndroid Build Coastguard Worker 
native(const Twine & path,SmallVectorImpl<char> & result)548*9880d681SAndroid Build Coastguard Worker void native(const Twine &path, SmallVectorImpl<char> &result) {
549*9880d681SAndroid Build Coastguard Worker   assert((!path.isSingleStringRef() ||
550*9880d681SAndroid Build Coastguard Worker           path.getSingleStringRef().data() != result.data()) &&
551*9880d681SAndroid Build Coastguard Worker          "path and result are not allowed to overlap!");
552*9880d681SAndroid Build Coastguard Worker   // Clear result.
553*9880d681SAndroid Build Coastguard Worker   result.clear();
554*9880d681SAndroid Build Coastguard Worker   path.toVector(result);
555*9880d681SAndroid Build Coastguard Worker   native(result);
556*9880d681SAndroid Build Coastguard Worker }
557*9880d681SAndroid Build Coastguard Worker 
native(SmallVectorImpl<char> & Path)558*9880d681SAndroid Build Coastguard Worker void native(SmallVectorImpl<char> &Path) {
559*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
560*9880d681SAndroid Build Coastguard Worker   std::replace(Path.begin(), Path.end(), '/', '\\');
561*9880d681SAndroid Build Coastguard Worker #else
562*9880d681SAndroid Build Coastguard Worker   for (auto PI = Path.begin(), PE = Path.end(); PI < PE; ++PI) {
563*9880d681SAndroid Build Coastguard Worker     if (*PI == '\\') {
564*9880d681SAndroid Build Coastguard Worker       auto PN = PI + 1;
565*9880d681SAndroid Build Coastguard Worker       if (PN < PE && *PN == '\\')
566*9880d681SAndroid Build Coastguard Worker         ++PI; // increment once, the for loop will move over the escaped slash
567*9880d681SAndroid Build Coastguard Worker       else
568*9880d681SAndroid Build Coastguard Worker         *PI = '/';
569*9880d681SAndroid Build Coastguard Worker     }
570*9880d681SAndroid Build Coastguard Worker   }
571*9880d681SAndroid Build Coastguard Worker #endif
572*9880d681SAndroid Build Coastguard Worker }
573*9880d681SAndroid Build Coastguard Worker 
filename(StringRef path)574*9880d681SAndroid Build Coastguard Worker StringRef filename(StringRef path) {
575*9880d681SAndroid Build Coastguard Worker   return *rbegin(path);
576*9880d681SAndroid Build Coastguard Worker }
577*9880d681SAndroid Build Coastguard Worker 
stem(StringRef path)578*9880d681SAndroid Build Coastguard Worker StringRef stem(StringRef path) {
579*9880d681SAndroid Build Coastguard Worker   StringRef fname = filename(path);
580*9880d681SAndroid Build Coastguard Worker   size_t pos = fname.find_last_of('.');
581*9880d681SAndroid Build Coastguard Worker   if (pos == StringRef::npos)
582*9880d681SAndroid Build Coastguard Worker     return fname;
583*9880d681SAndroid Build Coastguard Worker   else
584*9880d681SAndroid Build Coastguard Worker     if ((fname.size() == 1 && fname == ".") ||
585*9880d681SAndroid Build Coastguard Worker         (fname.size() == 2 && fname == ".."))
586*9880d681SAndroid Build Coastguard Worker       return fname;
587*9880d681SAndroid Build Coastguard Worker     else
588*9880d681SAndroid Build Coastguard Worker       return fname.substr(0, pos);
589*9880d681SAndroid Build Coastguard Worker }
590*9880d681SAndroid Build Coastguard Worker 
extension(StringRef path)591*9880d681SAndroid Build Coastguard Worker StringRef extension(StringRef path) {
592*9880d681SAndroid Build Coastguard Worker   StringRef fname = filename(path);
593*9880d681SAndroid Build Coastguard Worker   size_t pos = fname.find_last_of('.');
594*9880d681SAndroid Build Coastguard Worker   if (pos == StringRef::npos)
595*9880d681SAndroid Build Coastguard Worker     return StringRef();
596*9880d681SAndroid Build Coastguard Worker   else
597*9880d681SAndroid Build Coastguard Worker     if ((fname.size() == 1 && fname == ".") ||
598*9880d681SAndroid Build Coastguard Worker         (fname.size() == 2 && fname == ".."))
599*9880d681SAndroid Build Coastguard Worker       return StringRef();
600*9880d681SAndroid Build Coastguard Worker     else
601*9880d681SAndroid Build Coastguard Worker       return fname.substr(pos);
602*9880d681SAndroid Build Coastguard Worker }
603*9880d681SAndroid Build Coastguard Worker 
is_separator(char value)604*9880d681SAndroid Build Coastguard Worker bool is_separator(char value) {
605*9880d681SAndroid Build Coastguard Worker   switch(value) {
606*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
607*9880d681SAndroid Build Coastguard Worker     case '\\': // fall through
608*9880d681SAndroid Build Coastguard Worker #endif
609*9880d681SAndroid Build Coastguard Worker     case '/': return true;
610*9880d681SAndroid Build Coastguard Worker     default: return false;
611*9880d681SAndroid Build Coastguard Worker   }
612*9880d681SAndroid Build Coastguard Worker }
613*9880d681SAndroid Build Coastguard Worker 
614*9880d681SAndroid Build Coastguard Worker static const char preferred_separator_string[] = { preferred_separator, '\0' };
615*9880d681SAndroid Build Coastguard Worker 
get_separator()616*9880d681SAndroid Build Coastguard Worker StringRef get_separator() {
617*9880d681SAndroid Build Coastguard Worker   return preferred_separator_string;
618*9880d681SAndroid Build Coastguard Worker }
619*9880d681SAndroid Build Coastguard Worker 
has_root_name(const Twine & path)620*9880d681SAndroid Build Coastguard Worker bool has_root_name(const Twine &path) {
621*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
622*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
623*9880d681SAndroid Build Coastguard Worker 
624*9880d681SAndroid Build Coastguard Worker   return !root_name(p).empty();
625*9880d681SAndroid Build Coastguard Worker }
626*9880d681SAndroid Build Coastguard Worker 
has_root_directory(const Twine & path)627*9880d681SAndroid Build Coastguard Worker bool has_root_directory(const Twine &path) {
628*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
629*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
630*9880d681SAndroid Build Coastguard Worker 
631*9880d681SAndroid Build Coastguard Worker   return !root_directory(p).empty();
632*9880d681SAndroid Build Coastguard Worker }
633*9880d681SAndroid Build Coastguard Worker 
has_root_path(const Twine & path)634*9880d681SAndroid Build Coastguard Worker bool has_root_path(const Twine &path) {
635*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
636*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
637*9880d681SAndroid Build Coastguard Worker 
638*9880d681SAndroid Build Coastguard Worker   return !root_path(p).empty();
639*9880d681SAndroid Build Coastguard Worker }
640*9880d681SAndroid Build Coastguard Worker 
has_relative_path(const Twine & path)641*9880d681SAndroid Build Coastguard Worker bool has_relative_path(const Twine &path) {
642*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
643*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
644*9880d681SAndroid Build Coastguard Worker 
645*9880d681SAndroid Build Coastguard Worker   return !relative_path(p).empty();
646*9880d681SAndroid Build Coastguard Worker }
647*9880d681SAndroid Build Coastguard Worker 
has_filename(const Twine & path)648*9880d681SAndroid Build Coastguard Worker bool has_filename(const Twine &path) {
649*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
650*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
651*9880d681SAndroid Build Coastguard Worker 
652*9880d681SAndroid Build Coastguard Worker   return !filename(p).empty();
653*9880d681SAndroid Build Coastguard Worker }
654*9880d681SAndroid Build Coastguard Worker 
has_parent_path(const Twine & path)655*9880d681SAndroid Build Coastguard Worker bool has_parent_path(const Twine &path) {
656*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
657*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
658*9880d681SAndroid Build Coastguard Worker 
659*9880d681SAndroid Build Coastguard Worker   return !parent_path(p).empty();
660*9880d681SAndroid Build Coastguard Worker }
661*9880d681SAndroid Build Coastguard Worker 
has_stem(const Twine & path)662*9880d681SAndroid Build Coastguard Worker bool has_stem(const Twine &path) {
663*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
664*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
665*9880d681SAndroid Build Coastguard Worker 
666*9880d681SAndroid Build Coastguard Worker   return !stem(p).empty();
667*9880d681SAndroid Build Coastguard Worker }
668*9880d681SAndroid Build Coastguard Worker 
has_extension(const Twine & path)669*9880d681SAndroid Build Coastguard Worker bool has_extension(const Twine &path) {
670*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
671*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
672*9880d681SAndroid Build Coastguard Worker 
673*9880d681SAndroid Build Coastguard Worker   return !extension(p).empty();
674*9880d681SAndroid Build Coastguard Worker }
675*9880d681SAndroid Build Coastguard Worker 
is_absolute(const Twine & path)676*9880d681SAndroid Build Coastguard Worker bool is_absolute(const Twine &path) {
677*9880d681SAndroid Build Coastguard Worker   SmallString<128> path_storage;
678*9880d681SAndroid Build Coastguard Worker   StringRef p = path.toStringRef(path_storage);
679*9880d681SAndroid Build Coastguard Worker 
680*9880d681SAndroid Build Coastguard Worker   bool rootDir = has_root_directory(p),
681*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
682*9880d681SAndroid Build Coastguard Worker        rootName = has_root_name(p);
683*9880d681SAndroid Build Coastguard Worker #else
684*9880d681SAndroid Build Coastguard Worker        rootName = true;
685*9880d681SAndroid Build Coastguard Worker #endif
686*9880d681SAndroid Build Coastguard Worker 
687*9880d681SAndroid Build Coastguard Worker   return rootDir && rootName;
688*9880d681SAndroid Build Coastguard Worker }
689*9880d681SAndroid Build Coastguard Worker 
is_relative(const Twine & path)690*9880d681SAndroid Build Coastguard Worker bool is_relative(const Twine &path) { return !is_absolute(path); }
691*9880d681SAndroid Build Coastguard Worker 
remove_leading_dotslash(StringRef Path)692*9880d681SAndroid Build Coastguard Worker StringRef remove_leading_dotslash(StringRef Path) {
693*9880d681SAndroid Build Coastguard Worker   // Remove leading "./" (or ".//" or "././" etc.)
694*9880d681SAndroid Build Coastguard Worker   while (Path.size() > 2 && Path[0] == '.' && is_separator(Path[1])) {
695*9880d681SAndroid Build Coastguard Worker     Path = Path.substr(2);
696*9880d681SAndroid Build Coastguard Worker     while (Path.size() > 0 && is_separator(Path[0]))
697*9880d681SAndroid Build Coastguard Worker       Path = Path.substr(1);
698*9880d681SAndroid Build Coastguard Worker   }
699*9880d681SAndroid Build Coastguard Worker   return Path;
700*9880d681SAndroid Build Coastguard Worker }
701*9880d681SAndroid Build Coastguard Worker 
remove_dots(StringRef path,bool remove_dot_dot)702*9880d681SAndroid Build Coastguard Worker static SmallString<256> remove_dots(StringRef path, bool remove_dot_dot) {
703*9880d681SAndroid Build Coastguard Worker   SmallVector<StringRef, 16> components;
704*9880d681SAndroid Build Coastguard Worker 
705*9880d681SAndroid Build Coastguard Worker   // Skip the root path, then look for traversal in the components.
706*9880d681SAndroid Build Coastguard Worker   StringRef rel = path::relative_path(path);
707*9880d681SAndroid Build Coastguard Worker   for (StringRef C : llvm::make_range(path::begin(rel), path::end(rel))) {
708*9880d681SAndroid Build Coastguard Worker     if (C == ".")
709*9880d681SAndroid Build Coastguard Worker       continue;
710*9880d681SAndroid Build Coastguard Worker     if (remove_dot_dot) {
711*9880d681SAndroid Build Coastguard Worker       if (C == "..") {
712*9880d681SAndroid Build Coastguard Worker         if (!components.empty())
713*9880d681SAndroid Build Coastguard Worker           components.pop_back();
714*9880d681SAndroid Build Coastguard Worker         continue;
715*9880d681SAndroid Build Coastguard Worker       }
716*9880d681SAndroid Build Coastguard Worker     }
717*9880d681SAndroid Build Coastguard Worker     components.push_back(C);
718*9880d681SAndroid Build Coastguard Worker   }
719*9880d681SAndroid Build Coastguard Worker 
720*9880d681SAndroid Build Coastguard Worker   SmallString<256> buffer = path::root_path(path);
721*9880d681SAndroid Build Coastguard Worker   for (StringRef C : components)
722*9880d681SAndroid Build Coastguard Worker     path::append(buffer, C);
723*9880d681SAndroid Build Coastguard Worker   return buffer;
724*9880d681SAndroid Build Coastguard Worker }
725*9880d681SAndroid Build Coastguard Worker 
remove_dots(SmallVectorImpl<char> & path,bool remove_dot_dot)726*9880d681SAndroid Build Coastguard Worker bool remove_dots(SmallVectorImpl<char> &path, bool remove_dot_dot) {
727*9880d681SAndroid Build Coastguard Worker   StringRef p(path.data(), path.size());
728*9880d681SAndroid Build Coastguard Worker 
729*9880d681SAndroid Build Coastguard Worker   SmallString<256> result = remove_dots(p, remove_dot_dot);
730*9880d681SAndroid Build Coastguard Worker   if (result == path)
731*9880d681SAndroid Build Coastguard Worker     return false;
732*9880d681SAndroid Build Coastguard Worker 
733*9880d681SAndroid Build Coastguard Worker   path.swap(result);
734*9880d681SAndroid Build Coastguard Worker   return true;
735*9880d681SAndroid Build Coastguard Worker }
736*9880d681SAndroid Build Coastguard Worker 
737*9880d681SAndroid Build Coastguard Worker } // end namespace path
738*9880d681SAndroid Build Coastguard Worker 
739*9880d681SAndroid Build Coastguard Worker namespace fs {
740*9880d681SAndroid Build Coastguard Worker 
getUniqueID(const Twine Path,UniqueID & Result)741*9880d681SAndroid Build Coastguard Worker std::error_code getUniqueID(const Twine Path, UniqueID &Result) {
742*9880d681SAndroid Build Coastguard Worker   file_status Status;
743*9880d681SAndroid Build Coastguard Worker   std::error_code EC = status(Path, Status);
744*9880d681SAndroid Build Coastguard Worker   if (EC)
745*9880d681SAndroid Build Coastguard Worker     return EC;
746*9880d681SAndroid Build Coastguard Worker   Result = Status.getUniqueID();
747*9880d681SAndroid Build Coastguard Worker   return std::error_code();
748*9880d681SAndroid Build Coastguard Worker }
749*9880d681SAndroid Build Coastguard Worker 
createUniqueFile(const Twine & Model,int & ResultFd,SmallVectorImpl<char> & ResultPath,unsigned Mode)750*9880d681SAndroid Build Coastguard Worker std::error_code createUniqueFile(const Twine &Model, int &ResultFd,
751*9880d681SAndroid Build Coastguard Worker                                  SmallVectorImpl<char> &ResultPath,
752*9880d681SAndroid Build Coastguard Worker                                  unsigned Mode) {
753*9880d681SAndroid Build Coastguard Worker   return createUniqueEntity(Model, ResultFd, ResultPath, false, Mode, FS_File);
754*9880d681SAndroid Build Coastguard Worker }
755*9880d681SAndroid Build Coastguard Worker 
createUniqueFile(const Twine & Model,SmallVectorImpl<char> & ResultPath)756*9880d681SAndroid Build Coastguard Worker std::error_code createUniqueFile(const Twine &Model,
757*9880d681SAndroid Build Coastguard Worker                                  SmallVectorImpl<char> &ResultPath) {
758*9880d681SAndroid Build Coastguard Worker   int Dummy;
759*9880d681SAndroid Build Coastguard Worker   return createUniqueEntity(Model, Dummy, ResultPath, false, 0, FS_Name);
760*9880d681SAndroid Build Coastguard Worker }
761*9880d681SAndroid Build Coastguard Worker 
762*9880d681SAndroid Build Coastguard Worker static std::error_code
createTemporaryFile(const Twine & Model,int & ResultFD,llvm::SmallVectorImpl<char> & ResultPath,FSEntity Type)763*9880d681SAndroid Build Coastguard Worker createTemporaryFile(const Twine &Model, int &ResultFD,
764*9880d681SAndroid Build Coastguard Worker                     llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
765*9880d681SAndroid Build Coastguard Worker   SmallString<128> Storage;
766*9880d681SAndroid Build Coastguard Worker   StringRef P = Model.toNullTerminatedStringRef(Storage);
767*9880d681SAndroid Build Coastguard Worker   assert(P.find_first_of(separators) == StringRef::npos &&
768*9880d681SAndroid Build Coastguard Worker          "Model must be a simple filename.");
769*9880d681SAndroid Build Coastguard Worker   // Use P.begin() so that createUniqueEntity doesn't need to recreate Storage.
770*9880d681SAndroid Build Coastguard Worker   return createUniqueEntity(P.begin(), ResultFD, ResultPath,
771*9880d681SAndroid Build Coastguard Worker                             true, owner_read | owner_write, Type);
772*9880d681SAndroid Build Coastguard Worker }
773*9880d681SAndroid Build Coastguard Worker 
774*9880d681SAndroid Build Coastguard Worker static std::error_code
createTemporaryFile(const Twine & Prefix,StringRef Suffix,int & ResultFD,llvm::SmallVectorImpl<char> & ResultPath,FSEntity Type)775*9880d681SAndroid Build Coastguard Worker createTemporaryFile(const Twine &Prefix, StringRef Suffix, int &ResultFD,
776*9880d681SAndroid Build Coastguard Worker                     llvm::SmallVectorImpl<char> &ResultPath, FSEntity Type) {
777*9880d681SAndroid Build Coastguard Worker   const char *Middle = Suffix.empty() ? "-%%%%%%" : "-%%%%%%.";
778*9880d681SAndroid Build Coastguard Worker   return createTemporaryFile(Prefix + Middle + Suffix, ResultFD, ResultPath,
779*9880d681SAndroid Build Coastguard Worker                              Type);
780*9880d681SAndroid Build Coastguard Worker }
781*9880d681SAndroid Build Coastguard Worker 
createTemporaryFile(const Twine & Prefix,StringRef Suffix,int & ResultFD,SmallVectorImpl<char> & ResultPath)782*9880d681SAndroid Build Coastguard Worker std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
783*9880d681SAndroid Build Coastguard Worker                                     int &ResultFD,
784*9880d681SAndroid Build Coastguard Worker                                     SmallVectorImpl<char> &ResultPath) {
785*9880d681SAndroid Build Coastguard Worker   return createTemporaryFile(Prefix, Suffix, ResultFD, ResultPath, FS_File);
786*9880d681SAndroid Build Coastguard Worker }
787*9880d681SAndroid Build Coastguard Worker 
createTemporaryFile(const Twine & Prefix,StringRef Suffix,SmallVectorImpl<char> & ResultPath)788*9880d681SAndroid Build Coastguard Worker std::error_code createTemporaryFile(const Twine &Prefix, StringRef Suffix,
789*9880d681SAndroid Build Coastguard Worker                                     SmallVectorImpl<char> &ResultPath) {
790*9880d681SAndroid Build Coastguard Worker   int Dummy;
791*9880d681SAndroid Build Coastguard Worker   return createTemporaryFile(Prefix, Suffix, Dummy, ResultPath, FS_Name);
792*9880d681SAndroid Build Coastguard Worker }
793*9880d681SAndroid Build Coastguard Worker 
794*9880d681SAndroid Build Coastguard Worker 
795*9880d681SAndroid Build Coastguard Worker // This is a mkdtemp with a different pattern. We use createUniqueEntity mostly
796*9880d681SAndroid Build Coastguard Worker // for consistency. We should try using mkdtemp.
createUniqueDirectory(const Twine & Prefix,SmallVectorImpl<char> & ResultPath)797*9880d681SAndroid Build Coastguard Worker std::error_code createUniqueDirectory(const Twine &Prefix,
798*9880d681SAndroid Build Coastguard Worker                                       SmallVectorImpl<char> &ResultPath) {
799*9880d681SAndroid Build Coastguard Worker   int Dummy;
800*9880d681SAndroid Build Coastguard Worker   return createUniqueEntity(Prefix + "-%%%%%%", Dummy, ResultPath,
801*9880d681SAndroid Build Coastguard Worker                             true, 0, FS_Dir);
802*9880d681SAndroid Build Coastguard Worker }
803*9880d681SAndroid Build Coastguard Worker 
make_absolute(const Twine & current_directory,SmallVectorImpl<char> & path,bool use_current_directory)804*9880d681SAndroid Build Coastguard Worker static std::error_code make_absolute(const Twine &current_directory,
805*9880d681SAndroid Build Coastguard Worker                                      SmallVectorImpl<char> &path,
806*9880d681SAndroid Build Coastguard Worker                                      bool use_current_directory) {
807*9880d681SAndroid Build Coastguard Worker   StringRef p(path.data(), path.size());
808*9880d681SAndroid Build Coastguard Worker 
809*9880d681SAndroid Build Coastguard Worker   bool rootDirectory = path::has_root_directory(p),
810*9880d681SAndroid Build Coastguard Worker #ifdef LLVM_ON_WIN32
811*9880d681SAndroid Build Coastguard Worker        rootName = path::has_root_name(p);
812*9880d681SAndroid Build Coastguard Worker #else
813*9880d681SAndroid Build Coastguard Worker        rootName = true;
814*9880d681SAndroid Build Coastguard Worker #endif
815*9880d681SAndroid Build Coastguard Worker 
816*9880d681SAndroid Build Coastguard Worker   // Already absolute.
817*9880d681SAndroid Build Coastguard Worker   if (rootName && rootDirectory)
818*9880d681SAndroid Build Coastguard Worker     return std::error_code();
819*9880d681SAndroid Build Coastguard Worker 
820*9880d681SAndroid Build Coastguard Worker   // All of the following conditions will need the current directory.
821*9880d681SAndroid Build Coastguard Worker   SmallString<128> current_dir;
822*9880d681SAndroid Build Coastguard Worker   if (use_current_directory)
823*9880d681SAndroid Build Coastguard Worker     current_directory.toVector(current_dir);
824*9880d681SAndroid Build Coastguard Worker   else if (std::error_code ec = current_path(current_dir))
825*9880d681SAndroid Build Coastguard Worker     return ec;
826*9880d681SAndroid Build Coastguard Worker 
827*9880d681SAndroid Build Coastguard Worker   // Relative path. Prepend the current directory.
828*9880d681SAndroid Build Coastguard Worker   if (!rootName && !rootDirectory) {
829*9880d681SAndroid Build Coastguard Worker     // Append path to the current directory.
830*9880d681SAndroid Build Coastguard Worker     path::append(current_dir, p);
831*9880d681SAndroid Build Coastguard Worker     // Set path to the result.
832*9880d681SAndroid Build Coastguard Worker     path.swap(current_dir);
833*9880d681SAndroid Build Coastguard Worker     return std::error_code();
834*9880d681SAndroid Build Coastguard Worker   }
835*9880d681SAndroid Build Coastguard Worker 
836*9880d681SAndroid Build Coastguard Worker   if (!rootName && rootDirectory) {
837*9880d681SAndroid Build Coastguard Worker     StringRef cdrn = path::root_name(current_dir);
838*9880d681SAndroid Build Coastguard Worker     SmallString<128> curDirRootName(cdrn.begin(), cdrn.end());
839*9880d681SAndroid Build Coastguard Worker     path::append(curDirRootName, p);
840*9880d681SAndroid Build Coastguard Worker     // Set path to the result.
841*9880d681SAndroid Build Coastguard Worker     path.swap(curDirRootName);
842*9880d681SAndroid Build Coastguard Worker     return std::error_code();
843*9880d681SAndroid Build Coastguard Worker   }
844*9880d681SAndroid Build Coastguard Worker 
845*9880d681SAndroid Build Coastguard Worker   if (rootName && !rootDirectory) {
846*9880d681SAndroid Build Coastguard Worker     StringRef pRootName      = path::root_name(p);
847*9880d681SAndroid Build Coastguard Worker     StringRef bRootDirectory = path::root_directory(current_dir);
848*9880d681SAndroid Build Coastguard Worker     StringRef bRelativePath  = path::relative_path(current_dir);
849*9880d681SAndroid Build Coastguard Worker     StringRef pRelativePath  = path::relative_path(p);
850*9880d681SAndroid Build Coastguard Worker 
851*9880d681SAndroid Build Coastguard Worker     SmallString<128> res;
852*9880d681SAndroid Build Coastguard Worker     path::append(res, pRootName, bRootDirectory, bRelativePath, pRelativePath);
853*9880d681SAndroid Build Coastguard Worker     path.swap(res);
854*9880d681SAndroid Build Coastguard Worker     return std::error_code();
855*9880d681SAndroid Build Coastguard Worker   }
856*9880d681SAndroid Build Coastguard Worker 
857*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("All rootName and rootDirectory combinations should have "
858*9880d681SAndroid Build Coastguard Worker                    "occurred above!");
859*9880d681SAndroid Build Coastguard Worker }
860*9880d681SAndroid Build Coastguard Worker 
make_absolute(const Twine & current_directory,SmallVectorImpl<char> & path)861*9880d681SAndroid Build Coastguard Worker std::error_code make_absolute(const Twine &current_directory,
862*9880d681SAndroid Build Coastguard Worker                               SmallVectorImpl<char> &path) {
863*9880d681SAndroid Build Coastguard Worker   return make_absolute(current_directory, path, true);
864*9880d681SAndroid Build Coastguard Worker }
865*9880d681SAndroid Build Coastguard Worker 
make_absolute(SmallVectorImpl<char> & path)866*9880d681SAndroid Build Coastguard Worker std::error_code make_absolute(SmallVectorImpl<char> &path) {
867*9880d681SAndroid Build Coastguard Worker   return make_absolute(Twine(), path, false);
868*9880d681SAndroid Build Coastguard Worker }
869*9880d681SAndroid Build Coastguard Worker 
create_directories(const Twine & Path,bool IgnoreExisting,perms Perms)870*9880d681SAndroid Build Coastguard Worker std::error_code create_directories(const Twine &Path, bool IgnoreExisting,
871*9880d681SAndroid Build Coastguard Worker                                    perms Perms) {
872*9880d681SAndroid Build Coastguard Worker   SmallString<128> PathStorage;
873*9880d681SAndroid Build Coastguard Worker   StringRef P = Path.toStringRef(PathStorage);
874*9880d681SAndroid Build Coastguard Worker 
875*9880d681SAndroid Build Coastguard Worker   // Be optimistic and try to create the directory
876*9880d681SAndroid Build Coastguard Worker   std::error_code EC = create_directory(P, IgnoreExisting, Perms);
877*9880d681SAndroid Build Coastguard Worker   // If we succeeded, or had any error other than the parent not existing, just
878*9880d681SAndroid Build Coastguard Worker   // return it.
879*9880d681SAndroid Build Coastguard Worker   if (EC != errc::no_such_file_or_directory)
880*9880d681SAndroid Build Coastguard Worker     return EC;
881*9880d681SAndroid Build Coastguard Worker 
882*9880d681SAndroid Build Coastguard Worker   // We failed because of a no_such_file_or_directory, try to create the
883*9880d681SAndroid Build Coastguard Worker   // parent.
884*9880d681SAndroid Build Coastguard Worker   StringRef Parent = path::parent_path(P);
885*9880d681SAndroid Build Coastguard Worker   if (Parent.empty())
886*9880d681SAndroid Build Coastguard Worker     return EC;
887*9880d681SAndroid Build Coastguard Worker 
888*9880d681SAndroid Build Coastguard Worker   if ((EC = create_directories(Parent, IgnoreExisting, Perms)))
889*9880d681SAndroid Build Coastguard Worker       return EC;
890*9880d681SAndroid Build Coastguard Worker 
891*9880d681SAndroid Build Coastguard Worker   return create_directory(P, IgnoreExisting, Perms);
892*9880d681SAndroid Build Coastguard Worker }
893*9880d681SAndroid Build Coastguard Worker 
copy_file(const Twine & From,const Twine & To)894*9880d681SAndroid Build Coastguard Worker std::error_code copy_file(const Twine &From, const Twine &To) {
895*9880d681SAndroid Build Coastguard Worker   int ReadFD, WriteFD;
896*9880d681SAndroid Build Coastguard Worker   if (std::error_code EC = openFileForRead(From, ReadFD))
897*9880d681SAndroid Build Coastguard Worker     return EC;
898*9880d681SAndroid Build Coastguard Worker   if (std::error_code EC = openFileForWrite(To, WriteFD, F_None)) {
899*9880d681SAndroid Build Coastguard Worker     close(ReadFD);
900*9880d681SAndroid Build Coastguard Worker     return EC;
901*9880d681SAndroid Build Coastguard Worker   }
902*9880d681SAndroid Build Coastguard Worker 
903*9880d681SAndroid Build Coastguard Worker   const size_t BufSize = 4096;
904*9880d681SAndroid Build Coastguard Worker   char *Buf = new char[BufSize];
905*9880d681SAndroid Build Coastguard Worker   int BytesRead = 0, BytesWritten = 0;
906*9880d681SAndroid Build Coastguard Worker   for (;;) {
907*9880d681SAndroid Build Coastguard Worker     BytesRead = read(ReadFD, Buf, BufSize);
908*9880d681SAndroid Build Coastguard Worker     if (BytesRead <= 0)
909*9880d681SAndroid Build Coastguard Worker       break;
910*9880d681SAndroid Build Coastguard Worker     while (BytesRead) {
911*9880d681SAndroid Build Coastguard Worker       BytesWritten = write(WriteFD, Buf, BytesRead);
912*9880d681SAndroid Build Coastguard Worker       if (BytesWritten < 0)
913*9880d681SAndroid Build Coastguard Worker         break;
914*9880d681SAndroid Build Coastguard Worker       BytesRead -= BytesWritten;
915*9880d681SAndroid Build Coastguard Worker     }
916*9880d681SAndroid Build Coastguard Worker     if (BytesWritten < 0)
917*9880d681SAndroid Build Coastguard Worker       break;
918*9880d681SAndroid Build Coastguard Worker   }
919*9880d681SAndroid Build Coastguard Worker   close(ReadFD);
920*9880d681SAndroid Build Coastguard Worker   close(WriteFD);
921*9880d681SAndroid Build Coastguard Worker   delete[] Buf;
922*9880d681SAndroid Build Coastguard Worker 
923*9880d681SAndroid Build Coastguard Worker   if (BytesRead < 0 || BytesWritten < 0)
924*9880d681SAndroid Build Coastguard Worker     return std::error_code(errno, std::generic_category());
925*9880d681SAndroid Build Coastguard Worker   return std::error_code();
926*9880d681SAndroid Build Coastguard Worker }
927*9880d681SAndroid Build Coastguard Worker 
exists(file_status status)928*9880d681SAndroid Build Coastguard Worker bool exists(file_status status) {
929*9880d681SAndroid Build Coastguard Worker   return status_known(status) && status.type() != file_type::file_not_found;
930*9880d681SAndroid Build Coastguard Worker }
931*9880d681SAndroid Build Coastguard Worker 
status_known(file_status s)932*9880d681SAndroid Build Coastguard Worker bool status_known(file_status s) {
933*9880d681SAndroid Build Coastguard Worker   return s.type() != file_type::status_error;
934*9880d681SAndroid Build Coastguard Worker }
935*9880d681SAndroid Build Coastguard Worker 
is_directory(file_status status)936*9880d681SAndroid Build Coastguard Worker bool is_directory(file_status status) {
937*9880d681SAndroid Build Coastguard Worker   return status.type() == file_type::directory_file;
938*9880d681SAndroid Build Coastguard Worker }
939*9880d681SAndroid Build Coastguard Worker 
is_directory(const Twine & path,bool & result)940*9880d681SAndroid Build Coastguard Worker std::error_code is_directory(const Twine &path, bool &result) {
941*9880d681SAndroid Build Coastguard Worker   file_status st;
942*9880d681SAndroid Build Coastguard Worker   if (std::error_code ec = status(path, st))
943*9880d681SAndroid Build Coastguard Worker     return ec;
944*9880d681SAndroid Build Coastguard Worker   result = is_directory(st);
945*9880d681SAndroid Build Coastguard Worker   return std::error_code();
946*9880d681SAndroid Build Coastguard Worker }
947*9880d681SAndroid Build Coastguard Worker 
is_regular_file(file_status status)948*9880d681SAndroid Build Coastguard Worker bool is_regular_file(file_status status) {
949*9880d681SAndroid Build Coastguard Worker   return status.type() == file_type::regular_file;
950*9880d681SAndroid Build Coastguard Worker }
951*9880d681SAndroid Build Coastguard Worker 
is_regular_file(const Twine & path,bool & result)952*9880d681SAndroid Build Coastguard Worker std::error_code is_regular_file(const Twine &path, bool &result) {
953*9880d681SAndroid Build Coastguard Worker   file_status st;
954*9880d681SAndroid Build Coastguard Worker   if (std::error_code ec = status(path, st))
955*9880d681SAndroid Build Coastguard Worker     return ec;
956*9880d681SAndroid Build Coastguard Worker   result = is_regular_file(st);
957*9880d681SAndroid Build Coastguard Worker   return std::error_code();
958*9880d681SAndroid Build Coastguard Worker }
959*9880d681SAndroid Build Coastguard Worker 
is_other(file_status status)960*9880d681SAndroid Build Coastguard Worker bool is_other(file_status status) {
961*9880d681SAndroid Build Coastguard Worker   return exists(status) &&
962*9880d681SAndroid Build Coastguard Worker          !is_regular_file(status) &&
963*9880d681SAndroid Build Coastguard Worker          !is_directory(status);
964*9880d681SAndroid Build Coastguard Worker }
965*9880d681SAndroid Build Coastguard Worker 
is_other(const Twine & Path,bool & Result)966*9880d681SAndroid Build Coastguard Worker std::error_code is_other(const Twine &Path, bool &Result) {
967*9880d681SAndroid Build Coastguard Worker   file_status FileStatus;
968*9880d681SAndroid Build Coastguard Worker   if (std::error_code EC = status(Path, FileStatus))
969*9880d681SAndroid Build Coastguard Worker     return EC;
970*9880d681SAndroid Build Coastguard Worker   Result = is_other(FileStatus);
971*9880d681SAndroid Build Coastguard Worker   return std::error_code();
972*9880d681SAndroid Build Coastguard Worker }
973*9880d681SAndroid Build Coastguard Worker 
replace_filename(const Twine & filename,file_status st)974*9880d681SAndroid Build Coastguard Worker void directory_entry::replace_filename(const Twine &filename, file_status st) {
975*9880d681SAndroid Build Coastguard Worker   SmallString<128> path = path::parent_path(Path);
976*9880d681SAndroid Build Coastguard Worker   path::append(path, filename);
977*9880d681SAndroid Build Coastguard Worker   Path = path.str();
978*9880d681SAndroid Build Coastguard Worker   Status = st;
979*9880d681SAndroid Build Coastguard Worker }
980*9880d681SAndroid Build Coastguard Worker 
981*9880d681SAndroid Build Coastguard Worker /// @brief Identify the magic in magic.
identify_magic(StringRef Magic)982*9880d681SAndroid Build Coastguard Worker file_magic identify_magic(StringRef Magic) {
983*9880d681SAndroid Build Coastguard Worker   if (Magic.size() < 4)
984*9880d681SAndroid Build Coastguard Worker     return file_magic::unknown;
985*9880d681SAndroid Build Coastguard Worker   switch ((unsigned char)Magic[0]) {
986*9880d681SAndroid Build Coastguard Worker     case 0x00: {
987*9880d681SAndroid Build Coastguard Worker       // COFF bigobj or short import library file
988*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == (char)0x00 && Magic[2] == (char)0xff &&
989*9880d681SAndroid Build Coastguard Worker           Magic[3] == (char)0xff) {
990*9880d681SAndroid Build Coastguard Worker         size_t MinSize = offsetof(COFF::BigObjHeader, UUID) + sizeof(COFF::BigObjMagic);
991*9880d681SAndroid Build Coastguard Worker         if (Magic.size() < MinSize)
992*9880d681SAndroid Build Coastguard Worker           return file_magic::coff_import_library;
993*9880d681SAndroid Build Coastguard Worker 
994*9880d681SAndroid Build Coastguard Worker         int BigObjVersion = read16le(
995*9880d681SAndroid Build Coastguard Worker             Magic.data() + offsetof(COFF::BigObjHeader, Version));
996*9880d681SAndroid Build Coastguard Worker         if (BigObjVersion < COFF::BigObjHeader::MinBigObjectVersion)
997*9880d681SAndroid Build Coastguard Worker           return file_magic::coff_import_library;
998*9880d681SAndroid Build Coastguard Worker 
999*9880d681SAndroid Build Coastguard Worker         const char *Start = Magic.data() + offsetof(COFF::BigObjHeader, UUID);
1000*9880d681SAndroid Build Coastguard Worker         if (memcmp(Start, COFF::BigObjMagic, sizeof(COFF::BigObjMagic)) != 0)
1001*9880d681SAndroid Build Coastguard Worker           return file_magic::coff_import_library;
1002*9880d681SAndroid Build Coastguard Worker         return file_magic::coff_object;
1003*9880d681SAndroid Build Coastguard Worker       }
1004*9880d681SAndroid Build Coastguard Worker       // Windows resource file
1005*9880d681SAndroid Build Coastguard Worker       const char Expected[] = { 0, 0, 0, 0, '\x20', 0, 0, 0, '\xff' };
1006*9880d681SAndroid Build Coastguard Worker       if (Magic.size() >= sizeof(Expected) &&
1007*9880d681SAndroid Build Coastguard Worker           memcmp(Magic.data(), Expected, sizeof(Expected)) == 0)
1008*9880d681SAndroid Build Coastguard Worker         return file_magic::windows_resource;
1009*9880d681SAndroid Build Coastguard Worker       // 0x0000 = COFF unknown machine type
1010*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == 0)
1011*9880d681SAndroid Build Coastguard Worker         return file_magic::coff_object;
1012*9880d681SAndroid Build Coastguard Worker       break;
1013*9880d681SAndroid Build Coastguard Worker     }
1014*9880d681SAndroid Build Coastguard Worker     case 0xDE:  // 0x0B17C0DE = BC wraper
1015*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == (char)0xC0 && Magic[2] == (char)0x17 &&
1016*9880d681SAndroid Build Coastguard Worker           Magic[3] == (char)0x0B)
1017*9880d681SAndroid Build Coastguard Worker         return file_magic::bitcode;
1018*9880d681SAndroid Build Coastguard Worker       break;
1019*9880d681SAndroid Build Coastguard Worker     case 'B':
1020*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == 'C' && Magic[2] == (char)0xC0 && Magic[3] == (char)0xDE)
1021*9880d681SAndroid Build Coastguard Worker         return file_magic::bitcode;
1022*9880d681SAndroid Build Coastguard Worker       break;
1023*9880d681SAndroid Build Coastguard Worker     case '!':
1024*9880d681SAndroid Build Coastguard Worker       if (Magic.size() >= 8)
1025*9880d681SAndroid Build Coastguard Worker         if (memcmp(Magic.data(), "!<arch>\n", 8) == 0 ||
1026*9880d681SAndroid Build Coastguard Worker             memcmp(Magic.data(), "!<thin>\n", 8) == 0)
1027*9880d681SAndroid Build Coastguard Worker           return file_magic::archive;
1028*9880d681SAndroid Build Coastguard Worker       break;
1029*9880d681SAndroid Build Coastguard Worker 
1030*9880d681SAndroid Build Coastguard Worker     case '\177':
1031*9880d681SAndroid Build Coastguard Worker       if (Magic.size() >= 18 && Magic[1] == 'E' && Magic[2] == 'L' &&
1032*9880d681SAndroid Build Coastguard Worker           Magic[3] == 'F') {
1033*9880d681SAndroid Build Coastguard Worker         bool Data2MSB = Magic[5] == 2;
1034*9880d681SAndroid Build Coastguard Worker         unsigned high = Data2MSB ? 16 : 17;
1035*9880d681SAndroid Build Coastguard Worker         unsigned low  = Data2MSB ? 17 : 16;
1036*9880d681SAndroid Build Coastguard Worker         if (Magic[high] == 0)
1037*9880d681SAndroid Build Coastguard Worker           switch (Magic[low]) {
1038*9880d681SAndroid Build Coastguard Worker             default: return file_magic::elf;
1039*9880d681SAndroid Build Coastguard Worker             case 1: return file_magic::elf_relocatable;
1040*9880d681SAndroid Build Coastguard Worker             case 2: return file_magic::elf_executable;
1041*9880d681SAndroid Build Coastguard Worker             case 3: return file_magic::elf_shared_object;
1042*9880d681SAndroid Build Coastguard Worker             case 4: return file_magic::elf_core;
1043*9880d681SAndroid Build Coastguard Worker           }
1044*9880d681SAndroid Build Coastguard Worker         else
1045*9880d681SAndroid Build Coastguard Worker           // It's still some type of ELF file.
1046*9880d681SAndroid Build Coastguard Worker           return file_magic::elf;
1047*9880d681SAndroid Build Coastguard Worker       }
1048*9880d681SAndroid Build Coastguard Worker       break;
1049*9880d681SAndroid Build Coastguard Worker 
1050*9880d681SAndroid Build Coastguard Worker     case 0xCA:
1051*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == char(0xFE) && Magic[2] == char(0xBA) &&
1052*9880d681SAndroid Build Coastguard Worker           (Magic[3] == char(0xBE) || Magic[3] == char(0xBF))) {
1053*9880d681SAndroid Build Coastguard Worker         // This is complicated by an overlap with Java class files.
1054*9880d681SAndroid Build Coastguard Worker         // See the Mach-O section in /usr/share/file/magic for details.
1055*9880d681SAndroid Build Coastguard Worker         if (Magic.size() >= 8 && Magic[7] < 43)
1056*9880d681SAndroid Build Coastguard Worker           return file_magic::macho_universal_binary;
1057*9880d681SAndroid Build Coastguard Worker       }
1058*9880d681SAndroid Build Coastguard Worker       break;
1059*9880d681SAndroid Build Coastguard Worker 
1060*9880d681SAndroid Build Coastguard Worker       // The two magic numbers for mach-o are:
1061*9880d681SAndroid Build Coastguard Worker       // 0xfeedface - 32-bit mach-o
1062*9880d681SAndroid Build Coastguard Worker       // 0xfeedfacf - 64-bit mach-o
1063*9880d681SAndroid Build Coastguard Worker     case 0xFE:
1064*9880d681SAndroid Build Coastguard Worker     case 0xCE:
1065*9880d681SAndroid Build Coastguard Worker     case 0xCF: {
1066*9880d681SAndroid Build Coastguard Worker       uint16_t type = 0;
1067*9880d681SAndroid Build Coastguard Worker       if (Magic[0] == char(0xFE) && Magic[1] == char(0xED) &&
1068*9880d681SAndroid Build Coastguard Worker           Magic[2] == char(0xFA) &&
1069*9880d681SAndroid Build Coastguard Worker           (Magic[3] == char(0xCE) || Magic[3] == char(0xCF))) {
1070*9880d681SAndroid Build Coastguard Worker         /* Native endian */
1071*9880d681SAndroid Build Coastguard Worker         size_t MinSize;
1072*9880d681SAndroid Build Coastguard Worker         if (Magic[3] == char(0xCE))
1073*9880d681SAndroid Build Coastguard Worker           MinSize = sizeof(MachO::mach_header);
1074*9880d681SAndroid Build Coastguard Worker         else
1075*9880d681SAndroid Build Coastguard Worker           MinSize = sizeof(MachO::mach_header_64);
1076*9880d681SAndroid Build Coastguard Worker         if (Magic.size() >= MinSize)
1077*9880d681SAndroid Build Coastguard Worker           type = Magic[12] << 24 | Magic[13] << 12 | Magic[14] << 8 | Magic[15];
1078*9880d681SAndroid Build Coastguard Worker       } else if ((Magic[0] == char(0xCE) || Magic[0] == char(0xCF)) &&
1079*9880d681SAndroid Build Coastguard Worker                  Magic[1] == char(0xFA) && Magic[2] == char(0xED) &&
1080*9880d681SAndroid Build Coastguard Worker                  Magic[3] == char(0xFE)) {
1081*9880d681SAndroid Build Coastguard Worker         /* Reverse endian */
1082*9880d681SAndroid Build Coastguard Worker         size_t MinSize;
1083*9880d681SAndroid Build Coastguard Worker         if (Magic[0] == char(0xCE))
1084*9880d681SAndroid Build Coastguard Worker           MinSize = sizeof(MachO::mach_header);
1085*9880d681SAndroid Build Coastguard Worker         else
1086*9880d681SAndroid Build Coastguard Worker           MinSize = sizeof(MachO::mach_header_64);
1087*9880d681SAndroid Build Coastguard Worker         if (Magic.size() >= MinSize)
1088*9880d681SAndroid Build Coastguard Worker           type = Magic[15] << 24 | Magic[14] << 12 |Magic[13] << 8 | Magic[12];
1089*9880d681SAndroid Build Coastguard Worker       }
1090*9880d681SAndroid Build Coastguard Worker       switch (type) {
1091*9880d681SAndroid Build Coastguard Worker         default: break;
1092*9880d681SAndroid Build Coastguard Worker         case 1: return file_magic::macho_object;
1093*9880d681SAndroid Build Coastguard Worker         case 2: return file_magic::macho_executable;
1094*9880d681SAndroid Build Coastguard Worker         case 3: return file_magic::macho_fixed_virtual_memory_shared_lib;
1095*9880d681SAndroid Build Coastguard Worker         case 4: return file_magic::macho_core;
1096*9880d681SAndroid Build Coastguard Worker         case 5: return file_magic::macho_preload_executable;
1097*9880d681SAndroid Build Coastguard Worker         case 6: return file_magic::macho_dynamically_linked_shared_lib;
1098*9880d681SAndroid Build Coastguard Worker         case 7: return file_magic::macho_dynamic_linker;
1099*9880d681SAndroid Build Coastguard Worker         case 8: return file_magic::macho_bundle;
1100*9880d681SAndroid Build Coastguard Worker         case 9: return file_magic::macho_dynamically_linked_shared_lib_stub;
1101*9880d681SAndroid Build Coastguard Worker         case 10: return file_magic::macho_dsym_companion;
1102*9880d681SAndroid Build Coastguard Worker         case 11: return file_magic::macho_kext_bundle;
1103*9880d681SAndroid Build Coastguard Worker       }
1104*9880d681SAndroid Build Coastguard Worker       break;
1105*9880d681SAndroid Build Coastguard Worker     }
1106*9880d681SAndroid Build Coastguard Worker     case 0xF0: // PowerPC Windows
1107*9880d681SAndroid Build Coastguard Worker     case 0x83: // Alpha 32-bit
1108*9880d681SAndroid Build Coastguard Worker     case 0x84: // Alpha 64-bit
1109*9880d681SAndroid Build Coastguard Worker     case 0x66: // MPS R4000 Windows
1110*9880d681SAndroid Build Coastguard Worker     case 0x50: // mc68K
1111*9880d681SAndroid Build Coastguard Worker     case 0x4c: // 80386 Windows
1112*9880d681SAndroid Build Coastguard Worker     case 0xc4: // ARMNT Windows
1113*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == 0x01)
1114*9880d681SAndroid Build Coastguard Worker         return file_magic::coff_object;
1115*9880d681SAndroid Build Coastguard Worker 
1116*9880d681SAndroid Build Coastguard Worker     case 0x90: // PA-RISC Windows
1117*9880d681SAndroid Build Coastguard Worker     case 0x68: // mc68K Windows
1118*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == 0x02)
1119*9880d681SAndroid Build Coastguard Worker         return file_magic::coff_object;
1120*9880d681SAndroid Build Coastguard Worker       break;
1121*9880d681SAndroid Build Coastguard Worker 
1122*9880d681SAndroid Build Coastguard Worker     case 'M': // Possible MS-DOS stub on Windows PE file
1123*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == 'Z') {
1124*9880d681SAndroid Build Coastguard Worker         uint32_t off = read32le(Magic.data() + 0x3c);
1125*9880d681SAndroid Build Coastguard Worker         // PE/COFF file, either EXE or DLL.
1126*9880d681SAndroid Build Coastguard Worker         if (off < Magic.size() &&
1127*9880d681SAndroid Build Coastguard Worker             memcmp(Magic.data()+off, COFF::PEMagic, sizeof(COFF::PEMagic)) == 0)
1128*9880d681SAndroid Build Coastguard Worker           return file_magic::pecoff_executable;
1129*9880d681SAndroid Build Coastguard Worker       }
1130*9880d681SAndroid Build Coastguard Worker       break;
1131*9880d681SAndroid Build Coastguard Worker 
1132*9880d681SAndroid Build Coastguard Worker     case 0x64: // x86-64 Windows.
1133*9880d681SAndroid Build Coastguard Worker       if (Magic[1] == char(0x86))
1134*9880d681SAndroid Build Coastguard Worker         return file_magic::coff_object;
1135*9880d681SAndroid Build Coastguard Worker       break;
1136*9880d681SAndroid Build Coastguard Worker 
1137*9880d681SAndroid Build Coastguard Worker     default:
1138*9880d681SAndroid Build Coastguard Worker       break;
1139*9880d681SAndroid Build Coastguard Worker   }
1140*9880d681SAndroid Build Coastguard Worker   return file_magic::unknown;
1141*9880d681SAndroid Build Coastguard Worker }
1142*9880d681SAndroid Build Coastguard Worker 
identify_magic(const Twine & Path,file_magic & Result)1143*9880d681SAndroid Build Coastguard Worker std::error_code identify_magic(const Twine &Path, file_magic &Result) {
1144*9880d681SAndroid Build Coastguard Worker   int FD;
1145*9880d681SAndroid Build Coastguard Worker   if (std::error_code EC = openFileForRead(Path, FD))
1146*9880d681SAndroid Build Coastguard Worker     return EC;
1147*9880d681SAndroid Build Coastguard Worker 
1148*9880d681SAndroid Build Coastguard Worker   char Buffer[32];
1149*9880d681SAndroid Build Coastguard Worker   int Length = read(FD, Buffer, sizeof(Buffer));
1150*9880d681SAndroid Build Coastguard Worker   if (close(FD) != 0 || Length < 0)
1151*9880d681SAndroid Build Coastguard Worker     return std::error_code(errno, std::generic_category());
1152*9880d681SAndroid Build Coastguard Worker 
1153*9880d681SAndroid Build Coastguard Worker   Result = identify_magic(StringRef(Buffer, Length));
1154*9880d681SAndroid Build Coastguard Worker   return std::error_code();
1155*9880d681SAndroid Build Coastguard Worker }
1156*9880d681SAndroid Build Coastguard Worker 
status(file_status & result) const1157*9880d681SAndroid Build Coastguard Worker std::error_code directory_entry::status(file_status &result) const {
1158*9880d681SAndroid Build Coastguard Worker   return fs::status(Path, result);
1159*9880d681SAndroid Build Coastguard Worker }
1160*9880d681SAndroid Build Coastguard Worker 
1161*9880d681SAndroid Build Coastguard Worker } // end namespace fs
1162*9880d681SAndroid Build Coastguard Worker } // end namespace sys
1163*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
1164*9880d681SAndroid Build Coastguard Worker 
1165*9880d681SAndroid Build Coastguard Worker // Include the truly platform-specific parts.
1166*9880d681SAndroid Build Coastguard Worker #if defined(LLVM_ON_UNIX)
1167*9880d681SAndroid Build Coastguard Worker #include "Unix/Path.inc"
1168*9880d681SAndroid Build Coastguard Worker #endif
1169*9880d681SAndroid Build Coastguard Worker #if defined(LLVM_ON_WIN32)
1170*9880d681SAndroid Build Coastguard Worker #include "Windows/Path.inc"
1171*9880d681SAndroid Build Coastguard Worker #endif
1172*9880d681SAndroid Build Coastguard Worker 
1173*9880d681SAndroid Build Coastguard Worker namespace llvm {
1174*9880d681SAndroid Build Coastguard Worker namespace sys {
1175*9880d681SAndroid Build Coastguard Worker namespace path {
1176*9880d681SAndroid Build Coastguard Worker 
user_cache_directory(SmallVectorImpl<char> & Result,const Twine & Path1,const Twine & Path2,const Twine & Path3)1177*9880d681SAndroid Build Coastguard Worker bool user_cache_directory(SmallVectorImpl<char> &Result, const Twine &Path1,
1178*9880d681SAndroid Build Coastguard Worker                           const Twine &Path2, const Twine &Path3) {
1179*9880d681SAndroid Build Coastguard Worker   if (getUserCacheDir(Result)) {
1180*9880d681SAndroid Build Coastguard Worker     append(Result, Path1, Path2, Path3);
1181*9880d681SAndroid Build Coastguard Worker     return true;
1182*9880d681SAndroid Build Coastguard Worker   }
1183*9880d681SAndroid Build Coastguard Worker   return false;
1184*9880d681SAndroid Build Coastguard Worker }
1185*9880d681SAndroid Build Coastguard Worker 
1186*9880d681SAndroid Build Coastguard Worker } // end namespace path
1187*9880d681SAndroid Build Coastguard Worker } // end namsspace sys
1188*9880d681SAndroid Build Coastguard Worker } // end namespace llvm
1189