clang 22.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"
28#include "clang/Config/config.h"
29#include "clang/Driver/Driver.h"
44#include "llvm/ADT/APInt.h"
45#include "llvm/ADT/ArrayRef.h"
46#include "llvm/ADT/CachedHashString.h"
47#include "llvm/ADT/FloatingPointMode.h"
48#include "llvm/ADT/STLExtras.h"
49#include "llvm/ADT/SmallVector.h"
50#include "llvm/ADT/StringRef.h"
51#include "llvm/ADT/StringSwitch.h"
52#include "llvm/ADT/Twine.h"
53#include "llvm/Config/llvm-config.h"
54#include "llvm/Frontend/Debug/Options.h"
55#include "llvm/IR/DebugInfoMetadata.h"
56#include "llvm/Linker/Linker.h"
57#include "llvm/MC/MCTargetOptions.h"
58#include "llvm/Option/Arg.h"
59#include "llvm/Option/ArgList.h"
60#include "llvm/Option/OptSpecifier.h"
61#include "llvm/Option/OptTable.h"
62#include "llvm/Option/Option.h"
63#include "llvm/ProfileData/InstrProfReader.h"
64#include "llvm/Remarks/HotnessThresholdParser.h"
65#include "llvm/Support/CodeGen.h"
66#include "llvm/Support/Compiler.h"
67#include "llvm/Support/Error.h"
68#include "llvm/Support/ErrorHandling.h"
69#include "llvm/Support/ErrorOr.h"
70#include "llvm/Support/FileSystem.h"
71#include "llvm/Support/HashBuilder.h"
72#include "llvm/Support/MathExtras.h"
73#include "llvm/Support/MemoryBuffer.h"
74#include "llvm/Support/Path.h"
75#include "llvm/Support/Process.h"
76#include "llvm/Support/Regex.h"
77#include "llvm/Support/VersionTuple.h"
78#include "llvm/Support/VirtualFileSystem.h"
79#include "llvm/Support/raw_ostream.h"
80#include "llvm/Target/TargetOptions.h"
81#include "llvm/TargetParser/Host.h"
82#include "llvm/TargetParser/Triple.h"
83#include <algorithm>
84#include <cassert>
85#include <cstddef>
86#include <cstring>
87#include <ctime>
88#include <fstream>
89#include <limits>
90#include <memory>
91#include <optional>
92#include <string>
93#include <tuple>
94#include <type_traits>
95#include <utility>
96#include <vector>
97
98using namespace clang;
99using namespace driver;
100using namespace options;
101using namespace llvm::opt;
102
103//===----------------------------------------------------------------------===//
104// Helpers.
105//===----------------------------------------------------------------------===//
106
107// Parse misexpect tolerance argument value.
108// Valid option values are integers in the range [0, 100)
110 uint32_t Val;
111 if (Arg.getAsInteger(10, Val))
112 return llvm::createStringError(llvm::inconvertibleErrorCode(),
113 "Not an integer: %s", Arg.data());
114 return Val;
115}
116
117//===----------------------------------------------------------------------===//
118// Initialization.
119//===----------------------------------------------------------------------===//
120
121template <class T> std::shared_ptr<T> make_shared_copy(const T &X) {
122 return std::make_shared<T>(X);
123}
124
126 : LangOpts(std::make_shared<LangOptions>()),
127 TargetOpts(std::make_shared<TargetOptions>()),
128 DiagnosticOpts(std::make_shared<DiagnosticOptions>()),
129 HSOpts(std::make_shared<HeaderSearchOptions>()),
130 PPOpts(std::make_shared<PreprocessorOptions>()),
131 AnalyzerOpts(std::make_shared<AnalyzerOptions>()),
132 MigratorOpts(std::make_shared<MigratorOptions>()),
133 APINotesOpts(std::make_shared<APINotesOptions>()),
134 CodeGenOpts(std::make_shared<CodeGenOptions>()),
135 FSOpts(std::make_shared<FileSystemOptions>()),
136 FrontendOpts(std::make_shared<FrontendOptions>()),
139
142 if (this != &X) {
143 LangOpts = make_shared_copy(X.getLangOpts());
144 TargetOpts = make_shared_copy(X.getTargetOpts());
145 DiagnosticOpts = make_shared_copy(X.getDiagnosticOpts());
146 HSOpts = make_shared_copy(X.getHeaderSearchOpts());
147 PPOpts = make_shared_copy(X.getPreprocessorOpts());
148 AnalyzerOpts = make_shared_copy(X.getAnalyzerOpts());
149 MigratorOpts = make_shared_copy(X.getMigratorOpts());
150 APINotesOpts = make_shared_copy(X.getAPINotesOpts());
151 CodeGenOpts = make_shared_copy(X.getCodeGenOpts());
152 FSOpts = make_shared_copy(X.getFileSystemOpts());
153 FrontendOpts = make_shared_copy(X.getFrontendOpts());
154 DependencyOutputOpts = make_shared_copy(X.getDependencyOutputOpts());
155 PreprocessorOutputOpts = make_shared_copy(X.getPreprocessorOutputOpts());
156 }
157 return *this;
158}
159
162 if (this != &X) {
163 LangOpts = X.LangOpts;
164 TargetOpts = X.TargetOpts;
165 DiagnosticOpts = X.DiagnosticOpts;
166 HSOpts = X.HSOpts;
167 PPOpts = X.PPOpts;
168 AnalyzerOpts = X.AnalyzerOpts;
169 MigratorOpts = X.MigratorOpts;
170 APINotesOpts = X.APINotesOpts;
171 CodeGenOpts = X.CodeGenOpts;
172 FSOpts = X.FSOpts;
173 FrontendOpts = X.FrontendOpts;
174 DependencyOutputOpts = X.DependencyOutputOpts;
175 PreprocessorOutputOpts = X.PreprocessorOutputOpts;
176 }
177 return *this;
178}
179
184
190
191template <typename T>
192T &ensureOwned(std::shared_ptr<T> &Storage) {
193 if (Storage.use_count() > 1)
194 Storage = std::make_shared<T>(*Storage);
195 return *Storage;
196}
197
201
205
209
213
217
221
225
229
233
237
241
245
250
251//===----------------------------------------------------------------------===//
252// Normalizers
253//===----------------------------------------------------------------------===//
254
256
257#define OPTTABLE_STR_TABLE_CODE
258#include "clang/Driver/Options.inc"
259#undef OPTTABLE_STR_TABLE_CODE
260
261static llvm::StringRef lookupStrInTable(unsigned Offset) {
262 return OptionStrTable[Offset];
263}
264
265#define SIMPLE_ENUM_VALUE_TABLE
266#include "clang/Driver/Options.inc"
267#undef SIMPLE_ENUM_VALUE_TABLE
268
269static std::optional<bool> normalizeSimpleFlag(OptSpecifier Opt,
270 unsigned TableIndex,
271 const ArgList &Args,
272 DiagnosticsEngine &Diags) {
273 if (Args.hasArg(Opt))
274 return true;
275 return std::nullopt;
276}
277
278static std::optional<bool> normalizeSimpleNegativeFlag(OptSpecifier Opt,
279 unsigned,
280 const ArgList &Args,
282 if (Args.hasArg(Opt))
283 return false;
284 return std::nullopt;
285}
286
287/// The tblgen-erated code passes in a fifth parameter of an arbitrary type, but
288/// denormalizeSimpleFlags never looks at it. Avoid bloating compile-time with
289/// unnecessary template instantiations and just ignore it with a variadic
290/// argument.
292 unsigned SpellingOffset, Option::OptionClass,
293 unsigned, /*T*/...) {
294 Consumer(lookupStrInTable(SpellingOffset));
295}
297 const Twine &Spelling, Option::OptionClass,
298 unsigned, /*T*/...) {
299 Consumer(Spelling);
300}
301
302template <typename T> static constexpr bool is_uint64_t_convertible() {
303 return !std::is_same_v<T, uint64_t> && llvm::is_integral_or_enum<T>::value;
304}
305
306template <typename T,
307 std::enable_if_t<!is_uint64_t_convertible<T>(), bool> = false>
309 return [Value](OptSpecifier Opt, unsigned, const ArgList &Args,
310 DiagnosticsEngine &) -> std::optional<T> {
311 if (Args.hasArg(Opt))
312 return Value;
313 return std::nullopt;
314 };
315}
316
317template <typename T,
318 std::enable_if_t<is_uint64_t_convertible<T>(), bool> = false>
320 return makeFlagToValueNormalizer(uint64_t(Value));
321}
322
323static auto makeBooleanOptionNormalizer(bool Value, bool OtherValue,
324 OptSpecifier OtherOpt) {
325 return [Value, OtherValue,
326 OtherOpt](OptSpecifier Opt, unsigned, const ArgList &Args,
327 DiagnosticsEngine &) -> std::optional<bool> {
328 if (const Arg *A = Args.getLastArg(Opt, OtherOpt)) {
329 return A->getOption().matches(Opt) ? Value : OtherValue;
330 }
331 return std::nullopt;
332 };
333}
334
336 return [Value](ArgumentConsumer Consumer, unsigned SpellingOffset,
337 Option::OptionClass, unsigned, bool KeyPath) {
338 if (KeyPath == Value)
339 Consumer(lookupStrInTable(SpellingOffset));
340 };
341}
342
344 const Twine &Spelling,
345 Option::OptionClass OptClass, unsigned,
346 const Twine &Value) {
347 switch (OptClass) {
348 case Option::SeparateClass:
349 case Option::JoinedOrSeparateClass:
350 case Option::JoinedAndSeparateClass:
351 Consumer(Spelling);
352 Consumer(Value);
353 break;
354 case Option::JoinedClass:
355 case Option::CommaJoinedClass:
356 Consumer(Spelling + Value);
357 break;
358 default:
359 llvm_unreachable("Cannot denormalize an option with option class "
360 "incompatible with string denormalization.");
361 }
362}
363
364template <typename T>
365static void
366denormalizeString(ArgumentConsumer Consumer, unsigned SpellingOffset,
367 Option::OptionClass OptClass, unsigned TableIndex, T Value) {
368 denormalizeStringImpl(Consumer, lookupStrInTable(SpellingOffset), OptClass,
369 TableIndex, Twine(Value));
370}
371
372template <typename T>
373static void denormalizeString(ArgumentConsumer Consumer, const Twine &Spelling,
374 Option::OptionClass OptClass, unsigned TableIndex,
375 T Value) {
376 denormalizeStringImpl(Consumer, Spelling, OptClass, TableIndex, Twine(Value));
377}
378
379static std::optional<SimpleEnumValue>
380findValueTableByName(const SimpleEnumValueTable &Table, StringRef Name) {
381 for (int I = 0, E = Table.Size; I != E; ++I)
382 if (Name == Table.Table[I].Name)
383 return Table.Table[I];
384
385 return std::nullopt;
386}
387
388static std::optional<SimpleEnumValue>
389findValueTableByValue(const SimpleEnumValueTable &Table, unsigned Value) {
390 for (int I = 0, E = Table.Size; I != E; ++I)
391 if (Value == Table.Table[I].Value)
392 return Table.Table[I];
393
394 return std::nullopt;
395}
396
397static std::optional<unsigned> normalizeSimpleEnum(OptSpecifier Opt,
398 unsigned TableIndex,
399 const ArgList &Args,
400 DiagnosticsEngine &Diags) {
401 assert(TableIndex < SimpleEnumValueTablesSize);
402 const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
403
404 auto *Arg = Args.getLastArg(Opt);
405 if (!Arg)
406 return std::nullopt;
407
408 StringRef ArgValue = Arg->getValue();
409 if (auto MaybeEnumVal = findValueTableByName(Table, ArgValue))
410 return MaybeEnumVal->Value;
411
412 Diags.Report(diag::err_drv_invalid_value)
413 << Arg->getAsString(Args) << ArgValue;
414 return std::nullopt;
415}
416
418 unsigned SpellingOffset,
419 Option::OptionClass OptClass,
420 unsigned TableIndex, unsigned Value) {
421 assert(TableIndex < SimpleEnumValueTablesSize);
422 const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];
423 if (auto MaybeEnumVal = findValueTableByValue(Table, Value)) {
424 denormalizeString(Consumer, lookupStrInTable(SpellingOffset), OptClass,
425 TableIndex, MaybeEnumVal->Name);
426 } else {
427 llvm_unreachable("The simple enum value was not correctly defined in "
428 "the tablegen option description");
429 }
430}
431
432template <typename T>
434 unsigned SpellingOffset,
435 Option::OptionClass OptClass,
436 unsigned TableIndex, T Value) {
437 return denormalizeSimpleEnumImpl(Consumer, SpellingOffset, OptClass,
438 TableIndex, static_cast<unsigned>(Value));
439}
440
441static std::optional<std::string> normalizeString(OptSpecifier Opt,
442 int TableIndex,
443 const ArgList &Args,
444 DiagnosticsEngine &Diags) {
445 auto *Arg = Args.getLastArg(Opt);
446 if (!Arg)
447 return std::nullopt;
448 return std::string(Arg->getValue());
449}
450
451template <typename IntTy>
452static std::optional<IntTy> normalizeStringIntegral(OptSpecifier Opt, int,
453 const ArgList &Args,
454 DiagnosticsEngine &Diags) {
455 auto *Arg = Args.getLastArg(Opt);
456 if (!Arg)
457 return std::nullopt;
458 IntTy Res;
459 if (StringRef(Arg->getValue()).getAsInteger(0, Res)) {
460 Diags.Report(diag::err_drv_invalid_int_value)
461 << Arg->getAsString(Args) << Arg->getValue();
462 return std::nullopt;
463 }
464 return Res;
465}
466
467static std::optional<std::vector<std::string>>
468normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args,
470 return Args.getAllArgValues(Opt);
471}
472
474 unsigned SpellingOffset,
475 Option::OptionClass OptClass,
476 unsigned TableIndex,
477 const std::vector<std::string> &Values) {
478 switch (OptClass) {
479 case Option::CommaJoinedClass: {
480 std::string CommaJoinedValue;
481 if (!Values.empty()) {
482 CommaJoinedValue.append(Values.front());
483 for (const std::string &Value : llvm::drop_begin(Values, 1)) {
484 CommaJoinedValue.append(",");
485 CommaJoinedValue.append(Value);
486 }
487 }
488 denormalizeString(Consumer, SpellingOffset,
489 Option::OptionClass::JoinedClass, TableIndex,
490 CommaJoinedValue);
491 break;
492 }
493 case Option::JoinedClass:
494 case Option::SeparateClass:
495 case Option::JoinedOrSeparateClass:
496 for (const std::string &Value : Values)
497 denormalizeString(Consumer, SpellingOffset, OptClass, TableIndex, Value);
498 break;
499 default:
500 llvm_unreachable("Cannot denormalize an option with option class "
501 "incompatible with string vector denormalization.");
502 }
503}
504
505static std::optional<std::string> normalizeTriple(OptSpecifier Opt,
506 int TableIndex,
507 const ArgList &Args,
508 DiagnosticsEngine &Diags) {
509 auto *Arg = Args.getLastArg(Opt);
510 if (!Arg)
511 return std::nullopt;
512 return llvm::Triple::normalize(Arg->getValue());
513}
514
515template <typename T, typename U>
516static T mergeForwardValue(T KeyPath, U Value) {
517 return static_cast<T>(Value);
518}
519
520template <typename T, typename U> static T mergeMaskValue(T KeyPath, U Value) {
521 return KeyPath | Value;
522}
523
524template <typename T> static T extractForwardValue(T KeyPath) {
525 return KeyPath;
526}
527
528template <typename T, typename U, U Value>
529static T extractMaskValue(T KeyPath) {
530 return ((KeyPath & Value) == Value) ? static_cast<T>(Value) : T();
531}
532
533#define PARSE_OPTION_WITH_MARSHALLING( \
534 ARGS, DIAGS, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, \
535 ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \
536 METAVAR, VALUES, SUBCOMMANDIDS_OFFSET, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
537 DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
538 MERGER, EXTRACTOR, TABLE_INDEX) \
539 if ((VISIBILITY) & options::CC1Option) { \
540 KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \
541 if (IMPLIED_CHECK) \
542 KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \
543 if (SHOULD_PARSE) \
544 if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, ARGS, DIAGS)) \
545 KEYPATH = \
546 MERGER(KEYPATH, static_cast<decltype(KEYPATH)>(*MaybeValue)); \
547 }
548
549// Capture the extracted value as a lambda argument to avoid potential issues
550// with lifetime extension of the reference.
551#define GENERATE_OPTION_WITH_MARSHALLING( \
552 CONSUMER, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, ALIASARGS, \
553 FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \
554 SUBCOMMANDIDS_OFFSET, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \
555 IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \
556 TABLE_INDEX) \
557 if ((VISIBILITY) & options::CC1Option) { \
558 [&](const auto &Extracted) { \
559 if (ALWAYS_EMIT || \
560 (Extracted != \
561 static_cast<decltype(KEYPATH)>((IMPLIED_CHECK) ? (IMPLIED_VALUE) \
562 : (DEFAULT_VALUE)))) \
563 DENORMALIZER(CONSUMER, SPELLING_OFFSET, Option::KIND##Class, \
564 TABLE_INDEX, Extracted); \
565 }(EXTRACTOR(KEYPATH)); \
566 }
567
568static StringRef GetInputKindName(InputKind IK);
569
570static bool FixupInvocation(CompilerInvocation &Invocation,
571 DiagnosticsEngine &Diags, const ArgList &Args,
572 InputKind IK) {
573 unsigned NumErrorsBefore = Diags.getNumErrors();
574
575 LangOptions &LangOpts = Invocation.getLangOpts();
576 CodeGenOptions &CodeGenOpts = Invocation.getCodeGenOpts();
577 TargetOptions &TargetOpts = Invocation.getTargetOpts();
578 FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();
579 CodeGenOpts.XRayInstrumentFunctions = LangOpts.XRayInstrument;
580 CodeGenOpts.XRayAlwaysEmitCustomEvents = LangOpts.XRayAlwaysEmitCustomEvents;
581 CodeGenOpts.XRayAlwaysEmitTypedEvents = LangOpts.XRayAlwaysEmitTypedEvents;
582 CodeGenOpts.DisableFree = FrontendOpts.DisableFree;
583 FrontendOpts.GenerateGlobalModuleIndex = FrontendOpts.UseGlobalModuleIndex;
584 if (FrontendOpts.ShowStats)
585 CodeGenOpts.ClearASTBeforeBackend = false;
586 LangOpts.SanitizeCoverage = CodeGenOpts.hasSanitizeCoverage();
587 LangOpts.ForceEmitVTables = CodeGenOpts.ForceEmitVTables;
588 LangOpts.SpeculativeLoadHardening = CodeGenOpts.SpeculativeLoadHardening;
589 LangOpts.CurrentModule = LangOpts.ModuleName;
590
591 llvm::Triple T(TargetOpts.Triple);
592 llvm::Triple::ArchType Arch = T.getArch();
593
594 CodeGenOpts.CodeModel = TargetOpts.CodeModel;
595 CodeGenOpts.LargeDataThreshold = TargetOpts.LargeDataThreshold;
596
597 if (CodeGenOpts.getExceptionHandling() !=
599 T.isWindowsMSVCEnvironment())
600 Diags.Report(diag::err_fe_invalid_exception_model)
601 << static_cast<unsigned>(CodeGenOpts.getExceptionHandling()) << T.str();
602
603 if (LangOpts.AppleKext && !LangOpts.CPlusPlus)
604 Diags.Report(diag::warn_c_kext);
605
606 if (LangOpts.NewAlignOverride &&
607 !llvm::isPowerOf2_32(LangOpts.NewAlignOverride)) {
608 Arg *A = Args.getLastArg(OPT_fnew_alignment_EQ);
609 Diags.Report(diag::err_fe_invalid_alignment)
610 << A->getAsString(Args) << A->getValue();
611 LangOpts.NewAlignOverride = 0;
612 }
613
614 // The -f[no-]raw-string-literals option is only valid in C and in C++
615 // standards before C++11.
616 if (LangOpts.CPlusPlus11) {
617 if (Args.hasArg(OPT_fraw_string_literals, OPT_fno_raw_string_literals)) {
618 Args.claimAllArgs(OPT_fraw_string_literals, OPT_fno_raw_string_literals);
619 Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx11)
620 << bool(LangOpts.RawStringLiterals);
621 }
622
623 // Do not allow disabling raw string literals in C++11 or later.
624 LangOpts.RawStringLiterals = true;
625 }
626
627 LangOpts.NamedLoops =
628 Args.hasFlag(OPT_fnamed_loops, OPT_fno_named_loops, LangOpts.C2y);
629
630 // Prevent the user from specifying both -fsycl-is-device and -fsycl-is-host.
631 if (LangOpts.SYCLIsDevice && LangOpts.SYCLIsHost)
632 Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fsycl-is-device"
633 << "-fsycl-is-host";
634
635 if (Args.hasArg(OPT_fgnu89_inline) && LangOpts.CPlusPlus)
636 Diags.Report(diag::err_drv_argument_not_allowed_with)
637 << "-fgnu89-inline" << GetInputKindName(IK);
638
639 if (Args.hasArg(OPT_hlsl_entrypoint) && !LangOpts.HLSL)
640 Diags.Report(diag::err_drv_argument_not_allowed_with)
641 << "-hlsl-entry" << GetInputKindName(IK);
642
643 if (Args.hasArg(OPT_fdx_rootsignature_version) && !LangOpts.HLSL)
644 Diags.Report(diag::err_drv_argument_not_allowed_with)
645 << "-fdx-rootsignature-version" << GetInputKindName(IK);
646
647 if (Args.hasArg(OPT_fdx_rootsignature_define) && !LangOpts.HLSL)
648 Diags.Report(diag::err_drv_argument_not_allowed_with)
649 << "-fdx-rootsignature-define" << GetInputKindName(IK);
650
651 if (Args.hasArg(OPT_fgpu_allow_device_init) && !LangOpts.HIP)
652 Diags.Report(diag::warn_ignored_hip_only_option)
653 << Args.getLastArg(OPT_fgpu_allow_device_init)->getAsString(Args);
654
655 if (Args.hasArg(OPT_gpu_max_threads_per_block_EQ) && !LangOpts.HIP)
656 Diags.Report(diag::warn_ignored_hip_only_option)
657 << Args.getLastArg(OPT_gpu_max_threads_per_block_EQ)->getAsString(Args);
658
659 // When these options are used, the compiler is allowed to apply
660 // optimizations that may affect the final result. For example
661 // (x+y)+z is transformed to x+(y+z) but may not give the same
662 // final result; it's not value safe.
663 // Another example can be to simplify x/x to 1.0 but x could be 0.0, INF
664 // or NaN. Final result may then differ. An error is issued when the eval
665 // method is set with one of these options.
666 if (Args.hasArg(OPT_ffp_eval_method_EQ)) {
667 if (LangOpts.ApproxFunc)
668 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 0;
669 if (LangOpts.AllowFPReassoc)
670 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 1;
671 if (LangOpts.AllowRecip)
672 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 2;
673 }
674
675 // -cl-strict-aliasing needs to emit diagnostic in the case where CL > 1.0.
676 // This option should be deprecated for CL > 1.0 because
677 // this option was added for compatibility with OpenCL 1.0.
678 if (Args.getLastArg(OPT_cl_strict_aliasing) &&
679 (LangOpts.getOpenCLCompatibleVersion() > 100))
680 Diags.Report(diag::warn_option_invalid_ocl_version)
681 << LangOpts.getOpenCLVersionString()
682 << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args);
683
684 if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {
685 auto DefaultCC = LangOpts.getDefaultCallingConv();
686
687 bool emitError = (DefaultCC == LangOptions::DCC_FastCall ||
688 DefaultCC == LangOptions::DCC_StdCall) &&
689 Arch != llvm::Triple::x86;
690 emitError |= (DefaultCC == LangOptions::DCC_VectorCall ||
691 DefaultCC == LangOptions::DCC_RegCall) &&
692 !T.isX86();
693 emitError |= DefaultCC == LangOptions::DCC_RtdCall && Arch != llvm::Triple::m68k;
694 if (emitError)
695 Diags.Report(diag::err_drv_argument_not_allowed_with)
696 << A->getSpelling() << T.getTriple();
697 }
698
699 return Diags.getNumErrors() == NumErrorsBefore;
700}
701
702//===----------------------------------------------------------------------===//
703// Deserialization (from args)
704//===----------------------------------------------------------------------===//
705
706static unsigned getOptimizationLevel(ArgList &Args, InputKind IK,
707 DiagnosticsEngine &Diags) {
708 unsigned DefaultOpt = 0;
709 if ((IK.getLanguage() == Language::OpenCL ||
711 !Args.hasArg(OPT_cl_opt_disable))
712 DefaultOpt = 2;
713
714 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
715 if (A->getOption().matches(options::OPT_O0))
716 return 0;
717
718 if (A->getOption().matches(options::OPT_Ofast))
719 return 3;
720
721 assert(A->getOption().matches(options::OPT_O));
722
723 StringRef S(A->getValue());
724 if (S == "s" || S == "z")
725 return 2;
726
727 if (S == "g")
728 return 1;
729
730 return getLastArgIntValue(Args, OPT_O, DefaultOpt, Diags);
731 }
732
733 return DefaultOpt;
734}
735
736static unsigned getOptimizationLevelSize(ArgList &Args) {
737 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {
738 if (A->getOption().matches(options::OPT_O)) {
739 switch (A->getValue()[0]) {
740 default:
741 return 0;
742 case 's':
743 return 1;
744 case 'z':
745 return 2;
746 }
747 }
748 }
749 return 0;
750}
751
752static void GenerateArg(ArgumentConsumer Consumer,
753 llvm::opt::OptSpecifier OptSpecifier) {
754 Option Opt = getDriverOptTable().getOption(OptSpecifier);
755 denormalizeSimpleFlag(Consumer, Opt.getPrefixedName(),
756 Option::OptionClass::FlagClass, 0);
757}
758
759static void GenerateArg(ArgumentConsumer Consumer,
760 llvm::opt::OptSpecifier OptSpecifier,
761 const Twine &Value) {
762 Option Opt = getDriverOptTable().getOption(OptSpecifier);
763 denormalizeString(Consumer, Opt.getPrefixedName(), Opt.getKind(), 0, Value);
764}
765
766// Parse command line arguments into CompilerInvocation.
767using ParseFn =
768 llvm::function_ref<bool(CompilerInvocation &, ArrayRef<const char *>,
769 DiagnosticsEngine &, const char *)>;
770
771// Generate command line arguments from CompilerInvocation.
772using GenerateFn = llvm::function_ref<void(
775
776/// May perform round-trip of command line arguments. By default, the round-trip
777/// is enabled in assert builds. This can be overwritten at run-time via the
778/// "-round-trip-args" and "-no-round-trip-args" command line flags, or via the
779/// ForceRoundTrip parameter.
780///
781/// During round-trip, the command line arguments are parsed into a dummy
782/// CompilerInvocation, which is used to generate the command line arguments
783/// again. The real CompilerInvocation is then created by parsing the generated
784/// arguments, not the original ones. This (in combination with tests covering
785/// argument behavior) ensures the generated command line is complete (doesn't
786/// drop/mangle any arguments).
787///
788/// Finally, we check the command line that was used to create the real
789/// CompilerInvocation instance. By default, we compare it to the command line
790/// the real CompilerInvocation generates. This checks whether the generator is
791/// deterministic. If \p CheckAgainstOriginalInvocation is enabled, we instead
792/// compare it to the original command line to verify the original command-line
793/// was canonical and can round-trip exactly.
794static bool RoundTrip(ParseFn Parse, GenerateFn Generate,
795 CompilerInvocation &RealInvocation,
796 CompilerInvocation &DummyInvocation,
797 ArrayRef<const char *> CommandLineArgs,
798 DiagnosticsEngine &Diags, const char *Argv0,
799 bool CheckAgainstOriginalInvocation = false,
800 bool ForceRoundTrip = false) {
801#ifndef NDEBUG
802 bool DoRoundTripDefault = true;
803#else
804 bool DoRoundTripDefault = false;
805#endif
806
807 bool DoRoundTrip = DoRoundTripDefault;
808 if (ForceRoundTrip) {
809 DoRoundTrip = true;
810 } else {
811 for (const auto *Arg : CommandLineArgs) {
812 if (Arg == StringRef("-round-trip-args"))
813 DoRoundTrip = true;
814 if (Arg == StringRef("-no-round-trip-args"))
815 DoRoundTrip = false;
816 }
817 }
818
819 // If round-trip was not requested, simply run the parser with the real
820 // invocation diagnostics.
821 if (!DoRoundTrip)
822 return Parse(RealInvocation, CommandLineArgs, Diags, Argv0);
823
824 // Serializes quoted (and potentially escaped) arguments.
825 auto SerializeArgs = [](ArrayRef<const char *> Args) {
826 std::string Buffer;
827 llvm::raw_string_ostream OS(Buffer);
828 for (const char *Arg : Args) {
829 llvm::sys::printArg(OS, Arg, /*Quote=*/true);
830 OS << ' ';
831 }
832 return Buffer;
833 };
834
835 // Setup a dummy DiagnosticsEngine.
836 DiagnosticOptions DummyDiagOpts;
837 DiagnosticsEngine DummyDiags(DiagnosticIDs::create(), DummyDiagOpts);
838 DummyDiags.setClient(new TextDiagnosticBuffer());
839
840 // Run the first parse on the original arguments with the dummy invocation and
841 // diagnostics.
842 if (!Parse(DummyInvocation, CommandLineArgs, DummyDiags, Argv0) ||
843 DummyDiags.getNumWarnings() != 0) {
844 // If the first parse did not succeed, it must be user mistake (invalid
845 // command line arguments). We won't be able to generate arguments that
846 // would reproduce the same result. Let's fail again with the real
847 // invocation and diagnostics, so all side-effects of parsing are visible.
848 unsigned NumWarningsBefore = Diags.getNumWarnings();
849 auto Success = Parse(RealInvocation, CommandLineArgs, Diags, Argv0);
850 if (!Success || Diags.getNumWarnings() != NumWarningsBefore)
851 return Success;
852
853 // Parse with original options and diagnostics succeeded even though it
854 // shouldn't have. Something is off.
855 Diags.Report(diag::err_cc1_round_trip_fail_then_ok);
856 Diags.Report(diag::note_cc1_round_trip_original)
857 << SerializeArgs(CommandLineArgs);
858 return false;
859 }
860
861 // Setup string allocator.
862 llvm::BumpPtrAllocator Alloc;
863 llvm::StringSaver StringPool(Alloc);
864 auto SA = [&StringPool](const Twine &Arg) {
865 return StringPool.save(Arg).data();
866 };
867
868 // Generate arguments from the dummy invocation. If Generate is the
869 // inverse of Parse, the newly generated arguments must have the same
870 // semantics as the original.
871 SmallVector<const char *> GeneratedArgs;
872 Generate(DummyInvocation, GeneratedArgs, SA);
873
874 // Run the second parse, now on the generated arguments, and with the real
875 // invocation and diagnostics. The result is what we will end up using for the
876 // rest of compilation, so if Generate is not inverse of Parse, something down
877 // the line will break.
878 bool Success2 = Parse(RealInvocation, GeneratedArgs, Diags, Argv0);
879
880 // The first parse on original arguments succeeded, but second parse of
881 // generated arguments failed. Something must be wrong with the generator.
882 if (!Success2) {
883 Diags.Report(diag::err_cc1_round_trip_ok_then_fail);
884 Diags.Report(diag::note_cc1_round_trip_generated)
885 << 1 << SerializeArgs(GeneratedArgs);
886 return false;
887 }
888
889 SmallVector<const char *> ComparisonArgs;
890 if (CheckAgainstOriginalInvocation)
891 // Compare against original arguments.
892 ComparisonArgs.assign(CommandLineArgs.begin(), CommandLineArgs.end());
893 else
894 // Generate arguments again, this time from the options we will end up using
895 // for the rest of the compilation.
896 Generate(RealInvocation, ComparisonArgs, SA);
897
898 // Compares two lists of arguments.
899 auto Equal = [](const ArrayRef<const char *> A,
900 const ArrayRef<const char *> B) {
901 return std::equal(A.begin(), A.end(), B.begin(), B.end(),
902 [](const char *AElem, const char *BElem) {
903 return StringRef(AElem) == StringRef(BElem);
904 });
905 };
906
907 // If we generated different arguments from what we assume are two
908 // semantically equivalent CompilerInvocations, the Generate function may
909 // be non-deterministic.
910 if (!Equal(GeneratedArgs, ComparisonArgs)) {
911 Diags.Report(diag::err_cc1_round_trip_mismatch);
912 Diags.Report(diag::note_cc1_round_trip_generated)
913 << 1 << SerializeArgs(GeneratedArgs);
914 Diags.Report(diag::note_cc1_round_trip_generated)
915 << 2 << SerializeArgs(ComparisonArgs);
916 return false;
917 }
918
919 Diags.Report(diag::remark_cc1_round_trip_generated)
920 << 1 << SerializeArgs(GeneratedArgs);
921 Diags.Report(diag::remark_cc1_round_trip_generated)
922 << 2 << SerializeArgs(ComparisonArgs);
923
924 return Success2;
925}
926
928 DiagnosticsEngine &Diags,
929 const char *Argv0) {
930 CompilerInvocation DummyInvocation1, DummyInvocation2;
931 return RoundTrip(
932 [](CompilerInvocation &Invocation, ArrayRef<const char *> CommandLineArgs,
933 DiagnosticsEngine &Diags, const char *Argv0) {
934 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
935 },
937 StringAllocator SA) {
938 Args.push_back("-cc1");
939 Invocation.generateCC1CommandLine(Args, SA);
940 },
941 DummyInvocation1, DummyInvocation2, Args, Diags, Argv0,
942 /*CheckAgainstOriginalInvocation=*/true, /*ForceRoundTrip=*/true);
943}
944
945static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
946 OptSpecifier GroupWithValue,
947 std::vector<std::string> &Diagnostics) {
948 for (auto *A : Args.filtered(Group)) {
949 if (A->getOption().getKind() == Option::FlagClass) {
950 // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
951 // its name (minus the "W" or "R" at the beginning) to the diagnostics.
952 Diagnostics.push_back(
953 std::string(A->getOption().getName().drop_front(1)));
954 } else if (A->getOption().matches(GroupWithValue)) {
955 // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic
956 // group. Add only the group name to the diagnostics.
957 Diagnostics.push_back(
958 std::string(A->getOption().getName().drop_front(1).rtrim("=-")));
959 } else {
960 // Otherwise, add its value (for OPT_W_Joined and similar).
961 Diagnostics.push_back(A->getValue());
962 }
963 }
964}
965
966// Parse the Static Analyzer configuration. If \p Diags is set to nullptr,
967// it won't verify the input.
968static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts,
969 DiagnosticsEngine *Diags);
970
971static void getAllNoBuiltinFuncValues(ArgList &Args,
972 std::vector<std::string> &Funcs) {
973 std::vector<std::string> Values = Args.getAllArgValues(OPT_fno_builtin_);
974 auto BuiltinEnd = llvm::partition(Values, Builtin::Context::isBuiltinFunc);
975 Funcs.insert(Funcs.end(), Values.begin(), BuiltinEnd);
976}
977
978static void GenerateAnalyzerArgs(const AnalyzerOptions &Opts,
979 ArgumentConsumer Consumer) {
980 const AnalyzerOptions *AnalyzerOpts = &Opts;
981
982#define ANALYZER_OPTION_WITH_MARSHALLING(...) \
983 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
984#include "clang/Driver/Options.inc"
985#undef ANALYZER_OPTION_WITH_MARSHALLING
986
987 if (Opts.AnalysisConstraintsOpt != RangeConstraintsModel) {
988 switch (Opts.AnalysisConstraintsOpt) {
989#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
990 case NAME##Model: \
991 GenerateArg(Consumer, OPT_analyzer_constraints, CMDFLAG); \
992 break;
993#include "clang/StaticAnalyzer/Core/Analyses.def"
994 default:
995 llvm_unreachable("Tried to generate unknown analysis constraint.");
996 }
997 }
998
999 if (Opts.AnalysisDiagOpt != PD_HTML) {
1000 switch (Opts.AnalysisDiagOpt) {
1001#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
1002 case PD_##NAME: \
1003 GenerateArg(Consumer, OPT_analyzer_output, CMDFLAG); \
1004 break;
1005#include "clang/StaticAnalyzer/Core/Analyses.def"
1006 default:
1007 llvm_unreachable("Tried to generate unknown analysis diagnostic client.");
1008 }
1009 }
1010
1011 if (Opts.AnalysisPurgeOpt != PurgeStmt) {
1012 switch (Opts.AnalysisPurgeOpt) {
1013#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
1014 case NAME: \
1015 GenerateArg(Consumer, OPT_analyzer_purge, CMDFLAG); \
1016 break;
1017#include "clang/StaticAnalyzer/Core/Analyses.def"
1018 default:
1019 llvm_unreachable("Tried to generate unknown analysis purge mode.");
1020 }
1021 }
1022
1023 if (Opts.InliningMode != NoRedundancy) {
1024 switch (Opts.InliningMode) {
1025#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
1026 case NAME: \
1027 GenerateArg(Consumer, OPT_analyzer_inlining_mode, CMDFLAG); \
1028 break;
1029#include "clang/StaticAnalyzer/Core/Analyses.def"
1030 default:
1031 llvm_unreachable("Tried to generate unknown analysis inlining mode.");
1032 }
1033 }
1034
1035 for (const auto &CP : Opts.CheckersAndPackages) {
1036 OptSpecifier Opt =
1037 CP.second ? OPT_analyzer_checker : OPT_analyzer_disable_checker;
1038 GenerateArg(Consumer, Opt, CP.first);
1039 }
1040
1041 AnalyzerOptions ConfigOpts;
1042 parseAnalyzerConfigs(ConfigOpts, nullptr);
1043
1044 // Sort options by key to avoid relying on StringMap iteration order.
1046 for (const auto &C : Opts.Config)
1047 SortedConfigOpts.emplace_back(C.getKey(), C.getValue());
1048 llvm::sort(SortedConfigOpts, llvm::less_first());
1049
1050 for (const auto &[Key, Value] : SortedConfigOpts) {
1051 // Don't generate anything that came from parseAnalyzerConfigs. It would be
1052 // redundant and may not be valid on the command line.
1053 auto Entry = ConfigOpts.Config.find(Key);
1054 if (Entry != ConfigOpts.Config.end() && Entry->getValue() == Value)
1055 continue;
1056
1057 GenerateArg(Consumer, OPT_analyzer_config, Key + "=" + Value);
1058 }
1059
1060 // Nothing to generate for FullCompilerInvocation.
1061}
1062
1063static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
1064 DiagnosticsEngine &Diags) {
1065 unsigned NumErrorsBefore = Diags.getNumErrors();
1066
1067 AnalyzerOptions *AnalyzerOpts = &Opts;
1068
1069#define ANALYZER_OPTION_WITH_MARSHALLING(...) \
1070 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
1071#include "clang/Driver/Options.inc"
1072#undef ANALYZER_OPTION_WITH_MARSHALLING
1073
1074 if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {
1075 StringRef Name = A->getValue();
1076 AnalysisConstraints Value = llvm::StringSwitch<AnalysisConstraints>(Name)
1077#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \
1078 .Case(CMDFLAG, NAME##Model)
1079#include "clang/StaticAnalyzer/Core/Analyses.def"
1080 .Default(NumConstraints);
1081 if (Value == NumConstraints) {
1082 Diags.Report(diag::err_drv_invalid_value)
1083 << A->getAsString(Args) << Name;
1084 } else {
1085#ifndef LLVM_WITH_Z3
1086 if (Value == AnalysisConstraints::Z3ConstraintsModel) {
1087 Diags.Report(diag::err_analyzer_not_built_with_z3);
1088 }
1089#endif // LLVM_WITH_Z3
1091 }
1092 }
1093
1094 if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {
1095 StringRef Name = A->getValue();
1096 AnalysisDiagClients Value = llvm::StringSwitch<AnalysisDiagClients>(Name)
1097#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \
1098 .Case(CMDFLAG, PD_##NAME)
1099#include "clang/StaticAnalyzer/Core/Analyses.def"
1100 .Default(NUM_ANALYSIS_DIAG_CLIENTS);
1102 Diags.Report(diag::err_drv_invalid_value)
1103 << A->getAsString(Args) << Name;
1104 } else {
1105 Opts.AnalysisDiagOpt = Value;
1106 }
1107 }
1108
1109 if (Arg *A = Args.getLastArg(OPT_analyzer_purge)) {
1110 StringRef Name = A->getValue();
1111 AnalysisPurgeMode Value = llvm::StringSwitch<AnalysisPurgeMode>(Name)
1112#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \
1113 .Case(CMDFLAG, NAME)
1114#include "clang/StaticAnalyzer/Core/Analyses.def"
1115 .Default(NumPurgeModes);
1116 if (Value == NumPurgeModes) {
1117 Diags.Report(diag::err_drv_invalid_value)
1118 << A->getAsString(Args) << Name;
1119 } else {
1120 Opts.AnalysisPurgeOpt = Value;
1121 }
1122 }
1123
1124 if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {
1125 StringRef Name = A->getValue();
1126 AnalysisInliningMode Value = llvm::StringSwitch<AnalysisInliningMode>(Name)
1127#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \
1128 .Case(CMDFLAG, NAME)
1129#include "clang/StaticAnalyzer/Core/Analyses.def"
1130 .Default(NumInliningModes);
1131 if (Value == NumInliningModes) {
1132 Diags.Report(diag::err_drv_invalid_value)
1133 << A->getAsString(Args) << Name;
1134 } else {
1135 Opts.InliningMode = Value;
1136 }
1137 }
1138
1139 Opts.CheckersAndPackages.clear();
1140 for (const Arg *A :
1141 Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {
1142 A->claim();
1143 bool IsEnabled = A->getOption().getID() == OPT_analyzer_checker;
1144 // We can have a list of comma separated checker names, e.g:
1145 // '-analyzer-checker=cocoa,unix'
1146 StringRef CheckerAndPackageList = A->getValue();
1147 SmallVector<StringRef, 16> CheckersAndPackages;
1148 CheckerAndPackageList.split(CheckersAndPackages, ",");
1149 for (const StringRef &CheckerOrPackage : CheckersAndPackages)
1150 Opts.CheckersAndPackages.emplace_back(std::string(CheckerOrPackage),
1151 IsEnabled);
1152 }
1153
1154 // Go through the analyzer configuration options.
1155 for (const auto *A : Args.filtered(OPT_analyzer_config)) {
1156
1157 // We can have a list of comma separated config names, e.g:
1158 // '-analyzer-config key1=val1,key2=val2'
1159 StringRef configList = A->getValue();
1160 SmallVector<StringRef, 4> configVals;
1161 configList.split(configVals, ",");
1162 for (const auto &configVal : configVals) {
1163 StringRef key, val;
1164 std::tie(key, val) = configVal.split("=");
1165 if (val.empty()) {
1166 Diags.Report(SourceLocation(),
1167 diag::err_analyzer_config_no_value) << configVal;
1168 break;
1169 }
1170 if (val.contains('=')) {
1171 Diags.Report(SourceLocation(),
1172 diag::err_analyzer_config_multiple_values)
1173 << configVal;
1174 break;
1175 }
1176
1177 // TODO: Check checker options too, possibly in CheckerRegistry.
1178 // Leave unknown non-checker configs unclaimed.
1179 if (!key.contains(":") && Opts.isUnknownAnalyzerConfig(key)) {
1181 Diags.Report(diag::err_analyzer_config_unknown) << key;
1182 continue;
1183 }
1184
1185 A->claim();
1186 Opts.Config[key] = std::string(val);
1187 }
1188 }
1189
1191 parseAnalyzerConfigs(Opts, &Diags);
1192 else
1193 parseAnalyzerConfigs(Opts, nullptr);
1194
1195 llvm::raw_string_ostream os(Opts.FullCompilerInvocation);
1196 for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) {
1197 if (i != 0)
1198 os << " ";
1199 os << Args.getArgString(i);
1200 }
1201
1202 return Diags.getNumErrors() == NumErrorsBefore;
1203}
1204
1206 StringRef OptionName, StringRef DefaultVal) {
1207 return Config.insert({OptionName, std::string(DefaultVal)}).first->second;
1208}
1209
1211 DiagnosticsEngine *Diags,
1212 StringRef &OptionField, StringRef Name,
1213 StringRef DefaultVal) {
1214 // String options may be known to invalid (e.g. if the expected string is a
1215 // file name, but the file does not exist), those will have to be checked in
1216 // parseConfigs.
1217 OptionField = getStringOption(Config, Name, DefaultVal);
1218}
1219
1221 DiagnosticsEngine *Diags,
1222 bool &OptionField, StringRef Name, bool DefaultVal) {
1223 auto PossiblyInvalidVal =
1224 llvm::StringSwitch<std::optional<bool>>(
1225 getStringOption(Config, Name, (DefaultVal ? "true" : "false")))
1226 .Case("true", true)
1227 .Case("false", false)
1228 .Default(std::nullopt);
1229
1230 if (!PossiblyInvalidVal) {
1231 if (Diags)
1232 Diags->Report(diag::err_analyzer_config_invalid_input)
1233 << Name << "a boolean";
1234 else
1235 OptionField = DefaultVal;
1236 } else
1237 OptionField = *PossiblyInvalidVal;
1238}
1239
1241 DiagnosticsEngine *Diags,
1242 unsigned &OptionField, StringRef Name,
1243 unsigned DefaultVal) {
1244
1245 OptionField = DefaultVal;
1246 bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal))
1247 .getAsInteger(0, OptionField);
1248 if (Diags && HasFailed)
1249 Diags->Report(diag::err_analyzer_config_invalid_input)
1250 << Name << "an unsigned";
1251}
1252
1254 DiagnosticsEngine *Diags,
1255 PositiveAnalyzerOption &OptionField, StringRef Name,
1256 unsigned DefaultVal) {
1257 auto Parsed = PositiveAnalyzerOption::create(
1258 getStringOption(Config, Name, std::to_string(DefaultVal)));
1259 if (Parsed.has_value()) {
1260 OptionField = Parsed.value();
1261 return;
1262 }
1263 if (Diags && !Parsed.has_value())
1264 Diags->Report(diag::err_analyzer_config_invalid_input)
1265 << Name << "a positive";
1266
1267 OptionField = DefaultVal;
1268}
1269
1271 DiagnosticsEngine *Diags) {
1272 // TODO: There's no need to store the entire configtable, it'd be plenty
1273 // enough to store checker options.
1274
1275#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
1276 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEFAULT_VAL);
1277#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(...)
1278#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1279
1280 assert(AnOpts.UserMode == "shallow" || AnOpts.UserMode == "deep");
1281 const bool InShallowMode = AnOpts.UserMode == "shallow";
1282
1283#define ANALYZER_OPTION(...)
1284#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
1285 SHALLOW_VAL, DEEP_VAL) \
1286 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, \
1287 InShallowMode ? SHALLOW_VAL : DEEP_VAL);
1288#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1289
1290 // At this point, AnalyzerOptions is configured. Let's validate some options.
1291
1292 // FIXME: Here we try to validate the silenced checkers or packages are valid.
1293 // The current approach only validates the registered checkers which does not
1294 // contain the runtime enabled checkers and optimally we would validate both.
1295 if (!AnOpts.RawSilencedCheckersAndPackages.empty()) {
1296 std::vector<StringRef> Checkers =
1297 AnOpts.getRegisteredCheckers(/*IncludeExperimental=*/true);
1298 std::vector<StringRef> Packages =
1299 AnOpts.getRegisteredPackages(/*IncludeExperimental=*/true);
1300
1301 SmallVector<StringRef, 16> CheckersAndPackages;
1302 AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages, ";");
1303
1304 for (const StringRef &CheckerOrPackage : CheckersAndPackages) {
1305 if (Diags) {
1306 bool IsChecker = CheckerOrPackage.contains('.');
1307 bool IsValidName = IsChecker
1308 ? llvm::is_contained(Checkers, CheckerOrPackage)
1309 : llvm::is_contained(Packages, CheckerOrPackage);
1310
1311 if (!IsValidName)
1312 Diags->Report(diag::err_unknown_analyzer_checker_or_package)
1313 << CheckerOrPackage;
1314 }
1315
1316 AnOpts.SilencedCheckersAndPackages.emplace_back(CheckerOrPackage);
1317 }
1318 }
1319
1320 if (!Diags)
1321 return;
1322
1323 if (AnOpts.ShouldTrackConditionsDebug && !AnOpts.ShouldTrackConditions)
1324 Diags->Report(diag::err_analyzer_config_invalid_input)
1325 << "track-conditions-debug" << "'track-conditions' to also be enabled";
1326}
1327
1328/// Generate a remark argument. This is an inverse of `ParseOptimizationRemark`.
1329static void
1331 StringRef Name,
1333 if (Remark.hasValidPattern()) {
1334 GenerateArg(Consumer, OptEQ, Remark.Pattern);
1335 } else if (Remark.Kind == CodeGenOptions::RK_Enabled) {
1336 GenerateArg(Consumer, OPT_R_Joined, Name);
1337 } else if (Remark.Kind == CodeGenOptions::RK_Disabled) {
1338 GenerateArg(Consumer, OPT_R_Joined, StringRef("no-") + Name);
1339 }
1340}
1341
1342/// Parse a remark command line argument. It may be missing, disabled/enabled by
1343/// '-R[no-]group' or specified with a regular expression by '-Rgroup=regexp'.
1344/// On top of that, it can be disabled/enabled globally by '-R[no-]everything'.
1347 OptSpecifier OptEQ, StringRef Name) {
1349
1350 auto InitializeResultPattern = [&Diags, &Args, &Result](const Arg *A,
1351 StringRef Pattern) {
1352 Result.Pattern = Pattern.str();
1353
1354 std::string RegexError;
1355 Result.Regex = std::make_shared<llvm::Regex>(Result.Pattern);
1356 if (!Result.Regex->isValid(RegexError)) {
1357 Diags.Report(diag::err_drv_optimization_remark_pattern)
1358 << RegexError << A->getAsString(Args);
1359 return false;
1360 }
1361
1362 return true;
1363 };
1364
1365 for (Arg *A : Args) {
1366 if (A->getOption().matches(OPT_R_Joined)) {
1367 StringRef Value = A->getValue();
1368
1369 if (Value == Name)
1371 else if (Value == "everything")
1373 else if (Value.split('-') == std::make_pair(StringRef("no"), Name))
1374 Result.Kind = CodeGenOptions::RK_Disabled;
1375 else if (Value == "no-everything")
1377 else
1378 continue;
1379
1380 if (Result.Kind == CodeGenOptions::RK_Disabled ||
1382 Result.Pattern = "";
1383 Result.Regex = nullptr;
1384 } else {
1385 InitializeResultPattern(A, ".*");
1386 }
1387 } else if (A->getOption().matches(OptEQ)) {
1388 Result.Kind = CodeGenOptions::RK_WithPattern;
1389 if (!InitializeResultPattern(A, A->getValue()))
1391 }
1392 }
1393
1394 return Result;
1395}
1396
1397static bool parseDiagnosticLevelMask(StringRef FlagName,
1398 const std::vector<std::string> &Levels,
1399 DiagnosticsEngine &Diags,
1401 bool Success = true;
1402 for (const auto &Level : Levels) {
1403 DiagnosticLevelMask const PM =
1404 llvm::StringSwitch<DiagnosticLevelMask>(Level)
1405 .Case("note", DiagnosticLevelMask::Note)
1406 .Case("remark", DiagnosticLevelMask::Remark)
1407 .Case("warning", DiagnosticLevelMask::Warning)
1408 .Case("error", DiagnosticLevelMask::Error)
1409 .Default(DiagnosticLevelMask::None);
1410 if (PM == DiagnosticLevelMask::None) {
1411 Success = false;
1412 Diags.Report(diag::err_drv_invalid_value) << FlagName << Level;
1413 }
1414 M = M | PM;
1415 }
1416 return Success;
1417}
1418
1419static void parseSanitizerKinds(StringRef FlagName,
1420 const std::vector<std::string> &Sanitizers,
1421 DiagnosticsEngine &Diags, SanitizerSet &S) {
1422 for (const auto &Sanitizer : Sanitizers) {
1423 SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
1424 if (K == SanitizerMask())
1425 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1426 else
1427 S.set(K, true);
1428 }
1429}
1430
1436
1439 const std::vector<std::string> &Sanitizers,
1440 DiagnosticsEngine &Diags) {
1441 SanitizerMaskCutoffs Cutoffs;
1442 for (const auto &Sanitizer : Sanitizers) {
1443 if (!parseSanitizerWeightedValue(Sanitizer, /*AllowGroups=*/false, Cutoffs))
1444 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1445 }
1446 return Cutoffs;
1447}
1448
1449static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle,
1450 ArgList &Args, DiagnosticsEngine &D,
1451 XRayInstrSet &S) {
1453 llvm::SplitString(Bundle, BundleParts, ",");
1454 for (const auto &B : BundleParts) {
1455 auto Mask = parseXRayInstrValue(B);
1456 if (Mask == XRayInstrKind::None)
1457 if (B != "none")
1458 D.Report(diag::err_drv_invalid_value) << FlagName << Bundle;
1459 else
1460 S.Mask = Mask;
1461 else if (Mask == XRayInstrKind::All)
1462 S.Mask = Mask;
1463 else
1464 S.set(Mask, true);
1465 }
1466}
1467
1470 serializeXRayInstrValue(S, BundleParts);
1471 std::string Buffer;
1472 llvm::raw_string_ostream OS(Buffer);
1473 llvm::interleave(BundleParts, OS, [&OS](StringRef Part) { OS << Part; }, ",");
1474 return Buffer;
1475}
1476
1479 const llvm::Triple &Triple) {
1480 assert(Triple.getArch() == llvm::Triple::aarch64);
1481 if (LangOpts.PointerAuthCalls) {
1482 using Key = PointerAuthSchema::ARM8_3Key;
1483 using Discrimination = PointerAuthSchema::Discrimination;
1484 // If you change anything here, be sure to update <ptrauth.h>.
1486 Key::ASIA, false,
1487 LangOpts.PointerAuthFunctionTypeDiscrimination ? Discrimination::Type
1488 : Discrimination::None);
1489
1491 Key::ASDA, LangOpts.PointerAuthVTPtrAddressDiscrimination,
1492 LangOpts.PointerAuthVTPtrTypeDiscrimination ? Discrimination::Type
1493 : Discrimination::None);
1494
1495 if (LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)
1497 PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1499 else
1501 PointerAuthSchema(Key::ASDA, false, Discrimination::None);
1502
1504 PointerAuthSchema(Key::ASDA, false, Discrimination::None);
1506 PointerAuthSchema(Key::ASIA, true, Discrimination::Decl);
1508 PointerAuthSchema(Key::ASIA, false, Discrimination::Type);
1509
1510 if (LangOpts.PointerAuthInitFini) {
1512 Key::ASIA, LangOpts.PointerAuthInitFiniAddressDiscrimination,
1513 Discrimination::Constant, InitFiniPointerConstantDiscriminator);
1514 }
1515
1517 PointerAuthSchema(Key::ASIA, true, Discrimination::None);
1519 PointerAuthSchema(Key::ASIA, true, Discrimination::None);
1521 PointerAuthSchema(Key::ASIA, true, Discrimination::None);
1522 if (LangOpts.PointerAuthBlockDescriptorPointers)
1524 PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1526
1528 PointerAuthSchema(Key::ASIA, true, Discrimination::None);
1530 PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1532 if (LangOpts.PointerAuthObjcIsa) {
1533 Opts.ObjCIsaPointers =
1534 PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1536 Opts.ObjCSuperPointers =
1537 PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1539 }
1540
1541 if (LangOpts.PointerAuthObjcClassROPointers)
1542 Opts.ObjCClassROPointers =
1543 PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1545 }
1546 Opts.ReturnAddresses = LangOpts.PointerAuthReturns;
1547 Opts.AuthTraps = LangOpts.PointerAuthAuthTraps;
1548 Opts.IndirectGotos = LangOpts.PointerAuthIndirectGotos;
1549 Opts.AArch64JumpTableHardening = LangOpts.AArch64JumpTableHardening;
1550}
1551
1553 const LangOptions &LangOpts,
1554 const llvm::Triple &Triple,
1555 DiagnosticsEngine &Diags) {
1556 if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthReturns &&
1557 !LangOpts.PointerAuthAuthTraps && !LangOpts.PointerAuthIndirectGotos &&
1558 !LangOpts.AArch64JumpTableHardening)
1559 return;
1560
1562}
1563
1564void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
1565 ArgumentConsumer Consumer,
1566 const llvm::Triple &T,
1567 const std::string &OutputFile,
1568 const LangOptions *LangOpts) {
1569 const CodeGenOptions &CodeGenOpts = Opts;
1570
1571 if (Opts.OptimizationLevel == 0)
1572 GenerateArg(Consumer, OPT_O0);
1573 else
1574 GenerateArg(Consumer, OPT_O, Twine(Opts.OptimizationLevel));
1575
1576#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1577 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
1578#include "clang/Driver/Options.inc"
1579#undef CODEGEN_OPTION_WITH_MARSHALLING
1580
1581 if (Opts.OptimizationLevel > 0) {
1582 if (Opts.Inlining == CodeGenOptions::NormalInlining)
1583 GenerateArg(Consumer, OPT_finline_functions);
1584 else if (Opts.Inlining == CodeGenOptions::OnlyHintInlining)
1585 GenerateArg(Consumer, OPT_finline_hint_functions);
1586 else if (Opts.Inlining == CodeGenOptions::OnlyAlwaysInlining)
1587 GenerateArg(Consumer, OPT_fno_inline);
1588 }
1589
1590 if (Opts.DirectAccessExternalData && LangOpts->PICLevel != 0)
1591 GenerateArg(Consumer, OPT_fdirect_access_external_data);
1592 else if (!Opts.DirectAccessExternalData && LangOpts->PICLevel == 0)
1593 GenerateArg(Consumer, OPT_fno_direct_access_external_data);
1594
1595 std::optional<StringRef> DebugInfoVal;
1596 switch (Opts.DebugInfo) {
1597 case llvm::codegenoptions::DebugLineTablesOnly:
1598 DebugInfoVal = "line-tables-only";
1599 break;
1600 case llvm::codegenoptions::DebugDirectivesOnly:
1601 DebugInfoVal = "line-directives-only";
1602 break;
1603 case llvm::codegenoptions::DebugInfoConstructor:
1604 DebugInfoVal = "constructor";
1605 break;
1606 case llvm::codegenoptions::LimitedDebugInfo:
1607 DebugInfoVal = "limited";
1608 break;
1609 case llvm::codegenoptions::FullDebugInfo:
1610 DebugInfoVal = "standalone";
1611 break;
1612 case llvm::codegenoptions::UnusedTypeInfo:
1613 DebugInfoVal = "unused-types";
1614 break;
1615 case llvm::codegenoptions::NoDebugInfo: // default value
1616 DebugInfoVal = std::nullopt;
1617 break;
1618 case llvm::codegenoptions::LocTrackingOnly: // implied value
1619 DebugInfoVal = std::nullopt;
1620 break;
1621 }
1622 if (DebugInfoVal)
1623 GenerateArg(Consumer, OPT_debug_info_kind_EQ, *DebugInfoVal);
1624
1625 for (const auto &Prefix : Opts.DebugPrefixMap)
1626 GenerateArg(Consumer, OPT_fdebug_prefix_map_EQ,
1627 Prefix.first + "=" + Prefix.second);
1628
1629 for (const auto &Prefix : Opts.CoveragePrefixMap)
1630 GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,
1631 Prefix.first + "=" + Prefix.second);
1632
1633 if (Opts.NewStructPathTBAA)
1634 GenerateArg(Consumer, OPT_new_struct_path_tbaa);
1635
1636 if (Opts.OptimizeSize == 1)
1637 GenerateArg(Consumer, OPT_O, "s");
1638 else if (Opts.OptimizeSize == 2)
1639 GenerateArg(Consumer, OPT_O, "z");
1640
1641 // SimplifyLibCalls is set only in the absence of -fno-builtin and
1642 // -ffreestanding. We'll consider that when generating them.
1643
1644 // NoBuiltinFuncs are generated by LangOptions.
1645
1646 if (Opts.UnrollLoops && Opts.OptimizationLevel <= 1)
1647 GenerateArg(Consumer, OPT_funroll_loops);
1648 else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1)
1649 GenerateArg(Consumer, OPT_fno_unroll_loops);
1650
1651 if (Opts.InterchangeLoops)
1652 GenerateArg(Consumer, OPT_floop_interchange);
1653 else
1654 GenerateArg(Consumer, OPT_fno_loop_interchange);
1655
1656 if (Opts.FuseLoops)
1657 GenerateArg(Consumer, OPT_fexperimental_loop_fusion);
1658
1659 if (!Opts.BinutilsVersion.empty())
1660 GenerateArg(Consumer, OPT_fbinutils_version_EQ, Opts.BinutilsVersion);
1661
1662 if (Opts.DebugNameTable ==
1663 static_cast<unsigned>(llvm::DICompileUnit::DebugNameTableKind::GNU))
1664 GenerateArg(Consumer, OPT_ggnu_pubnames);
1665 else if (Opts.DebugNameTable ==
1666 static_cast<unsigned>(
1667 llvm::DICompileUnit::DebugNameTableKind::Default))
1668 GenerateArg(Consumer, OPT_gpubnames);
1669
1670 if (Opts.DebugTemplateAlias)
1671 GenerateArg(Consumer, OPT_gtemplate_alias);
1672
1673 auto TNK = Opts.getDebugSimpleTemplateNames();
1674 if (TNK != llvm::codegenoptions::DebugTemplateNamesKind::Full) {
1675 if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Simple)
1676 GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "simple");
1677 else if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Mangled)
1678 GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "mangled");
1679 }
1680 // ProfileInstrumentUsePath is marshalled automatically, no need to generate
1681 // it or PGOUseInstrumentor.
1682
1683 if (Opts.TimePasses) {
1684 if (Opts.TimePassesPerRun)
1685 GenerateArg(Consumer, OPT_ftime_report_EQ, "per-pass-run");
1686 else
1687 GenerateArg(Consumer, OPT_ftime_report);
1688
1689 if (Opts.TimePassesJson)
1690 GenerateArg(Consumer, OPT_ftime_report_json);
1691 }
1692
1693 if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)
1694 GenerateArg(Consumer, OPT_flto_EQ, "full");
1695
1696 if (Opts.PrepareForThinLTO)
1697 GenerateArg(Consumer, OPT_flto_EQ, "thin");
1698
1699 if (!Opts.ThinLTOIndexFile.empty())
1700 GenerateArg(Consumer, OPT_fthinlto_index_EQ, Opts.ThinLTOIndexFile);
1701
1702 if (Opts.SaveTempsFilePrefix == OutputFile)
1703 GenerateArg(Consumer, OPT_save_temps_EQ, "obj");
1704
1705 StringRef MemProfileBasename("memprof.profraw");
1706 if (!Opts.MemoryProfileOutput.empty()) {
1707 if (Opts.MemoryProfileOutput == MemProfileBasename) {
1708 GenerateArg(Consumer, OPT_fmemory_profile);
1709 } else {
1710 size_t ArgLength =
1711 Opts.MemoryProfileOutput.size() - MemProfileBasename.size();
1712 GenerateArg(Consumer, OPT_fmemory_profile_EQ,
1713 Opts.MemoryProfileOutput.substr(0, ArgLength));
1714 }
1715 }
1716
1717 if (memcmp(Opts.CoverageVersion, "0000", 4))
1718 GenerateArg(Consumer, OPT_coverage_version_EQ,
1719 StringRef(Opts.CoverageVersion, 4));
1720
1721 // TODO: Check if we need to generate arguments stored in CmdArgs. (Namely
1722 // '-fembed_bitcode', which does not map to any CompilerInvocation field and
1723 // won't be generated.)
1724
1726 std::string InstrBundle =
1728 if (!InstrBundle.empty())
1729 GenerateArg(Consumer, OPT_fxray_instrumentation_bundle, InstrBundle);
1730 }
1731
1732 if (Opts.CFProtectionReturn && Opts.CFProtectionBranch)
1733 GenerateArg(Consumer, OPT_fcf_protection_EQ, "full");
1734 else if (Opts.CFProtectionReturn)
1735 GenerateArg(Consumer, OPT_fcf_protection_EQ, "return");
1736 else if (Opts.CFProtectionBranch)
1737 GenerateArg(Consumer, OPT_fcf_protection_EQ, "branch");
1738
1739 if (Opts.CFProtectionBranch) {
1740 switch (Opts.getCFBranchLabelScheme()) {
1742 break;
1743#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
1744 case CFBranchLabelSchemeKind::Kind: \
1745 GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, #FlagVal); \
1746 break;
1747#include "clang/Basic/CFProtectionOptions.def"
1748 }
1749 }
1750
1751 if (Opts.FunctionReturnThunks)
1752 GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern");
1753
1754 for (const auto &F : Opts.LinkBitcodeFiles) {
1755 bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded &&
1756 F.PropagateAttrs && F.Internalize;
1757 GenerateArg(Consumer,
1758 Builtint ? OPT_mlink_builtin_bitcode : OPT_mlink_bitcode_file,
1759 F.Filename);
1760 }
1761
1762 if (Opts.EmulatedTLS)
1763 GenerateArg(Consumer, OPT_femulated_tls);
1764
1765 if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE())
1766 GenerateArg(Consumer, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str());
1767
1768 if ((Opts.FPDenormalMode != Opts.FP32DenormalMode) ||
1769 (Opts.FP32DenormalMode != llvm::DenormalMode::getIEEE()))
1770 GenerateArg(Consumer, OPT_fdenormal_fp_math_f32_EQ,
1771 Opts.FP32DenormalMode.str());
1772
1773 if (Opts.StructReturnConvention == CodeGenOptions::SRCK_OnStack) {
1774 OptSpecifier Opt =
1775 T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return;
1776 GenerateArg(Consumer, Opt);
1777 } else if (Opts.StructReturnConvention == CodeGenOptions::SRCK_InRegs) {
1778 OptSpecifier Opt =
1779 T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return;
1780 GenerateArg(Consumer, Opt);
1781 }
1782
1783 if (Opts.EnableAIXExtendedAltivecABI)
1784 GenerateArg(Consumer, OPT_mabi_EQ_vec_extabi);
1785
1786 if (Opts.XCOFFReadOnlyPointers)
1787 GenerateArg(Consumer, OPT_mxcoff_roptr);
1788
1789 if (!Opts.OptRecordPasses.empty())
1790 GenerateArg(Consumer, OPT_opt_record_passes, Opts.OptRecordPasses);
1791
1792 if (!Opts.OptRecordFormat.empty())
1793 GenerateArg(Consumer, OPT_opt_record_format, Opts.OptRecordFormat);
1794
1795 GenerateOptimizationRemark(Consumer, OPT_Rpass_EQ, "pass",
1796 Opts.OptimizationRemark);
1797
1798 GenerateOptimizationRemark(Consumer, OPT_Rpass_missed_EQ, "pass-missed",
1800
1801 GenerateOptimizationRemark(Consumer, OPT_Rpass_analysis_EQ, "pass-analysis",
1803
1804 GenerateArg(Consumer, OPT_fdiagnostics_hotness_threshold_EQ,
1806 ? Twine(*Opts.DiagnosticsHotnessThreshold)
1807 : "auto");
1808
1809 GenerateArg(Consumer, OPT_fdiagnostics_misexpect_tolerance_EQ,
1810 Twine(*Opts.DiagnosticsMisExpectTolerance));
1811
1812 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeRecover))
1813 GenerateArg(Consumer, OPT_fsanitize_recover_EQ, Sanitizer);
1814
1815 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeTrap))
1816 GenerateArg(Consumer, OPT_fsanitize_trap_EQ, Sanitizer);
1817
1818 for (StringRef Sanitizer :
1820 GenerateArg(Consumer, OPT_fsanitize_merge_handlers_EQ, Sanitizer);
1821
1822 SmallVector<std::string, 4> Values;
1824 for (std::string Sanitizer : Values)
1825 GenerateArg(Consumer, OPT_fsanitize_skip_hot_cutoff_EQ, Sanitizer);
1826
1828 GenerateArg(Consumer, OPT_fallow_runtime_check_skip_hot_cutoff_EQ,
1829 std::to_string(*Opts.AllowRuntimeCheckSkipHotCutoff));
1830 }
1831
1832 for (StringRef Sanitizer :
1834 GenerateArg(Consumer, OPT_fsanitize_annotate_debug_info_EQ, Sanitizer);
1835
1836 if (!Opts.EmitVersionIdentMetadata)
1837 GenerateArg(Consumer, OPT_Qn);
1838
1839 switch (Opts.FiniteLoops) {
1841 break;
1843 GenerateArg(Consumer, OPT_ffinite_loops);
1844 break;
1846 GenerateArg(Consumer, OPT_fno_finite_loops);
1847 break;
1848 }
1849
1850 if (Opts.StaticClosure)
1851 GenerateArg(Consumer, OPT_static_libclosure);
1852}
1853
1854bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
1855 InputKind IK,
1856 DiagnosticsEngine &Diags,
1857 const llvm::Triple &T,
1858 const std::string &OutputFile,
1859 const LangOptions &LangOptsRef) {
1860 unsigned NumErrorsBefore = Diags.getNumErrors();
1861
1862 unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
1863 // TODO: This could be done in Driver
1864 unsigned MaxOptLevel = 3;
1865 if (OptimizationLevel > MaxOptLevel) {
1866 // If the optimization level is not supported, fall back on the default
1867 // optimization
1868 Diags.Report(diag::warn_drv_optimization_value)
1869 << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
1870 OptimizationLevel = MaxOptLevel;
1871 }
1872 Opts.OptimizationLevel = OptimizationLevel;
1873
1874 // The key paths of codegen options defined in Options.td start with
1875 // "CodeGenOpts.". Let's provide the expected variable name and type.
1876 CodeGenOptions &CodeGenOpts = Opts;
1877 // Some codegen options depend on language options. Let's provide the expected
1878 // variable name and type.
1879 const LangOptions *LangOpts = &LangOptsRef;
1880
1881#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1882 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
1883#include "clang/Driver/Options.inc"
1884#undef CODEGEN_OPTION_WITH_MARSHALLING
1885
1886 // At O0 we want to fully disable inlining outside of cases marked with
1887 // 'alwaysinline' that are required for correctness.
1888 if (Opts.OptimizationLevel == 0) {
1889 Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
1890 } else if (const Arg *A = Args.getLastArg(options::OPT_finline_functions,
1891 options::OPT_finline_hint_functions,
1892 options::OPT_fno_inline_functions,
1893 options::OPT_fno_inline)) {
1894 // Explicit inlining flags can disable some or all inlining even at
1895 // optimization levels above zero.
1896 if (A->getOption().matches(options::OPT_finline_functions))
1897 Opts.setInlining(CodeGenOptions::NormalInlining);
1898 else if (A->getOption().matches(options::OPT_finline_hint_functions))
1899 Opts.setInlining(CodeGenOptions::OnlyHintInlining);
1900 else
1901 Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
1902 } else {
1903 Opts.setInlining(CodeGenOptions::NormalInlining);
1904 }
1905
1906 // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to
1907 // -fdirect-access-external-data.
1908 Opts.DirectAccessExternalData =
1909 Args.hasArg(OPT_fdirect_access_external_data) ||
1910 (!Args.hasArg(OPT_fno_direct_access_external_data) &&
1911 LangOpts->PICLevel == 0);
1912
1913 if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
1914 unsigned Val =
1915 llvm::StringSwitch<unsigned>(A->getValue())
1916 .Case("line-tables-only", llvm::codegenoptions::DebugLineTablesOnly)
1917 .Case("line-directives-only",
1918 llvm::codegenoptions::DebugDirectivesOnly)
1919 .Case("constructor", llvm::codegenoptions::DebugInfoConstructor)
1920 .Case("limited", llvm::codegenoptions::LimitedDebugInfo)
1921 .Case("standalone", llvm::codegenoptions::FullDebugInfo)
1922 .Case("unused-types", llvm::codegenoptions::UnusedTypeInfo)
1923 .Default(~0U);
1924 if (Val == ~0U)
1925 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1926 << A->getValue();
1927 else
1928 Opts.setDebugInfo(static_cast<llvm::codegenoptions::DebugInfoKind>(Val));
1929 }
1930
1931 // If -fuse-ctor-homing is set and limited debug info is already on, then use
1932 // constructor homing, and vice versa for -fno-use-ctor-homing.
1933 if (const Arg *A =
1934 Args.getLastArg(OPT_fuse_ctor_homing, OPT_fno_use_ctor_homing)) {
1935 if (A->getOption().matches(OPT_fuse_ctor_homing) &&
1936 Opts.getDebugInfo() == llvm::codegenoptions::LimitedDebugInfo)
1937 Opts.setDebugInfo(llvm::codegenoptions::DebugInfoConstructor);
1938 if (A->getOption().matches(OPT_fno_use_ctor_homing) &&
1939 Opts.getDebugInfo() == llvm::codegenoptions::DebugInfoConstructor)
1940 Opts.setDebugInfo(llvm::codegenoptions::LimitedDebugInfo);
1941 }
1942
1943 for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) {
1944 auto Split = StringRef(Arg).split('=');
1945 Opts.DebugPrefixMap.emplace_back(Split.first, Split.second);
1946 }
1947
1948 for (const auto &Arg : Args.getAllArgValues(OPT_fcoverage_prefix_map_EQ)) {
1949 auto Split = StringRef(Arg).split('=');
1950 Opts.CoveragePrefixMap.emplace_back(Split.first, Split.second);
1951 }
1952
1953 const llvm::Triple::ArchType DebugEntryValueArchs[] = {
1954 llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64,
1955 llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips,
1956 llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el,
1957 llvm::Triple::riscv32, llvm::Triple::riscv64};
1958
1959 if (Opts.OptimizationLevel > 0 && Opts.hasReducedDebugInfo() &&
1960 llvm::is_contained(DebugEntryValueArchs, T.getArch()))
1961 Opts.EmitCallSiteInfo = true;
1962
1963 if (!Opts.EnableDIPreservationVerify && Opts.DIBugsReportFilePath.size()) {
1964 Diags.Report(diag::warn_ignoring_verify_debuginfo_preserve_export)
1965 << Opts.DIBugsReportFilePath;
1966 Opts.DIBugsReportFilePath = "";
1967 }
1968
1969 Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
1970 Args.hasArg(OPT_new_struct_path_tbaa);
1971 Opts.OptimizeSize = getOptimizationLevelSize(Args);
1972 Opts.SimplifyLibCalls = !LangOpts->NoBuiltin;
1973 if (Opts.SimplifyLibCalls)
1974 Opts.NoBuiltinFuncs = LangOpts->NoBuiltinFuncs;
1975 Opts.UnrollLoops =
1976 Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
1977 (Opts.OptimizationLevel > 1));
1978 Opts.InterchangeLoops =
1979 Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange, false);
1980 Opts.FuseLoops = Args.hasFlag(OPT_fexperimental_loop_fusion,
1981 OPT_fno_experimental_loop_fusion, false);
1982 Opts.BinutilsVersion =
1983 std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));
1984
1985 Opts.DebugTemplateAlias = Args.hasArg(OPT_gtemplate_alias);
1986
1987 Opts.DebugNameTable = static_cast<unsigned>(
1988 Args.hasArg(OPT_ggnu_pubnames)
1989 ? llvm::DICompileUnit::DebugNameTableKind::GNU
1990 : Args.hasArg(OPT_gpubnames)
1991 ? llvm::DICompileUnit::DebugNameTableKind::Default
1992 : llvm::DICompileUnit::DebugNameTableKind::None);
1993 if (const Arg *A = Args.getLastArg(OPT_gsimple_template_names_EQ)) {
1994 StringRef Value = A->getValue();
1995 if (Value != "simple" && Value != "mangled")
1996 Diags.Report(diag::err_drv_unsupported_option_argument)
1997 << A->getSpelling() << A->getValue();
1998 Opts.setDebugSimpleTemplateNames(
1999 StringRef(A->getValue()) == "simple"
2000 ? llvm::codegenoptions::DebugTemplateNamesKind::Simple
2001 : llvm::codegenoptions::DebugTemplateNamesKind::Mangled);
2002 }
2003
2004 if (Args.hasArg(OPT_ftime_report, OPT_ftime_report_EQ, OPT_ftime_report_json,
2005 OPT_stats_file_timers)) {
2006 Opts.TimePasses = true;
2007
2008 // -ftime-report= is only for new pass manager.
2009 if (const Arg *EQ = Args.getLastArg(OPT_ftime_report_EQ)) {
2010 StringRef Val = EQ->getValue();
2011 if (Val == "per-pass")
2012 Opts.TimePassesPerRun = false;
2013 else if (Val == "per-pass-run")
2014 Opts.TimePassesPerRun = true;
2015 else
2016 Diags.Report(diag::err_drv_invalid_value)
2017 << EQ->getAsString(Args) << EQ->getValue();
2018 }
2019
2020 if (Args.getLastArg(OPT_ftime_report_json))
2021 Opts.TimePassesJson = true;
2022 }
2023
2024 Opts.PrepareForLTO = false;
2025 Opts.PrepareForThinLTO = false;
2026 if (Arg *A = Args.getLastArg(OPT_flto_EQ)) {
2027 Opts.PrepareForLTO = true;
2028 StringRef S = A->getValue();
2029 if (S == "thin")
2030 Opts.PrepareForThinLTO = true;
2031 else if (S != "full")
2032 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
2033 if (Args.hasArg(OPT_funified_lto))
2034 Opts.PrepareForThinLTO = true;
2035 }
2036 if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
2037 if (IK.getLanguage() != Language::LLVM_IR)
2038 Diags.Report(diag::err_drv_argument_only_allowed_with)
2039 << A->getAsString(Args) << "-x ir";
2040 Opts.ThinLTOIndexFile =
2041 std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ));
2042 }
2043 if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))
2044 Opts.SaveTempsFilePrefix =
2045 llvm::StringSwitch<std::string>(A->getValue())
2046 .Case("obj", OutputFile)
2047 .Default(llvm::sys::path::filename(OutputFile).str());
2048
2049 // The memory profile runtime appends the pid to make this name more unique.
2050 const char *MemProfileBasename = "memprof.profraw";
2051 if (Args.hasArg(OPT_fmemory_profile_EQ)) {
2052 SmallString<128> Path(Args.getLastArgValue(OPT_fmemory_profile_EQ));
2053 llvm::sys::path::append(Path, MemProfileBasename);
2054 Opts.MemoryProfileOutput = std::string(Path);
2055 } else if (Args.hasArg(OPT_fmemory_profile))
2056 Opts.MemoryProfileOutput = MemProfileBasename;
2057
2058 if (Opts.CoverageNotesFile.size() || Opts.CoverageDataFile.size()) {
2059 if (Args.hasArg(OPT_coverage_version_EQ)) {
2060 StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
2061 if (CoverageVersion.size() != 4) {
2062 Diags.Report(diag::err_drv_invalid_value)
2063 << Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)
2064 << CoverageVersion;
2065 } else {
2066 memcpy(Opts.CoverageVersion, CoverageVersion.data(), 4);
2067 }
2068 }
2069 }
2070 // FIXME: For backend options that are not yet recorded as function
2071 // attributes in the IR, keep track of them so we can embed them in a
2072 // separate data section and use them when building the bitcode.
2073 for (const auto &A : Args) {
2074 // Do not encode output and input.
2075 if (A->getOption().getID() == options::OPT_o ||
2076 A->getOption().getID() == options::OPT_INPUT ||
2077 A->getOption().getID() == options::OPT_x ||
2078 A->getOption().getID() == options::OPT_fembed_bitcode ||
2079 A->getOption().matches(options::OPT_W_Group))
2080 continue;
2081 ArgStringList ASL;
2082 A->render(Args, ASL);
2083 for (const auto &arg : ASL) {
2084 StringRef ArgStr(arg);
2085 llvm::append_range(Opts.CmdArgs, ArgStr);
2086 // using \00 to separate each commandline options.
2087 Opts.CmdArgs.push_back('\0');
2088 }
2089 }
2090
2091 auto XRayInstrBundles =
2092 Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
2093 if (XRayInstrBundles.empty())
2095 else
2096 for (const auto &A : XRayInstrBundles)
2097 parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args,
2098 Diags, Opts.XRayInstrumentationBundle);
2099
2100 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
2101 StringRef Name = A->getValue();
2102 if (Name == "full") {
2103 Opts.CFProtectionReturn = 1;
2104 Opts.CFProtectionBranch = 1;
2105 } else if (Name == "return")
2106 Opts.CFProtectionReturn = 1;
2107 else if (Name == "branch")
2108 Opts.CFProtectionBranch = 1;
2109 else if (Name != "none")
2110 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
2111 }
2112
2113 if (Opts.CFProtectionBranch && T.isRISCV()) {
2114 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
2115 const auto Scheme =
2116 llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
2117#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
2118 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
2119#include "clang/Basic/CFProtectionOptions.def"
2122 Opts.setCFBranchLabelScheme(Scheme);
2123 else
2124 Diags.Report(diag::err_drv_invalid_value)
2125 << A->getAsString(Args) << A->getValue();
2126 }
2127 }
2128
2129 if (const Arg *A = Args.getLastArg(OPT_mfunction_return_EQ)) {
2130 auto Val = llvm::StringSwitch<llvm::FunctionReturnThunksKind>(A->getValue())
2131 .Case("keep", llvm::FunctionReturnThunksKind::Keep)
2132 .Case("thunk-extern", llvm::FunctionReturnThunksKind::Extern)
2133 .Default(llvm::FunctionReturnThunksKind::Invalid);
2134 // SystemZ might want to add support for "expolines."
2135 if (!T.isX86())
2136 Diags.Report(diag::err_drv_argument_not_allowed_with)
2137 << A->getSpelling() << T.getTriple();
2138 else if (Val == llvm::FunctionReturnThunksKind::Invalid)
2139 Diags.Report(diag::err_drv_invalid_value)
2140 << A->getAsString(Args) << A->getValue();
2141 else if (Val == llvm::FunctionReturnThunksKind::Extern &&
2142 Args.getLastArgValue(OPT_mcmodel_EQ) == "large")
2143 Diags.Report(diag::err_drv_argument_not_allowed_with)
2144 << A->getAsString(Args)
2145 << Args.getLastArg(OPT_mcmodel_EQ)->getAsString(Args);
2146 else
2147 Opts.FunctionReturnThunks = static_cast<unsigned>(Val);
2148 }
2149
2150 for (auto *A :
2151 Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {
2152 CodeGenOptions::BitcodeFileToLink F;
2153 F.Filename = A->getValue();
2154 if (A->getOption().matches(OPT_mlink_builtin_bitcode)) {
2155 F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;
2156 // When linking CUDA bitcode, propagate function attributes so that
2157 // e.g. libdevice gets fast-math attrs if we're building with fast-math.
2158 F.PropagateAttrs = true;
2159 F.Internalize = true;
2160 }
2161 Opts.LinkBitcodeFiles.push_back(F);
2162 }
2163
2164 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
2165 StringRef Val = A->getValue();
2166 Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);
2167 Opts.FP32DenormalMode = Opts.FPDenormalMode;
2168 if (!Opts.FPDenormalMode.isValid())
2169 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2170 }
2171
2172 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_f32_EQ)) {
2173 StringRef Val = A->getValue();
2174 Opts.FP32DenormalMode = llvm::parseDenormalFPAttribute(Val);
2175 if (!Opts.FP32DenormalMode.isValid())
2176 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2177 }
2178
2179 // X86_32 has -fppc-struct-return and -freg-struct-return.
2180 // PPC32 has -maix-struct-return and -msvr4-struct-return.
2181 if (Arg *A =
2182 Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return,
2183 OPT_maix_struct_return, OPT_msvr4_struct_return)) {
2184 // TODO: We might want to consider enabling these options on AIX in the
2185 // future.
2186 if (T.isOSAIX())
2187 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2188 << A->getSpelling() << T.str();
2189
2190 const Option &O = A->getOption();
2191 if (O.matches(OPT_fpcc_struct_return) ||
2192 O.matches(OPT_maix_struct_return)) {
2193 Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack);
2194 } else {
2195 assert(O.matches(OPT_freg_struct_return) ||
2196 O.matches(OPT_msvr4_struct_return));
2197 Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs);
2198 }
2199 }
2200
2201 if (Arg *A = Args.getLastArg(OPT_mxcoff_roptr)) {
2202 if (!T.isOSAIX())
2203 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2204 << A->getSpelling() << T.str();
2205
2206 // Since the storage mapping class is specified per csect,
2207 // without using data sections, it is less effective to use read-only
2208 // pointers. Using read-only pointers may cause other RO variables in the
2209 // same csect to become RW when the linker acts upon `-bforceimprw`;
2210 // therefore, we require that separate data sections
2211 // are used when `-mxcoff-roptr` is in effect. We respect the setting of
2212 // data-sections since we have not found reasons to do otherwise that
2213 // overcome the user surprise of not respecting the setting.
2214 if (!Args.hasFlag(OPT_fdata_sections, OPT_fno_data_sections, false))
2215 Diags.Report(diag::err_roptr_requires_data_sections);
2216
2217 Opts.XCOFFReadOnlyPointers = true;
2218 }
2219
2220 if (Arg *A = Args.getLastArg(OPT_mabi_EQ_quadword_atomics)) {
2221 if (!T.isOSAIX() || T.isPPC32())
2222 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2223 << A->getSpelling() << T.str();
2224 }
2225
2226 bool NeedLocTracking = false;
2227
2228 if (!Opts.OptRecordFile.empty())
2229 NeedLocTracking = true;
2230
2231 if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {
2232 Opts.OptRecordPasses = A->getValue();
2233 NeedLocTracking = true;
2234 }
2235
2236 if (Arg *A = Args.getLastArg(OPT_opt_record_format)) {
2237 Opts.OptRecordFormat = A->getValue();
2238 NeedLocTracking = true;
2239 }
2240
2241 Opts.OptimizationRemark =
2242 ParseOptimizationRemark(Diags, Args, OPT_Rpass_EQ, "pass");
2243
2245 ParseOptimizationRemark(Diags, Args, OPT_Rpass_missed_EQ, "pass-missed");
2246
2248 Diags, Args, OPT_Rpass_analysis_EQ, "pass-analysis");
2249
2250 NeedLocTracking |= Opts.OptimizationRemark.hasValidPattern() ||
2253
2254 bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
2255 bool UsingProfile =
2256 UsingSampleProfile || !Opts.ProfileInstrumentUsePath.empty();
2257
2258 if (Opts.DiagnosticsWithHotness && !UsingProfile &&
2259 // An IR file will contain PGO as metadata
2261 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2262 << "-fdiagnostics-show-hotness";
2263
2264 // Parse remarks hotness threshold. Valid value is either integer or 'auto'.
2265 if (auto *arg =
2266 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
2267 auto ResultOrErr =
2268 llvm::remarks::parseHotnessThresholdOption(arg->getValue());
2269
2270 if (!ResultOrErr) {
2271 Diags.Report(diag::err_drv_invalid_diagnotics_hotness_threshold)
2272 << "-fdiagnostics-hotness-threshold=";
2273 } else {
2274 Opts.DiagnosticsHotnessThreshold = *ResultOrErr;
2275 if ((!Opts.DiagnosticsHotnessThreshold ||
2276 *Opts.DiagnosticsHotnessThreshold > 0) &&
2277 !UsingProfile)
2278 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2279 << "-fdiagnostics-hotness-threshold=";
2280 }
2281 }
2282
2283 if (auto *arg =
2284 Args.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ)) {
2285 auto ResultOrErr = parseToleranceOption(arg->getValue());
2286
2287 if (!ResultOrErr) {
2288 Diags.Report(diag::err_drv_invalid_diagnotics_misexpect_tolerance)
2289 << "-fdiagnostics-misexpect-tolerance=";
2290 } else {
2291 Opts.DiagnosticsMisExpectTolerance = *ResultOrErr;
2292 if ((!Opts.DiagnosticsMisExpectTolerance ||
2293 *Opts.DiagnosticsMisExpectTolerance > 0) &&
2294 !UsingProfile)
2295 Diags.Report(diag::warn_drv_diagnostics_misexpect_requires_pgo)
2296 << "-fdiagnostics-misexpect-tolerance=";
2297 }
2298 }
2299
2300 // If the user requested to use a sample profile for PGO, then the
2301 // backend will need to track source location information so the profile
2302 // can be incorporated into the IR.
2303 if (UsingSampleProfile)
2304 NeedLocTracking = true;
2305
2306 if (!Opts.StackUsageOutput.empty())
2307 NeedLocTracking = true;
2308
2309 // If the user requested a flag that requires source locations available in
2310 // the backend, make sure that the backend tracks source location information.
2311 if (NeedLocTracking &&
2312 Opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo)
2313 Opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
2314
2315 // Parse -fsanitize-recover= arguments.
2316 // FIXME: Report unrecoverable sanitizers incorrectly specified here.
2317 parseSanitizerKinds("-fsanitize-recover=",
2318 Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,
2319 Opts.SanitizeRecover);
2320 parseSanitizerKinds("-fsanitize-trap=",
2321 Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
2322 Opts.SanitizeTrap);
2323 parseSanitizerKinds("-fsanitize-merge=",
2324 Args.getAllArgValues(OPT_fsanitize_merge_handlers_EQ),
2325 Diags, Opts.SanitizeMergeHandlers);
2326
2327 // Parse -fsanitize-skip-hot-cutoff= arguments.
2329 "-fsanitize-skip-hot-cutoff=",
2330 Args.getAllArgValues(OPT_fsanitize_skip_hot_cutoff_EQ), Diags);
2331
2333 "-fsanitize-annotate-debug-info=",
2334 Args.getAllArgValues(OPT_fsanitize_annotate_debug_info_EQ), Diags,
2336
2337 if (StringRef V =
2338 Args.getLastArgValue(OPT_fallow_runtime_check_skip_hot_cutoff_EQ);
2339 !V.empty()) {
2340 double A;
2341 if (V.getAsDouble(A) || A < 0.0 || A > 1.0) {
2342 Diags.Report(diag::err_drv_invalid_value)
2343 << "-fallow-runtime-check-skip-hot-cutoff=" << V;
2344 } else {
2346 }
2347 }
2348
2349 Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
2350
2351 if (!LangOpts->CUDAIsDevice)
2353
2354 if (Args.hasArg(options::OPT_ffinite_loops))
2355 Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Always;
2356 else if (Args.hasArg(options::OPT_fno_finite_loops))
2357 Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Never;
2358
2359 Opts.EmitIEEENaNCompliantInsts = Args.hasFlag(
2360 options::OPT_mamdgpu_ieee, options::OPT_mno_amdgpu_ieee, true);
2361 if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs)
2362 Diags.Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans);
2363
2364 Opts.StaticClosure = Args.hasArg(options::OPT_static_libclosure);
2365
2366 return Diags.getNumErrors() == NumErrorsBefore;
2367}
2368
2370 ArgumentConsumer Consumer) {
2371 const DependencyOutputOptions &DependencyOutputOpts = Opts;
2372#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2373 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2374#include "clang/Driver/Options.inc"
2375#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2376
2378 GenerateArg(Consumer, OPT_show_includes);
2379
2380 for (const auto &Dep : Opts.ExtraDeps) {
2381 switch (Dep.second) {
2383 // Sanitizer ignorelist arguments are generated from LanguageOptions.
2384 continue;
2385 case EDK_ModuleFile:
2386 // Module file arguments are generated from FrontendOptions and
2387 // HeaderSearchOptions.
2388 continue;
2389 case EDK_ProfileList:
2390 // Profile list arguments are generated from LanguageOptions via the
2391 // marshalling infrastructure.
2392 continue;
2393 case EDK_DepFileEntry:
2394 GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first);
2395 break;
2396 }
2397 }
2398}
2399
2401 ArgList &Args, DiagnosticsEngine &Diags,
2403 bool ShowLineMarkers) {
2404 unsigned NumErrorsBefore = Diags.getNumErrors();
2405
2406 DependencyOutputOptions &DependencyOutputOpts = Opts;
2407#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2408 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2409#include "clang/Driver/Options.inc"
2410#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2411
2412 if (Args.hasArg(OPT_show_includes)) {
2413 // Writing both /showIncludes and preprocessor output to stdout
2414 // would produce interleaved output, so use stderr for /showIncludes.
2415 // This behaves the same as cl.exe, when /E, /EP or /P are passed.
2416 if (Action == frontend::PrintPreprocessedInput || !ShowLineMarkers)
2418 else
2420 } else {
2422 }
2423
2424 // Add sanitizer ignorelists as extra dependencies.
2425 // They won't be discovered by the regular preprocessor, so
2426 // we let make / ninja to know about this implicit dependency.
2427 if (!Args.hasArg(OPT_fno_sanitize_ignorelist)) {
2428 for (const auto *A : Args.filtered(OPT_fsanitize_ignorelist_EQ)) {
2429 StringRef Val = A->getValue();
2430 if (!Val.contains('='))
2431 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_SanitizeIgnorelist);
2432 }
2433 if (Opts.IncludeSystemHeaders) {
2434 for (const auto *A : Args.filtered(OPT_fsanitize_system_ignorelist_EQ)) {
2435 StringRef Val = A->getValue();
2436 if (!Val.contains('='))
2437 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_SanitizeIgnorelist);
2438 }
2439 }
2440 }
2441
2442 // -fprofile-list= dependencies.
2443 for (const auto &Filename : Args.getAllArgValues(OPT_fprofile_list_EQ))
2444 Opts.ExtraDeps.emplace_back(Filename, EDK_ProfileList);
2445
2446 // Propagate the extra dependencies.
2447 for (const auto *A : Args.filtered(OPT_fdepfile_entry))
2448 Opts.ExtraDeps.emplace_back(A->getValue(), EDK_DepFileEntry);
2449
2450 // Only the -fmodule-file=<file> form.
2451 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
2452 StringRef Val = A->getValue();
2453 if (!Val.contains('='))
2454 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_ModuleFile);
2455 }
2456
2457 // Check for invalid combinations of header-include-format
2458 // and header-include-filtering.
2459 if (Opts.HeaderIncludeFormat == HIFMT_Textual &&
2461 if (Args.hasArg(OPT_header_include_format_EQ))
2462 Diags.Report(diag::err_drv_print_header_cc1_invalid_combination)
2465 else
2466 Diags.Report(diag::err_drv_print_header_cc1_invalid_filtering)
2468 } else if (Opts.HeaderIncludeFormat == HIFMT_JSON &&
2470 if (Args.hasArg(OPT_header_include_filtering_EQ))
2471 Diags.Report(diag::err_drv_print_header_cc1_invalid_combination)
2474 else
2475 Diags.Report(diag::err_drv_print_header_cc1_invalid_format)
2477 }
2478
2479 return Diags.getNumErrors() == NumErrorsBefore;
2480}
2481
2482static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) {
2483 // Color diagnostics default to auto ("on" if terminal supports) in the driver
2484 // but default to off in cc1, needing an explicit OPT_fdiagnostics_color.
2485 // Support both clang's -f[no-]color-diagnostics and gcc's
2486 // -f[no-]diagnostics-colors[=never|always|auto].
2487 enum {
2488 Colors_On,
2489 Colors_Off,
2490 Colors_Auto
2491 } ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
2492 for (auto *A : Args) {
2493 const Option &O = A->getOption();
2494 if (O.matches(options::OPT_fcolor_diagnostics)) {
2495 ShowColors = Colors_On;
2496 } else if (O.matches(options::OPT_fno_color_diagnostics)) {
2497 ShowColors = Colors_Off;
2498 } else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
2499 StringRef Value(A->getValue());
2500 if (Value == "always")
2501 ShowColors = Colors_On;
2502 else if (Value == "never")
2503 ShowColors = Colors_Off;
2504 else if (Value == "auto")
2505 ShowColors = Colors_Auto;
2506 }
2507 }
2508 return ShowColors == Colors_On ||
2509 (ShowColors == Colors_Auto &&
2510 llvm::sys::Process::StandardErrHasColors());
2511}
2512
2513static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
2514 DiagnosticsEngine &Diags) {
2515 bool Success = true;
2516 for (const auto &Prefix : VerifyPrefixes) {
2517 // Every prefix must start with a letter and contain only alphanumeric
2518 // characters, hyphens, and underscores.
2519 auto BadChar = llvm::find_if(Prefix, [](char C) {
2520 return !isAlphanumeric(C) && C != '-' && C != '_';
2521 });
2522 if (BadChar != Prefix.end() || !isLetter(Prefix[0])) {
2523 Success = false;
2524 Diags.Report(diag::err_drv_invalid_value) << "-verify=" << Prefix;
2525 Diags.Report(diag::note_drv_verify_prefix_spelling);
2526 }
2527 }
2528 return Success;
2529}
2530
2532 ArgumentConsumer Consumer) {
2533 const FileSystemOptions &FileSystemOpts = Opts;
2534
2535#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2536 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2537#include "clang/Driver/Options.inc"
2538#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2539}
2540
2541static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args,
2542 DiagnosticsEngine &Diags) {
2543 unsigned NumErrorsBefore = Diags.getNumErrors();
2544
2545 FileSystemOptions &FileSystemOpts = Opts;
2546
2547#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2548 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2549#include "clang/Driver/Options.inc"
2550#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2551
2552 return Diags.getNumErrors() == NumErrorsBefore;
2553}
2554
2556 ArgumentConsumer Consumer) {
2557 const MigratorOptions &MigratorOpts = Opts;
2558#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2559 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2560#include "clang/Driver/Options.inc"
2561#undef MIGRATOR_OPTION_WITH_MARSHALLING
2562}
2563
2564static bool ParseMigratorArgs(MigratorOptions &Opts, const ArgList &Args,
2565 DiagnosticsEngine &Diags) {
2566 unsigned NumErrorsBefore = Diags.getNumErrors();
2567
2568 MigratorOptions &MigratorOpts = Opts;
2569
2570#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2571 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2572#include "clang/Driver/Options.inc"
2573#undef MIGRATOR_OPTION_WITH_MARSHALLING
2574
2575 return Diags.getNumErrors() == NumErrorsBefore;
2576}
2577
2578void CompilerInvocationBase::GenerateDiagnosticArgs(
2579 const DiagnosticOptions &Opts, ArgumentConsumer Consumer,
2580 bool DefaultDiagColor) {
2581 const DiagnosticOptions *DiagnosticOpts = &Opts;
2582#define DIAG_OPTION_WITH_MARSHALLING(...) \
2583 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2584#include "clang/Driver/Options.inc"
2585#undef DIAG_OPTION_WITH_MARSHALLING
2586
2587 if (!Opts.DiagnosticSerializationFile.empty())
2588 GenerateArg(Consumer, OPT_diagnostic_serialized_file,
2590
2591 if (Opts.ShowColors)
2592 GenerateArg(Consumer, OPT_fcolor_diagnostics);
2593
2594 if (Opts.VerifyDiagnostics &&
2595 llvm::is_contained(Opts.VerifyPrefixes, "expected"))
2596 GenerateArg(Consumer, OPT_verify);
2597
2598 for (const auto &Prefix : Opts.VerifyPrefixes)
2599 if (Prefix != "expected")
2600 GenerateArg(Consumer, OPT_verify_EQ, Prefix);
2601
2602 DiagnosticLevelMask VIU = Opts.getVerifyIgnoreUnexpected();
2603 if (VIU == DiagnosticLevelMask::None) {
2604 // This is the default, don't generate anything.
2605 } else if (VIU == DiagnosticLevelMask::All) {
2606 GenerateArg(Consumer, OPT_verify_ignore_unexpected);
2607 } else {
2608 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Note) != 0)
2609 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "note");
2610 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Remark) != 0)
2611 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "remark");
2612 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Warning) != 0)
2613 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "warning");
2614 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Error) != 0)
2615 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "error");
2616 }
2617
2618 for (const auto &Warning : Opts.Warnings) {
2619 // This option is automatically generated from UndefPrefixes.
2620 if (Warning == "undef-prefix")
2621 continue;
2622 // This option is automatically generated from CheckConstexprFunctionBodies.
2623 if (Warning == "invalid-constexpr" || Warning == "no-invalid-constexpr")
2624 continue;
2625 Consumer(StringRef("-W") + Warning);
2626 }
2627
2628 for (const auto &Remark : Opts.Remarks) {
2629 // These arguments are generated from OptimizationRemark fields of
2630 // CodeGenOptions.
2631 StringRef IgnoredRemarks[] = {"pass", "no-pass",
2632 "pass-analysis", "no-pass-analysis",
2633 "pass-missed", "no-pass-missed"};
2634 if (llvm::is_contained(IgnoredRemarks, Remark))
2635 continue;
2636
2637 Consumer(StringRef("-R") + Remark);
2638 }
2639
2640 if (!Opts.DiagnosticSuppressionMappingsFile.empty()) {
2641 GenerateArg(Consumer, OPT_warning_suppression_mappings_EQ,
2643 }
2644}
2645
2646std::unique_ptr<DiagnosticOptions>
2648 auto DiagOpts = std::make_unique<DiagnosticOptions>();
2649 unsigned MissingArgIndex, MissingArgCount;
2650 InputArgList Args = getDriverOptTable().ParseArgs(
2651 Argv.slice(1), MissingArgIndex, MissingArgCount);
2652
2653 bool ShowColors = true;
2654 if (std::optional<std::string> NoColor =
2655 llvm::sys::Process::GetEnv("NO_COLOR");
2656 NoColor && !NoColor->empty()) {
2657 // If the user set the NO_COLOR environment variable, we'll honor that
2658 // unless the command line overrides it.
2659 ShowColors = false;
2660 }
2661
2662 // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
2663 // Any errors that would be diagnosed here will also be diagnosed later,
2664 // when the DiagnosticsEngine actually exists.
2665 (void)ParseDiagnosticArgs(*DiagOpts, Args, /*Diags=*/nullptr, ShowColors);
2666 return DiagOpts;
2667}
2668
2669bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
2670 DiagnosticsEngine *Diags,
2671 bool DefaultDiagColor) {
2672 std::optional<DiagnosticOptions> IgnoringDiagOpts;
2673 std::optional<DiagnosticsEngine> IgnoringDiags;
2674 if (!Diags) {
2675 IgnoringDiagOpts.emplace();
2676 IgnoringDiags.emplace(DiagnosticIDs::create(), *IgnoringDiagOpts,
2677 new IgnoringDiagConsumer());
2678 Diags = &*IgnoringDiags;
2679 }
2680
2681 unsigned NumErrorsBefore = Diags->getNumErrors();
2682
2683 // The key paths of diagnostic options defined in Options.td start with
2684 // "DiagnosticOpts->". Let's provide the expected variable name and type.
2685 DiagnosticOptions *DiagnosticOpts = &Opts;
2686
2687#define DIAG_OPTION_WITH_MARSHALLING(...) \
2688 PARSE_OPTION_WITH_MARSHALLING(Args, *Diags, __VA_ARGS__)
2689#include "clang/Driver/Options.inc"
2690#undef DIAG_OPTION_WITH_MARSHALLING
2691
2692 llvm::sys::Process::UseANSIEscapeCodes(Opts.UseANSIEscapeCodes);
2693
2694 if (Arg *A =
2695 Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))
2696 Opts.DiagnosticSerializationFile = A->getValue();
2697 Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor);
2698
2699 Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ);
2700 Opts.VerifyPrefixes = Args.getAllArgValues(OPT_verify_EQ);
2701 if (Args.hasArg(OPT_verify))
2702 Opts.VerifyPrefixes.push_back("expected");
2703 // Keep VerifyPrefixes in its original order for the sake of diagnostics, and
2704 // then sort it to prepare for fast lookup using std::binary_search.
2705 if (!checkVerifyPrefixes(Opts.VerifyPrefixes, *Diags))
2706 Opts.VerifyDiagnostics = false;
2707 else
2708 llvm::sort(Opts.VerifyPrefixes);
2711 "-verify-ignore-unexpected=",
2712 Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), *Diags, DiagMask);
2713 if (Args.hasArg(OPT_verify_ignore_unexpected))
2714 DiagMask = DiagnosticLevelMask::All;
2715 Opts.setVerifyIgnoreUnexpected(DiagMask);
2716 if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
2717 Diags->Report(diag::warn_ignoring_ftabstop_value)
2718 << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
2719 Opts.TabStop = DiagnosticOptions::DefaultTabStop;
2720 }
2721
2722 if (const Arg *A = Args.getLastArg(OPT_warning_suppression_mappings_EQ))
2723 Opts.DiagnosticSuppressionMappingsFile = A->getValue();
2724
2725 addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
2726 addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
2727
2728 return Diags->getNumErrors() == NumErrorsBefore;
2729}
2730
2731/// Parse the argument to the -ftest-module-file-extension
2732/// command-line argument.
2733///
2734/// \returns true on error, false on success.
2735static bool parseTestModuleFileExtensionArg(StringRef Arg,
2736 std::string &BlockName,
2737 unsigned &MajorVersion,
2738 unsigned &MinorVersion,
2739 bool &Hashed,
2740 std::string &UserInfo) {
2742 Arg.split(Args, ':', 5);
2743 if (Args.size() < 5)
2744 return true;
2745
2746 BlockName = std::string(Args[0]);
2747 if (Args[1].getAsInteger(10, MajorVersion)) return true;
2748 if (Args[2].getAsInteger(10, MinorVersion)) return true;
2749 if (Args[3].getAsInteger(2, Hashed)) return true;
2750 if (Args.size() > 4)
2751 UserInfo = std::string(Args[4]);
2752 return false;
2753}
2754
2755/// Return a table that associates command line option specifiers with the
2756/// frontend action. Note: The pair {frontend::PluginAction, OPT_plugin} is
2757/// intentionally missing, as this case is handled separately from other
2758/// frontend options.
2759static const auto &getFrontendActionTable() {
2760 static const std::pair<frontend::ActionKind, unsigned> Table[] = {
2761 {frontend::ASTDeclList, OPT_ast_list},
2762
2763 {frontend::ASTDump, OPT_ast_dump_all_EQ},
2764 {frontend::ASTDump, OPT_ast_dump_all},
2765 {frontend::ASTDump, OPT_ast_dump_EQ},
2766 {frontend::ASTDump, OPT_ast_dump},
2767 {frontend::ASTDump, OPT_ast_dump_lookups},
2768 {frontend::ASTDump, OPT_ast_dump_decl_types},
2769
2770 {frontend::ASTPrint, OPT_ast_print},
2771 {frontend::ASTView, OPT_ast_view},
2772 {frontend::DumpCompilerOptions, OPT_compiler_options_dump},
2773 {frontend::DumpRawTokens, OPT_dump_raw_tokens},
2774 {frontend::DumpTokens, OPT_dump_tokens},
2775 {frontend::EmitAssembly, OPT_S},
2776 {frontend::EmitBC, OPT_emit_llvm_bc},
2777 {frontend::EmitCIR, OPT_emit_cir},
2778 {frontend::EmitHTML, OPT_emit_html},
2779 {frontend::EmitLLVM, OPT_emit_llvm},
2780 {frontend::EmitLLVMOnly, OPT_emit_llvm_only},
2781 {frontend::EmitCodeGenOnly, OPT_emit_codegen_only},
2782 {frontend::EmitObj, OPT_emit_obj},
2783 {frontend::ExtractAPI, OPT_extract_api},
2784
2785 {frontend::FixIt, OPT_fixit_EQ},
2786 {frontend::FixIt, OPT_fixit},
2787
2788 {frontend::GenerateModule, OPT_emit_module},
2789 {frontend::GenerateModuleInterface, OPT_emit_module_interface},
2791 OPT_emit_reduced_module_interface},
2792 {frontend::GenerateHeaderUnit, OPT_emit_header_unit},
2793 {frontend::GeneratePCH, OPT_emit_pch},
2794 {frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs},
2795 {frontend::InitOnly, OPT_init_only},
2796 {frontend::ParseSyntaxOnly, OPT_fsyntax_only},
2797 {frontend::ModuleFileInfo, OPT_module_file_info},
2798 {frontend::VerifyPCH, OPT_verify_pch},
2799 {frontend::PrintPreamble, OPT_print_preamble},
2801 {frontend::TemplightDump, OPT_templight_dump},
2802 {frontend::RewriteMacros, OPT_rewrite_macros},
2803 {frontend::RewriteObjC, OPT_rewrite_objc},
2804 {frontend::RewriteTest, OPT_rewrite_test},
2805 {frontend::RunAnalysis, OPT_analyze},
2806 {frontend::RunPreprocessorOnly, OPT_Eonly},
2808 OPT_print_dependency_directives_minimized_source},
2809 };
2810
2811 return Table;
2812}
2813
2814/// Maps command line option to frontend action.
2815static std::optional<frontend::ActionKind>
2816getFrontendAction(OptSpecifier &Opt) {
2817 for (const auto &ActionOpt : getFrontendActionTable())
2818 if (ActionOpt.second == Opt.getID())
2819 return ActionOpt.first;
2820
2821 return std::nullopt;
2822}
2823
2824/// Maps frontend action to command line option.
2825static std::optional<OptSpecifier>
2827 for (const auto &ActionOpt : getFrontendActionTable())
2828 if (ActionOpt.first == ProgramAction)
2829 return OptSpecifier(ActionOpt.second);
2830
2831 return std::nullopt;
2832}
2833
2835 ArgumentConsumer Consumer, bool IsHeader) {
2836 const FrontendOptions &FrontendOpts = Opts;
2837#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2838 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2839#include "clang/Driver/Options.inc"
2840#undef FRONTEND_OPTION_WITH_MARSHALLING
2841
2842 std::optional<OptSpecifier> ProgramActionOpt =
2844
2845 // Generating a simple flag covers most frontend actions.
2846 std::function<void()> GenerateProgramAction = [&]() {
2847 GenerateArg(Consumer, *ProgramActionOpt);
2848 };
2849
2850 if (!ProgramActionOpt) {
2851 // PluginAction is the only program action handled separately.
2852 assert(Opts.ProgramAction == frontend::PluginAction &&
2853 "Frontend action without option.");
2854 GenerateProgramAction = [&]() {
2855 GenerateArg(Consumer, OPT_plugin, Opts.ActionName);
2856 };
2857 }
2858
2859 // FIXME: Simplify the complex 'AST dump' command line.
2860 if (Opts.ProgramAction == frontend::ASTDump) {
2861 GenerateProgramAction = [&]() {
2862 // ASTDumpLookups, ASTDumpDeclTypes and ASTDumpFilter are generated via
2863 // marshalling infrastructure.
2864
2865 if (Opts.ASTDumpFormat != ADOF_Default) {
2866 StringRef Format;
2867 switch (Opts.ASTDumpFormat) {
2868 case ADOF_Default:
2869 llvm_unreachable("Default AST dump format.");
2870 case ADOF_JSON:
2871 Format = "json";
2872 break;
2873 }
2874
2875 if (Opts.ASTDumpAll)
2876 GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);
2877 if (Opts.ASTDumpDecls)
2878 GenerateArg(Consumer, OPT_ast_dump_EQ, Format);
2879 } else {
2880 if (Opts.ASTDumpAll)
2881 GenerateArg(Consumer, OPT_ast_dump_all);
2882 if (Opts.ASTDumpDecls)
2883 GenerateArg(Consumer, OPT_ast_dump);
2884 }
2885 };
2886 }
2887
2888 if (Opts.ProgramAction == frontend::FixIt && !Opts.FixItSuffix.empty()) {
2889 GenerateProgramAction = [&]() {
2890 GenerateArg(Consumer, OPT_fixit_EQ, Opts.FixItSuffix);
2891 };
2892 }
2893
2894 GenerateProgramAction();
2895
2896 for (const auto &PluginArgs : Opts.PluginArgs) {
2897 Option Opt = getDriverOptTable().getOption(OPT_plugin_arg);
2898 for (const auto &PluginArg : PluginArgs.second)
2899 denormalizeString(Consumer,
2900 Opt.getPrefix() + Opt.getName() + PluginArgs.first,
2901 Opt.getKind(), 0, PluginArg);
2902 }
2903
2904 for (const auto &Ext : Opts.ModuleFileExtensions)
2905 if (auto *TestExt = dyn_cast_or_null<TestModuleFileExtension>(Ext.get()))
2906 GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());
2907
2908 if (!Opts.CodeCompletionAt.FileName.empty())
2909 GenerateArg(Consumer, OPT_code_completion_at,
2910 Opts.CodeCompletionAt.ToString());
2911
2912 for (const auto &Plugin : Opts.Plugins)
2913 GenerateArg(Consumer, OPT_load, Plugin);
2914
2915 // ASTDumpDecls and ASTDumpAll already handled with ProgramAction.
2916
2917 for (const auto &ModuleFile : Opts.ModuleFiles)
2918 GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);
2919
2920 if (Opts.AuxTargetCPU)
2921 GenerateArg(Consumer, OPT_aux_target_cpu, *Opts.AuxTargetCPU);
2922
2923 if (Opts.AuxTargetFeatures)
2924 for (const auto &Feature : *Opts.AuxTargetFeatures)
2925 GenerateArg(Consumer, OPT_aux_target_feature, Feature);
2926
2927 {
2928 StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";
2929 StringRef ModuleMap =
2930 Opts.DashX.getFormat() == InputKind::ModuleMap ? "-module-map" : "";
2931 StringRef HeaderUnit = "";
2932 switch (Opts.DashX.getHeaderUnitKind()) {
2934 break;
2936 HeaderUnit = "-user";
2937 break;
2939 HeaderUnit = "-system";
2940 break;
2942 HeaderUnit = "-header-unit";
2943 break;
2944 }
2945 StringRef Header = IsHeader ? "-header" : "";
2946
2947 StringRef Lang;
2948 switch (Opts.DashX.getLanguage()) {
2949 case Language::C:
2950 Lang = "c";
2951 break;
2952 case Language::OpenCL:
2953 Lang = "cl";
2954 break;
2956 Lang = "clcpp";
2957 break;
2958 case Language::CUDA:
2959 Lang = "cuda";
2960 break;
2961 case Language::HIP:
2962 Lang = "hip";
2963 break;
2964 case Language::CXX:
2965 Lang = "c++";
2966 break;
2967 case Language::ObjC:
2968 Lang = "objective-c";
2969 break;
2970 case Language::ObjCXX:
2971 Lang = "objective-c++";
2972 break;
2973 case Language::Asm:
2974 Lang = "assembler-with-cpp";
2975 break;
2976 case Language::Unknown:
2977 assert(Opts.DashX.getFormat() == InputKind::Precompiled &&
2978 "Generating -x argument for unknown language (not precompiled).");
2979 Lang = "ast";
2980 break;
2981 case Language::LLVM_IR:
2982 Lang = "ir";
2983 break;
2984 case Language::HLSL:
2985 Lang = "hlsl";
2986 break;
2987 case Language::CIR:
2988 Lang = "cir";
2989 break;
2990 }
2991
2992 GenerateArg(Consumer, OPT_x,
2993 Lang + HeaderUnit + Header + ModuleMap + Preprocessed);
2994 }
2995
2996 // OPT_INPUT has a unique class, generate it directly.
2997 for (const auto &Input : Opts.Inputs)
2998 Consumer(Input.getFile());
2999}
3000
3001static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
3002 DiagnosticsEngine &Diags, bool &IsHeaderFile) {
3003 unsigned NumErrorsBefore = Diags.getNumErrors();
3004
3005 FrontendOptions &FrontendOpts = Opts;
3006
3007#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
3008 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3009#include "clang/Driver/Options.inc"
3010#undef FRONTEND_OPTION_WITH_MARSHALLING
3011
3013 if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
3014 OptSpecifier Opt = OptSpecifier(A->getOption().getID());
3015 std::optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt);
3016 assert(ProgramAction && "Option specifier not in Action_Group.");
3017
3018 if (ProgramAction == frontend::ASTDump &&
3019 (Opt == OPT_ast_dump_all_EQ || Opt == OPT_ast_dump_EQ)) {
3020 unsigned Val = llvm::StringSwitch<unsigned>(A->getValue())
3021 .CaseLower("default", ADOF_Default)
3022 .CaseLower("json", ADOF_JSON)
3023 .Default(std::numeric_limits<unsigned>::max());
3024
3025 if (Val != std::numeric_limits<unsigned>::max())
3026 Opts.ASTDumpFormat = static_cast<ASTDumpOutputFormat>(Val);
3027 else {
3028 Diags.Report(diag::err_drv_invalid_value)
3029 << A->getAsString(Args) << A->getValue();
3031 }
3032 }
3033
3034 if (ProgramAction == frontend::FixIt && Opt == OPT_fixit_EQ)
3035 Opts.FixItSuffix = A->getValue();
3036
3037 if (ProgramAction == frontend::GenerateInterfaceStubs) {
3038 StringRef ArgStr =
3039 Args.hasArg(OPT_interface_stub_version_EQ)
3040 ? Args.getLastArgValue(OPT_interface_stub_version_EQ)
3041 : "ifs-v1";
3042 if (ArgStr == "experimental-yaml-elf-v1" ||
3043 ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-ifs-v2" ||
3044 ArgStr == "experimental-tapi-elf-v1") {
3045 std::string ErrorMessage =
3046 "Invalid interface stub format: " + ArgStr.str() +
3047 " is deprecated.";
3048 Diags.Report(diag::err_drv_invalid_value)
3049 << "Must specify a valid interface stub format type, ie: "
3050 "-interface-stub-version=ifs-v1"
3051 << ErrorMessage;
3052 ProgramAction = frontend::ParseSyntaxOnly;
3053 } else if (!ArgStr.starts_with("ifs-")) {
3054 std::string ErrorMessage =
3055 "Invalid interface stub format: " + ArgStr.str() + ".";
3056 Diags.Report(diag::err_drv_invalid_value)
3057 << "Must specify a valid interface stub format type, ie: "
3058 "-interface-stub-version=ifs-v1"
3059 << ErrorMessage;
3060 ProgramAction = frontend::ParseSyntaxOnly;
3061 }
3062 }
3063
3064 Opts.ProgramAction = *ProgramAction;
3065
3066 // Catch common mistakes when multiple actions are specified for cc1 (e.g.
3067 // -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to
3068 // support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name
3069 // X ACTION), we suppress the error when the two actions are separated by
3070 // -main-file-name.
3071 //
3072 // As an exception, accept composable -ast-dump*.
3073 if (!A->getSpelling().starts_with("-ast-dump")) {
3074 const Arg *SavedAction = nullptr;
3075 for (const Arg *AA :
3076 Args.filtered(OPT_Action_Group, OPT_main_file_name)) {
3077 if (AA->getOption().matches(OPT_main_file_name)) {
3078 SavedAction = nullptr;
3079 } else if (!SavedAction) {
3080 SavedAction = AA;
3081 } else {
3082 if (!A->getOption().matches(OPT_ast_dump_EQ))
3083 Diags.Report(diag::err_fe_invalid_multiple_actions)
3084 << SavedAction->getSpelling() << A->getSpelling();
3085 break;
3086 }
3087 }
3088 }
3089 }
3090
3091 if (const Arg* A = Args.getLastArg(OPT_plugin)) {
3092 Opts.Plugins.emplace_back(A->getValue(0));
3094 Opts.ActionName = A->getValue();
3095 }
3096 for (const auto *AA : Args.filtered(OPT_plugin_arg))
3097 Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
3098
3099 for (const std::string &Arg :
3100 Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
3101 std::string BlockName;
3102 unsigned MajorVersion;
3103 unsigned MinorVersion;
3104 bool Hashed;
3105 std::string UserInfo;
3106 if (parseTestModuleFileExtensionArg(Arg, BlockName, MajorVersion,
3107 MinorVersion, Hashed, UserInfo)) {
3108 Diags.Report(diag::err_test_module_file_extension_format) << Arg;
3109
3110 continue;
3111 }
3112
3113 // Add the testing module file extension.
3114 Opts.ModuleFileExtensions.push_back(
3115 std::make_shared<TestModuleFileExtension>(
3116 BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
3117 }
3118
3119 if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
3120 Opts.CodeCompletionAt =
3121 ParsedSourceLocation::FromString(A->getValue());
3122 if (Opts.CodeCompletionAt.FileName.empty()) {
3123 Diags.Report(diag::err_drv_invalid_value)
3124 << A->getAsString(Args) << A->getValue();
3125 Diags.Report(diag::note_command_line_code_loc_requirement);
3126 }
3127 }
3128
3129 Opts.Plugins = Args.getAllArgValues(OPT_load);
3130 Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);
3131 Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);
3132 // Only the -fmodule-file=<file> form.
3133 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3134 StringRef Val = A->getValue();
3135 if (!Val.contains('='))
3136 Opts.ModuleFiles.push_back(std::string(Val));
3137 }
3138
3140 Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"
3141 << "-emit-module";
3142 if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_cir))
3143 Opts.UseClangIRPipeline = true;
3144
3145#if CLANG_ENABLE_CIR
3146 if (Args.hasArg(OPT_clangir_disable_passes))
3147 Opts.ClangIRDisablePasses = true;
3148
3149 if (Args.hasArg(OPT_clangir_disable_verifier))
3150 Opts.ClangIRDisableCIRVerifier = true;
3151#endif // CLANG_ENABLE_CIR
3152
3153 if (Args.hasArg(OPT_aux_target_cpu))
3154 Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu));
3155 if (Args.hasArg(OPT_aux_target_feature))
3156 Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature);
3157
3159 if (const Arg *A = Args.getLastArg(OPT_x)) {
3160 StringRef XValue = A->getValue();
3161
3162 // Parse suffixes:
3163 // '<lang>(-[{header-unit,user,system}-]header|[-module-map][-cpp-output])'.
3164 // FIXME: Supporting '<lang>-header-cpp-output' would be useful.
3165 bool Preprocessed = XValue.consume_back("-cpp-output");
3166 bool ModuleMap = XValue.consume_back("-module-map");
3167 // Detect and consume the header indicator.
3168 bool IsHeader =
3169 XValue != "precompiled-header" && XValue.consume_back("-header");
3170
3171 // If we have c++-{user,system}-header, that indicates a header unit input
3172 // likewise, if the user put -fmodule-header together with a header with an
3173 // absolute path (header-unit-header).
3175 if (IsHeader || Preprocessed) {
3176 if (XValue.consume_back("-header-unit"))
3178 else if (XValue.consume_back("-system"))
3180 else if (XValue.consume_back("-user"))
3182 }
3183
3184 // The value set by this processing is an un-preprocessed source which is
3185 // not intended to be a module map or header unit.
3186 IsHeaderFile = IsHeader && !Preprocessed && !ModuleMap &&
3188
3189 // Principal languages.
3190 DashX = llvm::StringSwitch<InputKind>(XValue)
3191 .Case("c", Language::C)
3192 .Case("cl", Language::OpenCL)
3193 .Case("clcpp", Language::OpenCLCXX)
3194 .Case("cuda", Language::CUDA)
3195 .Case("hip", Language::HIP)
3196 .Case("c++", Language::CXX)
3197 .Case("objective-c", Language::ObjC)
3198 .Case("objective-c++", Language::ObjCXX)
3199 .Case("hlsl", Language::HLSL)
3200 .Default(Language::Unknown);
3201
3202 // "objc[++]-cpp-output" is an acceptable synonym for
3203 // "objective-c[++]-cpp-output".
3204 if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap &&
3206 DashX = llvm::StringSwitch<InputKind>(XValue)
3207 .Case("objc", Language::ObjC)
3208 .Case("objc++", Language::ObjCXX)
3209 .Default(Language::Unknown);
3210
3211 // Some special cases cannot be combined with suffixes.
3212 if (DashX.isUnknown() && !Preprocessed && !IsHeaderFile && !ModuleMap &&
3214 DashX = llvm::StringSwitch<InputKind>(XValue)
3215 .Case("cpp-output", InputKind(Language::C).getPreprocessed())
3216 .Case("assembler-with-cpp", Language::Asm)
3217 .Cases("ast", "pcm", "precompiled-header",
3219 .Case("ir", Language::LLVM_IR)
3220 .Case("cir", Language::CIR)
3221 .Default(Language::Unknown);
3222
3223 if (DashX.isUnknown())
3224 Diags.Report(diag::err_drv_invalid_value)
3225 << A->getAsString(Args) << A->getValue();
3226
3227 if (Preprocessed)
3228 DashX = DashX.getPreprocessed();
3229 // A regular header is considered mutually exclusive with a header unit.
3230 if (HUK != InputKind::HeaderUnit_None) {
3231 DashX = DashX.withHeaderUnit(HUK);
3232 IsHeaderFile = true;
3233 } else if (IsHeaderFile)
3234 DashX = DashX.getHeader();
3235 if (ModuleMap)
3236 DashX = DashX.withFormat(InputKind::ModuleMap);
3237 }
3238
3239 // '-' is the default input if none is given.
3240 std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
3241 Opts.Inputs.clear();
3242 if (Inputs.empty())
3243 Inputs.push_back("-");
3244
3246 Inputs.size() > 1)
3247 Diags.Report(diag::err_drv_header_unit_extra_inputs) << Inputs[1];
3248
3249 for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
3250 InputKind IK = DashX;
3251 if (IK.isUnknown()) {
3253 StringRef(Inputs[i]).rsplit('.').second);
3254 // FIXME: Warn on this?
3255 if (IK.isUnknown())
3256 IK = Language::C;
3257 // FIXME: Remove this hack.
3258 if (i == 0)
3259 DashX = IK;
3260 }
3261
3262 bool IsSystem = false;
3263
3264 // The -emit-module action implicitly takes a module map.
3266 IK.getFormat() == InputKind::Source) {
3268 IsSystem = Opts.IsSystemModule;
3269 }
3270
3271 Opts.Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem);
3272 }
3273
3274 Opts.DashX = DashX;
3275
3276 return Diags.getNumErrors() == NumErrorsBefore;
3277}
3278
3279std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
3280 void *MainAddr) {
3281 std::string ClangExecutable =
3282 llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
3283 return Driver::GetResourcesPath(ClangExecutable);
3284}
3285
3287 ArgumentConsumer Consumer) {
3288 const HeaderSearchOptions *HeaderSearchOpts = &Opts;
3289#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3290 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3291#include "clang/Driver/Options.inc"
3292#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3293
3294 if (Opts.UseLibcxx)
3295 GenerateArg(Consumer, OPT_stdlib_EQ, "libc++");
3296
3297 for (const auto &File : Opts.PrebuiltModuleFiles)
3298 GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second);
3299
3300 for (const auto &Path : Opts.PrebuiltModulePaths)
3301 GenerateArg(Consumer, OPT_fprebuilt_module_path, Path);
3302
3303 for (const auto &Macro : Opts.ModulesIgnoreMacros)
3304 GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val());
3305
3306 auto Matches = [](const HeaderSearchOptions::Entry &Entry,
3308 std::optional<bool> IsFramework,
3309 std::optional<bool> IgnoreSysRoot) {
3310 return llvm::is_contained(Groups, Entry.Group) &&
3311 (!IsFramework || (Entry.IsFramework == *IsFramework)) &&
3312 (!IgnoreSysRoot || (Entry.IgnoreSysRoot == *IgnoreSysRoot));
3313 };
3314
3315 auto It = Opts.UserEntries.begin();
3316 auto End = Opts.UserEntries.end();
3317
3318 // Add -I... and -F... options in order.
3319 for (; It < End && Matches(*It, {frontend::Angled}, std::nullopt, true);
3320 ++It) {
3321 OptSpecifier Opt = [It, Matches]() {
3322 if (Matches(*It, frontend::Angled, true, true))
3323 return OPT_F;
3324 if (Matches(*It, frontend::Angled, false, true))
3325 return OPT_I;
3326 llvm_unreachable("Unexpected HeaderSearchOptions::Entry.");
3327 }();
3328
3329 GenerateArg(Consumer, Opt, It->Path);
3330 }
3331
3332 // Note: some paths that came from "[-iprefix=xx] -iwithprefixbefore=yy" may
3333 // have already been generated as "-I[xx]yy". If that's the case, their
3334 // position on command line was such that this has no semantic impact on
3335 // include paths.
3336 for (; It < End &&
3337 Matches(*It, {frontend::After, frontend::Angled}, false, true);
3338 ++It) {
3339 OptSpecifier Opt =
3340 It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;
3341 GenerateArg(Consumer, Opt, It->Path);
3342 }
3343
3344 // Note: Some paths that came from "-idirafter=xxyy" may have already been
3345 // generated as "-iwithprefix=xxyy". If that's the case, their position on
3346 // command line was such that this has no semantic impact on include paths.
3347 for (; It < End && Matches(*It, {frontend::After}, false, true); ++It)
3348 GenerateArg(Consumer, OPT_idirafter, It->Path);
3349 for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It)
3350 GenerateArg(Consumer, OPT_iquote, It->Path);
3351 for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt);
3352 ++It)
3353 GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
3354 It->Path);
3355 for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
3356 GenerateArg(Consumer, OPT_iframework, It->Path);
3357 for (; It < End && Matches(*It, {frontend::System}, true, false); ++It)
3358 GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path);
3359
3360 // Add the paths for the various language specific isystem flags.
3361 for (; It < End && Matches(*It, {frontend::CSystem}, false, true); ++It)
3362 GenerateArg(Consumer, OPT_c_isystem, It->Path);
3363 for (; It < End && Matches(*It, {frontend::CXXSystem}, false, true); ++It)
3364 GenerateArg(Consumer, OPT_cxx_isystem, It->Path);
3365 for (; It < End && Matches(*It, {frontend::ObjCSystem}, false, true); ++It)
3366 GenerateArg(Consumer, OPT_objc_isystem, It->Path);
3367 for (; It < End && Matches(*It, {frontend::ObjCXXSystem}, false, true); ++It)
3368 GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);
3369
3370 // Add the internal paths from a driver that detects standard include paths.
3371 // Note: Some paths that came from "-internal-isystem" arguments may have
3372 // already been generated as "-isystem". If that's the case, their position on
3373 // command line was such that this has no semantic impact on include paths.
3374 for (; It < End &&
3375 Matches(*It, {frontend::System, frontend::ExternCSystem}, false, true);
3376 ++It) {
3377 OptSpecifier Opt = It->Group == frontend::System
3378 ? OPT_internal_isystem
3379 : OPT_internal_externc_isystem;
3380 GenerateArg(Consumer, Opt, It->Path);
3381 }
3382 for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
3383 GenerateArg(Consumer, OPT_internal_iframework, It->Path);
3384
3385 assert(It == End && "Unhandled HeaderSearchOption::Entry.");
3386
3387 // Add the path prefixes which are implicitly treated as being system headers.
3388 for (const auto &P : Opts.SystemHeaderPrefixes) {
3389 OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
3390 : OPT_no_system_header_prefix;
3391 GenerateArg(Consumer, Opt, P.Prefix);
3392 }
3393
3394 for (const std::string &F : Opts.VFSOverlayFiles)
3395 GenerateArg(Consumer, OPT_ivfsoverlay, F);
3396}
3397
3398static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
3399 DiagnosticsEngine &Diags) {
3400 unsigned NumErrorsBefore = Diags.getNumErrors();
3401
3402 HeaderSearchOptions *HeaderSearchOpts = &Opts;
3403
3404#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3405 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3406#include "clang/Driver/Options.inc"
3407#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3408
3409 if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
3410 Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
3411
3412 // Only the -fmodule-file=<name>=<file> form.
3413 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3414 StringRef Val = A->getValue();
3415 if (Val.contains('=')) {
3416 auto Split = Val.split('=');
3417 Opts.PrebuiltModuleFiles.insert_or_assign(
3418 std::string(Split.first), std::string(Split.second));
3419 }
3420 }
3421 for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
3422 Opts.AddPrebuiltModulePath(A->getValue());
3423
3424 for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
3425 StringRef MacroDef = A->getValue();
3426 Opts.ModulesIgnoreMacros.insert(
3427 llvm::CachedHashString(MacroDef.split('=').first));
3428 }
3429
3430 // Add -I... and -F... options in order.
3431 bool IsSysrootSpecified =
3432 Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
3433
3434 // Expand a leading `=` to the sysroot if one was passed (and it's not a
3435 // framework flag).
3436 auto PrefixHeaderPath = [IsSysrootSpecified,
3437 &Opts](const llvm::opt::Arg *A,
3438 bool IsFramework = false) -> std::string {
3439 assert(A->getNumValues() && "Unexpected empty search path flag!");
3440 if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') {
3441 SmallString<32> Buffer;
3442 llvm::sys::path::append(Buffer, Opts.Sysroot,
3443 llvm::StringRef(A->getValue()).substr(1));
3444 return std::string(Buffer);
3445 }
3446 return A->getValue();
3447 };
3448
3449 for (const auto *A : Args.filtered(OPT_I, OPT_F)) {
3450 bool IsFramework = A->getOption().matches(OPT_F);
3451 Opts.AddPath(PrefixHeaderPath(A, IsFramework), frontend::Angled,
3452 IsFramework, /*IgnoreSysroot=*/true);
3453 }
3454
3455 // Add -iprefix/-iwithprefix/-iwithprefixbefore options.
3456 StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
3457 for (const auto *A :
3458 Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
3459 if (A->getOption().matches(OPT_iprefix))
3460 Prefix = A->getValue();
3461 else if (A->getOption().matches(OPT_iwithprefix))
3462 Opts.AddPath(Prefix.str() + A->getValue(), frontend::After, false, true);
3463 else
3464 Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
3465 }
3466
3467 for (const auto *A : Args.filtered(OPT_idirafter))
3468 Opts.AddPath(PrefixHeaderPath(A), frontend::After, false, true);
3469 for (const auto *A : Args.filtered(OPT_iquote))
3470 Opts.AddPath(PrefixHeaderPath(A), frontend::Quoted, false, true);
3471
3472 for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) {
3473 if (A->getOption().matches(OPT_iwithsysroot)) {
3474 Opts.AddPath(A->getValue(), frontend::System, false,
3475 /*IgnoreSysRoot=*/false);
3476 continue;
3477 }
3478 Opts.AddPath(PrefixHeaderPath(A), frontend::System, false, true);
3479 }
3480 for (const auto *A : Args.filtered(OPT_iframework))
3481 Opts.AddPath(A->getValue(), frontend::System, true, true);
3482 for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
3483 Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
3484 /*IgnoreSysRoot=*/false);
3485
3486 // Add the paths for the various language specific isystem flags.
3487 for (const auto *A : Args.filtered(OPT_c_isystem))
3488 Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
3489 for (const auto *A : Args.filtered(OPT_cxx_isystem))
3490 Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
3491 for (const auto *A : Args.filtered(OPT_objc_isystem))
3492 Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
3493 for (const auto *A : Args.filtered(OPT_objcxx_isystem))
3494 Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
3495
3496 // Add the internal paths from a driver that detects standard include paths.
3497 for (const auto *A :
3498 Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
3500 if (A->getOption().matches(OPT_internal_externc_isystem))
3502 Opts.AddPath(A->getValue(), Group, false, true);
3503 }
3504 for (const auto *A : Args.filtered(OPT_internal_iframework))
3505 Opts.AddPath(A->getValue(), frontend::System, true, true);
3506
3507 // Add the path prefixes which are implicitly treated as being system headers.
3508 for (const auto *A :
3509 Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
3511 A->getValue(), A->getOption().matches(OPT_system_header_prefix));
3512
3513 for (const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))
3514 Opts.AddVFSOverlayFile(A->getValue());
3515
3516 return Diags.getNumErrors() == NumErrorsBefore;
3517}
3518
3520 ArgumentConsumer Consumer) {
3521 if (!Opts.SwiftVersion.empty())
3522 GenerateArg(Consumer, OPT_fapinotes_swift_version,
3523 Opts.SwiftVersion.getAsString());
3524
3525 for (const auto &Path : Opts.ModuleSearchPaths)
3526 GenerateArg(Consumer, OPT_iapinotes_modules, Path);
3527}
3528
3529static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
3530 DiagnosticsEngine &diags) {
3531 if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
3532 if (Opts.SwiftVersion.tryParse(A->getValue()))
3533 diags.Report(diag::err_drv_invalid_value)
3534 << A->getAsString(Args) << A->getValue();
3535 }
3536 for (const Arg *A : Args.filtered(OPT_iapinotes_modules))
3537 Opts.ModuleSearchPaths.push_back(A->getValue());
3538}
3539
3540static void GeneratePointerAuthArgs(const LangOptions &Opts,
3541 ArgumentConsumer Consumer) {
3542 if (Opts.PointerAuthIntrinsics)
3543 GenerateArg(Consumer, OPT_fptrauth_intrinsics);
3544 if (Opts.PointerAuthCalls)
3545 GenerateArg(Consumer, OPT_fptrauth_calls);
3546 if (Opts.PointerAuthReturns)
3547 GenerateArg(Consumer, OPT_fptrauth_returns);
3548 if (Opts.PointerAuthIndirectGotos)
3549 GenerateArg(Consumer, OPT_fptrauth_indirect_gotos);
3550 if (Opts.PointerAuthAuthTraps)
3551 GenerateArg(Consumer, OPT_fptrauth_auth_traps);
3552 if (Opts.PointerAuthVTPtrAddressDiscrimination)
3553 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
3554 if (Opts.PointerAuthVTPtrTypeDiscrimination)
3555 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
3556 if (Opts.PointerAuthTypeInfoVTPtrDiscrimination)
3557 GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination);
3558 if (Opts.PointerAuthFunctionTypeDiscrimination)
3559 GenerateArg(Consumer, OPT_fptrauth_function_pointer_type_discrimination);
3560 if (Opts.PointerAuthInitFini)
3561 GenerateArg(Consumer, OPT_fptrauth_init_fini);
3562 if (Opts.PointerAuthInitFiniAddressDiscrimination)
3563 GenerateArg(Consumer, OPT_fptrauth_init_fini_address_discrimination);
3564 if (Opts.PointerAuthELFGOT)
3565 GenerateArg(Consumer, OPT_fptrauth_elf_got);
3566 if (Opts.AArch64JumpTableHardening)
3567 GenerateArg(Consumer, OPT_faarch64_jump_table_hardening);
3568 if (Opts.PointerAuthObjcIsa)
3569 GenerateArg(Consumer, OPT_fptrauth_objc_isa);
3570 if (Opts.PointerAuthObjcInterfaceSel)
3571 GenerateArg(Consumer, OPT_fptrauth_objc_interface_sel);
3572 if (Opts.PointerAuthObjcClassROPointers)
3573 GenerateArg(Consumer, OPT_fptrauth_objc_class_ro);
3574 if (Opts.PointerAuthBlockDescriptorPointers)
3575 GenerateArg(Consumer, OPT_fptrauth_block_descriptor_pointers);
3576}
3577
3578static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
3579 DiagnosticsEngine &Diags) {
3580 Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
3581 Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
3582 Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
3583 Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
3584 Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
3585 Opts.PointerAuthVTPtrAddressDiscrimination =
3586 Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
3587 Opts.PointerAuthVTPtrTypeDiscrimination =
3588 Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
3589 Opts.PointerAuthTypeInfoVTPtrDiscrimination =
3590 Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination);
3591 Opts.PointerAuthFunctionTypeDiscrimination =
3592 Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination);
3593 Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
3594 Opts.PointerAuthInitFiniAddressDiscrimination =
3595 Args.hasArg(OPT_fptrauth_init_fini_address_discrimination);
3596 Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got);
3597 Opts.AArch64JumpTableHardening =
3598 Args.hasArg(OPT_faarch64_jump_table_hardening);
3599 Opts.PointerAuthBlockDescriptorPointers =
3600 Args.hasArg(OPT_fptrauth_block_descriptor_pointers);
3601 Opts.PointerAuthObjcIsa = Args.hasArg(OPT_fptrauth_objc_isa);
3602 Opts.PointerAuthObjcClassROPointers = Args.hasArg(OPT_fptrauth_objc_class_ro);
3603 Opts.PointerAuthObjcInterfaceSel =
3604 Args.hasArg(OPT_fptrauth_objc_interface_sel);
3605
3606 if (Opts.PointerAuthObjcInterfaceSel)
3607 Opts.PointerAuthObjcInterfaceSelKey =
3608 static_cast<unsigned>(PointerAuthSchema::ARM8_3Key::ASDB);
3609}
3610
3611/// Check if input file kind and language standard are compatible.
3613 const LangStandard &S) {
3614 switch (IK.getLanguage()) {
3615 case Language::Unknown:
3616 case Language::LLVM_IR:
3617 case Language::CIR:
3618 llvm_unreachable("should not parse language flags for this input");
3619
3620 case Language::C:
3621 case Language::ObjC:
3622 return S.getLanguage() == Language::C;
3623
3624 case Language::OpenCL:
3625 return S.getLanguage() == Language::OpenCL ||
3627
3629 return S.getLanguage() == Language::OpenCLCXX;
3630
3631 case Language::CXX:
3632 case Language::ObjCXX:
3633 return S.getLanguage() == Language::CXX;
3634
3635 case Language::CUDA:
3636 // FIXME: What -std= values should be permitted for CUDA compilations?
3637 return S.getLanguage() == Language::CUDA ||
3639
3640 case Language::HIP:
3641 return S.getLanguage() == Language::CXX || S.getLanguage() == Language::HIP;
3642
3643 case Language::Asm:
3644 // Accept (and ignore) all -std= values.
3645 // FIXME: The -std= value is not ignored; it affects the tokenization
3646 // and preprocessing rules if we're preprocessing this asm input.
3647 return true;
3648
3649 case Language::HLSL:
3650 return S.getLanguage() == Language::HLSL;
3651 }
3652
3653 llvm_unreachable("unexpected input language");
3654}
3655
3656/// Get language name for given input kind.
3657static StringRef GetInputKindName(InputKind IK) {
3658 switch (IK.getLanguage()) {
3659 case Language::C:
3660 return "C";
3661 case Language::ObjC:
3662 return "Objective-C";
3663 case Language::CXX:
3664 return "C++";
3665 case Language::ObjCXX:
3666 return "Objective-C++";
3667 case Language::OpenCL:
3668 return "OpenCL";
3670 return "C++ for OpenCL";
3671 case Language::CUDA:
3672 return "CUDA";
3673 case Language::HIP:
3674 return "HIP";
3675
3676 case Language::Asm:
3677 return "Asm";
3678 case Language::LLVM_IR:
3679 return "LLVM IR";
3680 case Language::CIR:
3681 return "Clang IR";
3682
3683 case Language::HLSL:
3684 return "HLSL";
3685
3686 case Language::Unknown:
3687 break;
3688 }
3689 llvm_unreachable("unknown input language");
3690}
3691
3692void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
3693 ArgumentConsumer Consumer,
3694 const llvm::Triple &T,
3695 InputKind IK) {
3696 if (IK.getFormat() == InputKind::Precompiled ||
3698 IK.getLanguage() == Language::CIR) {
3699 if (Opts.ObjCAutoRefCount)
3700 GenerateArg(Consumer, OPT_fobjc_arc);
3701 if (Opts.PICLevel != 0)
3702 GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));
3703 if (Opts.PIE)
3704 GenerateArg(Consumer, OPT_pic_is_pie);
3705 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3706 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3707
3708 return;
3709 }
3710
3711 OptSpecifier StdOpt;
3712 switch (Opts.LangStd) {
3713 case LangStandard::lang_opencl10:
3714 case LangStandard::lang_opencl11:
3715 case LangStandard::lang_opencl12:
3716 case LangStandard::lang_opencl20:
3717 case LangStandard::lang_opencl30:
3718 case LangStandard::lang_openclcpp10:
3719 case LangStandard::lang_openclcpp2021:
3720 StdOpt = OPT_cl_std_EQ;
3721 break;
3722 default:
3723 StdOpt = OPT_std_EQ;
3724 break;
3725 }
3726
3727 auto LangStandard = LangStandard::getLangStandardForKind(Opts.LangStd);
3728 GenerateArg(Consumer, StdOpt, LangStandard.getName());
3729
3730 if (Opts.IncludeDefaultHeader)
3731 GenerateArg(Consumer, OPT_finclude_default_header);
3732 if (Opts.DeclareOpenCLBuiltins)
3733 GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);
3734
3735 const LangOptions *LangOpts = &Opts;
3736
3737#define LANG_OPTION_WITH_MARSHALLING(...) \
3738 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3739#include "clang/Driver/Options.inc"
3740#undef LANG_OPTION_WITH_MARSHALLING
3741
3742 // The '-fcf-protection=' option is generated by CodeGenOpts generator.
3743
3744 if (Opts.ObjC) {
3745 GenerateArg(Consumer, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString());
3746
3747 if (Opts.GC == LangOptions::GCOnly)
3748 GenerateArg(Consumer, OPT_fobjc_gc_only);
3749 else if (Opts.GC == LangOptions::HybridGC)
3750 GenerateArg(Consumer, OPT_fobjc_gc);
3751 else if (Opts.ObjCAutoRefCount == 1)
3752 GenerateArg(Consumer, OPT_fobjc_arc);
3753
3754 if (Opts.ObjCWeakRuntime)
3755 GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);
3756
3757 if (Opts.ObjCWeak)
3758 GenerateArg(Consumer, OPT_fobjc_weak);
3759
3760 if (Opts.ObjCSubscriptingLegacyRuntime)
3761 GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime);
3762 }
3763
3764 if (Opts.GNUCVersion != 0) {
3765 unsigned Major = Opts.GNUCVersion / 100 / 100;
3766 unsigned Minor = (Opts.GNUCVersion / 100) % 100;
3767 unsigned Patch = Opts.GNUCVersion % 100;
3768 GenerateArg(Consumer, OPT_fgnuc_version_EQ,
3769 Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch));
3770 }
3771
3772 if (Opts.IgnoreXCOFFVisibility)
3773 GenerateArg(Consumer, OPT_mignore_xcoff_visibility);
3774
3775 if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) {
3776 GenerateArg(Consumer, OPT_ftrapv);
3777 GenerateArg(Consumer, OPT_ftrapv_handler, Opts.OverflowHandler);
3778 } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
3779 GenerateArg(Consumer, OPT_fwrapv);
3780 }
3781 if (Opts.PointerOverflowDefined)
3782 GenerateArg(Consumer, OPT_fwrapv_pointer);
3783
3784 if (Opts.MSCompatibilityVersion != 0) {
3785 unsigned Major = Opts.MSCompatibilityVersion / 10000000;
3786 unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;
3787 unsigned Subminor = Opts.MSCompatibilityVersion % 100000;
3788 GenerateArg(Consumer, OPT_fms_compatibility_version,
3789 Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor));
3790 }
3791
3792 if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
3793 T.isOSzOS()) {
3794 if (!Opts.Trigraphs)
3795 GenerateArg(Consumer, OPT_fno_trigraphs);
3796 } else {
3797 if (Opts.Trigraphs)
3798 GenerateArg(Consumer, OPT_ftrigraphs);
3799 }
3800
3801 if (T.isOSzOS() && !Opts.ZOSExt)
3802 GenerateArg(Consumer, OPT_fno_zos_extensions);
3803 else if (Opts.ZOSExt)
3804 GenerateArg(Consumer, OPT_fzos_extensions);
3805
3806 if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
3807 GenerateArg(Consumer, OPT_fblocks);
3808
3809 if (Opts.ConvergentFunctions)
3810 GenerateArg(Consumer, OPT_fconvergent_functions);
3811 else
3812 GenerateArg(Consumer, OPT_fno_convergent_functions);
3813
3814 if (Opts.NoBuiltin && !Opts.Freestanding)
3815 GenerateArg(Consumer, OPT_fno_builtin);
3816
3817 if (!Opts.NoBuiltin)
3818 for (const auto &Func : Opts.NoBuiltinFuncs)
3819 GenerateArg(Consumer, OPT_fno_builtin_, Func);
3820
3821 if (Opts.LongDoubleSize == 128)
3822 GenerateArg(Consumer, OPT_mlong_double_128);
3823 else if (Opts.LongDoubleSize == 64)
3824 GenerateArg(Consumer, OPT_mlong_double_64);
3825 else if (Opts.LongDoubleSize == 80)
3826 GenerateArg(Consumer, OPT_mlong_double_80);
3827
3828 // Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
3829
3830 // OpenMP was requested via '-fopenmp', not implied by '-fopenmp-simd' or
3831 // '-fopenmp-targets='.
3832 if (Opts.OpenMP && !Opts.OpenMPSimd) {
3833 GenerateArg(Consumer, OPT_fopenmp);
3834
3835 if (Opts.OpenMP != 51)
3836 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3837
3838 if (!Opts.OpenMPUseTLS)
3839 GenerateArg(Consumer, OPT_fnoopenmp_use_tls);
3840
3841 if (Opts.OpenMPIsTargetDevice)
3842 GenerateArg(Consumer, OPT_fopenmp_is_target_device);
3843
3844 if (Opts.OpenMPIRBuilder)
3845 GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder);
3846 }
3847
3848 if (Opts.OpenMPSimd) {
3849 GenerateArg(Consumer, OPT_fopenmp_simd);
3850
3851 if (Opts.OpenMP != 51)
3852 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3853 }
3854
3855 if (Opts.OpenMPThreadSubscription)
3856 GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription);
3857
3858 if (Opts.OpenMPTeamSubscription)
3859 GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription);
3860
3861 if (Opts.OpenMPTargetDebug != 0)
3862 GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ,
3863 Twine(Opts.OpenMPTargetDebug));
3864
3865 if (Opts.OpenMPCUDANumSMs != 0)
3866 GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ,
3867 Twine(Opts.OpenMPCUDANumSMs));
3868
3869 if (Opts.OpenMPCUDABlocksPerSM != 0)
3870 GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ,
3871 Twine(Opts.OpenMPCUDABlocksPerSM));
3872
3873 if (Opts.OpenMPCUDAReductionBufNum != 1024)
3874 GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
3875 Twine(Opts.OpenMPCUDAReductionBufNum));
3876
3877 if (!Opts.OMPTargetTriples.empty()) {
3878 std::string Targets;
3879 llvm::raw_string_ostream OS(Targets);
3880 llvm::interleave(
3881 Opts.OMPTargetTriples, OS,
3882 [&OS](const llvm::Triple &T) { OS << T.str(); }, ",");
3883 GenerateArg(Consumer, OPT_offload_targets_EQ, Targets);
3884 }
3885
3886 if (Opts.OpenMPCUDAMode)
3887 GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
3888
3889 if (Opts.OpenACC)
3890 GenerateArg(Consumer, OPT_fopenacc);
3891
3892 // The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
3893 // generated from CodeGenOptions.
3894
3895 if (Opts.DefaultFPContractMode == LangOptions::FPM_Fast)
3896 GenerateArg(Consumer, OPT_ffp_contract, "fast");
3897 else if (Opts.DefaultFPContractMode == LangOptions::FPM_On)
3898 GenerateArg(Consumer, OPT_ffp_contract, "on");
3899 else if (Opts.DefaultFPContractMode == LangOptions::FPM_Off)
3900 GenerateArg(Consumer, OPT_ffp_contract, "off");
3901 else if (Opts.DefaultFPContractMode == LangOptions::FPM_FastHonorPragmas)
3902 GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas");
3903
3904 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3905 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3906
3907 // Conflating '-fsanitize-system-ignorelist' and '-fsanitize-ignorelist'.
3908 for (const std::string &F : Opts.NoSanitizeFiles)
3909 GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);
3910
3911 switch (Opts.getClangABICompat()) {
3912#define ABI_VER_MAJOR_MINOR(Major, Minor) \
3913 case LangOptions::ClangABI::Ver##Major##_##Minor: \
3914 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major "." #Minor); \
3915 break;
3916#define ABI_VER_MAJOR(Major) \
3917 case LangOptions::ClangABI::Ver##Major: \
3918 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major ".0"); \
3919 break;
3920#define ABI_VER_LATEST(Latest) \
3921 case LangOptions::ClangABI::Latest: \
3922 break;
3923#include "clang/Basic/ABIVersions.def"
3924 }
3925
3926 if (Opts.getSignReturnAddressScope() ==
3928 GenerateArg(Consumer, OPT_msign_return_address_EQ, "all");
3929 else if (Opts.getSignReturnAddressScope() ==
3931 GenerateArg(Consumer, OPT_msign_return_address_EQ, "non-leaf");
3932
3933 if (Opts.getSignReturnAddressKey() ==
3935 GenerateArg(Consumer, OPT_msign_return_address_key_EQ, "b_key");
3936
3937 if (Opts.CXXABI)
3938 GenerateArg(Consumer, OPT_fcxx_abi_EQ,
3940
3941 if (Opts.RelativeCXXABIVTables)
3942 GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables);
3943 else
3944 GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables);
3945
3946 if (Opts.UseTargetPathSeparator)
3947 GenerateArg(Consumer, OPT_ffile_reproducible);
3948 else
3949 GenerateArg(Consumer, OPT_fno_file_reproducible);
3950
3951 for (const auto &MP : Opts.MacroPrefixMap)
3952 GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second);
3953
3954 if (!Opts.RandstructSeed.empty())
3955 GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed);
3956}
3957
3958bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
3959 InputKind IK, const llvm::Triple &T,
3960 std::vector<std::string> &Includes,
3961 DiagnosticsEngine &Diags) {
3962 unsigned NumErrorsBefore = Diags.getNumErrors();
3963
3964 if (IK.getFormat() == InputKind::Precompiled ||
3966 IK.getLanguage() == Language::CIR) {
3967 // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
3968 // PassManager in BackendUtil.cpp. They need to be initialized no matter
3969 // what the input type is.
3970 if (Args.hasArg(OPT_fobjc_arc))
3971 Opts.ObjCAutoRefCount = 1;
3972 // PICLevel and PIELevel are needed during code generation and this should
3973 // be set regardless of the input type.
3974 Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
3975 Opts.PIE = Args.hasArg(OPT_pic_is_pie);
3976 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
3977 Diags, Opts.Sanitize);
3978
3979 return Diags.getNumErrors() == NumErrorsBefore;
3980 }
3981
3982 // Other LangOpts are only initialized when the input is not AST or LLVM IR.
3983 // FIXME: Should we really be parsing this for an Language::Asm input?
3984
3985 // FIXME: Cleanup per-file based stuff.
3987 if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
3988 LangStd = LangStandard::getLangKind(A->getValue());
3989 if (LangStd == LangStandard::lang_unspecified) {
3990 Diags.Report(diag::err_drv_invalid_value)
3991 << A->getAsString(Args) << A->getValue();
3992 // Report supported standards with short description.
3993 for (unsigned KindValue = 0;
3994 KindValue != LangStandard::lang_unspecified;
3995 ++KindValue) {
3996 const LangStandard &Std = LangStandard::getLangStandardForKind(
3997 static_cast<LangStandard::Kind>(KindValue));
3998 if (IsInputCompatibleWithStandard(IK, Std)) {
3999 auto Diag = Diags.Report(diag::note_drv_use_standard);
4000 Diag << Std.getName() << Std.getDescription();
4001 unsigned NumAliases = 0;
4002#define LANGSTANDARD(id, name, lang, desc, features)
4003#define LANGSTANDARD_ALIAS(id, alias) \
4004 if (KindValue == LangStandard::lang_##id) ++NumAliases;
4005#define LANGSTANDARD_ALIAS_DEPR(id, alias)
4006#include "clang/Basic/LangStandards.def"
4007 Diag << NumAliases;
4008#define LANGSTANDARD(id, name, lang, desc, features)
4009#define LANGSTANDARD_ALIAS(id, alias) \
4010 if (KindValue == LangStandard::lang_##id) Diag << alias;
4011#define LANGSTANDARD_ALIAS_DEPR(id, alias)
4012#include "clang/Basic/LangStandards.def"
4013 }
4014 }
4015 } else {
4016 // Valid standard, check to make sure language and standard are
4017 // compatible.
4018 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
4019 if (!IsInputCompatibleWithStandard(IK, Std)) {
4020 Diags.Report(diag::err_drv_argument_not_allowed_with)
4021 << A->getAsString(Args) << GetInputKindName(IK);
4022 }
4023 }
4024 }
4025
4026 // -cl-std only applies for OpenCL language standards.
4027 // Override the -std option in this case.
4028 if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
4029 LangStandard::Kind OpenCLLangStd
4030 = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
4031 .Cases("cl", "CL", LangStandard::lang_opencl10)
4032 .Cases("cl1.0", "CL1.0", LangStandard::lang_opencl10)
4033 .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
4034 .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
4035 .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
4036 .Cases("cl3.0", "CL3.0", LangStandard::lang_opencl30)
4037 .Cases("clc++", "CLC++", LangStandard::lang_openclcpp10)
4038 .Cases("clc++1.0", "CLC++1.0", LangStandard::lang_openclcpp10)
4039 .Cases("clc++2021", "CLC++2021", LangStandard::lang_openclcpp2021)
4041
4042 if (OpenCLLangStd == LangStandard::lang_unspecified) {
4043 Diags.Report(diag::err_drv_invalid_value)
4044 << A->getAsString(Args) << A->getValue();
4045 }
4046 else
4047 LangStd = OpenCLLangStd;
4048 }
4049
4050 // These need to be parsed now. They are used to set OpenCL defaults.
4051 Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
4052 Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
4053
4054 LangOptions::setLangDefaults(Opts, IK.getLanguage(), T, Includes, LangStd);
4055
4056 // The key paths of codegen options defined in Options.td start with
4057 // "LangOpts->". Let's provide the expected variable name and type.
4058 LangOptions *LangOpts = &Opts;
4059
4060#define LANG_OPTION_WITH_MARSHALLING(...) \
4061 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4062#include "clang/Driver/Options.inc"
4063#undef LANG_OPTION_WITH_MARSHALLING
4064
4065 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4066 StringRef Name = A->getValue();
4067 if (Name == "full") {
4068 Opts.CFProtectionBranch = 1;
4069 Opts.CFProtectionReturn = 1;
4070 } else if (Name == "branch") {
4071 Opts.CFProtectionBranch = 1;
4072 } else if (Name == "return") {
4073 Opts.CFProtectionReturn = 1;
4074 }
4075 }
4076
4077 if (Opts.CFProtectionBranch) {
4078 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
4079 const auto Scheme =
4080 llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
4081#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
4082 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
4083#include "clang/Basic/CFProtectionOptions.def"
4085 Opts.setCFBranchLabelScheme(Scheme);
4086 }
4087 }
4088
4089 if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
4090 !Args.hasArg(OPT_sycl_std_EQ)) {
4091 // If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to
4092 // provide -sycl-std=, we want to default it to whatever the default SYCL
4093 // version is. I could not find a way to express this with the options
4094 // tablegen because we still want this value to be SYCL_None when the user
4095 // is not in device or host mode.
4096 Opts.setSYCLVersion(LangOptions::SYCL_Default);
4097 }
4098
4099 if (Opts.ObjC) {
4100 if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
4101 StringRef value = arg->getValue();
4102 if (Opts.ObjCRuntime.tryParse(value))
4103 Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
4104 }
4105
4106 if (Args.hasArg(OPT_fobjc_gc_only))
4107 Opts.setGC(LangOptions::GCOnly);
4108 else if (Args.hasArg(OPT_fobjc_gc))
4109 Opts.setGC(LangOptions::HybridGC);
4110 else if (Args.hasArg(OPT_fobjc_arc)) {
4111 Opts.ObjCAutoRefCount = 1;
4112 if (!Opts.ObjCRuntime.allowsARC())
4113 Diags.Report(diag::err_arc_unsupported_on_runtime);
4114 }
4115
4116 // ObjCWeakRuntime tracks whether the runtime supports __weak, not
4117 // whether the feature is actually enabled. This is predominantly
4118 // determined by -fobjc-runtime, but we allow it to be overridden
4119 // from the command line for testing purposes.
4120 if (Args.hasArg(OPT_fobjc_runtime_has_weak))
4121 Opts.ObjCWeakRuntime = 1;
4122 else
4123 Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();
4124
4125 // ObjCWeak determines whether __weak is actually enabled.
4126 // Note that we allow -fno-objc-weak to disable this even in ARC mode.
4127 if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
4128 if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
4129 assert(!Opts.ObjCWeak);
4130 } else if (Opts.getGC() != LangOptions::NonGC) {
4131 Diags.Report(diag::err_objc_weak_with_gc);
4132 } else if (!Opts.ObjCWeakRuntime) {
4133 Diags.Report(diag::err_objc_weak_unsupported);
4134 } else {
4135 Opts.ObjCWeak = 1;
4136 }
4137 } else if (Opts.ObjCAutoRefCount) {
4138 Opts.ObjCWeak = Opts.ObjCWeakRuntime;
4139 }
4140
4141 if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
4142 Opts.ObjCSubscriptingLegacyRuntime =
4144 }
4145
4146 if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
4147 // Check that the version has 1 to 3 components and the minor and patch
4148 // versions fit in two decimal digits.
4149 VersionTuple GNUCVer;
4150 bool Invalid = GNUCVer.tryParse(A->getValue());
4151 unsigned Major = GNUCVer.getMajor();
4152 unsigned Minor = GNUCVer.getMinor().value_or(0);
4153 unsigned Patch = GNUCVer.getSubminor().value_or(0);
4154 if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
4155 Diags.Report(diag::err_drv_invalid_value)
4156 << A->getAsString(Args) << A->getValue();
4157 }
4158 Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
4159 }
4160
4161 if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility)))
4162 Opts.IgnoreXCOFFVisibility = 1;
4163
4164 if (Args.hasArg(OPT_ftrapv)) {
4165 Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
4166 // Set the handler, if one is specified.
4167 Opts.OverflowHandler =
4168 std::string(Args.getLastArgValue(OPT_ftrapv_handler));
4169 }
4170 else if (Args.hasArg(OPT_fwrapv))
4171 Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
4172 if (Args.hasArg(OPT_fwrapv_pointer))
4173 Opts.PointerOverflowDefined = true;
4174
4175 Opts.MSCompatibilityVersion = 0;
4176 if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
4177 VersionTuple VT;
4178 if (VT.tryParse(A->getValue()))
4179 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
4180 << A->getValue();
4181 Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
4182 VT.getMinor().value_or(0) * 100000 +
4183 VT.getSubminor().value_or(0);
4184 }
4185
4186 // Mimicking gcc's behavior, trigraphs are only enabled if -trigraphs
4187 // is specified, or -std is set to a conforming mode.
4188 // Trigraphs are disabled by default in C++17 and C23 onwards.
4189 // For z/OS, trigraphs are enabled by default (without regard to the above).
4190 Opts.Trigraphs =
4191 (!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
4192 T.isOSzOS();
4193 Opts.Trigraphs =
4194 Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
4195
4196 Opts.ZOSExt =
4197 Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions, T.isOSzOS());
4198
4199 Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
4200 && Opts.OpenCLVersion == 200);
4201
4202 bool HasConvergentOperations = Opts.isTargetDevice() || Opts.OpenCL ||
4203 Opts.HLSL || T.isAMDGPU() || T.isNVPTX();
4204 Opts.ConvergentFunctions =
4205 Args.hasFlag(OPT_fconvergent_functions, OPT_fno_convergent_functions,
4206 HasConvergentOperations);
4207
4208 Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
4209 if (!Opts.NoBuiltin)
4211 if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
4212 if (A->getOption().matches(options::OPT_mlong_double_64))
4213 Opts.LongDoubleSize = 64;
4214 else if (A->getOption().matches(options::OPT_mlong_double_80))
4215 Opts.LongDoubleSize = 80;
4216 else if (A->getOption().matches(options::OPT_mlong_double_128))
4217 Opts.LongDoubleSize = 128;
4218 else
4219 Opts.LongDoubleSize = 0;
4220 }
4221 if (Opts.FastRelaxedMath || Opts.CLUnsafeMath)
4222 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4223
4224 llvm::sort(Opts.ModuleFeatures);
4225
4226 // -mrtd option
4227 if (Arg *A = Args.getLastArg(OPT_mrtd)) {
4228 if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
4229 Diags.Report(diag::err_drv_argument_not_allowed_with)
4230 << A->getSpelling() << "-fdefault-calling-conv";
4231 else {
4232 switch (T.getArch()) {
4233 case llvm::Triple::x86:
4234 Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
4235 break;
4236 case llvm::Triple::m68k:
4237 Opts.setDefaultCallingConv(LangOptions::DCC_RtdCall);
4238 break;
4239 default:
4240 Diags.Report(diag::err_drv_argument_not_allowed_with)
4241 << A->getSpelling() << T.getTriple();
4242 }
4243 }
4244 }
4245
4246 // Check if -fopenmp is specified and set default version to 5.1.
4247 Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;
4248 // Check if -fopenmp-simd is specified.
4249 bool IsSimdSpecified =
4250 Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
4251 /*Default=*/false);
4252 Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;
4253 Opts.OpenMPUseTLS =
4254 Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
4255 Opts.OpenMPIsTargetDevice =
4256 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_target_device);
4257 Opts.OpenMPIRBuilder =
4258 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_enable_irbuilder);
4259 bool IsTargetSpecified =
4260 Opts.OpenMPIsTargetDevice || Args.hasArg(options::OPT_offload_targets_EQ);
4261
4262 if (Opts.OpenMP || Opts.OpenMPSimd) {
4263 if (int Version = getLastArgIntValue(
4264 Args, OPT_fopenmp_version_EQ,
4265 (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))
4266 Opts.OpenMP = Version;
4267 // Provide diagnostic when a given target is not expected to be an OpenMP
4268 // device or host.
4269 if (!Opts.OpenMPIsTargetDevice) {
4270 switch (T.getArch()) {
4271 default:
4272 break;
4273 // Add unsupported host targets here:
4274 case llvm::Triple::nvptx:
4275 case llvm::Triple::nvptx64:
4276 Diags.Report(diag::err_drv_omp_host_target_not_supported) << T.str();
4277 break;
4278 }
4279 }
4280 }
4281
4282 // Set the flag to prevent the implementation from emitting device exception
4283 // handling code for those requiring so.
4284 if ((Opts.OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) ||
4285 Opts.OpenCLCPlusPlus) {
4286
4287 Opts.Exceptions = 0;
4288 Opts.CXXExceptions = 0;
4289 }
4290 if (Opts.OpenMPIsTargetDevice && T.isNVPTX()) {
4291 Opts.OpenMPCUDANumSMs =
4292 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_number_of_sm_EQ,
4293 Opts.OpenMPCUDANumSMs, Diags);
4294 Opts.OpenMPCUDABlocksPerSM =
4295 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,
4296 Opts.OpenMPCUDABlocksPerSM, Diags);
4297 Opts.OpenMPCUDAReductionBufNum = getLastArgIntValue(
4298 Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
4299 Opts.OpenMPCUDAReductionBufNum, Diags);
4300 }
4301
4302 // Set the value of the debugging flag used in the new offloading device RTL.
4303 // Set either by a specific value or to a default if not specified.
4304 if (Opts.OpenMPIsTargetDevice && (Args.hasArg(OPT_fopenmp_target_debug) ||
4305 Args.hasArg(OPT_fopenmp_target_debug_EQ))) {
4306 Opts.OpenMPTargetDebug = getLastArgIntValue(
4307 Args, OPT_fopenmp_target_debug_EQ, Opts.OpenMPTargetDebug, Diags);
4308 if (!Opts.OpenMPTargetDebug && Args.hasArg(OPT_fopenmp_target_debug))
4309 Opts.OpenMPTargetDebug = 1;
4310 }
4311
4312 if (Opts.OpenMPIsTargetDevice) {
4313 if (Args.hasArg(OPT_fopenmp_assume_teams_oversubscription))
4314 Opts.OpenMPTeamSubscription = true;
4315 if (Args.hasArg(OPT_fopenmp_assume_threads_oversubscription))
4316 Opts.OpenMPThreadSubscription = true;
4317 }
4318
4319 // Get the OpenMP target triples if any.
4320 if (Arg *A = Args.getLastArg(options::OPT_offload_targets_EQ)) {
4321 enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
4322 auto getArchPtrSize = [](const llvm::Triple &T) {
4323 if (T.isArch16Bit())
4324 return Arch16Bit;
4325 if (T.isArch32Bit())
4326 return Arch32Bit;
4327 assert(T.isArch64Bit() && "Expected 64-bit architecture");
4328 return Arch64Bit;
4329 };
4330
4331 for (unsigned i = 0; i < A->getNumValues(); ++i) {
4332 llvm::Triple TT(A->getValue(i));
4333
4334 if (TT.getArch() == llvm::Triple::UnknownArch ||
4335 !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() ||
4336 TT.getArch() == llvm::Triple::spirv64 ||
4337 TT.getArch() == llvm::Triple::systemz ||
4338 TT.getArch() == llvm::Triple::loongarch64 ||
4339 TT.getArch() == llvm::Triple::nvptx ||
4340 TT.getArch() == llvm::Triple::nvptx64 || TT.isAMDGCN() ||
4341 TT.getArch() == llvm::Triple::x86 ||
4342 TT.getArch() == llvm::Triple::x86_64))
4343 Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
4344 else if (getArchPtrSize(T) != getArchPtrSize(TT))
4345 Diags.Report(diag::err_drv_incompatible_omp_arch)
4346 << A->getValue(i) << T.str();
4347 else
4348 Opts.OMPTargetTriples.push_back(TT);
4349 }
4350 }
4351
4352 // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options
4353 Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice &&
4354 (T.isNVPTX() || T.isAMDGCN()) &&
4355 Args.hasArg(options::OPT_fopenmp_cuda_mode);
4356
4357 // OpenACC Configuration.
4358 if (Args.hasArg(options::OPT_fopenacc))
4359 Opts.OpenACC = true;
4360
4361 if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
4362 StringRef Val = A->getValue();
4363 if (Val == "fast")
4364 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4365 else if (Val == "on")
4366 Opts.setDefaultFPContractMode(LangOptions::FPM_On);
4367 else if (Val == "off")
4368 Opts.setDefaultFPContractMode(LangOptions::FPM_Off);
4369 else if (Val == "fast-honor-pragmas")
4370 Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
4371 else
4372 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
4373 }
4374
4375 if (auto *A =
4376 Args.getLastArg(OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {
4377 for (int i = 0, n = A->getNumValues(); i != n; ++i) {
4379 llvm::StringSwitch<unsigned>(A->getValue(i))
4380 .Case("none", LangOptionsBase::None)
4381 .Case("all", LangOptionsBase::All)
4382 .Case("add-unsigned-overflow-test",
4384 .Case("add-signed-overflow-test",
4386 .Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst)
4387 .Case("unsigned-post-decr-while",
4389 .Default(0);
4390 }
4391 }
4392
4393 // Parse -fsanitize= arguments.
4394 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
4395 Diags, Opts.Sanitize);
4396 Opts.NoSanitizeFiles = Args.getAllArgValues(OPT_fsanitize_ignorelist_EQ);
4397 std::vector<std::string> systemIgnorelists =
4398 Args.getAllArgValues(OPT_fsanitize_system_ignorelist_EQ);
4399 Opts.NoSanitizeFiles.insert(Opts.NoSanitizeFiles.end(),
4400 systemIgnorelists.begin(),
4401 systemIgnorelists.end());
4402
4403 if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
4404 Opts.setClangABICompat(LangOptions::ClangABI::Latest);
4405
4406 StringRef Ver = A->getValue();
4407 std::pair<StringRef, StringRef> VerParts = Ver.split('.');
4408 int Major, Minor = 0;
4409
4410 // Check the version number is valid: either 3.x (0 <= x <= 9) or
4411 // y or y.0 (4 <= y <= current version).
4412 if (!VerParts.first.starts_with("0") &&
4413 !VerParts.first.getAsInteger(10, Major) && 3 <= Major &&
4414 Major <= MAX_CLANG_ABI_COMPAT_VERSION &&
4415 (Major == 3
4416 ? VerParts.second.size() == 1 &&
4417 !VerParts.second.getAsInteger(10, Minor)
4418 : VerParts.first.size() == Ver.size() || VerParts.second == "0")) {
4419 // Got a valid version number.
4420#define ABI_VER_MAJOR_MINOR(Major_, Minor_) \
4421 if (std::tuple(Major, Minor) <= std::tuple(Major_, Minor_)) \
4422 Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_##_##Minor_); \
4423 else
4424#define ABI_VER_MAJOR(Major_) \
4425 if (Major <= Major_) \
4426 Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_); \
4427 else
4428#define ABI_VER_LATEST(Latest) \
4429 { /* Equivalent to latest version - do nothing */ \
4430 }
4431#include "clang/Basic/ABIVersions.def"
4432 } else if (Ver != "latest") {
4433 Diags.Report(diag::err_drv_invalid_value)
4434 << A->getAsString(Args) << A->getValue();
4435 }
4436 }
4437
4438 if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) {
4439 StringRef SignScope = A->getValue();
4440
4441 if (SignScope.equals_insensitive("none"))
4442 Opts.setSignReturnAddressScope(
4444 else if (SignScope.equals_insensitive("all"))
4445 Opts.setSignReturnAddressScope(
4447 else if (SignScope.equals_insensitive("non-leaf"))
4448 Opts.setSignReturnAddressScope(
4450 else
4451 Diags.Report(diag::err_drv_invalid_value)
4452 << A->getAsString(Args) << SignScope;
4453
4454 if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
4455 StringRef SignKey = A->getValue();
4456 if (!SignScope.empty() && !SignKey.empty()) {
4457 if (SignKey == "a_key")
4458 Opts.setSignReturnAddressKey(
4460 else if (SignKey == "b_key")
4461 Opts.setSignReturnAddressKey(
4463 else
4464 Diags.Report(diag::err_drv_invalid_value)
4465 << A->getAsString(Args) << SignKey;
4466 }
4467 }
4468 }
4469
4470 // The value can be empty, which indicates the system default should be used.
4471 StringRef CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);
4472 if (!CXXABI.empty()) {
4474 Diags.Report(diag::err_invalid_cxx_abi) << CXXABI;
4475 } else {
4478 Diags.Report(diag::err_unsupported_cxx_abi) << CXXABI << T.str();
4479 else
4480 Opts.CXXABI = Kind;
4481 }
4482 }
4483
4484 Opts.RelativeCXXABIVTables =
4485 Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
4486 options::OPT_fno_experimental_relative_cxx_abi_vtables,
4488
4489 // RTTI is on by default.
4490 bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti);
4491 Opts.OmitVTableRTTI =
4492 Args.hasFlag(options::OPT_fexperimental_omit_vtable_rtti,
4493 options::OPT_fno_experimental_omit_vtable_rtti, false);
4494 if (Opts.OmitVTableRTTI && HasRTTI)
4495 Diags.Report(diag::err_drv_using_omit_rtti_component_without_no_rtti);
4496
4497 for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
4498 auto Split = StringRef(A).split('=');
4499 Opts.MacroPrefixMap.insert(
4500 {std::string(Split.first), std::string(Split.second)});
4501 }
4502
4504 !Args.getLastArg(OPT_fno_file_reproducible) &&
4505 (Args.getLastArg(OPT_ffile_compilation_dir_EQ) ||
4506 Args.getLastArg(OPT_fmacro_prefix_map_EQ) ||
4507 Args.getLastArg(OPT_ffile_reproducible));
4508
4509 // Error if -mvscale-min is unbounded.
4510 if (Arg *A = Args.getLastArg(options::OPT_mvscale_min_EQ)) {
4511 unsigned VScaleMin;
4512 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4513 Diags.Report(diag::err_cc1_unbounded_vscale_min);
4514 }
4515 if (Arg *A = Args.getLastArg(options::OPT_mvscale_streaming_min_EQ)) {
4516 unsigned VScaleMin;
4517 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4518 Diags.Report(diag::err_cc1_unbounded_vscale_min);
4519 }
4520
4521 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) {
4522 std::ifstream SeedFile(A->getValue(0));
4523
4524 if (!SeedFile.is_open())
4525 Diags.Report(diag::err_drv_cannot_open_randomize_layout_seed_file)
4526 << A->getValue(0);
4527
4528 std::getline(SeedFile, Opts.RandstructSeed);
4529 }
4530
4531 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
4532 Opts.RandstructSeed = A->getValue(0);
4533
4534 // Validate options for HLSL
4535 if (Opts.HLSL) {
4536 // TODO: Revisit restricting SPIR-V to logical once we've figured out how to
4537 // handle PhysicalStorageBuffer64 memory model
4538 if (T.isDXIL() || T.isSPIRVLogical()) {
4539 enum { ShaderModel, VulkanEnv, ShaderStage };
4540 enum { OS, Environment };
4541
4542 int ExpectedOS = T.isSPIRVLogical() ? VulkanEnv : ShaderModel;
4543
4544 if (T.getOSName().empty()) {
4545 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4546 << ExpectedOS << OS << T.str();
4547 } else if (T.getEnvironmentName().empty()) {
4548 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4549 << ShaderStage << Environment << T.str();
4550 } else if (!T.isShaderStageEnvironment()) {
4551 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4552 << ShaderStage << T.getEnvironmentName() << T.str();
4553 }
4554
4555 if (T.isDXIL()) {
4556 if (!T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
4557 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4558 << ShaderModel << T.getOSName() << T.str();
4559 }
4560 // Validate that if fnative-half-type is given, that
4561 // the language standard is at least hlsl2018, and that
4562 // the target shader model is at least 6.2.
4563 if (Args.getLastArg(OPT_fnative_half_type)) {
4564 const LangStandard &Std =
4566 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018 &&
4567 T.getOSVersion() >= VersionTuple(6, 2)))
4568 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4569 << "-enable-16bit-types" << true << Std.getName()
4570 << T.getOSVersion().getAsString();
4571 }
4572 } else if (T.isSPIRVLogical()) {
4573 if (!T.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) {
4574 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4575 << VulkanEnv << T.getOSName() << T.str();
4576 }
4577 if (Args.getLastArg(OPT_fnative_half_type)) {
4578 const LangStandard &Std =
4580 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018))
4581 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4582 << "-fnative-half-type" << false << Std.getName();
4583 }
4584 } else {
4585 llvm_unreachable("expected DXIL or SPIR-V target");
4586 }
4587 } else
4588 Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
4589
4590 if (Opts.LangStd < LangStandard::lang_hlsl202x) {
4591 const LangStandard &Requested =
4593 const LangStandard &Recommended =
4594 LangStandard::getLangStandardForKind(LangStandard::lang_hlsl202x);
4595 Diags.Report(diag::warn_hlsl_langstd_minimal)
4596 << Requested.getName() << Recommended.getName();
4597 }
4598 }
4599
4600 return Diags.getNumErrors() == NumErrorsBefore;
4601}
4602
4604 switch (Action) {
4606 case frontend::ASTDump:
4607 case frontend::ASTPrint:
4608 case frontend::ASTView:
4610 case frontend::EmitBC:
4611 case frontend::EmitCIR:
4612 case frontend::EmitHTML:
4613 case frontend::EmitLLVM:
4616 case frontend::EmitObj:
4618 case frontend::FixIt:
4633 return false;
4634
4638 case frontend::InitOnly:
4644 return true;
4645 }
4646 llvm_unreachable("invalid frontend action");
4647}
4648
4650 switch (Action) {
4652 case frontend::EmitBC:
4653 case frontend::EmitCIR:
4654 case frontend::EmitHTML:
4655 case frontend::EmitLLVM:
4658 case frontend::EmitObj:
4665 return true;
4667 case frontend::ASTDump:
4668 case frontend::ASTPrint:
4669 case frontend::ASTView:
4671 case frontend::FixIt:
4683 case frontend::InitOnly:
4689 return false;
4690 }
4691 llvm_unreachable("invalid frontend action");
4692}
4693
4695 ArgumentConsumer Consumer,
4696 const LangOptions &LangOpts,
4697 const FrontendOptions &FrontendOpts,
4698 const CodeGenOptions &CodeGenOpts) {
4699 const PreprocessorOptions *PreprocessorOpts = &Opts;
4700
4701#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4702 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4703#include "clang/Driver/Options.inc"
4704#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4705
4706 if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate)
4707 GenerateArg(Consumer, OPT_pch_through_hdrstop_use);
4708
4709 for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn)
4710 GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);
4711
4712 if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false))
4713 GenerateArg(Consumer, OPT_preamble_bytes_EQ,
4714 Twine(Opts.PrecompiledPreambleBytes.first) + "," +
4715 (Opts.PrecompiledPreambleBytes.second ? "1" : "0"));
4716
4717 for (const auto &M : Opts.Macros) {
4718 // Don't generate __CET__ macro definitions. They are implied by the
4719 // -fcf-protection option that is generated elsewhere.
4720 if (M.first == "__CET__=1" && !M.second &&
4721 !CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch)
4722 continue;
4723 if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn &&
4724 !CodeGenOpts.CFProtectionBranch)
4725 continue;
4726 if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn &&
4727 CodeGenOpts.CFProtectionBranch)
4728 continue;
4729
4730 GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first);
4731 }
4732
4733 for (const auto &I : Opts.Includes) {
4734 // Don't generate OpenCL includes. They are implied by other flags that are
4735 // generated elsewhere.
4736 if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader &&
4737 ((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") ||
4738 I == "opencl-c.h"))
4739 continue;
4740 // Don't generate HLSL includes. They are implied by other flags that are
4741 // generated elsewhere.
4742 if (LangOpts.HLSL && I == "hlsl.h")
4743 continue;
4744
4745 GenerateArg(Consumer, OPT_include, I);
4746 }
4747
4748 for (const auto &CI : Opts.ChainedIncludes)
4749 GenerateArg(Consumer, OPT_chain_include, CI);
4750
4751 for (const auto &RF : Opts.RemappedFiles)
4752 GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second);
4753
4754 if (Opts.SourceDateEpoch)
4755 GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch));
4756
4757 if (Opts.DefineTargetOSMacros)
4758 GenerateArg(Consumer, OPT_fdefine_target_os_macros);
4759
4760 for (const auto &EmbedEntry : Opts.EmbedEntries)
4761 GenerateArg(Consumer, OPT_embed_dir_EQ, EmbedEntry);
4762
4763 // Don't handle LexEditorPlaceholders. It is implied by the action that is
4764 // generated elsewhere.
4765}
4766
4767static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
4768 DiagnosticsEngine &Diags,
4770 const FrontendOptions &FrontendOpts) {
4771 unsigned NumErrorsBefore = Diags.getNumErrors();
4772
4773 PreprocessorOptions *PreprocessorOpts = &Opts;
4774
4775#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4776 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4777#include "clang/Driver/Options.inc"
4778#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4779
4780 Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) ||
4781 Args.hasArg(OPT_pch_through_hdrstop_use);
4782
4783 for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
4784 Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
4785
4786 if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
4787 StringRef Value(A->getValue());
4788 size_t Comma = Value.find(',');
4789 unsigned Bytes = 0;
4790 unsigned EndOfLine = 0;
4791
4792 if (Comma == StringRef::npos ||
4793 Value.substr(0, Comma).getAsInteger(10, Bytes) ||
4794 Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
4795 Diags.Report(diag::err_drv_preamble_format);
4796 else {
4797 Opts.PrecompiledPreambleBytes.first = Bytes;
4798 Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
4799 }
4800 }
4801
4802 // Add macros from the command line.
4803 for (const auto *A : Args.filtered(OPT_D, OPT_U)) {
4804 if (A->getOption().matches(OPT_D))
4805 Opts.addMacroDef(A->getValue());
4806 else
4807 Opts.addMacroUndef(A->getValue());
4808 }
4809
4810 // Add the ordered list of -includes.
4811 for (const auto *A : Args.filtered(OPT_include))
4812 Opts.Includes.emplace_back(A->getValue());
4813
4814 for (const auto *A : Args.filtered(OPT_chain_include))
4815 Opts.ChainedIncludes.emplace_back(A->getValue());
4816
4817 for (const auto *A : Args.filtered(OPT_remap_file)) {
4818 std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
4819
4820 if (Split.second.empty()) {
4821 Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
4822 continue;
4823 }
4824
4825 Opts.addRemappedFile(Split.first, Split.second);
4826 }
4827
4828 if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
4829 StringRef Epoch = A->getValue();
4830 // SOURCE_DATE_EPOCH, if specified, must be a non-negative decimal integer.
4831 // On time64 systems, pick 253402300799 (the UNIX timestamp of
4832 // 9999-12-31T23:59:59Z) as the upper bound.
4833 const uint64_t MaxTimestamp =
4834 std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
4835 uint64_t V;
4836 if (Epoch.getAsInteger(10, V) || V > MaxTimestamp) {
4837 Diags.Report(diag::err_fe_invalid_source_date_epoch)
4838 << Epoch << MaxTimestamp;
4839 } else {
4840 Opts.SourceDateEpoch = V;
4841 }
4842 }
4843
4844 for (const auto *A : Args.filtered(OPT_embed_dir_EQ)) {
4845 StringRef Val = A->getValue();
4846 Opts.EmbedEntries.push_back(std::string(Val));
4847 }
4848
4849 // Always avoid lexing editor placeholders when we're just running the
4850 // preprocessor as we never want to emit the
4851 // "editor placeholder in source file" error in PP only mode.
4853 Opts.LexEditorPlaceholders = false;
4854
4856 Args.hasFlag(OPT_fdefine_target_os_macros,
4857 OPT_fno_define_target_os_macros, Opts.DefineTargetOSMacros);
4858
4859 return Diags.getNumErrors() == NumErrorsBefore;
4860}
4861
4862static void
4864 ArgumentConsumer Consumer,
4866 const PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
4867
4868#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4869 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4870#include "clang/Driver/Options.inc"
4871#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4872
4873 bool Generate_dM = isStrictlyPreprocessorAction(Action) && !Opts.ShowCPP;
4874 if (Generate_dM)
4875 GenerateArg(Consumer, OPT_dM);
4876 if (!Generate_dM && Opts.ShowMacros)
4877 GenerateArg(Consumer, OPT_dD);
4878 if (Opts.DirectivesOnly)
4879 GenerateArg(Consumer, OPT_fdirectives_only);
4880}
4881
4883 ArgList &Args, DiagnosticsEngine &Diags,
4885 unsigned NumErrorsBefore = Diags.getNumErrors();
4886
4887 PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
4888
4889#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4890 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4891#include "clang/Driver/Options.inc"
4892#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4893
4894 Opts.ShowCPP = isStrictlyPreprocessorAction(Action) && !Args.hasArg(OPT_dM);
4895 Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
4896 Opts.DirectivesOnly = Args.hasArg(OPT_fdirectives_only);
4897
4898 return Diags.getNumErrors() == NumErrorsBefore;
4899}
4900
4901static void GenerateTargetArgs(const TargetOptions &Opts,
4902 ArgumentConsumer Consumer) {
4903 const TargetOptions *TargetOpts = &Opts;
4904#define TARGET_OPTION_WITH_MARSHALLING(...) \
4905 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4906#include "clang/Driver/Options.inc"
4907#undef TARGET_OPTION_WITH_MARSHALLING
4908
4909 if (!Opts.SDKVersion.empty())
4910 GenerateArg(Consumer, OPT_target_sdk_version_EQ,
4911 Opts.SDKVersion.getAsString());
4912 if (!Opts.DarwinTargetVariantSDKVersion.empty())
4913 GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,
4914 Opts.DarwinTargetVariantSDKVersion.getAsString());
4915}
4916
4917static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
4918 DiagnosticsEngine &Diags) {
4919 unsigned NumErrorsBefore = Diags.getNumErrors();
4920
4921 TargetOptions *TargetOpts = &Opts;
4922
4923#define TARGET_OPTION_WITH_MARSHALLING(...) \
4924 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4925#include "clang/Driver/Options.inc"
4926#undef TARGET_OPTION_WITH_MARSHALLING
4927
4928 if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {
4929 llvm::VersionTuple Version;
4930 if (Version.tryParse(A->getValue()))
4931 Diags.Report(diag::err_drv_invalid_value)
4932 << A->getAsString(Args) << A->getValue();
4933 else
4934 Opts.SDKVersion = Version;
4935 }
4936 if (Arg *A =
4937 Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {
4938 llvm::VersionTuple Version;
4939 if (Version.tryParse(A->getValue()))
4940 Diags.Report(diag::err_drv_invalid_value)
4941 << A->getAsString(Args) << A->getValue();
4942 else
4943 Opts.DarwinTargetVariantSDKVersion = Version;
4944 }
4945
4946 return Diags.getNumErrors() == NumErrorsBefore;
4947}
4948
4949bool CompilerInvocation::CreateFromArgsImpl(
4950 CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs,
4951 DiagnosticsEngine &Diags, const char *Argv0) {
4952 unsigned NumErrorsBefore = Diags.getNumErrors();
4953
4954 // Parse the arguments.
4955 const OptTable &Opts = getDriverOptTable();
4956 llvm::opt::Visibility VisibilityMask(options::CC1Option);
4957 unsigned MissingArgIndex, MissingArgCount;
4958 InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
4959 MissingArgCount, VisibilityMask);
4960 LangOptions &LangOpts = Res.getLangOpts();
4961
4962 // Check for missing argument error.
4963 if (MissingArgCount)
4964 Diags.Report(diag::err_drv_missing_argument)
4965 << Args.getArgString(MissingArgIndex) << MissingArgCount;
4966
4967 // Issue errors on unknown arguments.
4968 for (const auto *A : Args.filtered(OPT_UNKNOWN)) {
4969 auto ArgString = A->getAsString(Args);
4970 std::string Nearest;
4971 if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1)
4972 Diags.Report(diag::err_drv_unknown_argument) << ArgString;
4973 else
4974 Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
4975 << ArgString << Nearest;
4976 }
4977
4978 ParseFileSystemArgs(Res.getFileSystemOpts(), Args, Diags);
4979 ParseMigratorArgs(Res.getMigratorOpts(), Args, Diags);
4980 ParseAnalyzerArgs(Res.getAnalyzerOpts(), Args, Diags);
4981 ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags,
4982 /*DefaultDiagColor=*/false);
4983 ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags, LangOpts.IsHeaderFile);
4984 // FIXME: We shouldn't have to pass the DashX option around here
4985 InputKind DashX = Res.getFrontendOpts().DashX;
4986 ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
4987 llvm::Triple T(Res.getTargetOpts().Triple);
4988 ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags);
4989 if (Res.getFrontendOpts().GenReducedBMI ||
4996 }
4997 ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
4998
4999 ParsePointerAuthArgs(LangOpts, Args, Diags);
5000
5001 ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
5002 Diags);
5004 LangOpts.ObjCExceptions = 1;
5005
5006 for (auto Warning : Res.getDiagnosticOpts().Warnings) {
5007 if (Warning == "misexpect" &&
5008 !Diags.isIgnored(diag::warn_profile_data_misexpect, SourceLocation())) {
5009 Res.getCodeGenOpts().MisExpect = true;
5010 }
5011 }
5012
5013 if (LangOpts.CUDA) {
5014 // During CUDA device-side compilation, the aux triple is the
5015 // triple used for host compilation.
5016 if (LangOpts.CUDAIsDevice)
5018 }
5019
5020 if (LangOpts.OpenACC && !Res.getFrontendOpts().UseClangIRPipeline &&
5022 Diags.Report(diag::warn_drv_openacc_without_cir);
5023
5024 // Set the triple of the host for OpenMP device compile.
5025 if (LangOpts.OpenMPIsTargetDevice)
5027
5028 ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
5030
5031 // FIXME: Override value name discarding when asan or msan is used because the
5032 // backend passes depend on the name of the alloca in order to print out
5033 // names.
5034 Res.getCodeGenOpts().DiscardValueNames &=
5035 !LangOpts.Sanitize.has(SanitizerKind::Address) &&
5036 !LangOpts.Sanitize.has(SanitizerKind::KernelAddress) &&
5037 !LangOpts.Sanitize.has(SanitizerKind::Memory) &&
5038 !LangOpts.Sanitize.has(SanitizerKind::KernelMemory);
5039
5040 ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags,
5042 Res.getFrontendOpts());
5045
5049 if (!Res.getDependencyOutputOpts().OutputFile.empty() &&
5050 Res.getDependencyOutputOpts().Targets.empty())
5051 Diags.Report(diag::err_fe_dependency_file_requires_MT);
5052
5053 // If sanitizer is enabled, disable OPT_ffine_grained_bitfield_accesses.
5054 if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
5055 !Res.getLangOpts().Sanitize.empty()) {
5056 Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
5057 Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
5058 }
5059
5060 // Store the command-line for using in the CodeView backend.
5061 if (Res.getCodeGenOpts().CodeViewCommandLine) {
5062 Res.getCodeGenOpts().Argv0 = Argv0;
5063 append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
5064 }
5065
5066 if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty() &&
5067 Res.getCodeGenOpts().getProfileUse() ==
5068 llvm::driver::ProfileInstrKind::ProfileNone)
5069 Diags.Report(diag::err_drv_profile_instrument_use_path_with_no_kind);
5070
5071 FixupInvocation(Res, Diags, Args, DashX);
5072
5073 return Diags.getNumErrors() == NumErrorsBefore;
5074}
5075
5077 ArrayRef<const char *> CommandLineArgs,
5078 DiagnosticsEngine &Diags,
5079 const char *Argv0) {
5080 CompilerInvocation DummyInvocation;
5081
5082 return RoundTrip(
5083 [](CompilerInvocation &Invocation, ArrayRef<const char *> CommandLineArgs,
5084 DiagnosticsEngine &Diags, const char *Argv0) {
5085 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
5086 },
5088 StringAllocator SA) {
5089 Args.push_back("-cc1");
5090 Invocation.generateCC1CommandLine(Args, SA);
5091 },
5092 Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
5093}
5094
5096 // FIXME: Consider using SHA1 instead of MD5.
5097 llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
5098
5099 // Note: For QoI reasons, the things we use as a hash here should all be
5100 // dumped via the -module-info flag.
5101
5102 // Start the signature with the compiler version.
5103 HBuilder.add(getClangFullRepositoryVersion());
5104
5105 // Also include the serialization version, in case LLVM_APPEND_VC_REV is off
5106 // and getClangFullRepositoryVersion() doesn't include git revision.
5108
5109 // Extend the signature with the language options
5110 // FIXME: Replace with C++20 `using enum LangOptions::CompatibilityKind`.
5112#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
5113 if constexpr (CK::Compatibility != CK::Benign) \
5114 HBuilder.add(LangOpts->Name);
5115#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description) \
5116 if constexpr (CK::Compatibility != CK::Benign) \
5117 HBuilder.add(static_cast<unsigned>(LangOpts->get##Name()));
5118#include "clang/Basic/LangOptions.def"
5119
5120 HBuilder.addRange(getLangOpts().ModuleFeatures);
5121
5122 HBuilder.add(getLangOpts().ObjCRuntime);
5123 HBuilder.addRange(getLangOpts().CommentOpts.BlockCommandNames);
5124
5125 // Extend the signature with the target options.
5126 HBuilder.add(getTargetOpts().Triple, getTargetOpts().CPU,
5127 getTargetOpts().TuneCPU, getTargetOpts().ABI);
5128 HBuilder.addRange(getTargetOpts().FeaturesAsWritten);
5129
5130 // Extend the signature with preprocessor options.
5131 const PreprocessorOptions &ppOpts = getPreprocessorOpts();
5132 HBuilder.add(ppOpts.UsePredefines, ppOpts.DetailedRecord);
5133
5134 const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
5135 for (const auto &Macro : getPreprocessorOpts().Macros) {
5136 // If we're supposed to ignore this macro for the purposes of modules,
5137 // don't put it into the hash.
5138 if (!hsOpts.ModulesIgnoreMacros.empty()) {
5139 // Check whether we're ignoring this macro.
5140 StringRef MacroDef = Macro.first;
5141 if (hsOpts.ModulesIgnoreMacros.count(
5142 llvm::CachedHashString(MacroDef.split('=').first)))
5143 continue;
5144 }
5145
5146 HBuilder.add(Macro);
5147 }
5148
5149 // Extend the signature with the sysroot and other header search options.
5150 HBuilder.add(hsOpts.Sysroot, hsOpts.ModuleFormat, hsOpts.UseDebugInfo,
5152 hsOpts.UseStandardCXXIncludes, hsOpts.UseLibcxx,
5154 HBuilder.add(hsOpts.ResourceDir);
5155
5156 if (hsOpts.ModulesStrictContextHash) {
5157 HBuilder.addRange(hsOpts.SystemHeaderPrefixes);
5158 HBuilder.addRange(hsOpts.UserEntries);
5159 HBuilder.addRange(hsOpts.VFSOverlayFiles);
5160
5161 const DiagnosticOptions &diagOpts = getDiagnosticOpts();
5162#define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name);
5163#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
5164 HBuilder.add(diagOpts.get##Name());
5165#include "clang/Basic/DiagnosticOptions.def"
5166#undef DIAGOPT
5167#undef ENUM_DIAGOPT
5168 }
5169
5170 // Extend the signature with the user build path.
5171 HBuilder.add(hsOpts.ModuleUserBuildPath);
5172
5173 // Extend the signature with the module file extensions.
5174 for (const auto &ext : getFrontendOpts().ModuleFileExtensions)
5175 ext->hashExtension(HBuilder);
5176
5177 // Extend the signature with the Swift version for API notes.
5179 if (!APINotesOpts.SwiftVersion.empty()) {
5180 HBuilder.add(APINotesOpts.SwiftVersion.getMajor());
5181 if (auto Minor = APINotesOpts.SwiftVersion.getMinor())
5182 HBuilder.add(*Minor);
5183 if (auto Subminor = APINotesOpts.SwiftVersion.getSubminor())
5184 HBuilder.add(*Subminor);
5185 if (auto Build = APINotesOpts.SwiftVersion.getBuild())
5186 HBuilder.add(*Build);
5187 }
5188
5189 // Extend the signature with affecting codegen options.
5190 {
5192#define CODEGENOPT(Name, Bits, Default, Compatibility) \
5193 if constexpr (CK::Compatibility != CK::Benign) \
5194 HBuilder.add(CodeGenOpts->Name);
5195#define ENUM_CODEGENOPT(Name, Type, Bits, Default, Compatibility) \
5196 if constexpr (CK::Compatibility != CK::Benign) \
5197 HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
5198#define DEBUGOPT(Name, Bits, Default, Compatibility)
5199#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility)
5200#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility)
5201#include "clang/Basic/CodeGenOptions.def"
5202 }
5203
5204 // When compiling with -gmodules, also hash -fdebug-prefix-map as it
5205 // affects the debug info in the PCM.
5206 if (getCodeGenOpts().DebugTypeExtRefs)
5207 HBuilder.addRange(getCodeGenOpts().DebugPrefixMap);
5208
5209 // Extend the signature with the affecting debug options.
5210 if (getHeaderSearchOpts().ModuleFormat == "obj") {
5211 // FIXME: Replace with C++20 `using enum CodeGenOptions::CompatibilityKind`.
5213#define DEBUGOPT(Name, Bits, Default, Compatibility) \
5214 if constexpr (CK::Compatibility != CK::Benign) \
5215 HBuilder.add(CodeGenOpts->Name);
5216#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility) \
5217 if constexpr (CK::Compatibility != CK::Benign) \
5218 HBuilder.add(CodeGenOpts->Name);
5219#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility) \
5220 if constexpr (CK::Compatibility != CK::Benign) \
5221 HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
5222#include "clang/Basic/DebugOptions.def"
5223 }
5224
5225 // Extend the signature with the enabled sanitizers, if at least one is
5226 // enabled. Sanitizers which cannot affect AST generation aren't hashed.
5227 SanitizerSet SanHash = getLangOpts().Sanitize;
5229 if (!SanHash.empty())
5230 HBuilder.add(SanHash.Mask);
5231
5232 llvm::MD5::MD5Result Result;
5233 HBuilder.getHasher().final(Result);
5234 uint64_t Hash = Result.high() ^ Result.low();
5235 return toString(llvm::APInt(64, Hash), 36, /*Signed=*/false);
5236}
5237
5239 ArgumentConsumer Consumer) const {
5240 llvm::Triple T(getTargetOpts().Triple);
5241
5245 GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer,
5246 /*DefaultDiagColor=*/false);
5247 GenerateFrontendArgs(getFrontendOpts(), Consumer, getLangOpts().IsHeaderFile);
5248 GenerateTargetArgs(getTargetOpts(), Consumer);
5252 GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX);
5253 GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T,
5254 getFrontendOpts().OutputFile, &getLangOpts());
5258 getFrontendOpts().ProgramAction);
5260}
5261
5262std::vector<std::string> CompilerInvocationBase::getCC1CommandLine() const {
5263 std::vector<std::string> Args{"-cc1"};
5265 [&Args](const Twine &Arg) { Args.push_back(Arg.str()); });
5266 return Args;
5267}
5268
5274
5276 getLangOpts().ImplicitModules = false;
5281 // The specific values we canonicalize to for pruning don't affect behaviour,
5282 /// so use the default values so they may be dropped from the command-line.
5283 getHeaderSearchOpts().ModuleCachePruneInterval = 7 * 24 * 60 * 60;
5284 getHeaderSearchOpts().ModuleCachePruneAfter = 31 * 24 * 60 * 60;
5285}
5286
5289 DiagnosticsEngine &Diags) {
5290 return createVFSFromCompilerInvocation(CI, Diags,
5291 llvm::vfs::getRealFileSystem());
5292}
5293
5301
5303 ArrayRef<std::string> VFSOverlayFiles, DiagnosticsEngine &Diags,
5305 if (VFSOverlayFiles.empty())
5306 return BaseFS;
5307
5309 // earlier vfs files are on the bottom
5310 for (const auto &File : VFSOverlayFiles) {
5311 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
5312 Result->getBufferForFile(File);
5313 if (!Buffer) {
5314 Diags.Report(diag::err_missing_vfs_overlay_file) << File;
5315 continue;
5316 }
5317
5318 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = llvm::vfs::getVFSFromYAML(
5319 std::move(Buffer.get()), /*DiagHandler*/ nullptr, File,
5320 /*DiagContext*/ nullptr, Result);
5321 if (!FS) {
5322 Diags.Report(diag::err_invalid_vfs_overlay) << File;
5323 continue;
5324 }
5325
5326 Result = FS;
5327 }
5328 return Result;
5329}
#define V(N, I)
Defines the Diagnostic-related interfaces.
Defines enum values for all the target-independent builtin functions.
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)
T & ensureOwned(std::shared_ptr< T > &Storage)
static void GenerateMigratorArgs(const MigratorOptions &Opts, ArgumentConsumer Consumer)
static const auto & getFrontendActionTable()
Return a table that associates command line option specifiers with the frontend action.
static void GenerateTargetArgs(const TargetOptions &Opts, ArgumentConsumer Consumer)
static std::optional< frontend::ActionKind > getFrontendAction(OptSpecifier &Opt)
Maps command line option to frontend action.
static bool checkVerifyPrefixes(const std::vector< std::string > &VerifyPrefixes, DiagnosticsEngine &Diags)
static SanitizerMaskCutoffs parseSanitizerWeightedKinds(StringRef FlagName, const std::vector< std::string > &Sanitizers, DiagnosticsEngine &Diags)
static void GenerateAPINotesArgs(const APINotesOptions &Opts, ArgumentConsumer Consumer)
static bool isCodeGenAction(frontend::ActionKind Action)
static std::optional< bool > normalizeSimpleNegativeFlag(OptSpecifier Opt, unsigned, const ArgList &Args, DiagnosticsEngine &)
static void GenerateFileSystemArgs(const FileSystemOptions &Opts, ArgumentConsumer Consumer)
static bool IsInputCompatibleWithStandard(InputKind IK, const LangStandard &S)
Check if input file kind and language standard are compatible.
static void denormalizeStringImpl(ArgumentConsumer Consumer, const Twine &Spelling, Option::OptionClass OptClass, unsigned, const Twine &Value)
static llvm::StringRef lookupStrInTable(unsigned Offset)
static void GeneratePreprocessorArgs(const PreprocessorOptions &Opts, ArgumentConsumer Consumer, const LangOptions &LangOpts, const FrontendOptions &FrontendOpts, const CodeGenOptions &CodeGenOpts)
static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, bool &IsHeaderFile)
static auto makeBooleanOptionDenormalizer(bool Value)
static void GeneratePreprocessorOutputArgs(const PreprocessorOutputOptions &Opts, ArgumentConsumer Consumer, frontend::ActionKind Action)
static bool isStrictlyPreprocessorAction(frontend::ActionKind Action)
static std::string serializeXRayInstrumentationBundle(const XRayInstrSet &S)
static bool ParseMigratorArgs(MigratorOptions &Opts, const ArgList &Args, DiagnosticsEngine &Diags)
static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor)
static T mergeForwardValue(T KeyPath, U Value)
static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args, DiagnosticsEngine &diags)
static void denormalizeStringVector(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, const std::vector< std::string > &Values)
static bool ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action, bool ShowLineMarkers)
static Expected< std::optional< uint32_t > > parseToleranceOption(StringRef Arg)
static std::optional< std::vector< std::string > > normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args, DiagnosticsEngine &)
static void GenerateAnalyzerArgs(const AnalyzerOptions &Opts, ArgumentConsumer Consumer)
static void GenerateOptimizationRemark(ArgumentConsumer Consumer, OptSpecifier OptEQ, StringRef Name, const CodeGenOptions::OptRemark &Remark)
Generate a remark argument. This is an inverse of ParseOptimizationRemark.
static bool ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action)
llvm::function_ref< void( CompilerInvocation &, SmallVectorImpl< const char * > &, CompilerInvocation::StringAllocator)> GenerateFn
static bool RoundTrip(ParseFn Parse, GenerateFn Generate, CompilerInvocation &RealInvocation, CompilerInvocation &DummyInvocation, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0, bool CheckAgainstOriginalInvocation=false, bool ForceRoundTrip=false)
May perform round-trip of command line arguments.
static T extractForwardValue(T KeyPath)
static void denormalizeSimpleEnum(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, T Value)
static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, DiagnosticsEngine &Diags)
std::shared_ptr< T > make_shared_copy(const T &X)
llvm::function_ref< bool(CompilerInvocation &, ArrayRef< const char * >, DiagnosticsEngine &, const char *)> ParseFn
static bool parseTestModuleFileExtensionArg(StringRef Arg, std::string &BlockName, unsigned &MajorVersion, unsigned &MinorVersion, bool &Hashed, std::string &UserInfo)
Parse the argument to the -ftest-module-file-extension command-line argument.
static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags)
static void GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts, ArgumentConsumer Consumer)
static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config, StringRef OptionName, StringRef DefaultVal)
static bool FixupInvocation(CompilerInvocation &Invocation, DiagnosticsEngine &Diags, const ArgList &Args, InputKind IK)
static void parseSanitizerKinds(StringRef FlagName, const std::vector< std::string > &Sanitizers, DiagnosticsEngine &Diags, SanitizerSet &S)
static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts, ArgumentConsumer Consumer)
Defines the clang::FileSystemOptions interface.
#define X(type, name)
Definition Value.h:97
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the clang::LangOptions interface.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines types useful for describing an Objective-C runtime.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Defines the clang::SanitizerKind enum.
Defines the clang::SourceLocation class and associated facilities.
#define CXXABI(Name, Str)
Defines the clang::TargetOptions class.
Defines version macros and version-related utility functions for Clang.
Defines the clang::XRayInstrKind enum.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Tracks various options which control how API notes are found and handled.
llvm::VersionTuple SwiftVersion
The Swift version which should be used for API notes.
std::vector< std::string > ModuleSearchPaths
The set of search paths where we API notes can be found for particular modules.
Stores options for the analyzer from the command line.
static std::vector< StringRef > getRegisteredPackages(bool IncludeExperimental=false)
Retrieves the list of packages generated from Checkers.td.
std::vector< std::pair< std::string, bool > > CheckersAndPackages
Pairs of checker/package name and enable/disable.
std::vector< std::string > SilencedCheckersAndPackages
Vector of checker/package names which will not emit warnings.
AnalysisDiagClients AnalysisDiagOpt
AnalysisConstraints AnalysisConstraintsOpt
ConfigTable Config
A key-value table of use-specified configuration values.
unsigned ShouldEmitErrorsOnInvalidConfigValue
AnalysisPurgeMode AnalysisPurgeOpt
bool isUnknownAnalyzerConfig(llvm::StringRef Name)
static std::vector< StringRef > getRegisteredCheckers(bool IncludeExperimental=false)
Retrieves the list of checkers generated from Checkers.td.
llvm::StringMap< std::string > ConfigTable
std::string FullCompilerInvocation
Store full compiler invocation for reproducible instructions in the generated report.
AnalysisInliningMode InliningMode
The mode of function selection used during inlining.
static bool isBuiltinFunc(llvm::StringRef Name)
Returns true if this is a libc/libm function without the '__builtin_' prefix.
Definition Builtins.cpp:123
CompatibilityKind
For ASTs produced with different option value, signifies their level of compatibility.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
llvm::SmallVector< std::pair< std::string, std::string >, 0 > CoveragePrefixMap
Prefix replacement map for source-based code coverage to remap source file paths in coverage mapping.
SanitizerSet SanitizeMergeHandlers
Set of sanitizer checks that can merge handlers (smaller code size at the expense of debuggability).
llvm::SmallVector< std::pair< std::string, std::string >, 0 > DebugPrefixMap
std::string OptRecordFile
The name of the file to which the backend should save YAML optimization records.
std::vector< BitcodeFileToLink > LinkBitcodeFiles
The files specified here are linked in to the module before optimizations.
std::optional< uint64_t > DiagnosticsHotnessThreshold
The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.
char CoverageVersion[4]
The version string to put into coverage files.
llvm::DenormalMode FPDenormalMode
The floating-point denormal mode to use.
std::string CoverageNotesFile
The filename with path we use for coverage notes files.
std::string ProfileInstrumentUsePath
Name of the profile file to use as input for -fprofile-instr-use.
std::string SampleProfileFile
Name of the profile file to use with -fprofile-sample-use.
uint64_t LargeDataThreshold
The code model-specific large data threshold to use (-mlarge-data-threshold).
std::string MemoryProfileOutput
Name of the profile file to use as output for with -fmemory-profile.
std::string CodeModel
The code model to use (-mcmodel).
std::string CoverageDataFile
The filename with path we use for coverage data files.
std::optional< uint32_t > DiagnosticsMisExpectTolerance
The maximum percentage profiling weights can deviate from the expected values in order to be included...
std::string StackUsageOutput
Name of the stack usage file (i.e., .su file) if user passes -fstack-usage.
std::string OptRecordPasses
The regex that filters the passes that should be saved to the optimization records.
std::string SaveTempsFilePrefix
Prefix to use for -save-temps output.
XRayInstrSet XRayInstrumentationBundle
Set of XRay instrumentation kinds to emit.
bool hasSanitizeCoverage() const
SanitizerSet SanitizeAnnotateDebugInfo
Set of sanitizer checks, for which the instrumentation will be annotated with extra debug info.
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
llvm::DenormalMode FP32DenormalMode
The floating-point denormal mode to use, for float.
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
SanitizerSet SanitizeRecover
Set of sanitizer checks that are non-fatal (i.e.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
OptRemark OptimizationRemark
Selected optimizations for which we should enable optimization remarks.
std::string ThinLTOIndexFile
Name of the function summary index file to use for ThinLTO function importing.
const char * Argv0
Executable and command-line used to create a given CompilerInvocation.
SanitizerMaskCutoffs SanitizeSkipHotCutoffs
Set of thresholds in a range [0.0, 1.0]: the top hottest code responsible for the given fraction of P...
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
std::vector< uint8_t > CmdArgs
List of backend command-line options for -fembed-bitcode.
OptRemark OptimizationRemarkAnalysis
Selected optimizations for which we should enable optimization analyses.
std::optional< double > AllowRuntimeCheckSkipHotCutoff
std::vector< std::string > CommandLineArgs
void resetNonModularOptions(StringRef ModuleFormat)
Reset all of the options that are not considered when building a module.
std::string OptRecordFormat
The format used for serializing remarks (default: YAML)
std::string DIBugsReportFilePath
The file to use for dumping bug report by Debugify for original debug info.
OptRemark OptimizationRemarkMissed
Selected optimizations for which we should enable missed optimization remarks.
The base class of CompilerInvocation.
std::shared_ptr< DiagnosticOptions > DiagnosticOpts
Options controlling the diagnostic engine.
std::shared_ptr< AnalyzerOptions > AnalyzerOpts
Options controlling the static analyzer.
std::shared_ptr< MigratorOptions > MigratorOpts
std::shared_ptr< PreprocessorOutputOptions > PreprocessorOutputOpts
Options controlling preprocessed output.
std::shared_ptr< APINotesOptions > APINotesOpts
Options controlling API notes.
std::shared_ptr< TargetOptions > TargetOpts
Options controlling the target.
const FrontendOptions & getFrontendOpts() const
const CodeGenOptions & getCodeGenOpts() const
llvm::function_ref< const char *(const Twine &)> StringAllocator
Command line generation.
const FileSystemOptions & getFileSystemOpts() const
std::shared_ptr< PreprocessorOptions > PPOpts
Options controlling the preprocessor (aside from #include handling).
const PreprocessorOutputOptions & getPreprocessorOutputOpts() const
std::vector< std::string > getCC1CommandLine() const
Generate cc1-compatible command line arguments from this instance, wrapping the result as a std::vect...
std::shared_ptr< FileSystemOptions > FSOpts
Options controlling file system operations.
const AnalyzerOptions & getAnalyzerOpts() const
const MigratorOptions & getMigratorOpts() const
void generateCC1CommandLine(llvm::SmallVectorImpl< const char * > &Args, StringAllocator SA) const
Generate cc1-compatible command line arguments from this instance.
CompilerInvocationBase & deep_copy_assign(const CompilerInvocationBase &X)
const DependencyOutputOptions & getDependencyOutputOpts() const
CompilerInvocationBase & shallow_copy_assign(const CompilerInvocationBase &X)
const TargetOptions & getTargetOpts() const
std::shared_ptr< CodeGenOptions > CodeGenOpts
Options controlling IRgen and the backend.
std::shared_ptr< LangOptions > LangOpts
Options controlling the language variant.
const APINotesOptions & getAPINotesOpts() const
const HeaderSearchOptions & getHeaderSearchOpts() const
std::shared_ptr< HeaderSearchOptions > HSOpts
Options controlling the #include directive.
const PreprocessorOptions & getPreprocessorOpts() const
const DiagnosticOptions & getDiagnosticOpts() const
const LangOptions & getLangOpts() const
Const getters.
std::shared_ptr< FrontendOptions > FrontendOpts
Options controlling the frontend itself.
llvm::function_ref< void(const Twine &)> ArgumentConsumer
std::shared_ptr< DependencyOutputOptions > DependencyOutputOpts
Options controlling dependency output.
Helper class for holding the data necessary to invoke the compiler.
PreprocessorOptions & getPreprocessorOpts()
void clearImplicitModuleBuildOptions()
Disable implicit modules and canonicalize options that are only used by implicit modules.
MigratorOptions & getMigratorOpts()
AnalyzerOptions & getAnalyzerOpts()
APINotesOptions & getAPINotesOpts()
static std::string GetResourcesPath(const char *Argv0, void *MainAddr)
Get the directory where the compiler headers reside, relative to the compiler binary (found by the pa...
static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0=nullptr)
Create a compiler invocation from a list of input options.
LangOptions & getLangOpts()
Mutable getters.
static bool checkCC1RoundTrip(ArrayRef< const char * > Args, DiagnosticsEngine &Diags, const char *Argv0=nullptr)
Check that Args can be parsed and re-serialized without change, emiting diagnostics for any differenc...
DependencyOutputOptions & getDependencyOutputOpts()
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()
HeaderSearchOptions & getHeaderSearchOpts()
DiagnosticOptions & getDiagnosticOpts()
PreprocessorOutputOptions & getPreprocessorOutputOpts()
Same as CompilerInvocation, but with copy-on-write optimization.
LangOptions & getMutLangOpts()
Mutable getters.
HeaderSearchOptions & getMutHeaderSearchOpts()
PreprocessorOptions & getMutPreprocessorOpts()
PreprocessorOutputOptions & getMutPreprocessorOutputOpts()
FileSystemOptions & getMutFileSystemOpts()
DiagnosticOptions & getMutDiagnosticOpts()
DependencyOutputOptions & getMutDependencyOutputOpts()
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
ShowIncludesDestination ShowIncludesDest
Destination of cl.exe style /showIncludes info.
HeaderIncludeFormatKind HeaderIncludeFormat
The format of header information.
std::string OutputFile
The file to write dependency output to.
HeaderIncludeFilteringKind HeaderIncludeFiltering
Determine whether header information should be filtered.
std::vector< std::string > Targets
A list of names to use as the targets in the dependency file; this list must contain at least one ent...
std::vector< std::pair< std::string, ExtraDepKind > > ExtraDeps
A list of extra dependencies (filename and kind) to be used for every target.
unsigned IncludeSystemHeaders
Include system header dependencies.
static llvm::IntrusiveRefCntPtr< DiagnosticIDs > create()
Options for controlling the compiler diagnostics engine.
std::string DiagnosticSuppressionMappingsFile
Path for the file that defines diagnostic suppression mappings.
std::vector< std::string > Remarks
The list of -R... options used to alter the diagnostic mappings, with the prefixes removed.
std::vector< std::string > Warnings
The list of -W... options used to alter the diagnostic mappings, with the prefixes removed.
std::vector< std::string > VerifyPrefixes
The prefixes for comment directives sought by -verify ("expected" by default).
std::string DiagnosticSerializationFile
The file to serialize diagnostics to (non-appending).
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:232
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)
Set the diagnostic client associated with this diagnostic object.
unsigned getNumErrors() const
Definition Diagnostic.h:886
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition Diagnostic.h:951
unsigned getNumWarnings() const
Definition Diagnostic.h:887
Keeps track of options that affect how file operations are performed.
FrontendOptions - Options for controlling the behavior of the frontend.
InputKind DashX
The input kind, either specified via -x argument or deduced from the input file name.
std::vector< std::string > ModuleFiles
The list of additional prebuilt module files to load before processing the input.
unsigned ClangIRDisablePasses
Disable Clang IR specific (CIR) passes.
std::map< std::string, std::vector< std::string > > PluginArgs
Args to pass to the plugins.
unsigned ClangIRDisableCIRVerifier
Disable Clang IR (CIR) verifier.
unsigned IsSystemModule
When using -emit-module, treat the modulemap as a system module.
unsigned UseClangIRPipeline
Use Clang IR pipeline to emit code.
ASTDumpOutputFormat ASTDumpFormat
Specifies the output format of the AST.
std::optional< std::string > AuxTargetCPU
Auxiliary target CPU for CUDA/HIP compilation.
std::string OutputFile
The output file, if any.
unsigned ShowStats
Show frontend performance metrics and statistics.
unsigned GenReducedBMI
Whether to generate reduced BMI for C++20 named modules.
std::string ActionName
The name of the action to run when using a plugin action.
std::vector< std::shared_ptr< ModuleFileExtension > > ModuleFileExtensions
The list of module file extensions.
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
std::string FixItSuffix
If given, the new suffix for fix-it rewritten files.
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
std::vector< std::string > Plugins
The list of plugins to load.
unsigned ASTDumpAll
Whether we deserialize all decls when forming AST dumps.
unsigned GenerateGlobalModuleIndex
Whether we can generate the global module index if needed.
unsigned DisableFree
Disable memory freeing on exit.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
frontend::ActionKind ProgramAction
The frontend action to perform.
std::optional< std::vector< std::string > > AuxTargetFeatures
Auxiliary target features for CUDA/HIP compilation.
std::string AuxTriple
Auxiliary triple for CUDA/HIP compilation.
unsigned UseGlobalModuleIndex
Whether we can use the global module index if available.
unsigned ASTDumpDecls
Whether we include declaration dumps in AST dumps.
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 ModulesSkipHeaderSearchPaths
Whether to entirely skip writing header search paths.
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.
unsigned ModulesSkipDiagnosticOptions
Whether to entirely skip writing diagnostic options.
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.
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.
@ AddUnsignedOverflowTest
if (a + b < a)
@ All
Exclude all overflow patterns (below)
@ AddSignedOverflowTest
if (a + b < a)
@ PostDecrInWhile
while (count–)
CompatibilityKind
For ASTs produced with different option value, signifies their level of compatibility.
Definition LangOptions.h:82
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
void resetNonModularOptions()
Reset all of the options that are not considered when building a module.
std::optional< TargetCXXABI::Kind > CXXABI
C++ ABI to compile with, if specified by the frontend through -fc++-abi=.
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
clang::ObjCRuntime ObjCRuntime
std::string getOpenCLVersionString() const
Return the OpenCL C or C++ for OpenCL language name and version as a string.
unsigned OverflowPatternExclusionMask
Which overflow patterns should be excluded from sanitizer instrumentation.
SanitizerSet Sanitize
Set of enabled sanitizers.
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
static void setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T, std::vector< std::string > &Includes, LangStandard::Kind LangStd=LangStandard::lang_unspecified)
Set language defaults for the given input language and language standard in the given LangOptions obj...
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
std::string RandstructSeed
The seed used by the randomize structure layout feature.
std::map< std::string, std::string, std::greater< std::string > > MacroPrefixMap
A prefix map for FILE, BASE_FILE and __builtin_FILE().
bool isTargetDevice() const
True when compiling for an offloading target device.
LangStandard::Kind LangStd
The used language standard.
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
bool SanitizeCoverage
Is at least one coverage instrumentation type enabled.
std::vector< llvm::Triple > OMPTargetTriples
Triples of the OpenMP targets that the host code codegen should take into account in order to generat...
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
The basic abstraction for the target Objective-C runtime.
Definition ObjCRuntime.h:28
bool allowsWeak() const
Does this runtime allow the use of __weak?
Kind getKind() const
Definition ObjCRuntime.h:77
bool tryParse(StringRef input)
Try to parse an Objective-C runtime specification from the given string.
std::string getAsString() const
bool allowsARC() const
Does this runtime allow ARC at all?
@ FragileMacOSX
'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...
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 separ...
std::vector< std::string > Includes
std::pair< unsigned, bool > PrecompiledPreambleBytes
If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...
bool LexEditorPlaceholders
When enabled, the preprocessor will construct editor placeholder tokens.
void resetNonModularOptions()
Reset any options that are not considered when building a module.
void addMacroUndef(StringRef Name)
std::set< std::string > DeserializedPCHDeclsToErrorOn
This is a set of names for decls that we do not want to be deserialized, and we emit an error if they...
std::vector< std::string > EmbedEntries
User specified embed entries.
void addMacroDef(StringRef Name)
bool DefineTargetOSMacros
Indicates whether to predefine target OS macros.
bool DetailedRecord
Whether we should maintain a detailed record of all macro definitions and expansions.
std::vector< std::string > ChainedIncludes
Headers that will be converted to chained PCHs in memory.
bool PCHWithHdrStop
When true, we are creating or using a PCH where a pragma hdrstop is expected to indicate the beginnin...
std::optional< uint64_t > SourceDateEpoch
If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.
bool UsePredefines
Initialize the preprocessor with the compiler and target specific predefines.
void addRemappedFile(StringRef From, StringRef To)
std::vector< std::pair< std::string, bool > > Macros
PreprocessorOutputOptions - Options for controlling the C preprocessor output (e.g....
unsigned ShowMacros
Print macro definitions.
unsigned ShowCPP
Print normal preprocessed output.
unsigned ShowLineMarkers
Show #line markers.
unsigned DirectivesOnly
Process directives but do not expand macros.
Encodes a location in the source.
static bool isSupportedCXXABI(const llvm::Triple &T, Kind Kind)
static const auto & getSpelling(Kind ABIKind)
static bool usesRelativeVTables(const llvm::Triple &T)
static bool isABI(StringRef Name)
Kind getKind() const
Options for controlling the target.
std::string Triple
The name of the target triple to compile for.
llvm::VersionTuple SDKVersion
The version of the SDK which was used during the compilation.
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.
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:127
#define bool
Definition gpuintrin.h:32
constexpr XRayInstrMask None
Definition XRayInstr.h:38
constexpr XRayInstrMask All
Definition XRayInstr.h:43
const llvm::opt::OptTable & getDriverOptTable()
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
IncludeDirGroup
IncludeDirGroup - Identifies the group an include Entry belongs to, representing its relative positiv...
@ CXXSystem
Like System, but only used for C++.
@ Angled
Paths for '#include <>' added by '-I'.
@ CSystem
Like System, but only used for C.
@ System
Like Angled, but marks system directories.
@ Quoted
'#include ""' paths, added by 'gcc -iquote'.
@ ExternCSystem
Like System, but headers are implicitly wrapped in extern "C".
@ ObjCSystem
Like System, but only used for ObjC.
@ ObjCXXSystem
Like System, but only used for ObjC++.
@ After
Like System, but searched after the system directories.
@ GenerateHeaderUnit
Generate a C++20 header unit module from a header file.
@ VerifyPCH
Load and verify that a PCH file is usable.
@ PrintPreprocessedInput
-E mode.
@ RewriteTest
Rewriter playground.
@ ParseSyntaxOnly
Parse and perform semantic analysis.
@ TemplightDump
Dump template instantiations.
@ 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.
@ 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.
bool EQ(InterpState &S, CodePtr OpPC)
Definition Interp.h:1228
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.
bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags=nullptr, bool DefaultDiagColor=true)
Fill out Opts based on the options given in Args.
SanitizerMask getPPTransparentSanitizers()
Return the sanitizers which do not affect preprocessing.
Definition Sanitizers.h:230
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromOverlayFiles(ArrayRef< std::string > VFSOverlayFiles, DiagnosticsEngine &Diags, IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS)
DiagnosticLevelMask
A bitmask representing the diagnostic levels used by VerifyDiagnosticConsumer.
const char * headerIncludeFormatKindToString(HeaderIncludeFormatKind K)
std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)
constexpr uint16_t BlockDescriptorConstantDiscriminator
Constant discriminator to be used with block descriptor pointers.
constexpr uint16_t IsaPointerConstantDiscriminator
Constant discriminator to be used with objective-c isa pointers.
const char * headerIncludeFilteringKindToString(HeaderIncludeFilteringKind K)
std::vector< std::string > Macros
A list of macros of the form <definition>=<expansion> .
Definition Format.h:3507
AnalysisConstraints
AnalysisConstraints - Set of available constraint models.
@ Success
Annotation was successful.
Definition Parser.h:65
@ Parse
Parse the block; this code is always used.
Definition Parser.h:137
constexpr uint16_t SuperPointerConstantDiscriminator
Constant discriminator to be used with objective-c superclass pointers.
void serializeSanitizerSet(SanitizerSet Set, SmallVectorImpl< StringRef > &Values)
Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
LLVM_READONLY bool isLetter(unsigned char c)
Return true if this character is an ASCII letter: [a-zA-Z].
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 MethodListPointerConstantDiscriminator
Constant discriminator to be used with method list pointers.
constexpr uint16_t ClassROConstantDiscriminator
Constant discriminator to be used with objective-c class_ro_t pointers.
constexpr uint16_t InitFiniPointerConstantDiscriminator
Constant discriminator to be used with function pointers in .init_array and .fini_array.
@ C
Languages that the frontend can parse and compile.
@ CIR
LLVM IR & CIR: we accept these so that we can run the optimizer on them, and compile them to assembly...
@ Asm
Assembly: we accept this only so that we can preprocess it.
bool parseSanitizerWeightedValue(StringRef Value, bool AllowGroups, SanitizerMaskCutoffs &Cutoffs)
Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= or -fno-sanitize= value lis...
@ Result
The result type of a method or function.
Definition TypeBase.h:905
XRayInstrMask parseXRayInstrValue(StringRef Value)
Parses a command line argument into a mask.
Definition XRayInstr.cpp:19
const FunctionProtoType * T
IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)
void serializeXRayInstrValue(XRayInstrSet Set, SmallVectorImpl< StringRef > &Values)
Serializes a set into a list of command line arguments.
Definition XRayInstr.cpp:34
AnalysisPurgeMode
AnalysisPurgeModes - Set of available strategies for dead symbol removal.
void serializeSanitizerMaskCutoffs(const SanitizerMaskCutoffs &Cutoffs, SmallVectorImpl< std::string > &Values)
Serialize a SanitizerMaskCutoffs into command line arguments.
ShaderStage
Shader programs run in specific pipeline stages.
Definition LangOptions.h:43
constexpr uint16_t StdTypeInfoVTablePointerConstantDiscrimination
Constant discriminator for std::type_info vtable pointers: 0xB1EA/45546 The value is ptrauth_string_d...
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
AnalysisDiagClients
AnalysisDiagClients - Set of available diagnostic clients for rendering analysis results.
@ NUM_ANALYSIS_DIAG_CLIENTS
std::string getClangFullRepositoryVersion()
Retrieves the full repository version that is an amalgamation of the information in getClangRepositor...
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.
AnalysisInliningMode
AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.
@ NumInliningModes
@ HIFMT_Textual
int const char * function
Definition c++config.h:31
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
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...
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.
clang::Language getLanguage() const
Get the language that this standard describes.
const char * getDescription() const
getDescription - Get the description of this standard.
static const LangStandard & getLangStandardForKind(Kind K)
const char * getName() const
getName - Get the name of this standard.
static Kind getLangKind(StringRef Name)
static ParsedSourceLocation FromString(StringRef Str)
Construct a parsed source location from a string; the Filename is empty on error.
std::string ToString() const
Serialize ParsedSourceLocation back to a string.
PointerAuthSchema BlockDescriptorPointers
The ABI for pointers to block descriptors.
PointerAuthSchema BlockHelperFunctionPointers
The ABI for block object copy/destroy function pointers.
PointerAuthSchema CXXVTablePointers
The ABI for C++ virtual table pointers (the pointer to the table itself) as installed in an actual cl...
PointerAuthSchema InitFiniPointers
The ABI for function addresses in .init_array and .fini_array.
PointerAuthSchema BlockInvocationFunctionPointers
The ABI for block invocation function pointers.
PointerAuthSchema BlockByrefHelperFunctionPointers
The ABI for __block variable copy/destroy function pointers.
PointerAuthSchema CXXVTTVTablePointers
The ABI for C++ virtual table pointers as installed in a VTT.
bool ReturnAddresses
Should return addresses be authenticated?
PointerAuthSchema CXXTypeInfoVTablePointer
TypeInfo has external ABI requirements and is emitted without actually having parsed the libcxx defin...
bool AArch64JumpTableHardening
Use hardened lowering for jump-table dispatch?
PointerAuthSchema ObjCMethodListPointer
The ABI for a reference to an Objective-C method list in _class_ro_t.
PointerAuthSchema FunctionPointers
The ABI for C function pointers.
PointerAuthSchema ObjCSuperPointers
The ABI for Objective-C superclass pointers.
bool AuthTraps
Do authentication failures cause a trap?
PointerAuthSchema CXXMemberFunctionPointers
The ABI for C++ member function pointers.
PointerAuthSchema CXXVirtualVariadicFunctionPointers
The ABI for variadic C++ virtual function pointers.
PointerAuthSchema ObjCMethodListFunctionPointers
The ABI for Objective-C method lists.
PointerAuthSchema ObjCClassROPointers
The ABI for Objective-C class_ro_t pointers.
PointerAuthSchema CXXVirtualFunctionPointers
The ABI for most C++ virtual function pointers, i.e. v-table entries.
PointerAuthSchema ObjCIsaPointers
The ABI for Objective-C isa pointers.
bool IndirectGotos
Do indirect goto label addresses need to be authenticated?
void clear(SanitizerMask K=SanitizerKind::All)
Disable the sanitizers specified in K.
Definition Sanitizers.h:195
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
Definition Sanitizers.h:187
bool empty() const
Returns true if no sanitizers are enabled.
Definition Sanitizers.h:198
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition Sanitizers.h:201
XRayInstrMask Mask
Definition XRayInstr.h:65
void set(XRayInstrMask K, bool Value)
Definition XRayInstr.h:55