Index: COFF/DriverUtils.cpp =================================================================== --- COFF/DriverUtils.cpp +++ COFF/DriverUtils.cpp @@ -279,18 +279,35 @@ } } +// An RAII temporary file class that automatically removes a temporary file. +namespace { +class TemporaryFile { +public: + explicit TemporaryFile(StringRef Extn) { + SmallString<128> S; + if (auto EC = sys::fs::createTemporaryFile("tmp", Extn, S)) + fatal(EC, "cannot create a temporary file"); + Path = S.str(); + } + + TemporaryFile(TemporaryFile &&Obj) { Path = std::move(Obj.Path); } + + ~TemporaryFile() { sys::fs::remove(Path); } + + std::string Path; +}; +} + // Create the default manifest file as a temporary file. -static std::string createDefaultXml() { +TemporaryFile createDefaultXml() { // Create a temporary file. - SmallString<128> Path; - if (auto EC = sys::fs::createTemporaryFile("tmp", "manifest", Path)) - fatal(EC, "cannot create a temporary file"); + TemporaryFile File("manifest"); // Open the temporary file for writing. std::error_code EC; - llvm::raw_fd_ostream OS(Path, EC, sys::fs::F_Text); + llvm::raw_fd_ostream OS(File.Path, EC, sys::fs::F_Text); if (EC) - fatal(EC, "failed to open " + Path); + fatal(EC, "failed to open " + File.Path); // Emit the XML. Note that we do *not* verify that the XML attributes are // syntactically correct. This is intentional for link.exe compatibility. @@ -316,7 +333,7 @@ } OS << "\n"; OS.close(); - return StringRef(Path); + return File; } static std::string readFile(StringRef Path) { @@ -328,44 +345,37 @@ static std::string createManifestXml() { // Create the default manifest file. - std::string Path1 = createDefaultXml(); + TemporaryFile File1 = createDefaultXml(); if (Config->ManifestInput.empty()) - return readFile(Path1); + return readFile(File1.Path); // If manifest files are supplied by the user using /MANIFESTINPUT // option, we need to merge them with the default manifest. - SmallString<128> Path2; - if (auto EC = sys::fs::createTemporaryFile("tmp", "manifest", Path2)) - fatal(EC, "cannot create a temporary file"); - FileRemover Remover1(Path1); - FileRemover Remover2(Path2); + TemporaryFile File2("manifest"); Executor E("mt.exe"); E.add("/manifest"); - E.add(Path1); + E.add(File1.Path); for (StringRef Filename : Config->ManifestInput) { E.add("/manifest"); E.add(Filename); } E.add("/nologo"); - E.add("/out:" + StringRef(Path2)); + E.add("/out:" + StringRef(File2.Path)); E.run(); - return readFile(Path2); + return readFile(File2.Path); } // Create a resource file containing a manifest XML. std::unique_ptr createManifestRes() { // Create a temporary file for the resource script file. - SmallString<128> RCPath; - if (auto EC = sys::fs::createTemporaryFile("tmp", "rc", RCPath)) - fatal(EC, "cannot create a temporary file"); - FileRemover RCRemover(RCPath); + TemporaryFile RCFile("rc"); // Open the temporary file for writing. std::error_code EC; - llvm::raw_fd_ostream Out(RCPath, EC, sys::fs::F_Text); + llvm::raw_fd_ostream Out(RCFile.Path, EC, sys::fs::F_Text); if (EC) - fatal(EC, "failed to open " + RCPath); + fatal(EC, "failed to open " + RCFile.Path); // Write resource script to the RC file. Out << "#define LANG_ENGLISH 9\n" @@ -379,17 +389,16 @@ Out.close(); // Create output resource file. - SmallString<128> ResPath; - if (auto EC = sys::fs::createTemporaryFile("tmp", "res", ResPath)) - fatal(EC, "cannot create a temporary file"); + TemporaryFile ResFile("res"); Executor E("rc.exe"); E.add("/fo"); - E.add(ResPath.str()); + E.add(ResFile.Path); E.add("/nologo"); - E.add(RCPath.str()); + E.add(RCFile.Path); E.run(); - return check(MemoryBuffer::getFile(ResPath), "could not open " + ResPath); + return check(MemoryBuffer::getFile(ResFile.Path), + "could not open " + ResFile.Path); } void createSideBySideManifest() { @@ -555,20 +564,18 @@ std::unique_ptr convertResToCOFF(const std::vector &MBs) { // Create an output file path. - SmallString<128> Path; - if (auto EC = llvm::sys::fs::createTemporaryFile("resource", "obj", Path)) - fatal(EC, "could not create temporary file"); + TemporaryFile File("obj"); // Execute cvtres.exe. Executor E("cvtres.exe"); E.add("/machine:" + machineToStr(Config->Machine)); E.add("/readonly"); E.add("/nologo"); - E.add("/out:" + Path); + E.add("/out:" + Twine(File.Path)); for (MemoryBufferRef MB : MBs) E.add(MB.getBufferIdentifier()); E.run(); - return check(MemoryBuffer::getFile(Path), "could not open " + Path); + return check(MemoryBuffer::getFile(File.Path), "could not open " + File.Path); } // Create OptTable