For PR797:
[oota-llvm.git] / lib / Bytecode / Archive / Archive.cpp
index 8f3850cf7a1613d1795386ff7627b556238f24cc..a661a4e992a449cdaa0edc9364b789f5fe911cd2 100644 (file)
@@ -39,7 +39,7 @@ ArchiveMember::getMemberSize() const {
 // This default constructor is only use by the ilist when it creates its
 // sentry node. We give it specific static values to make it stand out a bit.
 ArchiveMember::ArchiveMember()
-  : next(0), prev(0), parent(0), path("<invalid>"), flags(0), data(0)
+  : next(0), prev(0), parent(0), path("--invalid--"), flags(0), data(0)
 {
   info.user = sys::Process::GetCurrentUserId();
   info.group = sys::Process::GetCurrentGroupId();
@@ -61,7 +61,7 @@ ArchiveMember::ArchiveMember(Archive* PAR)
 // This method allows an ArchiveMember to be replaced with the data for a
 // different file, presumably as an update to the member. It also makes sure
 // the flags are reset correctly.
-void ArchiveMember::replaceWith(const sys::Path& newFile) {
+bool ArchiveMember::replaceWith(const sys::Path& newFile, std::string* ErrMsg) {
   assert(newFile.exists() && "Can't replace with a non-existent file");
   data = 0;
   path = newFile;
@@ -104,12 +104,14 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) {
     flags &= ~HasLongFilenameFlag;
 
   // Get the signature and status info
-  std::string magic;
   const char* signature = (const char*) data;
+  std::string magic;
   if (!signature) {
     path.getMagicNumber(magic,4);
     signature = magic.c_str();
-    path.getStatusInfo(info);
+    std::string err;
+    if (path.getFileStatus(info, ErrMsg))
+      return true;
   }
 
   // Determine what kind of file it is
@@ -125,28 +127,51 @@ void ArchiveMember::replaceWith(const sys::Path& newFile) {
       flags &= ~(BytecodeFlag|CompressedBytecodeFlag);
       break;
   }
+  return false;
 }
 
 // Archive constructor - this is the only constructor that gets used for the
 // Archive class. Everything else (default,copy) is deprecated. This just
 // initializes and maps the file into memory, if requested.
-Archive::Archive(const sys::Path& filename, bool map )
+Archive::Archive(const sys::Path& filename)
   : archPath(filename), members(), mapfile(0), base(0), symTab(), strtab(),
     symTabSize(0), firstFileOffset(0), modules(), foreignST(0)
 {
-  if (map) {
-    mapfile = new sys::MappedFile(filename);
-    base = (char*) mapfile->map();
-  }
 }
 
-// Archive destructor - just clean up memory
-Archive::~Archive() {
+bool
+Archive::mapToMemory(std::string* ErrMsg)
+{
+  mapfile = new sys::MappedFile();
+  if (mapfile->open(archPath, sys::MappedFile::READ_ACCESS, ErrMsg))
+    return true;
+  if (!(base = (char*) mapfile->map(ErrMsg)))
+    return true;
+  return false;
+}
+
+void Archive::cleanUpMemory() {
   // Shutdown the file mapping
   if (mapfile) {
     mapfile->close();
     delete mapfile;
+    
+    mapfile = 0;
+    base = 0;
+  }
+  
+  // Forget the entire symbol table
+  symTab.clear();
+  symTabSize = 0;
+  
+  firstFileOffset = 0;
+  
+  // Free the foreign symbol table member
+  if (foreignST) {
+    delete foreignST;
+    foreignST = 0;
   }
+  
   // Delete any ModuleProviders and ArchiveMember's we've allocated as a result
   // of symbol table searches.
   for (ModuleMap::iterator I=modules.begin(), E=modules.end(); I != E; ++I ) {
@@ -155,4 +180,8 @@ Archive::~Archive() {
   }
 }
 
-// vim: sw=2 ai
+// Archive destructor - just clean up memory
+Archive::~Archive() {
+  cleanUpMemory();
+}
+