28#include "clang/Config/config.h"
44#include "llvm/ADT/APInt.h"
45#include "llvm/ADT/ArrayRef.h"
46#include "llvm/ADT/CachedHashString.h"
47#include "llvm/ADT/FloatingPointMode.h"
48#include "llvm/ADT/STLExtras.h"
49#include "llvm/ADT/SmallVector.h"
50#include "llvm/ADT/StringRef.h"
51#include "llvm/ADT/StringSwitch.h"
52#include "llvm/ADT/Twine.h"
53#include "llvm/Config/llvm-config.h"
54#include "llvm/Frontend/Debug/Options.h"
55#include "llvm/IR/DebugInfoMetadata.h"
56#include "llvm/Linker/Linker.h"
57#include "llvm/MC/MCTargetOptions.h"
58#include "llvm/Option/Arg.h"
59#include "llvm/Option/ArgList.h"
60#include "llvm/Option/OptSpecifier.h"
61#include "llvm/Option/OptTable.h"
62#include "llvm/Option/Option.h"
63#include "llvm/ProfileData/InstrProfReader.h"
64#include "llvm/Remarks/HotnessThresholdParser.h"
65#include "llvm/Support/CodeGen.h"
66#include "llvm/Support/Compiler.h"
67#include "llvm/Support/Error.h"
68#include "llvm/Support/ErrorHandling.h"
69#include "llvm/Support/ErrorOr.h"
70#include "llvm/Support/FileSystem.h"
71#include "llvm/Support/HashBuilder.h"
72#include "llvm/Support/MathExtras.h"
73#include "llvm/Support/MemoryBuffer.h"
74#include "llvm/Support/Path.h"
75#include "llvm/Support/Process.h"
76#include "llvm/Support/Regex.h"
77#include "llvm/Support/VersionTuple.h"
78#include "llvm/Support/VirtualFileSystem.h"
79#include "llvm/Support/raw_ostream.h"
80#include "llvm/Target/TargetOptions.h"
81#include "llvm/TargetParser/Host.h"
82#include "llvm/TargetParser/Triple.h"
111 if (Arg.getAsInteger(10, Val))
112 return llvm::createStringError(llvm::inconvertibleErrorCode(),
113 "Not an integer: %s", Arg.data());
122 return std::make_shared<T>(
X);
193 if (Storage.use_count() > 1)
194 Storage = std::make_shared<T>(*Storage);
257#define OPTTABLE_STR_TABLE_CODE
258#include "clang/Driver/Options.inc"
259#undef OPTTABLE_STR_TABLE_CODE
262 return OptionStrTable[Offset];
265#define SIMPLE_ENUM_VALUE_TABLE
266#include "clang/Driver/Options.inc"
267#undef SIMPLE_ENUM_VALUE_TABLE
273 if (Args.hasArg(Opt))
282 if (Args.hasArg(Opt))
292 unsigned SpellingOffset, Option::OptionClass,
297 const Twine &Spelling, Option::OptionClass,
303 return !std::is_same_v<T, uint64_t> && llvm::is_integral_or_enum<T>::value;
307 std::enable_if_t<!is_uint64_t_convertible<T>(),
bool> =
false>
309 return [
Value](OptSpecifier Opt,
unsigned,
const ArgList &Args,
311 if (Args.hasArg(Opt))
318 std::enable_if_t<is_uint64_t_convertible<T>(),
bool> =
false>
324 OptSpecifier OtherOpt) {
325 return [
Value, OtherValue,
326 OtherOpt](OptSpecifier Opt,
unsigned,
const ArgList &Args,
328 if (
const Arg *A = Args.getLastArg(Opt, OtherOpt)) {
329 return A->getOption().matches(Opt) ?
Value : OtherValue;
337 Option::OptionClass,
unsigned,
bool KeyPath) {
338 if (KeyPath ==
Value)
344 const Twine &Spelling,
345 Option::OptionClass OptClass,
unsigned,
346 const Twine &
Value) {
348 case Option::SeparateClass:
349 case Option::JoinedOrSeparateClass:
350 case Option::JoinedAndSeparateClass:
354 case Option::JoinedClass:
355 case Option::CommaJoinedClass:
356 Consumer(Spelling +
Value);
359 llvm_unreachable(
"Cannot denormalize an option with option class "
360 "incompatible with string denormalization.");
367 Option::OptionClass OptClass,
unsigned TableIndex,
T Value) {
369 TableIndex, Twine(
Value));
374 Option::OptionClass OptClass,
unsigned TableIndex,
379static std::optional<SimpleEnumValue>
381 for (
int I = 0, E = Table.Size; I != E; ++I)
382 if (Name == Table.Table[I].Name)
383 return Table.Table[I];
388static std::optional<SimpleEnumValue>
390 for (
int I = 0, E = Table.Size; I != E; ++I)
392 return Table.Table[I];
401 assert(TableIndex < SimpleEnumValueTablesSize);
402 const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
404 auto *Arg = Args.getLastArg(Opt);
408 StringRef ArgValue = Arg->getValue();
410 return MaybeEnumVal->Value;
412 Diags.
Report(diag::err_drv_invalid_value)
413 << Arg->getAsString(Args) << ArgValue;
418 unsigned SpellingOffset,
419 Option::OptionClass OptClass,
420 unsigned TableIndex,
unsigned Value) {
421 assert(TableIndex < SimpleEnumValueTablesSize);
422 const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
425 TableIndex, MaybeEnumVal->Name);
427 llvm_unreachable(
"The simple enum value was not correctly defined in "
428 "the tablegen option description");
434 unsigned SpellingOffset,
435 Option::OptionClass OptClass,
436 unsigned TableIndex,
T Value) {
438 TableIndex,
static_cast<unsigned>(
Value));
445 auto *Arg = Args.getLastArg(Opt);
448 return std::string(Arg->getValue());
451template <
typename IntTy>
455 auto *Arg = Args.getLastArg(Opt);
459 if (StringRef(Arg->getValue()).getAsInteger(0, Res)) {
460 Diags.
Report(diag::err_drv_invalid_int_value)
461 << Arg->getAsString(Args) << Arg->getValue();
467static std::optional<std::vector<std::string>>
470 return Args.getAllArgValues(Opt);
474 unsigned SpellingOffset,
475 Option::OptionClass OptClass,
477 const std::vector<std::string> &Values) {
479 case Option::CommaJoinedClass: {
480 std::string CommaJoinedValue;
481 if (!Values.empty()) {
482 CommaJoinedValue.append(Values.front());
483 for (
const std::string &
Value : llvm::drop_begin(Values, 1)) {
484 CommaJoinedValue.append(
",");
485 CommaJoinedValue.append(
Value);
489 Option::OptionClass::JoinedClass, TableIndex,
493 case Option::JoinedClass:
494 case Option::SeparateClass:
495 case Option::JoinedOrSeparateClass:
496 for (
const std::string &
Value : Values)
500 llvm_unreachable(
"Cannot denormalize an option with option class "
501 "incompatible with string vector denormalization.");
509 auto *Arg = Args.getLastArg(Opt);
512 return llvm::Triple::normalize(Arg->getValue());
515template <
typename T,
typename U>
517 return static_cast<T>(
Value);
521 return KeyPath |
Value;
528template <
typename T,
typename U, U Value>
533#define PARSE_OPTION_WITH_MARSHALLING( \
534 ARGS, DIAGS, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, \
535 ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \
536 METAVAR, VALUES, SUBCOMMANDIDS_OFFSET, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
537 DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
538 MERGER, EXTRACTOR, TABLE_INDEX) \
539 if ((VISIBILITY) & options::CC1Option) { \
540 KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \
542 KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \
544 if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, ARGS, DIAGS)) \
546 MERGER(KEYPATH, static_cast<decltype(KEYPATH)>(*MaybeValue)); \
551#define GENERATE_OPTION_WITH_MARSHALLING( \
552 CONSUMER, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, ALIASARGS, \
553 FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \
554 SUBCOMMANDIDS_OFFSET, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
555 IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \
557 if ((VISIBILITY) & options::CC1Option) { \
558 [&](const auto &Extracted) { \
561 static_cast<decltype(KEYPATH)>((IMPLIED_CHECK) ? (IMPLIED_VALUE) \
562 : (DEFAULT_VALUE)))) \
563 DENORMALIZER(CONSUMER, SPELLING_OFFSET, Option::KIND##Class, \
564 TABLE_INDEX, Extracted); \
565 }(EXTRACTOR(KEYPATH)); \
579 CodeGenOpts.XRayInstrumentFunctions = LangOpts.XRayInstrument;
580 CodeGenOpts.XRayAlwaysEmitCustomEvents = LangOpts.XRayAlwaysEmitCustomEvents;
581 CodeGenOpts.XRayAlwaysEmitTypedEvents = LangOpts.XRayAlwaysEmitTypedEvents;
582 CodeGenOpts.DisableFree = FrontendOpts.
DisableFree;
585 CodeGenOpts.ClearASTBeforeBackend =
false;
587 LangOpts.ForceEmitVTables = CodeGenOpts.ForceEmitVTables;
588 LangOpts.SpeculativeLoadHardening = CodeGenOpts.SpeculativeLoadHardening;
591 llvm::Triple
T(TargetOpts.
Triple);
592 llvm::Triple::ArchType
Arch =
T.getArch();
597 if (CodeGenOpts.getExceptionHandling() !=
599 T.isWindowsMSVCEnvironment())
600 Diags.
Report(diag::err_fe_invalid_exception_model)
601 <<
static_cast<unsigned>(CodeGenOpts.getExceptionHandling()) <<
T.str();
603 if (LangOpts.AppleKext && !LangOpts.CPlusPlus)
604 Diags.
Report(diag::warn_c_kext);
606 if (LangOpts.NewAlignOverride &&
607 !llvm::isPowerOf2_32(LangOpts.NewAlignOverride)) {
608 Arg *A = Args.getLastArg(OPT_fnew_alignment_EQ);
609 Diags.
Report(diag::err_fe_invalid_alignment)
610 << A->getAsString(Args) << A->getValue();
611 LangOpts.NewAlignOverride = 0;
616 if (LangOpts.CPlusPlus11) {
617 if (Args.hasArg(OPT_fraw_string_literals, OPT_fno_raw_string_literals)) {
618 Args.claimAllArgs(OPT_fraw_string_literals, OPT_fno_raw_string_literals);
619 Diags.
Report(diag::warn_drv_fraw_string_literals_in_cxx11)
620 <<
bool(LangOpts.RawStringLiterals);
624 LangOpts.RawStringLiterals =
true;
627 LangOpts.NamedLoops =
628 Args.hasFlag(OPT_fnamed_loops, OPT_fno_named_loops, LangOpts.C2y);
631 if (LangOpts.SYCLIsDevice && LangOpts.SYCLIsHost)
632 Diags.
Report(diag::err_drv_argument_not_allowed_with) <<
"-fsycl-is-device"
635 if (Args.hasArg(OPT_fgnu89_inline) && LangOpts.CPlusPlus)
636 Diags.
Report(diag::err_drv_argument_not_allowed_with)
639 if (Args.hasArg(OPT_hlsl_entrypoint) && !LangOpts.HLSL)
640 Diags.
Report(diag::err_drv_argument_not_allowed_with)
643 if (Args.hasArg(OPT_fdx_rootsignature_version) && !LangOpts.HLSL)
644 Diags.
Report(diag::err_drv_argument_not_allowed_with)
647 if (Args.hasArg(OPT_fdx_rootsignature_define) && !LangOpts.HLSL)
648 Diags.
Report(diag::err_drv_argument_not_allowed_with)
651 if (Args.hasArg(OPT_fgpu_allow_device_init) && !LangOpts.HIP)
652 Diags.
Report(diag::warn_ignored_hip_only_option)
653 << Args.getLastArg(OPT_fgpu_allow_device_init)->getAsString(Args);
655 if (Args.hasArg(OPT_gpu_max_threads_per_block_EQ) && !LangOpts.HIP)
656 Diags.
Report(diag::warn_ignored_hip_only_option)
657 << Args.getLastArg(OPT_gpu_max_threads_per_block_EQ)->getAsString(Args);
666 if (Args.hasArg(OPT_ffp_eval_method_EQ)) {
667 if (LangOpts.ApproxFunc)
668 Diags.
Report(diag::err_incompatible_fp_eval_method_options) << 0;
669 if (LangOpts.AllowFPReassoc)
670 Diags.
Report(diag::err_incompatible_fp_eval_method_options) << 1;
671 if (LangOpts.AllowRecip)
672 Diags.
Report(diag::err_incompatible_fp_eval_method_options) << 2;
678 if (Args.getLastArg(OPT_cl_strict_aliasing) &&
680 Diags.
Report(diag::warn_option_invalid_ocl_version)
682 << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args);
684 if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
685 auto DefaultCC = LangOpts.getDefaultCallingConv();
689 Arch != llvm::Triple::x86;
695 Diags.
Report(diag::err_drv_argument_not_allowed_with)
696 << A->getSpelling() <<
T.getTriple();
708 unsigned DefaultOpt = 0;
711 !Args.hasArg(OPT_cl_opt_disable))
714 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
715 if (A->getOption().matches(options::OPT_O0))
718 if (A->getOption().matches(options::OPT_Ofast))
721 assert(A->getOption().matches(options::OPT_O));
723 StringRef S(A->getValue());
724 if (S ==
"s" || S ==
"z")
737 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
738 if (A->getOption().matches(options::OPT_O)) {
739 switch (A->getValue()[0]) {
753 llvm::opt::OptSpecifier OptSpecifier) {
756 Option::OptionClass::FlagClass, 0);
760 llvm::opt::OptSpecifier OptSpecifier,
761 const Twine &
Value) {
799 bool CheckAgainstOriginalInvocation =
false,
800 bool ForceRoundTrip =
false) {
802 bool DoRoundTripDefault =
true;
804 bool DoRoundTripDefault =
false;
807 bool DoRoundTrip = DoRoundTripDefault;
808 if (ForceRoundTrip) {
811 for (
const auto *Arg : CommandLineArgs) {
812 if (Arg == StringRef(
"-round-trip-args"))
814 if (Arg == StringRef(
"-no-round-trip-args"))
822 return Parse(RealInvocation, CommandLineArgs, Diags, Argv0);
827 llvm::raw_string_ostream OS(Buffer);
828 for (
const char *Arg : Args) {
829 llvm::sys::printArg(OS, Arg,
true);
842 if (!
Parse(DummyInvocation, CommandLineArgs, DummyDiags, Argv0) ||
849 auto Success =
Parse(RealInvocation, CommandLineArgs, Diags, Argv0);
855 Diags.
Report(diag::err_cc1_round_trip_fail_then_ok);
856 Diags.
Report(diag::note_cc1_round_trip_original)
857 << SerializeArgs(CommandLineArgs);
862 llvm::BumpPtrAllocator Alloc;
863 llvm::StringSaver StringPool(Alloc);
864 auto SA = [&StringPool](
const Twine &Arg) {
865 return StringPool.save(Arg).data();
872 Generate(DummyInvocation, GeneratedArgs, SA);
878 bool Success2 =
Parse(RealInvocation, GeneratedArgs, Diags, Argv0);
883 Diags.
Report(diag::err_cc1_round_trip_ok_then_fail);
884 Diags.
Report(diag::note_cc1_round_trip_generated)
885 << 1 << SerializeArgs(GeneratedArgs);
890 if (CheckAgainstOriginalInvocation)
892 ComparisonArgs.assign(CommandLineArgs.begin(), CommandLineArgs.end());
896 Generate(RealInvocation, ComparisonArgs, SA);
901 return std::equal(A.begin(), A.end(), B.begin(), B.end(),
902 [](
const char *AElem,
const char *BElem) {
903 return StringRef(AElem) == StringRef(BElem);
910 if (!
Equal(GeneratedArgs, ComparisonArgs)) {
911 Diags.
Report(diag::err_cc1_round_trip_mismatch);
912 Diags.
Report(diag::note_cc1_round_trip_generated)
913 << 1 << SerializeArgs(GeneratedArgs);
914 Diags.
Report(diag::note_cc1_round_trip_generated)
915 << 2 << SerializeArgs(ComparisonArgs);
919 Diags.
Report(diag::remark_cc1_round_trip_generated)
920 << 1 << SerializeArgs(GeneratedArgs);
921 Diags.
Report(diag::remark_cc1_round_trip_generated)
922 << 2 << SerializeArgs(ComparisonArgs);
934 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
938 Args.push_back(
"-cc1");
941 DummyInvocation1, DummyInvocation2, Args, Diags, Argv0,
946 OptSpecifier GroupWithValue,
947 std::vector<std::string> &Diagnostics) {
948 for (
auto *A : Args.filtered(Group)) {
949 if (A->getOption().getKind() == Option::FlagClass) {
952 Diagnostics.push_back(
953 std::string(A->getOption().getName().drop_front(1)));
954 }
else if (A->getOption().matches(GroupWithValue)) {
957 Diagnostics.push_back(
958 std::string(A->getOption().getName().drop_front(1).rtrim(
"=-")));
961 Diagnostics.push_back(A->getValue());
972 std::vector<std::string> &Funcs) {
973 std::vector<std::string> Values = Args.getAllArgValues(OPT_fno_builtin_);
975 Funcs.insert(Funcs.end(), Values.begin(), BuiltinEnd);
982#define ANALYZER_OPTION_WITH_MARSHALLING(...) \
983 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
984#include "clang/Driver/Options.inc"
985#undef ANALYZER_OPTION_WITH_MARSHALLING
989#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
991 GenerateArg(Consumer, OPT_analyzer_constraints, CMDFLAG); \
993#include "clang/StaticAnalyzer/Core/Analyses.def"
995 llvm_unreachable(
"Tried to generate unknown analysis constraint.");
1001#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
1003 GenerateArg(Consumer, OPT_analyzer_output, CMDFLAG); \
1005#include "clang/StaticAnalyzer/Core/Analyses.def"
1007 llvm_unreachable(
"Tried to generate unknown analysis diagnostic client.");
1013#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
1015 GenerateArg(Consumer, OPT_analyzer_purge, CMDFLAG); \
1017#include "clang/StaticAnalyzer/Core/Analyses.def"
1019 llvm_unreachable(
"Tried to generate unknown analysis purge mode.");
1025#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
1027 GenerateArg(Consumer, OPT_analyzer_inlining_mode, CMDFLAG); \
1029#include "clang/StaticAnalyzer/Core/Analyses.def"
1031 llvm_unreachable(
"Tried to generate unknown analysis inlining mode.");
1037 CP.second ? OPT_analyzer_checker : OPT_analyzer_disable_checker;
1046 for (
const auto &
C : Opts.
Config)
1047 SortedConfigOpts.emplace_back(
C.getKey(),
C.getValue());
1048 llvm::sort(SortedConfigOpts, llvm::less_first());
1050 for (
const auto &[Key,
Value] : SortedConfigOpts) {
1053 auto Entry = ConfigOpts.
Config.find(Key);
1054 if (Entry != ConfigOpts.
Config.end() && Entry->getValue() ==
Value)
1069#define ANALYZER_OPTION_WITH_MARSHALLING(...) \
1070 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
1071#include "clang/Driver/Options.inc"
1072#undef ANALYZER_OPTION_WITH_MARSHALLING
1074 if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
1075 StringRef Name = A->getValue();
1077#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
1078 .Case(CMDFLAG, NAME##Model)
1079#include "clang/StaticAnalyzer/Core/Analyses.def"
1082 Diags.
Report(diag::err_drv_invalid_value)
1083 << A->getAsString(Args) << Name;
1086 if (
Value == AnalysisConstraints::Z3ConstraintsModel) {
1087 Diags.
Report(diag::err_analyzer_not_built_with_z3);
1094 if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
1095 StringRef Name = A->getValue();
1097#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
1098 .Case(CMDFLAG, PD_##NAME)
1099#include "clang/StaticAnalyzer/Core/Analyses.def"
1102 Diags.
Report(diag::err_drv_invalid_value)
1103 << A->getAsString(Args) << Name;
1109 if (Arg *A = Args.getLastArg(OPT_analyzer_purge)) {
1110 StringRef Name = A->getValue();
1112#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
1113 .Case(CMDFLAG, NAME)
1114#include "clang/StaticAnalyzer/Core/Analyses.def"
1117 Diags.
Report(diag::err_drv_invalid_value)
1118 << A->getAsString(Args) << Name;
1124 if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {
1125 StringRef Name = A->getValue();
1127#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
1128 .Case(CMDFLAG, NAME)
1129#include "clang/StaticAnalyzer/Core/Analyses.def"
1132 Diags.
Report(diag::err_drv_invalid_value)
1133 << A->getAsString(Args) << Name;
1141 Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {
1143 bool IsEnabled = A->getOption().getID() == OPT_analyzer_checker;
1146 StringRef CheckerAndPackageList = A->getValue();
1148 CheckerAndPackageList.split(CheckersAndPackages,
",");
1149 for (
const StringRef &CheckerOrPackage : CheckersAndPackages)
1155 for (
const auto *A : Args.filtered(OPT_analyzer_config)) {
1159 StringRef configList = A->getValue();
1161 configList.split(configVals,
",");
1162 for (
const auto &configVal : configVals) {
1164 std::tie(key, val) = configVal.split(
"=");
1167 diag::err_analyzer_config_no_value) << configVal;
1170 if (val.contains(
'=')) {
1172 diag::err_analyzer_config_multiple_values)
1181 Diags.
Report(diag::err_analyzer_config_unknown) << key;
1186 Opts.
Config[key] = std::string(val);
1196 for (
unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) {
1199 os << Args.getArgString(i);
1206 StringRef OptionName, StringRef DefaultVal) {
1207 return Config.insert({OptionName, std::string(DefaultVal)}).first->second;
1212 StringRef &OptionField, StringRef Name,
1213 StringRef DefaultVal) {
1222 bool &OptionField, StringRef Name,
bool DefaultVal) {
1223 auto PossiblyInvalidVal =
1224 llvm::StringSwitch<std::optional<bool>>(
1227 .Case(
"false",
false)
1228 .Default(std::nullopt);
1230 if (!PossiblyInvalidVal) {
1232 Diags->
Report(diag::err_analyzer_config_invalid_input)
1233 << Name <<
"a boolean";
1235 OptionField = DefaultVal;
1237 OptionField = *PossiblyInvalidVal;
1242 unsigned &OptionField, StringRef Name,
1243 unsigned DefaultVal) {
1245 OptionField = DefaultVal;
1246 bool HasFailed =
getStringOption(Config, Name, std::to_string(DefaultVal))
1247 .getAsInteger(0, OptionField);
1248 if (Diags && HasFailed)
1249 Diags->
Report(diag::err_analyzer_config_invalid_input)
1250 << Name <<
"an unsigned";
1256 unsigned DefaultVal) {
1259 if (Parsed.has_value()) {
1260 OptionField = Parsed.value();
1263 if (Diags && !Parsed.has_value())
1264 Diags->
Report(diag::err_analyzer_config_invalid_input)
1265 << Name <<
"a positive";
1267 OptionField = DefaultVal;
1275#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
1276 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEFAULT_VAL);
1277#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(...)
1278#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1280 assert(AnOpts.UserMode ==
"shallow" || AnOpts.UserMode ==
"deep");
1281 const bool InShallowMode = AnOpts.UserMode ==
"shallow";
1283#define ANALYZER_OPTION(...)
1284#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
1285 SHALLOW_VAL, DEEP_VAL) \
1286 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, \
1287 InShallowMode ? SHALLOW_VAL : DEEP_VAL);
1288#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1295 if (!AnOpts.RawSilencedCheckersAndPackages.empty()) {
1296 std::vector<StringRef> Checkers =
1298 std::vector<StringRef> Packages =
1302 AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages,
";");
1304 for (
const StringRef &CheckerOrPackage : CheckersAndPackages) {
1306 bool IsChecker = CheckerOrPackage.contains(
'.');
1307 bool IsValidName = IsChecker
1308 ? llvm::is_contained(Checkers, CheckerOrPackage)
1309 : llvm::is_contained(Packages, CheckerOrPackage);
1312 Diags->
Report(diag::err_unknown_analyzer_checker_or_package)
1313 << CheckerOrPackage;
1323 if (AnOpts.ShouldTrackConditionsDebug && !AnOpts.ShouldTrackConditions)
1324 Diags->
Report(diag::err_analyzer_config_invalid_input)
1325 <<
"track-conditions-debug" <<
"'track-conditions' to also be enabled";
1333 if (
Remark.hasValidPattern()) {
1338 GenerateArg(Consumer, OPT_R_Joined, StringRef(
"no-") + Name);
1347 OptSpecifier OptEQ, StringRef Name) {
1350 auto InitializeResultPattern = [&Diags, &Args, &Result](
const Arg *A,
1351 StringRef Pattern) {
1352 Result.Pattern = Pattern.str();
1354 std::string RegexError;
1355 Result.Regex = std::make_shared<llvm::Regex>(Result.Pattern);
1356 if (!Result.Regex->isValid(RegexError)) {
1357 Diags.
Report(diag::err_drv_optimization_remark_pattern)
1358 << RegexError << A->getAsString(Args);
1365 for (Arg *A : Args) {
1366 if (A->getOption().matches(OPT_R_Joined)) {
1367 StringRef
Value = A->getValue();
1371 else if (
Value ==
"everything")
1373 else if (
Value.split(
'-') == std::make_pair(StringRef(
"no"), Name))
1375 else if (
Value ==
"no-everything")
1382 Result.Pattern =
"";
1383 Result.Regex =
nullptr;
1385 InitializeResultPattern(A,
".*");
1387 }
else if (A->getOption().matches(OptEQ)) {
1389 if (!InitializeResultPattern(A, A->getValue()))
1398 const std::vector<std::string> &Levels,
1402 for (
const auto &Level : Levels) {
1404 llvm::StringSwitch<DiagnosticLevelMask>(Level)
1412 Diags.
Report(diag::err_drv_invalid_value) << FlagName << Level;
1420 const std::vector<std::string> &Sanitizers,
1422 for (
const auto &Sanitizer : Sanitizers) {
1425 Diags.
Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1439 const std::vector<std::string> &Sanitizers,
1442 for (
const auto &Sanitizer : Sanitizers) {
1444 Diags.
Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1453 llvm::SplitString(Bundle, BundleParts,
",");
1454 for (
const auto &B : BundleParts) {
1458 D.
Report(diag::err_drv_invalid_value) << FlagName << Bundle;
1472 llvm::raw_string_ostream OS(Buffer);
1473 llvm::interleave(BundleParts, OS, [&OS](StringRef Part) { OS << Part; },
",");
1479 const llvm::Triple &Triple) {
1480 assert(Triple.getArch() == llvm::Triple::aarch64);
1487 LangOpts.PointerAuthFunctionTypeDiscrimination ? Discrimination::Type
1488 : Discrimination::None);
1491 Key::ASDA,
LangOpts.PointerAuthVTPtrAddressDiscrimination,
1492 LangOpts.PointerAuthVTPtrTypeDiscrimination ? Discrimination::Type
1493 : Discrimination::None);
1495 if (
LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)
1510 if (
LangOpts.PointerAuthInitFini) {
1512 Key::ASIA,
LangOpts.PointerAuthInitFiniAddressDiscrimination,
1522 if (
LangOpts.PointerAuthBlockDescriptorPointers)
1541 if (
LangOpts.PointerAuthObjcClassROPointers)
1554 const llvm::Triple &Triple,
1556 if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthReturns &&
1557 !LangOpts.PointerAuthAuthTraps && !LangOpts.PointerAuthIndirectGotos &&
1558 !LangOpts.AArch64JumpTableHardening)
1564void CompilerInvocationBase::GenerateCodeGenArgs(
const CodeGenOptions &Opts,
1566 const llvm::Triple &
T,
1567 const std::string &OutputFile,
1571 if (Opts.OptimizationLevel == 0)
1574 GenerateArg(Consumer, OPT_O, Twine(Opts.OptimizationLevel));
1576#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1577 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
1578#include "clang/Driver/Options.inc"
1579#undef CODEGEN_OPTION_WITH_MARSHALLING
1581 if (Opts.OptimizationLevel > 0) {
1585 GenerateArg(Consumer, OPT_finline_hint_functions);
1590 if (Opts.DirectAccessExternalData &&
LangOpts->PICLevel != 0)
1591 GenerateArg(Consumer, OPT_fdirect_access_external_data);
1592 else if (!Opts.DirectAccessExternalData &&
LangOpts->PICLevel == 0)
1593 GenerateArg(Consumer, OPT_fno_direct_access_external_data);
1595 std::optional<StringRef> DebugInfoVal;
1596 switch (Opts.DebugInfo) {
1597 case llvm::codegenoptions::DebugLineTablesOnly:
1598 DebugInfoVal =
"line-tables-only";
1600 case llvm::codegenoptions::DebugDirectivesOnly:
1601 DebugInfoVal =
"line-directives-only";
1603 case llvm::codegenoptions::DebugInfoConstructor:
1604 DebugInfoVal =
"constructor";
1606 case llvm::codegenoptions::LimitedDebugInfo:
1607 DebugInfoVal =
"limited";
1609 case llvm::codegenoptions::FullDebugInfo:
1610 DebugInfoVal =
"standalone";
1612 case llvm::codegenoptions::UnusedTypeInfo:
1613 DebugInfoVal =
"unused-types";
1615 case llvm::codegenoptions::NoDebugInfo:
1616 DebugInfoVal = std::nullopt;
1618 case llvm::codegenoptions::LocTrackingOnly:
1619 DebugInfoVal = std::nullopt;
1623 GenerateArg(Consumer, OPT_debug_info_kind_EQ, *DebugInfoVal);
1627 Prefix.first +
"=" + Prefix.second);
1630 GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,
1631 Prefix.first +
"=" + Prefix.second);
1633 if (Opts.NewStructPathTBAA)
1636 if (Opts.OptimizeSize == 1)
1638 else if (Opts.OptimizeSize == 2)
1646 if (Opts.UnrollLoops && Opts.OptimizationLevel <= 1)
1648 else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1)
1651 if (Opts.InterchangeLoops)
1657 GenerateArg(Consumer, OPT_fexperimental_loop_fusion);
1662 if (Opts.DebugNameTable ==
1663 static_cast<unsigned>(llvm::DICompileUnit::DebugNameTableKind::GNU))
1665 else if (Opts.DebugNameTable ==
1666 static_cast<unsigned>(
1667 llvm::DICompileUnit::DebugNameTableKind::Default))
1670 if (Opts.DebugTemplateAlias)
1673 auto TNK = Opts.getDebugSimpleTemplateNames();
1674 if (TNK != llvm::codegenoptions::DebugTemplateNamesKind::Full) {
1675 if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Simple)
1676 GenerateArg(Consumer, OPT_gsimple_template_names_EQ,
"simple");
1677 else if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Mangled)
1678 GenerateArg(Consumer, OPT_gsimple_template_names_EQ,
"mangled");
1683 if (Opts.TimePasses) {
1684 if (Opts.TimePassesPerRun)
1685 GenerateArg(Consumer, OPT_ftime_report_EQ,
"per-pass-run");
1689 if (Opts.TimePassesJson)
1693 if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)
1696 if (Opts.PrepareForThinLTO)
1705 StringRef MemProfileBasename(
"memprof.profraw");
1726 std::string InstrBundle =
1728 if (!InstrBundle.empty())
1729 GenerateArg(Consumer, OPT_fxray_instrumentation_bundle, InstrBundle);
1732 if (Opts.CFProtectionReturn && Opts.CFProtectionBranch)
1733 GenerateArg(Consumer, OPT_fcf_protection_EQ,
"full");
1734 else if (Opts.CFProtectionReturn)
1735 GenerateArg(Consumer, OPT_fcf_protection_EQ,
"return");
1736 else if (Opts.CFProtectionBranch)
1737 GenerateArg(Consumer, OPT_fcf_protection_EQ,
"branch");
1739 if (Opts.CFProtectionBranch) {
1740 switch (Opts.getCFBranchLabelScheme()) {
1743#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
1744 case CFBranchLabelSchemeKind::Kind: \
1745 GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, #FlagVal); \
1747#include "clang/Basic/CFProtectionOptions.def"
1751 if (Opts.FunctionReturnThunks)
1752 GenerateArg(Consumer, OPT_mfunction_return_EQ,
"thunk-extern");
1755 bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded &&
1756 F.PropagateAttrs && F.Internalize;
1758 Builtint ? OPT_mlink_builtin_bitcode : OPT_mlink_bitcode_file,
1762 if (Opts.EmulatedTLS)
1770 GenerateArg(Consumer, OPT_fdenormal_fp_math_f32_EQ,
1775 T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return;
1779 T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return;
1783 if (Opts.EnableAIXExtendedAltivecABI)
1786 if (Opts.XCOFFReadOnlyPointers)
1804 GenerateArg(Consumer, OPT_fdiagnostics_hotness_threshold_EQ,
1809 GenerateArg(Consumer, OPT_fdiagnostics_misexpect_tolerance_EQ,
1813 GenerateArg(Consumer, OPT_fsanitize_recover_EQ, Sanitizer);
1816 GenerateArg(Consumer, OPT_fsanitize_trap_EQ, Sanitizer);
1818 for (StringRef Sanitizer :
1820 GenerateArg(Consumer, OPT_fsanitize_merge_handlers_EQ, Sanitizer);
1822 SmallVector<std::string, 4> Values;
1824 for (std::string Sanitizer : Values)
1825 GenerateArg(Consumer, OPT_fsanitize_skip_hot_cutoff_EQ, Sanitizer);
1828 GenerateArg(Consumer, OPT_fallow_runtime_check_skip_hot_cutoff_EQ,
1832 for (StringRef Sanitizer :
1834 GenerateArg(Consumer, OPT_fsanitize_annotate_debug_info_EQ, Sanitizer);
1836 if (!Opts.EmitVersionIdentMetadata)
1839 switch (Opts.FiniteLoops) {
1850 if (Opts.StaticClosure)
1854bool CompilerInvocation::ParseCodeGenArgs(
CodeGenOptions &Opts, ArgList &Args,
1857 const llvm::Triple &
T,
1858 const std::string &OutputFile,
1864 unsigned MaxOptLevel = 3;
1865 if (OptimizationLevel > MaxOptLevel) {
1868 Diags.
Report(diag::warn_drv_optimization_value)
1869 << Args.getLastArg(OPT_O)->getAsString(Args) <<
"-O" << MaxOptLevel;
1870 OptimizationLevel = MaxOptLevel;
1872 Opts.OptimizationLevel = OptimizationLevel;
1879 const LangOptions *
LangOpts = &LangOptsRef;
1881#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1882 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
1883#include "clang/Driver/Options.inc"
1884#undef CODEGEN_OPTION_WITH_MARSHALLING
1888 if (Opts.OptimizationLevel == 0) {
1890 }
else if (
const Arg *A = Args.getLastArg(options::OPT_finline_functions,
1891 options::OPT_finline_hint_functions,
1892 options::OPT_fno_inline_functions,
1893 options::OPT_fno_inline)) {
1896 if (A->getOption().matches(options::OPT_finline_functions))
1898 else if (A->getOption().matches(options::OPT_finline_hint_functions))
1908 Opts.DirectAccessExternalData =
1909 Args.hasArg(OPT_fdirect_access_external_data) ||
1910 (!Args.hasArg(OPT_fno_direct_access_external_data) &&
1913 if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
1915 llvm::StringSwitch<unsigned>(A->getValue())
1916 .Case(
"line-tables-only", llvm::codegenoptions::DebugLineTablesOnly)
1917 .Case(
"line-directives-only",
1918 llvm::codegenoptions::DebugDirectivesOnly)
1919 .Case(
"constructor", llvm::codegenoptions::DebugInfoConstructor)
1920 .Case(
"limited", llvm::codegenoptions::LimitedDebugInfo)
1921 .Case(
"standalone", llvm::codegenoptions::FullDebugInfo)
1922 .Case(
"unused-types", llvm::codegenoptions::UnusedTypeInfo)
1925 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1928 Opts.setDebugInfo(
static_cast<llvm::codegenoptions::DebugInfoKind
>(Val));
1934 Args.getLastArg(OPT_fuse_ctor_homing, OPT_fno_use_ctor_homing)) {
1935 if (A->getOption().matches(OPT_fuse_ctor_homing) &&
1936 Opts.getDebugInfo() == llvm::codegenoptions::LimitedDebugInfo)
1937 Opts.setDebugInfo(llvm::codegenoptions::DebugInfoConstructor);
1938 if (A->getOption().matches(OPT_fno_use_ctor_homing) &&
1939 Opts.getDebugInfo() == llvm::codegenoptions::DebugInfoConstructor)
1940 Opts.setDebugInfo(llvm::codegenoptions::LimitedDebugInfo);
1943 for (
const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) {
1944 auto Split = StringRef(Arg).split(
'=');
1948 for (
const auto &Arg : Args.getAllArgValues(OPT_fcoverage_prefix_map_EQ)) {
1949 auto Split = StringRef(Arg).split(
'=');
1953 const llvm::Triple::ArchType DebugEntryValueArchs[] = {
1954 llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64,
1955 llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips,
1956 llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el,
1957 llvm::Triple::riscv32, llvm::Triple::riscv64};
1960 llvm::is_contained(DebugEntryValueArchs,
T.getArch()))
1961 Opts.EmitCallSiteInfo =
true;
1964 Diags.
Report(diag::warn_ignoring_verify_debuginfo_preserve_export)
1969 Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
1970 Args.hasArg(OPT_new_struct_path_tbaa);
1972 Opts.SimplifyLibCalls = !
LangOpts->NoBuiltin;
1973 if (Opts.SimplifyLibCalls)
1976 Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
1977 (Opts.OptimizationLevel > 1));
1978 Opts.InterchangeLoops =
1979 Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange,
false);
1980 Opts.FuseLoops = Args.hasFlag(OPT_fexperimental_loop_fusion,
1981 OPT_fno_experimental_loop_fusion,
false);
1983 std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));
1985 Opts.DebugTemplateAlias = Args.hasArg(OPT_gtemplate_alias);
1987 Opts.DebugNameTable =
static_cast<unsigned>(
1988 Args.hasArg(OPT_ggnu_pubnames)
1989 ? llvm::DICompileUnit::DebugNameTableKind::GNU
1990 : Args.hasArg(OPT_gpubnames)
1991 ? llvm::DICompileUnit::DebugNameTableKind::Default
1992 : llvm::DICompileUnit::DebugNameTableKind::None);
1993 if (
const Arg *A = Args.getLastArg(OPT_gsimple_template_names_EQ)) {
1994 StringRef
Value = A->getValue();
1996 Diags.
Report(diag::err_drv_unsupported_option_argument)
1997 << A->getSpelling() << A->getValue();
1998 Opts.setDebugSimpleTemplateNames(
1999 StringRef(A->getValue()) ==
"simple"
2000 ? llvm::codegenoptions::DebugTemplateNamesKind::Simple
2001 : llvm::codegenoptions::DebugTemplateNamesKind::Mangled);
2004 if (Args.hasArg(OPT_ftime_report, OPT_ftime_report_EQ, OPT_ftime_report_json,
2005 OPT_stats_file_timers)) {
2006 Opts.TimePasses =
true;
2009 if (
const Arg *EQ = Args.getLastArg(OPT_ftime_report_EQ)) {
2010 StringRef Val =
EQ->getValue();
2011 if (Val ==
"per-pass")
2012 Opts.TimePassesPerRun =
false;
2013 else if (Val ==
"per-pass-run")
2014 Opts.TimePassesPerRun =
true;
2016 Diags.
Report(diag::err_drv_invalid_value)
2017 <<
EQ->getAsString(Args) <<
EQ->getValue();
2020 if (Args.getLastArg(OPT_ftime_report_json))
2021 Opts.TimePassesJson =
true;
2024 Opts.PrepareForLTO =
false;
2025 Opts.PrepareForThinLTO =
false;
2026 if (Arg *A = Args.getLastArg(OPT_flto_EQ)) {
2027 Opts.PrepareForLTO =
true;
2028 StringRef S = A->getValue();
2030 Opts.PrepareForThinLTO =
true;
2031 else if (S !=
"full")
2032 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
2033 if (Args.hasArg(OPT_funified_lto))
2034 Opts.PrepareForThinLTO =
true;
2036 if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
2038 Diags.
Report(diag::err_drv_argument_only_allowed_with)
2039 << A->getAsString(Args) <<
"-x ir";
2041 std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ));
2043 if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))
2045 llvm::StringSwitch<std::string>(A->getValue())
2046 .Case(
"obj", OutputFile)
2047 .Default(llvm::sys::path::filename(OutputFile).str());
2050 const char *MemProfileBasename =
"memprof.profraw";
2051 if (Args.hasArg(OPT_fmemory_profile_EQ)) {
2052 SmallString<128> Path(Args.getLastArgValue(OPT_fmemory_profile_EQ));
2053 llvm::sys::path::append(Path, MemProfileBasename);
2055 }
else if (Args.hasArg(OPT_fmemory_profile))
2059 if (Args.hasArg(OPT_coverage_version_EQ)) {
2060 StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
2061 if (CoverageVersion.size() != 4) {
2062 Diags.
Report(diag::err_drv_invalid_value)
2063 << Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)
2073 for (
const auto &A : Args) {
2075 if (A->getOption().getID() == options::OPT_o ||
2076 A->getOption().getID() == options::OPT_INPUT ||
2077 A->getOption().getID() == options::OPT_x ||
2078 A->getOption().getID() == options::OPT_fembed_bitcode ||
2079 A->getOption().matches(options::OPT_W_Group))
2082 A->render(Args, ASL);
2083 for (
const auto &arg : ASL) {
2084 StringRef ArgStr(arg);
2085 llvm::append_range(Opts.
CmdArgs, ArgStr);
2091 auto XRayInstrBundles =
2092 Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
2093 if (XRayInstrBundles.empty())
2096 for (
const auto &A : XRayInstrBundles)
2100 if (
const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
2101 StringRef Name = A->getValue();
2102 if (Name ==
"full") {
2103 Opts.CFProtectionReturn = 1;
2104 Opts.CFProtectionBranch = 1;
2105 }
else if (Name ==
"return")
2106 Opts.CFProtectionReturn = 1;
2107 else if (Name ==
"branch")
2108 Opts.CFProtectionBranch = 1;
2109 else if (Name !=
"none")
2110 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
2113 if (Opts.CFProtectionBranch &&
T.isRISCV()) {
2114 if (
const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
2116 llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
2117#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
2118 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
2119#include "clang/Basic/CFProtectionOptions.def"
2122 Opts.setCFBranchLabelScheme(Scheme);
2124 Diags.
Report(diag::err_drv_invalid_value)
2125 << A->getAsString(Args) << A->getValue();
2129 if (
const Arg *A = Args.getLastArg(OPT_mfunction_return_EQ)) {
2130 auto Val = llvm::StringSwitch<llvm::FunctionReturnThunksKind>(A->getValue())
2131 .Case(
"keep", llvm::FunctionReturnThunksKind::Keep)
2132 .Case(
"thunk-extern", llvm::FunctionReturnThunksKind::Extern)
2133 .Default(llvm::FunctionReturnThunksKind::Invalid);
2136 Diags.
Report(diag::err_drv_argument_not_allowed_with)
2137 << A->getSpelling() <<
T.getTriple();
2138 else if (Val == llvm::FunctionReturnThunksKind::Invalid)
2139 Diags.
Report(diag::err_drv_invalid_value)
2140 << A->getAsString(Args) << A->getValue();
2141 else if (Val == llvm::FunctionReturnThunksKind::Extern &&
2142 Args.getLastArgValue(OPT_mcmodel_EQ) ==
"large")
2143 Diags.
Report(diag::err_drv_argument_not_allowed_with)
2144 << A->getAsString(Args)
2145 << Args.getLastArg(OPT_mcmodel_EQ)->getAsString(Args);
2147 Opts.FunctionReturnThunks =
static_cast<unsigned>(Val);
2151 Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {
2152 CodeGenOptions::BitcodeFileToLink F;
2154 if (A->getOption().matches(OPT_mlink_builtin_bitcode)) {
2155 F.
LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;
2164 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
2165 StringRef Val = A->getValue();
2169 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2172 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_f32_EQ)) {
2173 StringRef Val = A->getValue();
2176 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2182 Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return,
2183 OPT_maix_struct_return, OPT_msvr4_struct_return)) {
2187 Diags.
Report(diag::err_drv_unsupported_opt_for_target)
2188 << A->getSpelling() <<
T.str();
2190 const Option &O = A->getOption();
2191 if (O.matches(OPT_fpcc_struct_return) ||
2192 O.matches(OPT_maix_struct_return)) {
2195 assert(O.matches(OPT_freg_struct_return) ||
2196 O.matches(OPT_msvr4_struct_return));
2201 if (Arg *A = Args.getLastArg(OPT_mxcoff_roptr)) {
2203 Diags.
Report(diag::err_drv_unsupported_opt_for_target)
2204 << A->getSpelling() <<
T.str();
2214 if (!Args.hasFlag(OPT_fdata_sections, OPT_fno_data_sections,
false))
2215 Diags.
Report(diag::err_roptr_requires_data_sections);
2217 Opts.XCOFFReadOnlyPointers =
true;
2220 if (Arg *A = Args.getLastArg(OPT_mabi_EQ_quadword_atomics)) {
2221 if (!
T.isOSAIX() ||
T.isPPC32())
2222 Diags.
Report(diag::err_drv_unsupported_opt_for_target)
2223 << A->getSpelling() <<
T.str();
2226 bool NeedLocTracking =
false;
2229 NeedLocTracking =
true;
2231 if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {
2233 NeedLocTracking =
true;
2236 if (Arg *A = Args.getLastArg(OPT_opt_record_format)) {
2238 NeedLocTracking =
true;
2248 Diags, Args, OPT_Rpass_analysis_EQ,
"pass-analysis");
2258 if (Opts.DiagnosticsWithHotness && !UsingProfile &&
2261 Diags.
Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2262 <<
"-fdiagnostics-show-hotness";
2266 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
2268 llvm::remarks::parseHotnessThresholdOption(
arg->getValue());
2271 Diags.
Report(diag::err_drv_invalid_diagnotics_hotness_threshold)
2272 <<
"-fdiagnostics-hotness-threshold=";
2278 Diags.
Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2279 <<
"-fdiagnostics-hotness-threshold=";
2284 Args.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ)) {
2288 Diags.
Report(diag::err_drv_invalid_diagnotics_misexpect_tolerance)
2289 <<
"-fdiagnostics-misexpect-tolerance=";
2295 Diags.
Report(diag::warn_drv_diagnostics_misexpect_requires_pgo)
2296 <<
"-fdiagnostics-misexpect-tolerance=";
2303 if (UsingSampleProfile)
2304 NeedLocTracking =
true;
2307 NeedLocTracking =
true;
2311 if (NeedLocTracking &&
2312 Opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo)
2313 Opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
2318 Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,
2321 Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
2324 Args.getAllArgValues(OPT_fsanitize_merge_handlers_EQ),
2329 "-fsanitize-skip-hot-cutoff=",
2330 Args.getAllArgValues(OPT_fsanitize_skip_hot_cutoff_EQ), Diags);
2333 "-fsanitize-annotate-debug-info=",
2334 Args.getAllArgValues(OPT_fsanitize_annotate_debug_info_EQ), Diags,
2338 Args.getLastArgValue(OPT_fallow_runtime_check_skip_hot_cutoff_EQ);
2341 if (
V.getAsDouble(A) || A < 0.0 || A > 1.0) {
2342 Diags.
Report(diag::err_drv_invalid_value)
2343 <<
"-fallow-runtime-check-skip-hot-cutoff=" <<
V;
2349 Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn,
true);
2354 if (Args.hasArg(options::OPT_ffinite_loops))
2356 else if (Args.hasArg(options::OPT_fno_finite_loops))
2359 Opts.EmitIEEENaNCompliantInsts = Args.hasFlag(
2360 options::OPT_mamdgpu_ieee, options::OPT_mno_amdgpu_ieee,
true);
2361 if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs)
2362 Diags.
Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans);
2364 Opts.StaticClosure = Args.hasArg(options::OPT_static_libclosure);
2372#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2373 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2374#include "clang/Driver/Options.inc"
2375#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2380 for (
const auto &Dep : Opts.
ExtraDeps) {
2381 switch (Dep.second) {
2394 GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first);
2403 bool ShowLineMarkers) {
2407#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2408 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2409#include "clang/Driver/Options.inc"
2410#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2412 if (Args.hasArg(OPT_show_includes)) {
2427 if (!Args.hasArg(OPT_fno_sanitize_ignorelist)) {
2428 for (
const auto *A : Args.filtered(OPT_fsanitize_ignorelist_EQ)) {
2429 StringRef Val = A->getValue();
2430 if (!Val.contains(
'='))
2434 for (
const auto *A : Args.filtered(OPT_fsanitize_system_ignorelist_EQ)) {
2435 StringRef Val = A->getValue();
2436 if (!Val.contains(
'='))
2443 for (
const auto &Filename : Args.getAllArgValues(OPT_fprofile_list_EQ))
2447 for (
const auto *A : Args.filtered(OPT_fdepfile_entry))
2451 for (
const auto *A : Args.filtered(OPT_fmodule_file)) {
2452 StringRef Val = A->getValue();
2453 if (!Val.contains(
'='))
2461 if (Args.hasArg(OPT_header_include_format_EQ))
2462 Diags.
Report(diag::err_drv_print_header_cc1_invalid_combination)
2466 Diags.
Report(diag::err_drv_print_header_cc1_invalid_filtering)
2470 if (Args.hasArg(OPT_header_include_filtering_EQ))
2471 Diags.
Report(diag::err_drv_print_header_cc1_invalid_combination)
2475 Diags.
Report(diag::err_drv_print_header_cc1_invalid_format)
2491 } ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
2492 for (
auto *A : Args) {
2493 const Option &O = A->getOption();
2494 if (O.matches(options::OPT_fcolor_diagnostics)) {
2495 ShowColors = Colors_On;
2496 }
else if (O.matches(options::OPT_fno_color_diagnostics)) {
2497 ShowColors = Colors_Off;
2498 }
else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
2499 StringRef
Value(A->getValue());
2500 if (
Value ==
"always")
2501 ShowColors = Colors_On;
2502 else if (
Value ==
"never")
2503 ShowColors = Colors_Off;
2504 else if (
Value ==
"auto")
2505 ShowColors = Colors_Auto;
2508 return ShowColors == Colors_On ||
2509 (ShowColors == Colors_Auto &&
2510 llvm::sys::Process::StandardErrHasColors());
2516 for (
const auto &Prefix : VerifyPrefixes) {
2519 auto BadChar = llvm::find_if(Prefix, [](
char C) {
2522 if (BadChar != Prefix.end() || !
isLetter(Prefix[0])) {
2524 Diags.
Report(diag::err_drv_invalid_value) <<
"-verify=" << Prefix;
2525 Diags.
Report(diag::note_drv_verify_prefix_spelling);
2535#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2536 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2537#include "clang/Driver/Options.inc"
2538#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2547#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2548 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2549#include "clang/Driver/Options.inc"
2550#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2558#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2559 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2560#include "clang/Driver/Options.inc"
2561#undef MIGRATOR_OPTION_WITH_MARSHALLING
2570#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2571 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2572#include "clang/Driver/Options.inc"
2573#undef MIGRATOR_OPTION_WITH_MARSHALLING
2578void CompilerInvocationBase::GenerateDiagnosticArgs(
2580 bool DefaultDiagColor) {
2582#define DIAG_OPTION_WITH_MARSHALLING(...) \
2583 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2584#include "clang/Driver/Options.inc"
2585#undef DIAG_OPTION_WITH_MARSHALLING
2588 GenerateArg(Consumer, OPT_diagnostic_serialized_file,
2591 if (Opts.ShowColors)
2594 if (Opts.VerifyDiagnostics &&
2599 if (Prefix !=
"expected")
2606 GenerateArg(Consumer, OPT_verify_ignore_unexpected);
2609 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ,
"note");
2611 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ,
"remark");
2613 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ,
"warning");
2615 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ,
"error");
2620 if (
Warning ==
"undef-prefix")
2623 if (
Warning ==
"invalid-constexpr" ||
Warning ==
"no-invalid-constexpr")
2625 Consumer(StringRef(
"-W") +
Warning);
2631 StringRef IgnoredRemarks[] = {
"pass",
"no-pass",
2632 "pass-analysis",
"no-pass-analysis",
2633 "pass-missed",
"no-pass-missed"};
2634 if (llvm::is_contained(IgnoredRemarks,
Remark))
2637 Consumer(StringRef(
"-R") +
Remark);
2641 GenerateArg(Consumer, OPT_warning_suppression_mappings_EQ,
2646std::unique_ptr<DiagnosticOptions>
2648 auto DiagOpts = std::make_unique<DiagnosticOptions>();
2649 unsigned MissingArgIndex, MissingArgCount;
2651 Argv.slice(1), MissingArgIndex, MissingArgCount);
2653 bool ShowColors =
true;
2654 if (std::optional<std::string> NoColor =
2655 llvm::sys::Process::GetEnv(
"NO_COLOR");
2656 NoColor && !NoColor->empty()) {
2671 bool DefaultDiagColor) {
2672 std::optional<DiagnosticOptions> IgnoringDiagOpts;
2673 std::optional<DiagnosticsEngine> IgnoringDiags;
2675 IgnoringDiagOpts.emplace();
2678 Diags = &*IgnoringDiags;
2687#define DIAG_OPTION_WITH_MARSHALLING(...) \
2688 PARSE_OPTION_WITH_MARSHALLING(Args, *Diags, __VA_ARGS__)
2689#include "clang/Driver/Options.inc"
2690#undef DIAG_OPTION_WITH_MARSHALLING
2692 llvm::sys::Process::UseANSIEscapeCodes(Opts.UseANSIEscapeCodes);
2695 Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))
2699 Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ);
2701 if (Args.hasArg(OPT_verify))
2706 Opts.VerifyDiagnostics =
false;
2711 "-verify-ignore-unexpected=",
2712 Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), *Diags, DiagMask);
2713 if (Args.hasArg(OPT_verify_ignore_unexpected))
2715 Opts.setVerifyIgnoreUnexpected(DiagMask);
2717 Diags->
Report(diag::warn_ignoring_ftabstop_value)
2722 if (
const Arg *A = Args.getLastArg(OPT_warning_suppression_mappings_EQ))
2736 std::string &BlockName,
2737 unsigned &MajorVersion,
2738 unsigned &MinorVersion,
2740 std::string &UserInfo) {
2742 Arg.split(Args,
':', 5);
2743 if (Args.size() < 5)
2746 BlockName = std::string(Args[0]);
2747 if (Args[1].getAsInteger(10, MajorVersion))
return true;
2748 if (Args[2].getAsInteger(10, MinorVersion))
return true;
2749 if (Args[3].getAsInteger(2, Hashed))
return true;
2750 if (Args.size() > 4)
2751 UserInfo = std::string(Args[4]);
2760 static const std::pair<frontend::ActionKind, unsigned> Table[] = {
2791 OPT_emit_reduced_module_interface},
2808 OPT_print_dependency_directives_minimized_source},
2815static std::optional<frontend::ActionKind>
2818 if (ActionOpt.second == Opt.getID())
2819 return ActionOpt.first;
2821 return std::nullopt;
2825static std::optional<OptSpecifier>
2828 if (ActionOpt.first == ProgramAction)
2829 return OptSpecifier(ActionOpt.second);
2831 return std::nullopt;
2837#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2838 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2839#include "clang/Driver/Options.inc"
2840#undef FRONTEND_OPTION_WITH_MARSHALLING
2842 std::optional<OptSpecifier> ProgramActionOpt =
2850 if (!ProgramActionOpt) {
2853 "Frontend action without option.");
2854 GenerateProgramAction = [&]() {
2861 GenerateProgramAction = [&]() {
2869 llvm_unreachable(
"Default AST dump format.");
2876 GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);
2889 GenerateProgramAction = [&]() {
2894 GenerateProgramAction();
2896 for (
const auto &PluginArgs : Opts.
PluginArgs) {
2898 for (
const auto &PluginArg : PluginArgs.second)
2900 Opt.getPrefix() + Opt.getName() + PluginArgs.first,
2901 Opt.getKind(), 0, PluginArg);
2905 if (
auto *TestExt = dyn_cast_or_null<TestModuleFileExtension>(Ext.get()))
2906 GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());
2912 for (
const auto &Plugin : Opts.
Plugins)
2918 GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);
2931 StringRef HeaderUnit =
"";
2936 HeaderUnit =
"-user";
2939 HeaderUnit =
"-system";
2942 HeaderUnit =
"-header-unit";
2945 StringRef Header = IsHeader ?
"-header" :
"";
2968 Lang =
"objective-c";
2971 Lang =
"objective-c++";
2974 Lang =
"assembler-with-cpp";
2978 "Generating -x argument for unknown language (not precompiled).");
2993 Lang + HeaderUnit + Header +
ModuleMap + Preprocessed);
2997 for (
const auto &Input : Opts.
Inputs)
2998 Consumer(Input.getFile());
3007#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
3008 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3009#include "clang/Driver/Options.inc"
3010#undef FRONTEND_OPTION_WITH_MARSHALLING
3013 if (
const Arg *A = Args.getLastArg(OPT_Action_Group)) {
3014 OptSpecifier Opt = OptSpecifier(A->getOption().getID());
3016 assert(ProgramAction &&
"Option specifier not in Action_Group.");
3019 (Opt == OPT_ast_dump_all_EQ || Opt == OPT_ast_dump_EQ)) {
3020 unsigned Val = llvm::StringSwitch<unsigned>(A->getValue())
3023 .Default(std::numeric_limits<unsigned>::max());
3025 if (Val != std::numeric_limits<unsigned>::max())
3028 Diags.
Report(diag::err_drv_invalid_value)
3029 << A->getAsString(Args) << A->getValue();
3039 Args.hasArg(OPT_interface_stub_version_EQ)
3040 ? Args.getLastArgValue(OPT_interface_stub_version_EQ)
3042 if (ArgStr ==
"experimental-yaml-elf-v1" ||
3043 ArgStr ==
"experimental-ifs-v1" || ArgStr ==
"experimental-ifs-v2" ||
3044 ArgStr ==
"experimental-tapi-elf-v1") {
3045 std::string ErrorMessage =
3046 "Invalid interface stub format: " + ArgStr.str() +
3048 Diags.
Report(diag::err_drv_invalid_value)
3049 <<
"Must specify a valid interface stub format type, ie: "
3050 "-interface-stub-version=ifs-v1"
3053 }
else if (!ArgStr.starts_with(
"ifs-")) {
3054 std::string ErrorMessage =
3055 "Invalid interface stub format: " + ArgStr.str() +
".";
3056 Diags.
Report(diag::err_drv_invalid_value)
3057 <<
"Must specify a valid interface stub format type, ie: "
3058 "-interface-stub-version=ifs-v1"
3073 if (!A->getSpelling().starts_with(
"-ast-dump")) {
3074 const Arg *SavedAction =
nullptr;
3075 for (
const Arg *AA :
3076 Args.filtered(OPT_Action_Group, OPT_main_file_name)) {
3077 if (AA->getOption().matches(OPT_main_file_name)) {
3078 SavedAction =
nullptr;
3079 }
else if (!SavedAction) {
3082 if (!A->getOption().matches(OPT_ast_dump_EQ))
3083 Diags.
Report(diag::err_fe_invalid_multiple_actions)
3084 << SavedAction->getSpelling() << A->getSpelling();
3091 if (
const Arg* A = Args.getLastArg(OPT_plugin)) {
3092 Opts.
Plugins.emplace_back(A->getValue(0));
3096 for (
const auto *AA : Args.filtered(OPT_plugin_arg))
3097 Opts.
PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
3099 for (
const std::string &Arg :
3100 Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
3101 std::string BlockName;
3102 unsigned MajorVersion;
3103 unsigned MinorVersion;
3105 std::string UserInfo;
3107 MinorVersion, Hashed, UserInfo)) {
3108 Diags.
Report(diag::err_test_module_file_extension_format) << Arg;
3115 std::make_shared<TestModuleFileExtension>(
3116 BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
3119 if (
const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
3123 Diags.
Report(diag::err_drv_invalid_value)
3124 << A->getAsString(Args) << A->getValue();
3125 Diags.
Report(diag::note_command_line_code_loc_requirement);
3129 Opts.
Plugins = Args.getAllArgValues(OPT_load);
3130 Opts.
ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);
3131 Opts.
ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);
3133 for (
const auto *A : Args.filtered(OPT_fmodule_file)) {
3134 StringRef Val = A->getValue();
3135 if (!Val.contains(
'='))
3140 Diags.
Report(diag::err_drv_argument_only_allowed_with) <<
"-fsystem-module"
3142 if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_cir))
3146 if (Args.hasArg(OPT_clangir_disable_passes))
3149 if (Args.hasArg(OPT_clangir_disable_verifier))
3153 if (Args.hasArg(OPT_aux_target_cpu))
3154 Opts.
AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu));
3155 if (Args.hasArg(OPT_aux_target_feature))
3159 if (
const Arg *A = Args.getLastArg(OPT_x)) {
3160 StringRef XValue = A->getValue();
3165 bool Preprocessed = XValue.consume_back(
"-cpp-output");
3166 bool ModuleMap = XValue.consume_back(
"-module-map");
3169 XValue !=
"precompiled-header" && XValue.consume_back(
"-header");
3175 if (IsHeader || Preprocessed) {
3176 if (XValue.consume_back(
"-header-unit"))
3178 else if (XValue.consume_back(
"-system"))
3180 else if (XValue.consume_back(
"-user"))
3186 IsHeaderFile = IsHeader && !Preprocessed && !
ModuleMap &&
3190 DashX = llvm::StringSwitch<InputKind>(XValue)
3206 DashX = llvm::StringSwitch<InputKind>(XValue)
3214 DashX = llvm::StringSwitch<InputKind>(XValue)
3217 .Cases(
"ast",
"pcm",
"precompiled-header",
3224 Diags.
Report(diag::err_drv_invalid_value)
3225 << A->getAsString(Args) << A->getValue();
3232 IsHeaderFile =
true;
3233 }
else if (IsHeaderFile)
3240 std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
3243 Inputs.push_back(
"-");
3247 Diags.
Report(diag::err_drv_header_unit_extra_inputs) << Inputs[1];
3249 for (
unsigned i = 0, e = Inputs.size(); i != e; ++i) {
3253 StringRef(Inputs[i]).rsplit(
'.').second);
3262 bool IsSystem =
false;
3271 Opts.
Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem);
3281 std::string ClangExecutable =
3282 llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
3289#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3290 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3291#include "clang/Driver/Options.inc"
3292#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3301 GenerateArg(Consumer, OPT_fprebuilt_module_path, Path);
3308 std::optional<bool> IsFramework,
3309 std::optional<bool> IgnoreSysRoot) {
3310 return llvm::is_contained(Groups, Entry.
Group) &&
3311 (!IsFramework || (Entry.
IsFramework == *IsFramework)) &&
3312 (!IgnoreSysRoot || (Entry.
IgnoreSysRoot == *IgnoreSysRoot));
3321 OptSpecifier Opt = [It, Matches]() {
3326 llvm_unreachable(
"Unexpected HeaderSearchOptions::Entry.");
3340 It->Group ==
frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;
3347 for (; It < End && Matches(*It, {
frontend::After},
false,
true); ++It)
3353 GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
3358 GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path);
3366 GenerateArg(Consumer, OPT_objc_isystem, It->Path);
3368 GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);
3378 ? OPT_internal_isystem
3379 : OPT_internal_externc_isystem;
3383 GenerateArg(Consumer, OPT_internal_iframework, It->Path);
3385 assert(It == End &&
"Unhandled HeaderSearchOption::Entry.");
3389 OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
3390 : OPT_no_system_header_prefix;
3404#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3405 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3406#include "clang/Driver/Options.inc"
3407#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3409 if (
const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
3410 Opts.
UseLibcxx = (strcmp(A->getValue(),
"libc++") == 0);
3413 for (
const auto *A : Args.filtered(OPT_fmodule_file)) {
3414 StringRef Val = A->getValue();
3415 if (Val.contains(
'=')) {
3416 auto Split = Val.split(
'=');
3418 std::string(Split.first), std::string(Split.second));
3421 for (
const auto *A : Args.filtered(OPT_fprebuilt_module_path))
3424 for (
const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
3425 StringRef MacroDef = A->getValue();
3427 llvm::CachedHashString(MacroDef.split(
'=').first));
3431 bool IsSysrootSpecified =
3432 Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
3436 auto PrefixHeaderPath = [IsSysrootSpecified,
3437 &Opts](
const llvm::opt::Arg *A,
3438 bool IsFramework =
false) -> std::string {
3439 assert(A->getNumValues() &&
"Unexpected empty search path flag!");
3440 if (IsSysrootSpecified && !IsFramework && A->getValue()[0] ==
'=') {
3442 llvm::sys::path::append(Buffer, Opts.
Sysroot,
3443 llvm::StringRef(A->getValue()).substr(1));
3444 return std::string(Buffer);
3446 return A->getValue();
3449 for (
const auto *A : Args.filtered(OPT_I, OPT_F)) {
3450 bool IsFramework = A->getOption().matches(OPT_F);
3456 StringRef Prefix =
"";
3457 for (
const auto *A :
3458 Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
3459 if (A->getOption().matches(OPT_iprefix))
3460 Prefix = A->getValue();
3461 else if (A->getOption().matches(OPT_iwithprefix))
3467 for (
const auto *A : Args.filtered(OPT_idirafter))
3469 for (
const auto *A : Args.filtered(OPT_iquote))
3472 for (
const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) {
3473 if (A->getOption().matches(OPT_iwithsysroot)) {
3480 for (
const auto *A : Args.filtered(OPT_iframework))
3482 for (
const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
3487 for (
const auto *A : Args.filtered(OPT_c_isystem))
3489 for (
const auto *A : Args.filtered(OPT_cxx_isystem))
3491 for (
const auto *A : Args.filtered(OPT_objc_isystem))
3493 for (
const auto *A : Args.filtered(OPT_objcxx_isystem))
3497 for (
const auto *A :
3498 Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
3500 if (A->getOption().matches(OPT_internal_externc_isystem))
3502 Opts.
AddPath(A->getValue(), Group,
false,
true);
3504 for (
const auto *A : Args.filtered(OPT_internal_iframework))
3508 for (
const auto *A :
3509 Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
3511 A->getValue(), A->getOption().matches(OPT_system_header_prefix));
3513 for (
const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))
3522 GenerateArg(Consumer, OPT_fapinotes_swift_version,
3526 GenerateArg(Consumer, OPT_iapinotes_modules, Path);
3531 if (
const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
3533 diags.
Report(diag::err_drv_invalid_value)
3534 << A->getAsString(Args) << A->getValue();
3536 for (
const Arg *A : Args.filtered(OPT_iapinotes_modules))
3542 if (Opts.PointerAuthIntrinsics)
3544 if (Opts.PointerAuthCalls)
3546 if (Opts.PointerAuthReturns)
3548 if (Opts.PointerAuthIndirectGotos)
3549 GenerateArg(Consumer, OPT_fptrauth_indirect_gotos);
3550 if (Opts.PointerAuthAuthTraps)
3552 if (Opts.PointerAuthVTPtrAddressDiscrimination)
3553 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
3554 if (Opts.PointerAuthVTPtrTypeDiscrimination)
3555 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
3556 if (Opts.PointerAuthTypeInfoVTPtrDiscrimination)
3557 GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination);
3558 if (Opts.PointerAuthFunctionTypeDiscrimination)
3559 GenerateArg(Consumer, OPT_fptrauth_function_pointer_type_discrimination);
3560 if (Opts.PointerAuthInitFini)
3562 if (Opts.PointerAuthInitFiniAddressDiscrimination)
3563 GenerateArg(Consumer, OPT_fptrauth_init_fini_address_discrimination);
3564 if (Opts.PointerAuthELFGOT)
3566 if (Opts.AArch64JumpTableHardening)
3567 GenerateArg(Consumer, OPT_faarch64_jump_table_hardening);
3568 if (Opts.PointerAuthObjcIsa)
3570 if (Opts.PointerAuthObjcInterfaceSel)
3571 GenerateArg(Consumer, OPT_fptrauth_objc_interface_sel);
3572 if (Opts.PointerAuthObjcClassROPointers)
3573 GenerateArg(Consumer, OPT_fptrauth_objc_class_ro);
3574 if (Opts.PointerAuthBlockDescriptorPointers)
3575 GenerateArg(Consumer, OPT_fptrauth_block_descriptor_pointers);
3580 Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
3581 Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
3582 Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
3583 Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
3584 Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
3585 Opts.PointerAuthVTPtrAddressDiscrimination =
3586 Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
3587 Opts.PointerAuthVTPtrTypeDiscrimination =
3588 Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
3589 Opts.PointerAuthTypeInfoVTPtrDiscrimination =
3590 Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination);
3591 Opts.PointerAuthFunctionTypeDiscrimination =
3592 Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination);
3593 Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
3594 Opts.PointerAuthInitFiniAddressDiscrimination =
3595 Args.hasArg(OPT_fptrauth_init_fini_address_discrimination);
3596 Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got);
3597 Opts.AArch64JumpTableHardening =
3598 Args.hasArg(OPT_faarch64_jump_table_hardening);
3599 Opts.PointerAuthBlockDescriptorPointers =
3600 Args.hasArg(OPT_fptrauth_block_descriptor_pointers);
3601 Opts.PointerAuthObjcIsa = Args.hasArg(OPT_fptrauth_objc_isa);
3602 Opts.PointerAuthObjcClassROPointers = Args.hasArg(OPT_fptrauth_objc_class_ro);
3603 Opts.PointerAuthObjcInterfaceSel =
3604 Args.hasArg(OPT_fptrauth_objc_interface_sel);
3606 if (Opts.PointerAuthObjcInterfaceSel)
3607 Opts.PointerAuthObjcInterfaceSelKey =
3618 llvm_unreachable(
"should not parse language flags for this input");
3653 llvm_unreachable(
"unexpected input language");
3662 return "Objective-C";
3666 return "Objective-C++";
3670 return "C++ for OpenCL";
3689 llvm_unreachable(
"unknown input language");
3692void CompilerInvocationBase::GenerateLangArgs(
const LangOptions &Opts,
3694 const llvm::Triple &
T,
3699 if (Opts.ObjCAutoRefCount)
3701 if (Opts.PICLevel != 0)
3702 GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));
3706 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3711 OptSpecifier StdOpt;
3713 case LangStandard::lang_opencl10:
3714 case LangStandard::lang_opencl11:
3715 case LangStandard::lang_opencl12:
3716 case LangStandard::lang_opencl20:
3717 case LangStandard::lang_opencl30:
3718 case LangStandard::lang_openclcpp10:
3719 case LangStandard::lang_openclcpp2021:
3720 StdOpt = OPT_cl_std_EQ;
3723 StdOpt = OPT_std_EQ;
3728 GenerateArg(Consumer, StdOpt, LangStandard.getName());
3730 if (Opts.IncludeDefaultHeader)
3731 GenerateArg(Consumer, OPT_finclude_default_header);
3732 if (Opts.DeclareOpenCLBuiltins)
3733 GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);
3735 const LangOptions *
LangOpts = &Opts;
3737#define LANG_OPTION_WITH_MARSHALLING(...) \
3738 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3739#include "clang/Driver/Options.inc"
3740#undef LANG_OPTION_WITH_MARSHALLING
3751 else if (Opts.ObjCAutoRefCount == 1)
3754 if (Opts.ObjCWeakRuntime)
3755 GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);
3760 if (Opts.ObjCSubscriptingLegacyRuntime)
3761 GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime);
3764 if (Opts.GNUCVersion != 0) {
3765 unsigned Major = Opts.GNUCVersion / 100 / 100;
3766 unsigned Minor = (Opts.GNUCVersion / 100) % 100;
3767 unsigned Patch = Opts.GNUCVersion % 100;
3769 Twine(Major) +
"." + Twine(Minor) +
"." + Twine(Patch));
3772 if (Opts.IgnoreXCOFFVisibility)
3773 GenerateArg(Consumer, OPT_mignore_xcoff_visibility);
3781 if (Opts.PointerOverflowDefined)
3784 if (Opts.MSCompatibilityVersion != 0) {
3785 unsigned Major = Opts.MSCompatibilityVersion / 10000000;
3786 unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;
3787 unsigned Subminor = Opts.MSCompatibilityVersion % 100000;
3788 GenerateArg(Consumer, OPT_fms_compatibility_version,
3789 Twine(Major) +
"." + Twine(Minor) +
"." + Twine(Subminor));
3792 if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
3794 if (!Opts.Trigraphs)
3801 if (
T.isOSzOS() && !Opts.ZOSExt)
3803 else if (Opts.ZOSExt)
3806 if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
3809 if (Opts.ConvergentFunctions)
3812 GenerateArg(Consumer, OPT_fno_convergent_functions);
3814 if (Opts.NoBuiltin && !Opts.Freestanding)
3817 if (!Opts.NoBuiltin)
3821 if (Opts.LongDoubleSize == 128)
3823 else if (Opts.LongDoubleSize == 64)
3825 else if (Opts.LongDoubleSize == 80)
3832 if (Opts.OpenMP && !Opts.OpenMPSimd) {
3835 if (Opts.OpenMP != 51)
3836 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3838 if (!Opts.OpenMPUseTLS)
3841 if (Opts.OpenMPIsTargetDevice)
3842 GenerateArg(Consumer, OPT_fopenmp_is_target_device);
3844 if (Opts.OpenMPIRBuilder)
3845 GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder);
3848 if (Opts.OpenMPSimd) {
3851 if (Opts.OpenMP != 51)
3852 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3855 if (Opts.OpenMPThreadSubscription)
3856 GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription);
3858 if (Opts.OpenMPTeamSubscription)
3859 GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription);
3861 if (Opts.OpenMPTargetDebug != 0)
3862 GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ,
3863 Twine(Opts.OpenMPTargetDebug));
3865 if (Opts.OpenMPCUDANumSMs != 0)
3866 GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ,
3867 Twine(Opts.OpenMPCUDANumSMs));
3869 if (Opts.OpenMPCUDABlocksPerSM != 0)
3870 GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ,
3871 Twine(Opts.OpenMPCUDABlocksPerSM));
3873 if (Opts.OpenMPCUDAReductionBufNum != 1024)
3874 GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
3875 Twine(Opts.OpenMPCUDAReductionBufNum));
3878 std::string Targets;
3879 llvm::raw_string_ostream
OS(Targets);
3882 [&OS](
const llvm::Triple &
T) { OS << T.str(); },
",");
3883 GenerateArg(Consumer, OPT_offload_targets_EQ, Targets);
3886 if (Opts.OpenMPCUDAMode)
3902 GenerateArg(Consumer, OPT_ffp_contract,
"fast-honor-pragmas");
3905 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3909 GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);
3911 switch (Opts.getClangABICompat()) {
3912#define ABI_VER_MAJOR_MINOR(Major, Minor) \
3913 case LangOptions::ClangABI::Ver##Major##_##Minor: \
3914 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major "." #Minor); \
3916#define ABI_VER_MAJOR(Major) \
3917 case LangOptions::ClangABI::Ver##Major: \
3918 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major ".0"); \
3920#define ABI_VER_LATEST(Latest) \
3921 case LangOptions::ClangABI::Latest: \
3923#include "clang/Basic/ABIVersions.def"
3926 if (Opts.getSignReturnAddressScope() ==
3928 GenerateArg(Consumer, OPT_msign_return_address_EQ,
"all");
3929 else if (Opts.getSignReturnAddressScope() ==
3931 GenerateArg(Consumer, OPT_msign_return_address_EQ,
"non-leaf");
3933 if (Opts.getSignReturnAddressKey() ==
3935 GenerateArg(Consumer, OPT_msign_return_address_key_EQ,
"b_key");
3941 if (Opts.RelativeCXXABIVTables)
3942 GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables);
3944 GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables);
3952 GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first +
"=" + MP.second);
3958bool CompilerInvocation::ParseLangArgs(
LangOptions &Opts, ArgList &Args,
3960 std::vector<std::string> &Includes,
3970 if (Args.hasArg(OPT_fobjc_arc))
3971 Opts.ObjCAutoRefCount = 1;
3975 Opts.PIE = Args.hasArg(OPT_pic_is_pie);
3987 if (
const Arg *A = Args.getLastArg(OPT_std_EQ)) {
3990 Diags.
Report(diag::err_drv_invalid_value)
3991 << A->getAsString(Args) << A->getValue();
3993 for (
unsigned KindValue = 0;
3999 auto Diag = Diags.
Report(diag::note_drv_use_standard);
4001 unsigned NumAliases = 0;
4002#define LANGSTANDARD(id, name, lang, desc, features)
4003#define LANGSTANDARD_ALIAS(id, alias) \
4004 if (KindValue == LangStandard::lang_##id) ++NumAliases;
4005#define LANGSTANDARD_ALIAS_DEPR(id, alias)
4006#include "clang/Basic/LangStandards.def"
4008#define LANGSTANDARD(id, name, lang, desc, features)
4009#define LANGSTANDARD_ALIAS(id, alias) \
4010 if (KindValue == LangStandard::lang_##id) Diag << alias;
4011#define LANGSTANDARD_ALIAS_DEPR(id, alias)
4012#include "clang/Basic/LangStandards.def"
4020 Diags.
Report(diag::err_drv_argument_not_allowed_with)
4028 if (
const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
4030 = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
4031 .Cases(
"cl",
"CL", LangStandard::lang_opencl10)
4032 .Cases(
"cl1.0",
"CL1.0", LangStandard::lang_opencl10)
4033 .Cases(
"cl1.1",
"CL1.1", LangStandard::lang_opencl11)
4034 .Cases(
"cl1.2",
"CL1.2", LangStandard::lang_opencl12)
4035 .Cases(
"cl2.0",
"CL2.0", LangStandard::lang_opencl20)
4036 .Cases(
"cl3.0",
"CL3.0", LangStandard::lang_opencl30)
4037 .Cases(
"clc++",
"CLC++", LangStandard::lang_openclcpp10)
4038 .Cases(
"clc++1.0",
"CLC++1.0", LangStandard::lang_openclcpp10)
4039 .Cases(
"clc++2021",
"CLC++2021", LangStandard::lang_openclcpp2021)
4043 Diags.
Report(diag::err_drv_invalid_value)
4044 << A->getAsString(Args) << A->getValue();
4047 LangStd = OpenCLLangStd;
4051 Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
4052 Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
4060#define LANG_OPTION_WITH_MARSHALLING(...) \
4061 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4062#include "clang/Driver/Options.inc"
4063#undef LANG_OPTION_WITH_MARSHALLING
4065 if (
const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4066 StringRef Name = A->getValue();
4067 if (Name ==
"full") {
4068 Opts.CFProtectionBranch = 1;
4069 Opts.CFProtectionReturn = 1;
4070 }
else if (Name ==
"branch") {
4071 Opts.CFProtectionBranch = 1;
4072 }
else if (Name ==
"return") {
4073 Opts.CFProtectionReturn = 1;
4077 if (Opts.CFProtectionBranch) {
4078 if (
const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
4080 llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
4081#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
4082 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
4083#include "clang/Basic/CFProtectionOptions.def"
4085 Opts.setCFBranchLabelScheme(Scheme);
4089 if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
4090 !Args.hasArg(OPT_sycl_std_EQ)) {
4100 if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
4101 StringRef value =
arg->getValue();
4103 Diags.
Report(diag::err_drv_unknown_objc_runtime) << value;
4106 if (Args.hasArg(OPT_fobjc_gc_only))
4108 else if (Args.hasArg(OPT_fobjc_gc))
4110 else if (Args.hasArg(OPT_fobjc_arc)) {
4111 Opts.ObjCAutoRefCount = 1;
4113 Diags.
Report(diag::err_arc_unsupported_on_runtime);
4120 if (Args.hasArg(OPT_fobjc_runtime_has_weak))
4121 Opts.ObjCWeakRuntime = 1;
4127 if (
auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
4128 if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
4129 assert(!Opts.ObjCWeak);
4131 Diags.
Report(diag::err_objc_weak_with_gc);
4132 }
else if (!Opts.ObjCWeakRuntime) {
4133 Diags.
Report(diag::err_objc_weak_unsupported);
4137 }
else if (Opts.ObjCAutoRefCount) {
4138 Opts.ObjCWeak = Opts.ObjCWeakRuntime;
4141 if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
4142 Opts.ObjCSubscriptingLegacyRuntime =
4146 if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
4149 VersionTuple GNUCVer;
4150 bool Invalid = GNUCVer.tryParse(A->getValue());
4151 unsigned Major = GNUCVer.getMajor();
4152 unsigned Minor = GNUCVer.getMinor().value_or(0);
4153 unsigned Patch = GNUCVer.getSubminor().value_or(0);
4154 if (
Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
4155 Diags.
Report(diag::err_drv_invalid_value)
4156 << A->getAsString(Args) << A->getValue();
4158 Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
4161 if (
T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility)))
4162 Opts.IgnoreXCOFFVisibility = 1;
4164 if (Args.hasArg(OPT_ftrapv)) {
4168 std::string(Args.getLastArgValue(OPT_ftrapv_handler));
4170 else if (Args.hasArg(OPT_fwrapv))
4172 if (Args.hasArg(OPT_fwrapv_pointer))
4173 Opts.PointerOverflowDefined =
true;
4175 Opts.MSCompatibilityVersion = 0;
4176 if (
const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
4178 if (VT.tryParse(A->getValue()))
4179 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args)
4181 Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
4182 VT.getMinor().value_or(0) * 100000 +
4183 VT.getSubminor().value_or(0);
4191 (!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
4194 Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
4197 Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions,
T.isOSzOS());
4199 Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
4200 && Opts.OpenCLVersion == 200);
4202 bool HasConvergentOperations = Opts.
isTargetDevice() || Opts.OpenCL ||
4203 Opts.HLSL ||
T.isAMDGPU() ||
T.isNVPTX();
4204 Opts.ConvergentFunctions =
4205 Args.hasFlag(OPT_fconvergent_functions, OPT_fno_convergent_functions,
4206 HasConvergentOperations);
4208 Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
4209 if (!Opts.NoBuiltin)
4211 if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
4212 if (A->getOption().matches(options::OPT_mlong_double_64))
4213 Opts.LongDoubleSize = 64;
4214 else if (A->getOption().matches(options::OPT_mlong_double_80))
4215 Opts.LongDoubleSize = 80;
4216 else if (A->getOption().matches(options::OPT_mlong_double_128))
4217 Opts.LongDoubleSize = 128;
4219 Opts.LongDoubleSize = 0;
4221 if (Opts.FastRelaxedMath || Opts.CLUnsafeMath)
4227 if (Arg *A = Args.getLastArg(OPT_mrtd)) {
4229 Diags.
Report(diag::err_drv_argument_not_allowed_with)
4230 << A->getSpelling() <<
"-fdefault-calling-conv";
4232 switch (
T.getArch()) {
4233 case llvm::Triple::x86:
4236 case llvm::Triple::m68k:
4240 Diags.
Report(diag::err_drv_argument_not_allowed_with)
4241 << A->getSpelling() <<
T.getTriple();
4247 Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;
4249 bool IsSimdSpecified =
4250 Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
4252 Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;
4254 Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
4255 Opts.OpenMPIsTargetDevice =
4256 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_target_device);
4257 Opts.OpenMPIRBuilder =
4258 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_enable_irbuilder);
4259 bool IsTargetSpecified =
4260 Opts.OpenMPIsTargetDevice || Args.hasArg(options::OPT_offload_targets_EQ);
4262 if (Opts.OpenMP || Opts.OpenMPSimd) {
4264 Args, OPT_fopenmp_version_EQ,
4265 (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))
4266 Opts.OpenMP = Version;
4269 if (!Opts.OpenMPIsTargetDevice) {
4270 switch (
T.getArch()) {
4274 case llvm::Triple::nvptx:
4275 case llvm::Triple::nvptx64:
4276 Diags.
Report(diag::err_drv_omp_host_target_not_supported) <<
T.str();
4284 if ((Opts.OpenMPIsTargetDevice && (
T.isNVPTX() ||
T.isAMDGCN())) ||
4285 Opts.OpenCLCPlusPlus) {
4287 Opts.Exceptions = 0;
4288 Opts.CXXExceptions = 0;
4290 if (Opts.OpenMPIsTargetDevice &&
T.isNVPTX()) {
4291 Opts.OpenMPCUDANumSMs =
4293 Opts.OpenMPCUDANumSMs, Diags);
4294 Opts.OpenMPCUDABlocksPerSM =
4296 Opts.OpenMPCUDABlocksPerSM, Diags);
4298 Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
4299 Opts.OpenMPCUDAReductionBufNum, Diags);
4304 if (Opts.OpenMPIsTargetDevice && (Args.hasArg(OPT_fopenmp_target_debug) ||
4305 Args.hasArg(OPT_fopenmp_target_debug_EQ))) {
4307 Args, OPT_fopenmp_target_debug_EQ, Opts.OpenMPTargetDebug, Diags);
4308 if (!Opts.OpenMPTargetDebug && Args.hasArg(OPT_fopenmp_target_debug))
4309 Opts.OpenMPTargetDebug = 1;
4312 if (Opts.OpenMPIsTargetDevice) {
4313 if (Args.hasArg(OPT_fopenmp_assume_teams_oversubscription))
4314 Opts.OpenMPTeamSubscription =
true;
4315 if (Args.hasArg(OPT_fopenmp_assume_threads_oversubscription))
4316 Opts.OpenMPThreadSubscription =
true;
4320 if (Arg *A = Args.getLastArg(options::OPT_offload_targets_EQ)) {
4321 enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
4322 auto getArchPtrSize = [](
const llvm::Triple &
T) {
4323 if (
T.isArch16Bit())
4325 if (
T.isArch32Bit())
4327 assert(
T.isArch64Bit() &&
"Expected 64-bit architecture");
4331 for (
unsigned i = 0; i < A->getNumValues(); ++i) {
4332 llvm::Triple TT(A->getValue(i));
4334 if (TT.getArch() == llvm::Triple::UnknownArch ||
4335 !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() ||
4336 TT.getArch() == llvm::Triple::spirv64 ||
4337 TT.getArch() == llvm::Triple::systemz ||
4338 TT.getArch() == llvm::Triple::loongarch64 ||
4339 TT.getArch() == llvm::Triple::nvptx ||
4340 TT.getArch() == llvm::Triple::nvptx64 || TT.isAMDGCN() ||
4341 TT.getArch() == llvm::Triple::x86 ||
4342 TT.getArch() == llvm::Triple::x86_64))
4343 Diags.
Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
4344 else if (getArchPtrSize(
T) != getArchPtrSize(TT))
4345 Diags.
Report(diag::err_drv_incompatible_omp_arch)
4346 << A->getValue(i) <<
T.str();
4353 Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice &&
4354 (
T.isNVPTX() ||
T.isAMDGCN()) &&
4355 Args.hasArg(options::OPT_fopenmp_cuda_mode);
4358 if (Args.hasArg(options::OPT_fopenacc))
4359 Opts.OpenACC =
true;
4361 if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
4362 StringRef Val = A->getValue();
4365 else if (Val ==
"on")
4367 else if (Val ==
"off")
4369 else if (Val ==
"fast-honor-pragmas")
4372 Diags.
Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
4376 Args.getLastArg(OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {
4377 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
4379 llvm::StringSwitch<unsigned>(A->getValue(i))
4382 .Case(
"add-unsigned-overflow-test",
4384 .Case(
"add-signed-overflow-test",
4387 .Case(
"unsigned-post-decr-while",
4396 Opts.
NoSanitizeFiles = Args.getAllArgValues(OPT_fsanitize_ignorelist_EQ);
4397 std::vector<std::string> systemIgnorelists =
4398 Args.getAllArgValues(OPT_fsanitize_system_ignorelist_EQ);
4400 systemIgnorelists.begin(),
4401 systemIgnorelists.end());
4403 if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
4404 Opts.setClangABICompat(LangOptions::ClangABI::Latest);
4406 StringRef Ver = A->getValue();
4407 std::pair<StringRef, StringRef> VerParts = Ver.split(
'.');
4408 int Major, Minor = 0;
4412 if (!VerParts.first.starts_with(
"0") &&
4413 !VerParts.first.getAsInteger(10, Major) && 3 <= Major &&
4414 Major <= MAX_CLANG_ABI_COMPAT_VERSION &&
4416 ? VerParts.second.size() == 1 &&
4417 !VerParts.second.getAsInteger(10, Minor)
4418 : VerParts.first.size() == Ver.size() || VerParts.second ==
"0")) {
4420#define ABI_VER_MAJOR_MINOR(Major_, Minor_) \
4421 if (std::tuple(Major, Minor) <= std::tuple(Major_, Minor_)) \
4422 Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_##_##Minor_); \
4424#define ABI_VER_MAJOR(Major_) \
4425 if (Major <= Major_) \
4426 Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_); \
4428#define ABI_VER_LATEST(Latest) \
4431#include "clang/Basic/ABIVersions.def"
4432 }
else if (Ver !=
"latest") {
4433 Diags.
Report(diag::err_drv_invalid_value)
4434 << A->getAsString(Args) << A->getValue();
4438 if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) {
4439 StringRef SignScope = A->getValue();
4441 if (SignScope.equals_insensitive(
"none"))
4442 Opts.setSignReturnAddressScope(
4444 else if (SignScope.equals_insensitive(
"all"))
4445 Opts.setSignReturnAddressScope(
4447 else if (SignScope.equals_insensitive(
"non-leaf"))
4448 Opts.setSignReturnAddressScope(
4451 Diags.
Report(diag::err_drv_invalid_value)
4452 << A->getAsString(Args) << SignScope;
4454 if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
4455 StringRef SignKey = A->getValue();
4456 if (!SignScope.empty() && !SignKey.empty()) {
4457 if (SignKey ==
"a_key")
4458 Opts.setSignReturnAddressKey(
4460 else if (SignKey ==
"b_key")
4461 Opts.setSignReturnAddressKey(
4464 Diags.
Report(diag::err_drv_invalid_value)
4465 << A->getAsString(Args) << SignKey;
4471 StringRef
CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);
4478 Diags.
Report(diag::err_unsupported_cxx_abi) <<
CXXABI <<
T.str();
4484 Opts.RelativeCXXABIVTables =
4485 Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
4486 options::OPT_fno_experimental_relative_cxx_abi_vtables,
4490 bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti);
4491 Opts.OmitVTableRTTI =
4492 Args.hasFlag(options::OPT_fexperimental_omit_vtable_rtti,
4493 options::OPT_fno_experimental_omit_vtable_rtti,
false);
4494 if (Opts.OmitVTableRTTI && HasRTTI)
4495 Diags.
Report(diag::err_drv_using_omit_rtti_component_without_no_rtti);
4497 for (
const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
4498 auto Split = StringRef(A).split(
'=');
4500 {std::string(
Split.first), std::string(
Split.second)});
4504 !Args.getLastArg(OPT_fno_file_reproducible) &&
4505 (Args.getLastArg(OPT_ffile_compilation_dir_EQ) ||
4506 Args.getLastArg(OPT_fmacro_prefix_map_EQ) ||
4507 Args.getLastArg(OPT_ffile_reproducible));
4510 if (Arg *A = Args.getLastArg(options::OPT_mvscale_min_EQ)) {
4512 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4513 Diags.
Report(diag::err_cc1_unbounded_vscale_min);
4515 if (Arg *A = Args.getLastArg(options::OPT_mvscale_streaming_min_EQ)) {
4517 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4518 Diags.
Report(diag::err_cc1_unbounded_vscale_min);
4521 if (
const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) {
4522 std::ifstream SeedFile(A->getValue(0));
4524 if (!SeedFile.is_open())
4525 Diags.
Report(diag::err_drv_cannot_open_randomize_layout_seed_file)
4531 if (
const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
4538 if (
T.isDXIL() ||
T.isSPIRVLogical()) {
4540 enum {
OS, Environment };
4542 int ExpectedOS =
T.isSPIRVLogical() ? VulkanEnv : ShaderModel;
4544 if (
T.getOSName().empty()) {
4545 Diags.
Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4546 << ExpectedOS <<
OS <<
T.str();
4547 }
else if (
T.getEnvironmentName().empty()) {
4548 Diags.
Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4550 }
else if (!
T.isShaderStageEnvironment()) {
4551 Diags.
Report(diag::err_drv_hlsl_bad_shader_unsupported)
4556 if (!
T.isShaderModelOS() ||
T.getOSVersion() == VersionTuple(0)) {
4557 Diags.
Report(diag::err_drv_hlsl_bad_shader_unsupported)
4558 << ShaderModel <<
T.getOSName() <<
T.str();
4563 if (Args.getLastArg(OPT_fnative_half_type)) {
4564 const LangStandard &Std =
4566 if (!(Opts.
LangStd >= LangStandard::lang_hlsl2018 &&
4567 T.getOSVersion() >= VersionTuple(6, 2)))
4568 Diags.
Report(diag::err_drv_hlsl_16bit_types_unsupported)
4569 <<
"-enable-16bit-types" <<
true << Std.
getName()
4570 <<
T.getOSVersion().getAsString();
4572 }
else if (
T.isSPIRVLogical()) {
4573 if (!
T.isVulkanOS() ||
T.getVulkanVersion() == VersionTuple(0)) {
4574 Diags.
Report(diag::err_drv_hlsl_bad_shader_unsupported)
4575 << VulkanEnv <<
T.getOSName() <<
T.str();
4577 if (Args.getLastArg(OPT_fnative_half_type)) {
4578 const LangStandard &Std =
4580 if (!(Opts.
LangStd >= LangStandard::lang_hlsl2018))
4581 Diags.
Report(diag::err_drv_hlsl_16bit_types_unsupported)
4582 <<
"-fnative-half-type" <<
false << Std.
getName();
4585 llvm_unreachable(
"expected DXIL or SPIR-V target");
4588 Diags.
Report(diag::err_drv_hlsl_unsupported_target) <<
T.str();
4590 if (Opts.
LangStd < LangStandard::lang_hlsl202x) {
4591 const LangStandard &Requested =
4593 const LangStandard &Recommended =
4595 Diags.
Report(diag::warn_hlsl_langstd_minimal)
4646 llvm_unreachable(
"invalid frontend action");
4691 llvm_unreachable(
"invalid frontend action");
4701#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4702 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4703#include "clang/Driver/Options.inc"
4704#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4707 GenerateArg(Consumer, OPT_pch_through_hdrstop_use);
4710 GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);
4717 for (
const auto &M : Opts.
Macros) {
4720 if (M.first ==
"__CET__=1" && !M.second &&
4721 !CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch)
4723 if (M.first ==
"__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn &&
4724 !CodeGenOpts.CFProtectionBranch)
4726 if (M.first ==
"__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn &&
4727 CodeGenOpts.CFProtectionBranch)
4730 GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first);
4733 for (
const auto &I : Opts.
Includes) {
4736 if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader &&
4737 ((LangOpts.DeclareOpenCLBuiltins && I ==
"opencl-c-base.h") ||
4742 if (LangOpts.HLSL && I ==
"hlsl.h")
4752 GenerateArg(Consumer, OPT_remap_file, RF.first +
";" + RF.second);
4758 GenerateArg(Consumer, OPT_fdefine_target_os_macros);
4761 GenerateArg(Consumer, OPT_embed_dir_EQ, EmbedEntry);
4775#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4776 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4777#include "clang/Driver/Options.inc"
4778#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4780 Opts.
PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) ||
4781 Args.hasArg(OPT_pch_through_hdrstop_use);
4783 for (
const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
4786 if (
const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
4787 StringRef
Value(A->getValue());
4788 size_t Comma =
Value.find(
',');
4790 unsigned EndOfLine = 0;
4792 if (Comma == StringRef::npos ||
4793 Value.substr(0, Comma).getAsInteger(10, Bytes) ||
4794 Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
4795 Diags.
Report(diag::err_drv_preamble_format);
4803 for (
const auto *A : Args.filtered(OPT_D, OPT_U)) {
4804 if (A->getOption().matches(OPT_D))
4811 for (
const auto *A : Args.filtered(OPT_include))
4812 Opts.
Includes.emplace_back(A->getValue());
4814 for (
const auto *A : Args.filtered(OPT_chain_include))
4817 for (
const auto *A : Args.filtered(OPT_remap_file)) {
4818 std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(
';');
4820 if (Split.second.empty()) {
4821 Diags.
Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
4828 if (
const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
4829 StringRef Epoch = A->getValue();
4833 const uint64_t MaxTimestamp =
4834 std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
4836 if (Epoch.getAsInteger(10,
V) ||
V > MaxTimestamp) {
4837 Diags.
Report(diag::err_fe_invalid_source_date_epoch)
4838 << Epoch << MaxTimestamp;
4844 for (
const auto *A : Args.filtered(OPT_embed_dir_EQ)) {
4845 StringRef Val = A->getValue();
4856 Args.hasFlag(OPT_fdefine_target_os_macros,
4868#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4869 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4870#include "clang/Driver/Options.inc"
4871#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4889#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4890 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4891#include "clang/Driver/Options.inc"
4892#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4895 Opts.
ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
4904#define TARGET_OPTION_WITH_MARSHALLING(...) \
4905 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4906#include "clang/Driver/Options.inc"
4907#undef TARGET_OPTION_WITH_MARSHALLING
4913 GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,
4923#define TARGET_OPTION_WITH_MARSHALLING(...) \
4924 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4925#include "clang/Driver/Options.inc"
4926#undef TARGET_OPTION_WITH_MARSHALLING
4928 if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {
4929 llvm::VersionTuple Version;
4930 if (Version.tryParse(A->getValue()))
4931 Diags.
Report(diag::err_drv_invalid_value)
4932 << A->getAsString(Args) << A->getValue();
4937 Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {
4938 llvm::VersionTuple Version;
4939 if (Version.tryParse(A->getValue()))
4940 Diags.
Report(diag::err_drv_invalid_value)
4941 << A->getAsString(Args) << A->getValue();
4949bool CompilerInvocation::CreateFromArgsImpl(
4957 unsigned MissingArgIndex, MissingArgCount;
4958 InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
4959 MissingArgCount, VisibilityMask);
4963 if (MissingArgCount)
4964 Diags.
Report(diag::err_drv_missing_argument)
4965 << Args.getArgString(MissingArgIndex) << MissingArgCount;
4968 for (
const auto *A : Args.filtered(OPT_UNKNOWN)) {
4969 auto ArgString = A->getAsString(Args);
4970 std::string Nearest;
4971 if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1)
4972 Diags.
Report(diag::err_drv_unknown_argument) << ArgString;
4974 Diags.
Report(diag::err_drv_unknown_argument_with_suggestion)
4975 << ArgString << Nearest;
5008 !Diags.
isIgnored(diag::warn_profile_data_misexpect, SourceLocation())) {
5022 Diags.
Report(diag::warn_drv_openacc_without_cir);
5035 !
LangOpts.Sanitize.has(SanitizerKind::Address) &&
5036 !
LangOpts.Sanitize.has(SanitizerKind::KernelAddress) &&
5037 !
LangOpts.Sanitize.has(SanitizerKind::Memory) &&
5038 !
LangOpts.Sanitize.has(SanitizerKind::KernelMemory);
5051 Diags.
Report(diag::err_fe_dependency_file_requires_MT);
5057 Diags.
Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
5068 llvm::driver::ProfileInstrKind::ProfileNone)
5069 Diags.
Report(diag::err_drv_profile_instrument_use_path_with_no_kind);
5079 const char *Argv0) {
5085 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
5089 Args.push_back(
"-cc1");
5092 Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
5097 llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
5112#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
5113 if constexpr (CK::Compatibility != CK::Benign) \
5114 HBuilder.add(LangOpts->Name);
5115#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description) \
5116 if constexpr (CK::Compatibility != CK::Benign) \
5117 HBuilder.add(static_cast<unsigned>(LangOpts->get##Name()));
5118#include "clang/Basic/LangOptions.def"
5123 HBuilder.addRange(
getLangOpts().CommentOpts.BlockCommandNames);
5140 StringRef MacroDef =
Macro.first;
5142 llvm::CachedHashString(MacroDef.split(
'=').first)))
5146 HBuilder.add(
Macro);
5162#define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name);
5163#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
5164 HBuilder.add(diagOpts.get##Name());
5165#include "clang/Basic/DiagnosticOptions.def"
5175 ext->hashExtension(HBuilder);
5182 HBuilder.add(*Minor);
5183 if (
auto Subminor =
APINotesOpts.SwiftVersion.getSubminor())
5184 HBuilder.add(*Subminor);
5186 HBuilder.add(*Build);
5192#define CODEGENOPT(Name, Bits, Default, Compatibility) \
5193 if constexpr (CK::Compatibility != CK::Benign) \
5194 HBuilder.add(CodeGenOpts->Name);
5195#define ENUM_CODEGENOPT(Name, Type, Bits, Default, Compatibility) \
5196 if constexpr (CK::Compatibility != CK::Benign) \
5197 HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
5198#define DEBUGOPT(Name, Bits, Default, Compatibility)
5199#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility)
5200#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility)
5201#include "clang/Basic/CodeGenOptions.def"
5213#define DEBUGOPT(Name, Bits, Default, Compatibility) \
5214 if constexpr (CK::Compatibility != CK::Benign) \
5215 HBuilder.add(CodeGenOpts->Name);
5216#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility) \
5217 if constexpr (CK::Compatibility != CK::Benign) \
5218 HBuilder.add(CodeGenOpts->Name);
5219#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility) \
5220 if constexpr (CK::Compatibility != CK::Benign) \
5221 HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
5222#include "clang/Basic/DebugOptions.def"
5229 if (!SanHash.
empty())
5230 HBuilder.add(SanHash.
Mask);
5232 llvm::MD5::MD5Result
Result;
5233 HBuilder.getHasher().final(
Result);
5235 return toString(llvm::APInt(64, Hash), 36,
false);
5263 std::vector<std::string> Args{
"-cc1"};
5265 [&Args](
const Twine &Arg) { Args.push_back(Arg.str()); });
5291 llvm::vfs::getRealFileSystem());
5299 Diags, std::move(BaseFS));
5305 if (VFSOverlayFiles.empty())
5310 for (
const auto &
File : VFSOverlayFiles) {
5311 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
5314 Diags.
Report(diag::err_missing_vfs_overlay_file) <<
File;
5319 std::move(Buffer.get()),
nullptr,
File,
5322 Diags.
Report(diag::err_invalid_vfs_overlay) <<
File;
Defines the Diagnostic-related interfaces.
Defines enum values for all the target-independent builtin functions.
static void getAllNoBuiltinFuncValues(ArgList &Args, std::vector< std::string > &Funcs)
static T extractMaskValue(T KeyPath)
static std::optional< IntTy > normalizeStringIntegral(OptSpecifier Opt, int, const ArgList &Args, DiagnosticsEngine &Diags)
static T mergeMaskValue(T KeyPath, U Value)
static std::optional< std::string > normalizeString(OptSpecifier Opt, int TableIndex, const ArgList &Args, DiagnosticsEngine &Diags)
static auto makeBooleanOptionNormalizer(bool Value, bool OtherValue, OptSpecifier OtherOpt)
static void parsePointerAuthOptions(PointerAuthOptions &Opts, const LangOptions &LangOpts, const llvm::Triple &Triple, DiagnosticsEngine &Diags)
static void denormalizeString(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, T Value)
static SmallVector< StringRef, 4 > serializeSanitizerKinds(SanitizerSet S)
static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle, ArgList &Args, DiagnosticsEngine &D, XRayInstrSet &S)
static unsigned getOptimizationLevelSize(ArgList &Args)
static void GenerateFrontendArgs(const FrontendOptions &Opts, ArgumentConsumer Consumer, bool IsHeader)
static std::optional< SimpleEnumValue > findValueTableByValue(const SimpleEnumValueTable &Table, unsigned Value)
static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags)
static auto makeFlagToValueNormalizer(T Value)
static CodeGenOptions::OptRemark ParseOptimizationRemark(DiagnosticsEngine &Diags, ArgList &Args, OptSpecifier OptEQ, StringRef Name)
Parse a remark command line argument.
static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args, DiagnosticsEngine &Diags)
static constexpr bool is_uint64_t_convertible()
static void GeneratePointerAuthArgs(const LangOptions &Opts, ArgumentConsumer Consumer)
static std::optional< SimpleEnumValue > findValueTableByName(const SimpleEnumValueTable &Table, StringRef Name)
static std::optional< OptSpecifier > getProgramActionOpt(frontend::ActionKind ProgramAction)
Maps frontend action to command line option.
static bool parseDiagnosticLevelMask(StringRef FlagName, const std::vector< std::string > &Levels, DiagnosticsEngine &Diags, DiagnosticLevelMask &M)
static std::optional< bool > normalizeSimpleFlag(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, DiagnosticsEngine &Diags)
CompilerInvocation::ArgumentConsumer ArgumentConsumer
static void denormalizeSimpleEnumImpl(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, unsigned Value)
static void GenerateArg(ArgumentConsumer Consumer, llvm::opt::OptSpecifier OptSpecifier)
static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, OptSpecifier GroupWithValue, std::vector< std::string > &Diagnostics)
static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags)
static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags)
static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, DiagnosticsEngine *Diags)
static void denormalizeSimpleFlag(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass, unsigned,...)
The tblgen-erated code passes in a fifth parameter of an arbitrary type, but denormalizeSimpleFlags n...
static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action, const FrontendOptions &FrontendOpts)
static std::optional< unsigned > normalizeSimpleEnum(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, DiagnosticsEngine &Diags)
static StringRef GetInputKindName(InputKind IK)
Get language name for given input kind.
static void initOption(AnalyzerOptions::ConfigTable &Config, DiagnosticsEngine *Diags, StringRef &OptionField, StringRef Name, StringRef DefaultVal)
static std::optional< std::string > normalizeTriple(OptSpecifier Opt, int TableIndex, const ArgList &Args, DiagnosticsEngine &Diags)
T & ensureOwned(std::shared_ptr< T > &Storage)
static void GenerateMigratorArgs(const MigratorOptions &Opts, ArgumentConsumer Consumer)
static const auto & getFrontendActionTable()
Return a table that associates command line option specifiers with the frontend action.
static void GenerateTargetArgs(const TargetOptions &Opts, ArgumentConsumer Consumer)
static std::optional< frontend::ActionKind > getFrontendAction(OptSpecifier &Opt)
Maps command line option to frontend action.
static bool checkVerifyPrefixes(const std::vector< std::string > &VerifyPrefixes, DiagnosticsEngine &Diags)
static SanitizerMaskCutoffs parseSanitizerWeightedKinds(StringRef FlagName, const std::vector< std::string > &Sanitizers, DiagnosticsEngine &Diags)
static void GenerateAPINotesArgs(const APINotesOptions &Opts, ArgumentConsumer Consumer)
static bool isCodeGenAction(frontend::ActionKind Action)
static std::optional< bool > normalizeSimpleNegativeFlag(OptSpecifier Opt, unsigned, const ArgList &Args, DiagnosticsEngine &)
static void GenerateFileSystemArgs(const FileSystemOptions &Opts, ArgumentConsumer Consumer)
static bool IsInputCompatibleWithStandard(InputKind IK, const LangStandard &S)
Check if input file kind and language standard are compatible.
static void denormalizeStringImpl(ArgumentConsumer Consumer, const Twine &Spelling, Option::OptionClass OptClass, unsigned, const Twine &Value)
static llvm::StringRef lookupStrInTable(unsigned Offset)
static void GeneratePreprocessorArgs(const PreprocessorOptions &Opts, ArgumentConsumer Consumer, const LangOptions &LangOpts, const FrontendOptions &FrontendOpts, const CodeGenOptions &CodeGenOpts)
static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, bool &IsHeaderFile)
static auto makeBooleanOptionDenormalizer(bool Value)
static void GeneratePreprocessorOutputArgs(const PreprocessorOutputOptions &Opts, ArgumentConsumer Consumer, frontend::ActionKind Action)
static bool isStrictlyPreprocessorAction(frontend::ActionKind Action)
static std::string serializeXRayInstrumentationBundle(const XRayInstrSet &S)
static bool ParseMigratorArgs(MigratorOptions &Opts, const ArgList &Args, DiagnosticsEngine &Diags)
static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor)
static T mergeForwardValue(T KeyPath, U Value)
static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args, DiagnosticsEngine &diags)
static void denormalizeStringVector(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, const std::vector< std::string > &Values)
static bool ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action, bool ShowLineMarkers)
static Expected< std::optional< uint32_t > > parseToleranceOption(StringRef Arg)
static std::optional< std::vector< std::string > > normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args, DiagnosticsEngine &)
static void GenerateAnalyzerArgs(const AnalyzerOptions &Opts, ArgumentConsumer Consumer)
static void GenerateOptimizationRemark(ArgumentConsumer Consumer, OptSpecifier OptEQ, StringRef Name, const CodeGenOptions::OptRemark &Remark)
Generate a remark argument. This is an inverse of ParseOptimizationRemark.
static bool ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action)
llvm::function_ref< void( CompilerInvocation &, SmallVectorImpl< const char * > &, CompilerInvocation::StringAllocator)> GenerateFn
static bool RoundTrip(ParseFn Parse, GenerateFn Generate, CompilerInvocation &RealInvocation, CompilerInvocation &DummyInvocation, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0, bool CheckAgainstOriginalInvocation=false, bool ForceRoundTrip=false)
May perform round-trip of command line arguments.
static T extractForwardValue(T KeyPath)
static void denormalizeSimpleEnum(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, T Value)
static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, DiagnosticsEngine &Diags)
std::shared_ptr< T > make_shared_copy(const T &X)
llvm::function_ref< bool(CompilerInvocation &, ArrayRef< const char * >, DiagnosticsEngine &, const char *)> ParseFn
static bool parseTestModuleFileExtensionArg(StringRef Arg, std::string &BlockName, unsigned &MajorVersion, unsigned &MinorVersion, bool &Hashed, std::string &UserInfo)
Parse the argument to the -ftest-module-file-extension command-line argument.
static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags)
static void GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts, ArgumentConsumer Consumer)
static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config, StringRef OptionName, StringRef DefaultVal)
static bool FixupInvocation(CompilerInvocation &Invocation, DiagnosticsEngine &Diags, const ArgList &Args, InputKind IK)
static void parseSanitizerKinds(StringRef FlagName, const std::vector< std::string > &Sanitizers, DiagnosticsEngine &Diags, SanitizerSet &S)
static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts, ArgumentConsumer Consumer)
Defines the clang::FileSystemOptions interface.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines types useful for describing an Objective-C runtime.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SanitizerKind enum.
Defines the clang::SourceLocation class and associated facilities.
#define CXXABI(Name, Str)
Defines the clang::TargetOptions class.
Defines version macros and version-related utility functions for Clang.
Defines the clang::XRayInstrKind enum.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Tracks various options which control how API notes are found and handled.
llvm::VersionTuple SwiftVersion
The Swift version which should be used for API notes.
std::vector< std::string > ModuleSearchPaths
The set of search paths where we API notes can be found for particular modules.
Stores options for the analyzer from the command line.
static std::vector< StringRef > getRegisteredPackages(bool IncludeExperimental=false)
Retrieves the list of packages generated from Checkers.td.
std::vector< std::pair< std::string, bool > > CheckersAndPackages
Pairs of checker/package name and enable/disable.
std::vector< std::string > SilencedCheckersAndPackages
Vector of checker/package names which will not emit warnings.
AnalysisDiagClients AnalysisDiagOpt
AnalysisConstraints AnalysisConstraintsOpt
ConfigTable Config
A key-value table of use-specified configuration values.
unsigned ShouldEmitErrorsOnInvalidConfigValue
AnalysisPurgeMode AnalysisPurgeOpt
bool isUnknownAnalyzerConfig(llvm::StringRef Name)
static std::vector< StringRef > getRegisteredCheckers(bool IncludeExperimental=false)
Retrieves the list of checkers generated from Checkers.td.
llvm::StringMap< std::string > ConfigTable
std::string FullCompilerInvocation
Store full compiler invocation for reproducible instructions in the generated report.
AnalysisInliningMode InliningMode
The mode of function selection used during inlining.
static bool isBuiltinFunc(llvm::StringRef Name)
Returns true if this is a libc/libm function without the '__builtin_' prefix.
CompatibilityKind
For ASTs produced with different option value, signifies their level of compatibility.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::SmallVector< std::pair< std::string, std::string >, 0 > CoveragePrefixMap
Prefix replacement map for source-based code coverage to remap source file paths in coverage mapping.
SanitizerSet SanitizeMergeHandlers
Set of sanitizer checks that can merge handlers (smaller code size at the expense of debuggability).
llvm::SmallVector< std::pair< std::string, std::string >, 0 > DebugPrefixMap
std::string OptRecordFile
The name of the file to which the backend should save YAML optimization records.
std::string BinutilsVersion
std::vector< BitcodeFileToLink > LinkBitcodeFiles
The files specified here are linked in to the module before optimizations.
std::optional< uint64_t > DiagnosticsHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
char CoverageVersion[4]
The version string to put into coverage files.
llvm::DenormalMode FPDenormalMode
The floating-point denormal mode to use.
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
std::string ProfileInstrumentUsePath
Name of the profile file to use as input for -fprofile-instr-use.
std::string SampleProfileFile
Name of the profile file to use with -fprofile-sample-use.
uint64_t LargeDataThreshold
The code model-specific large data threshold to use (-mlarge-data-threshold).
std::string MemoryProfileOutput
Name of the profile file to use as output for with -fmemory-profile.
std::string CodeModel
The code model to use (-mcmodel).
std::string CoverageDataFile
The filename with path we use for coverage data files.
std::optional< uint32_t > DiagnosticsMisExpectTolerance
The maximum percentage profiling weights can deviate from the expected values in order to be included...
std::string StackUsageOutput
Name of the stack usage file (i.e., .su file) if user passes -fstack-usage.
std::string OptRecordPasses
The regex that filters the passes that should be saved to the optimization records.
std::string SaveTempsFilePrefix
Prefix to use for -save-temps output.
XRayInstrSet XRayInstrumentationBundle
Set of XRay instrumentation kinds to emit.
bool hasSanitizeCoverage() const
SanitizerSet SanitizeAnnotateDebugInfo
Set of sanitizer checks, for which the instrumentation will be annotated with extra debug info.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
llvm::DenormalMode FP32DenormalMode
The floating-point denormal mode to use, for float.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
SanitizerSet SanitizeRecover
Set of sanitizer checks that are non-fatal (i.e.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
OptRemark OptimizationRemark
Selected optimizations for which we should enable optimization remarks.
std::string ThinLTOIndexFile
Name of the function summary index file to use for ThinLTO function importing.
const char * Argv0
Executable and command-line used to create a given CompilerInvocation.
SanitizerMaskCutoffs SanitizeSkipHotCutoffs
Set of thresholds in a range [0.0, 1.0]: the top hottest code responsible for the given fraction of P...
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
std::vector< uint8_t > CmdArgs
List of backend command-line options for -fembed-bitcode.
OptRemark OptimizationRemarkAnalysis
Selected optimizations for which we should enable optimization analyses.
std::optional< double > AllowRuntimeCheckSkipHotCutoff
std::vector< std::string > CommandLineArgs
void resetNonModularOptions(StringRef ModuleFormat)
Reset all of the options that are not considered when building a module.
std::string OptRecordFormat
The format used for serializing remarks (default: YAML)
std::string DIBugsReportFilePath
The file to use for dumping bug report by Debugify for original debug info.
OptRemark OptimizationRemarkMissed
Selected optimizations for which we should enable missed optimization remarks.
The base class of CompilerInvocation.
std::shared_ptr< DiagnosticOptions > DiagnosticOpts
Options controlling the diagnostic engine.
std::shared_ptr< AnalyzerOptions > AnalyzerOpts
Options controlling the static analyzer.
std::shared_ptr< MigratorOptions > MigratorOpts
std::shared_ptr< PreprocessorOutputOptions > PreprocessorOutputOpts
Options controlling preprocessed output.
std::shared_ptr< APINotesOptions > APINotesOpts
Options controlling API notes.
std::shared_ptr< TargetOptions > TargetOpts
Options controlling the target.
const FrontendOptions & getFrontendOpts() const
const CodeGenOptions & getCodeGenOpts() const
llvm::function_ref< const char *(const Twine &)> StringAllocator
Command line generation.
const FileSystemOptions & getFileSystemOpts() const
std::shared_ptr< PreprocessorOptions > PPOpts
Options controlling the preprocessor (aside from #include handling).
const PreprocessorOutputOptions & getPreprocessorOutputOpts() const
std::vector< std::string > getCC1CommandLine() const
Generate cc1-compatible command line arguments from this instance, wrapping the result as a std::vect...
std::shared_ptr< FileSystemOptions > FSOpts
Options controlling file system operations.
const AnalyzerOptions & getAnalyzerOpts() const
const MigratorOptions & getMigratorOpts() const
void generateCC1CommandLine(llvm::SmallVectorImpl< const char * > &Args, StringAllocator SA) const
Generate cc1-compatible command line arguments from this instance.
CompilerInvocationBase & deep_copy_assign(const CompilerInvocationBase &X)
const DependencyOutputOptions & getDependencyOutputOpts() const
CompilerInvocationBase & shallow_copy_assign(const CompilerInvocationBase &X)
const TargetOptions & getTargetOpts() const
std::shared_ptr< CodeGenOptions > CodeGenOpts
Options controlling IRgen and the backend.
std::shared_ptr< LangOptions > LangOpts
Options controlling the language variant.
const APINotesOptions & getAPINotesOpts() const
const HeaderSearchOptions & getHeaderSearchOpts() const
std::shared_ptr< HeaderSearchOptions > HSOpts
Options controlling the #include directive.
const PreprocessorOptions & getPreprocessorOpts() const
const DiagnosticOptions & getDiagnosticOpts() const
const LangOptions & getLangOpts() const
Const getters.
std::shared_ptr< FrontendOptions > FrontendOpts
Options controlling the frontend itself.
llvm::function_ref< void(const Twine &)> ArgumentConsumer
std::shared_ptr< DependencyOutputOptions > DependencyOutputOpts
Options controlling dependency output.
Helper class for holding the data necessary to invoke the compiler.
PreprocessorOptions & getPreprocessorOpts()
void clearImplicitModuleBuildOptions()
Disable implicit modules and canonicalize options that are only used by implicit modules.
MigratorOptions & getMigratorOpts()
AnalyzerOptions & getAnalyzerOpts()
APINotesOptions & getAPINotesOpts()
static std::string GetResourcesPath(const char *Argv0, void *MainAddr)
Get the directory where the compiler headers reside, relative to the compiler binary (found by the pa...
static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0=nullptr)
Create a compiler invocation from a list of input options.
LangOptions & getLangOpts()
Mutable getters.
static bool checkCC1RoundTrip(ArrayRef< const char * > Args, DiagnosticsEngine &Diags, const char *Argv0=nullptr)
Check that Args can be parsed and re-serialized without change, emiting diagnostics for any differenc...
DependencyOutputOptions & getDependencyOutputOpts()
CompilerInvocation()=default
void resetNonModularOptions()
Reset all of the options that are not considered when building a module.
FrontendOptions & getFrontendOpts()
std::string getModuleHash() const
Retrieve a module hash string that is suitable for uniquely identifying the conditions under which th...
FileSystemOptions & getFileSystemOpts()
CompilerInvocation & operator=(const CompilerInvocation &X)
static void setDefaultPointerAuthOptions(PointerAuthOptions &Opts, const LangOptions &LangOpts, const llvm::Triple &Triple)
Populate Opts with the default set of pointer authentication-related options given LangOpts and Tripl...
CodeGenOptions & getCodeGenOpts()
TargetOptions & getTargetOpts()
HeaderSearchOptions & getHeaderSearchOpts()
DiagnosticOptions & getDiagnosticOpts()
PreprocessorOutputOptions & getPreprocessorOutputOpts()
Same as CompilerInvocation, but with copy-on-write optimization.
FrontendOptions & getMutFrontendOpts()
LangOptions & getMutLangOpts()
Mutable getters.
HeaderSearchOptions & getMutHeaderSearchOpts()
MigratorOptions & getMutMigratorOpts()
PreprocessorOptions & getMutPreprocessorOpts()
APINotesOptions & getMutAPINotesOpts()
PreprocessorOutputOptions & getMutPreprocessorOutputOpts()
CodeGenOptions & getMutCodeGenOpts()
TargetOptions & getMutTargetOpts()
FileSystemOptions & getMutFileSystemOpts()
AnalyzerOptions & getMutAnalyzerOpts()
DiagnosticOptions & getMutDiagnosticOpts()
DependencyOutputOptions & getMutDependencyOutputOpts()
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
ShowIncludesDestination ShowIncludesDest
Destination of cl.exe style /showIncludes info.
HeaderIncludeFormatKind HeaderIncludeFormat
The format of header information.
std::string OutputFile
The file to write dependency output to.
HeaderIncludeFilteringKind HeaderIncludeFiltering
Determine whether header information should be filtered.
std::vector< std::string > Targets
A list of names to use as the targets in the dependency file; this list must contain at least one ent...
std::vector< std::pair< std::string, ExtraDepKind > > ExtraDeps
A list of extra dependencies (filename and kind) to be used for every target.
unsigned IncludeSystemHeaders
Include system header dependencies.
static llvm::IntrusiveRefCntPtr< DiagnosticIDs > create()
Options for controlling the compiler diagnostics engine.
std::string DiagnosticSuppressionMappingsFile
Path for the file that defines diagnostic suppression mappings.
std::vector< std::string > Remarks
The list of -R... options used to alter the diagnostic mappings, with the prefixes removed.
std::vector< std::string > Warnings
The list of -W... options used to alter the diagnostic mappings, with the prefixes removed.
std::vector< std::string > VerifyPrefixes
The prefixes for comment directives sought by -verify ("expected" by default).
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
unsigned getNumErrors() const
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
unsigned getNumWarnings() const
Keeps track of options that affect how file operations are performed.
FrontendOptions - Options for controlling the behavior of the frontend.
InputKind DashX
The input kind, either specified via -x argument or deduced from the input file name.
std::vector< std::string > ModuleFiles
The list of additional prebuilt module files to load before processing the input.
unsigned ClangIRDisablePasses
Disable Clang IR specific (CIR) passes.
std::map< std::string, std::vector< std::string > > PluginArgs
Args to pass to the plugins.
unsigned ClangIRDisableCIRVerifier
Disable Clang IR (CIR) verifier.
unsigned IsSystemModule
When using -emit-module, treat the modulemap as a system module.
unsigned UseClangIRPipeline
Use Clang IR pipeline to emit code.
ASTDumpOutputFormat ASTDumpFormat
Specifies the output format of the AST.
std::optional< std::string > AuxTargetCPU
Auxiliary target CPU for CUDA/HIP compilation.
std::string OutputFile
The output file, if any.
unsigned ShowStats
Show frontend performance metrics and statistics.
unsigned GenReducedBMI
Whether to generate reduced BMI for C++20 named modules.
std::string ActionName
The name of the action to run when using a plugin action.
std::vector< std::shared_ptr< ModuleFileExtension > > ModuleFileExtensions
The list of module file extensions.
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
std::string FixItSuffix
If given, the new suffix for fix-it rewritten files.
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
std::vector< std::string > Plugins
The list of plugins to load.
unsigned ASTDumpAll
Whether we deserialize all decls when forming AST dumps.
unsigned GenerateGlobalModuleIndex
Whether we can generate the global module index if needed.
unsigned DisableFree
Disable memory freeing on exit.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
frontend::ActionKind ProgramAction
The frontend action to perform.
std::optional< std::vector< std::string > > AuxTargetFeatures
Auxiliary target features for CUDA/HIP compilation.
std::string AuxTriple
Auxiliary triple for CUDA/HIP compilation.
unsigned UseGlobalModuleIndex
Whether we can use the global module index if available.
unsigned ASTDumpDecls
Whether we include declaration dumps in AST dumps.
A diagnostic client that ignores all diagnostics.
@ None
No signing for any function.
@ NonLeaf
Sign the return address of functions that spill LR.
@ All
Sign the return address of all functions,.
@ BKey
Return address signing uses APIB key.
@ AKey
Return address signing uses APIA key.
@ None
Don't exclude any overflow patterns from sanitizers.
@ AddUnsignedOverflowTest
if (a + b < a)
@ All
Exclude all overflow patterns (below)
@ AddSignedOverflowTest
if (a + b < a)
@ PostDecrInWhile
while (count–)
CompatibilityKind
For ASTs produced with different option value, signifies their level of compatibility.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void resetNonModularOptions()
Reset all of the options that are not considered when building a module.
std::optional< TargetCXXABI::Kind > CXXABI
C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
clang::ObjCRuntime ObjCRuntime
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned OverflowPatternExclusionMask
Which overflow patterns should be excluded from sanitizer instrumentation.
SanitizerSet Sanitize
Set of enabled sanitizers.
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
static void setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T, std::vector< std::string > &Includes, LangStandard::Kind LangStd=LangStandard::lang_unspecified)
Set language defaults for the given input language and language standard in the given LangOptions obj...
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
std::string RandstructSeed
The seed used by the randomize structure layout feature.
std::map< std::string, std::string, std::greater< std::string > > MacroPrefixMap
A prefix map for FILE, BASE_FILE and __builtin_FILE().
bool isTargetDevice() const
True when compiling for an offloading target device.
LangStandard::Kind LangStd
The used language standard.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
bool SanitizeCoverage
Is at least one coverage instrumentation type enabled.
std::vector< llvm::Triple > OMPTargetTriples
Triples of the OpenMP targets that the host code codegen should take into account in order to generat...
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
The basic abstraction for the target Objective-C runtime.
bool allowsWeak() const
Does this runtime allow the use of __weak?
bool tryParse(StringRef input)
Try to parse an Objective-C runtime specification from the given string.
std::string getAsString() const
bool allowsARC() const
Does this runtime allow ARC at all?
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
Discrimination
Forms of extra discrimination.
ARM8_3Key
Hardware pointer-signing keys in ARM8.3.
static constexpr std::optional< PositiveAnalyzerOption > create(unsigned Val)
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
std::vector< std::pair< std::string, std::string > > RemappedFiles
The set of file remappings, which take existing files on the system (the first part of each pair) and...
bool PCHWithHdrStopCreate
When true, we are creating a PCH or creating the PCH object while expecting a pragma hdrstop to separ...
std::vector< std::string > Includes
std::pair< unsigned, bool > PrecompiledPreambleBytes
If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...
bool LexEditorPlaceholders
When enabled, the preprocessor will construct editor placeholder tokens.
void resetNonModularOptions()
Reset any options that are not considered when building a module.
void addMacroUndef(StringRef Name)
std::set< std::string > DeserializedPCHDeclsToErrorOn
This is a set of names for decls that we do not want to be deserialized, and we emit an error if they...
std::vector< std::string > EmbedEntries
User specified embed entries.
void addMacroDef(StringRef Name)
bool DefineTargetOSMacros
Indicates whether to predefine target OS macros.
bool DetailedRecord
Whether we should maintain a detailed record of all macro definitions and expansions.
std::vector< std::string > ChainedIncludes
Headers that will be converted to chained PCHs in memory.
bool PCHWithHdrStop
When true, we are creating or using a PCH where a pragma hdrstop is expected to indicate the beginnin...
std::optional< uint64_t > SourceDateEpoch
If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
bool UsePredefines
Initialize the preprocessor with the compiler and target specific predefines.
void addRemappedFile(StringRef From, StringRef To)
std::vector< std::pair< std::string, bool > > Macros
PreprocessorOutputOptions - Options for controlling the C preprocessor output (e.g....
unsigned ShowMacros
Print macro definitions.
unsigned ShowCPP
Print normal preprocessed output.
unsigned ShowLineMarkers
Show #line markers.
unsigned DirectivesOnly
Process directives but do not expand macros.
Encodes a location in the source.
static bool isSupportedCXXABI(const llvm::Triple &T, Kind Kind)
static const auto & getSpelling(Kind ABIKind)
static bool usesRelativeVTables(const llvm::Triple &T)
static bool isABI(StringRef Name)
Options for controlling the target.
std::string Triple
The name of the target triple to compile for.
llvm::VersionTuple SDKVersion
The version of the SDK which was used during the compilation.
uint64_t LargeDataThreshold
llvm::VersionTuple DarwinTargetVariantSDKVersion
The version of the darwin target variant SDK which was used during the compilation.
std::string HostTriple
When compiling for the device side, contains the triple used to compile for the host.
Action - Represent an abstract compilation step to perform.
static std::string GetResourcesPath(StringRef BinaryPath)
Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...
constexpr XRayInstrMask None
constexpr XRayInstrMask All
const llvm::opt::OptTable & getDriverOptTable()
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
IncludeDirGroup
IncludeDirGroup - Identifies the group an include Entry belongs to, representing its relative positiv...
@ CXXSystem
Like System, but only used for C++.
@ Angled
Paths for '#include <>' added by '-I'.
@ CSystem
Like System, but only used for C.
@ System
Like Angled, but marks system directories.
@ Quoted
'#include ""' paths, added by 'gcc -iquote'.
@ ExternCSystem
Like System, but headers are implicitly wrapped in extern "C".
@ ObjCSystem
Like System, but only used for ObjC.
@ ObjCXXSystem
Like System, but only used for ObjC++.
@ After
Like System, but searched after the system directories.
@ GenerateHeaderUnit
Generate a C++20 header unit module from a header file.
@ VerifyPCH
Load and verify that a PCH file is usable.
@ PrintPreprocessedInput
-E mode.
@ RewriteTest
Rewriter playground.
@ ParseSyntaxOnly
Parse and perform semantic analysis.
@ TemplightDump
Dump template instantiations.
@ GenerateModuleInterface
Generate pre-compiled module from a standard C++ module interface unit.
@ EmitLLVM
Emit a .ll file.
@ PrintPreamble
Print the "preamble" of the input file.
@ InitOnly
Only execute frontend initialization.
@ ASTView
Parse ASTs and view them in Graphviz.
@ PluginAction
Run a plugin action,.
@ DumpRawTokens
Dump out raw tokens.
@ PrintDependencyDirectivesSourceMinimizerOutput
Print the output of the dependency directives source minimizer.
@ RewriteObjC
ObjC->C Rewriter.
@ RunPreprocessorOnly
Just lex, no output.
@ ModuleFileInfo
Dump information about a module file.
@ EmitCIR
Emit a .cir file.
@ DumpCompilerOptions
Dump the compiler configuration.
@ RunAnalysis
Run one or more source code analyses.
@ ASTPrint
Parse ASTs and print them.
@ GenerateReducedModuleInterface
Generate reduced module interface for a standard C++ module interface unit.
@ GenerateInterfaceStubs
Generate Interface Stub Files.
@ ASTDump
Parse ASTs and dump them.
@ DumpTokens
Dump out preprocessed tokens.
@ FixIt
Parse and apply any fixits to the source.
@ EmitAssembly
Emit a .s file.
@ EmitCodeGenOnly
Generate machine code, but don't emit anything.
@ RewriteMacros
Expand macros but not #includes.
@ EmitHTML
Translate input source into HTML.
@ GeneratePCH
Generate pre-compiled header.
@ EmitLLVMOnly
Generate LLVM IR, but do not emit anything.
@ GenerateModule
Generate pre-compiled module from a module map.
@ ASTDeclList
Parse ASTs and list Decl nodes.
bool EQ(InterpState &S, CodePtr OpPC)
const unsigned VERSION_MINOR
AST file minor version number supported by this version of Clang.
const unsigned VERSION_MAJOR
AST file major version number supported by this version of Clang.
The JSON file list parser is used to communicate input to InstallAPI.
ASTDumpOutputFormat
Used to specify the format for printing AST dump information.
bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags=nullptr, bool DefaultDiagColor=true)
Fill out Opts based on the options given in Args.
SanitizerMask getPPTransparentSanitizers()
Return the sanitizers which do not affect preprocessing.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromOverlayFiles(ArrayRef< std::string > VFSOverlayFiles, DiagnosticsEngine &Diags, IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS)
DiagnosticLevelMask
A bitmask representing the diagnostic levels used by VerifyDiagnosticConsumer.
const char * headerIncludeFormatKindToString(HeaderIncludeFormatKind K)
std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)
constexpr uint16_t BlockDescriptorConstantDiscriminator
Constant discriminator to be used with block descriptor pointers.
constexpr uint16_t IsaPointerConstantDiscriminator
Constant discriminator to be used with objective-c isa pointers.
const char * headerIncludeFilteringKindToString(HeaderIncludeFilteringKind K)
std::vector< std::string > Macros
A list of macros of the form <definition>=<expansion> .
AnalysisConstraints
AnalysisConstraints - Set of available constraint models.
@ Success
Annotation was successful.
@ Parse
Parse the block; this code is always used.
constexpr uint16_t SuperPointerConstantDiscriminator
Constant discriminator to be used with objective-c superclass pointers.
void serializeSanitizerSet(SanitizerSet Set, SmallVectorImpl< StringRef > &Values)
Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
constexpr uint16_t MethodListPointerConstantDiscriminator
Constant discriminator to be used with method list pointers.
constexpr uint16_t ClassROConstantDiscriminator
Constant discriminator to be used with objective-c class_ro_t pointers.
constexpr uint16_t InitFiniPointerConstantDiscriminator
Constant discriminator to be used with function pointers in .init_array and .fini_array.
@ C
Languages that the frontend can parse and compile.
@ CIR
LLVM IR & CIR: we accept these so that we can run the optimizer on them, and compile them to assembly...
@ Asm
Assembly: we accept this only so that we can preprocess it.
bool parseSanitizerWeightedValue(StringRef Value, bool AllowGroups, SanitizerMaskCutoffs &Cutoffs)
Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= or -fno-sanitize= value lis...
@ Result
The result type of a method or function.
XRayInstrMask parseXRayInstrValue(StringRef Value)
Parses a command line argument into a mask.
const FunctionProtoType * T
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
void serializeXRayInstrValue(XRayInstrSet Set, SmallVectorImpl< StringRef > &Values)
Serializes a set into a list of command line arguments.
AnalysisPurgeMode
AnalysisPurgeModes - Set of available strategies for dead symbol removal.
void serializeSanitizerMaskCutoffs(const SanitizerMaskCutoffs &Cutoffs, SmallVectorImpl< std::string > &Values)
Serialize a SanitizerMaskCutoffs into command line arguments.
ShaderStage
Shader programs run in specific pipeline stages.
constexpr uint16_t StdTypeInfoVTablePointerConstantDiscrimination
Constant discriminator for std::type_info vtable pointers: 0xB1EA/45546 The value is ptrauth_string_d...
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
AnalysisDiagClients
AnalysisDiagClients - Set of available diagnostic clients for rendering analysis results.
@ NUM_ANALYSIS_DIAG_CLIENTS
std::string getClangFullRepositoryVersion()
Retrieves the full repository version that is an amalgamation of the information in getClangRepositor...
int getLastArgIntValue(const llvm::opt::ArgList &Args, llvm::opt::OptSpecifier Id, int Default, DiagnosticsEngine *Diags=nullptr, unsigned Base=0)
Return the value of the last argument as an integer, or a default.
AnalysisInliningMode
AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
int const char * function
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
bool Internalize
If true, we use LLVM module internalizer.
bool PropagateAttrs
If true, we set attributes functions in the bitcode library according to our CodeGenOptions,...
std::string Filename
The filename of the bitcode file to link in.
unsigned LinkFlags
Bitwise combination of llvm::Linker::Flags, passed to the LLVM linker.
Dummy tag type whose instance can be passed into the constructor to prevent creation of the reference...
LangStandard - Information about the properties of a particular language standard.
clang::Language getLanguage() const
Get the language that this standard describes.
const char * getDescription() const
getDescription - Get the description of this standard.
static const LangStandard & getLangStandardForKind(Kind K)
const char * getName() const
getName - Get the name of this standard.
static Kind getLangKind(StringRef Name)
static ParsedSourceLocation FromString(StringRef Str)
Construct a parsed source location from a string; the Filename is empty on error.
std::string ToString() const
Serialize ParsedSourceLocation back to a string.
PointerAuthSchema BlockDescriptorPointers
The ABI for pointers to block descriptors.
PointerAuthSchema BlockHelperFunctionPointers
The ABI for block object copy/destroy function pointers.
PointerAuthSchema CXXVTablePointers
The ABI for C++ virtual table pointers (the pointer to the table itself) as installed in an actual cl...
PointerAuthSchema InitFiniPointers
The ABI for function addresses in .init_array and .fini_array.
PointerAuthSchema BlockInvocationFunctionPointers
The ABI for block invocation function pointers.
PointerAuthSchema BlockByrefHelperFunctionPointers
The ABI for __block variable copy/destroy function pointers.
PointerAuthSchema CXXVTTVTablePointers
The ABI for C++ virtual table pointers as installed in a VTT.
bool ReturnAddresses
Should return addresses be authenticated?
PointerAuthSchema CXXTypeInfoVTablePointer
TypeInfo has external ABI requirements and is emitted without actually having parsed the libcxx defin...
bool AArch64JumpTableHardening
Use hardened lowering for jump-table dispatch?
PointerAuthSchema ObjCMethodListPointer
The ABI for a reference to an Objective-C method list in _class_ro_t.
PointerAuthSchema FunctionPointers
The ABI for C function pointers.
PointerAuthSchema ObjCSuperPointers
The ABI for Objective-C superclass pointers.
bool AuthTraps
Do authentication failures cause a trap?
PointerAuthSchema CXXMemberFunctionPointers
The ABI for C++ member function pointers.
PointerAuthSchema CXXVirtualVariadicFunctionPointers
The ABI for variadic C++ virtual function pointers.
PointerAuthSchema ObjCMethodListFunctionPointers
The ABI for Objective-C method lists.
PointerAuthSchema ObjCClassROPointers
The ABI for Objective-C class_ro_t pointers.
PointerAuthSchema CXXVirtualFunctionPointers
The ABI for most C++ virtual function pointers, i.e. v-table entries.
PointerAuthSchema ObjCIsaPointers
The ABI for Objective-C isa pointers.
bool IndirectGotos
Do indirect goto label addresses need to be authenticated?
void clear(SanitizerMask K=SanitizerKind::All)
Disable the sanitizers specified in K.
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
bool empty() const
Returns true if no sanitizers are enabled.
SanitizerMask Mask
Bitmask of enabled sanitizers.
void set(XRayInstrMask K, bool Value)