diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 82226405a4ff346d85a99fb8422878624303e036..30ae6ffebcbc08ae60855e0cdb3194e595f67017 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -517,54 +517,66 @@ void Driver::generateCompilationDiagnostics(Compilation &C, return; } + const ArgStringList &TempFiles = C.getTempFiles(); + if (TempFiles.empty()) { + Diag(clang::diag::note_drv_command_failed_diag_msg) + << "Error generating preprocessed source(s)."; + return; + } + Diag(clang::diag::note_drv_command_failed_diag_msg) << "\n********************\n\n" "PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:\n" "Preprocessed source(s) and associated run script(s) are located at:"; - const ArgStringList &Files = C.getTempFiles(); - for (ArgStringList::const_iterator it = Files.begin(), ie = Files.end(); - it != ie; ++it) { - Diag(clang::diag::note_drv_command_failed_diag_msg) << *it; - std::string Script = StringRef(*it).rsplit('.').first; - // In some cases (modules) we'll dump extra data to help with reproducing - // the crash into a directory next to the output. - SmallString<128> VFS; - if (llvm::sys::fs::exists(Script + ".cache")) { - Diag(clang::diag::note_drv_command_failed_diag_msg) << Script + ".cache"; - VFS = llvm::sys::path::filename(Script + ".cache"); - llvm::sys::path::append(VFS, "vfs", "vfs.yaml"); - } - std::error_code EC; - Script += ".sh"; - llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::F_Excl); - if (EC) { - Diag(clang::diag::note_drv_command_failed_diag_msg) - << "Error generating run script: " + Script + " " + EC.message(); - } else { - // Replace the original filename with the preprocessed one. - size_t I, E; - I = Cmd.find("-main-file-name "); - assert(I != std::string::npos && "Expected to find -main-file-name"); - I += 16; - E = Cmd.find(" ", I); - assert(E != std::string::npos && "-main-file-name missing argument?"); - StringRef OldFilename = StringRef(Cmd).slice(I, E); - StringRef NewFilename = llvm::sys::path::filename(*it); - I = StringRef(Cmd).rfind(OldFilename); - E = I + OldFilename.size(); - if (E + 1 < Cmd.size() && Cmd[E] == '"') - ++E; // Replace a trailing quote if present. - I = Cmd.rfind(" ", I) + 1; - Cmd.replace(I, E - I, NewFilename.data(), NewFilename.size()); - if (!VFS.empty()) { - // Add the VFS overlay to the reproduction script. - I += NewFilename.size(); - Cmd.insert(I, std::string(" -ivfsoverlay ") + VFS.c_str()); - } - ScriptOS << Cmd; - Diag(clang::diag::note_drv_command_failed_diag_msg) << Script; + for (const char *TempFile : TempFiles) + Diag(clang::diag::note_drv_command_failed_diag_msg) << TempFile; + + // Assume associated files are based off of the first temporary file. + const char *MainFile = TempFiles[0]; + + std::string Script = StringRef(MainFile).rsplit('.').first; + + // In some cases (modules) we'll dump extra data to help with reproducing + // the crash into a directory next to the output. + // FIXME: We should be able to generate these as extra temp files now that it + // won't mess up the run script. + SmallString<128> VFS; + if (llvm::sys::fs::exists(Script + ".cache")) { + Diag(clang::diag::note_drv_command_failed_diag_msg) << Script + ".cache"; + VFS = llvm::sys::path::filename(Script + ".cache"); + llvm::sys::path::append(VFS, "vfs", "vfs.yaml"); + } + + std::error_code EC; + Script += ".sh"; + llvm::raw_fd_ostream ScriptOS(Script, EC, llvm::sys::fs::F_Excl); + if (EC) { + Diag(clang::diag::note_drv_command_failed_diag_msg) + << "Error generating run script: " + Script + " " + EC.message(); + } else { + // Replace the original filename with the preprocessed one. + size_t I, E; + I = Cmd.find("-main-file-name "); + assert(I != std::string::npos && "Expected to find -main-file-name"); + I += 16; + E = Cmd.find(" ", I); + assert(E != std::string::npos && "-main-file-name missing argument?"); + StringRef OldFilename = StringRef(Cmd).slice(I, E); + StringRef NewFilename = llvm::sys::path::filename(MainFile); + I = StringRef(Cmd).rfind(OldFilename); + E = I + OldFilename.size(); + if (E + 1 < Cmd.size() && Cmd[E] == '"') + ++E; // Replace a trailing quote if present. + I = Cmd.rfind(" ", I) + 1; + Cmd.replace(I, E - I, NewFilename.data(), NewFilename.size()); + if (!VFS.empty()) { + // Add the VFS overlay to the reproduction script. + I += NewFilename.size(); + Cmd.insert(I, std::string(" -ivfsoverlay ") + VFS.c_str()); } + ScriptOS << Cmd; + Diag(clang::diag::note_drv_command_failed_diag_msg) << Script; } Diag(clang::diag::note_drv_command_failed_diag_msg) << "\n\n********************";