@@ -646,16 +646,23 @@ struct DependencyScannerReproducerOptions {
646646 std::vector<std::string> BuildArgs;
647647 std::optional<std::string> ModuleName;
648648 std::optional<std::string> WorkingDirectory;
649+ std::optional<std::string> ReproducerLocation;
650+ bool UseUniqueReproducerName;
649651
650652 DependencyScannerReproducerOptions (int argc, const char *const *argv,
651653 const char *ModuleName,
652- const char *WorkingDirectory) {
654+ const char *WorkingDirectory,
655+ const char *ReproducerLocation,
656+ bool UseUniqueReproducerName)
657+ : UseUniqueReproducerName(UseUniqueReproducerName) {
653658 if (argv)
654659 BuildArgs.assign (argv, argv + argc);
655660 if (ModuleName)
656661 this ->ModuleName = ModuleName;
657662 if (WorkingDirectory)
658663 this ->WorkingDirectory = WorkingDirectory;
664+ if (ReproducerLocation)
665+ this ->ReproducerLocation = ReproducerLocation;
659666 }
660667};
661668
@@ -690,9 +697,11 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScannerReproducerOptions,
690697CXDependencyScannerReproducerOptions
691698clang_experimental_DependencyScannerReproducerOptions_create(
692699 int argc, const char *const *argv, const char *ModuleName,
693- const char *WorkingDirectory) {
694- return wrap (new DependencyScannerReproducerOptions{argc, argv, ModuleName,
695- WorkingDirectory});
700+ const char *WorkingDirectory, const char *ReproducerLocation,
701+ bool UseUniqueReproducerName) {
702+ return wrap (new DependencyScannerReproducerOptions{
703+ argc, argv, ModuleName, WorkingDirectory, ReproducerLocation,
704+ UseUniqueReproducerName});
696705}
697706
698707void clang_experimental_DependencyScannerReproducerOptions_dispose (
@@ -714,6 +723,9 @@ enum CXErrorCode clang_experimental_DependencyScanner_generateReproducer(
714723 return Report (CXError_InvalidArguments) << " missing compilation command" ;
715724 if (!Opts.WorkingDirectory )
716725 return Report (CXError_InvalidArguments) << " missing working directory" ;
726+ if (!Opts.UseUniqueReproducerName && !Opts.ReproducerLocation )
727+ return Report (CXError_InvalidArguments)
728+ << " non-unique reproducer is allowed only in a custom location" ;
717729
718730 CASOptions CASOpts;
719731 IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> FS;
@@ -724,9 +736,24 @@ enum CXErrorCode clang_experimental_DependencyScanner_generateReproducer(
724736
725737 llvm::SmallString<128 > ReproScriptPath;
726738 int ScriptFD;
727- if (auto EC = llvm::sys::fs::createTemporaryFile (" reproducer" , " sh" , ScriptFD,
728- ReproScriptPath)) {
729- return ReportFailure () << " failed to create a reproducer script file" ;
739+ if (Opts.ReproducerLocation ) {
740+ if (auto EC = llvm::sys::fs::create_directories (*Opts.ReproducerLocation ))
741+ return ReportFailure () << " failed to create a reproducer location '"
742+ << *Opts.ReproducerLocation << " '\n "
743+ << EC.message ();
744+ SmallString<128 > Path (*Opts.ReproducerLocation );
745+ llvm::sys::path::append (Path, " reproducer" );
746+ const char *UniqueSuffix = Opts.UseUniqueReproducerName ? " -%%%%%%" : " " ;
747+ if (auto EC = llvm::sys::fs::createUniqueFile (Path + UniqueSuffix + " .sh" ,
748+ ScriptFD, ReproScriptPath))
749+ return ReportFailure () << " failed to create a reproducer script file\n "
750+ << EC.message ();
751+ } else {
752+ if (auto EC = llvm::sys::fs::createTemporaryFile (
753+ " reproducer" , " sh" , ScriptFD, ReproScriptPath)) {
754+ return ReportFailure () << " failed to create a reproducer script file\n "
755+ << EC.message ();
756+ }
730757 }
731758 SmallString<128 > FileCachePath = ReproScriptPath;
732759 llvm::sys::path::replace_extension (FileCachePath, " .cache" );
0 commit comments