@@ -646,16 +646,23 @@ struct DependencyScannerReproducerOptions {
646
646
std::vector<std::string> BuildArgs;
647
647
std::optional<std::string> ModuleName;
648
648
std::optional<std::string> WorkingDirectory;
649
+ std::optional<std::string> ReproducerLocation;
650
+ bool UseUniqueReproducerName;
649
651
650
652
DependencyScannerReproducerOptions (int argc, const char *const *argv,
651
653
const char *ModuleName,
652
- const char *WorkingDirectory) {
654
+ const char *WorkingDirectory,
655
+ const char *ReproducerLocation,
656
+ bool UseUniqueReproducerName)
657
+ : UseUniqueReproducerName(UseUniqueReproducerName) {
653
658
if (argv)
654
659
BuildArgs.assign (argv, argv + argc);
655
660
if (ModuleName)
656
661
this ->ModuleName = ModuleName;
657
662
if (WorkingDirectory)
658
663
this ->WorkingDirectory = WorkingDirectory;
664
+ if (ReproducerLocation)
665
+ this ->ReproducerLocation = ReproducerLocation;
659
666
}
660
667
};
661
668
@@ -690,9 +697,11 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScannerReproducerOptions,
690
697
CXDependencyScannerReproducerOptions
691
698
clang_experimental_DependencyScannerReproducerOptions_create(
692
699
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});
696
705
}
697
706
698
707
void clang_experimental_DependencyScannerReproducerOptions_dispose (
@@ -714,6 +723,9 @@ enum CXErrorCode clang_experimental_DependencyScanner_generateReproducer(
714
723
return Report (CXError_InvalidArguments) << " missing compilation command" ;
715
724
if (!Opts.WorkingDirectory )
716
725
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" ;
717
729
718
730
CASOptions CASOpts;
719
731
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> FS;
@@ -724,9 +736,24 @@ enum CXErrorCode clang_experimental_DependencyScanner_generateReproducer(
724
736
725
737
llvm::SmallString<128 > ReproScriptPath;
726
738
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
+ }
730
757
}
731
758
SmallString<128 > FileCachePath = ReproScriptPath;
732
759
llvm::sys::path::replace_extension (FileCachePath, " .cache" );
0 commit comments