@@ -853,16 +853,16 @@ class ObjcMethodReferenceCollector: public SourceEntityWalker {
853853 }
854854};
855855
856- static std::optional<int > createObjCMessageTraceFile (const InputFile &input,
857- ModuleDecl *MD,
858- std::vector<SourceFile*> &filesToWalk) {
856+ static void createObjCMessageTraceFile (const InputFile &input, ModuleDecl *MD) {
859857 if (input.getLoadedModuleTracePath ().empty ()) {
860858 // we basically rely on the passing down of module trace file path
861859 // as an indicator that this job needs to emit an ObjC message trace file.
862860 // FIXME: add a separate swift-frontend flag for ObjC message trace path
863861 // specifically.
864- return {} ;
862+ return ;
865863 }
864+ auto &ctx = MD->getASTContext ();
865+ std::vector<SourceFile*> filesToWalk;
866866 for (auto *FU : MD->getFiles ()) {
867867 if (auto *SF = dyn_cast<SourceFile>(FU)) {
868868 switch (SF->Kind ) {
@@ -880,29 +880,47 @@ static std::optional<int> createObjCMessageTraceFile(const InputFile &input,
880880 }
881881 // No source files to walk, abort.
882882 if (filesToWalk.empty ()) {
883- return {} ;
883+ return ;
884884 }
885885 llvm::SmallString<128 > tracePath;
886- if (const char *P = ::getenv (" SWIFT_COMPILER_OBJC_MESSAGE_TRACE_DIRECTORY " )) {
887- StringRef DirPath = P;
888- llvm::sys::path::append (tracePath, DirPath );
886+ if (const char *P = ::getenv (" SWIFT_COMPILER_OBJC_MESSAGE_TRACE_PATH " )) {
887+ StringRef FilePath = P;
888+ llvm::sys::path::append (tracePath, FilePath );
889889 } else {
890890 llvm::sys::path::append (tracePath, input.getLoadedModuleTracePath ());
891891 llvm::sys::path::remove_filename (tracePath);
892- llvm::sys::path::append (tracePath, " .SWIFT_FINE_DEPENDENCY_TRACE" );
892+ llvm::sys::path::append (tracePath, " .SWIFT_FINE_DEPENDENCY_TRACE.json" );
893+ }
894+ // Write output via atomic append.
895+ llvm::vfs::OutputConfig config;
896+ config.setAppend ().setAtomicWrite ();
897+ auto outputFile = ctx.getOutputBackend ().createFile (tracePath, config);
898+ if (!outputFile) {
899+ ctx.Diags .diagnose (SourceLoc (), diag::error_opening_output, tracePath,
900+ toString (outputFile.takeError ()));
901+ return ;
893902 }
894- if (!llvm::sys::fs::exists (tracePath)) {
895- if (llvm::sys::fs::create_directory (tracePath))
896- return {};
903+ ObjcMethodReferenceCollector collector (MD);
904+ for (auto *SF : filesToWalk) {
905+ collector.setFileBeforeVisiting (SF);
906+ collector.walk (*SF);
907+ }
908+
909+ // print this json line.
910+ std::string stringBuffer;
911+ {
912+ llvm::raw_string_ostream memoryBuffer (stringBuffer);
913+ collector.serializeAsJson (memoryBuffer);
897914 }
898- SmallString<32 > fileName (MD->getNameStr ());
899- fileName.append (" -%%%%-%%%%-%%%%.json" );
900- llvm::sys::path::append (tracePath, fileName);
901- int tmpFD;
902- if (llvm::sys::fs::createUniqueFile (tracePath.str (), tmpFD, tracePath)) {
903- return {};
915+ stringBuffer += " \n " ;
916+
917+ // Write output via atomic append.
918+ *outputFile << stringBuffer;
919+ if (auto err = outputFile->keep ()) {
920+ ctx.Diags .diagnose (SourceLoc (), diag::error_opening_output,
921+ tracePath, toString (std::move (err)));
922+ return ;
904923 }
905- return tmpFD;
906924}
907925
908926bool swift::emitObjCMessageSendTraceIfNeeded (ModuleDecl *mainModule,
@@ -912,18 +930,7 @@ bool swift::emitObjCMessageSendTraceIfNeeded(ModuleDecl *mainModule,
912930 " We should've already exited earlier if there was an error." );
913931
914932 opts.InputsAndOutputs .forEachInput ([&](const InputFile &input) {
915- std::vector<SourceFile*> filesToWalk;
916- auto tmpFD = createObjCMessageTraceFile (input, mainModule, filesToWalk);
917- if (!tmpFD)
918- return false ;
919- // Write the contents of the buffer.
920- llvm::raw_fd_ostream out (*tmpFD, /* shouldClose=*/ true );
921- ObjcMethodReferenceCollector collector (mainModule);
922- for (auto *SF : filesToWalk) {
923- collector.setFileBeforeVisiting (SF);
924- collector.walk (*SF);
925- }
926- collector.serializeAsJson (out);
933+ createObjCMessageTraceFile (input, mainModule);
927934 return true ;
928935 });
929936 return false ;
0 commit comments