LoopVectorize: Vectorize all accesses in address space zero with unit stride
[oota-llvm.git] / tools / llvm-ar / ArchiveWriter.cpp
index 5563b564b3909eb5d03da6a83651ab6068d54467..bdccf3e0d91d1ecfef0c75feb7b2a5ac00da98d9 100644 (file)
@@ -18,7 +18,6 @@
 #include "llvm/IR/Module.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/PathV1.h"
 #include "llvm/Support/Process.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/system_error.h"
@@ -81,7 +80,7 @@ Archive* Archive::CreateEmpty(StringRef FilePath, LLVMContext& C) {
 // compressed.
 bool
 Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr,
-                    int sz, bool TruncateNames) const {
+                    int sz) const {
 
   // Set the permissions mode, uid and gid
   hdr.init();
@@ -98,13 +97,7 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr,
   sprintf(buffer,"%-12u", unsigned(secondsSinceEpoch));
   memcpy(hdr.date,buffer,12);
 
-  // Get rid of trailing blanks in the name
-  std::string mbrPath = mbr.getPath().str();
-  size_t mbrLen = mbrPath.length();
-  while (mbrLen > 0 && mbrPath[mbrLen-1] == ' ') {
-    mbrPath.erase(mbrLen-1,1);
-    mbrLen--;
-  }
+  std::string mbrPath = sys::path::filename(mbr.getPath());
 
   // Set the name field in one of its various flavors.
   bool writeLongName = false;
@@ -114,18 +107,6 @@ Archive::fillHeader(const ArchiveMember &mbr, ArchiveMemberHeader& hdr,
     memcpy(hdr.name,ARFILE_SVR4_SYMTAB_NAME,16);
   } else if (mbr.isBSD4SymbolTable()) {
     memcpy(hdr.name,ARFILE_BSD4_SYMTAB_NAME,16);
-  } else if (TruncateNames) {
-    const char* nm = mbrPath.c_str();
-    unsigned len = mbrPath.length();
-    size_t slashpos = mbrPath.rfind('/');
-    if (slashpos != std::string::npos) {
-      nm += slashpos + 1;
-      len -= slashpos +1;
-    }
-    if (len > 15)
-      len = 15;
-    memcpy(hdr.name,nm,len);
-    hdr.name[len] = '/';
   } else if (mbrPath.length() < 16 && mbrPath.find('/') == std::string::npos) {
     memcpy(hdr.name,mbrPath.c_str(),mbrPath.length());
     hdr.name[mbrPath.length()] = '/';
@@ -165,36 +146,31 @@ bool Archive::addFileBefore(StringRef filePath, iterator where,
   ArchiveMember* mbr = new ArchiveMember(this);
 
   mbr->data = 0;
-  mbr->path = filePath.str();
-  sys::PathWithStatus PWS(mbr->path);
-  const sys::FileStatus *FSInfo = PWS.getFileStatus(false, ErrMsg);
-  if (!FSInfo) {
+  mbr->path = filePath;
+  sys::fs::file_status Status;
+  error_code EC = sys::fs::status(filePath, Status);
+  if (EC) {
+    delete mbr;
+    return true;
+  }
+  mbr->User = Status.getUser();
+  mbr->Group = Status.getGroup();
+  mbr->Mode = Status.permissions();
+  mbr->ModTime = Status.getLastModificationTime();
+  // FIXME: On posix this is a second stat.
+  EC =  sys::fs::file_size(filePath, mbr->Size);
+  if (EC) {
     delete mbr;
     return true;
   }
-  mbr->User = FSInfo->getUser();
-  mbr->Group = FSInfo->getGroup();
-  mbr->Mode = FSInfo->getMode();
-  mbr->ModTime = FSInfo->getTimestamp();
-  mbr->Size = FSInfo->getSize();
 
   unsigned flags = 0;
-  bool hasSlash = filePath.str().find('/') != std::string::npos;
-  if (hasSlash)
-    flags |= ArchiveMember::HasPathFlag;
-  if (hasSlash || filePath.str().length() > 15)
+  if (sys::path::filename(filePath).size() > 15)
     flags |= ArchiveMember::HasLongFilenameFlag;
 
   sys::fs::file_magic type;
   if (sys::fs::identify_magic(mbr->path, type))
     type = sys::fs::file_magic::unknown;
-  switch (type) {
-    case sys::fs::file_magic::bitcode:
-      flags |= ArchiveMember::BitcodeFlag;
-      break;
-    default:
-      break;
-  }
   mbr->flags = flags;
   members.insert(where,mbr);
   return false;
@@ -204,12 +180,11 @@ bool Archive::addFileBefore(StringRef filePath, iterator where,
 bool
 Archive::writeMember(
   const ArchiveMember& member,
-  std::ofstream& ARFile,
-  bool TruncateNames,
+  raw_fd_ostream& ARFile,
   std::string* ErrMsg
 ) {
 
-  unsigned filepos = ARFile.tellp();
+  uint64_t filepos = ARFile.tell();
   filepos -= 8;
 
   // Get the data and its size either from the
@@ -233,22 +208,22 @@ Archive::writeMember(
 
   // Compute the fields of the header
   ArchiveMemberHeader Hdr;
-  bool writeLongName = fillHeader(member,Hdr,hdrSize,TruncateNames);
+  bool writeLongName = fillHeader(member,Hdr,hdrSize);
 
   // Write header to archive file
   ARFile.write((char*)&Hdr, sizeof(Hdr));
 
   // Write the long filename if its long
   if (writeLongName) {
-    ARFile.write(member.getPath().str().data(),
-                 member.getPath().str().length());
+    StringRef Name = sys::path::filename(member.getPath());
+    ARFile.write(Name.data(), Name.size());
   }
 
   // Write the (possibly compressed) member's content to the file.
   ARFile.write(data,fSize);
 
   // Make sure the member is an even length
-  if ((ARFile.tellp() & 1) == 1)
+  if ((ARFile.tell() & 1) == 1)
     ARFile << ARFILE_PAD;
 
   // Close the mapped file if it was opened
@@ -260,7 +235,7 @@ Archive::writeMember(
 // This writes to a temporary file first. Options are for creating a symbol
 // table, flattening the file names (no directories, 15 chars max) and
 // compressing each archive member.
-bool Archive::writeToDisk(bool TruncateNames, std::string *ErrMsg) {
+bool Archive::writeToDisk(std::string *ErrMsg) {
   // Make sure they haven't opened up the file, not loaded it,
   // but are now trying to write it which would wipe out the file.
   if (members.empty() && mapfile && mapfile->getBufferSize() > 8) {
@@ -270,25 +245,18 @@ bool Archive::writeToDisk(bool TruncateNames, std::string *ErrMsg) {
   }
 
   // Create a temporary file to store the archive in
-  sys::Path TmpArchive(archPath);
-  if (TmpArchive.createTemporaryFileOnDisk(ErrMsg))
+  int TmpArchiveFD;
+  SmallString<128> TmpArchive;
+  error_code EC = sys::fs::createUniqueFile(
+      archPath + ".temp-archive-%%%%%%%.a", TmpArchiveFD, TmpArchive);
+  if (EC)
     return true;
 
   // Make sure the temporary gets removed if we crash
-  sys::RemoveFileOnSignal(TmpArchive.str());
+  sys::RemoveFileOnSignal(TmpArchive);
 
   // Create archive file for output.
-  std::ios::openmode io_mode = std::ios::out | std::ios::trunc |
-                               std::ios::binary;
-  std::ofstream ArchiveFile(TmpArchive.c_str(), io_mode);
-
-  // Check for errors opening or creating archive file.
-  if (!ArchiveFile.is_open() || ArchiveFile.bad()) {
-    TmpArchive.eraseFromDisk();
-    if (ErrMsg)
-      *ErrMsg = "Error opening archive file: " + archPath;
-    return true;
-  }
+  raw_fd_ostream ArchiveFile(TmpArchiveFD, true);
 
   // Write magic string to archive.
   ArchiveFile << ARFILE_MAGIC;
@@ -296,8 +264,8 @@ bool Archive::writeToDisk(bool TruncateNames, std::string *ErrMsg) {
   // Loop over all member files, and write them out. Note that this also
   // builds the symbol table, symTab.
   for (MembersList::iterator I = begin(), E = end(); I != E; ++I) {
-    if (writeMember(*I, ArchiveFile, TruncateNames, ErrMsg)) {
-      TmpArchive.eraseFromDisk();
+    if (writeMember(*I, ArchiveFile, ErrMsg)) {
+      sys::fs::remove(Twine(TmpArchive));
       ArchiveFile.close();
       return true;
     }
@@ -311,15 +279,10 @@ bool Archive::writeToDisk(bool TruncateNames, std::string *ErrMsg) {
   // this because we cannot replace an open file on Windows.
   cleanUpMemory();
 
-  if (TmpArchive.renamePathOnDisk(sys::Path(archPath), ErrMsg))
-    return true;
-
-  // Set correct read and write permissions after temporary file is moved
-  // to final destination path.
-  if (sys::Path(archPath).makeReadableOnDisk(ErrMsg))
-    return true;
-  if (sys::Path(archPath).makeWriteableOnDisk(ErrMsg))
+  if (sys::fs::rename(Twine(TmpArchive), archPath)) {
+    *ErrMsg = EC.message();
     return true;
+  }
 
   return false;
 }