clang 20.0.0git
CompilerInvocation.cpp
Go to the documentation of this file.
1//===- CompilerInvocation.cpp ---------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
19#include "clang/Basic/LLVM.h"
26#include "clang/Basic/Version.h"
29#include "clang/Config/config.h"
30#include "clang/Driver/Driver.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 <algorithm>
90#include <atomic>
91#include <cassert>
92#include <cstddef>
93#include <cstring>
94#include <ctime>
95#include <fstream>
96#include <limits>
97#include <memory>
98#include <optional>
99#include <string>
100#include <tuple>
101#include <type_traits>
102#include <utility>
103#include <vector>
104
105using namespace clang;
106using namespace driver;
107using namespace options;
108using namespace llvm::opt;
109
110//===----------------------------------------------------------------------===//
111// Helpers.
112//===----------------------------------------------------------------------===//
113
114// Parse misexpect tolerance argument value.
115// Valid option values are integers in the range [0, 100)
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// Initialization.
126//===----------------------------------------------------------------------===//
127
128namespace {
129template <class T> std::shared_ptr<T> make_shared_copy(const T &X) {
130 return std::make_shared<T>(X);
131}
132
133template <class T>
134llvm::IntrusiveRefCntPtr<T> makeIntrusiveRefCntCopy(const T &X) {
135 return llvm::makeIntrusiveRefCnt<T>(X);
136}
137} // namespace
138
140 : LangOpts(std::make_shared<LangOptions>()),
141 TargetOpts(std::make_shared<TargetOptions>()),
142 DiagnosticOpts(llvm::makeIntrusiveRefCnt<DiagnosticOptions>()),
143 HSOpts(std::make_shared<HeaderSearchOptions>()),
144 PPOpts(std::make_shared<PreprocessorOptions>()),
145 AnalyzerOpts(llvm::makeIntrusiveRefCnt<AnalyzerOptions>()),
146 MigratorOpts(std::make_shared<MigratorOptions>()),
147 APINotesOpts(std::make_shared<APINotesOptions>()),
148 CodeGenOpts(std::make_shared<CodeGenOptions>()),
149 FSOpts(std::make_shared<FileSystemOptions>()),
150 FrontendOpts(std::make_shared<FrontendOptions>()),
151 DependencyOutputOpts(std::make_shared<DependencyOutputOptions>()),
152 PreprocessorOutputOpts(std::make_shared<PreprocessorOutputOptions>()) {}
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());
168 DependencyOutputOpts = make_shared_copy(X.getDependencyOutputOpts());
169 PreprocessorOutputOpts = make_shared_copy(X.getPreprocessorOutputOpts());
170 }
171 return *this;
172}
173
176 if (this != &X) {
177 LangOpts = X.LangOpts;
178 TargetOpts = X.TargetOpts;
179 DiagnosticOpts = X.DiagnosticOpts;
180 HSOpts = X.HSOpts;
181 PPOpts = X.PPOpts;
182 AnalyzerOpts = X.AnalyzerOpts;
183 MigratorOpts = X.MigratorOpts;
184 APINotesOpts = X.APINotesOpts;
185 CodeGenOpts = X.CodeGenOpts;
186 FSOpts = X.FSOpts;
187 FrontendOpts = X.FrontendOpts;
188 DependencyOutputOpts = X.DependencyOutputOpts;
189 PreprocessorOutputOpts = X.PreprocessorOutputOpts;
190 }
191 return *this;
192}
193
197}
198
202 return *this;
203}
204
205namespace {
206template <typename T>
207T &ensureOwned(std::shared_ptr<T> &Storage) {
208 if (Storage.use_count() > 1)
209 Storage = std::make_shared<T>(*Storage);
210 return *Storage;
211}
212
213template <typename T>
214T &ensureOwned(llvm::IntrusiveRefCntPtr<T> &Storage) {
215 if (Storage.useCount() > 1)
216 Storage = llvm::makeIntrusiveRefCnt<T>(*Storage);
217 return *Storage;
218}
219} // namespace
220
222 return ensureOwned(LangOpts);
223}
224
226 return ensureOwned(TargetOpts);
227}
228
230 return ensureOwned(DiagnosticOpts);
231}
232
234 return ensureOwned(HSOpts);
235}
236
238 return ensureOwned(PPOpts);
239}
240
242 return ensureOwned(AnalyzerOpts);
243}
244
246 return ensureOwned(MigratorOpts);
247}
248
250 return ensureOwned(APINotesOpts);
251}
252
254 return ensureOwned(CodeGenOpts);
255}
256
258 return ensureOwned(FSOpts);
259}
260
262 return ensureOwned(FrontendOpts);
263}
264
266 return ensureOwned(DependencyOutputOpts);
267}
268
271 return ensureOwned(PreprocessorOutputOpts);
272}
273
274//===----------------------------------------------------------------------===//
275// Normalizers
276//===----------------------------------------------------------------------===//
277
279
280#define OPTTABLE_STR_TABLE_CODE
281#include "clang/Driver/Options.inc"
282#undef OPTTABLE_STR_TABLE_CODE
283
284static llvm::StringRef lookupStrInTable(unsigned Offset) {
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
292static std::optional<bool> normalizeSimpleFlag(OptSpecifier Opt,
293 unsigned TableIndex,
294 const ArgList &Args,
295 DiagnosticsEngine &Diags) {
296 if (Args.hasArg(Opt))
297 return true;
298 return std::nullopt;
299}
300
301static std::optional<bool> normalizeSimpleNegativeFlag(OptSpecifier Opt,
302 unsigned,
303 const ArgList &Args,
305 if (Args.hasArg(Opt))
306 return false;
307 return std::nullopt;
308}
309
310/// The tblgen-erated code passes in a fifth parameter of an arbitrary type, but
311/// denormalizeSimpleFlags never looks at it. Avoid bloating compile-time with
312/// unnecessary template instantiations and just ignore it with a variadic
313/// argument.
315 unsigned SpellingOffset, Option::OptionClass,
316 unsigned, /*T*/...) {
317 Consumer(lookupStrInTable(SpellingOffset));
318}
320 const Twine &Spelling, Option::OptionClass,
321 unsigned, /*T*/...) {
322 Consumer(Spelling);
323}
324
325template <typename T> static constexpr bool is_uint64_t_convertible() {
326 return !std::is_same_v<T, uint64_t> && llvm::is_integral_or_enum<T>::value;
327}
328
329template <typename T,
330 std::enable_if_t<!is_uint64_t_convertible<T>(), bool> = false>
332 return [Value](OptSpecifier Opt, unsigned, const ArgList &Args,
333 DiagnosticsEngine &) -> std::optional<T> {
334 if (Args.hasArg(Opt))
335 return Value;
336 return std::nullopt;
337 };
338}
339
340template <typename T,
341 std::enable_if_t<is_uint64_t_convertible<T>(), bool> = false>
342static auto makeFlagToValueNormalizer(T Value) {
344}
345
346static auto makeBooleanOptionNormalizer(bool Value, bool OtherValue,
347 OptSpecifier OtherOpt) {
348 return [Value, OtherValue,
349 OtherOpt](OptSpecifier Opt, unsigned, const ArgList &Args,
350 DiagnosticsEngine &) -> std::optional<bool> {
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
359 return [Value](ArgumentConsumer Consumer, unsigned SpellingOffset,
360 Option::OptionClass, unsigned, bool KeyPath) {
361 if (KeyPath == Value)
362 Consumer(lookupStrInTable(SpellingOffset));
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);
375 Consumer(Value);
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 <typename T>
388static void
389denormalizeString(ArgumentConsumer Consumer, unsigned SpellingOffset,
390 Option::OptionClass OptClass, unsigned TableIndex, T Value) {
391 denormalizeStringImpl(Consumer, lookupStrInTable(SpellingOffset), OptClass,
392 TableIndex, Twine(Value));
393}
394
395template <typename T>
396static void denormalizeString(ArgumentConsumer Consumer, const Twine &Spelling,
397 Option::OptionClass OptClass, unsigned TableIndex,
398 T Value) {
399 denormalizeStringImpl(Consumer, Spelling, OptClass, TableIndex, Twine(Value));
400}
401
402static std::optional<SimpleEnumValue>
403findValueTableByName(const SimpleEnumValueTable &Table, StringRef Name) {
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<SimpleEnumValue>
412findValueTableByValue(const SimpleEnumValueTable &Table, unsigned Value) {
413 for (int I = 0, E = Table.Size; I != E; ++I)
414 if (Value == Table.Table[I].Value)
415 return Table.Table[I];
416
417 return std::nullopt;
418}
419
420static std::optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
421 unsigned TableIndex,
422 const ArgList &Args,
423 DiagnosticsEngine &Diags) {
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();
432 if (auto MaybeEnumVal = findValueTableByName(Table, ArgValue))
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];
446 if (auto MaybeEnumVal = findValueTableByValue(Table, Value)) {
447 denormalizeString(Consumer, lookupStrInTable(SpellingOffset), OptClass,
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 <typename T>
457 unsigned SpellingOffset,
458 Option::OptionClass OptClass,
459 unsigned TableIndex, T Value) {
460 return denormalizeSimpleEnumImpl(Consumer, SpellingOffset, OptClass,
461 TableIndex, static_cast<unsigned>(Value));
462}
463
464static std::optional<std::string> normalizeString(OptSpecifier Opt,
465 int TableIndex,
466 const ArgList &Args,
467 DiagnosticsEngine &Diags) {
468 auto *Arg = Args.getLastArg(Opt);
469 if (!Arg)
470 return std::nullopt;
471 return std::string(Arg->getValue());
472}
473
474template <typename IntTy>
475static std::optional<IntTy> normalizeStringIntegral(OptSpecifier Opt, int,
476 const ArgList &Args,
477 DiagnosticsEngine &Diags) {
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::vector<std::string>>
491normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args,
493 return Args.getAllArgValues(Opt);
494}
495
497 unsigned SpellingOffset,
498 Option::OptionClass OptClass,
499 unsigned TableIndex,
500 const std::vector<std::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 }
511 denormalizeString(Consumer, SpellingOffset,
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)
520 denormalizeString(Consumer, SpellingOffset, OptClass, TableIndex, Value);
521 break;
522 default:
523 llvm_unreachable("Cannot denormalize an option with option class "
524 "incompatible with string vector denormalization.");
525 }
526}
527
528static std::optional<std::string> normalizeTriple(OptSpecifier Opt,
529 int TableIndex,
530 const ArgList &Args,
531 DiagnosticsEngine &Diags) {
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>
539static T mergeForwardValue(T KeyPath, U Value) {
540 return static_cast<T>(Value);
541}
542
543template <typename T, typename U> static T mergeMaskValue(T KeyPath, U Value) {
544 return KeyPath | Value;
545}
546
547template <typename T> static T extractForwardValue(T KeyPath) {
548 return KeyPath;
549}
550
551template <typename T, typename U, U Value>
552static T extractMaskValue(T KeyPath) {
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// Capture the extracted value as a lambda argument to avoid potential issues
573// with lifetime extension of the reference.
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
590static StringRef GetInputKindName(InputKind IK);
591
592static bool FixupInvocation(CompilerInvocation &Invocation,
593 DiagnosticsEngine &Diags, const ArgList &Args,
594 InputKind IK) {
595 unsigned NumErrorsBefore = Diags.getNumErrors();
596
597 LangOptions &LangOpts = Invocation.getLangOpts();
598 CodeGenOptions &CodeGenOpts = Invocation.getCodeGenOpts();
599 TargetOptions &TargetOpts = Invocation.getTargetOpts();
600 FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();
601 CodeGenOpts.XRayInstrumentFunctions = LangOpts.XRayInstrument;
602 CodeGenOpts.XRayAlwaysEmitCustomEvents = LangOpts.XRayAlwaysEmitCustomEvents;
603 CodeGenOpts.XRayAlwaysEmitTypedEvents = LangOpts.XRayAlwaysEmitTypedEvents;
604 CodeGenOpts.DisableFree = FrontendOpts.DisableFree;
605 FrontendOpts.GenerateGlobalModuleIndex = FrontendOpts.UseGlobalModuleIndex;
606 if (FrontendOpts.ShowStats)
607 CodeGenOpts.ClearASTBeforeBackend = false;
608 LangOpts.SanitizeCoverage = CodeGenOpts.hasSanitizeCoverage();
609 LangOpts.ForceEmitVTables = CodeGenOpts.ForceEmitVTables;
610 LangOpts.SpeculativeLoadHardening = CodeGenOpts.SpeculativeLoadHardening;
611 LangOpts.CurrentModule = LangOpts.ModuleName;
612
613 llvm::Triple T(TargetOpts.Triple);
614 llvm::Triple::ArchType Arch = T.getArch();
615
616 CodeGenOpts.CodeModel = TargetOpts.CodeModel;
617 CodeGenOpts.LargeDataThreshold = TargetOpts.LargeDataThreshold;
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 // The -f[no-]raw-string-literals option is only valid in C and in C++
637 // standards before C++11.
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 // Do not allow disabling raw string literals in C++11 or later.
646 LangOpts.RawStringLiterals = true;
647 }
648
649 // Prevent the user from specifying both -fsycl-is-device and -fsycl-is-host.
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)
656 << "-fgnu89-inline" << GetInputKindName(IK);
657
658 if (Args.hasArg(OPT_hlsl_entrypoint) && !LangOpts.HLSL)
659 Diags.Report(diag::err_drv_argument_not_allowed_with)
660 << "-hlsl-entry" << GetInputKindName(IK);
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 // When these options are used, the compiler is allowed to apply
671 // optimizations that may affect the final result. For example
672 // (x+y)+z is transformed to x+(y+z) but may not give the same
673 // final result; it's not value safe.
674 // Another example can be to simplify x/x to 1.0 but x could be 0.0, INF
675 // or NaN. Final result may then differ. An error is issued when the eval
676 // method is set with one of these options.
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 // -cl-strict-aliasing needs to emit diagnostic in the case where CL > 1.0.
687 // This option should be deprecated for CL > 1.0 because
688 // this option was added for compatibility with OpenCL 1.0.
689 if (Args.getLastArg(OPT_cl_strict_aliasing) &&
690 (LangOpts.getOpenCLCompatibleVersion() > 100))
691 Diags.Report(diag::warn_option_invalid_ocl_version)
692 << LangOpts.getOpenCLVersionString()
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
698 bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
699 DefaultCC == LangOptions::DCC_StdCall) &&
700 Arch != llvm::Triple::x86;
701 emitError |= (DefaultCC == LangOptions::DCC_VectorCall ||
702 DefaultCC == LangOptions::DCC_RegCall) &&
703 !T.isX86();
704 emitError |= DefaultCC == LangOptions::DCC_RtdCall && Arch != llvm::Triple::m68k;
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// Deserialization (from args)
715//===----------------------------------------------------------------------===//
716
717static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
718 DiagnosticsEngine &Diags) {
719 unsigned DefaultOpt = 0;
720 if ((IK.getLanguage() == Language::OpenCL ||
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
741 return getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
742 }
743
744 return DefaultOpt;
745}
746
747static unsigned getOptimizationLevelSize(ArgList &Args) {
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
763static void GenerateArg(ArgumentConsumer Consumer,
764 llvm::opt::OptSpecifier OptSpecifier) {
765 Option Opt = getDriverOptTable().getOption(OptSpecifier);
766 denormalizeSimpleFlag(Consumer, Opt.getPrefixedName(),
767 Option::OptionClass::FlagClass, 0);
768}
769
770static void GenerateArg(ArgumentConsumer Consumer,
771 llvm::opt::OptSpecifier OptSpecifier,
772 const Twine &Value) {
773 Option Opt = getDriverOptTable().getOption(OptSpecifier);
774 denormalizeString(Consumer, Opt.getPrefixedName(), Opt.getKind(), 0, Value);
775}
776
777// Parse command line arguments into CompilerInvocation.
778using ParseFn =
779 llvm::function_ref<bool(CompilerInvocation &, ArrayRef<const char *>,
780 DiagnosticsEngine &, const char *)>;
781
782// Generate command line arguments from CompilerInvocation.
783using GenerateFn = llvm::function_ref<void(
786
787/// May perform round-trip of command line arguments. By default, the round-trip
788/// is enabled in assert builds. This can be overwritten at run-time via the
789/// "-round-trip-args" and "-no-round-trip-args" command line flags, or via the
790/// ForceRoundTrip parameter.
791///
792/// During round-trip, the command line arguments are parsed into a dummy
793/// CompilerInvocation, which is used to generate the command line arguments
794/// again. The real CompilerInvocation is then created by parsing the generated
795/// arguments, not the original ones. This (in combination with tests covering
796/// argument behavior) ensures the generated command line is complete (doesn't
797/// drop/mangle any arguments).
798///
799/// Finally, we check the command line that was used to create the real
800/// CompilerInvocation instance. By default, we compare it to the command line
801/// the real CompilerInvocation generates. This checks whether the generator is
802/// deterministic. If \p CheckAgainstOriginalInvocation is enabled, we instead
803/// compare it to the original command line to verify the original command-line
804/// was canonical and can round-trip exactly.
805static bool RoundTrip(ParseFn Parse, GenerateFn Generate,
806 CompilerInvocation &RealInvocation,
807 CompilerInvocation &DummyInvocation,
808 ArrayRef<const char *> CommandLineArgs,
809 DiagnosticsEngine &Diags, const char *Argv0,
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 // If round-trip was not requested, simply run the parser with the real
831 // invocation diagnostics.
832 if (!DoRoundTrip)
833 return Parse(RealInvocation, CommandLineArgs, Diags, Argv0);
834
835 // Serializes quoted (and potentially escaped) arguments.
836 auto SerializeArgs = [](ArrayRef<const char *> Args) {
837 std::string Buffer;
838 llvm::raw_string_ostream OS(Buffer);
839 for (const char *Arg : Args) {
840 llvm::sys::printArg(OS, Arg, /*Quote=*/true);
841 OS << ' ';
842 }
843 return Buffer;
844 };
845
846 // Setup a dummy DiagnosticsEngine.
847 DiagnosticsEngine DummyDiags(new DiagnosticIDs(), new DiagnosticOptions());
848 DummyDiags.setClient(new TextDiagnosticBuffer());
849
850 // Run the first parse on the original arguments with the dummy invocation and
851 // diagnostics.
852 if (!Parse(DummyInvocation, CommandLineArgs, DummyDiags, Argv0) ||
853 DummyDiags.getNumWarnings() != 0) {
854 // If the first parse did not succeed, it must be user mistake (invalid
855 // command line arguments). We won't be able to generate arguments that
856 // would reproduce the same result. Let's fail again with the real
857 // invocation and diagnostics, so all side-effects of parsing are visible.
858 unsigned NumWarningsBefore = Diags.getNumWarnings();
859 auto Success = Parse(RealInvocation, CommandLineArgs, Diags, Argv0);
860 if (!Success || Diags.getNumWarnings() != NumWarningsBefore)
861 return Success;
862
863 // Parse with original options and diagnostics succeeded even though it
864 // shouldn't have. Something is off.
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 // Setup string allocator.
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 // Generate arguments from the dummy invocation. If Generate is the
879 // inverse of Parse, the newly generated arguments must have the same
880 // semantics as the original.
881 SmallVector<const char *> GeneratedArgs;
882 Generate(DummyInvocation, GeneratedArgs, SA);
883
884 // Run the second parse, now on the generated arguments, and with the real
885 // invocation and diagnostics. The result is what we will end up using for the
886 // rest of compilation, so if Generate is not inverse of Parse, something down
887 // the line will break.
888 bool Success2 = Parse(RealInvocation, GeneratedArgs, Diags, Argv0);
889
890 // The first parse on original arguments succeeded, but second parse of
891 // generated arguments failed. Something must be wrong with the generator.
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
899 SmallVector<const char *> ComparisonArgs;
900 if (CheckAgainstOriginalInvocation)
901 // Compare against original arguments.
902 ComparisonArgs.assign(CommandLineArgs.begin(), CommandLineArgs.end());
903 else
904 // Generate arguments again, this time from the options we will end up using
905 // for the rest of the compilation.
906 Generate(RealInvocation, ComparisonArgs, SA);
907
908 // Compares two lists of arguments.
909 auto Equal = [](const ArrayRef<const char *> A,
910 const ArrayRef<const char *> B) {
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 // If we generated different arguments from what we assume are two
918 // semantically equivalent CompilerInvocations, the Generate function may
919 // be non-deterministic.
920 if (!Equal(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
938 DiagnosticsEngine &Diags,
939 const char *Argv0) {
940 CompilerInvocation DummyInvocation1, DummyInvocation2;
941 return RoundTrip(
942 [](CompilerInvocation &Invocation, ArrayRef<const char *> CommandLineArgs,
943 DiagnosticsEngine &Diags, const char *Argv0) {
944 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
945 },
947 StringAllocator SA) {
948 Args.push_back("-cc1");
949 Invocation.generateCC1CommandLine(Args, SA);
950 },
951 DummyInvocation1, DummyInvocation2, Args, Diags, Argv0,
952 /*CheckAgainstOriginalInvocation=*/true, /*ForceRoundTrip=*/true);
953}
954
955static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
956 OptSpecifier GroupWithValue,
957 std::vector<std::string> &Diagnostics) {
958 for (auto *A : Args.filtered(Group)) {
959 if (A->getOption().getKind() == Option::FlagClass) {
960 // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
961 // its name (minus the "W" or "R" at the beginning) to the diagnostics.
962 Diagnostics.push_back(
963 std::string(A->getOption().getName().drop_front(1)));
964 } else if (A->getOption().matches(GroupWithValue)) {
965 // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic
966 // group. Add only the group name to the diagnostics.
967 Diagnostics.push_back(
968 std::string(A->getOption().getName().drop_front(1).rtrim("=-")));
969 } else {
970 // Otherwise, add its value (for OPT_W_Joined and similar).
971 Diagnostics.push_back(A->getValue());
972 }
973 }
974}
975
976// Parse the Static Analyzer configuration. If \p Diags is set to nullptr,
977// it won't verify the input.
978static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
979 DiagnosticsEngine *Diags);
980
981static void getAllNoBuiltinFuncValues(ArgList &Args,
982 std::vector<std::string> &Funcs) {
983 std::vector<std::string> Values = Args.getAllArgValues(OPT_fno_builtin_);
984 auto BuiltinEnd = llvm::partition(Values, Builtin::Context::isBuiltinFunc);
985 Funcs.insert(Funcs.end(), Values.begin(), BuiltinEnd);
986}
987
988static void GenerateAnalyzerArgs(const AnalyzerOptions &Opts,
989 ArgumentConsumer Consumer) {
990 const AnalyzerOptions *AnalyzerOpts = &Opts;
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
997 if (Opts.AnalysisConstraintsOpt != RangeConstraintsModel) {
998 switch (Opts.AnalysisConstraintsOpt) {
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
1009 if (Opts.AnalysisDiagOpt != PD_HTML) {
1010 switch (Opts.AnalysisDiagOpt) {
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
1021 if (Opts.AnalysisPurgeOpt != PurgeStmt) {
1022 switch (Opts.AnalysisPurgeOpt) {
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
1033 if (Opts.InliningMode != NoRedundancy) {
1034 switch (Opts.InliningMode) {
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
1045 for (const auto &CP : Opts.CheckersAndPackages) {
1046 OptSpecifier Opt =
1047 CP.second ? OPT_analyzer_checker : OPT_analyzer_disable_checker;
1048 GenerateArg(Consumer, Opt, CP.first);
1049 }
1050
1051 AnalyzerOptions ConfigOpts;
1052 parseAnalyzerConfigs(ConfigOpts, nullptr);
1053
1054 // Sort options by key to avoid relying on StringMap iteration order.
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 // Don't generate anything that came from parseAnalyzerConfigs. It would be
1062 // redundant and may not be valid on the command line.
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 // Nothing to generate for FullCompilerInvocation.
1071}
1072
1073static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
1074 DiagnosticsEngine &Diags) {
1075 unsigned NumErrorsBefore = Diags.getNumErrors();
1076
1077 AnalyzerOptions *AnalyzerOpts = &Opts;
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();
1086 AnalysisConstraints Value = llvm::StringSwitch<AnalysisConstraints>(Name)
1087#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
1088 .Case(CMDFLAG, NAME##Model)
1089#include "clang/StaticAnalyzer/Core/Analyses.def"
1090 .Default(NumConstraints);
1091 if (Value == NumConstraints) {
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 // LLVM_WITH_Z3
1101 }
1102 }
1103
1104 if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
1105 StringRef Name = A->getValue();
1106 AnalysisDiagClients Value = llvm::StringSwitch<AnalysisDiagClients>(Name)
1107#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
1108 .Case(CMDFLAG, PD_##NAME)
1109#include "clang/StaticAnalyzer/Core/Analyses.def"
1110 .Default(NUM_ANALYSIS_DIAG_CLIENTS);
1112 Diags.Report(diag::err_drv_invalid_value)
1113 << A->getAsString(Args) << Name;
1114 } else {
1115 Opts.AnalysisDiagOpt = Value;
1116 }
1117 }
1118
1119 if (Arg *A = Args.getLastArg(OPT_analyzer_purge)) {
1120 StringRef Name = A->getValue();
1121 AnalysisPurgeMode Value = llvm::StringSwitch<AnalysisPurgeMode>(Name)
1122#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
1123 .Case(CMDFLAG, NAME)
1124#include "clang/StaticAnalyzer/Core/Analyses.def"
1125 .Default(NumPurgeModes);
1126 if (Value == NumPurgeModes) {
1127 Diags.Report(diag::err_drv_invalid_value)
1128 << A->getAsString(Args) << Name;
1129 } else {
1130 Opts.AnalysisPurgeOpt = Value;
1131 }
1132 }
1133
1134 if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {
1135 StringRef Name = A->getValue();
1136 AnalysisInliningMode Value = llvm::StringSwitch<AnalysisInliningMode>(Name)
1137#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
1138 .Case(CMDFLAG, NAME)
1139#include "clang/StaticAnalyzer/Core/Analyses.def"
1140 .Default(NumInliningModes);
1141 if (Value == NumInliningModes) {
1142 Diags.Report(diag::err_drv_invalid_value)
1143 << A->getAsString(Args) << Name;
1144 } else {
1145 Opts.InliningMode = Value;
1146 }
1147 }
1148
1149 Opts.CheckersAndPackages.clear();
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 // We can have a list of comma separated checker names, e.g:
1155 // '-analyzer-checker=cocoa,unix'
1156 StringRef CheckerAndPackageList = A->getValue();
1157 SmallVector<StringRef, 16> CheckersAndPackages;
1158 CheckerAndPackageList.split(CheckersAndPackages, ",");
1159 for (const StringRef &CheckerOrPackage : CheckersAndPackages)
1160 Opts.CheckersAndPackages.emplace_back(std::string(CheckerOrPackage),
1161 IsEnabled);
1162 }
1163
1164 // Go through the analyzer configuration options.
1165 for (const auto *A : Args.filtered(OPT_analyzer_config)) {
1166
1167 // We can have a list of comma separated config names, e.g:
1168 // '-analyzer-config key1=val1,key2=val2'
1169 StringRef configList = A->getValue();
1170 SmallVector<StringRef, 4> configVals;
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()) {
1176 Diags.Report(SourceLocation(),
1177 diag::err_analyzer_config_no_value) << configVal;
1178 break;
1179 }
1180 if (val.contains('=')) {
1181 Diags.Report(SourceLocation(),
1182 diag::err_analyzer_config_multiple_values)
1183 << configVal;
1184 break;
1185 }
1186
1187 // TODO: Check checker options too, possibly in CheckerRegistry.
1188 // Leave unknown non-checker configs unclaimed.
1189 if (!key.contains(":") && Opts.isUnknownAnalyzerConfig(key)) {
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
1201 parseAnalyzerConfigs(Opts, &Diags);
1202 else
1203 parseAnalyzerConfigs(Opts, nullptr);
1204
1205 llvm::raw_string_ostream os(Opts.FullCompilerInvocation);
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
1221 DiagnosticsEngine *Diags,
1222 StringRef &OptionField, StringRef Name,
1223 StringRef DefaultVal) {
1224 // String options may be known to invalid (e.g. if the expected string is a
1225 // file name, but the file does not exist), those will have to be checked in
1226 // parseConfigs.
1227 OptionField = getStringOption(Config, Name, DefaultVal);
1228}
1229
1231 DiagnosticsEngine *Diags,
1232 bool &OptionField, StringRef Name, bool DefaultVal) {
1233 auto PossiblyInvalidVal =
1234 llvm::StringSwitch<std::optional<bool>>(
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
1251 DiagnosticsEngine *Diags,
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
1264 DiagnosticsEngine *Diags,
1265 PositiveAnalyzerOption &OptionField, StringRef Name,
1266 unsigned DefaultVal) {
1267 auto Parsed = PositiveAnalyzerOption::create(
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
1281 DiagnosticsEngine *Diags) {
1282 // TODO: There's no need to store the entire configtable, it'd be plenty
1283 // enough to store checker options.
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 // At this point, AnalyzerOptions is configured. Let's validate some options.
1301
1302 // FIXME: Here we try to validate the silenced checkers or packages are valid.
1303 // The current approach only validates the registered checkers which does not
1304 // contain the runtime enabled checkers and optimally we would validate both.
1305 if (!AnOpts.RawSilencedCheckersAndPackages.empty()) {
1306 std::vector<StringRef> Checkers =
1307 AnOpts.getRegisteredCheckers(/*IncludeExperimental=*/true);
1308 std::vector<StringRef> Packages =
1309 AnOpts.getRegisteredPackages(/*IncludeExperimental=*/true);
1310
1311 SmallVector<StringRef, 16> CheckersAndPackages;
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
1326 AnOpts.SilencedCheckersAndPackages.emplace_back(CheckerOrPackage);
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/// Generate a remark argument. This is an inverse of `ParseOptimizationRemark`.
1348static void
1350 StringRef Name,
1352 if (Remark.hasValidPattern()) {
1353 GenerateArg(Consumer, OptEQ, Remark.Pattern);
1354 } else if (Remark.Kind == CodeGenOptions::RK_Enabled) {
1355 GenerateArg(Consumer, OPT_R_Joined, Name);
1356 } else if (Remark.Kind == CodeGenOptions::RK_Disabled) {
1357 GenerateArg(Consumer, OPT_R_Joined, StringRef("no-") + Name);
1358 }
1359}
1360
1361/// Parse a remark command line argument. It may be missing, disabled/enabled by
1362/// '-R[no-]group' or specified with a regular expression by '-Rgroup=regexp'.
1363/// On top of that, it can be disabled/enabled globally by '-R[no-]everything'.
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_shared<llvm::Regex>(Result.Pattern);
1375 if (!Result.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
1399 if (Result.Kind == CodeGenOptions::RK_Disabled ||
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
1413 return Result;
1414}
1415
1416static bool parseDiagnosticLevelMask(StringRef FlagName,
1417 const std::vector<std::string> &Levels,
1418 DiagnosticsEngine &Diags,
1420 bool Success = true;
1421 for (const auto &Level : Levels) {
1422 DiagnosticLevelMask const PM =
1423 llvm::StringSwitch<DiagnosticLevelMask>(Level)
1424 .Case("note", DiagnosticLevelMask::Note)
1425 .Case("remark", DiagnosticLevelMask::Remark)
1426 .Case("warning", DiagnosticLevelMask::Warning)
1427 .Case("error", DiagnosticLevelMask::Error)
1428 .Default(DiagnosticLevelMask::None);
1429 if (PM == DiagnosticLevelMask::None) {
1430 Success = false;
1431 Diags.Report(diag::err_drv_invalid_value) << FlagName << Level;
1432 }
1433 M = M | PM;
1434 }
1435 return Success;
1436}
1437
1438static void parseSanitizerKinds(StringRef FlagName,
1439 const std::vector<std::string> &Sanitizers,
1440 DiagnosticsEngine &Diags, SanitizerSet &S) {
1441 for (const auto &Sanitizer : Sanitizers) {
1442 SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
1443 if (K == SanitizerMask())
1444 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1445 else
1446 S.set(K, true);
1447 }
1448}
1449
1452 serializeSanitizerSet(S, Values);
1453 return Values;
1454}
1455
1458 const std::vector<std::string> &Sanitizers,
1459 DiagnosticsEngine &Diags) {
1460 SanitizerMaskCutoffs Cutoffs;
1461 for (const auto &Sanitizer : Sanitizers) {
1462 if (!parseSanitizerWeightedValue(Sanitizer, /*AllowGroups=*/false, Cutoffs))
1463 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1464 }
1465 return Cutoffs;
1466}
1467
1468static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle,
1469 ArgList &Args, DiagnosticsEngine &D,
1470 XRayInstrSet &S) {
1472 llvm::SplitString(Bundle, BundleParts, ",");
1473 for (const auto &B : BundleParts) {
1474 auto Mask = parseXRayInstrValue(B);
1475 if (Mask == XRayInstrKind::None)
1476 if (B != "none")
1477 D.Report(diag::err_drv_invalid_value) << FlagName << Bundle;
1478 else
1479 S.Mask = Mask;
1480 else if (Mask == XRayInstrKind::All)
1481 S.Mask = Mask;
1482 else
1483 S.set(Mask, true);
1484 }
1485}
1486
1489 serializeXRayInstrValue(S, BundleParts);
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// Set the profile kind using fprofile-instrument-use-path.
1498 const Twine &ProfileName,
1499 llvm::vfs::FileSystem &FS,
1500 DiagnosticsEngine &Diags) {
1501 auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName, FS);
1502 if (auto E = ReaderOrErr.takeError()) {
1503 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
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_ptr<llvm::IndexedInstrProfReader> PGOReader =
1511 std::move(ReaderOrErr.get());
1512 // Currently memprof profiles are only added at the IR level. Mark the profile
1513 // type as IR in that case as well and the subsequent matching needs to detect
1514 // which is available (might be one or both).
1515 if (PGOReader->isIRLevelProfile() || PGOReader->hasMemoryProfile()) {
1516 if (PGOReader->hasCSIRLevelProfile())
1517 Opts.setProfileUse(CodeGenOptions::ProfileCSIRInstr);
1518 else
1519 Opts.setProfileUse(CodeGenOptions::ProfileIRInstr);
1520 } else
1521 Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
1522}
1523
1525 PointerAuthOptions &Opts, const LangOptions &LangOpts,
1526 const llvm::Triple &Triple) {
1527 assert(Triple.getArch() == llvm::Triple::aarch64);
1528 if (LangOpts.PointerAuthCalls) {
1529 using Key = PointerAuthSchema::ARM8_3Key;
1530 using Discrimination = PointerAuthSchema::Discrimination;
1531 // If you change anything here, be sure to update <ptrauth.h>.
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)
1544 PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1546 else
1548 PointerAuthSchema(Key::ASDA, false, Discrimination::None);
1549
1551 PointerAuthSchema(Key::ASDA, false, Discrimination::None);
1553 PointerAuthSchema(Key::ASIA, true, Discrimination::Decl);
1555 PointerAuthSchema(Key::ASIA, false, Discrimination::Type);
1556
1557 if (LangOpts.PointerAuthInitFini) {
1559 Key::ASIA, LangOpts.PointerAuthInitFiniAddressDiscrimination,
1560 Discrimination::Constant, InitFiniPointerConstantDiscriminator);
1561 }
1562 }
1563 Opts.ReturnAddresses = LangOpts.PointerAuthReturns;
1564 Opts.AuthTraps = LangOpts.PointerAuthAuthTraps;
1565 Opts.IndirectGotos = LangOpts.PointerAuthIndirectGotos;
1566 Opts.AArch64JumpTableHardening = LangOpts.AArch64JumpTableHardening;
1567}
1568
1570 const LangOptions &LangOpts,
1571 const llvm::Triple &Triple,
1572 DiagnosticsEngine &Diags) {
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,
1582 ArgumentConsumer Consumer,
1583 const llvm::Triple &T,
1584 const std::string &OutputFile,
1585 const LangOptions *LangOpts) {
1586 const CodeGenOptions &CodeGenOpts = Opts;
1587
1588 if (Opts.OptimizationLevel == 0)
1589 GenerateArg(Consumer, OPT_O0);
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) {
1599 if (Opts.Inlining == CodeGenOptions::NormalInlining)
1600 GenerateArg(Consumer, OPT_finline_functions);
1601 else if (Opts.Inlining == CodeGenOptions::OnlyHintInlining)
1602 GenerateArg(Consumer, OPT_finline_hint_functions);
1603 else if (Opts.Inlining == CodeGenOptions::OnlyAlwaysInlining)
1604 GenerateArg(Consumer, OPT_fno_inline);
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<StringRef> 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: // default value
1633 DebugInfoVal = std::nullopt;
1634 break;
1635 case llvm::codegenoptions::LocTrackingOnly: // implied value
1636 DebugInfoVal = std::nullopt;
1637 break;
1638 }
1639 if (DebugInfoVal)
1640 GenerateArg(Consumer, OPT_debug_info_kind_EQ, *DebugInfoVal);
1641
1642 for (const auto &Prefix : Opts.DebugPrefixMap)
1643 GenerateArg(Consumer, OPT_fdebug_prefix_map_EQ,
1644 Prefix.first + "=" + Prefix.second);
1645
1646 for (const auto &Prefix : Opts.CoveragePrefixMap)
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)
1654 GenerateArg(Consumer, OPT_O, "s");
1655 else if (Opts.OptimizeSize == 2)
1656 GenerateArg(Consumer, OPT_O, "z");
1657
1658 // SimplifyLibCalls is set only in the absence of -fno-builtin and
1659 // -ffreestanding. We'll consider that when generating them.
1660
1661 // NoBuiltinFuncs are generated by LangOptions.
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
1668 if (!Opts.BinutilsVersion.empty())
1669 GenerateArg(Consumer, OPT_fbinutils_version_EQ, Opts.BinutilsVersion);
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))
1677 GenerateArg(Consumer, OPT_gpubnames);
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 // ProfileInstrumentUsePath is marshalled automatically, no need to generate
1690 // it or PGOUseInstrumentor.
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
1705 if (!Opts.ThinLTOIndexFile.empty())
1706 GenerateArg(Consumer, OPT_fthinlto_index_EQ, Opts.ThinLTOIndexFile);
1707
1708 if (Opts.SaveTempsFilePrefix == OutputFile)
1709 GenerateArg(Consumer, OPT_save_temps_EQ, "obj");
1710
1711 StringRef MemProfileBasename("memprof.profraw");
1712 if (!Opts.MemoryProfileOutput.empty()) {
1713 if (Opts.MemoryProfileOutput == MemProfileBasename) {
1714 GenerateArg(Consumer, OPT_fmemory_profile);
1715 } else {
1716 size_t ArgLength =
1717 Opts.MemoryProfileOutput.size() - MemProfileBasename.size();
1718 GenerateArg(Consumer, OPT_fmemory_profile_EQ,
1719 Opts.MemoryProfileOutput.substr(0, ArgLength));
1720 }
1721 }
1722
1723 if (memcmp(Opts.CoverageVersion, "0000", 4))
1724 GenerateArg(Consumer, OPT_coverage_version_EQ,
1725 StringRef(Opts.CoverageVersion, 4));
1726
1727 // TODO: Check if we need to generate arguments stored in CmdArgs. (Namely
1728 // '-fembed_bitcode', which does not map to any CompilerInvocation field and
1729 // won't be generated.)
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
1760 for (const auto &F : Opts.LinkBitcodeFiles) {
1761 bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded &&
1762 F.PropagateAttrs && F.Internalize;
1763 GenerateArg(Consumer,
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())
1772 GenerateArg(Consumer, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str());
1773
1774 if ((Opts.FPDenormalMode != Opts.FP32DenormalMode) ||
1775 (Opts.FP32DenormalMode != llvm::DenormalMode::getIEEE()))
1776 GenerateArg(Consumer, OPT_fdenormal_fp_math_f32_EQ,
1777 Opts.FP32DenormalMode.str());
1778
1779 if (Opts.StructReturnConvention == CodeGenOptions::SRCK_OnStack) {
1780 OptSpecifier Opt =
1781 T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return;
1782 GenerateArg(Consumer, Opt);
1783 } else if (Opts.StructReturnConvention == CodeGenOptions::SRCK_InRegs) {
1784 OptSpecifier Opt =
1785 T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return;
1786 GenerateArg(Consumer, Opt);
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
1795 if (!Opts.OptRecordPasses.empty())
1796 GenerateArg(Consumer, OPT_opt_record_passes, Opts.OptRecordPasses);
1797
1798 if (!Opts.OptRecordFormat.empty())
1799 GenerateArg(Consumer, OPT_opt_record_format, Opts.OptRecordFormat);
1800
1801 GenerateOptimizationRemark(Consumer, OPT_Rpass_EQ, "pass",
1802 Opts.OptimizationRemark);
1803
1804 GenerateOptimizationRemark(Consumer, OPT_Rpass_missed_EQ, "pass-missed",
1806
1807 GenerateOptimizationRemark(Consumer, OPT_Rpass_analysis_EQ, "pass-analysis",
1809
1810 GenerateArg(Consumer, OPT_fdiagnostics_hotness_threshold_EQ,
1812 ? Twine(*Opts.DiagnosticsHotnessThreshold)
1813 : "auto");
1814
1815 GenerateArg(Consumer, OPT_fdiagnostics_misexpect_tolerance_EQ,
1816 Twine(*Opts.DiagnosticsMisExpectTolerance));
1817
1818 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeRecover))
1819 GenerateArg(Consumer, OPT_fsanitize_recover_EQ, Sanitizer);
1820
1821 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeTrap))
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)
1834 GenerateArg(Consumer, OPT_Qn);
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,
1849 InputKind IK,
1850 DiagnosticsEngine &Diags,
1851 const llvm::Triple &T,
1852 const std::string &OutputFile,
1853 const LangOptions &LangOptsRef) {
1854 unsigned NumErrorsBefore = Diags.getNumErrors();
1855
1856 unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
1857 // TODO: This could be done in Driver
1858 unsigned MaxOptLevel = 3;
1859 if (OptimizationLevel > MaxOptLevel) {
1860 // If the optimization level is not supported, fall back on the default
1861 // optimization
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 // The key paths of codegen options defined in Options.td start with
1869 // "CodeGenOpts.". Let's provide the expected variable name and type.
1871 // Some codegen options depend on language options. Let's provide the expected
1872 // variable name and type.
1873 const LangOptions *LangOpts = &LangOptsRef;
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 // At O0 we want to fully disable inlining outside of cases marked with
1881 // 'alwaysinline' that are required for correctness.
1882 if (Opts.OptimizationLevel == 0) {
1883 Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
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 // Explicit inlining flags can disable some or all inlining even at
1889 // optimization levels above zero.
1890 if (A->getOption().matches(options::OPT_finline_functions))
1891 Opts.setInlining(CodeGenOptions::NormalInlining);
1892 else if (A->getOption().matches(options::OPT_finline_hint_functions))
1893 Opts.setInlining(CodeGenOptions::OnlyHintInlining);
1894 else
1895 Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
1896 } else {
1897 Opts.setInlining(CodeGenOptions::NormalInlining);
1898 }
1899
1900 // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to
1901 // -fdirect-access-external-data.
1902 Opts.DirectAccessExternalData =
1903 Args.hasArg(OPT_fdirect_access_external_data) ||
1904 (!Args.hasArg(OPT_fno_direct_access_external_data) &&
1905 LangOpts->PICLevel == 0);
1906
1907 if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
1908 unsigned Val =
1909 llvm::StringSwitch<unsigned>(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_cast<llvm::codegenoptions::DebugInfoKind>(Val));
1923 }
1924
1925 // If -fuse-ctor-homing is set and limited debug info is already on, then use
1926 // constructor homing, and vice versa for -fno-use-ctor-homing.
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('=');
1939 Opts.DebugPrefixMap.emplace_back(Split.first, Split.second);
1940 }
1941
1942 for (const auto &Arg : Args.getAllArgValues(OPT_fcoverage_prefix_map_EQ)) {
1943 auto Split = StringRef(Arg).split('=');
1944 Opts.CoveragePrefixMap.emplace_back(Split.first, Split.second);
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
1952 if (Opts.OptimizationLevel > 0 && Opts.hasReducedDebugInfo() &&
1953 llvm::is_contained(DebugEntryValueArchs, T.getArch()))
1954 Opts.EmitCallSiteInfo = true;
1955
1956 if (!Opts.EnableDIPreservationVerify && Opts.DIBugsReportFilePath.size()) {
1957 Diags.Report(diag::warn_ignoring_verify_debuginfo_preserve_export)
1958 << Opts.DIBugsReportFilePath;
1959 Opts.DIBugsReportFilePath = "";
1960 }
1961
1962 Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
1963 Args.hasArg(OPT_new_struct_path_tbaa);
1964 Opts.OptimizeSize = getOptimizationLevelSize(Args);
1965 Opts.SimplifyLibCalls = !LangOpts->NoBuiltin;
1966 if (Opts.SimplifyLibCalls)
1967 Opts.NoBuiltinFuncs = LangOpts->NoBuiltinFuncs;
1968 Opts.UnrollLoops =
1969 Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
1970 (Opts.OptimizationLevel > 1));
1971 Opts.BinutilsVersion =
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 // -ftime-report= is only for new pass manager.
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)) {
2022 if (IK.getLanguage() != Language::LLVM_IR)
2023 Diags.Report(diag::err_drv_argument_only_allowed_with)
2024 << A->getAsString(Args) << "-x ir";
2025 Opts.ThinLTOIndexFile =
2026 std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ));
2027 }
2028 if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))
2029 Opts.SaveTempsFilePrefix =
2030 llvm::StringSwitch<std::string>(A->getValue())
2031 .Case("obj", OutputFile)
2032 .Default(llvm::sys::path::filename(OutputFile).str());
2033
2034 // The memory profile runtime appends the pid to make this name more unique.
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);
2040 Opts.MemoryProfileOutput = std::string(Path);
2041 } else if (Args.hasArg(OPT_fmemory_profile))
2042 Opts.MemoryProfileOutput = MemProfileBasename;
2043
2044 if (Opts.CoverageNotesFile.size() || Opts.CoverageDataFile.size()) {
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 {
2052 memcpy(Opts.CoverageVersion, CoverageVersion.data(), 4);
2053 }
2054 }
2055 }
2056 // FIXME: For backend options that are not yet recorded as function
2057 // attributes in the IR, keep track of them so we can embed them in a
2058 // separate data section and use them when building the bitcode.
2059 for (const auto &A : Args) {
2060 // Do not encode output and input.
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 // using \00 to separate each commandline options.
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)
2083 parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args,
2084 Diags, Opts.XRayInstrumentationBundle);
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<CFBranchLabelSchemeKind>(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::StringSwitch<llvm::FunctionReturnThunksKind>(A->getValue())
2117 .Case("keep", llvm::FunctionReturnThunksKind::Keep)
2118 .Case("thunk-extern", llvm::FunctionReturnThunksKind::Extern)
2119 .Default(llvm::FunctionReturnThunksKind::Invalid);
2120 // SystemZ might want to add support for "expolines."
2121 if (!T.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)) {
2139 F.Filename = A->getValue();
2140 if (A->getOption().matches(OPT_mlink_builtin_bitcode)) {
2141 F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;
2142 // When linking CUDA bitcode, propagate function attributes so that
2143 // e.g. libdevice gets fast-math attrs if we're building with fast-math.
2144 F.PropagateAttrs = true;
2145 F.Internalize = true;
2146 }
2147 Opts.LinkBitcodeFiles.push_back(F);
2148 }
2149
2150 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
2151 StringRef Val = A->getValue();
2152 Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);
2153 Opts.FP32DenormalMode = Opts.FPDenormalMode;
2154 if (!Opts.FPDenormalMode.isValid())
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);
2161 if (!Opts.FP32DenormalMode.isValid())
2162 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2163 }
2164
2165 // X86_32 has -fppc-struct-return and -freg-struct-return.
2166 // PPC32 has -maix-struct-return and -msvr4-struct-return.
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 // TODO: We might want to consider enabling these options on AIX in the
2171 // future.
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)) {
2179 Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack);
2180 } else {
2181 assert(O.matches(OPT_freg_struct_return) ||
2182 O.matches(OPT_msvr4_struct_return));
2183 Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs);
2184 }
2185 }
2186
2187 if (Arg *A = Args.getLastArg(OPT_mxcoff_roptr)) {
2188 if (!T.isOSAIX())
2189 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2190 << A->getSpelling() << T.str();
2191
2192 // Since the storage mapping class is specified per csect,
2193 // without using data sections, it is less effective to use read-only
2194 // pointers. Using read-only pointers may cause other RO variables in the
2195 // same csect to become RW when the linker acts upon `-bforceimprw`;
2196 // therefore, we require that separate data sections
2197 // are used when `-mxcoff-roptr` is in effect. We respect the setting of
2198 // data-sections since we have not found reasons to do otherwise that
2199 // overcome the user surprise of not respecting the setting.
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 (!T.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
2214 if (!Opts.OptRecordFile.empty())
2215 NeedLocTracking = true;
2216
2217 if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {
2218 Opts.OptRecordPasses = A->getValue();
2219 NeedLocTracking = true;
2220 }
2221
2222 if (Arg *A = Args.getLastArg(OPT_opt_record_format)) {
2223 Opts.OptRecordFormat = A->getValue();
2224 NeedLocTracking = true;
2225 }
2226
2227 Opts.OptimizationRemark =
2228 ParseOptimizationRemark(Diags, Args, OPT_Rpass_EQ, "pass");
2229
2231 ParseOptimizationRemark(Diags, Args, OPT_Rpass_missed_EQ, "pass-missed");
2232
2234 Diags, Args, OPT_Rpass_analysis_EQ, "pass-analysis");
2235
2236 NeedLocTracking |= Opts.OptimizationRemark.hasValidPattern() ||
2239
2240 bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
2241 bool UsingProfile =
2242 UsingSampleProfile || !Opts.ProfileInstrumentUsePath.empty();
2243
2244 if (Opts.DiagnosticsWithHotness && !UsingProfile &&
2245 // An IR file will contain PGO as metadata
2247 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2248 << "-fdiagnostics-show-hotness";
2249
2250 // Parse remarks hotness threshold. Valid value is either integer or 'auto'.
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 {
2260 Opts.DiagnosticsHotnessThreshold = *ResultOrErr;
2261 if ((!Opts.DiagnosticsHotnessThreshold ||
2262 *Opts.DiagnosticsHotnessThreshold > 0) &&
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)) {
2271 auto ResultOrErr = parseToleranceOption(arg->getValue());
2272
2273 if (!ResultOrErr) {
2274 Diags.Report(diag::err_drv_invalid_diagnotics_misexpect_tolerance)
2275 << "-fdiagnostics-misexpect-tolerance=";
2276 } else {
2277 Opts.DiagnosticsMisExpectTolerance = *ResultOrErr;
2278 if ((!Opts.DiagnosticsMisExpectTolerance ||
2279 *Opts.DiagnosticsMisExpectTolerance > 0) &&
2280 !UsingProfile)
2281 Diags.Report(diag::warn_drv_diagnostics_misexpect_requires_pgo)
2282 << "-fdiagnostics-misexpect-tolerance=";
2283 }
2284 }
2285
2286 // If the user requested to use a sample profile for PGO, then the
2287 // backend will need to track source location information so the profile
2288 // can be incorporated into the IR.
2289 if (UsingSampleProfile)
2290 NeedLocTracking = true;
2291
2292 if (!Opts.StackUsageOutput.empty())
2293 NeedLocTracking = true;
2294
2295 // If the user requested a flag that requires source locations available in
2296 // the backend, make sure that the backend tracks source location information.
2297 if (NeedLocTracking &&
2298 Opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo)
2299 Opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
2300
2301 // Parse -fsanitize-recover= arguments.
2302 // FIXME: Report unrecoverable sanitizers incorrectly specified here.
2303 parseSanitizerKinds("-fsanitize-recover=",
2304 Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,
2305 Opts.SanitizeRecover);
2306 parseSanitizerKinds("-fsanitize-trap=",
2307 Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
2308 Opts.SanitizeTrap);
2309 parseSanitizerKinds("-fsanitize-merge=",
2310 Args.getAllArgValues(OPT_fsanitize_merge_handlers_EQ),
2311 Diags, Opts.SanitizeMergeHandlers);
2312
2313 // Parse -fsanitize-skip-hot-cutoff= arguments.
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 (!LangOpts->CUDAIsDevice)
2322
2323 if (Args.hasArg(options::OPT_ffinite_loops))
2324 Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Always;
2325 else if (Args.hasArg(options::OPT_fno_finite_loops))
2326 Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Never;
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
2337 ArgumentConsumer Consumer) {
2338 const DependencyOutputOptions &DependencyOutputOpts = Opts;
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 // Sanitizer ignorelist arguments are generated from LanguageOptions.
2351 continue;
2352 case EDK_ModuleFile:
2353 // Module file arguments are generated from FrontendOptions and
2354 // HeaderSearchOptions.
2355 continue;
2356 case EDK_ProfileList:
2357 // Profile list arguments are generated from LanguageOptions via the
2358 // marshalling infrastructure.
2359 continue;
2360 case EDK_DepFileEntry:
2361 GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first);
2362 break;
2363 }
2364 }
2365}
2366
2368 ArgList &Args, DiagnosticsEngine &Diags,
2370 bool ShowLineMarkers) {
2371 unsigned NumErrorsBefore = Diags.getNumErrors();
2372
2373 DependencyOutputOptions &DependencyOutputOpts = Opts;
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 // Writing both /showIncludes and preprocessor output to stdout
2381 // would produce interleaved output, so use stderr for /showIncludes.
2382 // This behaves the same as cl.exe, when /E, /EP or /P are passed.
2383 if (Action == frontend::PrintPreprocessedInput || !ShowLineMarkers)
2385 else
2387 } else {
2389 }
2390
2391 // Add sanitizer ignorelists as extra dependencies.
2392 // They won't be discovered by the regular preprocessor, so
2393 // we let make / ninja to know about this implicit dependency.
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('='))
2398 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_SanitizeIgnorelist);
2399 }
2400 if (Opts.IncludeSystemHeaders) {
2401 for (const auto *A : Args.filtered(OPT_fsanitize_system_ignorelist_EQ)) {
2402 StringRef Val = A->getValue();
2403 if (!Val.contains('='))
2404 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_SanitizeIgnorelist);
2405 }
2406 }
2407 }
2408
2409 // -fprofile-list= dependencies.
2410 for (const auto &Filename : Args.getAllArgValues(OPT_fprofile_list_EQ))
2411 Opts.ExtraDeps.emplace_back(Filename, EDK_ProfileList);
2412
2413 // Propagate the extra dependencies.
2414 for (const auto *A : Args.filtered(OPT_fdepfile_entry))
2415 Opts.ExtraDeps.emplace_back(A->getValue(), EDK_DepFileEntry);
2416
2417 // Only the -fmodule-file=<file> form.
2418 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
2419 StringRef Val = A->getValue();
2420 if (!Val.contains('='))
2421 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_ModuleFile);
2422 }
2423
2424 // Check for invalid combinations of header-include-format
2425 // and header-include-filtering.
2426 if ((Opts.HeaderIncludeFormat == HIFMT_Textual &&
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
2437static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) {
2438 // Color diagnostics default to auto ("on" if terminal supports) in the driver
2439 // but default to off in cc1, needing an explicit OPT_fdiagnostics_color.
2440 // Support both clang's -f[no-]color-diagnostics and gcc's
2441 // -f[no-]diagnostics-colors[=never|always|auto].
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)) {
2450 ShowColors = Colors_On;
2451 } else if (O.matches(options::OPT_fno_color_diagnostics)) {
2452 ShowColors = Colors_Off;
2453 } else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
2454 StringRef Value(A->getValue());
2455 if (Value == "always")
2456 ShowColors = Colors_On;
2457 else if (Value == "never")
2458 ShowColors = Colors_Off;
2459 else if (Value == "auto")
2460 ShowColors = Colors_Auto;
2461 }
2462 }
2463 return ShowColors == Colors_On ||
2464 (ShowColors == Colors_Auto &&
2465 llvm::sys::Process::StandardErrHasColors());
2466}
2467
2468static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
2469 DiagnosticsEngine &Diags) {
2470 bool Success = true;
2471 for (const auto &Prefix : VerifyPrefixes) {
2472 // Every prefix must start with a letter and contain only alphanumeric
2473 // characters, hyphens, and underscores.
2474 auto BadChar = llvm::find_if(Prefix, [](char C) {
2475 return !isAlphanumeric(C) && C != '-' && C != '_';
2476 });
2477 if (BadChar != Prefix.end() || !isLetter(Prefix[0])) {
2478 Success = false;
2479 Diags.Report(diag::err_drv_invalid_value) << "-verify=" << Prefix;
2480 Diags.Report(diag::note_drv_verify_prefix_spelling);
2481 }
2482 }
2483 return Success;
2484}
2485
2487 ArgumentConsumer Consumer) {
2488 const FileSystemOptions &FileSystemOpts = Opts;
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
2496static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args,
2497 DiagnosticsEngine &Diags) {
2498 unsigned NumErrorsBefore = Diags.getNumErrors();
2499
2500 FileSystemOptions &FileSystemOpts = Opts;
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
2511 ArgumentConsumer Consumer) {
2512 const MigratorOptions &MigratorOpts = Opts;
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
2519static bool ParseMigratorArgs(MigratorOptions &Opts, const ArgList &Args,
2520 DiagnosticsEngine &Diags) {
2521 unsigned NumErrorsBefore = Diags.getNumErrors();
2522
2523 MigratorOptions &MigratorOpts = Opts;
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(
2534 const DiagnosticOptions &Opts, ArgumentConsumer Consumer,
2535 bool DefaultDiagColor) {
2536 const DiagnosticOptions *DiagnosticOpts = &Opts;
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
2542 if (!Opts.DiagnosticSerializationFile.empty())
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"))
2551 GenerateArg(Consumer, OPT_verify);
2552
2553 for (const auto &Prefix : Opts.VerifyPrefixes)
2554 if (Prefix != "expected")
2555 GenerateArg(Consumer, OPT_verify_EQ, Prefix);
2556
2557 DiagnosticLevelMask VIU = Opts.getVerifyIgnoreUnexpected();
2558 if (VIU == DiagnosticLevelMask::None) {
2559 // This is the default, don't generate anything.
2560 } else if (VIU == DiagnosticLevelMask::All) {
2561 GenerateArg(Consumer, OPT_verify_ignore_unexpected);
2562 } else {
2563 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Note) != 0)
2564 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "note");
2565 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Remark) != 0)
2566 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "remark");
2567 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Warning) != 0)
2568 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "warning");
2569 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Error) != 0)
2570 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "error");
2571 }
2572
2573 for (const auto &Warning : Opts.Warnings) {
2574 // This option is automatically generated from UndefPrefixes.
2575 if (Warning == "undef-prefix")
2576 continue;
2577 // This option is automatically generated from CheckConstexprFunctionBodies.
2578 if (Warning == "invalid-constexpr" || Warning == "no-invalid-constexpr")
2579 continue;
2580 Consumer(StringRef("-W") + Warning);
2581 }
2582
2583 for (const auto &Remark : Opts.Remarks) {
2584 // These arguments are generated from OptimizationRemark fields of
2585 // CodeGenOptions.
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
2595 if (!Opts.DiagnosticSuppressionMappingsFile.empty()) {
2596 GenerateArg(Consumer, OPT_warning_suppression_mappings_EQ,
2598 }
2599}
2600
2601std::unique_ptr<DiagnosticOptions>
2603 auto DiagOpts = std::make_unique<DiagnosticOptions>();
2604 unsigned MissingArgIndex, MissingArgCount;
2605 InputArgList Args = getDriverOptTable().ParseArgs(
2606 Argv.slice(1), MissingArgIndex, MissingArgCount);
2607
2608 bool ShowColors = true;
2609 if (std::optional<std::string> NoColor =
2610 llvm::sys::Process::GetEnv("NO_COLOR");
2611 NoColor && !NoColor->empty()) {
2612 // If the user set the NO_COLOR environment variable, we'll honor that
2613 // unless the command line overrides it.
2614 ShowColors = false;
2615 }
2616
2617 // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
2618 // Any errors that would be diagnosed here will also be diagnosed later,
2619 // when the DiagnosticsEngine actually exists.
2620 (void)ParseDiagnosticArgs(*DiagOpts, Args, /*Diags=*/nullptr, ShowColors);
2621 return DiagOpts;
2622}
2623
2624bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
2625 DiagnosticsEngine *Diags,
2626 bool DefaultDiagColor) {
2627 std::optional<DiagnosticsEngine> IgnoringDiags;
2628 if (!Diags) {
2629 IgnoringDiags.emplace(new DiagnosticIDs(), new DiagnosticOptions(),
2630 new IgnoringDiagConsumer());
2631 Diags = &*IgnoringDiags;
2632 }
2633
2634 unsigned NumErrorsBefore = Diags->getNumErrors();
2635
2636 // The key paths of diagnostic options defined in Options.td start with
2637 // "DiagnosticOpts->". Let's provide the expected variable name and type.
2638 DiagnosticOptions *DiagnosticOpts = &Opts;
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))
2649 Opts.DiagnosticSerializationFile = A->getValue();
2650 Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor);
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))
2655 Opts.VerifyPrefixes.push_back("expected");
2656 // Keep VerifyPrefixes in its original order for the sake of diagnostics, and
2657 // then sort it to prepare for fast lookup using std::binary_search.
2658 if (!checkVerifyPrefixes(Opts.VerifyPrefixes, *Diags))
2659 Opts.VerifyDiagnostics = false;
2660 else
2661 llvm::sort(Opts.VerifyPrefixes);
2664 "-verify-ignore-unexpected=",
2665 Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), *Diags, DiagMask);
2666 if (Args.hasArg(OPT_verify_ignore_unexpected))
2667 DiagMask = DiagnosticLevelMask::All;
2668 Opts.setVerifyIgnoreUnexpected(DiagMask);
2669 if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
2670 Diags->Report(diag::warn_ignoring_ftabstop_value)
2671 << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
2672 Opts.TabStop = DiagnosticOptions::DefaultTabStop;
2673 }
2674
2675 if (const Arg *A = Args.getLastArg(OPT_warning_suppression_mappings_EQ))
2676 Opts.DiagnosticSuppressionMappingsFile = A->getValue();
2677
2678 addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
2679 addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
2680
2681 return Diags->getNumErrors() == NumErrorsBefore;
2682}
2683
2684/// Parse the argument to the -ftest-module-file-extension
2685/// command-line argument.
2686///
2687/// \returns true on error, false on success.
2688static bool parseTestModuleFileExtensionArg(StringRef Arg,
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/// Return a table that associates command line option specifiers with the
2709/// frontend action. Note: The pair {frontend::PluginAction, OPT_plugin} is
2710/// intentionally missing, as this case is handled separately from other
2711/// frontend options.
2712static const auto &getFrontendActionTable() {
2713 static const std::pair<frontend::ActionKind, unsigned> Table[] = {
2714 {frontend::ASTDeclList, OPT_ast_list},
2715
2716 {frontend::ASTDump, OPT_ast_dump_all_EQ},
2717 {frontend::ASTDump, OPT_ast_dump_all},
2718 {frontend::ASTDump, OPT_ast_dump_EQ},
2719 {frontend::ASTDump, OPT_ast_dump},
2720 {frontend::ASTDump, OPT_ast_dump_lookups},
2721 {frontend::ASTDump, OPT_ast_dump_decl_types},
2722
2723 {frontend::ASTPrint, OPT_ast_print},
2724 {frontend::ASTView, OPT_ast_view},
2725 {frontend::DumpCompilerOptions, OPT_compiler_options_dump},
2726 {frontend::DumpRawTokens, OPT_dump_raw_tokens},
2727 {frontend::DumpTokens, OPT_dump_tokens},
2728 {frontend::EmitAssembly, OPT_S},
2729 {frontend::EmitBC, OPT_emit_llvm_bc},
2730 {frontend::EmitCIR, OPT_emit_cir},
2731 {frontend::EmitHTML, OPT_emit_html},
2732 {frontend::EmitLLVM, OPT_emit_llvm},
2733 {frontend::EmitLLVMOnly, OPT_emit_llvm_only},
2734 {frontend::EmitCodeGenOnly, OPT_emit_codegen_only},
2735 {frontend::EmitObj, OPT_emit_obj},
2736 {frontend::ExtractAPI, OPT_extract_api},
2737
2738 {frontend::FixIt, OPT_fixit_EQ},
2739 {frontend::FixIt, OPT_fixit},
2740
2741 {frontend::GenerateModule, OPT_emit_module},
2742 {frontend::GenerateModuleInterface, OPT_emit_module_interface},
2744 OPT_emit_reduced_module_interface},
2745 {frontend::GenerateHeaderUnit, OPT_emit_header_unit},
2746 {frontend::GeneratePCH, OPT_emit_pch},
2747 {frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs},
2748 {frontend::InitOnly, OPT_init_only},
2749 {frontend::ParseSyntaxOnly, OPT_fsyntax_only},
2750 {frontend::ModuleFileInfo, OPT_module_file_info},
2751 {frontend::VerifyPCH, OPT_verify_pch},
2752 {frontend::PrintPreamble, OPT_print_preamble},
2754 {frontend::TemplightDump, OPT_templight_dump},
2755 {frontend::RewriteMacros, OPT_rewrite_macros},
2756 {frontend::RewriteObjC, OPT_rewrite_objc},
2757 {frontend::RewriteTest, OPT_rewrite_test},
2758 {frontend::RunAnalysis, OPT_analyze},
2759 {frontend::MigrateSource, OPT_migrate},
2760 {frontend::RunPreprocessorOnly, OPT_Eonly},
2762 OPT_print_dependency_directives_minimized_source},
2763 };
2764
2765 return Table;
2766}
2767
2768/// Maps command line option to frontend action.
2769static std::optional<frontend::ActionKind>
2770getFrontendAction(OptSpecifier &Opt) {
2771 for (const auto &ActionOpt : getFrontendActionTable())
2772 if (ActionOpt.second == Opt.getID())
2773 return ActionOpt.first;
2774
2775 return std::nullopt;
2776}
2777
2778/// Maps frontend action to command line option.
2779static std::optional<OptSpecifier>
2781 for (const auto &ActionOpt : getFrontendActionTable())
2782 if (ActionOpt.first == ProgramAction)
2783 return OptSpecifier(ActionOpt.second);
2784
2785 return std::nullopt;
2786}
2787
2789 ArgumentConsumer Consumer, bool IsHeader) {
2790 const FrontendOptions &FrontendOpts = Opts;
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<OptSpecifier> ProgramActionOpt =
2798
2799 // Generating a simple flag covers most frontend actions.
2800 std::function<void()> GenerateProgramAction = [&]() {
2801 GenerateArg(Consumer, *ProgramActionOpt);
2802 };
2803
2804 if (!ProgramActionOpt) {
2805 // PluginAction is the only program action handled separately.
2806 assert(Opts.ProgramAction == frontend::PluginAction &&
2807 "Frontend action without option.");
2808 GenerateProgramAction = [&]() {
2809 GenerateArg(Consumer, OPT_plugin, Opts.ActionName);
2810 };
2811 }
2812
2813 // FIXME: Simplify the complex 'AST dump' command line.
2814 if (Opts.ProgramAction == frontend::ASTDump) {
2815 GenerateProgramAction = [&]() {
2816 // ASTDumpLookups, ASTDumpDeclTypes and ASTDumpFilter are generated via
2817 // marshalling infrastructure.
2818
2819 if (Opts.ASTDumpFormat != ADOF_Default) {
2820 StringRef Format;
2821 switch (Opts.ASTDumpFormat) {
2822 case ADOF_Default:
2823 llvm_unreachable("Default AST dump format.");
2824 case ADOF_JSON:
2825 Format = "json";
2826 break;
2827 }
2828
2829 if (Opts.ASTDumpAll)
2830 GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);
2831 if (Opts.ASTDumpDecls)
2832 GenerateArg(Consumer, OPT_ast_dump_EQ, Format);
2833 } else {
2834 if (Opts.ASTDumpAll)
2835 GenerateArg(Consumer, OPT_ast_dump_all);
2836 if (Opts.ASTDumpDecls)
2837 GenerateArg(Consumer, OPT_ast_dump);
2838 }
2839 };
2840 }
2841
2842 if (Opts.ProgramAction == frontend::FixIt && !Opts.FixItSuffix.empty()) {
2843 GenerateProgramAction = [&]() {
2844 GenerateArg(Consumer, OPT_fixit_EQ, Opts.FixItSuffix);
2845 };
2846 }
2847
2848 GenerateProgramAction();
2849
2850 for (const auto &PluginArgs : Opts.PluginArgs) {
2851 Option Opt = getDriverOptTable().getOption(OPT_plugin_arg);
2852 for (const auto &PluginArg : PluginArgs.second)
2853 denormalizeString(Consumer,
2854 Opt.getPrefix() + Opt.getName() + PluginArgs.first,
2855 Opt.getKind(), 0, PluginArg);
2856 }
2857
2858 for (const auto &Ext : Opts.ModuleFileExtensions)
2859 if (auto *TestExt = dyn_cast_or_null<TestModuleFileExtension>(Ext.get()))
2860 GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());
2861
2862 if (!Opts.CodeCompletionAt.FileName.empty())
2863 GenerateArg(Consumer, OPT_code_completion_at,
2864 Opts.CodeCompletionAt.ToString());
2865
2866 for (const auto &Plugin : Opts.Plugins)
2867 GenerateArg(Consumer, OPT_load, Plugin);
2868
2869 // ASTDumpDecls and ASTDumpAll already handled with ProgramAction.
2870
2871 for (const auto &ModuleFile : Opts.ModuleFiles)
2872 GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);
2873
2874 if (Opts.AuxTargetCPU)
2875 GenerateArg(Consumer, OPT_aux_target_cpu, *Opts.AuxTargetCPU);
2876
2877 if (Opts.AuxTargetFeatures)
2878 for (const auto &Feature : *Opts.AuxTargetFeatures)
2879 GenerateArg(Consumer, OPT_aux_target_feature, Feature);
2880
2881 {
2882 StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";
2883 StringRef ModuleMap =
2884 Opts.DashX.getFormat() == InputKind::ModuleMap ? "-module-map" : "";
2885 StringRef HeaderUnit = "";
2886 switch (Opts.DashX.getHeaderUnitKind()) {
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;
2902 switch (Opts.DashX.getLanguage()) {
2903 case Language::C:
2904 Lang = "c";
2905 break;
2906 case Language::OpenCL:
2907 Lang = "cl";
2908 break;
2910 Lang = "clcpp";
2911 break;
2912 case Language::CUDA:
2913 Lang = "cuda";
2914 break;
2915 case Language::HIP:
2916 Lang = "hip";
2917 break;
2918 case Language::CXX:
2919 Lang = "c++";
2920 break;
2921 case Language::ObjC:
2922 Lang = "objective-c";
2923 break;
2924 case Language::ObjCXX:
2925 Lang = "objective-c++";
2926 break;
2927 case Language::Asm:
2928 Lang = "assembler-with-cpp";
2929 break;
2930 case Language::Unknown:
2931 assert(Opts.DashX.getFormat() == InputKind::Precompiled &&
2932 "Generating -x argument for unknown language (not precompiled).");
2933 Lang = "ast";
2934 break;
2935 case Language::LLVM_IR:
2936 Lang = "ir";
2937 break;
2938 case Language::HLSL:
2939 Lang = "hlsl";
2940 break;
2941 case Language::CIR:
2942 Lang = "cir";
2943 break;
2944 }
2945
2946 GenerateArg(Consumer, OPT_x,
2947 Lang + HeaderUnit + Header + ModuleMap + Preprocessed);
2948 }
2949
2950 // OPT_INPUT has a unique class, generate it directly.
2951 for (const auto &Input : Opts.Inputs)
2952 Consumer(Input.getFile());
2953}
2954
2955static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
2956 DiagnosticsEngine &Diags, bool &IsHeaderFile) {
2957 unsigned NumErrorsBefore = Diags.getNumErrors();
2958
2959 FrontendOptions &FrontendOpts = Opts;
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::optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt);
2970 assert(ProgramAction && "Option specifier not in Action_Group.");
2971
2972 if (ProgramAction == frontend::ASTDump &&
2973 (Opt == OPT_ast_dump_all_EQ || Opt == OPT_ast_dump_EQ)) {
2974 unsigned Val = llvm::StringSwitch<unsigned>(A->getValue())
2975 .CaseLower("default", ADOF_Default)
2976 .CaseLower("json", ADOF_JSON)
2977 .Default(std::numeric_limits<unsigned>::max());
2978
2979 if (Val != std::numeric_limits<unsigned>::max())
2980 Opts.ASTDumpFormat = static_cast<ASTDumpOutputFormat>(Val);
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)
2989 Opts.FixItSuffix = A->getValue();
2990
2991 if (ProgramAction == frontend::GenerateInterfaceStubs) {
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;
3006 ProgramAction = frontend::ParseSyntaxOnly;
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;
3014 ProgramAction = frontend::ParseSyntaxOnly;
3015 }
3016 }
3017
3018 Opts.ProgramAction = *ProgramAction;
3019
3020 // Catch common mistakes when multiple actions are specified for cc1 (e.g.
3021 // -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to
3022 // support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name
3023 // X ACTION), we suppress the error when the two actions are separated by
3024 // -main-file-name.
3025 //
3026 // As an exception, accept composable -ast-dump*.
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));
3048 Opts.ActionName = A->getValue();
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;
3060 if (parseTestModuleFileExtensionArg(Arg, BlockName, MajorVersion,
3061 MinorVersion, Hashed, UserInfo)) {
3062 Diags.Report(diag::err_test_module_file_extension_format) << Arg;
3063
3064 continue;
3065 }
3066
3067 // Add the testing module file extension.
3068 Opts.ModuleFileExtensions.push_back(
3069 std::make_shared<TestModuleFileExtension>(
3070 BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
3071 }
3072
3073 if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
3074 Opts.CodeCompletionAt =
3075 ParsedSourceLocation::FromString(A->getValue());
3076 if (Opts.CodeCompletionAt.FileName.empty())
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 // Only the -fmodule-file=<file> form.
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))
3095 Opts.UseClangIRPipeline = true;
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 // Parse suffixes:
3113 // '<lang>(-[{header-unit,user,system}-]header|[-module-map][-cpp-output])'.
3114 // FIXME: Supporting '<lang>-header-cpp-output' would be useful.
3115 bool Preprocessed = XValue.consume_back("-cpp-output");
3116 bool ModuleMap = XValue.consume_back("-module-map");
3117 // Detect and consume the header indicator.
3118 bool IsHeader =
3119 XValue != "precompiled-header" && XValue.consume_back("-header");
3120
3121 // If we have c++-{user,system}-header, that indicates a header unit input
3122 // likewise, if the user put -fmodule-header together with a header with an
3123 // absolute path (header-unit-header).
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 // The value set by this processing is an un-preprocessed source which is
3135 // not intended to be a module map or header unit.
3136 IsHeaderFile = IsHeader && !Preprocessed && !ModuleMap &&
3138
3139 // Principal languages.
3140 DashX = llvm::StringSwitch<InputKind>(XValue)
3141 .Case("c", Language::C)
3142 .Case("cl", Language::OpenCL)
3143 .Case("clcpp", Language::OpenCLCXX)
3144 .Case("cuda", Language::CUDA)
3145 .Case("hip", Language::HIP)
3146 .Case("c++", Language::CXX)
3147 .Case("objective-c", Language::ObjC)
3148 .Case("objective-c++", Language::ObjCXX)
3149 .Case("hlsl", Language::HLSL)
3150 .Default(Language::Unknown);
3151
3152 // "objc[++]-cpp-output" is an acceptable synonym for
3153 // "objective-c[++]-cpp-output".
3154 if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap &&
3156 DashX = llvm::StringSwitch<InputKind>(XValue)
3157 .Case("objc", Language::ObjC)
3158 .Case("objc++", Language::ObjCXX)
3159 .Default(Language::Unknown);
3160
3161 // Some special cases cannot be combined with suffixes.
3162 if (DashX.isUnknown() && !Preprocessed && !IsHeaderFile && !ModuleMap &&
3164 DashX = llvm::StringSwitch<InputKind>(XValue)
3165 .Case("cpp-output", InputKind(Language::C).getPreprocessed())
3166 .Case("assembler-with-cpp", Language::Asm)
3167 .Cases("ast", "pcm", "precompiled-header",
3169 .Case("ir", Language::LLVM_IR)
3170 .Case("cir", Language::CIR)
3171 .Default(Language::Unknown);
3172
3173 if (DashX.isUnknown())
3174 Diags.Report(diag::err_drv_invalid_value)
3175 << A->getAsString(Args) << A->getValue();
3176
3177 if (Preprocessed)
3178 DashX = DashX.getPreprocessed();
3179 // A regular header is considered mutually exclusive with a header unit.
3180 if (HUK != InputKind::HeaderUnit_None) {
3181 DashX = DashX.withHeaderUnit(HUK);
3182 IsHeaderFile = true;
3183 } else if (IsHeaderFile)
3184 DashX = DashX.getHeader();
3185 if (ModuleMap)
3186 DashX = DashX.withFormat(InputKind::ModuleMap);
3187 }
3188
3189 // '-' is the default input if none is given.
3190 std::vector<std::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) {
3200 InputKind IK = DashX;
3201 if (IK.isUnknown()) {
3203 StringRef(Inputs[i]).rsplit('.').second);
3204 // FIXME: Warn on this?
3205 if (IK.isUnknown())
3206 IK = Language::C;
3207 // FIXME: Remove this hack.
3208 if (i == 0)
3209 DashX = IK;
3210 }
3211
3212 bool IsSystem = false;
3213
3214 // The -emit-module action implicitly takes a module map.
3216 IK.getFormat() == InputKind::Source) {
3218 IsSystem = Opts.IsSystemModule;
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
3229std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
3230 void *MainAddr) {
3231 std::string ClangExecutable =
3232 llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
3233 return Driver::GetResourcesPath(ClangExecutable);
3234}
3235
3237 ArgumentConsumer Consumer) {
3238 const HeaderSearchOptions *HeaderSearchOpts = &Opts;
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
3244 if (Opts.UseLibcxx)
3245 GenerateArg(Consumer, OPT_stdlib_EQ, "libc++");
3246
3247 if (!Opts.ModuleCachePath.empty())
3248 GenerateArg(Consumer, OPT_fmodules_cache_path, Opts.ModuleCachePath);
3249
3250 for (const auto &File : Opts.PrebuiltModuleFiles)
3251 GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second);
3252
3253 for (const auto &Path : Opts.PrebuiltModulePaths)
3254 GenerateArg(Consumer, OPT_fprebuilt_module_path, Path);
3255
3256 for (const auto &Macro : Opts.ModulesIgnoreMacros)
3257 GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val());
3258
3259 auto Matches = [](const HeaderSearchOptions::Entry &Entry,
3261 std::optional<bool> IsFramework,
3262 std::optional<bool> IgnoreSysRoot) {
3263 return llvm::is_contained(Groups, Entry.Group) &&
3264 (!IsFramework || (Entry.IsFramework == *IsFramework)) &&
3265 (!IgnoreSysRoot || (Entry.IgnoreSysRoot == *IgnoreSysRoot));
3266 };
3267
3268 auto It = Opts.UserEntries.begin();
3269 auto End = Opts.UserEntries.end();
3270
3271 // Add -I... and -F... options in order.
3272 for (; It < End && Matches(*It, {frontend::Angled}, std::nullopt, true);
3273 ++It) {
3274 OptSpecifier Opt = [It, Matches]() {
3275 if (Matches(*It, frontend::Angled, true, true))
3276 return OPT_F;
3277 if (Matches(*It, frontend::Angled, false, true))
3278 return OPT_I;
3279 llvm_unreachable("Unexpected HeaderSearchOptions::Entry.");
3280 }();
3281
3282 GenerateArg(Consumer, Opt, It->Path);
3283 }
3284
3285 // Note: some paths that came from "[-iprefix=xx] -iwithprefixbefore=yy" may
3286 // have already been generated as "-I[xx]yy". If that's the case, their
3287 // position on command line was such that this has no semantic impact on
3288 // include paths.
3289 for (; It < End &&
3290 Matches(*It, {frontend::After, frontend::Angled}, false, true);
3291 ++It) {
3292 OptSpecifier Opt =
3293 It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;
3294 GenerateArg(Consumer, Opt, It->Path);
3295 }
3296
3297 // Note: Some paths that came from "-idirafter=xxyy" may have already been
3298 // generated as "-iwithprefix=xxyy". If that's the case, their position on
3299 // command line was such that this has no semantic impact on include paths.
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 // Add the paths for the various language specific isystem flags.
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);
3318 for (; It < End && Matches(*It, {frontend::ObjCSystem}, false, true); ++It)
3319 GenerateArg(Consumer, OPT_objc_isystem, It->Path);
3320 for (; It < End && Matches(*It, {frontend::ObjCXXSystem}, false, true); ++It)
3321 GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);
3322
3323 // Add the internal paths from a driver that detects standard include paths.
3324 // Note: Some paths that came from "-internal-isystem" arguments may have
3325 // already been generated as "-isystem". If that's the case, their position on
3326 // command line was such that this has no semantic impact on include paths.
3327 for (; It < End &&
3328 Matches(*It, {frontend::System, frontend::ExternCSystem}, false, true);
3329 ++It) {
3330 OptSpecifier Opt = It->Group == frontend::System
3331 ? OPT_internal_isystem
3332 : OPT_internal_externc_isystem;
3333 GenerateArg(Consumer, Opt, It->Path);
3334 }
3335
3336 assert(It == End && "Unhandled HeaderSearchOption::Entry.");
3337
3338 // Add the path prefixes which are implicitly treated as being system headers.
3339 for (const auto &P : Opts.SystemHeaderPrefixes) {
3340 OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
3341 : OPT_no_system_header_prefix;
3342 GenerateArg(Consumer, Opt, P.Prefix);
3343 }
3344
3345 for (const std::string &F : Opts.VFSOverlayFiles)
3346 GenerateArg(Consumer, OPT_ivfsoverlay, F);
3347}
3348
3349static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
3350 DiagnosticsEngine &Diags,
3351 const std::string &WorkingDir) {
3352 unsigned NumErrorsBefore = Diags.getNumErrors();
3353
3354 HeaderSearchOptions *HeaderSearchOpts = &Opts;
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 // Canonicalize -fmodules-cache-path before storing it.
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);
3373 Opts.ModuleCachePath = std::string(P);
3374
3375 // Only the -fmodule-file=<name>=<file> form.
3376 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3377 StringRef Val = A->getValue();
3378 if (Val.contains('=')) {
3379 auto Split = Val.split('=');
3380 Opts.PrebuiltModuleFiles.insert_or_assign(
3381 std::string(Split.first), std::string(Split.second));
3382 }
3383 }
3384 for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
3385 Opts.AddPrebuiltModulePath(A->getValue());
3386
3387 for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
3388 StringRef MacroDef = A->getValue();
3389 Opts.ModulesIgnoreMacros.insert(
3390 llvm::CachedHashString(MacroDef.split('=').first));
3391 }
3392
3393 // Add -I... and -F... options in order.
3394 bool IsSysrootSpecified =
3395 Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
3396
3397 // Expand a leading `=` to the sysroot if one was passed (and it's not a
3398 // framework flag).
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] == '=') {
3404 SmallString<32> Buffer;
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);
3414 Opts.AddPath(PrefixHeaderPath(A, IsFramework), frontend::Angled,
3415 IsFramework, /*IgnoreSysroot=*/true);
3416 }
3417
3418 // Add -iprefix/-iwithprefix/-iwithprefixbefore options.
3419 StringRef Prefix = ""; // FIXME: This isn't the correct default 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))
3425 Opts.AddPath(Prefix.str() + A->getValue(), frontend::After, false, true);
3426 else
3427 Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
3428 }
3429
3430 for (const auto *A : Args.filtered(OPT_idirafter))
3431 Opts.AddPath(PrefixHeaderPath(A), frontend::After, false, true);
3432 for (const auto *A : Args.filtered(OPT_iquote))
3433 Opts.AddPath(PrefixHeaderPath(A), frontend::Quoted, false, true);
3434
3435 for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) {
3436 if (A->getOption().matches(OPT_iwithsysroot)) {
3437 Opts.AddPath(A->getValue(), frontend::System, false,
3438 /*IgnoreSysRoot=*/false);
3439 continue;
3440 }
3441 Opts.AddPath(PrefixHeaderPath(A), frontend::System, false, true);
3442 }
3443 for (const auto *A : Args.filtered(OPT_iframework))
3444 Opts.AddPath(A->getValue(), frontend::System, true, true);
3445 for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
3446 Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
3447 /*IgnoreSysRoot=*/false);
3448
3449 // Add the paths for the various language specific isystem flags.
3450 for (const auto *A : Args.filtered(OPT_c_isystem))
3451 Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
3452 for (const auto *A : Args.filtered(OPT_cxx_isystem))
3453 Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
3454 for (const auto *A : Args.filtered(OPT_objc_isystem))
3455 Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
3456 for (const auto *A : Args.filtered(OPT_objcxx_isystem))
3457 Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
3458
3459 // Add the internal paths from a driver that detects standard include paths.
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 // Add the path prefixes which are implicitly treated as being system headers.
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))
3475 Opts.AddVFSOverlayFile(A->getValue());
3476
3477 return Diags.getNumErrors() == NumErrorsBefore;
3478}
3479
3481 ArgumentConsumer Consumer) {
3482 if (!Opts.SwiftVersion.empty())
3483 GenerateArg(Consumer, OPT_fapinotes_swift_version,
3484 Opts.SwiftVersion.getAsString());
3485
3486 for (const auto &Path : Opts.ModuleSearchPaths)
3487 GenerateArg(Consumer, OPT_iapinotes_modules, Path);
3488}
3489
3490static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
3491 DiagnosticsEngine &diags) {
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))
3498 Opts.ModuleSearchPaths.push_back(A->getValue());
3499}
3500
3501static void GeneratePointerAuthArgs(const LangOptions &Opts,
3502 ArgumentConsumer Consumer) {
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
3531static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
3532 DiagnosticsEngine &Diags) {
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/// Check if input file kind and language standard are compatible.
3556 const LangStandard &S) {
3557 switch (IK.getLanguage()) {
3558 case Language::Unknown:
3559 case Language::LLVM_IR:
3560 case Language::CIR:
3561 llvm_unreachable("should not parse language flags for this input");
3562
3563 case Language::C:
3564 case Language::ObjC:
3565 return S.getLanguage() == Language::C;
3566
3567 case Language::OpenCL:
3568 return S.getLanguage() == Language::OpenCL ||
3569 S.getLanguage() == Language::OpenCLCXX;
3570
3572 return S.getLanguage() == Language::OpenCLCXX;
3573
3574 case Language::CXX:
3575 case Language::ObjCXX:
3576 return S.getLanguage() == Language::CXX;
3577
3578 case Language::CUDA:
3579 // FIXME: What -std= values should be permitted for CUDA compilations?
3580 return S.getLanguage() == Language::CUDA ||
3581 S.getLanguage() == Language::CXX;
3582
3583 case Language::HIP:
3584 return S.getLanguage() == Language::CXX || S.getLanguage() == Language::HIP;
3585
3586 case Language::Asm:
3587 // Accept (and ignore) all -std= values.
3588 // FIXME: The -std= value is not ignored; it affects the tokenization
3589 // and preprocessing rules if we're preprocessing this asm input.
3590 return true;
3591
3592 case Language::HLSL:
3593 return S.getLanguage() == Language::HLSL;
3594 }
3595
3596 llvm_unreachable("unexpected input language");
3597}
3598
3599/// Get language name for given input kind.
3600static StringRef GetInputKindName(InputKind IK) {
3601 switch (IK.getLanguage()) {
3602 case Language::C:
3603 return "C";
3604 case Language::ObjC:
3605 return "Objective-C";
3606 case Language::CXX:
3607 return "C++";
3608 case Language::ObjCXX:
3609 return "Objective-C++";
3610 case Language::OpenCL:
3611 return "OpenCL";
3613 return "C++ for OpenCL";
3614 case Language::CUDA:
3615 return "CUDA";
3616 case Language::HIP:
3617 return "HIP";
3618
3619 case Language::Asm:
3620 return "Asm";
3621 case Language::LLVM_IR:
3622 return "LLVM IR";
3623 case Language::CIR:
3624 return "Clang IR";
3625
3626 case Language::HLSL:
3627 return "HLSL";
3628
3629 case Language::Unknown:
3630 break;
3631 }
3632 llvm_unreachable("unknown input language");
3633}
3634
3635void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
3636 ArgumentConsumer Consumer,
3637 const llvm::Triple &T,
3638 InputKind IK) {
3639 if (IK.getFormat() == InputKind::Precompiled ||
3641 IK.getLanguage() == Language::CIR) {
3642 if (Opts.ObjCAutoRefCount)
3643 GenerateArg(Consumer, OPT_fobjc_arc);
3644 if (Opts.PICLevel != 0)
3645 GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));
3646 if (Opts.PIE)
3647 GenerateArg(Consumer, OPT_pic_is_pie);
3648 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3649 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3650
3651 return;
3652 }
3653
3654 OptSpecifier StdOpt;
3655 switch (Opts.LangStd) {
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
3671 GenerateArg(Consumer, StdOpt, LangStandard.getName());
3672
3673 if (Opts.IncludeDefaultHeader)
3674 GenerateArg(Consumer, OPT_finclude_default_header);
3675 if (Opts.DeclareOpenCLBuiltins)
3676 GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);
3677
3678 const LangOptions *LangOpts = &Opts;
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 // The '-fcf-protection=' option is generated by CodeGenOpts generator.
3686
3687 if (Opts.ObjC) {
3688 GenerateArg(Consumer, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString());
3689
3690 if (Opts.GC == LangOptions::GCOnly)
3691 GenerateArg(Consumer, OPT_fobjc_gc_only);
3692 else if (Opts.GC == LangOptions::HybridGC)
3693 GenerateArg(Consumer, OPT_fobjc_gc);
3694 else if (Opts.ObjCAutoRefCount == 1)
3695 GenerateArg(Consumer, OPT_fobjc_arc);
3696
3697 if (Opts.ObjCWeakRuntime)
3698 GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);
3699
3700 if (Opts.ObjCWeak)
3701 GenerateArg(Consumer, OPT_fobjc_weak);
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
3718 if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) {
3719 GenerateArg(Consumer, OPT_ftrapv);
3720 GenerateArg(Consumer, OPT_ftrapv_handler, Opts.OverflowHandler);
3721 } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
3722 GenerateArg(Consumer, OPT_fwrapv);
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)
3739 GenerateArg(Consumer, OPT_ftrigraphs);
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))
3748 GenerateArg(Consumer, OPT_fblocks);
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)
3756 GenerateArg(Consumer, OPT_fno_builtin);
3757
3758 if (!Opts.NoBuiltin)
3759 for (const auto &Func : Opts.NoBuiltinFuncs)
3760 GenerateArg(Consumer, OPT_fno_builtin_, Func);
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 // Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
3770
3771 // OpenMP was requested via '-fopenmp', not implied by '-fopenmp-simd' or
3772 // '-fopenmp-targets='.
3773 if (Opts.OpenMP && !Opts.OpenMPSimd) {
3774 GenerateArg(Consumer, OPT_fopenmp);
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
3818 if (!Opts.OMPTargetTriples.empty()) {
3819 std::string Targets;
3820 llvm::raw_string_ostream OS(Targets);
3821 llvm::interleave(
3822 Opts.OMPTargetTriples, OS,
3823 [&OS](const llvm::Triple &T) { OS << T.str(); }, ",");
3824 GenerateArg(Consumer, OPT_fopenmp_targets_EQ, Targets);
3825 }
3826
3827 if (!Opts.OMPHostIRFile.empty())
3828 GenerateArg(Consumer, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile);
3829
3830 if (Opts.OpenMPCUDAMode)
3831 GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
3832
3833 if (Opts.OpenACC) {
3834 GenerateArg(Consumer, OPT_fopenacc);
3835 if (!Opts.OpenACCMacroOverride.empty())
3836 GenerateArg(Consumer, OPT_openacc_macro_override,
3838 }
3839
3840 // The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
3841 // generated from CodeGenOptions.
3842
3843 if (Opts.DefaultFPContractMode == LangOptions::FPM_Fast)
3844 GenerateArg(Consumer, OPT_ffp_contract, "fast");
3845 else if (Opts.DefaultFPContractMode == LangOptions::FPM_On)
3846 GenerateArg(Consumer, OPT_ffp_contract, "on");
3847 else if (Opts.DefaultFPContractMode == LangOptions::FPM_Off)
3848 GenerateArg(Consumer, OPT_ffp_contract, "off");
3849 else if (Opts.DefaultFPContractMode == LangOptions::FPM_FastHonorPragmas)
3850 GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas");
3851
3852 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3853 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3854
3855 // Conflating '-fsanitize-system-ignorelist' and '-fsanitize-ignorelist'.
3856 for (const std::string &F : Opts.NoSanitizeFiles)
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
3911 if (Opts.CXXABI)
3912 GenerateArg(Consumer, OPT_fcxx_abi_EQ,
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
3920 if (Opts.UseTargetPathSeparator)
3921 GenerateArg(Consumer, OPT_ffile_reproducible);
3922 else
3923 GenerateArg(Consumer, OPT_fno_file_reproducible);
3924
3925 for (const auto &MP : Opts.MacroPrefixMap)
3926 GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second);
3927
3928 if (!Opts.RandstructSeed.empty())
3929 GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed);
3930}
3931
3932bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
3933 InputKind IK, const llvm::Triple &T,
3934 std::vector<std::string> &Includes,
3935 DiagnosticsEngine &Diags) {
3936 unsigned NumErrorsBefore = Diags.getNumErrors();
3937
3938 if (IK.getFormat() == InputKind::Precompiled ||
3940 IK.getLanguage() == Language::CIR) {
3941 // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
3942 // PassManager in BackendUtil.cpp. They need to be initialized no matter
3943 // what the input type is.
3944 if (Args.hasArg(OPT_fobjc_arc))
3945 Opts.ObjCAutoRefCount = 1;
3946 // PICLevel and PIELevel are needed during code generation and this should
3947 // be set regardless of the input type.
3948 Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
3949 Opts.PIE = Args.hasArg(OPT_pic_is_pie);
3950 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
3951 Diags, Opts.Sanitize);
3952
3953 return Diags.getNumErrors() == NumErrorsBefore;
3954 }
3955
3956 // Other LangOpts are only initialized when the input is not AST or LLVM IR.
3957 // FIXME: Should we really be parsing this for an Language::Asm input?
3958
3959 // FIXME: Cleanup per-file based stuff.
3961 if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
3962 LangStd = LangStandard::getLangKind(A->getValue());
3963 if (LangStd == LangStandard::lang_unspecified) {
3964 Diags.Report(diag::err_drv_invalid_value)
3965 << A->getAsString(Args) << A->getValue();
3966 // Report supported standards with short description.
3967 for (unsigned KindValue = 0;
3968 KindValue != LangStandard::lang_unspecified;
3969 ++KindValue) {
3971 static_cast<LangStandard::Kind>(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 // Valid standard, check to make sure language and standard are
3991 // compatible.
3994 Diags.Report(diag::err_drv_argument_not_allowed_with)
3995 << A->getAsString(Args) << GetInputKindName(IK);
3996 }
3997 }
3998 }
3999
4000 // -cl-std only applies for OpenCL language standards.
4001 // Override the -std option in this case.
4002 if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
4003 LangStandard::Kind OpenCLLangStd
4004 = llvm::StringSwitch<LangStandard::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
4016 if (OpenCLLangStd == LangStandard::lang_unspecified) {
4017 Diags.Report(diag::err_drv_invalid_value)
4018 << A->getAsString(Args) << A->getValue();
4019 }
4020 else
4021 LangStd = OpenCLLangStd;
4022 }
4023
4024 // These need to be parsed now. They are used to set OpenCL defaults.
4025 Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
4026 Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
4027
4028 LangOptions::setLangDefaults(Opts, IK.getLanguage(), T, Includes, LangStd);
4029
4030 // The key paths of codegen options defined in Options.td start with
4031 // "LangOpts->". Let's provide the expected variable name and type.
4032 LangOptions *LangOpts = &Opts;
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<CFBranchLabelSchemeKind>(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 // If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to
4061 // provide -sycl-std=, we want to default it to whatever the default SYCL
4062 // version is. I could not find a way to express this with the options
4063 // tablegen because we still want this value to be SYCL_None when the user
4064 // is not in device or host mode.
4065 Opts.setSYCLVersion(LangOptions::SYCL_Default);
4066 }
4067
4068 if (Opts.ObjC) {
4069 if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
4070 StringRef value = arg->getValue();
4071 if (Opts.ObjCRuntime.tryParse(value))
4072 Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
4073 }
4074
4075 if (Args.hasArg(OPT_fobjc_gc_only))
4076 Opts.setGC(LangOptions::GCOnly);
4077 else if (Args.hasArg(OPT_fobjc_gc))
4078 Opts.setGC(LangOptions::HybridGC);
4079 else if (Args.hasArg(OPT_fobjc_arc)) {
4080 Opts.ObjCAutoRefCount = 1;
4081 if (!Opts.ObjCRuntime.allowsARC())
4082 Diags.Report(diag::err_arc_unsupported_on_runtime);
4083 }
4084
4085 // ObjCWeakRuntime tracks whether the runtime supports __weak, not
4086 // whether the feature is actually enabled. This is predominantly
4087 // determined by -fobjc-runtime, but we allow it to be overridden
4088 // from the command line for testing purposes.
4089 if (Args.hasArg(OPT_fobjc_runtime_has_weak))
4090 Opts.ObjCWeakRuntime = 1;
4091 else
4092 Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();
4093
4094 // ObjCWeak determines whether __weak is actually enabled.
4095 // Note that we allow -fno-objc-weak to disable this even in ARC mode.
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);
4099 } else if (Opts.getGC() != LangOptions::NonGC) {
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 // Check that the version has 1 to 3 components and the minor and patch
4117 // versions fit in two decimal digits.
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)) {
4134 Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
4135 // Set the handler, if one is specified.
4136 Opts.OverflowHandler =
4137 std::string(Args.getLastArgValue(OPT_ftrapv_handler));
4138 }
4139 else if (Args.hasArg(OPT_fwrapv))
4140 Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
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 // Mimicking gcc's behavior, trigraphs are only enabled if -trigraphs
4154 // is specified, or -std is set to a conforming mode.
4155 // Trigraphs are disabled by default in C++17 and C23 onwards.
4156 // For z/OS, trigraphs are enabled by default (without regard to the above).
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)
4190 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4191
4192 llvm::sort(Opts.ModuleFeatures);
4193
4194 // -mrtd option
4195 if (Arg *A = Args.getLastArg(OPT_mrtd)) {
4196 if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
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:
4202 Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
4203 break;
4204 case llvm::Triple::m68k:
4205 Opts.setDefaultCallingConv(LangOptions::DCC_RtdCall);
4206 break;
4207 default:
4208 Diags.Report(diag::err_drv_argument_not_allowed_with)
4209 << A->getSpelling() << T.getTriple();
4210 }
4211 }
4212 }
4213
4214 // Check if -fopenmp is specified and set default version to 5.0.
4215 Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;
4216 // Check if -fopenmp-simd is specified.
4217 bool IsSimdSpecified =
4218 Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
4219 /*Default=*/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) {
4231 if (int Version = getLastArgIntValue(
4232 Args, OPT_fopenmp_version_EQ,
4233 (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))
4234 Opts.OpenMP = Version;
4235 // Provide diagnostic when a given target is not expected to be an OpenMP
4236 // device or host.
4237 if (!Opts.OpenMPIsTargetDevice) {
4238 switch (T.getArch()) {
4239 default:
4240 break;
4241 // Add unsupported host targets here:
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 // Set the flag to prevent the implementation from emitting device exception
4251 // handling code for those requiring so.
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 =
4260 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_number_of_sm_EQ,
4261 Opts.OpenMPCUDANumSMs, Diags);
4262 Opts.OpenMPCUDABlocksPerSM =
4263 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,
4264 Opts.OpenMPCUDABlocksPerSM, Diags);
4265 Opts.OpenMPCUDAReductionBufNum = getLastArgIntValue(
4266 Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
4267 Opts.OpenMPCUDAReductionBufNum, Diags);
4268 }
4269
4270 // Set the value of the debugging flag used in the new offloading device RTL.
4271 // Set either by a specific value or to a default if not specified.
4272 if (Opts.OpenMPIsTargetDevice && (Args.hasArg(OPT_fopenmp_target_debug) ||
4273 Args.hasArg(OPT_fopenmp_target_debug_EQ))) {
4274 Opts.OpenMPTargetDebug = getLastArgIntValue(
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 // Get the OpenMP target triples if any.
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
4317 Opts.OMPTargetTriples.push_back(TT);
4318 }
4319 }
4320
4321 // Get OpenMP host file path if any and report if a non existent file is
4322 // found
4323 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) {
4324 Opts.OMPHostIRFile = A->getValue();
4325 if (!llvm::sys::fs::exists(Opts.OMPHostIRFile))
4326 Diags.Report(diag::err_drv_omp_host_ir_file_not_found)
4327 << Opts.OMPHostIRFile;
4328 }
4329
4330 // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options
4331 Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice &&
4332 (T.isNVPTX() || T.isAMDGCN()) &&
4333 Args.hasArg(options::OPT_fopenmp_cuda_mode);
4334
4335 // OpenACC Configuration.
4336 if (Args.hasArg(options::OPT_fopenacc)) {
4337 Opts.OpenACC = true;
4338
4339 if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override))
4340 Opts.OpenACCMacroOverride = A->getValue();
4341 }
4342
4343 // FIXME: Eliminate this dependency.
4344 unsigned Opt = getOptimizationLevel(Args, IK, Diags),
4345 OptSize = getOptimizationLevelSize(Args);
4346 Opts.Optimize = Opt != 0;
4347 Opts.OptimizeSize = OptSize != 0;
4348
4349 // This is the __NO_INLINE__ define, which just depends on things like the
4350 // optimization level and -fno-inline, not actually whether the backend has
4351 // inlining enabled.
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")
4362 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4363 else if (Val == "on")
4364 Opts.setDefaultFPContractMode(LangOptions::FPM_On);
4365 else if (Val == "off")
4366 Opts.setDefaultFPContractMode(LangOptions::FPM_Off);
4367 else if (Val == "fast-honor-pragmas")
4368 Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
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<unsigned>(A->getValue(i))
4378 .Case("none", LangOptionsBase::None)
4379 .Case("all", LangOptionsBase::All)
4380 .Case("add-unsigned-overflow-test",
4382 .Case("add-signed-overflow-test",
4384 .Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst)
4385 .Case("unsigned-post-decr-while",
4387 .Default(0);
4388 }
4389 }
4390
4391 // Parse -fsanitize= arguments.
4392 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
4393 Diags, Opts.Sanitize);
4394 Opts.NoSanitizeFiles = Args.getAllArgValues(OPT_fsanitize_ignorelist_EQ);
4395 std::vector<std::string> systemIgnorelists =
4396 Args.getAllArgValues(OPT_fsanitize_system_ignorelist_EQ);
4397 Opts.NoSanitizeFiles.insert(Opts.NoSanitizeFiles.end(),
4398 systemIgnorelists.begin(),
4399 systemIgnorelists.end());
4400
4401 if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
4402 Opts.setClangABICompat(LangOptions::ClangABI::Latest);
4403
4404 StringRef Ver = A->getValue();
4405 std::pair<StringRef, StringRef> VerParts = Ver.split('.');
4406 unsigned Major, Minor = 0;
4407
4408 // Check the version number is valid: either 3.x (0 <= x <= 9) or
4409 // y or y.0 (4 <= y <= current version).
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 // Got a valid version number.
4418 if (Major == 3 && Minor <= 8)
4419 Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8);
4420 else if (Major <= 4)
4421 Opts.setClangABICompat(LangOptions::ClangABI::Ver4);
4422 else if (Major <= 6)
4423 Opts.setClangABICompat(LangOptions::ClangABI::Ver6);
4424 else if (Major <= 7)
4425 Opts.setClangABICompat(LangOptions::ClangABI::Ver7);
4426 else if (Major <= 9)
4427 Opts.setClangABICompat(LangOptions::ClangABI::Ver9);
4428 else if (Major <= 11)
4429 Opts.setClangABICompat(LangOptions::ClangABI::Ver11);
4430 else if (Major <= 12)
4431 Opts.setClangABICompat(LangOptions::ClangABI::Ver12);
4432 else if (Major <= 14)
4433 Opts.setClangABICompat(LangOptions::ClangABI::Ver14);
4434 else if (Major <= 15)
4435 Opts.setClangABICompat(LangOptions::ClangABI::Ver15);
4436 else if (Major <= 17)
4437 Opts.setClangABICompat(LangOptions::ClangABI::Ver17);
4438 else if (Major <= 18)
4439 Opts.setClangABICompat(LangOptions::ClangABI::Ver18);
4440 else if (Major <= 19)
4441 Opts.setClangABICompat(LangOptions::ClangABI::Ver19);
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 // The value can be empty, which indicates the system default should be used.
4481 StringRef CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);
4482 if (!CXXABI.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
4490 Opts.CXXABI = Kind;
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 // RTTI is on by default.
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('=');
4509 Opts.MacroPrefixMap.insert(
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 // Error if -mvscale-min is unbounded.
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
4533 std::getline(SeedFile, Opts.RandstructSeed);
4534 }
4535
4536 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
4537 Opts.RandstructSeed = A->getValue(0);
4538
4539 // Validate options for HLSL
4540 if (Opts.HLSL) {
4541 // TODO: Revisit restricting SPIR-V to logical once we've figured out how to
4542 // handle PhysicalStorageBuffer64 memory model
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)
4554 << ShaderStage << Environment << T.str();
4555 } else if (!T.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 (!T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
4562 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4563 << ShaderModel << T.getOSName() << T.str();
4564 }
4565 // Validate that if fnative-half-type is given, that
4566 // the language standard is at least hlsl2018, and that
4567 // the target shader model is at least 6.2.
4568 if (Args.getLastArg(OPT_fnative_half_type)) {
4569 const LangStandard &Std =
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 (!T.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)) {
4583 const LangStandard &Std =
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) {
4596 const LangStandard &Requested =
4598 const LangStandard &Recommended =
4599 LangStandard::getLangStandardForKind(LangStandard::lang_hlsl202x);
4600 Diags.Report(diag::warn_hlsl_langstd_minimal)
4601 << Requested.getName() << Recommended.getName();
4602 }
4603 }
4604
4605 return Diags.getNumErrors() == NumErrorsBefore;
4606}
4607
4609 switch (Action) {
4611 case frontend::ASTDump:
4612 case frontend::ASTPrint:
4613 case frontend::ASTView:
4615 case frontend::EmitBC:
4616 case frontend::EmitCIR:
4617 case frontend::EmitHTML:
4618 case frontend::EmitLLVM:
4621 case frontend::EmitObj:
4623 case frontend::FixIt:
4639 return false;
4640
4644 case frontend::InitOnly:
4650 return true;
4651 }
4652 llvm_unreachable("invalid frontend action");
4653}
4654
4656 ArgumentConsumer Consumer,
4657 const LangOptions &LangOpts,
4658 const FrontendOptions &FrontendOpts,
4659 const CodeGenOptions &CodeGenOpts) {
4660 const PreprocessorOptions *PreprocessorOpts = &Opts;
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
4667 if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate)
4668 GenerateArg(Consumer, OPT_pch_through_hdrstop_use);
4669
4670 for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn)
4671 GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);
4672
4673 if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false))
4674 GenerateArg(Consumer, OPT_preamble_bytes_EQ,
4675 Twine(Opts.PrecompiledPreambleBytes.first) + "," +
4676 (Opts.PrecompiledPreambleBytes.second ? "1" : "0"));
4677
4678 for (const auto &M : Opts.Macros) {
4679 // Don't generate __CET__ macro definitions. They are implied by the
4680 // -fcf-protection option that is generated elsewhere.
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 // Don't generate OpenCL includes. They are implied by other flags that are
4696 // generated elsewhere.
4697 if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader &&
4698 ((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") ||
4699 I == "opencl-c.h"))
4700 continue;
4701 // Don't generate HLSL includes. They are implied by other flags that are
4702 // generated elsewhere.
4703 if (LangOpts.HLSL && I == "hlsl.h")
4704 continue;
4705
4706 GenerateArg(Consumer, OPT_include, I);
4707 }
4708
4709 for (const auto &CI : Opts.ChainedIncludes)
4710 GenerateArg(Consumer, OPT_chain_include, CI);
4711
4712 for (const auto &RF : Opts.RemappedFiles)
4713 GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second);
4714
4715 if (Opts.SourceDateEpoch)
4716 GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch));
4717
4718 if (Opts.DefineTargetOSMacros)
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 // Don't handle LexEditorPlaceholders. It is implied by the action that is
4725 // generated elsewhere.
4726}
4727
4728static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
4729 DiagnosticsEngine &Diags,
4731 const FrontendOptions &FrontendOpts) {
4732 unsigned NumErrorsBefore = Diags.getNumErrors();
4733
4734 PreprocessorOptions *PreprocessorOpts = &Opts;
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))
4745 Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
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 {
4758 Opts.PrecompiledPreambleBytes.first = Bytes;
4759 Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
4760 }
4761 }
4762
4763 // Add the __CET__ macro if a CFProtection option is set.
4764 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4765 StringRef Name = A->getValue();
4766 if (Name == "branch")
4767 Opts.addMacroDef("__CET__=1");
4768 else if (Name == "return")
4769 Opts.addMacroDef("__CET__=2");
4770 else if (Name == "full")
4771 Opts.addMacroDef("__CET__=3");
4772 }
4773
4774 // Add macros from the command line.
4775 for (const auto *A : Args.filtered(OPT_D, OPT_U)) {
4776 if (A->getOption().matches(OPT_D))
4777 Opts.addMacroDef(A->getValue());
4778 else
4779 Opts.addMacroUndef(A->getValue());
4780 }
4781
4782 // Add the ordered list of -includes.
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))
4787 Opts.ChainedIncludes.emplace_back(A->getValue());
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
4797 Opts.addRemappedFile(Split.first, Split.second);
4798 }
4799
4800 if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
4801 StringRef Epoch = A->getValue();
4802 // SOURCE_DATE_EPOCH, if specified, must be a non-negative decimal integer.
4803 // On time64 systems, pick 253402300799 (the UNIX timestamp of
4804 // 9999-12-31T23:59:59Z) as the upper bound.
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 {
4812 Opts.SourceDateEpoch = V;
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 // Always avoid lexing editor placeholders when we're just running the
4822 // preprocessor as we never want to emit the
4823 // "editor placeholder in source file" error in PP only mode.
4825 Opts.LexEditorPlaceholders = false;
4826
4828 Args.hasFlag(OPT_fdefine_target_os_macros,
4829 OPT_fno_define_target_os_macros, Opts.DefineTargetOSMacros);
4830
4831 return Diags.getNumErrors() == NumErrorsBefore;
4832}
4833
4834static void
4836 ArgumentConsumer Consumer,
4838 const PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
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
4845 bool Generate_dM = isStrictlyPreprocessorAction(Action) && !Opts.ShowCPP;
4846 if (Generate_dM)
4847 GenerateArg(Consumer, OPT_dM);
4848 if (!Generate_dM && Opts.ShowMacros)
4849 GenerateArg(Consumer, OPT_dD);
4850 if (Opts.DirectivesOnly)
4851 GenerateArg(Consumer, OPT_fdirectives_only);
4852}
4853
4855 ArgList &Args, DiagnosticsEngine &Diags,
4857 unsigned NumErrorsBefore = Diags.getNumErrors();
4858
4859 PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
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
4866 Opts.ShowCPP = isStrictlyPreprocessorAction(Action) && !Args.hasArg(OPT_dM);
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
4873static void GenerateTargetArgs(const TargetOptions &Opts,
4874 ArgumentConsumer Consumer) {
4875 const TargetOptions *TargetOpts = &Opts;
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
4881 if (!Opts.SDKVersion.empty())
4882 GenerateArg(Consumer, OPT_target_sdk_version_EQ,
4883 Opts.SDKVersion.getAsString());
4884 if (!Opts.DarwinTargetVariantSDKVersion.empty())
4885 GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,
4886 Opts.DarwinTargetVariantSDKVersion.getAsString());
4887}
4888
4889static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
4890 DiagnosticsEngine &Diags) {
4891 unsigned NumErrorsBefore = Diags.getNumErrors();
4892
4893 TargetOptions *TargetOpts = &Opts;
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
4906 Opts.SDKVersion = Version;
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
4915 Opts.DarwinTargetVariantSDKVersion = Version;
4916 }
4917
4918 return Diags.getNumErrors() == NumErrorsBefore;
4919}
4920
4921bool CompilerInvocation::CreateFromArgsImpl(
4922 CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs,
4923 DiagnosticsEngine &Diags, const char *Argv0) {
4924 unsigned NumErrorsBefore = Diags.getNumErrors();
4925
4926 // Parse the arguments.
4927 const OptTable &Opts = getDriverOptTable();
4928 llvm::opt::Visibility VisibilityMask(options::CC1Option);
4929 unsigned MissingArgIndex, MissingArgCount;
4930 InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
4931 MissingArgCount, VisibilityMask);
4933
4934 // Check for missing argument error.
4935 if (MissingArgCount)
4936 Diags.Report(diag::err_drv_missing_argument)
4937 << Args.getArgString(MissingArgIndex) << MissingArgCount;
4938
4939 // Issue errors on unknown arguments.
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
4950 ParseFileSystemArgs(Res.getFileSystemOpts(), Args, Diags);
4951 ParseMigratorArgs(Res.getMigratorOpts(), Args, Diags);
4952 ParseAnalyzerArgs(Res.getAnalyzerOpts(), Args, Diags);
4953 ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags,
4954 /*DefaultDiagColor=*/false);
4955 ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags, LangOpts.IsHeaderFile);
4956 // FIXME: We shouldn't have to pass the DashX option around here
4957 InputKind DashX = Res.getFrontendOpts().DashX;
4958 ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
4959 llvm::Triple T(Res.getTargetOpts().Triple);
4960 ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
4962 ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
4963
4964 ParsePointerAuthArgs(LangOpts, Args, Diags);
4965
4966 ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
4967 Diags);
4969 LangOpts.ObjCExceptions = 1;
4970
4971 for (auto Warning : Res.getDiagnosticOpts().Warnings) {
4972 if (Warning == "misexpect" &&
4973 !Diags.isIgnored(diag::warn_profile_data_misexpect, SourceLocation())) {
4974 Res.getCodeGenOpts().MisExpect = true;
4975 }
4976 }
4977
4978 if (LangOpts.CUDA) {
4979 // During CUDA device-side compilation, the aux triple is the
4980 // triple used for host compilation.
4981 if (LangOpts.CUDAIsDevice)
4983 }
4984
4985 // Set the triple of the host for OpenMP device compile.
4986 if (LangOpts.OpenMPIsTargetDevice)
4988
4989 ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
4991
4992 // FIXME: Override value name discarding when asan or msan is used because the
4993 // backend passes depend on the name of the alloca in order to print out
4994 // names.
4995 Res.getCodeGenOpts().DiscardValueNames &=
4996 !LangOpts.Sanitize.has(SanitizerKind::Address) &&
4997 !LangOpts.Sanitize.has(SanitizerKind::KernelAddress) &&
4998 !LangOpts.Sanitize.has(SanitizerKind::Memory) &&
4999 !LangOpts.Sanitize.has(SanitizerKind::KernelMemory);
5000
5001 ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags,
5003 Res.getFrontendOpts());
5006
5010 if (!Res.getDependencyOutputOpts().OutputFile.empty() &&
5011 Res.getDependencyOutputOpts().Targets.empty())
5012 Diags.Report(diag::err_fe_dependency_file_requires_MT);
5013
5014 // If sanitizer is enabled, disable OPT_ffine_grained_bitfield_accesses.
5015 if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
5016 !Res.getLangOpts().Sanitize.empty()) {
5017 Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
5018 Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
5019 }
5020
5021 // Store the command-line for using in the CodeView backend.
5022 if (Res.getCodeGenOpts().CodeViewCommandLine) {
5023 Res.getCodeGenOpts().Argv0 = Argv0;
5024 append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
5025 }
5026
5027 // Set PGOOptions. Need to create a temporary VFS to read the profile
5028 // to determine the PGO type.
5029 if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty()) {
5030 auto FS =
5032 Diags, llvm::vfs::getRealFileSystem());
5035 Diags);
5036 }
5037
5038 FixupInvocation(Res, Diags, Args, DashX);
5039
5040 return Diags.getNumErrors() == NumErrorsBefore;
5041}
5042
5044 ArrayRef<const char *> CommandLineArgs,
5045 DiagnosticsEngine &Diags,
5046 const char *Argv0) {
5047 CompilerInvocation DummyInvocation;
5048
5049 return RoundTrip(
5050 [](CompilerInvocation &Invocation, ArrayRef<const char *> CommandLineArgs,
5051 DiagnosticsEngine &Diags, const char *Argv0) {
5052 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
5053 },
5055 StringAllocator SA) {
5056 Args.push_back("-cc1");
5057 Invocation.generateCC1CommandLine(Args, SA);
5058 },
5059 Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
5060}
5061
5063 // FIXME: Consider using SHA1 instead of MD5.
5064 llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
5065
5066 // Note: For QoI reasons, the things we use as a hash here should all be
5067 // dumped via the -module-info flag.
5068
5069 // Start the signature with the compiler version.
5070 HBuilder.add(getClangFullRepositoryVersion());
5071
5072 // Also include the serialization version, in case LLVM_APPEND_VC_REV is off
5073 // and getClangFullRepositoryVersion() doesn't include git revision.
5075
5076 // Extend the signature with the language options
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<unsigned>(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
5086 HBuilder.add(getLangOpts().ObjCRuntime);
5087 HBuilder.addRange(getLangOpts().CommentOpts.BlockCommandNames);
5088
5089 // Extend the signature with the target options.
5090 HBuilder.add(getTargetOpts().Triple, getTargetOpts().CPU,
5091 getTargetOpts().TuneCPU, getTargetOpts().ABI);
5092 HBuilder.addRange(getTargetOpts().FeaturesAsWritten);
5093
5094 // Extend the signature with preprocessor options.
5095 const PreprocessorOptions &ppOpts = getPreprocessorOpts();
5096 HBuilder.add(ppOpts.UsePredefines, ppOpts.DetailedRecord);
5097
5098 const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
5099 for (const auto &Macro : getPreprocessorOpts().Macros) {
5100 // If we're supposed to ignore this macro for the purposes of modules,
5101 // don't put it into the hash.
5102 if (!hsOpts.ModulesIgnoreMacros.empty()) {
5103 // Check whether we're ignoring this macro.
5104 StringRef MacroDef = Macro.first;
5105 if (hsOpts.ModulesIgnoreMacros.count(
5106 llvm::CachedHashString(MacroDef.split('=').first)))
5107 continue;
5108 }
5109
5110 HBuilder.add(Macro);
5111 }
5112
5113 // Extend the signature with the sysroot and other header search options.
5114 HBuilder.add(hsOpts.Sysroot, hsOpts.ModuleFormat, hsOpts.UseDebugInfo,
5116 hsOpts.UseStandardCXXIncludes, hsOpts.UseLibcxx,
5118 HBuilder.add(hsOpts.ResourceDir);
5119
5120 if (hsOpts.ModulesStrictContextHash) {
5121 HBuilder.addRange(hsOpts.SystemHeaderPrefixes);
5122 HBuilder.addRange(hsOpts.UserEntries);
5123 HBuilder.addRange(hsOpts.VFSOverlayFiles);
5124
5125 const DiagnosticOptions &diagOpts = getDiagnosticOpts();
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 // Extend the signature with the user build path.
5135 HBuilder.add(hsOpts.ModuleUserBuildPath);
5136
5137 // Extend the signature with the module file extensions.
5138 for (const auto &ext : getFrontendOpts().ModuleFileExtensions)
5139 ext->hashExtension(HBuilder);
5140
5141 // Extend the signature with the Swift version for API notes.
5143 if (!APINotesOpts.SwiftVersion.empty()) {
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 // When compiling with -gmodules, also hash -fdebug-prefix-map as it
5154 // affects the debug info in the PCM.
5155 if (getCodeGenOpts().DebugTypeExtRefs)
5156 HBuilder.addRange(getCodeGenOpts().DebugPrefixMap);
5157
5158 // Extend the signature with the affecting debug options.
5159 if (getHeaderSearchOpts().ModuleFormat == "obj") {
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<unsigned>(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 // Extend the signature with the enabled sanitizers, if at least one is
5171 // enabled. Sanitizers which cannot affect AST generation aren't hashed.
5172 SanitizerSet SanHash = getLangOpts().Sanitize;
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, /*Signed=*/false);
5181}
5182
5184 ArgumentConsumer Consumer) const {
5185 llvm::Triple T(getTargetOpts().Triple);
5186
5190 GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer,
5191 /*DefaultDiagColor=*/false);
5192 GenerateFrontendArgs(getFrontendOpts(), Consumer, getLangOpts().IsHeaderFile);
5193 GenerateTargetArgs(getTargetOpts(), Consumer);
5197 GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX);
5198 GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T,
5199 getFrontendOpts().OutputFile, &getLangOpts());
5203 getFrontendOpts().ProgramAction);
5205}
5206
5207std::vector<std::string> CompilerInvocationBase::getCC1CommandLine() const {
5208 std::vector<std::string> Args{"-cc1"};
5210 [&Args](const Twine &Arg) { Args.push_back(Arg.str()); });
5211 return Args;
5212}
5213
5218}
5219
5221 getLangOpts().ImplicitModules = false;
5226 // The specific values we canonicalize to for pruning don't affect behaviour,
5227 /// so use the default values so they may be dropped from the command-line.
5228 getHeaderSearchOpts().ModuleCachePruneInterval = 7 * 24 * 60 * 60;
5229 getHeaderSearchOpts().ModuleCachePruneAfter = 31 * 24 * 60 * 60;
5230}
5231
5234 DiagnosticsEngine &Diags) {
5235 return createVFSFromCompilerInvocation(CI, Diags,
5236 llvm::vfs::getRealFileSystem());
5237}
5238
5241 const CompilerInvocation &CI, DiagnosticsEngine &Diags,
5244 Diags, std::move(BaseFS));
5245}
5246
5248 ArrayRef<std::string> VFSOverlayFiles, DiagnosticsEngine &Diags,
5250 if (VFSOverlayFiles.empty())
5251 return BaseFS;
5252
5254 // earlier vfs files are on the bottom
5255 for (const auto &File : VFSOverlayFiles) {
5256 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
5257 Result->getBufferForFile(File);
5258 if (!Buffer) {
5259 Diags.Report(diag::err_missing_vfs_overlay_file) << File;
5260 continue;
5261 }
5262
5263 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = llvm::vfs::getVFSFromYAML(
5264 std::move(Buffer.get()), /*DiagHandler*/ nullptr, File,
5265 /*DiagContext*/ nullptr, Result);
5266 if (!FS) {
5267 Diags.Report(diag::err_invalid_vfs_overlay) << File;
5268 continue;
5269 }
5270
5271 Result = FS;
5272 }
5273 return Result;
5274}
#define V(N, I)
Definition: ASTContext.h:3453
StringRef P
Defines the Diagnostic-related interfaces.
Defines enum values for all the target-independent builtin functions.
const Decl * D
IndirectLocalPath & Path
Expr * E
Defines the clang::CommentOptions interface.
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.
StringRef Filename
Definition: Format.cpp:3051
LangStandard::Kind Std
#define X(type, name)
Definition: Value.h:144
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.
bool ShowColors
Definition: Logger.cpp:29
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)
#define bool
Definition: amdgpuintrin.h:20
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.
Definition: Builtins.cpp:63
Implements C++ ABI-specific semantic analysis functions.
Definition: CXXABI.h:29
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()
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()
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.
Definition: Diagnostic.h:231
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Definition: Diagnostic.h:1493
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:896
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
Definition: Diagnostic.cpp:105
unsigned getNumErrors() const
Definition: Diagnostic.h:880
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition: Diagnostic.h:939
unsigned getNumWarnings() const
Definition: Diagnostic.h:881
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.
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.
enum clang::FrontendOptions::@201 ARCMTAction
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.
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
unsigned ModulesStrictContextHash
Whether we should include all things that could impact the module in the hash.
void AddPath(StringRef Path, frontend::IncludeDirGroup Group, bool IsFramework, bool IgnoreSysRoot)
AddPath - Add the Path path to the specified Group list.
unsigned ModuleCachePruneInterval
The interval (in seconds) between pruning operations.
std::map< std::string, std::string, std::less<> > PrebuiltModuleFiles
The mapping of module names to prebuilt module files.
uint64_t BuildSessionTimestamp
The time in seconds when the build session started.
std::vector< std::string > PrebuiltModulePaths
The directories used to load prebuilt module files.
unsigned ImplicitModuleMaps
Implicit module maps.
void AddSystemHeaderPrefix(StringRef Prefix, bool IsSystemHeader)
AddSystemHeaderPrefix - Override whether #include directives naming a path starting with Prefix shoul...
std::vector< SystemHeaderPrefix > SystemHeaderPrefixes
User-specified system header prefixes.
std::string ModuleFormat
The module/pch container format.
std::string Sysroot
If non-empty, the directory to use as a "virtual system root" for include paths.
llvm::SmallSetVector< llvm::CachedHashString, 16 > ModulesIgnoreMacros
The set of macro names that should be ignored for the purposes of computing the module hash.
std::string ModuleCachePath
The directory used for the module cache.
std::string ModuleUserBuildPath
The directory used for a user build.
std::vector< std::string > VFSOverlayFiles
The set of user-provided virtual filesystem overlay files.
unsigned UseLibcxx
Use libc++ instead of the default libstdc++.
unsigned UseBuiltinIncludes
Include the compiler builtin includes.
unsigned UseStandardCXXIncludes
Include the system standard C++ library include search directories.
unsigned UseDebugInfo
Whether the module includes debug information (-gmodules).
std::vector< Entry > UserEntries
User specified include entries.
std::string ResourceDir
The directory which holds the compiler resource files (builtin includes, etc.).
void AddPrebuiltModulePath(StringRef Name)
unsigned UseStandardSystemIncludes
Include the system standard include search directories.
void AddVFSOverlayFile(StringRef Name)
unsigned ModulesValidateOncePerBuildSession
If true, skip verifying input files used by modules if the module was already verified during this bu...
unsigned ModuleCachePruneAfter
The time (in seconds) after which an unused module file will be considered unused and will,...
A diagnostic client that ignores all diagnostics.
Definition: Diagnostic.h:1739
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
Format getFormat() const
HeaderUnitKind getHeaderUnitKind() const
InputKind getHeader() const
InputKind withFormat(Format F) const
Language getLanguage() const
@ 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.
Definition: LangOptions.h:385
@ AddUnsignedOverflowTest
if (a + b < a)
Definition: LangOptions.h:391
@ All
Exclude all overflow patterns (below)
Definition: LangOptions.h:387
@ AddSignedOverflowTest
if (a + b < a)
Definition: LangOptions.h:389
@ PostDecrInWhile
while (count–)
Definition: LangOptions.h:395
@ 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...
Definition: LangOptions.h:499
void resetNonModularOptions()
Reset all of the options that are not considered when building a module.
Definition: LangOptions.cpp:25
std::optional< TargetCXXABI::Kind > CXXABI
C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
Definition: LangOptions.h:587
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
Definition: LangOptions.h:566
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Definition: LangOptions.h:547
clang::ObjCRuntime ObjCRuntime
Definition: LangOptions.h:534
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
Definition: LangOptions.cpp:79
unsigned OverflowPatternExclusionMask
Which overflow patterns should be excluded from sanitizer instrumentation.
Definition: LangOptions.h:597
SanitizerSet Sanitize
Set of enabled sanitizers.
Definition: LangOptions.h:505
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
Definition: LangOptions.h:610
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...
Definition: LangOptions.cpp:89
std::string OMPHostIRFile
Name of the IR file that contains the result of the OpenMP target host code generation.
Definition: LangOptions.h:577
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Definition: LangOptions.h:544
std::string RandstructSeed
The seed used by the randomize structure layout feature.
Definition: LangOptions.h:602
std::map< std::string, std::string, std::greater< std::string > > MacroPrefixMap
A prefix map for FILE, BASE_FILE and __builtin_FILE().
Definition: LangOptions.h:569
LangStandard::Kind LangStd
The used language standard.
Definition: LangOptions.h:502
std::string OpenACCMacroOverride
Definition: LangOptions.h:619
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Definition: LangOptions.cpp:63
bool SanitizeCoverage
Is at least one coverage instrumentation type enabled.
Definition: LangOptions.h:507
std::vector< llvm::Triple > OMPTargetTriples
Triples of the OpenMP targets that the host code codegen should take into account in order to generat...
Definition: LangOptions.h:573
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
Definition: LangOptions.h:511
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:554
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
Definition: LangOptions.h:560
The basic abstraction for the target Objective-C runtime.
Definition: ObjCRuntime.h:28
bool allowsWeak() const
Does this runtime allow the use of __weak?
Definition: ObjCRuntime.h:299
Kind getKind() const
Definition: ObjCRuntime.h:77
bool tryParse(StringRef input)
Try to parse an Objective-C runtime specification from the given string.
Definition: ObjCRuntime.cpp:48
std::string getAsString() const
Definition: ObjCRuntime.cpp:23
bool allowsARC() const
Does this runtime allow ARC at all?
Definition: ObjCRuntime.h:150
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
Definition: ObjCRuntime.h:40
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)
Definition: TargetCXXABI.h:87
static const auto & getSpelling(Kind ABIKind)
Definition: TargetCXXABI.h:60
static bool usesRelativeVTables(const llvm::Triple &T)
Definition: TargetCXXABI.h:67
static bool isABI(StringRef Name)
Definition: TargetCXXABI.h:63
Kind getKind() const
Definition: TargetCXXABI.h:80
Options for controlling the target.
Definition: TargetOptions.h:26
std::string Triple
The name of the target triple to compile for.
Definition: TargetOptions.h:29
llvm::VersionTuple SDKVersion
The version of the SDK which was used during the compilation.
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.
Definition: TargetOptions.h:33
Value()=default
Action - Represent an abstract compilation step to perform.
Definition: Action.h:47
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...
Definition: Driver.cpp:172
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
constexpr XRayInstrMask All
Definition: XRayInstr.h:43
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.
@ EmitBC
Emit a .bc file.
@ 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,.
@ EmitObj
Emit a .o file.
@ 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.
Definition: ASTBitCodes.h:57
const unsigned VERSION_MAJOR
AST file major version number supported by this version of Clang.
Definition: ASTBitCodes.h:47
The JSON file list parser is used to communicate input to InstallAPI.
ASTDumpOutputFormat
Used to specify the format for printing AST dump information.
@ ADOF_Default
SanitizerMask getPPTransparentSanitizers()
Return the sanitizers which do not affect preprocessing.
Definition: Sanitizers.h:226
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.
@ NumConstraints
@ HIFIL_None
Definition: HeaderInclude.h:27
@ HIFIL_Only_Direct_System
Definition: HeaderInclude.h:27
void serializeSanitizerSet(SanitizerSet Set, SmallVectorImpl< StringRef > &Values)
Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
Definition: Sanitizers.cpp:87
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
Definition: CharInfo.h:132
LLVM_READONLY bool isAlphanumeric(unsigned char c)
Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].
Definition: CharInfo.h:138
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...
Definition: Sanitizers.cpp:64
@ Result
The result type of a method or function.
XRayInstrMask parseXRayInstrValue(StringRef Value)
Parses a command line argument into a mask.
Definition: XRayInstr.cpp:19
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.
Definition: XRayInstr.cpp:34
AnalysisPurgeMode
AnalysisPurgeModes - Set of available strategies for dead symbol removal.
@ NumPurgeModes
void serializeSanitizerMaskCutoffs(const SanitizerMaskCutoffs &Cutoffs, SmallVectorImpl< std::string > &Values)
Serialize a SanitizerMaskCutoffs into values for -fsanitize= or -fno-sanitize=.
Definition: Sanitizers.cpp:95
ShaderStage
Shader programs run in specific pipeline stages.
Definition: LangOptions.h:42
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.
Definition: Sanitizers.cpp:54
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...
Definition: Version.cpp:68
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.
@ NumInliningModes
@ HIFMT_JSON
Definition: HeaderInclude.h:22
@ HIFMT_Textual
Definition: HeaderInclude.h:22
unsigned long uint64_t
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
Definition: complex_cmath.h:40
Optimization remark with an optional regular expression pattern.
bool hasValidPattern() const
Returns true iff the optimization remark holds a valid regular expression.
Dummy tag type whose instance can be passed into the constructor to prevent creation of the reference...
frontend::IncludeDirGroup Group
unsigned IgnoreSysRoot
IgnoreSysRoot - This is false if an absolute path should be treated relative to the sysroot,...
LangStandard - Information about the properties of a particular language standard.
Definition: LangStandard.h:71
static const LangStandard & getLangStandardForKind(Kind K)
const char * getName() const
getName - Get the name of this standard.
Definition: LangStandard.h:86
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.
Definition: Sanitizers.h:190
bool empty() const
Returns true if no sanitizers are enabled.
Definition: Sanitizers.h:193
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:196
XRayInstrMask Mask
Definition: XRayInstr.h:65