@@ -647,6 +647,8 @@ struct DependencyScannerReproducerOptions {
647
647
const char *const *argv;
648
648
const char *ModuleName;
649
649
const char *WorkingDirectory;
650
+ const char *ReproducerLocation;
651
+ bool UseUniqueReproducerName;
650
652
};
651
653
652
654
// Helper class to capture a returnable error code and to return a formatted
@@ -680,9 +682,11 @@ DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DependencyScannerReproducerOptions,
680
682
CXDependencyScannerReproducerOptions
681
683
clang_experimental_DependencyScannerReproducerOptions_create(
682
684
int argc, const char *const *argv, const char *ModuleName,
683
- const char *WorkingDirectory) {
684
- return wrap (new DependencyScannerReproducerOptions{argc, argv, ModuleName,
685
- WorkingDirectory});
685
+ const char *WorkingDirectory, const char *ReproducerLocation,
686
+ bool UseUniqueReproducerName) {
687
+ return wrap (new DependencyScannerReproducerOptions{
688
+ argc, argv, ModuleName, WorkingDirectory, ReproducerLocation,
689
+ UseUniqueReproducerName});
686
690
}
687
691
688
692
void clang_experimental_DependencyScannerReproducerOptions_dispose (
@@ -702,10 +706,14 @@ enum CXErrorCode clang_experimental_DependencyScanner_generateReproducer(
702
706
DependencyScannerReproducerOptions &Opts = *unwrap (CXOptions);
703
707
int argc = Opts.argc ;
704
708
const char *const *argv = Opts.argv ;
709
+ const char *ReproducerLocation = Opts.ReproducerLocation ;
705
710
if (argc < 2 || !argv)
706
711
return Report (CXError_InvalidArguments) << " missing compilation command" ;
707
712
if (!Opts.WorkingDirectory )
708
713
return Report (CXError_InvalidArguments) << " missing working directory" ;
714
+ if (!Opts.UseUniqueReproducerName && !ReproducerLocation)
715
+ return Report (CXError_InvalidArguments)
716
+ << " non-unique reproducer is allowed only in a custom location" ;
709
717
710
718
CASOptions CASOpts;
711
719
IntrusiveRefCntPtr<llvm::cas::CachingOnDiskFileSystem> FS;
@@ -716,9 +724,24 @@ enum CXErrorCode clang_experimental_DependencyScanner_generateReproducer(
716
724
717
725
llvm::SmallString<128 > ReproScriptPath;
718
726
int ScriptFD;
719
- if (auto EC = llvm::sys::fs::createTemporaryFile (" reproducer" , " sh" , ScriptFD,
720
- ReproScriptPath)) {
721
- return ReportFailure () << " failed to create a reproducer script file" ;
727
+ if (ReproducerLocation) {
728
+ if (auto EC = llvm::sys::fs::create_directories (ReproducerLocation))
729
+ return ReportFailure () << " failed to create a reproducer location '"
730
+ << ReproducerLocation << " '\n "
731
+ << EC.message ();
732
+ SmallString<128 > Path (ReproducerLocation);
733
+ llvm::sys::path::append (Path, " reproducer" );
734
+ const char *UniqueSuffix = Opts.UseUniqueReproducerName ? " -%%%%%%" : " " ;
735
+ if (auto EC = llvm::sys::fs::createUniqueFile (Path + UniqueSuffix + " .sh" ,
736
+ ScriptFD, ReproScriptPath))
737
+ return ReportFailure () << " failed to create a reproducer script file\n "
738
+ << EC.message ();
739
+ } else {
740
+ if (auto EC = llvm::sys::fs::createTemporaryFile (
741
+ " reproducer" , " sh" , ScriptFD, ReproScriptPath)) {
742
+ return ReportFailure () << " failed to create a reproducer script file\n "
743
+ << EC.message ();
744
+ }
722
745
}
723
746
SmallString<128 > FileCachePath = ReproScriptPath;
724
747
llvm::sys::path::replace_extension (FileCachePath, " .cache" );
0 commit comments