clang: lib/Frontend/CompilerInvocation.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
29#include "clang/Config/config.h"
48#include "llvm/ADT/APInt.h"
49#include "llvm/ADT/ArrayRef.h"
50#include "llvm/ADT/CachedHashString.h"
51#include "llvm/ADT/FloatingPointMode.h"
52#include "llvm/ADT/Hashing.h"
53#include "llvm/ADT/STLExtras.h"
54#include "llvm/ADT/SmallString.h"
55#include "llvm/ADT/SmallVector.h"
56#include "llvm/ADT/StringRef.h"
57#include "llvm/ADT/StringSwitch.h"
58#include "llvm/ADT/Twine.h"
59#include "llvm/Config/llvm-config.h"
60#include "llvm/Frontend/Debug/Options.h"
61#include "llvm/IR/DebugInfoMetadata.h"
62#include "llvm/Linker/Linker.h"
63#include "llvm/MC/MCTargetOptions.h"
64#include "llvm/Option/Arg.h"
65#include "llvm/Option/ArgList.h"
66#include "llvm/Option/OptSpecifier.h"
67#include "llvm/Option/OptTable.h"
68#include "llvm/Option/Option.h"
69#include "llvm/ProfileData/InstrProfReader.h"
70#include "llvm/Remarks/HotnessThresholdParser.h"
71#include "llvm/Support/CodeGen.h"
72#include "llvm/Support/Compiler.h"
73#include "llvm/Support/Error.h"
74#include "llvm/Support/ErrorHandling.h"
75#include "llvm/Support/ErrorOr.h"
76#include "llvm/Support/FileSystem.h"
77#include "llvm/Support/HashBuilder.h"
78#include "llvm/Support/MathExtras.h"
79#include "llvm/Support/MemoryBuffer.h"
80#include "llvm/Support/Path.h"
81#include "llvm/Support/Process.h"
82#include "llvm/Support/Regex.h"
83#include "llvm/Support/VersionTuple.h"
84#include "llvm/Support/VirtualFileSystem.h"
85#include "llvm/Support/raw_ostream.h"
86#include "llvm/Target/TargetOptions.h"
87#include "llvm/TargetParser/Host.h"
88#include "llvm/TargetParser/Triple.h"
89#include
90#include
91#include
92#include
93#include
94#include
95#include
96#include
97#include
98#include
99#include
100#include
101#include <type_traits>
102#include
103#include
104
105using namespace clang;
106using namespace driver;
107using namespace options;
109
110
111
112
113
114
115
117 uint32_t Val;
118 if (Arg.getAsInteger(10, Val))
119 return llvm::createStringError(llvm::inconvertibleErrorCode(),
120 "Not an integer: %s", Arg.data());
121 return Val;
122}
123
124
125
126
127
128namespace {
129template std::shared_ptr make_shared_copy(const T &X) {
130 return std::make_shared(X);
131}
132
133template
135 return llvm::makeIntrusiveRefCnt(X);
136}
137}
138
153
156 if (this != &X) {
157 LangOpts = make_shared_copy(X.getLangOpts());
158 TargetOpts = make_shared_copy(X.getTargetOpts());
159 DiagnosticOpts = makeIntrusiveRefCntCopy(X.getDiagnosticOpts());
160 HSOpts = make_shared_copy(X.getHeaderSearchOpts());
161 PPOpts = make_shared_copy(X.getPreprocessorOpts());
162 AnalyzerOpts = makeIntrusiveRefCntCopy(X.getAnalyzerOpts());
163 MigratorOpts = make_shared_copy(X.getMigratorOpts());
164 APINotesOpts = make_shared_copy(X.getAPINotesOpts());
165 CodeGenOpts = make_shared_copy(X.getCodeGenOpts());
166 FSOpts = make_shared_copy(X.getFileSystemOpts());
167 FrontendOpts = make_shared_copy(X.getFrontendOpts());
170 }
171 return *this;
172}
173
176 if (this != &X) {
190 }
191 return *this;
192}
193
197}
198
202 return *this;
203}
204
205namespace {
206template
207T &ensureOwned(std::shared_ptr &Storage) {
208 if (Storage.use_count() > 1)
209 Storage = std::make_shared(*Storage);
210 return *Storage;
211}
212
213template
215 if (Storage.useCount() > 1)
216 Storage = llvm::makeIntrusiveRefCnt(*Storage);
217 return *Storage;
218}
219}
220
222 return ensureOwned(LangOpts);
223}
224
227}
228
231}
232
234 return ensureOwned(HSOpts);
235}
236
238 return ensureOwned(PPOpts);
239}
240
243}
244
247}
248
251}
252
255}
256
258 return ensureOwned(FSOpts);
259}
260
263}
264
267}
268
272}
273
274
275
276
277
279
280#define OPTTABLE_STR_TABLE_CODE
281#include "clang/Driver/Options.inc"
282#undef OPTTABLE_STR_TABLE_CODE
283
285 return &OptionStrTable[Offset];
286}
287
288#define SIMPLE_ENUM_VALUE_TABLE
289#include "clang/Driver/Options.inc"
290#undef SIMPLE_ENUM_VALUE_TABLE
291
293 unsigned TableIndex,
294 const ArgList &Args,
296 if (Args.hasArg(Opt))
297 return true;
298 return std::nullopt;
299}
300
302 unsigned,
303 const ArgList &Args,
305 if (Args.hasArg(Opt))
306 return false;
307 return std::nullopt;
308}
309
310
311
312
313
315 unsigned SpellingOffset, Option::OptionClass,
316 unsigned, ...) {
318}
320 const Twine &Spelling, Option::OptionClass,
321 unsigned, ...) {
322 Consumer(Spelling);
323}
324
326 return !std::is_same_v<T, uint64_t> && llvm::is_integral_or_enum::value;
327}
328
329template <typename T,
330 std::enable_if_t<!is_uint64_t_convertible(), bool> = false>
332 return [Value](OptSpecifier Opt, unsigned, const ArgList &Args,
334 if (Args.hasArg(Opt))
336 return std::nullopt;
337 };
338}
339
340template <typename T,
341 std::enable_if_t<is_uint64_t_convertible(), bool> = false>
344}
345
347 OptSpecifier OtherOpt) {
348 return [Value, OtherValue,
349 OtherOpt](OptSpecifier Opt, unsigned, const ArgList &Args,
351 if (const Arg *A = Args.getLastArg(Opt, OtherOpt)) {
352 return A->getOption().matches(Opt) ? Value : OtherValue;
353 }
354 return std::nullopt;
355 };
356}
357
360 Option::OptionClass, unsigned, bool KeyPath) {
361 if (KeyPath == Value)
363 };
364}
365
367 const Twine &Spelling,
368 Option::OptionClass OptClass, unsigned,
369 const Twine &Value) {
370 switch (OptClass) {
371 case Option::SeparateClass:
372 case Option::JoinedOrSeparateClass:
373 case Option::JoinedAndSeparateClass:
374 Consumer(Spelling);
376 break;
377 case Option::JoinedClass:
378 case Option::CommaJoinedClass:
379 Consumer(Spelling + Value);
380 break;
381 default:
382 llvm_unreachable("Cannot denormalize an option with option class "
383 "incompatible with string denormalization.");
384 }
385}
386
387template
388static void
390 Option::OptionClass OptClass, unsigned TableIndex, T Value) {
392 TableIndex, Twine(Value));
393}
394
395template
397 Option::OptionClass OptClass, unsigned TableIndex,
400}
401
402static std::optional
404 for (int I = 0, E = Table.Size; I != E; ++I)
405 if (Name == Table.Table[I].Name)
406 return Table.Table[I];
407
408 return std::nullopt;
409}
410
411static std::optional
413 for (int I = 0, E = Table.Size; I != E; ++I)
415 return Table.Table[I];
416
417 return std::nullopt;
418}
419
421 unsigned TableIndex,
422 const ArgList &Args,
424 assert(TableIndex < SimpleEnumValueTablesSize);
425 const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
426
427 auto *Arg = Args.getLastArg(Opt);
428 if (!Arg)
429 return std::nullopt;
430
431 StringRef ArgValue = Arg->getValue();
433 return MaybeEnumVal->Value;
434
435 Diags.Report(diag::err_drv_invalid_value)
436 << Arg->getAsString(Args) << ArgValue;
437 return std::nullopt;
438}
439
441 unsigned SpellingOffset,
442 Option::OptionClass OptClass,
443 unsigned TableIndex, unsigned Value) {
444 assert(TableIndex < SimpleEnumValueTablesSize);
445 const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
448 TableIndex, MaybeEnumVal->Name);
449 } else {
450 llvm_unreachable("The simple enum value was not correctly defined in "
451 "the tablegen option description");
452 }
453}
454
455template
457 unsigned SpellingOffset,
458 Option::OptionClass OptClass,
459 unsigned TableIndex, T Value) {
461 TableIndex, static_cast<unsigned>(Value));
462}
463
465 int TableIndex,
466 const ArgList &Args,
468 auto *Arg = Args.getLastArg(Opt);
469 if (!Arg)
470 return std::nullopt;
471 return std::string(Arg->getValue());
472}
473
474template
476 const ArgList &Args,
478 auto *Arg = Args.getLastArg(Opt);
479 if (!Arg)
480 return std::nullopt;
481 IntTy Res;
482 if (StringRef(Arg->getValue()).getAsInteger(0, Res)) {
483 Diags.Report(diag::err_drv_invalid_int_value)
484 << Arg->getAsString(Args) << Arg->getValue();
485 return std::nullopt;
486 }
487 return Res;
488}
489
490static std::optional<std::vectorstd::string>
493 return Args.getAllArgValues(Opt);
494}
495
497 unsigned SpellingOffset,
498 Option::OptionClass OptClass,
499 unsigned TableIndex,
500 const std::vectorstd::string &Values) {
501 switch (OptClass) {
502 case Option::CommaJoinedClass: {
503 std::string CommaJoinedValue;
504 if (!Values.empty()) {
505 CommaJoinedValue.append(Values.front());
506 for (const std::string &Value : llvm::drop_begin(Values, 1)) {
507 CommaJoinedValue.append(",");
508 CommaJoinedValue.append(Value);
509 }
510 }
512 Option::OptionClass::JoinedClass, TableIndex,
513 CommaJoinedValue);
514 break;
515 }
516 case Option::JoinedClass:
517 case Option::SeparateClass:
518 case Option::JoinedOrSeparateClass:
519 for (const std::string &Value : Values)
521 break;
522 default:
523 llvm_unreachable("Cannot denormalize an option with option class "
524 "incompatible with string vector denormalization.");
525 }
526}
527
529 int TableIndex,
530 const ArgList &Args,
532 auto *Arg = Args.getLastArg(Opt);
533 if (!Arg)
534 return std::nullopt;
535 return llvm::Triple::normalize(Arg->getValue());
536}
537
538template <typename T, typename U>
540 return static_cast<T>(Value);
541}
542
544 return KeyPath | Value;
545}
546
548 return KeyPath;
549}
550
551template <typename T, typename U, U Value>
553 return ((KeyPath & Value) == Value) ? static_cast<T>(Value) : T();
554}
555
556#define PARSE_OPTION_WITH_MARSHALLING( \
557 ARGS, DIAGS, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, \
558 ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \
559 METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
560 IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \
561 TABLE_INDEX) \
562 if ((VISIBILITY) & options::CC1Option) { \
563 KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \
564 if (IMPLIED_CHECK) \
565 KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \
566 if (SHOULD_PARSE) \
567 if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, ARGS, DIAGS)) \
568 KEYPATH = \
569 MERGER(KEYPATH, static_cast<decltype(KEYPATH)>(*MaybeValue)); \
570 }
571
572
573
574#define GENERATE_OPTION_WITH_MARSHALLING( \
575 CONSUMER, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, ALIASARGS, \
576 FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \
577 SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \
578 IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \
579 if ((VISIBILITY) & options::CC1Option) { \
580 [&](const auto &Extracted) { \
581 if (ALWAYS_EMIT || \
582 (Extracted != \
583 static_cast<decltype(KEYPATH)>((IMPLIED_CHECK) ? (IMPLIED_VALUE) \
584 : (DEFAULT_VALUE)))) \
585 DENORMALIZER(CONSUMER, SPELLING_OFFSET, Option::KIND##Class, \
586 TABLE_INDEX, Extracted); \
587 }(EXTRACTOR(KEYPATH)); \
588 }
589
591
595 unsigned NumErrorsBefore = Diags.getNumErrors();
596
601 CodeGenOpts.XRayInstrumentFunctions = LangOpts.XRayInstrument;
602 CodeGenOpts.XRayAlwaysEmitCustomEvents = LangOpts.XRayAlwaysEmitCustomEvents;
603 CodeGenOpts.XRayAlwaysEmitTypedEvents = LangOpts.XRayAlwaysEmitTypedEvents;
604 CodeGenOpts.DisableFree = FrontendOpts.DisableFree;
607 CodeGenOpts.ClearASTBeforeBackend = false;
609 LangOpts.ForceEmitVTables = CodeGenOpts.ForceEmitVTables;
610 LangOpts.SpeculativeLoadHardening = CodeGenOpts.SpeculativeLoadHardening;
612
613 llvm::Triple T(TargetOpts.Triple);
614 llvm::Triple::ArchType Arch = T.getArch();
615
618
619 if (LangOpts.getExceptionHandling() !=
621 T.isWindowsMSVCEnvironment())
622 Diags.Report(diag::err_fe_invalid_exception_model)
623 << static_cast<unsigned>(LangOpts.getExceptionHandling()) << T.str();
624
625 if (LangOpts.AppleKext && !LangOpts.CPlusPlus)
626 Diags.Report(diag::warn_c_kext);
627
628 if (LangOpts.NewAlignOverride &&
629 !llvm::isPowerOf2_32(LangOpts.NewAlignOverride)) {
630 Arg *A = Args.getLastArg(OPT_fnew_alignment_EQ);
631 Diags.Report(diag::err_fe_invalid_alignment)
632 << A->getAsString(Args) << A->getValue();
633 LangOpts.NewAlignOverride = 0;
634 }
635
636
637
638 if (LangOpts.CPlusPlus11) {
639 if (Args.hasArg(OPT_fraw_string_literals, OPT_fno_raw_string_literals)) {
640 Args.claimAllArgs(OPT_fraw_string_literals, OPT_fno_raw_string_literals);
641 Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx11)
642 << bool(LangOpts.RawStringLiterals);
643 }
644
645
646 LangOpts.RawStringLiterals = true;
647 }
648
649
650 if (LangOpts.SYCLIsDevice && LangOpts.SYCLIsHost)
651 Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fsycl-is-device"
652 << "-fsycl-is-host";
653
654 if (Args.hasArg(OPT_fgnu89_inline) && LangOpts.CPlusPlus)
655 Diags.Report(diag::err_drv_argument_not_allowed_with)
657
658 if (Args.hasArg(OPT_hlsl_entrypoint) && !LangOpts.HLSL)
659 Diags.Report(diag::err_drv_argument_not_allowed_with)
661
662 if (Args.hasArg(OPT_fgpu_allow_device_init) && !LangOpts.HIP)
663 Diags.Report(diag::warn_ignored_hip_only_option)
664 << Args.getLastArg(OPT_fgpu_allow_device_init)->getAsString(Args);
665
666 if (Args.hasArg(OPT_gpu_max_threads_per_block_EQ) && !LangOpts.HIP)
667 Diags.Report(diag::warn_ignored_hip_only_option)
668 << Args.getLastArg(OPT_gpu_max_threads_per_block_EQ)->getAsString(Args);
669
670
671
672
673
674
675
676
677 if (Args.hasArg(OPT_ffp_eval_method_EQ)) {
678 if (LangOpts.ApproxFunc)
679 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 0;
680 if (LangOpts.AllowFPReassoc)
681 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 1;
682 if (LangOpts.AllowRecip)
683 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 2;
684 }
685
686
687
688
689 if (Args.getLastArg(OPT_cl_strict_aliasing) &&
691 Diags.Report(diag::warn_option_invalid_ocl_version)
693 << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args);
694
695 if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
696 auto DefaultCC = LangOpts.getDefaultCallingConv();
697
700 Arch != llvm::Triple::x86;
703 .isX86();
705 if (emitError)
706 Diags.Report(diag::err_drv_argument_not_allowed_with)
707 << A->getSpelling() << T.getTriple();
708 }
709
710 return Diags.getNumErrors() == NumErrorsBefore;
711}
712
713
714
715
716
719 unsigned DefaultOpt = 0;
722 !Args.hasArg(OPT_cl_opt_disable))
723 DefaultOpt = 2;
724
725 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
726 if (A->getOption().matches(options::OPT_O0))
727 return 0;
728
729 if (A->getOption().matches(options::OPT_Ofast))
730 return 3;
731
732 assert(A->getOption().matches(options::OPT_O));
733
734 StringRef S(A->getValue());
735 if (S == "s" || S == "z")
736 return 2;
737
738 if (S == "g")
739 return 1;
740
742 }
743
744 return DefaultOpt;
745}
746
748 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
749 if (A->getOption().matches(options::OPT_O)) {
750 switch (A->getValue()[0]) {
751 default:
752 return 0;
753 case 's':
754 return 1;
755 case 'z':
756 return 2;
757 }
758 }
759 }
760 return 0;
761}
762
764 llvm::opt::OptSpecifier OptSpecifier) {
767 Option::OptionClass::FlagClass, 0);
768}
769
771 llvm::opt::OptSpecifier OptSpecifier,
772 const Twine &Value) {
775}
776
777
781
782
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
810 bool CheckAgainstOriginalInvocation = false,
811 bool ForceRoundTrip = false) {
812#ifndef NDEBUG
813 bool DoRoundTripDefault = true;
814#else
815 bool DoRoundTripDefault = false;
816#endif
817
818 bool DoRoundTrip = DoRoundTripDefault;
819 if (ForceRoundTrip) {
820 DoRoundTrip = true;
821 } else {
822 for (const auto *Arg : CommandLineArgs) {
823 if (Arg == StringRef("-round-trip-args"))
824 DoRoundTrip = true;
825 if (Arg == StringRef("-no-round-trip-args"))
826 DoRoundTrip = false;
827 }
828 }
829
830
831
832 if (!DoRoundTrip)
833 return Parse(RealInvocation, CommandLineArgs, Diags, Argv0);
834
835
837 std::string Buffer;
838 llvm::raw_string_ostream OS(Buffer);
839 for (const char *Arg : Args) {
840 llvm::sys::printArg(OS, Arg, true);
841 OS << ' ';
842 }
843 return Buffer;
844 };
845
846
849
850
851
852 if (!Parse(DummyInvocation, CommandLineArgs, DummyDiags, Argv0) ||
854
855
856
857
859 auto Success = Parse(RealInvocation, CommandLineArgs, Diags, Argv0);
862
863
864
865 Diags.Report(diag::err_cc1_round_trip_fail_then_ok);
866 Diags.Report(diag::note_cc1_round_trip_original)
867 << SerializeArgs(CommandLineArgs);
868 return false;
869 }
870
871
872 llvm::BumpPtrAllocator Alloc;
873 llvm::StringSaver StringPool(Alloc);
874 auto SA = [&StringPool](const Twine &Arg) {
875 return StringPool.save(Arg).data();
876 };
877
878
879
880
882 Generate(DummyInvocation, GeneratedArgs, SA);
883
884
885
886
887
888 bool Success2 = Parse(RealInvocation, GeneratedArgs, Diags, Argv0);
889
890
891
892 if (!Success2) {
893 Diags.Report(diag::err_cc1_round_trip_ok_then_fail);
894 Diags.Report(diag::note_cc1_round_trip_generated)
895 << 1 << SerializeArgs(GeneratedArgs);
896 return false;
897 }
898
900 if (CheckAgainstOriginalInvocation)
901
902 ComparisonArgs.assign(CommandLineArgs.begin(), CommandLineArgs.end());
903 else
904
905
906 Generate(RealInvocation, ComparisonArgs, SA);
907
908
911 return std::equal(A.begin(), A.end(), B.begin(), B.end(),
912 [](const char *AElem, const char *BElem) {
913 return StringRef(AElem) == StringRef(BElem);
914 });
915 };
916
917
918
919
920 if ((GeneratedArgs, ComparisonArgs)) {
921 Diags.Report(diag::err_cc1_round_trip_mismatch);
922 Diags.Report(diag::note_cc1_round_trip_generated)
923 << 1 << SerializeArgs(GeneratedArgs);
924 Diags.Report(diag::note_cc1_round_trip_generated)
925 << 2 << SerializeArgs(ComparisonArgs);
926 return false;
927 }
928
929 Diags.Report(diag::remark_cc1_round_trip_generated)
930 << 1 << SerializeArgs(GeneratedArgs);
931 Diags.Report(diag::remark_cc1_round_trip_generated)
932 << 2 << SerializeArgs(ComparisonArgs);
933
934 return Success2;
935}
936
939 const char *Argv0) {
944 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
945 },
948 Args.push_back("-cc1");
950 },
951 DummyInvocation1, DummyInvocation2, Args, Diags, Argv0,
952 true, true);
953}
954
956 OptSpecifier GroupWithValue,
957 std::vectorstd::string &Diagnostics) {
958 for (auto *A : Args.filtered(Group)) {
959 if (A->getOption().getKind() == Option::FlagClass) {
960
961
962 Diagnostics.push_back(
963 std::string(A->getOption().getName().drop_front(1)));
964 } else if (A->getOption().matches(GroupWithValue)) {
965
966
967 Diagnostics.push_back(
968 std::string(A->getOption().getName().drop_front(1).rtrim("=-")));
969 } else {
970
971 Diagnostics.push_back(A->getValue());
972 }
973 }
974}
975
976
977
980
982 std::vectorstd::string &Funcs) {
983 std::vectorstd::string Values = Args.getAllArgValues(OPT_fno_builtin_);
985 Funcs.insert(Funcs.end(), Values.begin(), BuiltinEnd);
986}
987
991
992#define ANALYZER_OPTION_WITH_MARSHALLING(...) \
993 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
994#include "clang/Driver/Options.inc"
995#undef ANALYZER_OPTION_WITH_MARSHALLING
996
999#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
1000 case NAME##Model: \
1001 GenerateArg(Consumer, OPT_analyzer_constraints, CMDFLAG); \
1002 break;
1003#include "clang/StaticAnalyzer/Core/Analyses.def"
1004 default:
1005 llvm_unreachable("Tried to generate unknown analysis constraint.");
1006 }
1007 }
1008
1011#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
1012 case PD_##NAME: \
1013 GenerateArg(Consumer, OPT_analyzer_output, CMDFLAG); \
1014 break;
1015#include "clang/StaticAnalyzer/Core/Analyses.def"
1016 default:
1017 llvm_unreachable("Tried to generate unknown analysis diagnostic client.");
1018 }
1019 }
1020
1023#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
1024 case NAME: \
1025 GenerateArg(Consumer, OPT_analyzer_purge, CMDFLAG); \
1026 break;
1027#include "clang/StaticAnalyzer/Core/Analyses.def"
1028 default:
1029 llvm_unreachable("Tried to generate unknown analysis purge mode.");
1030 }
1031 }
1032
1035#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
1036 case NAME: \
1037 GenerateArg(Consumer, OPT_analyzer_inlining_mode, CMDFLAG); \
1038 break;
1039#include "clang/StaticAnalyzer/Core/Analyses.def"
1040 default:
1041 llvm_unreachable("Tried to generate unknown analysis inlining mode.");
1042 }
1043 }
1044
1046 OptSpecifier Opt =
1047 CP.second ? OPT_analyzer_checker : OPT_analyzer_disable_checker;
1049 }
1050
1053
1054
1056 for (const auto &C : Opts.Config)
1057 SortedConfigOpts.emplace_back(C.getKey(), C.getValue());
1058 llvm::sort(SortedConfigOpts, llvm::less_first());
1059
1060 for (const auto &[Key, Value] : SortedConfigOpts) {
1061
1062
1063 auto Entry = ConfigOpts.Config.find(Key);
1064 if (Entry != ConfigOpts.Config.end() && Entry->getValue() == Value)
1065 continue;
1066
1067 GenerateArg(Consumer, OPT_analyzer_config, Key + "=" + Value);
1068 }
1069
1070
1071}
1072
1075 unsigned NumErrorsBefore = Diags.getNumErrors();
1076
1078
1079#define ANALYZER_OPTION_WITH_MARSHALLING(...) \
1080 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
1081#include "clang/Driver/Options.inc"
1082#undef ANALYZER_OPTION_WITH_MARSHALLING
1083
1084 if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
1085 StringRef Name = A->getValue();
1087#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
1088 .Case(CMDFLAG, NAME##Model)
1089#include "clang/StaticAnalyzer/Core/Analyses.def"
1092 Diags.Report(diag::err_drv_invalid_value)
1093 << A->getAsString(Args) << Name;
1094 } else {
1095#ifndef LLVM_WITH_Z3
1096 if (Value == AnalysisConstraints::Z3ConstraintsModel) {
1097 Diags.Report(diag::err_analyzer_not_built_with_z3);
1098 }
1099#endif
1101 }
1102 }
1103
1104 if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
1105 StringRef Name = A->getValue();
1107#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
1108 .Case(CMDFLAG, PD_##NAME)
1109#include "clang/StaticAnalyzer/Core/Analyses.def"
1112 Diags.Report(diag::err_drv_invalid_value)
1113 << A->getAsString(Args) << Name;
1114 } else {
1116 }
1117 }
1118
1119 if (Arg *A = Args.getLastArg(OPT_analyzer_purge)) {
1120 StringRef Name = A->getValue();
1122#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
1123 .Case(CMDFLAG, NAME)
1124#include "clang/StaticAnalyzer/Core/Analyses.def"
1127 Diags.Report(diag::err_drv_invalid_value)
1128 << A->getAsString(Args) << Name;
1129 } else {
1131 }
1132 }
1133
1134 if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {
1135 StringRef Name = A->getValue();
1137#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
1138 .Case(CMDFLAG, NAME)
1139#include "clang/StaticAnalyzer/Core/Analyses.def"
1142 Diags.Report(diag::err_drv_invalid_value)
1143 << A->getAsString(Args) << Name;
1144 } else {
1146 }
1147 }
1148
1150 for (const Arg *A :
1151 Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {
1152 A->claim();
1153 bool IsEnabled = A->getOption().getID() == OPT_analyzer_checker;
1154
1155
1156 StringRef CheckerAndPackageList = A->getValue();
1158 CheckerAndPackageList.split(CheckersAndPackages, ",");
1159 for (const StringRef &CheckerOrPackage : CheckersAndPackages)
1161 IsEnabled);
1162 }
1163
1164
1165 for (const auto *A : Args.filtered(OPT_analyzer_config)) {
1166
1167
1168
1169 StringRef configList = A->getValue();
1171 configList.split(configVals, ",");
1172 for (const auto &configVal : configVals) {
1173 StringRef key, val;
1174 std::tie(key, val) = configVal.split("=");
1175 if (val.empty()) {
1177 diag::err_analyzer_config_no_value) << configVal;
1178 break;
1179 }
1180 if (val.contains('=')) {
1182 diag::err_analyzer_config_multiple_values)
1183 << configVal;
1184 break;
1185 }
1186
1187
1188
1191 Diags.Report(diag::err_analyzer_config_unknown) << key;
1192 continue;
1193 }
1194
1195 A->claim();
1196 Opts.Config[key] = std::string(val);
1197 }
1198 }
1199
1202 else
1204
1206 for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) {
1207 if (i != 0)
1208 os << " ";
1209 os << Args.getArgString(i);
1210 }
1211
1212 return Diags.getNumErrors() == NumErrorsBefore;
1213}
1214
1216 StringRef OptionName, StringRef DefaultVal) {
1217 return Config.insert({OptionName, std::string(DefaultVal)}).first->second;
1218}
1219
1222 StringRef &OptionField, StringRef Name,
1223 StringRef DefaultVal) {
1224
1225
1226
1227 OptionField = getStringOption(Config, Name, DefaultVal);
1228}
1229
1232 bool &OptionField, StringRef Name, bool DefaultVal) {
1233 auto PossiblyInvalidVal =
1234 llvm::StringSwitch<std::optional>(
1235 getStringOption(Config, Name, (DefaultVal ? "true" : "false")))
1236 .Case("true", true)
1237 .Case("false", false)
1238 .Default(std::nullopt);
1239
1240 if (!PossiblyInvalidVal) {
1241 if (Diags)
1242 Diags->Report(diag::err_analyzer_config_invalid_input)
1243 << Name << "a boolean";
1244 else
1245 OptionField = DefaultVal;
1246 } else
1247 OptionField = *PossiblyInvalidVal;
1248}
1249
1252 unsigned &OptionField, StringRef Name,
1253 unsigned DefaultVal) {
1254
1255 OptionField = DefaultVal;
1256 bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal))
1257 .getAsInteger(0, OptionField);
1258 if (Diags && HasFailed)
1259 Diags->Report(diag::err_analyzer_config_invalid_input)
1260 << Name << "an unsigned";
1261}
1262
1266 unsigned DefaultVal) {
1268 getStringOption(Config, Name, std::to_string(DefaultVal)));
1269 if (Parsed.has_value()) {
1270 OptionField = Parsed.value();
1271 return;
1272 }
1273 if (Diags && !Parsed.has_value())
1274 Diags->Report(diag::err_analyzer_config_invalid_input)
1275 << Name << "a positive";
1276
1277 OptionField = DefaultVal;
1278}
1279
1282
1283
1284
1285#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
1286 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEFAULT_VAL);
1287#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(...)
1288#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1289
1290 assert(AnOpts.UserMode == "shallow" || AnOpts.UserMode == "deep");
1291 const bool InShallowMode = AnOpts.UserMode == "shallow";
1292
1293#define ANALYZER_OPTION(...)
1294#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
1295 SHALLOW_VAL, DEEP_VAL) \
1296 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, \
1297 InShallowMode ? SHALLOW_VAL : DEEP_VAL);
1298#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1299
1300
1301
1302
1303
1304
1305 if (!AnOpts.RawSilencedCheckersAndPackages.empty()) {
1306 std::vector Checkers =
1308 std::vector Packages =
1310
1312 AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages, ";");
1313
1314 for (const StringRef &CheckerOrPackage : CheckersAndPackages) {
1315 if (Diags) {
1316 bool IsChecker = CheckerOrPackage.contains('.');
1317 bool IsValidName = IsChecker
1318 ? llvm::is_contained(Checkers, CheckerOrPackage)
1319 : llvm::is_contained(Packages, CheckerOrPackage);
1320
1321 if (!IsValidName)
1322 Diags->Report(diag::err_unknown_analyzer_checker_or_package)
1323 << CheckerOrPackage;
1324 }
1325
1327 }
1328 }
1329
1330 if (!Diags)
1331 return;
1332
1333 if (AnOpts.ShouldTrackConditionsDebug && !AnOpts.ShouldTrackConditions)
1334 Diags->Report(diag::err_analyzer_config_invalid_input)
1335 << "track-conditions-debug" << "'track-conditions' to also be enabled";
1336
1337 if (!AnOpts.CTUDir.empty() && !llvm::sys::fs::is_directory(AnOpts.CTUDir))
1338 Diags->Report(diag::err_analyzer_config_invalid_input) << "ctu-dir"
1339 << "a filename";
1340
1341 if (!AnOpts.ModelPath.empty() &&
1342 !llvm::sys::fs::is_directory(AnOpts.ModelPath))
1343 Diags->Report(diag::err_analyzer_config_invalid_input) << "model-path"
1344 << "a filename";
1345}
1346
1347
1348static void
1350 StringRef Name,
1352 if (Remark.hasValidPattern()) {
1355 GenerateArg(Consumer, OPT_R_Joined, Name);
1357 GenerateArg(Consumer, OPT_R_Joined, StringRef("no-") + Name);
1358 }
1359}
1360
1361
1362
1363
1366 OptSpecifier OptEQ, StringRef Name) {
1368
1369 auto InitializeResultPattern = [&Diags, &Args, &Result](const Arg *A,
1370 StringRef Pattern) {
1371 Result.Pattern = Pattern.str();
1372
1373 std::string RegexError;
1374 Result.Regex = std::make_sharedllvm::Regex(Result.Pattern);
1375 if (.Regex->isValid(RegexError)) {
1376 Diags.Report(diag::err_drv_optimization_remark_pattern)
1377 << RegexError << A->getAsString(Args);
1378 return false;
1379 }
1380
1381 return true;
1382 };
1383
1384 for (Arg *A : Args) {
1385 if (A->getOption().matches(OPT_R_Joined)) {
1386 StringRef Value = A->getValue();
1387
1388 if (Value == Name)
1390 else if (Value == "everything")
1392 else if (Value.split('-') == std::make_pair(StringRef("no"), Name))
1394 else if (Value == "no-everything")
1396 else
1397 continue;
1398
1401 Result.Pattern = "";
1402 Result.Regex = nullptr;
1403 } else {
1404 InitializeResultPattern(A, ".*");
1405 }
1406 } else if (A->getOption().matches(OptEQ)) {
1408 if (!InitializeResultPattern(A, A->getValue()))
1410 }
1411 }
1412
1414}
1415
1417 const std::vectorstd::string &Levels,
1421 for (const auto &Level : Levels) {
1423 llvm::StringSwitch(Level)
1431 Diags.Report(diag::err_drv_invalid_value) << FlagName << Level;
1432 }
1433 M = M | PM;
1434 }
1436}
1437
1439 const std::vectorstd::string &Sanitizers,
1441 for (const auto &Sanitizer : Sanitizers) {
1444 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1445 else
1446 S.set(K, true);
1447 }
1448}
1449
1453 return Values;
1454}
1455
1458 const std::vectorstd::string &Sanitizers,
1461 for (const auto &Sanitizer : Sanitizers) {
1463 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1464 }
1465 return Cutoffs;
1466}
1467
1472 llvm::SplitString(Bundle, BundleParts, ",");
1473 for (const auto &B : BundleParts) {
1476 if (B != "none")
1477 D.Report(diag::err_drv_invalid_value) << FlagName << Bundle;
1478 else
1479 S.Mask = Mask;
1481 S.Mask = Mask;
1482 else
1483 S.set(Mask, true);
1484 }
1485}
1486
1490 std::string Buffer;
1491 llvm::raw_string_ostream OS(Buffer);
1492 llvm::interleave(BundleParts, OS, [&OS](StringRef Part) { OS << Part; }, ",");
1493 return Buffer;
1494}
1495
1496
1498 const Twine &ProfileName,
1499 llvm::vfs::FileSystem &FS,
1501 auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName, FS);
1502 if (auto E = ReaderOrErr.takeError()) {
1504 "Error in reading profile %0: %1");
1505 llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {
1506 Diags.Report(DiagID) << ProfileName.str() << EI.message();
1507 });
1508 return;
1509 }
1510 std::unique_ptrllvm::IndexedInstrProfReader PGOReader =
1511 std::move(ReaderOrErr.get());
1512
1513
1514
1515 if (PGOReader->isIRLevelProfile() || PGOReader->hasMemoryProfile()) {
1516 if (PGOReader->hasCSIRLevelProfile())
1518 else
1520 } else
1522}
1523
1526 const llvm::Triple &Triple) {
1527 assert(Triple.getArch() == llvm::Triple::aarch64);
1528 if (LangOpts.PointerAuthCalls) {
1531
1533 Key::ASIA, false,
1534 LangOpts.PointerAuthFunctionTypeDiscrimination ? Discrimination::Type
1535 : Discrimination::None);
1536
1538 Key::ASDA, LangOpts.PointerAuthVTPtrAddressDiscrimination,
1539 LangOpts.PointerAuthVTPtrTypeDiscrimination ? Discrimination::Type
1540 : Discrimination::None);
1541
1542 if (LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)
1546 else
1549
1556
1557 if (LangOpts.PointerAuthInitFini) {
1559 Key::ASIA, LangOpts.PointerAuthInitFiniAddressDiscrimination,
1561 }
1562 }
1567}
1568
1571 const llvm::Triple &Triple,
1573 if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthReturns &&
1574 !LangOpts.PointerAuthAuthTraps && !LangOpts.PointerAuthIndirectGotos &&
1575 !LangOpts.AArch64JumpTableHardening)
1576 return;
1577
1579}
1580
1581void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
1583 const llvm::Triple &T,
1584 const std::string &OutputFile,
1587
1588 if (Opts.OptimizationLevel == 0)
1590 else
1591 GenerateArg(Consumer, OPT_O, Twine(Opts.OptimizationLevel));
1592
1593#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1594 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
1595#include "clang/Driver/Options.inc"
1596#undef CODEGEN_OPTION_WITH_MARSHALLING
1597
1598 if (Opts.OptimizationLevel > 0) {
1600 GenerateArg(Consumer, OPT_finline_functions);
1602 GenerateArg(Consumer, OPT_finline_hint_functions);
1605 }
1606
1607 if (Opts.DirectAccessExternalData && LangOpts->PICLevel != 0)
1608 GenerateArg(Consumer, OPT_fdirect_access_external_data);
1609 else if (!Opts.DirectAccessExternalData && LangOpts->PICLevel == 0)
1610 GenerateArg(Consumer, OPT_fno_direct_access_external_data);
1611
1612 std::optional DebugInfoVal;
1613 switch (Opts.DebugInfo) {
1614 case llvm::codegenoptions::DebugLineTablesOnly:
1615 DebugInfoVal = "line-tables-only";
1616 break;
1617 case llvm::codegenoptions::DebugDirectivesOnly:
1618 DebugInfoVal = "line-directives-only";
1619 break;
1620 case llvm::codegenoptions::DebugInfoConstructor:
1621 DebugInfoVal = "constructor";
1622 break;
1623 case llvm::codegenoptions::LimitedDebugInfo:
1624 DebugInfoVal = "limited";
1625 break;
1626 case llvm::codegenoptions::FullDebugInfo:
1627 DebugInfoVal = "standalone";
1628 break;
1629 case llvm::codegenoptions::UnusedTypeInfo:
1630 DebugInfoVal = "unused-types";
1631 break;
1632 case llvm::codegenoptions::NoDebugInfo:
1633 DebugInfoVal = std::nullopt;
1634 break;
1635 case llvm::codegenoptions::LocTrackingOnly:
1636 DebugInfoVal = std::nullopt;
1637 break;
1638 }
1639 if (DebugInfoVal)
1640 GenerateArg(Consumer, OPT_debug_info_kind_EQ, *DebugInfoVal);
1641
1643 GenerateArg(Consumer, OPT_fdebug_prefix_map_EQ,
1644 Prefix.first + "=" + Prefix.second);
1645
1647 GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,
1648 Prefix.first + "=" + Prefix.second);
1649
1650 if (Opts.NewStructPathTBAA)
1651 GenerateArg(Consumer, OPT_new_struct_path_tbaa);
1652
1653 if (Opts.OptimizeSize == 1)
1655 else if (Opts.OptimizeSize == 2)
1657
1658
1659
1660
1661
1662
1663 if (Opts.UnrollLoops && Opts.OptimizationLevel <= 1)
1664 GenerateArg(Consumer, OPT_funroll_loops);
1665 else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1)
1666 GenerateArg(Consumer, OPT_fno_unroll_loops);
1667
1670
1671 if (Opts.DebugNameTable ==
1672 static_cast<unsigned>(llvm::DICompileUnit::DebugNameTableKind::GNU))
1673 GenerateArg(Consumer, OPT_ggnu_pubnames);
1674 else if (Opts.DebugNameTable ==
1675 static_cast<unsigned>(
1676 llvm::DICompileUnit::DebugNameTableKind::Default))
1678
1679 if (Opts.DebugTemplateAlias)
1680 GenerateArg(Consumer, OPT_gtemplate_alias);
1681
1682 auto TNK = Opts.getDebugSimpleTemplateNames();
1683 if (TNK != llvm::codegenoptions::DebugTemplateNamesKind::Full) {
1684 if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Simple)
1685 GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "simple");
1686 else if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Mangled)
1687 GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "mangled");
1688 }
1689
1690
1691
1692 if (Opts.TimePasses) {
1693 if (Opts.TimePassesPerRun)
1694 GenerateArg(Consumer, OPT_ftime_report_EQ, "per-pass-run");
1695 else
1696 GenerateArg(Consumer, OPT_ftime_report);
1697 }
1698
1699 if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)
1700 GenerateArg(Consumer, OPT_flto_EQ, "full");
1701
1702 if (Opts.PrepareForThinLTO)
1703 GenerateArg(Consumer, OPT_flto_EQ, "thin");
1704
1707
1709 GenerateArg(Consumer, OPT_save_temps_EQ, "obj");
1710
1711 StringRef MemProfileBasename("memprof.profraw");
1714 GenerateArg(Consumer, OPT_fmemory_profile);
1715 } else {
1716 size_t ArgLength =
1718 GenerateArg(Consumer, OPT_fmemory_profile_EQ,
1720 }
1721 }
1722
1724 GenerateArg(Consumer, OPT_coverage_version_EQ,
1726
1727
1728
1729
1730
1732 std::string InstrBundle =
1734 if (!InstrBundle.empty())
1735 GenerateArg(Consumer, OPT_fxray_instrumentation_bundle, InstrBundle);
1736 }
1737
1738 if (Opts.CFProtectionReturn && Opts.CFProtectionBranch)
1739 GenerateArg(Consumer, OPT_fcf_protection_EQ, "full");
1740 else if (Opts.CFProtectionReturn)
1741 GenerateArg(Consumer, OPT_fcf_protection_EQ, "return");
1742 else if (Opts.CFProtectionBranch)
1743 GenerateArg(Consumer, OPT_fcf_protection_EQ, "branch");
1744
1745 if (Opts.CFProtectionBranch) {
1746 switch (Opts.getCFBranchLabelScheme()) {
1748 break;
1749#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
1750 case CFBranchLabelSchemeKind::Kind: \
1751 GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, #FlagVal); \
1752 break;
1753#include "clang/Basic/CFProtectionOptions.def"
1754 }
1755 }
1756
1757 if (Opts.FunctionReturnThunks)
1758 GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern");
1759
1761 bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded &&
1762 F.PropagateAttrs && F.Internalize;
1764 Builtint ? OPT_mlink_builtin_bitcode : OPT_mlink_bitcode_file,
1765 F.Filename);
1766 }
1767
1768 if (Opts.EmulatedTLS)
1769 GenerateArg(Consumer, OPT_femulated_tls);
1770
1771 if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE())
1773
1776 GenerateArg(Consumer, OPT_fdenormal_fp_math_f32_EQ,
1778
1780 OptSpecifier Opt =
1781 T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return;
1784 OptSpecifier Opt =
1785 T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return;
1787 }
1788
1789 if (Opts.EnableAIXExtendedAltivecABI)
1790 GenerateArg(Consumer, OPT_mabi_EQ_vec_extabi);
1791
1792 if (Opts.XCOFFReadOnlyPointers)
1793 GenerateArg(Consumer, OPT_mxcoff_roptr);
1794
1797
1800
1803
1806
1809
1810 GenerateArg(Consumer, OPT_fdiagnostics_hotness_threshold_EQ,
1813 : "auto");
1814
1815 GenerateArg(Consumer, OPT_fdiagnostics_misexpect_tolerance_EQ,
1817
1819 GenerateArg(Consumer, OPT_fsanitize_recover_EQ, Sanitizer);
1820
1822 GenerateArg(Consumer, OPT_fsanitize_trap_EQ, Sanitizer);
1823
1824 for (StringRef Sanitizer :
1826 GenerateArg(Consumer, OPT_fsanitize_merge_handlers_EQ, Sanitizer);
1827
1830 for (std::string Sanitizer : Values)
1831 GenerateArg(Consumer, OPT_fsanitize_skip_hot_cutoff_EQ, Sanitizer);
1832
1833 if (!Opts.EmitVersionIdentMetadata)
1835
1836 switch (Opts.FiniteLoops) {
1838 break;
1840 GenerateArg(Consumer, OPT_ffinite_loops);
1841 break;
1843 GenerateArg(Consumer, OPT_fno_finite_loops);
1844 break;
1845 }
1846}
1847
1848bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
1851 const llvm::Triple &T,
1852 const std::string &OutputFile,
1854 unsigned NumErrorsBefore = Diags.getNumErrors();
1855
1857
1858 unsigned MaxOptLevel = 3;
1859 if (OptimizationLevel > MaxOptLevel) {
1860
1861
1862 Diags.Report(diag::warn_drv_optimization_value)
1863 << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
1864 OptimizationLevel = MaxOptLevel;
1865 }
1866 Opts.OptimizationLevel = OptimizationLevel;
1867
1868
1869
1871
1872
1874
1875#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1876 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
1877#include "clang/Driver/Options.inc"
1878#undef CODEGEN_OPTION_WITH_MARSHALLING
1879
1880
1881
1882 if (Opts.OptimizationLevel == 0) {
1884 } else if (const Arg *A = Args.getLastArg(options::OPT_finline_functions,
1885 options::OPT_finline_hint_functions,
1886 options::OPT_fno_inline_functions,
1887 options::OPT_fno_inline)) {
1888
1889
1890 if (A->getOption().matches(options::OPT_finline_functions))
1892 else if (A->getOption().matches(options::OPT_finline_hint_functions))
1894 else
1896 } else {
1898 }
1899
1900
1901
1902 Opts.DirectAccessExternalData =
1903 Args.hasArg(OPT_fdirect_access_external_data) ||
1904 (!Args.hasArg(OPT_fno_direct_access_external_data) &&
1906
1907 if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
1908 unsigned Val =
1909 llvm::StringSwitch(A->getValue())
1910 .Case("line-tables-only", llvm::codegenoptions::DebugLineTablesOnly)
1911 .Case("line-directives-only",
1912 llvm::codegenoptions::DebugDirectivesOnly)
1913 .Case("constructor", llvm::codegenoptions::DebugInfoConstructor)
1914 .Case("limited", llvm::codegenoptions::LimitedDebugInfo)
1915 .Case("standalone", llvm::codegenoptions::FullDebugInfo)
1916 .Case("unused-types", llvm::codegenoptions::UnusedTypeInfo)
1917 .Default(~0U);
1918 if (Val == ~0U)
1919 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1920 << A->getValue();
1921 else
1922 Opts.setDebugInfo(static_castllvm::codegenoptions::DebugInfoKind\(Val));
1923 }
1924
1925
1926
1927 if (const Arg *A =
1928 Args.getLastArg(OPT_fuse_ctor_homing, OPT_fno_use_ctor_homing)) {
1929 if (A->getOption().matches(OPT_fuse_ctor_homing) &&
1930 Opts.getDebugInfo() == llvm::codegenoptions::LimitedDebugInfo)
1931 Opts.setDebugInfo(llvm::codegenoptions::DebugInfoConstructor);
1932 if (A->getOption().matches(OPT_fno_use_ctor_homing) &&
1933 Opts.getDebugInfo() == llvm::codegenoptions::DebugInfoConstructor)
1934 Opts.setDebugInfo(llvm::codegenoptions::LimitedDebugInfo);
1935 }
1936
1937 for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) {
1938 auto Split = StringRef(Arg).split('=');
1940 }
1941
1942 for (const auto &Arg : Args.getAllArgValues(OPT_fcoverage_prefix_map_EQ)) {
1943 auto Split = StringRef(Arg).split('=');
1945 }
1946
1947 const llvm::Triple::ArchType DebugEntryValueArchs[] = {
1948 llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64,
1949 llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips,
1950 llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el};
1951
1953 llvm::is_contained(DebugEntryValueArchs, T.getArch()))
1954 Opts.EmitCallSiteInfo = true;
1955
1957 Diags.Report(diag::warn_ignoring_verify_debuginfo_preserve_export)
1960 }
1961
1962 Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
1963 Args.hasArg(OPT_new_struct_path_tbaa);
1965 Opts.SimplifyLibCalls = ->NoBuiltin;
1966 if (Opts.SimplifyLibCalls)
1968 Opts.UnrollLoops =
1969 Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
1970 (Opts.OptimizationLevel > 1));
1972 std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));
1973
1974 Opts.DebugTemplateAlias = Args.hasArg(OPT_gtemplate_alias);
1975
1976 Opts.DebugNameTable = static_cast<unsigned>(
1977 Args.hasArg(OPT_ggnu_pubnames)
1978 ? llvm::DICompileUnit::DebugNameTableKind::GNU
1979 : Args.hasArg(OPT_gpubnames)
1980 ? llvm::DICompileUnit::DebugNameTableKind::Default
1981 : llvm::DICompileUnit::DebugNameTableKind::None);
1982 if (const Arg *A = Args.getLastArg(OPT_gsimple_template_names_EQ)) {
1983 StringRef Value = A->getValue();
1984 if (Value != "simple" && Value != "mangled")
1985 Diags.Report(diag::err_drv_unsupported_option_argument)
1986 << A->getSpelling() << A->getValue();
1987 Opts.setDebugSimpleTemplateNames(
1988 StringRef(A->getValue()) == "simple"
1989 ? llvm::codegenoptions::DebugTemplateNamesKind::Simple
1990 : llvm::codegenoptions::DebugTemplateNamesKind::Mangled);
1991 }
1992
1993 if (const Arg *A = Args.getLastArg(OPT_ftime_report, OPT_ftime_report_EQ)) {
1994 Opts.TimePasses = true;
1995
1996
1997 if (A->getOption().getID() == OPT_ftime_report_EQ) {
1998 StringRef Val = A->getValue();
1999 if (Val == "per-pass")
2000 Opts.TimePassesPerRun = false;
2001 else if (Val == "per-pass-run")
2002 Opts.TimePassesPerRun = true;
2003 else
2004 Diags.Report(diag::err_drv_invalid_value)
2005 << A->getAsString(Args) << A->getValue();
2006 }
2007 }
2008
2009 Opts.PrepareForLTO = false;
2010 Opts.PrepareForThinLTO = false;
2011 if (Arg *A = Args.getLastArg(OPT_flto_EQ)) {
2012 Opts.PrepareForLTO = true;
2013 StringRef S = A->getValue();
2014 if (S == "thin")
2015 Opts.PrepareForThinLTO = true;
2016 else if (S != "full")
2017 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
2018 if (Args.hasArg(OPT_funified_lto))
2019 Opts.PrepareForThinLTO = true;
2020 }
2021 if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
2023 Diags.Report(diag::err_drv_argument_only_allowed_with)
2024 << A->getAsString(Args) << "-x ir";
2026 std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ));
2027 }
2028 if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))
2030 llvm::StringSwitchstd::string(A->getValue())
2031 .Case("obj", OutputFile)
2032 .Default(llvm::sys::path::filename(OutputFile).str());
2033
2034
2035 const char *MemProfileBasename = "memprof.profraw";
2036 if (Args.hasArg(OPT_fmemory_profile_EQ)) {
2038 std::string(Args.getLastArgValue(OPT_fmemory_profile_EQ)));
2039 llvm::sys::path::append(Path, MemProfileBasename);
2041 } else if (Args.hasArg(OPT_fmemory_profile))
2043
2045 if (Args.hasArg(OPT_coverage_version_EQ)) {
2046 StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
2047 if (CoverageVersion.size() != 4) {
2048 Diags.Report(diag::err_drv_invalid_value)
2049 << Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)
2050 << CoverageVersion;
2051 } else {
2053 }
2054 }
2055 }
2056
2057
2058
2059 for (const auto &A : Args) {
2060
2061 if (A->getOption().getID() == options::OPT_o ||
2062 A->getOption().getID() == options::OPT_INPUT ||
2063 A->getOption().getID() == options::OPT_x ||
2064 A->getOption().getID() == options::OPT_fembed_bitcode ||
2065 A->getOption().matches(options::OPT_W_Group))
2066 continue;
2067 ArgStringList ASL;
2068 A->render(Args, ASL);
2069 for (const auto &arg : ASL) {
2070 StringRef ArgStr(arg);
2071 Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end());
2072
2073 Opts.CmdArgs.push_back('\0');
2074 }
2075 }
2076
2077 auto XRayInstrBundles =
2078 Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
2079 if (XRayInstrBundles.empty())
2081 else
2082 for (const auto &A : XRayInstrBundles)
2085
2086 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
2087 StringRef Name = A->getValue();
2088 if (Name == "full") {
2089 Opts.CFProtectionReturn = 1;
2090 Opts.CFProtectionBranch = 1;
2091 } else if (Name == "return")
2092 Opts.CFProtectionReturn = 1;
2093 else if (Name == "branch")
2094 Opts.CFProtectionBranch = 1;
2095 else if (Name != "none")
2096 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
2097 }
2098
2099 if (Opts.CFProtectionBranch && T.isRISCV()) {
2100 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
2101 const auto Scheme =
2102 llvm::StringSwitch(A->getValue())
2103#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
2104 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
2105#include "clang/Basic/CFProtectionOptions.def"
2108 Opts.setCFBranchLabelScheme(Scheme);
2109 else
2110 Diags.Report(diag::err_drv_invalid_value)
2111 << A->getAsString(Args) << A->getValue();
2112 }
2113 }
2114
2115 if (const Arg *A = Args.getLastArg(OPT_mfunction_return_EQ)) {
2116 auto Val = llvm::StringSwitchllvm::FunctionReturnThunksKind(A->getValue())
2117 .Case("keep", llvm::FunctionReturnThunksKind::Keep)
2118 .Case("thunk-extern", llvm::FunctionReturnThunksKind::Extern)
2119 .Default(llvm::FunctionReturnThunksKind::Invalid);
2120
2121 if (.isX86())
2122 Diags.Report(diag::err_drv_argument_not_allowed_with)
2123 << A->getSpelling() << T.getTriple();
2124 else if (Val == llvm::FunctionReturnThunksKind::Invalid)
2125 Diags.Report(diag::err_drv_invalid_value)
2126 << A->getAsString(Args) << A->getValue();
2127 else if (Val == llvm::FunctionReturnThunksKind::Extern &&
2128 Args.getLastArgValue(OPT_mcmodel_EQ) == "large")
2129 Diags.Report(diag::err_drv_argument_not_allowed_with)
2130 << A->getAsString(Args)
2131 << Args.getLastArg(OPT_mcmodel_EQ)->getAsString(Args);
2132 else
2133 Opts.FunctionReturnThunks = static_cast<unsigned>(Val);
2134 }
2135
2136 for (auto *A :
2137 Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {
2140 if (A->getOption().matches(OPT_mlink_builtin_bitcode)) {
2141 F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;
2142
2143
2146 }
2148 }
2149
2150 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
2151 StringRef Val = A->getValue();
2152 Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);
2155 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2156 }
2157
2158 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_f32_EQ)) {
2159 StringRef Val = A->getValue();
2160 Opts.FP32DenormalMode = llvm::parseDenormalFPAttribute(Val);
2162 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2163 }
2164
2165
2166
2167 if (Arg *A =
2168 Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return,
2169 OPT_maix_struct_return, OPT_msvr4_struct_return)) {
2170
2171
2172 if (T.isOSAIX())
2173 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2174 << A->getSpelling() << T.str();
2175
2176 const Option &O = A->getOption();
2177 if (O.matches(OPT_fpcc_struct_return) ||
2178 O.matches(OPT_maix_struct_return)) {
2180 } else {
2181 assert(O.matches(OPT_freg_struct_return) ||
2182 O.matches(OPT_msvr4_struct_return));
2184 }
2185 }
2186
2187 if (Arg *A = Args.getLastArg(OPT_mxcoff_roptr)) {
2188 if (.isOSAIX())
2189 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2190 << A->getSpelling() << T.str();
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200 if (!Args.hasFlag(OPT_fdata_sections, OPT_fno_data_sections, false))
2201 Diags.Report(diag::err_roptr_requires_data_sections);
2202
2203 Opts.XCOFFReadOnlyPointers = true;
2204 }
2205
2206 if (Arg *A = Args.getLastArg(OPT_mabi_EQ_quadword_atomics)) {
2207 if (.isOSAIX() || T.isPPC32())
2208 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2209 << A->getSpelling() << T.str();
2210 }
2211
2212 bool NeedLocTracking = false;
2213
2215 NeedLocTracking = true;
2216
2217 if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {
2219 NeedLocTracking = true;
2220 }
2221
2222 if (Arg *A = Args.getLastArg(OPT_opt_record_format)) {
2224 NeedLocTracking = true;
2225 }
2226
2229
2232
2234 Diags, Args, OPT_Rpass_analysis_EQ, "pass-analysis");
2235
2239
2241 bool UsingProfile =
2243
2244 if (Opts.DiagnosticsWithHotness && !UsingProfile &&
2245
2247 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2248 << "-fdiagnostics-show-hotness";
2249
2250
2251 if (auto *arg =
2252 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
2253 auto ResultOrErr =
2254 llvm::remarks::parseHotnessThresholdOption(arg->getValue());
2255
2256 if (!ResultOrErr) {
2257 Diags.Report(diag::err_drv_invalid_diagnotics_hotness_threshold)
2258 << "-fdiagnostics-hotness-threshold=";
2259 } else {
2263 !UsingProfile)
2264 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2265 << "-fdiagnostics-hotness-threshold=";
2266 }
2267 }
2268
2269 if (auto *arg =
2270 Args.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ)) {
2272
2273 if (!ResultOrErr) {
2274 Diags.Report(diag::err_drv_invalid_diagnotics_misexpect_tolerance)
2275 << "-fdiagnostics-misexpect-tolerance=";
2276 } else {
2280 !UsingProfile)
2281 Diags.Report(diag::warn_drv_diagnostics_misexpect_requires_pgo)
2282 << "-fdiagnostics-misexpect-tolerance=";
2283 }
2284 }
2285
2286
2287
2288
2289 if (UsingSampleProfile)
2290 NeedLocTracking = true;
2291
2293 NeedLocTracking = true;
2294
2295
2296
2297 if (NeedLocTracking &&
2298 Opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo)
2299 Opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
2300
2301
2302
2304 Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,
2307 Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
2310 Args.getAllArgValues(OPT_fsanitize_merge_handlers_EQ),
2312
2313
2315 "-fsanitize-skip-hot-cutoff=",
2316 Args.getAllArgValues(OPT_fsanitize_skip_hot_cutoff_EQ), Diags);
2317
2318 Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
2319
2320 if (->CUDAIsDevice)
2322
2323 if (Args.hasArg(options::OPT_ffinite_loops))
2325 else if (Args.hasArg(options::OPT_fno_finite_loops))
2327
2328 Opts.EmitIEEENaNCompliantInsts = Args.hasFlag(
2329 options::OPT_mamdgpu_ieee, options::OPT_mno_amdgpu_ieee, true);
2330 if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs)
2331 Diags.Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans);
2332
2333 return Diags.getNumErrors() == NumErrorsBefore;
2334}
2335
2339#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2340 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2341#include "clang/Driver/Options.inc"
2342#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2343
2345 GenerateArg(Consumer, OPT_show_includes);
2346
2347 for (const auto &Dep : Opts.ExtraDeps) {
2348 switch (Dep.second) {
2350
2351 continue;
2353
2354
2355 continue;
2357
2358
2359 continue;
2361 GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first);
2362 break;
2363 }
2364 }
2365}
2366
2370 bool ShowLineMarkers) {
2371 unsigned NumErrorsBefore = Diags.getNumErrors();
2372
2374#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2375 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2376#include "clang/Driver/Options.inc"
2377#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2378
2379 if (Args.hasArg(OPT_show_includes)) {
2380
2381
2382
2385 else
2387 } else {
2389 }
2390
2391
2392
2393
2394 if (!Args.hasArg(OPT_fno_sanitize_ignorelist)) {
2395 for (const auto *A : Args.filtered(OPT_fsanitize_ignorelist_EQ)) {
2396 StringRef Val = A->getValue();
2397 if (!Val.contains('='))
2399 }
2401 for (const auto *A : Args.filtered(OPT_fsanitize_system_ignorelist_EQ)) {
2402 StringRef Val = A->getValue();
2403 if (!Val.contains('='))
2405 }
2406 }
2407 }
2408
2409
2410 for (const auto &Filename : Args.getAllArgValues(OPT_fprofile_list_EQ))
2412
2413
2414 for (const auto *A : Args.filtered(OPT_fdepfile_entry))
2416
2417
2418 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
2419 StringRef Val = A->getValue();
2420 if (!Val.contains('='))
2422 }
2423
2424
2425
2430 Diags.Report(diag::err_drv_print_header_env_var_combination_cc1)
2431 << Args.getLastArg(OPT_header_include_format_EQ)->getValue()
2432 << Args.getLastArg(OPT_header_include_filtering_EQ)->getValue();
2433
2434 return Diags.getNumErrors() == NumErrorsBefore;
2435}
2436
2438
2439
2440
2441
2442 enum {
2443 Colors_On,
2444 Colors_Off,
2445 Colors_Auto
2446 } ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
2447 for (auto *A : Args) {
2448 const Option &O = A->getOption();
2449 if (O.matches(options::OPT_fcolor_diagnostics)) {
2451 } else if (O.matches(options::OPT_fno_color_diagnostics)) {
2453 } else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
2454 StringRef Value(A->getValue());
2455 if (Value == "always")
2457 else if (Value == "never")
2459 else if (Value == "auto")
2461 }
2462 }
2465 llvm::sys::Process::StandardErrHasColors());
2466}
2467
2471 for (const auto &Prefix : VerifyPrefixes) {
2472
2473
2474 auto BadChar = llvm::find_if(Prefix, [](char C) {
2476 });
2477 if (BadChar != Prefix.end() || (Prefix[0])) {
2479 Diags.Report(diag::err_drv_invalid_value) << "-verify=" << Prefix;
2480 Diags.Report(diag::note_drv_verify_prefix_spelling);
2481 }
2482 }
2484}
2485
2489
2490#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2491 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2492#include "clang/Driver/Options.inc"
2493#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2494}
2495
2498 unsigned NumErrorsBefore = Diags.getNumErrors();
2499
2501
2502#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2503 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2504#include "clang/Driver/Options.inc"
2505#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2506
2507 return Diags.getNumErrors() == NumErrorsBefore;
2508}
2509
2513#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2514 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2515#include "clang/Driver/Options.inc"
2516#undef MIGRATOR_OPTION_WITH_MARSHALLING
2517}
2518
2521 unsigned NumErrorsBefore = Diags.getNumErrors();
2522
2524
2525#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2526 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2527#include "clang/Driver/Options.inc"
2528#undef MIGRATOR_OPTION_WITH_MARSHALLING
2529
2530 return Diags.getNumErrors() == NumErrorsBefore;
2531}
2532
2533void CompilerInvocationBase::GenerateDiagnosticArgs(
2535 bool DefaultDiagColor) {
2537#define DIAG_OPTION_WITH_MARSHALLING(...) \
2538 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2539#include "clang/Driver/Options.inc"
2540#undef DIAG_OPTION_WITH_MARSHALLING
2541
2543 GenerateArg(Consumer, OPT_diagnostic_serialized_file,
2545
2546 if (Opts.ShowColors)
2547 GenerateArg(Consumer, OPT_fcolor_diagnostics);
2548
2549 if (Opts.VerifyDiagnostics &&
2550 llvm::is_contained(Opts.VerifyPrefixes, "expected"))
2552
2554 if (Prefix != "expected")
2555 GenerateArg(Consumer, OPT_verify_EQ, Prefix);
2556
2559
2561 GenerateArg(Consumer, OPT_verify_ignore_unexpected);
2562 } else {
2564 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "note");
2566 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "remark");
2568 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "warning");
2570 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "error");
2571 }
2572
2574
2575 if (Warning == "undef-prefix")
2576 continue;
2577
2578 if (Warning == "invalid-constexpr" || Warning == "no-invalid-constexpr")
2579 continue;
2580 Consumer(StringRef("-W") + Warning);
2581 }
2582
2584
2585
2586 StringRef IgnoredRemarks[] = {"pass", "no-pass",
2587 "pass-analysis", "no-pass-analysis",
2588 "pass-missed", "no-pass-missed"};
2589 if (llvm::is_contained(IgnoredRemarks, Remark))
2590 continue;
2591
2592 Consumer(StringRef("-R") + Remark);
2593 }
2594
2596 GenerateArg(Consumer, OPT_warning_suppression_mappings_EQ,
2598 }
2599}
2600
2601std::unique_ptr
2603 auto DiagOpts = std::make_unique();
2604 unsigned MissingArgIndex, MissingArgCount;
2606 Argv.slice(1), MissingArgIndex, MissingArgCount);
2607
2609 if (std::optionalstd::string NoColor =
2610 llvm::sys::Process::GetEnv("NO_COLOR");
2611 NoColor && !NoColor->empty()) {
2612
2613
2615 }
2616
2617
2618
2619
2621 return DiagOpts;
2622}
2623
2626 bool DefaultDiagColor) {
2627 std::optional IgnoringDiags;
2628 if (!Diags) {
2631 Diags = &*IgnoringDiags;
2632 }
2633
2634 unsigned NumErrorsBefore = Diags->getNumErrors();
2635
2636
2637
2639
2640#define DIAG_OPTION_WITH_MARSHALLING(...) \
2641 PARSE_OPTION_WITH_MARSHALLING(Args, *Diags, __VA_ARGS__)
2642#include "clang/Driver/Options.inc"
2643#undef DIAG_OPTION_WITH_MARSHALLING
2644
2645 llvm::sys::Process::UseANSIEscapeCodes(Opts.UseANSIEscapeCodes);
2646
2647 if (Arg *A =
2648 Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))
2651
2652 Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ);
2653 Opts.VerifyPrefixes = Args.getAllArgValues(OPT_verify_EQ);
2654 if (Args.hasArg(OPT_verify))
2656
2657
2659 Opts.VerifyDiagnostics = false;
2660 else
2664 "-verify-ignore-unexpected=",
2665 Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), *Diags, DiagMask);
2666 if (Args.hasArg(OPT_verify_ignore_unexpected))
2668 Opts.setVerifyIgnoreUnexpected(DiagMask);
2670 Diags->Report(diag::warn_ignoring_ftabstop_value)
2673 }
2674
2675 if (const Arg *A = Args.getLastArg(OPT_warning_suppression_mappings_EQ))
2677
2680
2681 return Diags->getNumErrors() == NumErrorsBefore;
2682}
2683
2684
2685
2686
2687
2689 std::string &BlockName,
2690 unsigned &MajorVersion,
2691 unsigned &MinorVersion,
2692 bool &Hashed,
2693 std::string &UserInfo) {
2695 Arg.split(Args, ':', 5);
2696 if (Args.size() < 5)
2697 return true;
2698
2699 BlockName = std::string(Args[0]);
2700 if (Args[1].getAsInteger(10, MajorVersion)) return true;
2701 if (Args[2].getAsInteger(10, MinorVersion)) return true;
2702 if (Args[3].getAsInteger(2, Hashed)) return true;
2703 if (Args.size() > 4)
2704 UserInfo = std::string(Args[4]);
2705 return false;
2706}
2707
2708
2709
2710
2711
2713 static const std::pair<frontend::ActionKind, unsigned> Table[] = {
2715
2722
2737
2740
2744 OPT_emit_reduced_module_interface},
2762 OPT_print_dependency_directives_minimized_source},
2763 };
2764
2765 return Table;
2766}
2767
2768
2769static std::optionalfrontend::ActionKind
2772 if (ActionOpt.second == Opt.getID())
2773 return ActionOpt.first;
2774
2775 return std::nullopt;
2776}
2777
2778
2779static std::optional
2782 if (ActionOpt.first == ProgramAction)
2783 return OptSpecifier(ActionOpt.second);
2784
2785 return std::nullopt;
2786}
2787
2791#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2792 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2793#include "clang/Driver/Options.inc"
2794#undef FRONTEND_OPTION_WITH_MARSHALLING
2795
2796 std::optional ProgramActionOpt =
2798
2799
2800 std::function<void()> GenerateProgramAction = [&]() {
2801 GenerateArg(Consumer, *ProgramActionOpt);
2802 };
2803
2804 if (!ProgramActionOpt) {
2805
2807 "Frontend action without option.");
2808 GenerateProgramAction = [&]() {
2810 };
2811 }
2812
2813
2815 GenerateProgramAction = [&]() {
2816
2817
2818
2820 StringRef Format;
2823 llvm_unreachable("Default AST dump format.");
2825 Format = "json";
2826 break;
2827 }
2828
2830 GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);
2832 GenerateArg(Consumer, OPT_ast_dump_EQ, Format);
2833 } else {
2835 GenerateArg(Consumer, OPT_ast_dump_all);
2838 }
2839 };
2840 }
2841
2843 GenerateProgramAction = [&]() {
2845 };
2846 }
2847
2848 GenerateProgramAction();
2849
2850 for (const auto &PluginArgs : Opts.PluginArgs) {
2852 for (const auto &PluginArg : PluginArgs.second)
2854 Opt.getPrefix() + Opt.getName() + PluginArgs.first,
2855 Opt.getKind(), 0, PluginArg);
2856 }
2857
2859 if (auto *TestExt = dyn_cast_or_null(Ext.get()))
2860 GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());
2861
2863 GenerateArg(Consumer, OPT_code_completion_at,
2865
2866 for (const auto &Plugin : Opts.Plugins)
2867 GenerateArg(Consumer, OPT_load, Plugin);
2868
2869
2870
2871 for (const auto &ModuleFile : Opts.ModuleFiles)
2872 GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);
2873
2876
2879 GenerateArg(Consumer, OPT_aux_target_feature, Feature);
2880
2881 {
2882 StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";
2885 StringRef HeaderUnit = "";
2888 break;
2890 HeaderUnit = "-user";
2891 break;
2893 HeaderUnit = "-system";
2894 break;
2896 HeaderUnit = "-header-unit";
2897 break;
2898 }
2899 StringRef Header = IsHeader ? "-header" : "";
2900
2901 StringRef Lang;
2904 Lang = "c";
2905 break;
2907 Lang = "cl";
2908 break;
2910 Lang = "clcpp";
2911 break;
2913 Lang = "cuda";
2914 break;
2916 Lang = "hip";
2917 break;
2919 Lang = "c++";
2920 break;
2922 Lang = "objective-c";
2923 break;
2925 Lang = "objective-c++";
2926 break;
2928 Lang = "assembler-with-cpp";
2929 break;
2932 "Generating -x argument for unknown language (not precompiled).");
2933 Lang = "ast";
2934 break;
2936 Lang = "ir";
2937 break;
2939 Lang = "hlsl";
2940 break;
2942 Lang = "cir";
2943 break;
2944 }
2945
2947 Lang + HeaderUnit + Header + ModuleMap + Preprocessed);
2948 }
2949
2950
2951 for (const auto &Input : Opts.Inputs)
2952 Consumer(Input.getFile());
2953}
2954
2957 unsigned NumErrorsBefore = Diags.getNumErrors();
2958
2960
2961#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2962 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2963#include "clang/Driver/Options.inc"
2964#undef FRONTEND_OPTION_WITH_MARSHALLING
2965
2967 if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
2968 OptSpecifier Opt = OptSpecifier(A->getOption().getID());
2969 std::optionalfrontend::ActionKind ProgramAction = getFrontendAction(Opt);
2970 assert(ProgramAction && "Option specifier not in Action_Group.");
2971
2973 (Opt == OPT_ast_dump_all_EQ || Opt == OPT_ast_dump_EQ)) {
2974 unsigned Val = llvm::StringSwitch(A->getValue())
2977 .Default(std::numeric_limits::max());
2978
2979 if (Val != std::numeric_limits::max())
2981 else {
2982 Diags.Report(diag::err_drv_invalid_value)
2983 << A->getAsString(Args) << A->getValue();
2985 }
2986 }
2987
2988 if (ProgramAction == frontend::FixIt && Opt == OPT_fixit_EQ)
2990
2992 StringRef ArgStr =
2993 Args.hasArg(OPT_interface_stub_version_EQ)
2994 ? Args.getLastArgValue(OPT_interface_stub_version_EQ)
2995 : "ifs-v1";
2996 if (ArgStr == "experimental-yaml-elf-v1" ||
2997 ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-ifs-v2" ||
2998 ArgStr == "experimental-tapi-elf-v1") {
2999 std::string ErrorMessage =
3000 "Invalid interface stub format: " + ArgStr.str() +
3001 " is deprecated.";
3002 Diags.Report(diag::err_drv_invalid_value)
3003 << "Must specify a valid interface stub format type, ie: "
3004 "-interface-stub-version=ifs-v1"
3005 << ErrorMessage;
3007 } else if (!ArgStr.starts_with("ifs-")) {
3008 std::string ErrorMessage =
3009 "Invalid interface stub format: " + ArgStr.str() + ".";
3010 Diags.Report(diag::err_drv_invalid_value)
3011 << "Must specify a valid interface stub format type, ie: "
3012 "-interface-stub-version=ifs-v1"
3013 << ErrorMessage;
3015 }
3016 }
3017
3019
3020
3021
3022
3023
3024
3025
3026
3027 if (!A->getSpelling().starts_with("-ast-dump")) {
3028 const Arg *SavedAction = nullptr;
3029 for (const Arg *AA :
3030 Args.filtered(OPT_Action_Group, OPT_main_file_name)) {
3031 if (AA->getOption().matches(OPT_main_file_name)) {
3032 SavedAction = nullptr;
3033 } else if (!SavedAction) {
3034 SavedAction = AA;
3035 } else {
3036 if (!A->getOption().matches(OPT_ast_dump_EQ))
3037 Diags.Report(diag::err_fe_invalid_multiple_actions)
3038 << SavedAction->getSpelling() << A->getSpelling();
3039 break;
3040 }
3041 }
3042 }
3043 }
3044
3045 if (const Arg* A = Args.getLastArg(OPT_plugin)) {
3046 Opts.Plugins.emplace_back(A->getValue(0));
3049 }
3050 for (const auto *AA : Args.filtered(OPT_plugin_arg))
3051 Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
3052
3053 for (const std::string &Arg :
3054 Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
3055 std::string BlockName;
3056 unsigned MajorVersion;
3057 unsigned MinorVersion;
3058 bool Hashed;
3059 std::string UserInfo;
3061 MinorVersion, Hashed, UserInfo)) {
3062 Diags.Report(diag::err_test_module_file_extension_format) << Arg;
3063
3064 continue;
3065 }
3066
3067
3069 std::make_shared(
3070 BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
3071 }
3072
3073 if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
3077 Diags.Report(diag::err_drv_invalid_value)
3078 << A->getAsString(Args) << A->getValue();
3079 }
3080
3081 Opts.Plugins = Args.getAllArgValues(OPT_load);
3082 Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);
3083 Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);
3084
3085 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3086 StringRef Val = A->getValue();
3087 if (!Val.contains('='))
3088 Opts.ModuleFiles.push_back(std::string(Val));
3089 }
3090
3092 Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"
3093 << "-emit-module";
3094 if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_cir))
3096
3097 if (Args.hasArg(OPT_aux_target_cpu))
3098 Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu));
3099 if (Args.hasArg(OPT_aux_target_feature))
3100 Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature);
3101
3104 Diags.Report(diag::err_drv_argument_not_allowed_with)
3105 << "ARC migration" << "ObjC migration";
3106 }
3107
3109 if (const Arg *A = Args.getLastArg(OPT_x)) {
3110 StringRef XValue = A->getValue();
3111
3112
3113
3114
3115 bool Preprocessed = XValue.consume_back("-cpp-output");
3116 bool ModuleMap = XValue.consume_back("-module-map");
3117
3118 bool IsHeader =
3119 XValue != "precompiled-header" && XValue.consume_back("-header");
3120
3121
3122
3123
3125 if (IsHeader || Preprocessed) {
3126 if (XValue.consume_back("-header-unit"))
3128 else if (XValue.consume_back("-system"))
3130 else if (XValue.consume_back("-user"))
3132 }
3133
3134
3135
3136 IsHeaderFile = IsHeader && !Preprocessed && &&
3138
3139
3140 DashX = llvm::StringSwitch(XValue)
3151
3152
3153
3154 if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && &&
3156 DashX = llvm::StringSwitch(XValue)
3160
3161
3162 if (DashX.isUnknown() && !Preprocessed && !IsHeaderFile && &&
3164 DashX = llvm::StringSwitch(XValue)
3167 .Cases("ast", "pcm", "precompiled-header",
3172
3174 Diags.Report(diag::err_drv_invalid_value)
3175 << A->getAsString(Args) << A->getValue();
3176
3177 if (Preprocessed)
3179
3182 IsHeaderFile = true;
3183 } else if (IsHeaderFile)
3187 }
3188
3189
3190 std::vectorstd::string Inputs = Args.getAllArgValues(OPT_INPUT);
3191 Opts.Inputs.clear();
3192 if (Inputs.empty())
3193 Inputs.push_back("-");
3194
3196 Inputs.size() > 1)
3197 Diags.Report(diag::err_drv_header_unit_extra_inputs) << Inputs[1];
3198
3199 for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
3203 StringRef(Inputs[i]).rsplit('.').second);
3204
3207
3208 if (i == 0)
3209 DashX = IK;
3210 }
3211
3212 bool IsSystem = false;
3213
3214
3219 }
3220
3221 Opts.Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem);
3222 }
3223
3224 Opts.DashX = DashX;
3225
3226 return Diags.getNumErrors() == NumErrorsBefore;
3227}
3228
3230 void *MainAddr) {
3231 std::string ClangExecutable =
3232 llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
3234}
3235
3239#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3240 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3241#include "clang/Driver/Options.inc"
3242#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3243
3245 GenerateArg(Consumer, OPT_stdlib_EQ, "libc++");
3246
3249
3251 GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second);
3252
3255
3257 GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val());
3258
3261 std::optional IsFramework,
3262 std::optional IgnoreSysRoot) {
3263 return llvm::is_contained(Groups, Entry.Group) &&
3264 (!IsFramework || (Entry.IsFramework == *IsFramework)) &&
3265 (!IgnoreSysRoot || (Entry.IgnoreSysRoot == *IgnoreSysRoot));
3266 };
3267
3270
3271
3272 for (; It < End && Matches(*It, {frontend::Angled}, std::nullopt, true);
3273 ++It) {
3274 OptSpecifier Opt = [It, Matches]() {
3276 return OPT_F;
3278 return OPT_I;
3279 llvm_unreachable("Unexpected HeaderSearchOptions::Entry.");
3280 }();
3281
3283 }
3284
3285
3286
3287
3288
3289 for (; It < End &&
3291 ++It) {
3292 OptSpecifier Opt =
3293 It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;
3295 }
3296
3297
3298
3299
3300 for (; It < End && Matches(*It, {frontend::After}, false, true); ++It)
3301 GenerateArg(Consumer, OPT_idirafter, It->Path);
3302 for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It)
3303 GenerateArg(Consumer, OPT_iquote, It->Path);
3304 for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt);
3305 ++It)
3306 GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
3307 It->Path);
3308 for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
3309 GenerateArg(Consumer, OPT_iframework, It->Path);
3310 for (; It < End && Matches(*It, {frontend::System}, true, false); ++It)
3311 GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path);
3312
3313
3314 for (; It < End && Matches(*It, {frontend::CSystem}, false, true); ++It)
3315 GenerateArg(Consumer, OPT_c_isystem, It->Path);
3316 for (; It < End && Matches(*It, {frontend::CXXSystem}, false, true); ++It)
3317 GenerateArg(Consumer, OPT_cxx_isystem, It->Path);
3319 GenerateArg(Consumer, OPT_objc_isystem, It->Path);
3321 GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);
3322
3323
3324
3325
3326
3327 for (; It < End &&
3329 ++It) {
3331 ? OPT_internal_isystem
3332 : OPT_internal_externc_isystem;
3334 }
3335
3336 assert(It == End && "Unhandled HeaderSearchOption::Entry.");
3337
3338
3340 OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
3341 : OPT_no_system_header_prefix;
3343 }
3344
3346 GenerateArg(Consumer, OPT_ivfsoverlay, F);
3347}
3348
3351 const std::string &WorkingDir) {
3352 unsigned NumErrorsBefore = Diags.getNumErrors();
3353
3355
3356#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3357 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3358#include "clang/Driver/Options.inc"
3359#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3360
3361 if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
3362 Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
3363
3364
3365 SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path));
3366 if (!(P.empty() || llvm::sys::path::is_absolute(P))) {
3367 if (WorkingDir.empty())
3368 llvm::sys::fs::make_absolute(P);
3369 else
3370 llvm::sys::fs::make_absolute(WorkingDir, P);
3371 }
3372 llvm::sys::path::remove_dots(P);
3374
3375
3376 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3377 StringRef Val = A->getValue();
3378 if (Val.contains('=')) {
3379 auto Split = Val.split('=');
3381 std::string(Split.first), std::string(Split.second));
3382 }
3383 }
3384 for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
3386
3387 for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
3388 StringRef MacroDef = A->getValue();
3390 llvm::CachedHashString(MacroDef.split('=').first));
3391 }
3392
3393
3394 bool IsSysrootSpecified =
3395 Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
3396
3397
3398
3399 auto PrefixHeaderPath = [IsSysrootSpecified,
3400 &Opts](const llvm::opt::Arg *A,
3401 bool IsFramework = false) -> std::string {
3402 assert(A->getNumValues() && "Unexpected empty search path flag!");
3403 if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') {
3405 llvm::sys::path::append(Buffer, Opts.Sysroot,
3406 llvm::StringRef(A->getValue()).substr(1));
3407 return std::string(Buffer);
3408 }
3409 return A->getValue();
3410 };
3411
3412 for (const auto *A : Args.filtered(OPT_I, OPT_F)) {
3413 bool IsFramework = A->getOption().matches(OPT_F);
3415 IsFramework, true);
3416 }
3417
3418
3419 StringRef Prefix = "";
3420 for (const auto *A :
3421 Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
3422 if (A->getOption().matches(OPT_iprefix))
3423 Prefix = A->getValue();
3424 else if (A->getOption().matches(OPT_iwithprefix))
3426 else
3428 }
3429
3430 for (const auto *A : Args.filtered(OPT_idirafter))
3432 for (const auto *A : Args.filtered(OPT_iquote))
3434
3435 for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) {
3436 if (A->getOption().matches(OPT_iwithsysroot)) {
3438 false);
3439 continue;
3440 }
3442 }
3443 for (const auto *A : Args.filtered(OPT_iframework))
3445 for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
3447 false);
3448
3449
3450 for (const auto *A : Args.filtered(OPT_c_isystem))
3452 for (const auto *A : Args.filtered(OPT_cxx_isystem))
3454 for (const auto *A : Args.filtered(OPT_objc_isystem))
3456 for (const auto *A : Args.filtered(OPT_objcxx_isystem))
3458
3459
3460 for (const auto *A :
3461 Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
3463 if (A->getOption().matches(OPT_internal_externc_isystem))
3465 Opts.AddPath(A->getValue(), Group, false, true);
3466 }
3467
3468
3469 for (const auto *A :
3470 Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
3472 A->getValue(), A->getOption().matches(OPT_system_header_prefix));
3473
3474 for (const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))
3476
3477 return Diags.getNumErrors() == NumErrorsBefore;
3478}
3479
3483 GenerateArg(Consumer, OPT_fapinotes_swift_version,
3485
3488}
3489
3492 if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
3493 if (Opts.SwiftVersion.tryParse(A->getValue()))
3494 diags.Report(diag::err_drv_invalid_value)
3495 << A->getAsString(Args) << A->getValue();
3496 }
3497 for (const Arg *A : Args.filtered(OPT_iapinotes_modules))
3499}
3500
3503 if (Opts.PointerAuthIntrinsics)
3504 GenerateArg(Consumer, OPT_fptrauth_intrinsics);
3505 if (Opts.PointerAuthCalls)
3506 GenerateArg(Consumer, OPT_fptrauth_calls);
3507 if (Opts.PointerAuthReturns)
3508 GenerateArg(Consumer, OPT_fptrauth_returns);
3509 if (Opts.PointerAuthIndirectGotos)
3510 GenerateArg(Consumer, OPT_fptrauth_indirect_gotos);
3511 if (Opts.PointerAuthAuthTraps)
3512 GenerateArg(Consumer, OPT_fptrauth_auth_traps);
3513 if (Opts.PointerAuthVTPtrAddressDiscrimination)
3514 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
3515 if (Opts.PointerAuthVTPtrTypeDiscrimination)
3516 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
3517 if (Opts.PointerAuthTypeInfoVTPtrDiscrimination)
3518 GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination);
3519 if (Opts.PointerAuthFunctionTypeDiscrimination)
3520 GenerateArg(Consumer, OPT_fptrauth_function_pointer_type_discrimination);
3521 if (Opts.PointerAuthInitFini)
3522 GenerateArg(Consumer, OPT_fptrauth_init_fini);
3523 if (Opts.PointerAuthInitFiniAddressDiscrimination)
3524 GenerateArg(Consumer, OPT_fptrauth_init_fini_address_discrimination);
3525 if (Opts.PointerAuthELFGOT)
3526 GenerateArg(Consumer, OPT_fptrauth_elf_got);
3527 if (Opts.AArch64JumpTableHardening)
3528 GenerateArg(Consumer, OPT_faarch64_jump_table_hardening);
3529}
3530
3533 Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
3534 Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
3535 Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
3536 Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
3537 Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
3538 Opts.PointerAuthVTPtrAddressDiscrimination =
3539 Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
3540 Opts.PointerAuthVTPtrTypeDiscrimination =
3541 Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
3542 Opts.PointerAuthTypeInfoVTPtrDiscrimination =
3543 Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination);
3544 Opts.PointerAuthFunctionTypeDiscrimination =
3545 Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination);
3546 Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
3547 Opts.PointerAuthInitFiniAddressDiscrimination =
3548 Args.hasArg(OPT_fptrauth_init_fini_address_discrimination);
3549 Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got);
3550 Opts.AArch64JumpTableHardening =
3551 Args.hasArg(OPT_faarch64_jump_table_hardening);
3552}
3553
3554
3561 llvm_unreachable("should not parse language flags for this input");
3562
3566
3570
3573
3577
3579
3582
3585
3587
3588
3589
3590 return true;
3591
3594 }
3595
3596 llvm_unreachable("unexpected input language");
3597}
3598
3599
3603 return "C";
3605 return "Objective-C";
3607 return "C++";
3609 return "Objective-C++";
3611 return "OpenCL";
3613 return "C++ for OpenCL";
3615 return "CUDA";
3617 return "HIP";
3618
3620 return "Asm";
3622 return "LLVM IR";
3624 return "Clang IR";
3625
3627 return "HLSL";
3628
3630 break;
3631 }
3632 llvm_unreachable("unknown input language");
3633}
3634
3635void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
3637 const llvm::Triple &T,
3642 if (Opts.ObjCAutoRefCount)
3644 if (Opts.PICLevel != 0)
3645 GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));
3646 if (Opts.PIE)
3649 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3650
3651 return;
3652 }
3653
3654 OptSpecifier StdOpt;
3656 case LangStandard::lang_opencl10:
3657 case LangStandard::lang_opencl11:
3658 case LangStandard::lang_opencl12:
3659 case LangStandard::lang_opencl20:
3660 case LangStandard::lang_opencl30:
3661 case LangStandard::lang_openclcpp10:
3662 case LangStandard::lang_openclcpp2021:
3663 StdOpt = OPT_cl_std_EQ;
3664 break;
3665 default:
3666 StdOpt = OPT_std_EQ;
3667 break;
3668 }
3669
3672
3673 if (Opts.IncludeDefaultHeader)
3674 GenerateArg(Consumer, OPT_finclude_default_header);
3675 if (Opts.DeclareOpenCLBuiltins)
3676 GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);
3677
3679
3680#define LANG_OPTION_WITH_MARSHALLING(...) \
3681 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3682#include "clang/Driver/Options.inc"
3683#undef LANG_OPTION_WITH_MARSHALLING
3684
3685
3686
3687 if (Opts.ObjC) {
3689
3691 GenerateArg(Consumer, OPT_fobjc_gc_only);
3694 else if (Opts.ObjCAutoRefCount == 1)
3696
3697 if (Opts.ObjCWeakRuntime)
3698 GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);
3699
3700 if (Opts.ObjCWeak)
3702
3703 if (Opts.ObjCSubscriptingLegacyRuntime)
3704 GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime);
3705 }
3706
3707 if (Opts.GNUCVersion != 0) {
3708 unsigned Major = Opts.GNUCVersion / 100 / 100;
3709 unsigned Minor = (Opts.GNUCVersion / 100) % 100;
3710 unsigned Patch = Opts.GNUCVersion % 100;
3711 GenerateArg(Consumer, OPT_fgnuc_version_EQ,
3712 Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch));
3713 }
3714
3715 if (Opts.IgnoreXCOFFVisibility)
3716 GenerateArg(Consumer, OPT_mignore_xcoff_visibility);
3717
3723 }
3724
3725 if (Opts.MSCompatibilityVersion != 0) {
3726 unsigned Major = Opts.MSCompatibilityVersion / 10000000;
3727 unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;
3728 unsigned Subminor = Opts.MSCompatibilityVersion % 100000;
3729 GenerateArg(Consumer, OPT_fms_compatibility_version,
3730 Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor));
3731 }
3732
3733 if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
3734 T.isOSzOS()) {
3735 if (!Opts.Trigraphs)
3736 GenerateArg(Consumer, OPT_fno_trigraphs);
3737 } else {
3738 if (Opts.Trigraphs)
3740 }
3741
3742 if (T.isOSzOS() && !Opts.ZOSExt)
3743 GenerateArg(Consumer, OPT_fno_zos_extensions);
3744 else if (Opts.ZOSExt)
3745 GenerateArg(Consumer, OPT_fzos_extensions);
3746
3747 if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
3749
3750 if (Opts.ConvergentFunctions)
3751 GenerateArg(Consumer, OPT_fconvergent_functions);
3752 else
3753 GenerateArg(Consumer, OPT_fno_convergent_functions);
3754
3755 if (Opts.NoBuiltin && !Opts.Freestanding)
3757
3758 if (!Opts.NoBuiltin)
3761
3762 if (Opts.LongDoubleSize == 128)
3763 GenerateArg(Consumer, OPT_mlong_double_128);
3764 else if (Opts.LongDoubleSize == 64)
3765 GenerateArg(Consumer, OPT_mlong_double_64);
3766 else if (Opts.LongDoubleSize == 80)
3767 GenerateArg(Consumer, OPT_mlong_double_80);
3768
3769
3770
3771
3772
3773 if (Opts.OpenMP && !Opts.OpenMPSimd) {
3775
3776 if (Opts.OpenMP != 51)
3777 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3778
3779 if (!Opts.OpenMPUseTLS)
3780 GenerateArg(Consumer, OPT_fnoopenmp_use_tls);
3781
3782 if (Opts.OpenMPIsTargetDevice)
3783 GenerateArg(Consumer, OPT_fopenmp_is_target_device);
3784
3785 if (Opts.OpenMPIRBuilder)
3786 GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder);
3787 }
3788
3789 if (Opts.OpenMPSimd) {
3790 GenerateArg(Consumer, OPT_fopenmp_simd);
3791
3792 if (Opts.OpenMP != 51)
3793 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3794 }
3795
3796 if (Opts.OpenMPThreadSubscription)
3797 GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription);
3798
3799 if (Opts.OpenMPTeamSubscription)
3800 GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription);
3801
3802 if (Opts.OpenMPTargetDebug != 0)
3803 GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ,
3804 Twine(Opts.OpenMPTargetDebug));
3805
3806 if (Opts.OpenMPCUDANumSMs != 0)
3807 GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ,
3808 Twine(Opts.OpenMPCUDANumSMs));
3809
3810 if (Opts.OpenMPCUDABlocksPerSM != 0)
3811 GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ,
3812 Twine(Opts.OpenMPCUDABlocksPerSM));
3813
3814 if (Opts.OpenMPCUDAReductionBufNum != 1024)
3815 GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
3816 Twine(Opts.OpenMPCUDAReductionBufNum));
3817
3819 std::string Targets;
3820 llvm::raw_string_ostream OS(Targets);
3821 llvm::interleave(
3823 [&OS](const llvm::Triple &T) { OS << T.str(); }, ",");
3824 GenerateArg(Consumer, OPT_fopenmp_targets_EQ, Targets);
3825 }
3826
3829
3830 if (Opts.OpenMPCUDAMode)
3831 GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
3832
3833 if (Opts.OpenACC) {
3836 GenerateArg(Consumer, OPT_openacc_macro_override,
3838 }
3839
3840
3841
3842
3844 GenerateArg(Consumer, OPT_ffp_contract, "fast");
3846 GenerateArg(Consumer, OPT_ffp_contract, "on");
3848 GenerateArg(Consumer, OPT_ffp_contract, "off");
3850 GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas");
3851
3853 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3854
3855
3857 GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);
3858
3859 switch (Opts.getClangABICompat()) {
3861 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "3.8");
3862 break;
3864 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "4.0");
3865 break;
3867 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "6.0");
3868 break;
3870 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "7.0");
3871 break;
3873 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "9.0");
3874 break;
3876 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "11.0");
3877 break;
3879 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "12.0");
3880 break;
3882 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "14.0");
3883 break;
3885 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "15.0");
3886 break;
3888 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0");
3889 break;
3891 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0");
3892 break;
3894 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "19.0");
3895 break;
3897 break;
3898 }
3899
3900 if (Opts.getSignReturnAddressScope() ==
3902 GenerateArg(Consumer, OPT_msign_return_address_EQ, "all");
3903 else if (Opts.getSignReturnAddressScope() ==
3905 GenerateArg(Consumer, OPT_msign_return_address_EQ, "non-leaf");
3906
3907 if (Opts.getSignReturnAddressKey() ==
3909 GenerateArg(Consumer, OPT_msign_return_address_key_EQ, "b_key");
3910
3914
3915 if (Opts.RelativeCXXABIVTables)
3916 GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables);
3917 else
3918 GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables);
3919
3921 GenerateArg(Consumer, OPT_ffile_reproducible);
3922 else
3923 GenerateArg(Consumer, OPT_fno_file_reproducible);
3924
3926 GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second);
3927
3930}
3931
3932bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
3933 InputKind IK, const llvm::Triple &T,
3934 std::vectorstd::string &Includes,
3936 unsigned NumErrorsBefore = Diags.getNumErrors();
3937
3941
3942
3943
3944 if (Args.hasArg(OPT_fobjc_arc))
3945 Opts.ObjCAutoRefCount = 1;
3946
3947
3949 Opts.PIE = Args.hasArg(OPT_pic_is_pie);
3950 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
3952
3953 return Diags.getNumErrors() == NumErrorsBefore;
3954 }
3955
3956
3957
3958
3959
3961 if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
3964 Diags.Report(diag::err_drv_invalid_value)
3965 << A->getAsString(Args) << A->getValue();
3966
3967 for (unsigned KindValue = 0;
3969 ++KindValue) {
3973 auto Diag = Diags.Report(diag::note_drv_use_standard);
3974 Diag << Std.getName() << Std.getDescription();
3975 unsigned NumAliases = 0;
3976#define LANGSTANDARD(id, name, lang, desc, features)
3977#define LANGSTANDARD_ALIAS(id, alias) \
3978 if (KindValue == LangStandard::lang_##id) ++NumAliases;
3979#define LANGSTANDARD_ALIAS_DEPR(id, alias)
3980#include "clang/Basic/LangStandards.def"
3981 Diag << NumAliases;
3982#define LANGSTANDARD(id, name, lang, desc, features)
3983#define LANGSTANDARD_ALIAS(id, alias) \
3984 if (KindValue == LangStandard::lang_##id) Diag << alias;
3985#define LANGSTANDARD_ALIAS_DEPR(id, alias)
3986#include "clang/Basic/LangStandards.def"
3987 }
3988 }
3989 } else {
3990
3991
3994 Diags.Report(diag::err_drv_argument_not_allowed_with)
3996 }
3997 }
3998 }
3999
4000
4001
4002 if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
4004 = llvm::StringSwitchLangStandard::Kind(A->getValue())
4005 .Cases("cl", "CL", LangStandard::lang_opencl10)
4006 .Cases("cl1.0", "CL1.0", LangStandard::lang_opencl10)
4007 .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
4008 .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
4009 .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
4010 .Cases("cl3.0", "CL3.0", LangStandard::lang_opencl30)
4011 .Cases("clc++", "CLC++", LangStandard::lang_openclcpp10)
4012 .Cases("clc++1.0", "CLC++1.0", LangStandard::lang_openclcpp10)
4013 .Cases("clc++2021", "CLC++2021", LangStandard::lang_openclcpp2021)
4015
4017 Diags.Report(diag::err_drv_invalid_value)
4018 << A->getAsString(Args) << A->getValue();
4019 }
4020 else
4021 LangStd = OpenCLLangStd;
4022 }
4023
4024
4025 Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
4026 Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
4027
4029
4030
4031
4033
4034#define LANG_OPTION_WITH_MARSHALLING(...) \
4035 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4036#include "clang/Driver/Options.inc"
4037#undef LANG_OPTION_WITH_MARSHALLING
4038
4039 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4040 StringRef Name = A->getValue();
4041 if (Name == "full" || Name == "branch") {
4042 Opts.CFProtectionBranch = 1;
4043 }
4044 }
4045
4046 if (Opts.CFProtectionBranch) {
4047 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
4048 const auto Scheme =
4049 llvm::StringSwitch(A->getValue())
4050#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
4051 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
4052#include "clang/Basic/CFProtectionOptions.def"
4054 Opts.setCFBranchLabelScheme(Scheme);
4055 }
4056 }
4057
4058 if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
4059 !Args.hasArg(OPT_sycl_std_EQ)) {
4060
4061
4062
4063
4064
4066 }
4067
4068 if (Opts.ObjC) {
4069 if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
4070 StringRef value = arg->getValue();
4072 Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
4073 }
4074
4075 if (Args.hasArg(OPT_fobjc_gc_only))
4077 else if (Args.hasArg(OPT_fobjc_gc))
4079 else if (Args.hasArg(OPT_fobjc_arc)) {
4080 Opts.ObjCAutoRefCount = 1;
4082 Diags.Report(diag::err_arc_unsupported_on_runtime);
4083 }
4084
4085
4086
4087
4088
4089 if (Args.hasArg(OPT_fobjc_runtime_has_weak))
4090 Opts.ObjCWeakRuntime = 1;
4091 else
4093
4094
4095
4096 if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
4097 if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
4098 assert(!Opts.ObjCWeak);
4100 Diags.Report(diag::err_objc_weak_with_gc);
4101 } else if (!Opts.ObjCWeakRuntime) {
4102 Diags.Report(diag::err_objc_weak_unsupported);
4103 } else {
4104 Opts.ObjCWeak = 1;
4105 }
4106 } else if (Opts.ObjCAutoRefCount) {
4107 Opts.ObjCWeak = Opts.ObjCWeakRuntime;
4108 }
4109
4110 if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
4111 Opts.ObjCSubscriptingLegacyRuntime =
4113 }
4114
4115 if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
4116
4117
4118 VersionTuple GNUCVer;
4119 bool Invalid = GNUCVer.tryParse(A->getValue());
4120 unsigned Major = GNUCVer.getMajor();
4121 unsigned Minor = GNUCVer.getMinor().value_or(0);
4122 unsigned Patch = GNUCVer.getSubminor().value_or(0);
4123 if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
4124 Diags.Report(diag::err_drv_invalid_value)
4125 << A->getAsString(Args) << A->getValue();
4126 }
4127 Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
4128 }
4129
4130 if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility)))
4131 Opts.IgnoreXCOFFVisibility = 1;
4132
4133 if (Args.hasArg(OPT_ftrapv)) {
4135
4137 std::string(Args.getLastArgValue(OPT_ftrapv_handler));
4138 }
4139 else if (Args.hasArg(OPT_fwrapv))
4141
4142 Opts.MSCompatibilityVersion = 0;
4143 if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
4144 VersionTuple VT;
4145 if (VT.tryParse(A->getValue()))
4146 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
4147 << A->getValue();
4148 Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
4149 VT.getMinor().value_or(0) * 100000 +
4150 VT.getSubminor().value_or(0);
4151 }
4152
4153
4154
4155
4156
4157 Opts.Trigraphs =
4158 (!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
4159 T.isOSzOS();
4160 Opts.Trigraphs =
4161 Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
4162
4163 Opts.ZOSExt =
4164 Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions, T.isOSzOS());
4165
4166 Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
4167 && Opts.OpenCLVersion == 200);
4168
4169 bool HasConvergentOperations = Opts.OpenMPIsTargetDevice || Opts.OpenCL ||
4170 Opts.CUDAIsDevice || Opts.SYCLIsDevice ||
4171 Opts.HLSL || T.isAMDGPU() || T.isNVPTX();
4172 Opts.ConvergentFunctions =
4173 Args.hasFlag(OPT_fconvergent_functions, OPT_fno_convergent_functions,
4174 HasConvergentOperations);
4175
4176 Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
4177 if (!Opts.NoBuiltin)
4179 if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
4180 if (A->getOption().matches(options::OPT_mlong_double_64))
4181 Opts.LongDoubleSize = 64;
4182 else if (A->getOption().matches(options::OPT_mlong_double_80))
4183 Opts.LongDoubleSize = 80;
4184 else if (A->getOption().matches(options::OPT_mlong_double_128))
4185 Opts.LongDoubleSize = 128;
4186 else
4187 Opts.LongDoubleSize = 0;
4188 }
4189 if (Opts.FastRelaxedMath || Opts.CLUnsafeMath)
4191
4193
4194
4195 if (Arg *A = Args.getLastArg(OPT_mrtd)) {
4197 Diags.Report(diag::err_drv_argument_not_allowed_with)
4198 << A->getSpelling() << "-fdefault-calling-conv";
4199 else {
4200 switch (T.getArch()) {
4201 case llvm::Triple::x86:
4203 break;
4204 case llvm::Triple::m68k:
4206 break;
4207 default:
4208 Diags.Report(diag::err_drv_argument_not_allowed_with)
4209 << A->getSpelling() << T.getTriple();
4210 }
4211 }
4212 }
4213
4214
4215 Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;
4216
4217 bool IsSimdSpecified =
4218 Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
4219 false);
4220 Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;
4221 Opts.OpenMPUseTLS =
4222 Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
4223 Opts.OpenMPIsTargetDevice =
4224 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_target_device);
4225 Opts.OpenMPIRBuilder =
4226 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_enable_irbuilder);
4227 bool IsTargetSpecified =
4228 Opts.OpenMPIsTargetDevice || Args.hasArg(options::OPT_fopenmp_targets_EQ);
4229
4230 if (Opts.OpenMP || Opts.OpenMPSimd) {
4232 Args, OPT_fopenmp_version_EQ,
4233 (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))
4234 Opts.OpenMP = Version;
4235
4236
4237 if (!Opts.OpenMPIsTargetDevice) {
4238 switch (T.getArch()) {
4239 default:
4240 break;
4241
4242 case llvm::Triple::nvptx:
4243 case llvm::Triple::nvptx64:
4244 Diags.Report(diag::err_drv_omp_host_target_not_supported) << T.str();
4245 break;
4246 }
4247 }
4248 }
4249
4250
4251
4252 if ((Opts.OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) ||
4253 Opts.OpenCLCPlusPlus) {
4254
4255 Opts.Exceptions = 0;
4256 Opts.CXXExceptions = 0;
4257 }
4258 if (Opts.OpenMPIsTargetDevice && T.isNVPTX()) {
4259 Opts.OpenMPCUDANumSMs =
4261 Opts.OpenMPCUDANumSMs, Diags);
4262 Opts.OpenMPCUDABlocksPerSM =
4263 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,
4264 Opts.OpenMPCUDABlocksPerSM, Diags);
4266 Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
4267 Opts.OpenMPCUDAReductionBufNum, Diags);
4268 }
4269
4270
4271
4272 if (Opts.OpenMPIsTargetDevice && (Args.hasArg(OPT_fopenmp_target_debug) ||
4273 Args.hasArg(OPT_fopenmp_target_debug_EQ))) {
4275 Args, OPT_fopenmp_target_debug_EQ, Opts.OpenMPTargetDebug, Diags);
4276 if (!Opts.OpenMPTargetDebug && Args.hasArg(OPT_fopenmp_target_debug))
4277 Opts.OpenMPTargetDebug = 1;
4278 }
4279
4280 if (Opts.OpenMPIsTargetDevice) {
4281 if (Args.hasArg(OPT_fopenmp_assume_teams_oversubscription))
4282 Opts.OpenMPTeamSubscription = true;
4283 if (Args.hasArg(OPT_fopenmp_assume_threads_oversubscription))
4284 Opts.OpenMPThreadSubscription = true;
4285 }
4286
4287
4288 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
4289 enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
4290 auto getArchPtrSize = [](const llvm::Triple &T) {
4291 if (T.isArch16Bit())
4292 return Arch16Bit;
4293 if (T.isArch32Bit())
4294 return Arch32Bit;
4295 assert(T.isArch64Bit() && "Expected 64-bit architecture");
4296 return Arch64Bit;
4297 };
4298
4299 for (unsigned i = 0; i < A->getNumValues(); ++i) {
4300 llvm::Triple TT(A->getValue(i));
4301
4302 if (TT.getArch() == llvm::Triple::UnknownArch ||
4303 !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() ||
4304 TT.getArch() == llvm::Triple::spirv64 ||
4305 TT.getArch() == llvm::Triple::systemz ||
4306 TT.getArch() == llvm::Triple::loongarch64 ||
4307 TT.getArch() == llvm::Triple::nvptx ||
4308 TT.getArch() == llvm::Triple::nvptx64 ||
4309 TT.getArch() == llvm::Triple::amdgcn ||
4310 TT.getArch() == llvm::Triple::x86 ||
4311 TT.getArch() == llvm::Triple::x86_64))
4312 Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
4313 else if (getArchPtrSize(T) != getArchPtrSize(TT))
4314 Diags.Report(diag::err_drv_incompatible_omp_arch)
4315 << A->getValue(i) << T.str();
4316 else
4318 }
4319 }
4320
4321
4322
4323 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) {
4326 Diags.Report(diag::err_drv_omp_host_ir_file_not_found)
4328 }
4329
4330
4331 Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice &&
4332 (T.isNVPTX() || T.isAMDGCN()) &&
4333 Args.hasArg(options::OPT_fopenmp_cuda_mode);
4334
4335
4336 if (Args.hasArg(options::OPT_fopenacc)) {
4337 Opts.OpenACC = true;
4338
4339 if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override))
4341 }
4342
4343
4346 Opts.Optimize = Opt != 0;
4347 Opts.OptimizeSize = OptSize != 0;
4348
4349
4350
4351
4352 Opts.NoInlineDefine = !Opts.Optimize;
4353 if (Arg *InlineArg = Args.getLastArg(
4354 options::OPT_finline_functions, options::OPT_finline_hint_functions,
4355 options::OPT_fno_inline_functions, options::OPT_fno_inline))
4356 if (InlineArg->getOption().matches(options::OPT_fno_inline))
4357 Opts.NoInlineDefine = true;
4358
4359 if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
4360 StringRef Val = A->getValue();
4361 if (Val == "fast")
4363 else if (Val == "on")
4365 else if (Val == "off")
4367 else if (Val == "fast-honor-pragmas")
4369 else
4370 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
4371 }
4372
4373 if (auto *A =
4374 Args.getLastArg(OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {
4375 for (int i = 0, n = A->getNumValues(); i != n; ++i) {
4377 llvm::StringSwitch(A->getValue(i))
4380 .Case("add-unsigned-overflow-test",
4382 .Case("add-signed-overflow-test",
4385 .Case("unsigned-post-decr-while",
4387 .Default(0);
4388 }
4389 }
4390
4391
4392 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
4394 Opts.NoSanitizeFiles = Args.getAllArgValues(OPT_fsanitize_ignorelist_EQ);
4395 std::vectorstd::string systemIgnorelists =
4396 Args.getAllArgValues(OPT_fsanitize_system_ignorelist_EQ);
4398 systemIgnorelists.begin(),
4399 systemIgnorelists.end());
4400
4401 if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
4403
4404 StringRef Ver = A->getValue();
4405 std::pair<StringRef, StringRef> VerParts = Ver.split('.');
4406 unsigned Major, Minor = 0;
4407
4408
4409
4410 if (!VerParts.first.starts_with("0") &&
4411 !VerParts.first.getAsInteger(10, Major) && 3 <= Major &&
4412 Major <= CLANG_VERSION_MAJOR &&
4413 (Major == 3
4414 ? VerParts.second.size() == 1 &&
4415 !VerParts.second.getAsInteger(10, Minor)
4416 : VerParts.first.size() == Ver.size() || VerParts.second == "0")) {
4417
4418 if (Major == 3 && Minor <= 8)
4420 else if (Major <= 4)
4422 else if (Major <= 6)
4424 else if (Major <= 7)
4426 else if (Major <= 9)
4428 else if (Major <= 11)
4430 else if (Major <= 12)
4432 else if (Major <= 14)
4434 else if (Major <= 15)
4436 else if (Major <= 17)
4438 else if (Major <= 18)
4440 else if (Major <= 19)
4442 } else if (Ver != "latest") {
4443 Diags.Report(diag::err_drv_invalid_value)
4444 << A->getAsString(Args) << A->getValue();
4445 }
4446 }
4447
4448 if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) {
4449 StringRef SignScope = A->getValue();
4450
4451 if (SignScope.equals_insensitive("none"))
4452 Opts.setSignReturnAddressScope(
4454 else if (SignScope.equals_insensitive("all"))
4455 Opts.setSignReturnAddressScope(
4457 else if (SignScope.equals_insensitive("non-leaf"))
4458 Opts.setSignReturnAddressScope(
4460 else
4461 Diags.Report(diag::err_drv_invalid_value)
4462 << A->getAsString(Args) << SignScope;
4463
4464 if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
4465 StringRef SignKey = A->getValue();
4466 if (!SignScope.empty() && !SignKey.empty()) {
4467 if (SignKey == "a_key")
4468 Opts.setSignReturnAddressKey(
4470 else if (SignKey == "b_key")
4471 Opts.setSignReturnAddressKey(
4473 else
4474 Diags.Report(diag::err_drv_invalid_value)
4475 << A->getAsString(Args) << SignKey;
4476 }
4477 }
4478 }
4479
4480
4481 StringRef CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);
4482 if (.empty()) {
4484 Diags.Report(diag::err_invalid_cxx_abi) << CXXABI;
4485 } else {
4488 Diags.Report(diag::err_unsupported_cxx_abi) << CXXABI << T.str();
4489 else
4491 }
4492 }
4493
4494 Opts.RelativeCXXABIVTables =
4495 Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
4496 options::OPT_fno_experimental_relative_cxx_abi_vtables,
4498
4499
4500 bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti);
4501 Opts.OmitVTableRTTI =
4502 Args.hasFlag(options::OPT_fexperimental_omit_vtable_rtti,
4503 options::OPT_fno_experimental_omit_vtable_rtti, false);
4504 if (Opts.OmitVTableRTTI && HasRTTI)
4505 Diags.Report(diag::err_drv_using_omit_rtti_component_without_no_rtti);
4506
4507 for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
4508 auto Split = StringRef(A).split('=');
4510 {std::string(Split.first), std::string(Split.second)});
4511 }
4512
4514 !Args.getLastArg(OPT_fno_file_reproducible) &&
4515 (Args.getLastArg(OPT_ffile_compilation_dir_EQ) ||
4516 Args.getLastArg(OPT_fmacro_prefix_map_EQ) ||
4517 Args.getLastArg(OPT_ffile_reproducible));
4518
4519
4520 if (Arg *A = Args.getLastArg(options::OPT_mvscale_min_EQ)) {
4521 unsigned VScaleMin;
4522 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4523 Diags.Report(diag::err_cc1_unbounded_vscale_min);
4524 }
4525
4526 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) {
4527 std::ifstream SeedFile(A->getValue(0));
4528
4529 if (!SeedFile.is_open())
4530 Diags.Report(diag::err_drv_cannot_open_randomize_layout_seed_file)
4531 << A->getValue(0);
4532
4534 }
4535
4536 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
4538
4539
4540 if (Opts.HLSL) {
4541
4542
4543 if (T.isDXIL() || T.isSPIRVLogical()) {
4544 enum { ShaderModel, VulkanEnv, ShaderStage };
4545 enum { OS, Environment };
4546
4547 int ExpectedOS = T.isSPIRVLogical() ? VulkanEnv : ShaderModel;
4548
4549 if (T.getOSName().empty()) {
4550 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4551 << ExpectedOS << OS << T.str();
4552 } else if (T.getEnvironmentName().empty()) {
4553 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4555 } else if (.isShaderStageEnvironment()) {
4556 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4557 << ShaderStage << T.getEnvironmentName() << T.str();
4558 }
4559
4560 if (T.isDXIL()) {
4561 if (.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
4562 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4563 << ShaderModel << T.getOSName() << T.str();
4564 }
4565
4566
4567
4568 if (Args.getLastArg(OPT_fnative_half_type)) {
4571 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018 &&
4572 T.getOSVersion() >= VersionTuple(6, 2)))
4573 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4574 << "-enable-16bit-types" << true << Std.getName()
4575 << T.getOSVersion().getAsString();
4576 }
4577 } else if (T.isSPIRVLogical()) {
4578 if (.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) {
4579 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4580 << VulkanEnv << T.getOSName() << T.str();
4581 }
4582 if (Args.getLastArg(OPT_fnative_half_type)) {
4585 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018))
4586 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4587 << "-fnative-half-type" << false << Std.getName();
4588 }
4589 } else {
4590 llvm_unreachable("expected DXIL or SPIR-V target");
4591 }
4592 } else
4593 Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
4594
4595 if (Opts.LangStd < LangStandard::lang_hlsl202x) {
4600 Diags.Report(diag::warn_hlsl_langstd_minimal)
4602 }
4603 }
4604
4605 return Diags.getNumErrors() == NumErrorsBefore;
4606}
4607
4639 return false;
4640
4650 return true;
4651 }
4652 llvm_unreachable("invalid frontend action");
4653}
4654
4661
4662#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4663 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4664#include "clang/Driver/Options.inc"
4665#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4666
4668 GenerateArg(Consumer, OPT_pch_through_hdrstop_use);
4669
4671 GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);
4672
4674 GenerateArg(Consumer, OPT_preamble_bytes_EQ,
4677
4678 for (const auto &M : Opts.Macros) {
4679
4680
4681 if (M.first == "__CET__=1" && !M.second &&
4682 !CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch)
4683 continue;
4684 if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn &&
4685 !CodeGenOpts.CFProtectionBranch)
4686 continue;
4687 if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn &&
4688 CodeGenOpts.CFProtectionBranch)
4689 continue;
4690
4691 GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first);
4692 }
4693
4694 for (const auto &I : Opts.Includes) {
4695
4696
4697 if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader &&
4698 ((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") ||
4699 I == "opencl-c.h"))
4700 continue;
4701
4702
4703 if (LangOpts.HLSL && I == "hlsl.h")
4704 continue;
4705
4707 }
4708
4710 GenerateArg(Consumer, OPT_chain_include, CI);
4711
4713 GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second);
4714
4717
4719 GenerateArg(Consumer, OPT_fdefine_target_os_macros);
4720
4721 for (const auto &EmbedEntry : Opts.EmbedEntries)
4722 GenerateArg(Consumer, OPT_embed_dir_EQ, EmbedEntry);
4723
4724
4725
4726}
4727
4732 unsigned NumErrorsBefore = Diags.getNumErrors();
4733
4735
4736#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4737 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4738#include "clang/Driver/Options.inc"
4739#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4740
4741 Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) ||
4742 Args.hasArg(OPT_pch_through_hdrstop_use);
4743
4744 for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
4746
4747 if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
4748 StringRef Value(A->getValue());
4749 size_t Comma = Value.find(',');
4750 unsigned Bytes = 0;
4751 unsigned EndOfLine = 0;
4752
4753 if (Comma == StringRef::npos ||
4754 Value.substr(0, Comma).getAsInteger(10, Bytes) ||
4755 Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
4756 Diags.Report(diag::err_drv_preamble_format);
4757 else {
4760 }
4761 }
4762
4763
4764 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4765 StringRef Name = A->getValue();
4766 if (Name == "branch")
4768 else if (Name == "return")
4770 else if (Name == "full")
4772 }
4773
4774
4775 for (const auto *A : Args.filtered(OPT_D, OPT_U)) {
4776 if (A->getOption().matches(OPT_D))
4778 else
4780 }
4781
4782
4783 for (const auto *A : Args.filtered(OPT_include))
4784 Opts.Includes.emplace_back(A->getValue());
4785
4786 for (const auto *A : Args.filtered(OPT_chain_include))
4788
4789 for (const auto *A : Args.filtered(OPT_remap_file)) {
4790 std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
4791
4792 if (Split.second.empty()) {
4793 Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
4794 continue;
4795 }
4796
4798 }
4799
4800 if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
4801 StringRef Epoch = A->getValue();
4802
4803
4804
4805 const uint64_t MaxTimestamp =
4806 std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
4807 uint64_t V;
4808 if (Epoch.getAsInteger(10, V) || V > MaxTimestamp) {
4809 Diags.Report(diag::err_fe_invalid_source_date_epoch)
4810 << Epoch << MaxTimestamp;
4811 } else {
4813 }
4814 }
4815
4816 for (const auto *A : Args.filtered(OPT_embed_dir_EQ)) {
4817 StringRef Val = A->getValue();
4818 Opts.EmbedEntries.push_back(std::string(Val));
4819 }
4820
4821
4822
4823
4826
4828 Args.hasFlag(OPT_fdefine_target_os_macros,
4830
4831 return Diags.getNumErrors() == NumErrorsBefore;
4832}
4833
4834static void
4839
4840#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4841 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4842#include "clang/Driver/Options.inc"
4843#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4844
4846 if (Generate_dM)
4848 if (!Generate_dM && Opts.ShowMacros)
4851 GenerateArg(Consumer, OPT_fdirectives_only);
4852}
4853
4857 unsigned NumErrorsBefore = Diags.getNumErrors();
4858
4860
4861#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4862 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4863#include "clang/Driver/Options.inc"
4864#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4865
4867 Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
4868 Opts.DirectivesOnly = Args.hasArg(OPT_fdirectives_only);
4869
4870 return Diags.getNumErrors() == NumErrorsBefore;
4871}
4872
4876#define TARGET_OPTION_WITH_MARSHALLING(...) \
4877 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4878#include "clang/Driver/Options.inc"
4879#undef TARGET_OPTION_WITH_MARSHALLING
4880
4882 GenerateArg(Consumer, OPT_target_sdk_version_EQ,
4885 GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,
4887}
4888
4891 unsigned NumErrorsBefore = Diags.getNumErrors();
4892
4894
4895#define TARGET_OPTION_WITH_MARSHALLING(...) \
4896 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4897#include "clang/Driver/Options.inc"
4898#undef TARGET_OPTION_WITH_MARSHALLING
4899
4900 if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {
4901 llvm::VersionTuple Version;
4902 if (Version.tryParse(A->getValue()))
4903 Diags.Report(diag::err_drv_invalid_value)
4904 << A->getAsString(Args) << A->getValue();
4905 else
4907 }
4908 if (Arg *A =
4909 Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {
4910 llvm::VersionTuple Version;
4911 if (Version.tryParse(A->getValue()))
4912 Diags.Report(diag::err_drv_invalid_value)
4913 << A->getAsString(Args) << A->getValue();
4914 else
4916 }
4917
4918 return Diags.getNumErrors() == NumErrorsBefore;
4919}
4920
4921bool CompilerInvocation::CreateFromArgsImpl(
4924 unsigned NumErrorsBefore = Diags.getNumErrors();
4925
4926
4929 unsigned MissingArgIndex, MissingArgCount;
4930 InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
4931 MissingArgCount, VisibilityMask);
4933
4934
4935 if (MissingArgCount)
4936 Diags.Report(diag::err_drv_missing_argument)
4937 << Args.getArgString(MissingArgIndex) << MissingArgCount;
4938
4939
4940 for (const auto *A : Args.filtered(OPT_UNKNOWN)) {
4941 auto ArgString = A->getAsString(Args);
4942 std::string Nearest;
4943 if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1)
4944 Diags.Report(diag::err_drv_unknown_argument) << ArgString;
4945 else
4946 Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
4947 << ArgString << Nearest;
4948 }
4949
4954 false);
4956
4963
4965
4967 Diags);
4969 LangOpts.ObjCExceptions = 1;
4970
4972 if (Warning == "misexpect" &&
4975 }
4976 }
4977
4979
4980
4983 }
4984
4985
4986 if (LangOpts.OpenMPIsTargetDevice)
4988
4989 ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
4991
4992
4993
4994
4996 .Sanitize.has(SanitizerKind::Address) &&
4997 .Sanitize.has(SanitizerKind::KernelAddress) &&
4998 .Sanitize.has(SanitizerKind::Memory) &&
4999 .Sanitize.has(SanitizerKind::KernelMemory);
5000
5006
5012 Diags.Report(diag::err_fe_dependency_file_requires_MT);
5013
5014
5015 if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
5017 Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
5018 Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
5019 }
5020
5021
5025 }
5026
5027
5028
5030 auto FS =
5032 Diags, llvm::vfs::getRealFileSystem());
5035 Diags);
5036 }
5037
5039
5040 return Diags.getNumErrors() == NumErrorsBefore;
5041}
5042
5046 const char *Argv0) {
5048
5052 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
5053 },
5056 Args.push_back("-cc1");
5058 },
5059 Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
5060}
5061
5063
5064 llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
5065
5066
5067
5068
5069
5071
5072
5073
5075
5076
5077#define LANGOPT(Name, Bits, Default, Description) HBuilder.add(LangOpts->Name);
5078#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
5079 HBuilder.add(static_cast(LangOpts->get##Name()));
5080#define BENIGN_LANGOPT(Name, Bits, Default, Description)
5081#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
5082#include "clang/Basic/LangOptions.def"
5083
5084 HBuilder.addRange(getLangOpts().ModuleFeatures);
5085
5087 HBuilder.addRange(getLangOpts().CommentOpts.BlockCommandNames);
5088
5089
5092 HBuilder.addRange(getTargetOpts().FeaturesAsWritten);
5093
5094
5097
5100
5101
5103
5104 StringRef MacroDef = Macro.first;
5106 llvm::CachedHashString(MacroDef.split('=').first)))
5107 continue;
5108 }
5109
5110 HBuilder.add(Macro);
5111 }
5112
5113
5119
5124
5126#define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name);
5127#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
5128 HBuilder.add(diagOpts.get##Name());
5129#include "clang/Basic/DiagnosticOptions.def"
5130#undef DIAGOPT
5131#undef ENUM_DIAGOPT
5132 }
5133
5134
5136
5137
5138 for (const auto &ext : getFrontendOpts().ModuleFileExtensions)
5139 ext->hashExtension(HBuilder);
5140
5141
5144 HBuilder.add(APINotesOpts.SwiftVersion.getMajor());
5145 if (auto Minor = APINotesOpts.SwiftVersion.getMinor())
5146 HBuilder.add(*Minor);
5147 if (auto Subminor = APINotesOpts.SwiftVersion.getSubminor())
5148 HBuilder.add(*Subminor);
5149 if (auto Build = APINotesOpts.SwiftVersion.getBuild())
5150 HBuilder.add(*Build);
5151 }
5152
5153
5154
5157
5158
5160#define DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);
5161#define VALUE_DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);
5162#define ENUM_DEBUGOPT(Name, Type, Bits, Default) \
5163 HBuilder.add(static_cast(CodeGenOpts->get##Name()));
5164#define BENIGN_DEBUGOPT(Name, Bits, Default)
5165#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default)
5166#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default)
5167#include "clang/Basic/DebugOptions.def"
5168 }
5169
5170
5171
5174 if (!SanHash.empty())
5175 HBuilder.add(SanHash.Mask);
5176
5177 llvm::MD5::MD5Result Result;
5178 HBuilder.getHasher().final(Result);
5179 uint64_t Hash = Result.high() ^ Result.low();
5180 return toString(llvm::APInt(64, Hash), 36, false);
5181}
5182
5186
5191 false);
5205}
5206
5208 std::vectorstd::string Args{"-cc1"};
5210 [&Args](const Twine &Arg) { Args.push_back(Arg.str()); });
5211 return Args;
5212}
5213
5218}
5219
5226
5227
5230}
5231
5236 llvm::vfs::getRealFileSystem());
5237}
5238
5244 Diags, std::move(BaseFS));
5245}
5246
5250 if (VFSOverlayFiles.empty())
5251 return BaseFS;
5252
5254
5255 for (const auto &File : VFSOverlayFiles) {
5256 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> Buffer =
5258 if (!Buffer) {
5259 Diags.Report(diag::err_missing_vfs_overlay_file) << File;
5260 continue;
5261 }
5262
5264 std::move(Buffer.get()), nullptr, File,
5265 nullptr, Result);
5266 if (!FS) {
5267 Diags.Report(diag::err_invalid_vfs_overlay) << File;
5268 continue;
5269 }
5270
5272 }
5274}
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)
llvm::function_ref< bool(CompilerInvocation &, ArrayRef< const char * >, DiagnosticsEngine &, const char *)> ParseFn
llvm::function_ref< void(CompilerInvocation &, SmallVectorImpl< const char * > &, CompilerInvocation::StringAllocator)> GenerateFn
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 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 void setPGOUseInstrumentor(CodeGenOptions &Opts, const Twine &ProfileName, llvm::vfs::FileSystem &FS, DiagnosticsEngine &Diags)
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 ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, const std::string &WorkingDir)
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)
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)
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 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.
Defines the clang::TargetOptions class.
Defines version macros and version-related utility functions for Clang.
Defines the clang::Visibility enumeration and various utility functions.
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.
Implements C++ ABI-specific semantic analysis functions.
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
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::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< 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
AnalyzerOptionsRef AnalyzerOpts
Options controlling the static analyzer.
IntrusiveRefCntPtr< DiagnosticOptions > DiagnosticOpts
Options controlling the diagnostic engine.
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()
std::shared_ptr< LangOptions > LangOpts
Base class internals.
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.
Used for handling and querying diagnostic IDs.
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.
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
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.
std::string WorkingDir
If set, paths are resolved as if the working directory was set to the value of WorkingDir.
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.
enum clang::FrontendOptions::@202 ARCMTAction
std::map< std::string, std::vector< std::string > > PluginArgs
Args to pass to the plugins.
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.
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.
The kind of a file that we've been handed as an input.
bool isPreprocessed() const
InputKind withHeaderUnit(HeaderUnitKind HU) const
bool isUnknown() const
Is the input kind fully-unknown?
InputKind getPreprocessed() const
HeaderUnitKind getHeaderUnitKind() const
InputKind getHeader() const
InputKind withFormat(Format F) const
Language getLanguage() const
@ 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–)
@ Ver6
Attempt to be ABI-compatible with code generated by Clang 6.0.x (SVN r321711).
@ Ver18
Attempt to be ABI-compatible with code generated by Clang 18.0.x.
@ Ver4
Attempt to be ABI-compatible with code generated by Clang 4.0.x (SVN r291814).
@ Ver14
Attempt to be ABI-compatible with code generated by Clang 14.0.x.
@ Ver11
Attempt to be ABI-compatible with code generated by Clang 11.0.x (git 2e10b7a39b93).
@ Ver19
Attempt to be ABI-compatible with code generated by Clang 19.0.x.
@ Ver15
Attempt to be ABI-compatible with code generated by Clang 15.0.x.
@ Ver17
Attempt to be ABI-compatible with code generated by Clang 17.0.x.
@ Ver7
Attempt to be ABI-compatible with code generated by Clang 7.0.x (SVN r338536).
@ Latest
Conform to the underlying platform's C and C++ ABIs as closely as we can.
@ Ver3_8
Attempt to be ABI-compatible with code generated by Clang 3.8.x (SVN r257626).
@ Ver12
Attempt to be ABI-compatible with code generated by Clang 12.0.x (git 8e464dd76bef).
@ Ver9
Attempt to be ABI-compatible with code generated by Clang 9.0.x (SVN r351319).
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 OMPHostIRFile
Name of the IR file that contains the result of the OpenMP target host code generation.
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().
LangStandard::Kind LangStd
The used language standard.
std::string OpenACCMacroOverride
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 sepa...
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 beginni...
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()
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.
@ MigrateSource
Run migrator.
@ 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.
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.
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.
std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)
AnalysisConstraints
AnalysisConstraints - Set of available constraint models.
@ HIFIL_Only_Direct_System
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 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.
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 values for -fsanitize= or -fno-sanitize=.
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.
const FunctionProtoType * T
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.
bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags=nullptr, bool DefaultDiagColor=true)
Fill out Opts based on the options given in Args.
@ Success
Template argument deduction was successful.
AnalysisInliningMode
AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
Diagnostic wrappers for TextAPI types for error reporting.
__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.
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 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 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 FunctionPointers
The ABI for C function 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 CXXVirtualFunctionPointers
The ABI for most C++ virtual function pointers, i.e. v-table entries.
bool IndirectGotos
Do indirect goto label addresses need to be authenticated?
void clear(SanitizerMask K=SanitizerKind::All)
Disable the sanitizers specified in K.
bool empty() const
Returns true if no sanitizers are enabled.
SanitizerMask Mask
Bitmask of enabled sanitizers.