;
35using namespacedriver;
39 constllvm::opt::ArgStringList &Arguments,
41 const char*PrependArg)
42: Source(Source), Creator(Creator), ResponseSupport(ResponseSupport),
43Executable(Executable), PrependArg(PrependArg), Arguments(Arguments) {
44 for(
const auto&II : Inputs)
47 for(
const auto&II : Outputs)
49OutputFilenames.push_back(II.getFilename());
55static bool skipArgs(
const char*Flag,
boolHaveCrashVFS,
int&SkipNum,
60 boolShouldSkip = llvm::StringSwitch<bool>(Flag)
61.Cases(
"-MF",
"-MT",
"-MQ",
"-serialize-diagnostic-file",
true)
62.Cases(
"-o",
"-dependency-file",
true)
63.Cases(
"-fdebug-compilation-dir",
"-diagnostic-log-file",
true)
64.Cases(
"-dwarf-debug-flags",
"-ivfsoverlay",
true)
70IsInclude = llvm::StringSwitch<bool>(Flag)
71.Cases(
"-include",
"-header-include-file",
true)
72.Cases(
"-idirafter",
"-internal-isystem",
"-iwithprefix",
true)
73.Cases(
"-internal-externc-isystem",
"-iprefix",
true)
74.Cases(
"-iwithprefixbefore",
"-isystem",
"-iquote",
true)
75.Cases(
"-isysroot",
"-I",
"-F",
"-resource-dir",
true)
76.Cases(
"-iframework",
"-include-pch",
true)
84ShouldSkip = llvm::StringSwitch<bool>(Flag)
85.Cases(
"-M",
"-MM",
"-MG",
"-MP",
"-MD",
true)
86.Case(
"-MMD",
true)
95StringRef FlagRef(Flag);
96IsInclude = FlagRef.starts_with(
"-F") || FlagRef.starts_with(
"-I");
99 if(FlagRef.starts_with(
"-fmodules-cache-path="))
106voidCommand::writeResponseFile(raw_ostream &OS)
const{
109 for(
const auto*Arg : InputFileList) {
118 for(
const auto*Arg : Arguments) {
121 for(; *Arg !=
'\0'; Arg++) {
122 if(*Arg ==
'\"'|| *Arg ==
'\\') {
132voidCommand::buildArgvForResponseFile(
138Out.push_back(Executable);
139Out.push_back(ResponseFileFlag.c_str());
143llvm::StringSet<> Inputs;
144 for(
const auto*InputName : InputFileList)
145Inputs.insert(InputName);
146Out.push_back(Executable);
149Out.push_back(PrependArg);
153 boolFirstInput =
true;
154 for(
const auto*Arg : Arguments) {
155 if(Inputs.count(Arg) == 0) {
157}
else if(FirstInput) {
160Out.push_back(ResponseFile);
170 using namespace llvm;
174 if(path::is_absolute(InInc))
176std::error_code EC = fs::current_path(OutInc);
179path::append(OutInc, InInc);
185StringRef FlagRef(Args[Idx + NumArgs - 1]);
186assert((FlagRef.starts_with(
"-F") || FlagRef.starts_with(
"-I")) &&
187 "Expecting -I or -F");
188StringRef Inc = FlagRef.slice(2, StringRef::npos);
189 if(getAbsPath(Inc, NewInc)) {
192IncFlags.push_back(std::move(NewArg));
197assert(NumArgs == 2 &&
"Not expecting more than two arguments");
198StringRef Inc(Args[Idx + NumArgs - 1]);
199 if(!getAbsPath(Inc, NewInc))
202IncFlags.push_back(std::move(NewInc));
209llvm::sys::printArg(OS, Executable,
true);
213 if(ResponseFile !=
nullptr) {
214buildArgvForResponseFile(ArgsRespFile);
216}
else if(PrependArg) {
218llvm::sys::printArg(OS, PrependArg,
true);
221 boolHaveCrashVFS = CrashInfo && !CrashInfo->
VFSPath.empty();
222 for(
size_ti = 0, e = Args.size(); i < e; ++i) {
223 const char*
constArg = Args[i];
227 boolIsInclude =
false;
228 if(
skipArgs(Arg, HaveCrashVFS, NumArgs, IsInclude)) {
234 if(HaveCrashVFS && IsInclude) {
237 if(!NewIncFlags.empty()) {
238 for(
auto&F : NewIncFlags) {
240llvm::sys::printArg(OS, F.c_str(), Quote);
251(i == 0 || StringRef(Args[i - 1]) !=
"-main-file-name")) {
255llvm::sys::printArg(OS,
ShortName.str(), Quote);
261llvm::sys::printArg(OS, Arg, Quote);
264 if(CrashInfo && HaveCrashVFS) {
266llvm::sys::printArg(OS,
"-ivfsoverlay", Quote);
268llvm::sys::printArg(OS, CrashInfo->
VFSPath.str(), Quote);
276llvm::sys::path::parent_path(CrashInfo->
VFSPath));
277llvm::sys::path::append(RelModCacheDir,
"repro-modules");
279std::string ModCachePath =
"-fmodules-cache-path=";
280ModCachePath.append(RelModCacheDir.c_str());
283llvm::sys::printArg(OS, ModCachePath, Quote);
286 if(ResponseFile !=
nullptr) {
287OS <<
"\n Arguments passed via response file:\n";
288writeResponseFile(OS);
293OS <<
" (end of response file)";
306Environment.reserve(NewEnvironment.size() + 1);
307Environment.assign(NewEnvironment.begin(), NewEnvironment.end());
308Environment.push_back(
nullptr);
312 conststd::vector<std::optional<std::string>> &Redirects) {
313RedirectFiles = Redirects;
319llvm::outs() << llvm::sys::path::filename(Arg.getFilename()) <<
"\n";
320llvm::outs().flush();
325std::string *ErrMsg,
bool*ExecutionFailed)
const{
329 if(ResponseFile ==
nullptr) {
330Argv.push_back(Executable);
332Argv.push_back(PrependArg);
333Argv.append(Arguments.begin(), Arguments.end());
334Argv.push_back(
nullptr);
337std::string RespContents;
338llvm::raw_string_ostream SS(RespContents);
341writeResponseFile(SS);
342buildArgvForResponseFile(Argv);
343Argv.push_back(
nullptr);
346 if(std::error_code EC = writeFileWithEncoding(
349*ErrMsg = EC.message();
351*ExecutionFailed =
true;
358std::optional<ArrayRef<StringRef>>
Env;
359std::vector<StringRef> ArgvVectorStorage;
360 if(!Environment.empty()) {
361assert(Environment.back() ==
nullptr&&
362 "Environment vector should be null-terminated by now");
363ArgvVectorStorage = llvm::toStringRefArray(Environment.data());
367 autoArgs = llvm::toStringRefArray(Argv.data());
370 if(!RedirectFiles.empty()) {
371std::vector<std::optional<StringRef>> RedirectFilesOptional;
372 for(
const auto&Ele : RedirectFiles)
374RedirectFilesOptional.push_back(std::optional<StringRef>(*Ele));
376RedirectFilesOptional.push_back(std::nullopt);
378 returnllvm::sys::ExecuteAndWait(Executable, Args,
Env,
381ErrMsg, ExecutionFailed, &ProcStat);
384 returnllvm::sys::ExecuteAndWait(Executable, Args,
Env, Redirects,
386ErrMsg, ExecutionFailed, &ProcStat);
391 const char*Executable,
392 constllvm::opt::ArgStringList &Arguments,
394 const char*PrependArg)
395:
Command(Source, Creator, ResponseSupport, Executable, Arguments, Inputs,
396Outputs, PrependArg) {
403OS <<
" (in-process)\n";
408std::string *ErrMsg,
bool*ExecutionFailed)
const{
420Argv.push_back(
nullptr);
427*ExecutionFailed =
false;
429llvm::CrashRecoveryContext CRC;
430CRC.DumpStackAndCleanupOnFailure =
true;
432 const void*PrettyState = llvm::SavePrettyStackState();
437 if(!CRC.RunSafely([&]() { R = D.CC1Main(Argv); })) {
438llvm::RestorePrettyStackState(PrettyState);
447 "The CC1Command doesn't support changing the environment vars!");
452 for(
const auto&Job : *
this)
453Job.Print(OS, Terminator, Quote, CrashInfo);
static void rewriteIncludes(const llvm::ArrayRef< const char * > &Args, size_t Idx, size_t NumArgs, llvm::SmallVectorImpl< llvm::SmallString< 128 > > &IncFlags)
Rewrite relative include-like flag paths to absolute ones.
static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, bool &IsInclude)
Check if the compiler flag in question should be skipped when emitting a reproducer.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Action - Represent an abstract compilation step to perform.
void setEnvironment(llvm::ArrayRef< const char * > NewEnvironment) override
Sets the environment to be used by the new process.
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const override
int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const override
CC1Command(const Action &Source, const Tool &Creator, ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef< InputInfo > Inputs, ArrayRef< InputInfo > Outputs={}, const char *PrependArg=nullptr)
Command - An executable path/name and argument vector to execute.
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
const llvm::opt::ArgStringList & getArguments() const
void setResponseFile(const char *FileName)
Set to pass arguments via a response file when launching the command.
void setRedirectFiles(const std::vector< std::optional< std::string > > &Redirects)
Command(const Action &Source, const Tool &Creator, ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef< InputInfo > Inputs, ArrayRef< InputInfo > Outputs={}, const char *PrependArg=nullptr)
bool PrintInputFilenames
Whether to print the input filenames when executing.
const char * getExecutable() const
virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
bool InProcess
Whether the command will be executed in this process or not.
virtual void setEnvironment(llvm::ArrayRef< const char * > NewEnvironment)
Sets the environment to be used by the new process.
void PrintFileNames() const
Optionally print the filenames to be compiled.
virtual int Execute(ArrayRef< std::optional< StringRef > > Redirects, std::string *ErrMsg, bool *ExecutionFailed) const
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
InputInfo - Wrapper for information about an input source.
const char * getFilename() const
void clear()
Clear the job list.
void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo=nullptr) const
The JSON file list parser is used to communicate input to InstallAPI.
Diagnostic wrappers for TextAPI types for error reporting.
ResponseFileKind ResponseKind
The level of support for response files.
llvm::sys::WindowsEncodingMethod ResponseEncoding
The encoding to use when writing response files on Windows.
const char * ResponseFlag
What prefix to use for the command-line argument when passing a response file.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4