1b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===-- Path.cpp - Implement OS Path Concept --------------------*- C++ -*-===//
2f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman//
3b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//                     The LLVM Compiler Infrastructure
4b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman//
8b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===----------------------------------------------------------------------===//
9b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//
10b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//  This header file implements the operating system Path concept.
11b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//
12b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===----------------------------------------------------------------------===//
138e66595512b065b69d595bae665b6ad665eca6d0Reid Spencer
141f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/Path.h"
1528f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer#include "llvm/Support/FileSystem.h"
1679fc9249574cee0ec69d920e5a16497ba799020aReid Spencer#include "llvm/Config/config.h"
1754453f2978c76b3aa71be7bb4e9657c8539f8648Michael J. Spencer#include "llvm/Support/FileSystem.h"
18539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher#include "llvm/Support/Endian.h"
1998bc8ed49be09c282e2f0f679fcce382f62390dcAlkis Evlogimenos#include <cassert>
20f52e32aab0422407cc8def93348667c255bb5d80Duncan Sands#include <cstring>
21c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattner#include <ostream>
22c67dc457ceb543f00d2d67e857c1d6f25371378aChris Lattnerusing namespace llvm;
238e66595512b065b69d595bae665b6ad665eca6d0Reid Spencerusing namespace sys;
24539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christophernamespace {
25539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopherusing support::ulittle32_t;
26539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher}
27b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer
28b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===----------------------------------------------------------------------===//
29b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//=== WARNING: Implementation here must contain only TRULY operating system
30f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman//===          independent code.
31b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer//===----------------------------------------------------------------------===//
32b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer
3340db5d4539144aa086b60685a4dae324972fb23fBill Wendlingbool Path::operator==(const Path &that) const {
3440db5d4539144aa086b60685a4dae324972fb23fBill Wendling  return path == that.path;
3540db5d4539144aa086b60685a4dae324972fb23fBill Wendling}
3640db5d4539144aa086b60685a4dae324972fb23fBill Wendling
3740db5d4539144aa086b60685a4dae324972fb23fBill Wendlingbool Path::operator<(const Path& that) const {
3840db5d4539144aa086b60685a4dae324972fb23fBill Wendling  return path < that.path;
3940db5d4539144aa086b60685a4dae324972fb23fBill Wendling}
4040db5d4539144aa086b60685a4dae324972fb23fBill Wendling
41f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha BrukmanLLVMFileType
426fa6a32e4e2fdbb77c82fd7f64a7232cdcac994eChris Lattnersys::IdentifyFileType(const char *magic, unsigned length) {
43f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer  assert(magic && "Invalid magic number string");
44f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer  assert(length >=4 && "Invalid magic number length");
454cdc44c82c4415b467760065fed146f73933c67bTorok Edwin  switch ((unsigned char)magic[0]) {
466fa6a32e4e2fdbb77c82fd7f64a7232cdcac994eChris Lattner    case 0xDE:  // 0x0B17C0DE = BC wraper
476fa6a32e4e2fdbb77c82fd7f64a7232cdcac994eChris Lattner      if (magic[1] == (char)0xC0 && magic[2] == (char)0x17 &&
486fa6a32e4e2fdbb77c82fd7f64a7232cdcac994eChris Lattner          magic[3] == (char)0x0B)
496fa6a32e4e2fdbb77c82fd7f64a7232cdcac994eChris Lattner        return Bitcode_FileType;
506fa6a32e4e2fdbb77c82fd7f64a7232cdcac994eChris Lattner      break;
51f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner    case 'B':
52f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner      if (magic[1] == 'C' && magic[2] == (char)0xC0 && magic[3] == (char)0xDE)
53f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner        return Bitcode_FileType;
54f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner      break;
55f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer    case '!':
568bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer      if (length >= 8)
57f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer        if (memcmp(magic,"!<arch>\n",8) == 0)
588bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer          return Archive_FileType;
598bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer      break;
604a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
618bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case '\177':
6224eac6cb00ab18afe7a175ea876bbde776c07532Chris Lattner      if (magic[1] == 'E' && magic[2] == 'L' && magic[3] == 'F') {
63b935cd15142491bdee9baff00db8d63c18d402dbMeador Inge        bool Data2MSB = magic[5] == 2;
64b935cd15142491bdee9baff00db8d63c18d402dbMeador Inge        unsigned high = Data2MSB ? 16 : 17;
65b935cd15142491bdee9baff00db8d63c18d402dbMeador Inge        unsigned low  = Data2MSB ? 17 : 16;
66b935cd15142491bdee9baff00db8d63c18d402dbMeador Inge        if (length >= 18 && magic[high] == 0)
67b935cd15142491bdee9baff00db8d63c18d402dbMeador Inge          switch (magic[low]) {
68947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer            default: break;
69947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer            case 1: return ELF_Relocatable_FileType;
70947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer            case 2: return ELF_Executable_FileType;
71947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer            case 3: return ELF_SharedObject_FileType;
72947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer            case 4: return ELF_Core_FileType;
73947aa7de67c553a0bbf0ef60173f23a8747014bfReid Spencer          }
7424eac6cb00ab18afe7a175ea876bbde776c07532Chris Lattner      }
758bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer      break;
768bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer
77ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner    case 0xCA:
784a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer      if (magic[1] == char(0xFE) && magic[2] == char(0xBA) &&
79ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner          magic[3] == char(0xBE)) {
804a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer        // This is complicated by an overlap with Java class files.
81652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        // See the Mach-O section in /usr/share/file/magic for details.
824a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer        if (length >= 8 && magic[7] < 43)
83652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner          // FIXME: Universal Binary of any type.
84652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner          return Mach_O_DynamicallyLinkedSharedLib_FileType;
85652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner      }
86652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner      break;
87652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner
88f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher      // The two magic numbers for mach-o are:
89f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher      // 0xfeedface - 32-bit mach-o
90f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher      // 0xfeedfacf - 64-bit mach-o
91652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner    case 0xFE:
92f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher    case 0xCE:
93f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher    case 0xCF: {
94fc1fd54a346fe07101228d77aa20682b2b61b2ffBill Wendling      uint16_t type = 0;
954a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer      if (magic[0] == char(0xFE) && magic[1] == char(0xED) &&
96faebf11a3468767bb702b8e9fca98237f1d3a126Michael J. Spencer          magic[2] == char(0xFA) &&
97f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher          (magic[3] == char(0xCE) || magic[3] == char(0xCF))) {
98652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        /* Native endian */
99652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        if (length >= 16) type = magic[14] << 8 | magic[15];
100f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher      } else if ((magic[0] == char(0xCE) || magic[0] == char(0xCF)) &&
101f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher                 magic[1] == char(0xFA) && magic[2] == char(0xED) &&
102f0c3af637ae4d8b827909aa5b3d618eea9ef8cd6Eric Christopher                 magic[3] == char(0xFE)) {
103652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        /* Reverse endian */
104652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        if (length >= 14) type = magic[13] << 8 | magic[12];
105fc1fd54a346fe07101228d77aa20682b2b61b2ffBill Wendling      }
106652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner      switch (type) {
1074a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer        default: break;
1084a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer        case 1: return Mach_O_Object_FileType;
109652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        case 2: return Mach_O_Executable_FileType;
110652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        case 3: return Mach_O_FixedVirtualMemorySharedLib_FileType;
111652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        case 4: return Mach_O_Core_FileType;
112b1a33c4a598d67a9b911bb3b45b379e36fb9396cPeter Collingbourne        case 5: return Mach_O_PreloadExecutable_FileType;
113652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        case 6: return Mach_O_DynamicallyLinkedSharedLib_FileType;
114652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        case 7: return Mach_O_DynamicLinker_FileType;
115652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        case 8: return Mach_O_Bundle_FileType;
116652154918809b9aabeb90775fe58ecb91b1fa176Chris Lattner        case 9: return Mach_O_DynamicallyLinkedSharedLibStub_FileType;
117836623420dbf5eb3a3facde2841179ded91ab55bBenjamin Kramer        case 10: return Mach_O_DSYMCompanion_FileType;
118ade7592085cbb3d37a7cc9701c4c07c9c58a87c5Chris Lattner      }
1198bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer      break;
120fc1fd54a346fe07101228d77aa20682b2b61b2ffBill Wendling    }
1218bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case 0xF0: // PowerPC Windows
1228bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case 0x83: // Alpha 32-bit
1238bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case 0x84: // Alpha 64-bit
1248bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case 0x66: // MPS R4000 Windows
1258bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case 0x50: // mc68K
1268bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case 0x4c: // 80386 Windows
1278bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer      if (magic[1] == 0x01)
1288bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer        return COFF_FileType;
1298bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer
1308bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case 0x90: // PA-RISC Windows
1318bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer    case 0x68: // mc68K Windows
1328bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer      if (magic[1] == 0x02)
1338bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer        return COFF_FileType;
134f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer      break;
135539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
136539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher    case 0x4d: // Possible MS-DOS stub on Windows PE file
137539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher      if (magic[1] == 0x5a) {
138539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher        uint32_t off = *reinterpret_cast<const ulittle32_t *>(magic + 0x3c);
139539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher        // PE/COFF file, either EXE or DLL.
140539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher        if (off < length && memcmp(magic + off, "PE\0\0",4) == 0)
141539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher          return COFF_FileType;
142539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher      }
143539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher      break;
144539d8d8a72995d08afe7b986fe98a1dc7fec4b0aEric Christopher
1457e7d01de9c85af70dd4058358f8eb36d82c3e49fMichael J. Spencer    case 0x64: // x86-64 Windows.
1467e7d01de9c85af70dd4058358f8eb36d82c3e49fMichael J. Spencer      if (magic[1] == char(0x86))
1477e7d01de9c85af70dd4058358f8eb36d82c3e49fMichael J. Spencer        return COFF_FileType;
1487e7d01de9c85af70dd4058358f8eb36d82c3e49fMichael J. Spencer      break;
149f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer
150f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer    default:
151f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer      break;
152f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer  }
1538bb5fd17f9a715ac9ce87619f3b6c1066a244859Reid Spencer  return Unknown_FileType;
154f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer}
155f37ce99c0af5921bb0cc132350ffdf8b73cf30a7Reid Spencer
156ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencerbool
157ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid SpencerPath::isArchive() const {
1585b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  fs::file_magic type;
15928f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  if (fs::identify_magic(str(), type))
16028f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer    return false;
1615b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  return type == fs::file_magic::archive;
162ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer}
163ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer
164ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencerbool
165ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid SpencerPath::isDynamicLibrary() const {
1665b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  fs::file_magic type;
16728f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  if (fs::identify_magic(str(), type))
16828f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer    return false;
16928f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  switch (type) {
17028f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer    default: return false;
1715b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case fs::file_magic::macho_fixed_virtual_memory_shared_lib:
1725b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case fs::file_magic::macho_dynamically_linked_shared_lib:
1735b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case fs::file_magic::macho_dynamically_linked_shared_lib_stub:
1745b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case fs::file_magic::elf_shared_object:
1755b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer    case fs::file_magic::pecoff_executable:  return true;
17628f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  }
177ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer}
178ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer
1798a26f818896c6a02ebdb11d624cb9ef39f082df2Michael J. Spencerbool
1808a26f818896c6a02ebdb11d624cb9ef39f082df2Michael J. SpencerPath::isObjectFile() const {
1815b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  fs::file_magic type;
1825b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  if (fs::identify_magic(str(), type) || type == fs::file_magic::unknown)
18328f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer    return false;
18428f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  return true;
1858a26f818896c6a02ebdb11d624cb9ef39f082df2Michael J. Spencer}
1868a26f818896c6a02ebdb11d624cb9ef39f082df2Michael J. Spencer
187ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid SpencerPath
188ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid SpencerPath::FindLibrary(std::string& name) {
189ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer  std::vector<sys::Path> LibPaths;
190ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer  GetSystemLibraryPaths(LibPaths);
191ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer  for (unsigned i = 0; i < LibPaths.size(); ++i) {
192ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer    sys::Path FullPath(LibPaths[i]);
193dd04df0ec33a903ee7fc747701bafde622f77d8bReid Spencer    FullPath.appendComponent("lib" + name + LTDL_SHLIB_EXT);
194ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer    if (FullPath.isDynamicLibrary())
195ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer      return FullPath;
196dd04df0ec33a903ee7fc747701bafde622f77d8bReid Spencer    FullPath.eraseSuffix();
197ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer    FullPath.appendSuffix("a");
198ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer    if (FullPath.isArchive())
199ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer      return FullPath;
200ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer  }
201ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer  return sys::Path();
202ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer}
203ccb23a13e90c20e555ede74f30ea2ecb90e24d18Reid Spencer
20488cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey YasskinStringRef Path::GetDLLSuffix() {
205c8aef4b2ea23f7da3668f35872ee5bd8df28bcc0Mikhail Glushenkov  return &(LTDL_SHLIB_EXT[1]);
20679fc9249574cee0ec69d920e5a16497ba799020aReid Spencer}
20779fc9249574cee0ec69d920e5a16497ba799020aReid Spencer
208552a3c29dcdfaade9610a822fbfd3adc61eb1263Dan Gohmanvoid
209bd6e0323b94361559e125b07cb244629b0da0281Mikhail GlushenkovPath::appendSuffix(StringRef suffix) {
210bd6e0323b94361559e125b07cb244629b0da0281Mikhail Glushenkov  if (!suffix.empty()) {
211bd6e0323b94361559e125b07cb244629b0da0281Mikhail Glushenkov    path.append(".");
212bd6e0323b94361559e125b07cb244629b0da0281Mikhail Glushenkov    path.append(suffix);
213bd6e0323b94361559e125b07cb244629b0da0281Mikhail Glushenkov  }
214bd6e0323b94361559e125b07cb244629b0da0281Mikhail Glushenkov}
215bd6e0323b94361559e125b07cb244629b0da0281Mikhail Glushenkov
216bd6e0323b94361559e125b07cb244629b0da0281Mikhail Glushenkovbool
217f283a5e53a99d13035a9e783acff80d4ea064a92Chris LattnerPath::isBitcodeFile() const {
2185b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  fs::file_magic type;
21928f0ed5c9de4a68f34c0219d4ab83652c4647150Michael J. Spencer  if (fs::identify_magic(str(), type))
220f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner    return false;
2215b08230930ee219382f6d0abe9d16aa160907169Michael J. Spencer  return type == fs::file_magic::bitcode;
222f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner}
223f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner
22488cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskinbool Path::hasMagicNumber(StringRef Magic) const {
225f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner  std::string actualMagic;
22634cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  if (getMagicNumber(actualMagic, static_cast<unsigned>(Magic.size())))
227f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner    return Magic == actualMagic;
228f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner  return false;
229f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner}
230f283a5e53a99d13035a9e783acff80d4ea064a92Chris Lattner
231e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattnerstatic void getPathList(const char*path, std::vector<Path>& Paths) {
232e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner  const char* at = path;
233e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner  const char* delim = strchr(at, PathSeparator);
234e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner  Path tmpPath;
235e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner  while (delim != 0) {
236e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner    std::string tmp(at, size_t(delim-at));
237e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner    if (tmpPath.set(tmp))
238e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner      if (tmpPath.canRead())
239e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner        Paths.push_back(tmpPath);
240e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner    at = delim + 1;
241e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner    delim = strchr(at, PathSeparator);
242e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner  }
243e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner
244e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner  if (*at != 0)
245e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner    if (tmpPath.set(std::string(at)))
246e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner      if (tmpPath.canRead())
247e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner        Paths.push_back(tmpPath);
248e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner}
249e1b332a30459a726e882a4f484a9a31f2cea9e29Chris Lattner
25088cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskinstatic StringRef getDirnameCharSep(StringRef path, const char *Sep) {
25188cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskin  assert(Sep[0] != '\0' && Sep[1] == '\0' &&
25288cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskin         "Sep must be a 1-character string literal.");
253cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  if (path.empty())
254cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek    return ".";
2554a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
256cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  // If the path is all slashes, return a single slash.
257cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  // Otherwise, remove all trailing slashes.
2584a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
25934cd4a484e532cc463fd5a4bf59b88d13c5467c1Evan Cheng  signed pos = static_cast<signed>(path.size()) - 1;
2604a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
26188cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskin  while (pos >= 0 && path[pos] == Sep[0])
262cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek    --pos;
2634a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
264cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  if (pos < 0)
26588cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskin    return path[0] == Sep[0] ? Sep : ".";
2664a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
267cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  // Any slashes left?
268cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  signed i = 0;
2694a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
27088cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskin  while (i < pos && path[i] != Sep[0])
271cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek    ++i;
2724a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
273cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  if (i == pos) // No slashes?  Return "."
274cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek    return ".";
2754a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
2764a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer  // There is at least one slash left.  Remove all trailing non-slashes.
27788cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskin  while (pos >= 0 && path[pos] != Sep[0])
278cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek    --pos;
2794a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
280cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  // Remove any trailing slashes.
28188cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskin  while (pos >= 0 && path[pos] == Sep[0])
282cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek    --pos;
2834a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
284cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  if (pos < 0)
28588cd3582b6cb70c0283e4c5d6d783114323a1ce1Jeffrey Yasskin    return path[0] == Sep[0] ? Sep : ".";
2864a295d301d83f07ad2840abe25a1691aef481c83Michael J. Spencer
287cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek  return path.substr(0, pos+1);
288cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek}
289cf55c8e221c1d31a361f99ee49078d261cdf431cTed Kremenek
290b89a2237ea79e0576fdb426b124f1940f53da159Reid Spencer// Include the truly platform-specific parts of this class.
291dafe55f64b038445adce31fe884e453db859194cReid Spencer#if defined(LLVM_ON_UNIX)
292bccc8abc79338d1cfdd5ea20f7288452ddf75b84Reid Spencer#include "Unix/Path.inc"
293dafe55f64b038445adce31fe884e453db859194cReid Spencer#endif
294dafe55f64b038445adce31fe884e453db859194cReid Spencer#if defined(LLVM_ON_WIN32)
2951f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "Windows/Path.inc"
296dafe55f64b038445adce31fe884e453db859194cReid Spencer#endif
297