diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -223,7 +223,7 @@ /// identifying the conditions under which the module was built. std::string getModuleHash() const; - using StringAllocator = llvm::function_ref; + using StringAllocator = llvm::function_ref; /// Generate cc1-compatible command line arguments from this instance. /// /// \param [out] Args - The generated arguments. Note that the caller is @@ -233,7 +233,21 @@ /// command line argument and return a pointer to the newly allocated string. /// The returned pointer is what gets appended to Args. void generateCC1CommandLine(llvm::SmallVectorImpl &Args, - StringAllocator SA) const; + StringAllocator SA) const { + generateCC1CommandLine([&](const Twine &Arg) { + // No need to allocate static string literals. + Args.push_back(Arg.isSingleStringLiteral() + ? Arg.getSingleStringRef().data() + : SA(Arg)); + }); + } + + using ArgumentConsumer = llvm::function_ref; + /// Generate cc1-compatible command line arguments from this instance. + /// + /// \param Consumer - Callback that gets invoked for every single generated + /// command line argument. + void generateCC1CommandLine(ArgumentConsumer Consumer) const; /// Generate cc1-compatible command line arguments from this instance, /// wrapping the result as a std::vector. @@ -267,8 +281,8 @@ /// Generate command line options from DiagnosticOptions. static void GenerateDiagnosticArgs(const DiagnosticOptions &Opts, - SmallVectorImpl &Args, - StringAllocator SA, bool DefaultDiagColor); + ArgumentConsumer Consumer, + bool DefaultDiagColor); /// Parse command line options that map to LangOptions. static bool ParseLangArgs(LangOptions &Opts, llvm::opt::ArgList &Args, @@ -278,8 +292,7 @@ /// Generate command line options from LangOptions. static void GenerateLangArgs(const LangOptions &Opts, - SmallVectorImpl &Args, - StringAllocator SA, const llvm::Triple &T, + ArgumentConsumer Consumer, const llvm::Triple &T, InputKind IK); /// Parse command line options that map to CodeGenOptions. @@ -291,8 +304,8 @@ // Generate command line options from CodeGenOptions. static void GenerateCodeGenArgs(const CodeGenOptions &Opts, - SmallVectorImpl &Args, - StringAllocator SA, const llvm::Triple &T, + ArgumentConsumer Consumer, + const llvm::Triple &T, const std::string &OutputFile, const LangOptions *LangOpts); }; diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -165,6 +165,8 @@ // Normalizers //===----------------------------------------------------------------------===// +using ArgumentConsumer = CompilerInvocation::ArgumentConsumer; + #define SIMPLE_ENUM_VALUE_TABLE #include "clang/Driver/Options.inc" #undef SIMPLE_ENUM_VALUE_TABLE @@ -191,13 +193,10 @@ /// denormalizeSimpleFlags never looks at it. Avoid bloating compile-time with /// unnecessary template instantiations and just ignore it with a variadic /// argument. -static void denormalizeSimpleFlag(SmallVectorImpl &Args, - const Twine &Spelling, - CompilerInvocation::StringAllocator, - Option::OptionClass, unsigned, /*T*/...) { - // Spelling is already allocated or a static string, no need to call SA. - assert(*Spelling.getSingleStringRef().end() == '\0'); - Args.push_back(Spelling.getSingleStringRef().data()); +static void denormalizeSimpleFlag(ArgumentConsumer Consumer, + const Twine &Spelling, Option::OptionClass, + unsigned, /*T*/...) { + Consumer(Spelling); } template static constexpr bool is_uint64_t_convertible() { @@ -234,34 +233,27 @@ } static auto makeBooleanOptionDenormalizer(bool Value) { - return [Value](SmallVectorImpl &Args, const Twine &Spelling, - CompilerInvocation::StringAllocator, Option::OptionClass, - unsigned, bool KeyPath) { - if (KeyPath == Value) { - // Spelling is already allocated or a static string, no need to call SA. - assert(*Spelling.getSingleStringRef().end() == '\0'); - Args.push_back(Spelling.getSingleStringRef().data()); - } + return [Value](ArgumentConsumer Consumer, const Twine &Spelling, + Option::OptionClass, unsigned, bool KeyPath) { + if (KeyPath == Value) + Consumer(Spelling); }; } -static void denormalizeStringImpl(SmallVectorImpl &Args, +static void denormalizeStringImpl(ArgumentConsumer Consumer, const Twine &Spelling, - CompilerInvocation::StringAllocator SA, Option::OptionClass OptClass, unsigned, const Twine &Value) { switch (OptClass) { case Option::SeparateClass: case Option::JoinedOrSeparateClass: case Option::JoinedAndSeparateClass: - // Spelling is already allocated or a static string, no need to call SA. - assert(*Spelling.getSingleStringRef().end() == '\0'); - Args.push_back(Spelling.getSingleStringRef().data()); - Args.push_back(SA(Value)); + Consumer(Spelling); + Consumer(Value); break; case Option::JoinedClass: case Option::CommaJoinedClass: - Args.push_back(SA(Twine(Spelling) + Value)); + Consumer(Spelling + Value); break; default: llvm_unreachable("Cannot denormalize an option with option class " @@ -270,11 +262,10 @@ } template -static void -denormalizeString(SmallVectorImpl &Args, const Twine &Spelling, - CompilerInvocation::StringAllocator SA, - Option::OptionClass OptClass, unsigned TableIndex, T Value) { - denormalizeStringImpl(Args, Spelling, SA, OptClass, TableIndex, Twine(Value)); +static void denormalizeString(ArgumentConsumer Consumer, const Twine &Spelling, + Option::OptionClass OptClass, unsigned TableIndex, + T Value) { + denormalizeStringImpl(Consumer, Spelling, OptClass, TableIndex, Twine(Value)); } static std::optional @@ -315,15 +306,14 @@ return std::nullopt; } -static void denormalizeSimpleEnumImpl(SmallVectorImpl &Args, +static void denormalizeSimpleEnumImpl(ArgumentConsumer Consumer, const Twine &Spelling, - CompilerInvocation::StringAllocator SA, Option::OptionClass OptClass, unsigned TableIndex, unsigned Value) { assert(TableIndex < SimpleEnumValueTablesSize); const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; if (auto MaybeEnumVal = findValueTableByValue(Table, Value)) { - denormalizeString(Args, Spelling, SA, OptClass, TableIndex, + denormalizeString(Consumer, Spelling, OptClass, TableIndex, MaybeEnumVal->Name); } else { llvm_unreachable("The simple enum value was not correctly defined in " @@ -332,12 +322,11 @@ } template -static void denormalizeSimpleEnum(SmallVectorImpl &Args, +static void denormalizeSimpleEnum(ArgumentConsumer Consumer, const Twine &Spelling, - CompilerInvocation::StringAllocator SA, Option::OptionClass OptClass, unsigned TableIndex, T Value) { - return denormalizeSimpleEnumImpl(Args, Spelling, SA, OptClass, TableIndex, + return denormalizeSimpleEnumImpl(Consumer, Spelling, OptClass, TableIndex, static_cast(Value)); } @@ -373,9 +362,8 @@ return Args.getAllArgValues(Opt); } -static void denormalizeStringVector(SmallVectorImpl &Args, +static void denormalizeStringVector(ArgumentConsumer Consumer, const Twine &Spelling, - CompilerInvocation::StringAllocator SA, Option::OptionClass OptClass, unsigned TableIndex, const std::vector &Values) { @@ -389,7 +377,7 @@ CommaJoinedValue.append(Value); } } - denormalizeString(Args, Spelling, SA, Option::OptionClass::JoinedClass, + denormalizeString(Consumer, Spelling, Option::OptionClass::JoinedClass, TableIndex, CommaJoinedValue); break; } @@ -397,7 +385,7 @@ case Option::SeparateClass: case Option::JoinedOrSeparateClass: for (const std::string &Value : Values) - denormalizeString(Args, Spelling, SA, OptClass, TableIndex, Value); + denormalizeString(Consumer, Spelling, OptClass, TableIndex, Value); break; default: llvm_unreachable("Cannot denormalize an option with option class " @@ -451,18 +439,18 @@ // Capture the extracted value as a lambda argument to avoid potential issues // with lifetime extension of the reference. #define GENERATE_OPTION_WITH_MARSHALLING( \ - ARGS, STRING_ALLOCATOR, PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, \ - ALIASARGS, FLAGS, PARAM, HELPTEXT, METAVAR, VALUES, SPELLING, \ - SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \ - IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + CONSUMER, PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ + PARAM, HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, \ + KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, \ + DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ if ((FLAGS)&options::CC1Option) { \ [&](const auto &Extracted) { \ if (ALWAYS_EMIT || \ (Extracted != \ static_cast((IMPLIED_CHECK) ? (IMPLIED_VALUE) \ : (DEFAULT_VALUE)))) \ - DENORMALIZER(ARGS, SPELLING, STRING_ALLOCATOR, Option::KIND##Class, \ - TABLE_INDEX, Extracted); \ + DENORMALIZER(CONSUMER, SPELLING, Option::KIND##Class, TABLE_INDEX, \ + Extracted); \ }(EXTRACTOR(KEYPATH)); \ } @@ -624,21 +612,19 @@ return 0; } -static void GenerateArg(SmallVectorImpl &Args, - llvm::opt::OptSpecifier OptSpecifier, - CompilerInvocation::StringAllocator SA) { +static void GenerateArg(ArgumentConsumer Consumer, + llvm::opt::OptSpecifier OptSpecifier) { Option Opt = getDriverOptTable().getOption(OptSpecifier); - denormalizeSimpleFlag(Args, SA(Opt.getPrefix() + Opt.getName()), SA, + denormalizeSimpleFlag(Consumer, Opt.getPrefix() + Opt.getName(), Option::OptionClass::FlagClass, 0); } -static void GenerateArg(SmallVectorImpl &Args, +static void GenerateArg(ArgumentConsumer Consumer, llvm::opt::OptSpecifier OptSpecifier, - const Twine &Value, - CompilerInvocation::StringAllocator SA) { + const Twine &Value) { Option Opt = getDriverOptTable().getOption(OptSpecifier); - denormalizeString(Args, SA(Opt.getPrefix() + Opt.getName()), SA, - Opt.getKind(), 0, Value); + denormalizeString(Consumer, Opt.getPrefix() + Opt.getName(), Opt.getKind(), 0, + Value); } // Parse command line arguments into CompilerInvocation. @@ -854,12 +840,11 @@ } static void GenerateAnalyzerArgs(AnalyzerOptions &Opts, - SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA) { + ArgumentConsumer Consumer) { const AnalyzerOptions *AnalyzerOpts = &Opts; #define ANALYZER_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef ANALYZER_OPTION_WITH_MARSHALLING @@ -867,7 +852,7 @@ switch (Opts.AnalysisConstraintsOpt) { #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \ case NAME##Model: \ - GenerateArg(Args, OPT_analyzer_constraints, CMDFLAG, SA); \ + GenerateArg(Consumer, OPT_analyzer_constraints, CMDFLAG); \ break; #include "clang/StaticAnalyzer/Core/Analyses.def" default: @@ -879,7 +864,7 @@ switch (Opts.AnalysisDiagOpt) { #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \ case PD_##NAME: \ - GenerateArg(Args, OPT_analyzer_output, CMDFLAG, SA); \ + GenerateArg(Consumer, OPT_analyzer_output, CMDFLAG); \ break; #include "clang/StaticAnalyzer/Core/Analyses.def" default: @@ -891,7 +876,7 @@ switch (Opts.AnalysisPurgeOpt) { #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \ case NAME: \ - GenerateArg(Args, OPT_analyzer_purge, CMDFLAG, SA); \ + GenerateArg(Consumer, OPT_analyzer_purge, CMDFLAG); \ break; #include "clang/StaticAnalyzer/Core/Analyses.def" default: @@ -903,7 +888,7 @@ switch (Opts.InliningMode) { #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \ case NAME: \ - GenerateArg(Args, OPT_analyzer_inlining_mode, CMDFLAG, SA); \ + GenerateArg(Consumer, OPT_analyzer_inlining_mode, CMDFLAG); \ break; #include "clang/StaticAnalyzer/Core/Analyses.def" default: @@ -914,7 +899,7 @@ for (const auto &CP : Opts.CheckersAndPackages) { OptSpecifier Opt = CP.second ? OPT_analyzer_checker : OPT_analyzer_disable_checker; - GenerateArg(Args, Opt, CP.first, SA); + GenerateArg(Consumer, Opt, CP.first); } AnalyzerOptions ConfigOpts; @@ -933,7 +918,7 @@ if (Entry != ConfigOpts.Config.end() && Entry->getValue() == Value) continue; - GenerateArg(Args, OPT_analyzer_config, Key + "=" + Value, SA); + GenerateArg(Consumer, OPT_analyzer_config, Key + "=" + Value); } // Nothing to generate for FullCompilerInvocation. @@ -1199,16 +1184,15 @@ /// Generate a remark argument. This is an inverse of `ParseOptimizationRemark`. static void -GenerateOptimizationRemark(SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA, - OptSpecifier OptEQ, StringRef Name, +GenerateOptimizationRemark(ArgumentConsumer Consumer, OptSpecifier OptEQ, + StringRef Name, const CodeGenOptions::OptRemark &Remark) { if (Remark.hasValidPattern()) { - GenerateArg(Args, OptEQ, Remark.Pattern, SA); + GenerateArg(Consumer, OptEQ, Remark.Pattern); } else if (Remark.Kind == CodeGenOptions::RK_Enabled) { - GenerateArg(Args, OPT_R_Joined, Name, SA); + GenerateArg(Consumer, OPT_R_Joined, Name); } else if (Remark.Kind == CodeGenOptions::RK_Disabled) { - GenerateArg(Args, OPT_R_Joined, StringRef("no-") + Name, SA); + GenerateArg(Consumer, OPT_R_Joined, StringRef("no-") + Name); } } @@ -1363,35 +1347,36 @@ Opts.setProfileUse(CodeGenOptions::ProfileClangInstr); } -void CompilerInvocation::GenerateCodeGenArgs( - const CodeGenOptions &Opts, SmallVectorImpl &Args, - StringAllocator SA, const llvm::Triple &T, const std::string &OutputFile, - const LangOptions *LangOpts) { +void CompilerInvocation::GenerateCodeGenArgs(const CodeGenOptions &Opts, + ArgumentConsumer Consumer, + const llvm::Triple &T, + const std::string &OutputFile, + const LangOptions *LangOpts) { const CodeGenOptions &CodeGenOpts = Opts; if (Opts.OptimizationLevel == 0) - GenerateArg(Args, OPT_O0, SA); + GenerateArg(Consumer, OPT_O0); else - GenerateArg(Args, OPT_O, Twine(Opts.OptimizationLevel), SA); + GenerateArg(Consumer, OPT_O, Twine(Opts.OptimizationLevel)); #define CODEGEN_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef CODEGEN_OPTION_WITH_MARSHALLING if (Opts.OptimizationLevel > 0) { if (Opts.Inlining == CodeGenOptions::NormalInlining) - GenerateArg(Args, OPT_finline_functions, SA); + GenerateArg(Consumer, OPT_finline_functions); else if (Opts.Inlining == CodeGenOptions::OnlyHintInlining) - GenerateArg(Args, OPT_finline_hint_functions, SA); + GenerateArg(Consumer, OPT_finline_hint_functions); else if (Opts.Inlining == CodeGenOptions::OnlyAlwaysInlining) - GenerateArg(Args, OPT_fno_inline, SA); + GenerateArg(Consumer, OPT_fno_inline); } if (Opts.DirectAccessExternalData && LangOpts->PICLevel != 0) - GenerateArg(Args, OPT_fdirect_access_external_data, SA); + GenerateArg(Consumer, OPT_fdirect_access_external_data); else if (!Opts.DirectAccessExternalData && LangOpts->PICLevel == 0) - GenerateArg(Args, OPT_fno_direct_access_external_data, SA); + GenerateArg(Consumer, OPT_fno_direct_access_external_data); std::optional DebugInfoVal; switch (Opts.DebugInfo) { @@ -1421,23 +1406,23 @@ break; } if (DebugInfoVal) - GenerateArg(Args, OPT_debug_info_kind_EQ, *DebugInfoVal, SA); + GenerateArg(Consumer, OPT_debug_info_kind_EQ, *DebugInfoVal); for (const auto &Prefix : Opts.DebugPrefixMap) - GenerateArg(Args, OPT_fdebug_prefix_map_EQ, - Prefix.first + "=" + Prefix.second, SA); + GenerateArg(Consumer, OPT_fdebug_prefix_map_EQ, + Prefix.first + "=" + Prefix.second); for (const auto &Prefix : Opts.CoveragePrefixMap) - GenerateArg(Args, OPT_fcoverage_prefix_map_EQ, - Prefix.first + "=" + Prefix.second, SA); + GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ, + Prefix.first + "=" + Prefix.second); if (Opts.NewStructPathTBAA) - GenerateArg(Args, OPT_new_struct_path_tbaa, SA); + GenerateArg(Consumer, OPT_new_struct_path_tbaa); if (Opts.OptimizeSize == 1) - GenerateArg(Args, OPT_O, "s", SA); + GenerateArg(Consumer, OPT_O, "s"); else if (Opts.OptimizeSize == 2) - GenerateArg(Args, OPT_O, "z", SA); + GenerateArg(Consumer, OPT_O, "z"); // SimplifyLibCalls is set only in the absence of -fno-builtin and // -ffreestanding. We'll consider that when generating them. @@ -1445,65 +1430,65 @@ // NoBuiltinFuncs are generated by LangOptions. if (Opts.UnrollLoops && Opts.OptimizationLevel <= 1) - GenerateArg(Args, OPT_funroll_loops, SA); + GenerateArg(Consumer, OPT_funroll_loops); else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1) - GenerateArg(Args, OPT_fno_unroll_loops, SA); + GenerateArg(Consumer, OPT_fno_unroll_loops); if (!Opts.BinutilsVersion.empty()) - GenerateArg(Args, OPT_fbinutils_version_EQ, Opts.BinutilsVersion, SA); + GenerateArg(Consumer, OPT_fbinutils_version_EQ, Opts.BinutilsVersion); if (Opts.DebugNameTable == static_cast(llvm::DICompileUnit::DebugNameTableKind::GNU)) - GenerateArg(Args, OPT_ggnu_pubnames, SA); + GenerateArg(Consumer, OPT_ggnu_pubnames); else if (Opts.DebugNameTable == static_cast( llvm::DICompileUnit::DebugNameTableKind::Default)) - GenerateArg(Args, OPT_gpubnames, SA); + GenerateArg(Consumer, OPT_gpubnames); auto TNK = Opts.getDebugSimpleTemplateNames(); if (TNK != llvm::codegenoptions::DebugTemplateNamesKind::Full) { if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Simple) - GenerateArg(Args, OPT_gsimple_template_names_EQ, "simple", SA); + GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "simple"); else if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Mangled) - GenerateArg(Args, OPT_gsimple_template_names_EQ, "mangled", SA); + GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "mangled"); } // ProfileInstrumentUsePath is marshalled automatically, no need to generate // it or PGOUseInstrumentor. if (Opts.TimePasses) { if (Opts.TimePassesPerRun) - GenerateArg(Args, OPT_ftime_report_EQ, "per-pass-run", SA); + GenerateArg(Consumer, OPT_ftime_report_EQ, "per-pass-run"); else - GenerateArg(Args, OPT_ftime_report, SA); + GenerateArg(Consumer, OPT_ftime_report); } if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO) - GenerateArg(Args, OPT_flto_EQ, "full", SA); + GenerateArg(Consumer, OPT_flto_EQ, "full"); if (Opts.PrepareForThinLTO) - GenerateArg(Args, OPT_flto_EQ, "thin", SA); + GenerateArg(Consumer, OPT_flto_EQ, "thin"); if (!Opts.ThinLTOIndexFile.empty()) - GenerateArg(Args, OPT_fthinlto_index_EQ, Opts.ThinLTOIndexFile, SA); + GenerateArg(Consumer, OPT_fthinlto_index_EQ, Opts.ThinLTOIndexFile); if (Opts.SaveTempsFilePrefix == OutputFile) - GenerateArg(Args, OPT_save_temps_EQ, "obj", SA); + GenerateArg(Consumer, OPT_save_temps_EQ, "obj"); StringRef MemProfileBasename("memprof.profraw"); if (!Opts.MemoryProfileOutput.empty()) { if (Opts.MemoryProfileOutput == MemProfileBasename) { - GenerateArg(Args, OPT_fmemory_profile, SA); + GenerateArg(Consumer, OPT_fmemory_profile); } else { size_t ArgLength = Opts.MemoryProfileOutput.size() - MemProfileBasename.size(); - GenerateArg(Args, OPT_fmemory_profile_EQ, - Opts.MemoryProfileOutput.substr(0, ArgLength), SA); + GenerateArg(Consumer, OPT_fmemory_profile_EQ, + Opts.MemoryProfileOutput.substr(0, ArgLength)); } } if (memcmp(Opts.CoverageVersion, "408*", 4) != 0) - GenerateArg(Args, OPT_coverage_version_EQ, - StringRef(Opts.CoverageVersion, 4), SA); + GenerateArg(Consumer, OPT_coverage_version_EQ, + StringRef(Opts.CoverageVersion, 4)); // TODO: Check if we need to generate arguments stored in CmdArgs. (Namely // '-fembed_bitcode', which does not map to any CompilerInvocation field and @@ -1513,95 +1498,94 @@ std::string InstrBundle = serializeXRayInstrumentationBundle(Opts.XRayInstrumentationBundle); if (!InstrBundle.empty()) - GenerateArg(Args, OPT_fxray_instrumentation_bundle, InstrBundle, SA); + GenerateArg(Consumer, OPT_fxray_instrumentation_bundle, InstrBundle); } if (Opts.CFProtectionReturn && Opts.CFProtectionBranch) - GenerateArg(Args, OPT_fcf_protection_EQ, "full", SA); + GenerateArg(Consumer, OPT_fcf_protection_EQ, "full"); else if (Opts.CFProtectionReturn) - GenerateArg(Args, OPT_fcf_protection_EQ, "return", SA); + GenerateArg(Consumer, OPT_fcf_protection_EQ, "return"); else if (Opts.CFProtectionBranch) - GenerateArg(Args, OPT_fcf_protection_EQ, "branch", SA); + GenerateArg(Consumer, OPT_fcf_protection_EQ, "branch"); if (Opts.FunctionReturnThunks) - GenerateArg(Args, OPT_mfunction_return_EQ, "thunk-extern", SA); + GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern"); for (const auto &F : Opts.LinkBitcodeFiles) { bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded && F.PropagateAttrs && F.Internalize; - GenerateArg(Args, + GenerateArg(Consumer, Builtint ? OPT_mlink_builtin_bitcode : OPT_mlink_bitcode_file, - F.Filename, SA); + F.Filename); } if (Opts.EmulatedTLS) - GenerateArg(Args, OPT_femulated_tls, SA); + GenerateArg(Consumer, OPT_femulated_tls); if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE()) - GenerateArg(Args, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str(), SA); + GenerateArg(Consumer, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str()); if ((Opts.FPDenormalMode != Opts.FP32DenormalMode) || (Opts.FP32DenormalMode != llvm::DenormalMode::getIEEE())) - GenerateArg(Args, OPT_fdenormal_fp_math_f32_EQ, Opts.FP32DenormalMode.str(), - SA); + GenerateArg(Consumer, OPT_fdenormal_fp_math_f32_EQ, + Opts.FP32DenormalMode.str()); if (Opts.StructReturnConvention == CodeGenOptions::SRCK_OnStack) { OptSpecifier Opt = T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return; - GenerateArg(Args, Opt, SA); + GenerateArg(Consumer, Opt); } else if (Opts.StructReturnConvention == CodeGenOptions::SRCK_InRegs) { OptSpecifier Opt = T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return; - GenerateArg(Args, Opt, SA); + GenerateArg(Consumer, Opt); } if (Opts.EnableAIXExtendedAltivecABI) - GenerateArg(Args, OPT_mabi_EQ_vec_extabi, SA); + GenerateArg(Consumer, OPT_mabi_EQ_vec_extabi); if (Opts.XCOFFReadOnlyPointers) - GenerateArg(Args, OPT_mxcoff_roptr, SA); + GenerateArg(Consumer, OPT_mxcoff_roptr); if (!Opts.OptRecordPasses.empty()) - GenerateArg(Args, OPT_opt_record_passes, Opts.OptRecordPasses, SA); + GenerateArg(Consumer, OPT_opt_record_passes, Opts.OptRecordPasses); if (!Opts.OptRecordFormat.empty()) - GenerateArg(Args, OPT_opt_record_format, Opts.OptRecordFormat, SA); + GenerateArg(Consumer, OPT_opt_record_format, Opts.OptRecordFormat); - GenerateOptimizationRemark(Args, SA, OPT_Rpass_EQ, "pass", + GenerateOptimizationRemark(Consumer, OPT_Rpass_EQ, "pass", Opts.OptimizationRemark); - GenerateOptimizationRemark(Args, SA, OPT_Rpass_missed_EQ, "pass-missed", + GenerateOptimizationRemark(Consumer, OPT_Rpass_missed_EQ, "pass-missed", Opts.OptimizationRemarkMissed); - GenerateOptimizationRemark(Args, SA, OPT_Rpass_analysis_EQ, "pass-analysis", + GenerateOptimizationRemark(Consumer, OPT_Rpass_analysis_EQ, "pass-analysis", Opts.OptimizationRemarkAnalysis); - GenerateArg(Args, OPT_fdiagnostics_hotness_threshold_EQ, + GenerateArg(Consumer, OPT_fdiagnostics_hotness_threshold_EQ, Opts.DiagnosticsHotnessThreshold ? Twine(*Opts.DiagnosticsHotnessThreshold) - : "auto", - SA); + : "auto"); - GenerateArg(Args, OPT_fdiagnostics_misexpect_tolerance_EQ, - Twine(*Opts.DiagnosticsMisExpectTolerance), SA); + GenerateArg(Consumer, OPT_fdiagnostics_misexpect_tolerance_EQ, + Twine(*Opts.DiagnosticsMisExpectTolerance)); for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeRecover)) - GenerateArg(Args, OPT_fsanitize_recover_EQ, Sanitizer, SA); + GenerateArg(Consumer, OPT_fsanitize_recover_EQ, Sanitizer); for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeTrap)) - GenerateArg(Args, OPT_fsanitize_trap_EQ, Sanitizer, SA); + GenerateArg(Consumer, OPT_fsanitize_trap_EQ, Sanitizer); if (!Opts.EmitVersionIdentMetadata) - GenerateArg(Args, OPT_Qn, SA); + GenerateArg(Consumer, OPT_Qn); switch (Opts.FiniteLoops) { case CodeGenOptions::FiniteLoopsKind::Language: break; case CodeGenOptions::FiniteLoopsKind::Always: - GenerateArg(Args, OPT_ffinite_loops, SA); + GenerateArg(Consumer, OPT_ffinite_loops); break; case CodeGenOptions::FiniteLoopsKind::Never: - GenerateArg(Args, OPT_fno_finite_loops, SA); + GenerateArg(Consumer, OPT_fno_finite_loops); break; } } @@ -2074,18 +2058,16 @@ return Diags.getNumErrors() == NumErrorsBefore; } -static void -GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts, - SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA) { +static void GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts, + ArgumentConsumer Consumer) { const DependencyOutputOptions &DependencyOutputOpts = Opts; #define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING if (Opts.ShowIncludesDest != ShowIncludesDestination::None) - GenerateArg(Args, OPT_show_includes, SA); + GenerateArg(Consumer, OPT_show_includes); for (const auto &Dep : Opts.ExtraDeps) { switch (Dep.second) { @@ -2101,7 +2083,7 @@ // marshalling infrastructure. continue; case EDK_DepFileEntry: - GenerateArg(Args, OPT_fdepfile_entry, Dep.first, SA); + GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first); break; } } @@ -2227,12 +2209,11 @@ } static void GenerateFileSystemArgs(const FileSystemOptions &Opts, - SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA) { + ArgumentConsumer Consumer) { const FileSystemOptions &FileSystemOpts = Opts; #define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef FILE_SYSTEM_OPTION_WITH_MARSHALLING } @@ -2252,11 +2233,10 @@ } static void GenerateMigratorArgs(const MigratorOptions &Opts, - SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA) { + ArgumentConsumer Consumer) { const MigratorOptions &MigratorOpts = Opts; #define MIGRATOR_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef MIGRATOR_OPTION_WITH_MARSHALLING } @@ -2275,51 +2255,51 @@ return Diags.getNumErrors() == NumErrorsBefore; } -void CompilerInvocation::GenerateDiagnosticArgs( - const DiagnosticOptions &Opts, SmallVectorImpl &Args, - StringAllocator SA, bool DefaultDiagColor) { +void CompilerInvocation::GenerateDiagnosticArgs(const DiagnosticOptions &Opts, + ArgumentConsumer Consumer, + bool DefaultDiagColor) { const DiagnosticOptions *DiagnosticOpts = &Opts; #define DIAG_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef DIAG_OPTION_WITH_MARSHALLING if (!Opts.DiagnosticSerializationFile.empty()) - GenerateArg(Args, OPT_diagnostic_serialized_file, - Opts.DiagnosticSerializationFile, SA); + GenerateArg(Consumer, OPT_diagnostic_serialized_file, + Opts.DiagnosticSerializationFile); if (Opts.ShowColors) - GenerateArg(Args, OPT_fcolor_diagnostics, SA); + GenerateArg(Consumer, OPT_fcolor_diagnostics); if (Opts.VerifyDiagnostics && llvm::is_contained(Opts.VerifyPrefixes, "expected")) - GenerateArg(Args, OPT_verify, SA); + GenerateArg(Consumer, OPT_verify); for (const auto &Prefix : Opts.VerifyPrefixes) if (Prefix != "expected") - GenerateArg(Args, OPT_verify_EQ, Prefix, SA); + GenerateArg(Consumer, OPT_verify_EQ, Prefix); DiagnosticLevelMask VIU = Opts.getVerifyIgnoreUnexpected(); if (VIU == DiagnosticLevelMask::None) { // This is the default, don't generate anything. } else if (VIU == DiagnosticLevelMask::All) { - GenerateArg(Args, OPT_verify_ignore_unexpected, SA); + GenerateArg(Consumer, OPT_verify_ignore_unexpected); } else { if (static_cast(VIU & DiagnosticLevelMask::Note) != 0) - GenerateArg(Args, OPT_verify_ignore_unexpected_EQ, "note", SA); + GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "note"); if (static_cast(VIU & DiagnosticLevelMask::Remark) != 0) - GenerateArg(Args, OPT_verify_ignore_unexpected_EQ, "remark", SA); + GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "remark"); if (static_cast(VIU & DiagnosticLevelMask::Warning) != 0) - GenerateArg(Args, OPT_verify_ignore_unexpected_EQ, "warning", SA); + GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "warning"); if (static_cast(VIU & DiagnosticLevelMask::Error) != 0) - GenerateArg(Args, OPT_verify_ignore_unexpected_EQ, "error", SA); + GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "error"); } for (const auto &Warning : Opts.Warnings) { // This option is automatically generated from UndefPrefixes. if (Warning == "undef-prefix") continue; - Args.push_back(SA(StringRef("-W") + Warning)); + Consumer(StringRef("-W") + Warning); } for (const auto &Remark : Opts.Remarks) { @@ -2331,7 +2311,7 @@ if (llvm::is_contained(IgnoredRemarks, Remark)) continue; - Args.push_back(SA(StringRef("-R") + Remark)); + Consumer(StringRef("-R") + Remark); } } @@ -2517,12 +2497,10 @@ } static void GenerateFrontendArgs(const FrontendOptions &Opts, - SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA, - bool IsHeader) { + ArgumentConsumer Consumer, bool IsHeader) { const FrontendOptions &FrontendOpts = Opts; #define FRONTEND_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef FRONTEND_OPTION_WITH_MARSHALLING @@ -2531,7 +2509,7 @@ // Generating a simple flag covers most frontend actions. std::function GenerateProgramAction = [&]() { - GenerateArg(Args, *ProgramActionOpt, SA); + GenerateArg(Consumer, *ProgramActionOpt); }; if (!ProgramActionOpt) { @@ -2539,7 +2517,7 @@ assert(Opts.ProgramAction == frontend::PluginAction && "Frontend action without option."); GenerateProgramAction = [&]() { - GenerateArg(Args, OPT_plugin, Opts.ActionName, SA); + GenerateArg(Consumer, OPT_plugin, Opts.ActionName); }; } @@ -2560,21 +2538,21 @@ } if (Opts.ASTDumpAll) - GenerateArg(Args, OPT_ast_dump_all_EQ, Format, SA); + GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format); if (Opts.ASTDumpDecls) - GenerateArg(Args, OPT_ast_dump_EQ, Format, SA); + GenerateArg(Consumer, OPT_ast_dump_EQ, Format); } else { if (Opts.ASTDumpAll) - GenerateArg(Args, OPT_ast_dump_all, SA); + GenerateArg(Consumer, OPT_ast_dump_all); if (Opts.ASTDumpDecls) - GenerateArg(Args, OPT_ast_dump, SA); + GenerateArg(Consumer, OPT_ast_dump); } }; } if (Opts.ProgramAction == frontend::FixIt && !Opts.FixItSuffix.empty()) { GenerateProgramAction = [&]() { - GenerateArg(Args, OPT_fixit_EQ, Opts.FixItSuffix, SA); + GenerateArg(Consumer, OPT_fixit_EQ, Opts.FixItSuffix); }; } @@ -2582,34 +2560,34 @@ for (const auto &PluginArgs : Opts.PluginArgs) { Option Opt = getDriverOptTable().getOption(OPT_plugin_arg); - const char *Spelling = - SA(Opt.getPrefix() + Opt.getName() + PluginArgs.first); for (const auto &PluginArg : PluginArgs.second) - denormalizeString(Args, Spelling, SA, Opt.getKind(), 0, PluginArg); + denormalizeString(Consumer, + Opt.getPrefix() + Opt.getName() + PluginArgs.first, + Opt.getKind(), 0, PluginArg); } for (const auto &Ext : Opts.ModuleFileExtensions) if (auto *TestExt = dyn_cast_or_null(Ext.get())) - GenerateArg(Args, OPT_ftest_module_file_extension_EQ, TestExt->str(), SA); + GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str()); if (!Opts.CodeCompletionAt.FileName.empty()) - GenerateArg(Args, OPT_code_completion_at, Opts.CodeCompletionAt.ToString(), - SA); + GenerateArg(Consumer, OPT_code_completion_at, + Opts.CodeCompletionAt.ToString()); for (const auto &Plugin : Opts.Plugins) - GenerateArg(Args, OPT_load, Plugin, SA); + GenerateArg(Consumer, OPT_load, Plugin); // ASTDumpDecls and ASTDumpAll already handled with ProgramAction. for (const auto &ModuleFile : Opts.ModuleFiles) - GenerateArg(Args, OPT_fmodule_file, ModuleFile, SA); + GenerateArg(Consumer, OPT_fmodule_file, ModuleFile); if (Opts.AuxTargetCPU) - GenerateArg(Args, OPT_aux_target_cpu, *Opts.AuxTargetCPU, SA); + GenerateArg(Consumer, OPT_aux_target_cpu, *Opts.AuxTargetCPU); if (Opts.AuxTargetFeatures) for (const auto &Feature : *Opts.AuxTargetFeatures) - GenerateArg(Args, OPT_aux_target_feature, Feature, SA); + GenerateArg(Consumer, OPT_aux_target_feature, Feature); { StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : ""; @@ -2676,13 +2654,13 @@ break; } - GenerateArg(Args, OPT_x, - Lang + HeaderUnit + Header + ModuleMap + Preprocessed, SA); + GenerateArg(Consumer, OPT_x, + Lang + HeaderUnit + Header + ModuleMap + Preprocessed); } // OPT_INPUT has a unique class, generate it directly. for (const auto &Input : Opts.Inputs) - Args.push_back(SA(Input.getFile())); + Consumer(Input.getFile()); } static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, @@ -2941,28 +2919,27 @@ } static void GenerateHeaderSearchArgs(HeaderSearchOptions &Opts, - SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA) { + ArgumentConsumer Consumer) { const HeaderSearchOptions *HeaderSearchOpts = &Opts; #define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef HEADER_SEARCH_OPTION_WITH_MARSHALLING if (Opts.UseLibcxx) - GenerateArg(Args, OPT_stdlib_EQ, "libc++", SA); + GenerateArg(Consumer, OPT_stdlib_EQ, "libc++"); if (!Opts.ModuleCachePath.empty()) - GenerateArg(Args, OPT_fmodules_cache_path, Opts.ModuleCachePath, SA); + GenerateArg(Consumer, OPT_fmodules_cache_path, Opts.ModuleCachePath); for (const auto &File : Opts.PrebuiltModuleFiles) - GenerateArg(Args, OPT_fmodule_file, File.first + "=" + File.second, SA); + GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second); for (const auto &Path : Opts.PrebuiltModulePaths) - GenerateArg(Args, OPT_fprebuilt_module_path, Path, SA); + GenerateArg(Consumer, OPT_fprebuilt_module_path, Path); for (const auto &Macro : Opts.ModulesIgnoreMacros) - GenerateArg(Args, OPT_fmodules_ignore_macro, Macro.val(), SA); + GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val()); auto Matches = [](const HeaderSearchOptions::Entry &Entry, llvm::ArrayRef Groups, @@ -2993,8 +2970,8 @@ }(); if (It->Group == frontend::IndexHeaderMap) - GenerateArg(Args, OPT_index_header_map, SA); - GenerateArg(Args, Opt, It->Path, SA); + GenerateArg(Consumer, OPT_index_header_map); + GenerateArg(Consumer, Opt, It->Path); }; // Note: some paths that came from "[-iprefix=xx] -iwithprefixbefore=yy" may @@ -3006,34 +2983,34 @@ ++It) { OptSpecifier Opt = It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore; - GenerateArg(Args, Opt, It->Path, SA); + GenerateArg(Consumer, Opt, It->Path); } // Note: Some paths that came from "-idirafter=xxyy" may have already been // generated as "-iwithprefix=xxyy". If that's the case, their position on // command line was such that this has no semantic impact on include paths. for (; It < End && Matches(*It, {frontend::After}, false, true); ++It) - GenerateArg(Args, OPT_idirafter, It->Path, SA); + GenerateArg(Consumer, OPT_idirafter, It->Path); for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It) - GenerateArg(Args, OPT_iquote, It->Path, SA); + GenerateArg(Consumer, OPT_iquote, It->Path); for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt); ++It) - GenerateArg(Args, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot, - It->Path, SA); + GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot, + It->Path); for (; It < End && Matches(*It, {frontend::System}, true, true); ++It) - GenerateArg(Args, OPT_iframework, It->Path, SA); + GenerateArg(Consumer, OPT_iframework, It->Path); for (; It < End && Matches(*It, {frontend::System}, true, false); ++It) - GenerateArg(Args, OPT_iframeworkwithsysroot, It->Path, SA); + GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path); // Add the paths for the various language specific isystem flags. for (; It < End && Matches(*It, {frontend::CSystem}, false, true); ++It) - GenerateArg(Args, OPT_c_isystem, It->Path, SA); + GenerateArg(Consumer, OPT_c_isystem, It->Path); for (; It < End && Matches(*It, {frontend::CXXSystem}, false, true); ++It) - GenerateArg(Args, OPT_cxx_isystem, It->Path, SA); + GenerateArg(Consumer, OPT_cxx_isystem, It->Path); for (; It < End && Matches(*It, {frontend::ObjCSystem}, false, true); ++It) - GenerateArg(Args, OPT_objc_isystem, It->Path, SA); + GenerateArg(Consumer, OPT_objc_isystem, It->Path); for (; It < End && Matches(*It, {frontend::ObjCXXSystem}, false, true); ++It) - GenerateArg(Args, OPT_objcxx_isystem, It->Path, SA); + GenerateArg(Consumer, OPT_objcxx_isystem, It->Path); // Add the internal paths from a driver that detects standard include paths. // Note: Some paths that came from "-internal-isystem" arguments may have @@ -3045,7 +3022,7 @@ OptSpecifier Opt = It->Group == frontend::System ? OPT_internal_isystem : OPT_internal_externc_isystem; - GenerateArg(Args, Opt, It->Path, SA); + GenerateArg(Consumer, Opt, It->Path); } assert(It == End && "Unhandled HeaderSearchOption::Entry."); @@ -3054,11 +3031,11 @@ for (const auto &P : Opts.SystemHeaderPrefixes) { OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix : OPT_no_system_header_prefix; - GenerateArg(Args, Opt, P.Prefix, SA); + GenerateArg(Consumer, Opt, P.Prefix); } for (const std::string &F : Opts.VFSOverlayFiles) - GenerateArg(Args, OPT_ivfsoverlay, F, SA); + GenerateArg(Consumer, OPT_ivfsoverlay, F); } static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, @@ -3272,19 +3249,18 @@ } void CompilerInvocation::GenerateLangArgs(const LangOptions &Opts, - SmallVectorImpl &Args, - StringAllocator SA, + ArgumentConsumer Consumer, const llvm::Triple &T, InputKind IK) { if (IK.getFormat() == InputKind::Precompiled || IK.getLanguage() == Language::LLVM_IR) { if (Opts.ObjCAutoRefCount) - GenerateArg(Args, OPT_fobjc_arc, SA); + GenerateArg(Consumer, OPT_fobjc_arc); if (Opts.PICLevel != 0) - GenerateArg(Args, OPT_pic_level, Twine(Opts.PICLevel), SA); + GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel)); if (Opts.PIE) - GenerateArg(Args, OPT_pic_is_pie, SA); + GenerateArg(Consumer, OPT_pic_is_pie); for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize)) - GenerateArg(Args, OPT_fsanitize_EQ, Sanitizer, SA); + GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer); return; } @@ -3306,145 +3282,145 @@ } auto LangStandard = LangStandard::getLangStandardForKind(Opts.LangStd); - GenerateArg(Args, StdOpt, LangStandard.getName(), SA); + GenerateArg(Consumer, StdOpt, LangStandard.getName()); if (Opts.IncludeDefaultHeader) - GenerateArg(Args, OPT_finclude_default_header, SA); + GenerateArg(Consumer, OPT_finclude_default_header); if (Opts.DeclareOpenCLBuiltins) - GenerateArg(Args, OPT_fdeclare_opencl_builtins, SA); + GenerateArg(Consumer, OPT_fdeclare_opencl_builtins); const LangOptions *LangOpts = &Opts; #define LANG_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef LANG_OPTION_WITH_MARSHALLING // The '-fcf-protection=' option is generated by CodeGenOpts generator. if (Opts.ObjC) { - GenerateArg(Args, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString(), SA); + GenerateArg(Consumer, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString()); if (Opts.GC == LangOptions::GCOnly) - GenerateArg(Args, OPT_fobjc_gc_only, SA); + GenerateArg(Consumer, OPT_fobjc_gc_only); else if (Opts.GC == LangOptions::HybridGC) - GenerateArg(Args, OPT_fobjc_gc, SA); + GenerateArg(Consumer, OPT_fobjc_gc); else if (Opts.ObjCAutoRefCount == 1) - GenerateArg(Args, OPT_fobjc_arc, SA); + GenerateArg(Consumer, OPT_fobjc_arc); if (Opts.ObjCWeakRuntime) - GenerateArg(Args, OPT_fobjc_runtime_has_weak, SA); + GenerateArg(Consumer, OPT_fobjc_runtime_has_weak); if (Opts.ObjCWeak) - GenerateArg(Args, OPT_fobjc_weak, SA); + GenerateArg(Consumer, OPT_fobjc_weak); if (Opts.ObjCSubscriptingLegacyRuntime) - GenerateArg(Args, OPT_fobjc_subscripting_legacy_runtime, SA); + GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime); } if (Opts.GNUCVersion != 0) { unsigned Major = Opts.GNUCVersion / 100 / 100; unsigned Minor = (Opts.GNUCVersion / 100) % 100; unsigned Patch = Opts.GNUCVersion % 100; - GenerateArg(Args, OPT_fgnuc_version_EQ, - Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch), SA); + GenerateArg(Consumer, OPT_fgnuc_version_EQ, + Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch)); } if (Opts.IgnoreXCOFFVisibility) - GenerateArg(Args, OPT_mignore_xcoff_visibility, SA); + GenerateArg(Consumer, OPT_mignore_xcoff_visibility); if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) { - GenerateArg(Args, OPT_ftrapv, SA); - GenerateArg(Args, OPT_ftrapv_handler, Opts.OverflowHandler, SA); + GenerateArg(Consumer, OPT_ftrapv); + GenerateArg(Consumer, OPT_ftrapv_handler, Opts.OverflowHandler); } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) { - GenerateArg(Args, OPT_fwrapv, SA); + GenerateArg(Consumer, OPT_fwrapv); } if (Opts.MSCompatibilityVersion != 0) { unsigned Major = Opts.MSCompatibilityVersion / 10000000; unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100; unsigned Subminor = Opts.MSCompatibilityVersion % 100000; - GenerateArg(Args, OPT_fms_compatibility_version, - Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor), SA); + GenerateArg(Consumer, OPT_fms_compatibility_version, + Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor)); } if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17) || T.isOSzOS()) { if (!Opts.Trigraphs) - GenerateArg(Args, OPT_fno_trigraphs, SA); + GenerateArg(Consumer, OPT_fno_trigraphs); } else { if (Opts.Trigraphs) - GenerateArg(Args, OPT_ftrigraphs, SA); + GenerateArg(Consumer, OPT_ftrigraphs); } if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200)) - GenerateArg(Args, OPT_fblocks, SA); + GenerateArg(Consumer, OPT_fblocks); if (Opts.ConvergentFunctions && !(Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Opts.SYCLIsDevice)) - GenerateArg(Args, OPT_fconvergent_functions, SA); + GenerateArg(Consumer, OPT_fconvergent_functions); if (Opts.NoBuiltin && !Opts.Freestanding) - GenerateArg(Args, OPT_fno_builtin, SA); + GenerateArg(Consumer, OPT_fno_builtin); if (!Opts.NoBuiltin) for (const auto &Func : Opts.NoBuiltinFuncs) - GenerateArg(Args, OPT_fno_builtin_, Func, SA); + GenerateArg(Consumer, OPT_fno_builtin_, Func); if (Opts.LongDoubleSize == 128) - GenerateArg(Args, OPT_mlong_double_128, SA); + GenerateArg(Consumer, OPT_mlong_double_128); else if (Opts.LongDoubleSize == 64) - GenerateArg(Args, OPT_mlong_double_64, SA); + GenerateArg(Consumer, OPT_mlong_double_64); else if (Opts.LongDoubleSize == 80) - GenerateArg(Args, OPT_mlong_double_80, SA); + GenerateArg(Consumer, OPT_mlong_double_80); // Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='. // OpenMP was requested via '-fopenmp', not implied by '-fopenmp-simd' or // '-fopenmp-targets='. if (Opts.OpenMP && !Opts.OpenMPSimd) { - GenerateArg(Args, OPT_fopenmp, SA); + GenerateArg(Consumer, OPT_fopenmp); if (Opts.OpenMP != 51) - GenerateArg(Args, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP), SA); + GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP)); if (!Opts.OpenMPUseTLS) - GenerateArg(Args, OPT_fnoopenmp_use_tls, SA); + GenerateArg(Consumer, OPT_fnoopenmp_use_tls); if (Opts.OpenMPIsTargetDevice) - GenerateArg(Args, OPT_fopenmp_is_target_device, SA); + GenerateArg(Consumer, OPT_fopenmp_is_target_device); if (Opts.OpenMPIRBuilder) - GenerateArg(Args, OPT_fopenmp_enable_irbuilder, SA); + GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder); } if (Opts.OpenMPSimd) { - GenerateArg(Args, OPT_fopenmp_simd, SA); + GenerateArg(Consumer, OPT_fopenmp_simd); if (Opts.OpenMP != 51) - GenerateArg(Args, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP), SA); + GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP)); } if (Opts.OpenMPThreadSubscription) - GenerateArg(Args, OPT_fopenmp_assume_threads_oversubscription, SA); + GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription); if (Opts.OpenMPTeamSubscription) - GenerateArg(Args, OPT_fopenmp_assume_teams_oversubscription, SA); + GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription); if (Opts.OpenMPTargetDebug != 0) - GenerateArg(Args, OPT_fopenmp_target_debug_EQ, - Twine(Opts.OpenMPTargetDebug), SA); + GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ, + Twine(Opts.OpenMPTargetDebug)); if (Opts.OpenMPCUDANumSMs != 0) - GenerateArg(Args, OPT_fopenmp_cuda_number_of_sm_EQ, - Twine(Opts.OpenMPCUDANumSMs), SA); + GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ, + Twine(Opts.OpenMPCUDANumSMs)); if (Opts.OpenMPCUDABlocksPerSM != 0) - GenerateArg(Args, OPT_fopenmp_cuda_blocks_per_sm_EQ, - Twine(Opts.OpenMPCUDABlocksPerSM), SA); + GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ, + Twine(Opts.OpenMPCUDABlocksPerSM)); if (Opts.OpenMPCUDAReductionBufNum != 1024) - GenerateArg(Args, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ, - Twine(Opts.OpenMPCUDAReductionBufNum), SA); + GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ, + Twine(Opts.OpenMPCUDAReductionBufNum)); if (!Opts.OMPTargetTriples.empty()) { std::string Targets; @@ -3452,83 +3428,83 @@ llvm::interleave( Opts.OMPTargetTriples, OS, [&OS](const llvm::Triple &T) { OS << T.str(); }, ","); - GenerateArg(Args, OPT_fopenmp_targets_EQ, OS.str(), SA); + GenerateArg(Consumer, OPT_fopenmp_targets_EQ, OS.str()); } if (!Opts.OMPHostIRFile.empty()) - GenerateArg(Args, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile, SA); + GenerateArg(Consumer, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile); if (Opts.OpenMPCUDAMode) - GenerateArg(Args, OPT_fopenmp_cuda_mode, SA); + GenerateArg(Consumer, OPT_fopenmp_cuda_mode); // The arguments used to set Optimize, OptimizeSize and NoInlineDefine are // generated from CodeGenOptions. if (Opts.DefaultFPContractMode == LangOptions::FPM_Fast) - GenerateArg(Args, OPT_ffp_contract, "fast", SA); + GenerateArg(Consumer, OPT_ffp_contract, "fast"); else if (Opts.DefaultFPContractMode == LangOptions::FPM_On) - GenerateArg(Args, OPT_ffp_contract, "on", SA); + GenerateArg(Consumer, OPT_ffp_contract, "on"); else if (Opts.DefaultFPContractMode == LangOptions::FPM_Off) - GenerateArg(Args, OPT_ffp_contract, "off", SA); + GenerateArg(Consumer, OPT_ffp_contract, "off"); else if (Opts.DefaultFPContractMode == LangOptions::FPM_FastHonorPragmas) - GenerateArg(Args, OPT_ffp_contract, "fast-honor-pragmas", SA); + GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas"); for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize)) - GenerateArg(Args, OPT_fsanitize_EQ, Sanitizer, SA); + GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer); // Conflating '-fsanitize-system-ignorelist' and '-fsanitize-ignorelist'. for (const std::string &F : Opts.NoSanitizeFiles) - GenerateArg(Args, OPT_fsanitize_ignorelist_EQ, F, SA); + GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F); if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver3_8) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "3.8", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "3.8"); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver4) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "4.0", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "4.0"); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver6) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "6.0", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "6.0"); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver7) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "7.0", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "7.0"); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver9) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "9.0", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "9.0"); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver11) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "11.0", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "11.0"); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver12) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "12.0", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "12.0"); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver14) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "14.0", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "14.0"); else if (Opts.getClangABICompat() == LangOptions::ClangABI::Ver15) - GenerateArg(Args, OPT_fclang_abi_compat_EQ, "15.0", SA); + GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "15.0"); if (Opts.getSignReturnAddressScope() == LangOptions::SignReturnAddressScopeKind::All) - GenerateArg(Args, OPT_msign_return_address_EQ, "all", SA); + GenerateArg(Consumer, OPT_msign_return_address_EQ, "all"); else if (Opts.getSignReturnAddressScope() == LangOptions::SignReturnAddressScopeKind::NonLeaf) - GenerateArg(Args, OPT_msign_return_address_EQ, "non-leaf", SA); + GenerateArg(Consumer, OPT_msign_return_address_EQ, "non-leaf"); if (Opts.getSignReturnAddressKey() == LangOptions::SignReturnAddressKeyKind::BKey) - GenerateArg(Args, OPT_msign_return_address_key_EQ, "b_key", SA); + GenerateArg(Consumer, OPT_msign_return_address_key_EQ, "b_key"); if (Opts.CXXABI) - GenerateArg(Args, OPT_fcxx_abi_EQ, TargetCXXABI::getSpelling(*Opts.CXXABI), - SA); + GenerateArg(Consumer, OPT_fcxx_abi_EQ, + TargetCXXABI::getSpelling(*Opts.CXXABI)); if (Opts.RelativeCXXABIVTables) - GenerateArg(Args, OPT_fexperimental_relative_cxx_abi_vtables, SA); + GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables); else - GenerateArg(Args, OPT_fno_experimental_relative_cxx_abi_vtables, SA); + GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables); if (Opts.UseTargetPathSeparator) - GenerateArg(Args, OPT_ffile_reproducible, SA); + GenerateArg(Consumer, OPT_ffile_reproducible); else - GenerateArg(Args, OPT_fno_file_reproducible, SA); + GenerateArg(Consumer, OPT_fno_file_reproducible); for (const auto &MP : Opts.MacroPrefixMap) - GenerateArg(Args, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second, SA); + GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second); if (!Opts.RandstructSeed.empty()) - GenerateArg(Args, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed, SA); + GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed); } bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args, @@ -4129,29 +4105,27 @@ } static void GeneratePreprocessorArgs(PreprocessorOptions &Opts, - SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA, + ArgumentConsumer Consumer, const LangOptions &LangOpts, const FrontendOptions &FrontendOpts, const CodeGenOptions &CodeGenOpts) { PreprocessorOptions *PreprocessorOpts = &Opts; #define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef PREPROCESSOR_OPTION_WITH_MARSHALLING if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate) - GenerateArg(Args, OPT_pch_through_hdrstop_use, SA); + GenerateArg(Consumer, OPT_pch_through_hdrstop_use); for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn) - GenerateArg(Args, OPT_error_on_deserialized_pch_decl, D, SA); + GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D); if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false)) - GenerateArg(Args, OPT_preamble_bytes_EQ, + GenerateArg(Consumer, OPT_preamble_bytes_EQ, Twine(Opts.PrecompiledPreambleBytes.first) + "," + - (Opts.PrecompiledPreambleBytes.second ? "1" : "0"), - SA); + (Opts.PrecompiledPreambleBytes.second ? "1" : "0")); for (const auto &M : Opts.Macros) { // Don't generate __CET__ macro definitions. They are implied by the @@ -4166,7 +4140,7 @@ CodeGenOpts.CFProtectionBranch) continue; - GenerateArg(Args, M.second ? OPT_U : OPT_D, M.first, SA); + GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first); } for (const auto &I : Opts.Includes) { @@ -4181,17 +4155,17 @@ if (LangOpts.HLSL && I == "hlsl.h") continue; - GenerateArg(Args, OPT_include, I, SA); + GenerateArg(Consumer, OPT_include, I); } for (const auto &CI : Opts.ChainedIncludes) - GenerateArg(Args, OPT_chain_include, CI, SA); + GenerateArg(Consumer, OPT_chain_include, CI); for (const auto &RF : Opts.RemappedFiles) - GenerateArg(Args, OPT_remap_file, RF.first + ";" + RF.second, SA); + GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second); if (Opts.SourceDateEpoch) - GenerateArg(Args, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch), SA); + GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch)); // Don't handle LexEditorPlaceholders. It is implied by the action that is // generated elsewhere. @@ -4294,23 +4268,24 @@ return Diags.getNumErrors() == NumErrorsBefore; } -static void GeneratePreprocessorOutputArgs( - const PreprocessorOutputOptions &Opts, SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA, frontend::ActionKind Action) { +static void +GeneratePreprocessorOutputArgs(const PreprocessorOutputOptions &Opts, + ArgumentConsumer Consumer, + frontend::ActionKind Action) { const PreprocessorOutputOptions &PreprocessorOutputOpts = Opts; #define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING bool Generate_dM = isStrictlyPreprocessorAction(Action) && !Opts.ShowCPP; if (Generate_dM) - GenerateArg(Args, OPT_dM, SA); + GenerateArg(Consumer, OPT_dM); if (!Generate_dM && Opts.ShowMacros) - GenerateArg(Args, OPT_dD, SA); + GenerateArg(Consumer, OPT_dD); if (Opts.DirectivesOnly) - GenerateArg(Args, OPT_fdirectives_only, SA); + GenerateArg(Consumer, OPT_fdirectives_only); } static bool ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, @@ -4333,20 +4308,19 @@ } static void GenerateTargetArgs(const TargetOptions &Opts, - SmallVectorImpl &Args, - CompilerInvocation::StringAllocator SA) { + ArgumentConsumer Consumer) { const TargetOptions *TargetOpts = &Opts; #define TARGET_OPTION_WITH_MARSHALLING(...) \ - GENERATE_OPTION_WITH_MARSHALLING(Args, SA, __VA_ARGS__) + GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__) #include "clang/Driver/Options.inc" #undef TARGET_OPTION_WITH_MARSHALLING if (!Opts.SDKVersion.empty()) - GenerateArg(Args, OPT_target_sdk_version_EQ, Opts.SDKVersion.getAsString(), - SA); + GenerateArg(Consumer, OPT_target_sdk_version_EQ, + Opts.SDKVersion.getAsString()); if (!Opts.DarwinTargetVariantSDKVersion.empty()) - GenerateArg(Args, OPT_darwin_target_variant_sdk_version_EQ, - Opts.DarwinTargetVariantSDKVersion.getAsString(), SA); + GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ, + Opts.DarwinTargetVariantSDKVersion.getAsString()); } static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args, @@ -4616,24 +4590,24 @@ } void CompilerInvocation::generateCC1CommandLine( - SmallVectorImpl &Args, StringAllocator SA) const { + ArgumentConsumer Consumer) const { llvm::Triple T(TargetOpts->Triple); - GenerateFileSystemArgs(FileSystemOpts, Args, SA); - GenerateMigratorArgs(MigratorOpts, Args, SA); - GenerateAnalyzerArgs(*AnalyzerOpts, Args, SA); - GenerateDiagnosticArgs(*DiagnosticOpts, Args, SA, false); - GenerateFrontendArgs(FrontendOpts, Args, SA, LangOpts->IsHeaderFile); - GenerateTargetArgs(*TargetOpts, Args, SA); - GenerateHeaderSearchArgs(*HeaderSearchOpts, Args, SA); - GenerateLangArgs(*LangOpts, Args, SA, T, FrontendOpts.DashX); - GenerateCodeGenArgs(CodeGenOpts, Args, SA, T, FrontendOpts.OutputFile, + GenerateFileSystemArgs(FileSystemOpts, Consumer); + GenerateMigratorArgs(MigratorOpts, Consumer); + GenerateAnalyzerArgs(*AnalyzerOpts, Consumer); + GenerateDiagnosticArgs(*DiagnosticOpts, Consumer, false); + GenerateFrontendArgs(FrontendOpts, Consumer, LangOpts->IsHeaderFile); + GenerateTargetArgs(*TargetOpts, Consumer); + GenerateHeaderSearchArgs(*HeaderSearchOpts, Consumer); + GenerateLangArgs(*LangOpts, Consumer, T, FrontendOpts.DashX); + GenerateCodeGenArgs(CodeGenOpts, Consumer, T, FrontendOpts.OutputFile, &*LangOpts); - GeneratePreprocessorArgs(*PreprocessorOpts, Args, SA, *LangOpts, FrontendOpts, + GeneratePreprocessorArgs(*PreprocessorOpts, Consumer, *LangOpts, FrontendOpts, CodeGenOpts); - GeneratePreprocessorOutputArgs(PreprocessorOutputOpts, Args, SA, + GeneratePreprocessorOutputArgs(PreprocessorOutputOpts, Consumer, FrontendOpts.ProgramAction); - GenerateDependencyOutputArgs(DependencyOutputOpts, Args, SA); + GenerateDependencyOutputArgs(DependencyOutputOpts, Consumer); } std::vector CompilerInvocation::getCC1CommandLine() const {