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.AllocTokenMax)
1837 GenerateArg(Consumer, OPT_falloc_token_max_EQ,
1838 std::to_string(*Opts.AllocTokenMax));
1839
1840 if (!Opts.EmitVersionIdentMetadata)
1841 GenerateArg(Consumer, OPT_Qn);
1842
1843 switch (Opts.FiniteLoops) {
1845 break;
1847 GenerateArg(Consumer, OPT_ffinite_loops);
1848 break;
1850 GenerateArg(Consumer, OPT_fno_finite_loops);
1851 break;
1852 }
1853
1854 if (Opts.StaticClosure)
1855 GenerateArg(Consumer, OPT_static_libclosure);
1856}
1857
1858bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
1859 InputKind IK,
1860 DiagnosticsEngine &Diags,
1861 const llvm::Triple &T,
1862 const std::string &OutputFile,
1863 const LangOptions &LangOptsRef) {
1864 unsigned NumErrorsBefore = Diags.getNumErrors();
1865
1866 unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
1867 // TODO: This could be done in Driver
1868 unsigned MaxOptLevel = 3;
1869 if (OptimizationLevel > MaxOptLevel) {
1870 // If the optimization level is not supported, fall back on the default
1871 // optimization
1872 Diags.Report(diag::warn_drv_optimization_value)
1873 << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
1874 OptimizationLevel = MaxOptLevel;
1875 }
1876 Opts.OptimizationLevel = OptimizationLevel;
1877
1878 // The key paths of codegen options defined in Options.td start with
1879 // "CodeGenOpts.". Let's provide the expected variable name and type.
1880 CodeGenOptions &CodeGenOpts = Opts;
1881 // Some codegen options depend on language options. Let's provide the expected
1882 // variable name and type.
1883 const LangOptions *LangOpts = &LangOptsRef;
1884
1885#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1886 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
1887#include "clang/Driver/Options.inc"
1888#undef CODEGEN_OPTION_WITH_MARSHALLING
1889
1890 // At O0 we want to fully disable inlining outside of cases marked with
1891 // 'alwaysinline' that are required for correctness.
1892 if (Opts.OptimizationLevel == 0) {
1893 Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
1894 } else if (const Arg *A = Args.getLastArg(options::OPT_finline_functions,
1895 options::OPT_finline_hint_functions,
1896 options::OPT_fno_inline_functions,
1897 options::OPT_fno_inline)) {
1898 // Explicit inlining flags can disable some or all inlining even at
1899 // optimization levels above zero.
1900 if (A->getOption().matches(options::OPT_finline_functions))
1901 Opts.setInlining(CodeGenOptions::NormalInlining);
1902 else if (A->getOption().matches(options::OPT_finline_hint_functions))
1903 Opts.setInlining(CodeGenOptions::OnlyHintInlining);
1904 else
1905 Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
1906 } else {
1907 Opts.setInlining(CodeGenOptions::NormalInlining);
1908 }
1909
1910 // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to
1911 // -fdirect-access-external-data.
1912 Opts.DirectAccessExternalData =
1913 Args.hasArg(OPT_fdirect_access_external_data) ||
1914 (!Args.hasArg(OPT_fno_direct_access_external_data) &&
1915 LangOpts->PICLevel == 0);
1916
1917 if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
1918 unsigned Val =
1919 llvm::StringSwitch<unsigned>(A->getValue())
1920 .Case("line-tables-only", llvm::codegenoptions::DebugLineTablesOnly)
1921 .Case("line-directives-only",
1922 llvm::codegenoptions::DebugDirectivesOnly)
1923 .Case("constructor", llvm::codegenoptions::DebugInfoConstructor)
1924 .Case("limited", llvm::codegenoptions::LimitedDebugInfo)
1925 .Case("standalone", llvm::codegenoptions::FullDebugInfo)
1926 .Case("unused-types", llvm::codegenoptions::UnusedTypeInfo)
1927 .Default(~0U);
1928 if (Val == ~0U)
1929 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1930 << A->getValue();
1931 else
1932 Opts.setDebugInfo(static_cast<llvm::codegenoptions::DebugInfoKind>(Val));
1933 }
1934
1935 // If -fuse-ctor-homing is set and limited debug info is already on, then use
1936 // constructor homing, and vice versa for -fno-use-ctor-homing.
1937 if (const Arg *A =
1938 Args.getLastArg(OPT_fuse_ctor_homing, OPT_fno_use_ctor_homing)) {
1939 if (A->getOption().matches(OPT_fuse_ctor_homing) &&
1940 Opts.getDebugInfo() == llvm::codegenoptions::LimitedDebugInfo)
1941 Opts.setDebugInfo(llvm::codegenoptions::DebugInfoConstructor);
1942 if (A->getOption().matches(OPT_fno_use_ctor_homing) &&
1943 Opts.getDebugInfo() == llvm::codegenoptions::DebugInfoConstructor)
1944 Opts.setDebugInfo(llvm::codegenoptions::LimitedDebugInfo);
1945 }
1946
1947 for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) {
1948 auto Split = StringRef(Arg).split('=');
1949 Opts.DebugPrefixMap.emplace_back(Split.first, Split.second);
1950 }
1951
1952 for (const auto &Arg : Args.getAllArgValues(OPT_fcoverage_prefix_map_EQ)) {
1953 auto Split = StringRef(Arg).split('=');
1954 Opts.CoveragePrefixMap.emplace_back(Split.first, Split.second);
1955 }
1956
1957 const llvm::Triple::ArchType DebugEntryValueArchs[] = {
1958 llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64,
1959 llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips,
1960 llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el,
1961 llvm::Triple::riscv32, llvm::Triple::riscv64};
1962
1963 if (Opts.OptimizationLevel > 0 && Opts.hasReducedDebugInfo() &&
1964 llvm::is_contained(DebugEntryValueArchs, T.getArch()))
1965 Opts.EmitCallSiteInfo = true;
1966
1967 if (!Opts.EnableDIPreservationVerify && Opts.DIBugsReportFilePath.size()) {
1968 Diags.Report(diag::warn_ignoring_verify_debuginfo_preserve_export)
1969 << Opts.DIBugsReportFilePath;
1970 Opts.DIBugsReportFilePath = "";
1971 }
1972
1973 Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
1974 Args.hasArg(OPT_new_struct_path_tbaa);
1975 Opts.OptimizeSize = getOptimizationLevelSize(Args);
1976 Opts.SimplifyLibCalls = !LangOpts->NoBuiltin;
1977 if (Opts.SimplifyLibCalls)
1978 Opts.NoBuiltinFuncs = LangOpts->NoBuiltinFuncs;
1979 Opts.UnrollLoops =
1980 Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
1981 (Opts.OptimizationLevel > 1));
1982 Opts.InterchangeLoops =
1983 Args.hasFlag(OPT_floop_interchange, OPT_fno_loop_interchange, false);
1984 Opts.FuseLoops = Args.hasFlag(OPT_fexperimental_loop_fusion,
1985 OPT_fno_experimental_loop_fusion, false);
1986 Opts.BinutilsVersion =
1987 std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));
1988
1989 Opts.DebugTemplateAlias = Args.hasArg(OPT_gtemplate_alias);
1990
1991 Opts.DebugNameTable = static_cast<unsigned>(
1992 Args.hasArg(OPT_ggnu_pubnames)
1993 ? llvm::DICompileUnit::DebugNameTableKind::GNU
1994 : Args.hasArg(OPT_gpubnames)
1995 ? llvm::DICompileUnit::DebugNameTableKind::Default
1996 : llvm::DICompileUnit::DebugNameTableKind::None);
1997 if (const Arg *A = Args.getLastArg(OPT_gsimple_template_names_EQ)) {
1998 StringRef Value = A->getValue();
1999 if (Value != "simple" && Value != "mangled")
2000 Diags.Report(diag::err_drv_unsupported_option_argument)
2001 << A->getSpelling() << A->getValue();
2002 Opts.setDebugSimpleTemplateNames(
2003 StringRef(A->getValue()) == "simple"
2004 ? llvm::codegenoptions::DebugTemplateNamesKind::Simple
2005 : llvm::codegenoptions::DebugTemplateNamesKind::Mangled);
2006 }
2007
2008 if (Args.hasArg(OPT_ftime_report, OPT_ftime_report_EQ, OPT_ftime_report_json,
2009 OPT_stats_file_timers)) {
2010 Opts.TimePasses = true;
2011
2012 // -ftime-report= is only for new pass manager.
2013 if (const Arg *EQ = Args.getLastArg(OPT_ftime_report_EQ)) {
2014 StringRef Val = EQ->getValue();
2015 if (Val == "per-pass")
2016 Opts.TimePassesPerRun = false;
2017 else if (Val == "per-pass-run")
2018 Opts.TimePassesPerRun = true;
2019 else
2020 Diags.Report(diag::err_drv_invalid_value)
2021 << EQ->getAsString(Args) << EQ->getValue();
2022 }
2023
2024 if (Args.getLastArg(OPT_ftime_report_json))
2025 Opts.TimePassesJson = true;
2026 }
2027
2028 Opts.PrepareForLTO = false;
2029 Opts.PrepareForThinLTO = false;
2030 if (Arg *A = Args.getLastArg(OPT_flto_EQ)) {
2031 Opts.PrepareForLTO = true;
2032 StringRef S = A->getValue();
2033 if (S == "thin")
2034 Opts.PrepareForThinLTO = true;
2035 else if (S != "full")
2036 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
2037 if (Args.hasArg(OPT_funified_lto))
2038 Opts.PrepareForThinLTO = true;
2039 }
2040 if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
2041 if (IK.getLanguage() != Language::LLVM_IR)
2042 Diags.Report(diag::err_drv_argument_only_allowed_with)
2043 << A->getAsString(Args) << "-x ir";
2044 Opts.ThinLTOIndexFile =
2045 std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ));
2046 }
2047 if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))
2048 Opts.SaveTempsFilePrefix =
2049 llvm::StringSwitch<std::string>(A->getValue())
2050 .Case("obj", OutputFile)
2051 .Default(llvm::sys::path::filename(OutputFile).str());
2052
2053 // The memory profile runtime appends the pid to make this name more unique.
2054 const char *MemProfileBasename = "memprof.profraw";
2055 if (Args.hasArg(OPT_fmemory_profile_EQ)) {
2056 SmallString<128> Path(Args.getLastArgValue(OPT_fmemory_profile_EQ));
2057 llvm::sys::path::append(Path, MemProfileBasename);
2058 Opts.MemoryProfileOutput = std::string(Path);
2059 } else if (Args.hasArg(OPT_fmemory_profile))
2060 Opts.MemoryProfileOutput = MemProfileBasename;
2061
2062 if (Opts.CoverageNotesFile.size() || Opts.CoverageDataFile.size()) {
2063 if (Args.hasArg(OPT_coverage_version_EQ)) {
2064 StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
2065 if (CoverageVersion.size() != 4) {
2066 Diags.Report(diag::err_drv_invalid_value)
2067 << Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)
2068 << CoverageVersion;
2069 } else {
2070 memcpy(Opts.CoverageVersion, CoverageVersion.data(), 4);
2071 }
2072 }
2073 }
2074 // FIXME: For backend options that are not yet recorded as function
2075 // attributes in the IR, keep track of them so we can embed them in a
2076 // separate data section and use them when building the bitcode.
2077 for (const auto &A : Args) {
2078 // Do not encode output and input.
2079 if (A->getOption().getID() == options::OPT_o ||
2080 A->getOption().getID() == options::OPT_INPUT ||
2081 A->getOption().getID() == options::OPT_x ||
2082 A->getOption().getID() == options::OPT_fembed_bitcode ||
2083 A->getOption().matches(options::OPT_W_Group))
2084 continue;
2085 ArgStringList ASL;
2086 A->render(Args, ASL);
2087 for (const auto &arg : ASL) {
2088 StringRef ArgStr(arg);
2089 llvm::append_range(Opts.CmdArgs, ArgStr);
2090 // using \00 to separate each commandline options.
2091 Opts.CmdArgs.push_back('\0');
2092 }
2093 }
2094
2095 auto XRayInstrBundles =
2096 Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
2097 if (XRayInstrBundles.empty())
2099 else
2100 for (const auto &A : XRayInstrBundles)
2101 parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args,
2102 Diags, Opts.XRayInstrumentationBundle);
2103
2104 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
2105 StringRef Name = A->getValue();
2106 if (Name == "full") {
2107 Opts.CFProtectionReturn = 1;
2108 Opts.CFProtectionBranch = 1;
2109 } else if (Name == "return")
2110 Opts.CFProtectionReturn = 1;
2111 else if (Name == "branch")
2112 Opts.CFProtectionBranch = 1;
2113 else if (Name != "none")
2114 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
2115 }
2116
2117 if (Opts.CFProtectionBranch && T.isRISCV()) {
2118 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
2119 const auto Scheme =
2120 llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
2121#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
2122 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
2123#include "clang/Basic/CFProtectionOptions.def"
2126 Opts.setCFBranchLabelScheme(Scheme);
2127 else
2128 Diags.Report(diag::err_drv_invalid_value)
2129 << A->getAsString(Args) << A->getValue();
2130 }
2131 }
2132
2133 if (const Arg *A = Args.getLastArg(OPT_mfunction_return_EQ)) {
2134 auto Val = llvm::StringSwitch<llvm::FunctionReturnThunksKind>(A->getValue())
2135 .Case("keep", llvm::FunctionReturnThunksKind::Keep)
2136 .Case("thunk-extern", llvm::FunctionReturnThunksKind::Extern)
2137 .Default(llvm::FunctionReturnThunksKind::Invalid);
2138 // SystemZ might want to add support for "expolines."
2139 if (!T.isX86())
2140 Diags.Report(diag::err_drv_argument_not_allowed_with)
2141 << A->getSpelling() << T.getTriple();
2142 else if (Val == llvm::FunctionReturnThunksKind::Invalid)
2143 Diags.Report(diag::err_drv_invalid_value)
2144 << A->getAsString(Args) << A->getValue();
2145 else if (Val == llvm::FunctionReturnThunksKind::Extern &&
2146 Args.getLastArgValue(OPT_mcmodel_EQ) == "large")
2147 Diags.Report(diag::err_drv_argument_not_allowed_with)
2148 << A->getAsString(Args)
2149 << Args.getLastArg(OPT_mcmodel_EQ)->getAsString(Args);
2150 else
2151 Opts.FunctionReturnThunks = static_cast<unsigned>(Val);
2152 }
2153
2154 for (auto *A :
2155 Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {
2156 CodeGenOptions::BitcodeFileToLink F;
2157 F.Filename = A->getValue();
2158 if (A->getOption().matches(OPT_mlink_builtin_bitcode)) {
2159 F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;
2160 // When linking CUDA bitcode, propagate function attributes so that
2161 // e.g. libdevice gets fast-math attrs if we're building with fast-math.
2162 F.PropagateAttrs = true;
2163 F.Internalize = true;
2164 }
2165 Opts.LinkBitcodeFiles.push_back(F);
2166 }
2167
2168 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
2169 StringRef Val = A->getValue();
2170 Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);
2171 Opts.FP32DenormalMode = Opts.FPDenormalMode;
2172 if (!Opts.FPDenormalMode.isValid())
2173 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2174 }
2175
2176 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_f32_EQ)) {
2177 StringRef Val = A->getValue();
2178 Opts.FP32DenormalMode = llvm::parseDenormalFPAttribute(Val);
2179 if (!Opts.FP32DenormalMode.isValid())
2180 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2181 }
2182
2183 // X86_32 has -fppc-struct-return and -freg-struct-return.
2184 // PPC32 has -maix-struct-return and -msvr4-struct-return.
2185 if (Arg *A =
2186 Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return,
2187 OPT_maix_struct_return, OPT_msvr4_struct_return)) {
2188 // TODO: We might want to consider enabling these options on AIX in the
2189 // future.
2190 if (T.isOSAIX())
2191 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2192 << A->getSpelling() << T.str();
2193
2194 const Option &O = A->getOption();
2195 if (O.matches(OPT_fpcc_struct_return) ||
2196 O.matches(OPT_maix_struct_return)) {
2197 Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack);
2198 } else {
2199 assert(O.matches(OPT_freg_struct_return) ||
2200 O.matches(OPT_msvr4_struct_return));
2201 Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs);
2202 }
2203 }
2204
2205 if (Arg *A = Args.getLastArg(OPT_mxcoff_roptr)) {
2206 if (!T.isOSAIX())
2207 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2208 << A->getSpelling() << T.str();
2209
2210 // Since the storage mapping class is specified per csect,
2211 // without using data sections, it is less effective to use read-only
2212 // pointers. Using read-only pointers may cause other RO variables in the
2213 // same csect to become RW when the linker acts upon `-bforceimprw`;
2214 // therefore, we require that separate data sections
2215 // are used when `-mxcoff-roptr` is in effect. We respect the setting of
2216 // data-sections since we have not found reasons to do otherwise that
2217 // overcome the user surprise of not respecting the setting.
2218 if (!Args.hasFlag(OPT_fdata_sections, OPT_fno_data_sections, false))
2219 Diags.Report(diag::err_roptr_requires_data_sections);
2220
2221 Opts.XCOFFReadOnlyPointers = true;
2222 }
2223
2224 if (Arg *A = Args.getLastArg(OPT_mabi_EQ_quadword_atomics)) {
2225 if (!T.isOSAIX() || T.isPPC32())
2226 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2227 << A->getSpelling() << T.str();
2228 }
2229
2230 bool NeedLocTracking = false;
2231
2232 if (!Opts.OptRecordFile.empty())
2233 NeedLocTracking = true;
2234
2235 if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {
2236 Opts.OptRecordPasses = A->getValue();
2237 NeedLocTracking = true;
2238 }
2239
2240 if (Arg *A = Args.getLastArg(OPT_opt_record_format)) {
2241 Opts.OptRecordFormat = A->getValue();
2242 NeedLocTracking = true;
2243 }
2244
2245 Opts.OptimizationRemark =
2246 ParseOptimizationRemark(Diags, Args, OPT_Rpass_EQ, "pass");
2247
2249 ParseOptimizationRemark(Diags, Args, OPT_Rpass_missed_EQ, "pass-missed");
2250
2252 Diags, Args, OPT_Rpass_analysis_EQ, "pass-analysis");
2253
2254 NeedLocTracking |= Opts.OptimizationRemark.hasValidPattern() ||
2257
2258 bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
2259 bool UsingProfile =
2260 UsingSampleProfile || !Opts.ProfileInstrumentUsePath.empty();
2261
2262 if (Opts.DiagnosticsWithHotness && !UsingProfile &&
2263 // An IR file will contain PGO as metadata
2265 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2266 << "-fdiagnostics-show-hotness";
2267
2268 // Parse remarks hotness threshold. Valid value is either integer or 'auto'.
2269 if (auto *arg =
2270 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
2271 auto ResultOrErr =
2272 llvm::remarks::parseHotnessThresholdOption(arg->getValue());
2273
2274 if (!ResultOrErr) {
2275 Diags.Report(diag::err_drv_invalid_diagnotics_hotness_threshold)
2276 << "-fdiagnostics-hotness-threshold=";
2277 } else {
2278 Opts.DiagnosticsHotnessThreshold = *ResultOrErr;
2279 if ((!Opts.DiagnosticsHotnessThreshold ||
2280 *Opts.DiagnosticsHotnessThreshold > 0) &&
2281 !UsingProfile)
2282 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2283 << "-fdiagnostics-hotness-threshold=";
2284 }
2285 }
2286
2287 if (auto *arg =
2288 Args.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ)) {
2289 auto ResultOrErr = parseToleranceOption(arg->getValue());
2290
2291 if (!ResultOrErr) {
2292 Diags.Report(diag::err_drv_invalid_diagnotics_misexpect_tolerance)
2293 << "-fdiagnostics-misexpect-tolerance=";
2294 } else {
2295 Opts.DiagnosticsMisExpectTolerance = *ResultOrErr;
2296 if ((!Opts.DiagnosticsMisExpectTolerance ||
2297 *Opts.DiagnosticsMisExpectTolerance > 0) &&
2298 !UsingProfile)
2299 Diags.Report(diag::warn_drv_diagnostics_misexpect_requires_pgo)
2300 << "-fdiagnostics-misexpect-tolerance=";
2301 }
2302 }
2303
2304 // If the user requested to use a sample profile for PGO, then the
2305 // backend will need to track source location information so the profile
2306 // can be incorporated into the IR.
2307 if (UsingSampleProfile)
2308 NeedLocTracking = true;
2309
2310 if (!Opts.StackUsageOutput.empty())
2311 NeedLocTracking = true;
2312
2313 // If the user requested a flag that requires source locations available in
2314 // the backend, make sure that the backend tracks source location information.
2315 if (NeedLocTracking &&
2316 Opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo)
2317 Opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
2318
2319 // Parse -fsanitize-recover= arguments.
2320 // FIXME: Report unrecoverable sanitizers incorrectly specified here.
2321 parseSanitizerKinds("-fsanitize-recover=",
2322 Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,
2323 Opts.SanitizeRecover);
2324 parseSanitizerKinds("-fsanitize-trap=",
2325 Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
2326 Opts.SanitizeTrap);
2327 parseSanitizerKinds("-fsanitize-merge=",
2328 Args.getAllArgValues(OPT_fsanitize_merge_handlers_EQ),
2329 Diags, Opts.SanitizeMergeHandlers);
2330
2331 // Parse -fsanitize-skip-hot-cutoff= arguments.
2333 "-fsanitize-skip-hot-cutoff=",
2334 Args.getAllArgValues(OPT_fsanitize_skip_hot_cutoff_EQ), Diags);
2335
2337 "-fsanitize-annotate-debug-info=",
2338 Args.getAllArgValues(OPT_fsanitize_annotate_debug_info_EQ), Diags,
2340
2341 if (StringRef V =
2342 Args.getLastArgValue(OPT_fallow_runtime_check_skip_hot_cutoff_EQ);
2343 !V.empty()) {
2344 double A;
2345 if (V.getAsDouble(A) || A < 0.0 || A > 1.0) {
2346 Diags.Report(diag::err_drv_invalid_value)
2347 << "-fallow-runtime-check-skip-hot-cutoff=" << V;
2348 } else {
2350 }
2351 }
2352
2353 if (const auto *Arg = Args.getLastArg(options::OPT_falloc_token_max_EQ)) {
2354 StringRef S = Arg->getValue();
2355 uint64_t Value = 0;
2356 if (S.getAsInteger(0, Value))
2357 Diags.Report(diag::err_drv_invalid_value) << Arg->getAsString(Args) << S;
2358 else
2359 Opts.AllocTokenMax = Value;
2360 }
2361
2362 Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
2363
2364 if (!LangOpts->CUDAIsDevice)
2366
2367 if (Args.hasArg(options::OPT_ffinite_loops))
2368 Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Always;
2369 else if (Args.hasArg(options::OPT_fno_finite_loops))
2370 Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Never;
2371
2372 Opts.EmitIEEENaNCompliantInsts = Args.hasFlag(
2373 options::OPT_mamdgpu_ieee, options::OPT_mno_amdgpu_ieee, true);
2374 if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs)
2375 Diags.Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans);
2376
2377 Opts.StaticClosure = Args.hasArg(options::OPT_static_libclosure);
2378
2379 return Diags.getNumErrors() == NumErrorsBefore;
2380}
2381
2383 ArgumentConsumer Consumer) {
2384 const DependencyOutputOptions &DependencyOutputOpts = Opts;
2385#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2386 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2387#include "clang/Driver/Options.inc"
2388#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2389
2391 GenerateArg(Consumer, OPT_show_includes);
2392
2393 for (const auto &Dep : Opts.ExtraDeps) {
2394 switch (Dep.second) {
2396 // Sanitizer ignorelist arguments are generated from LanguageOptions.
2397 continue;
2398 case EDK_ModuleFile:
2399 // Module file arguments are generated from FrontendOptions and
2400 // HeaderSearchOptions.
2401 continue;
2402 case EDK_ProfileList:
2403 // Profile list arguments are generated from LanguageOptions via the
2404 // marshalling infrastructure.
2405 continue;
2406 case EDK_DepFileEntry:
2407 GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first);
2408 break;
2409 }
2410 }
2411}
2412
2414 ArgList &Args, DiagnosticsEngine &Diags,
2416 bool ShowLineMarkers) {
2417 unsigned NumErrorsBefore = Diags.getNumErrors();
2418
2419 DependencyOutputOptions &DependencyOutputOpts = Opts;
2420#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2421 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2422#include "clang/Driver/Options.inc"
2423#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2424
2425 if (Args.hasArg(OPT_show_includes)) {
2426 // Writing both /showIncludes and preprocessor output to stdout
2427 // would produce interleaved output, so use stderr for /showIncludes.
2428 // This behaves the same as cl.exe, when /E, /EP or /P are passed.
2429 if (Action == frontend::PrintPreprocessedInput || !ShowLineMarkers)
2431 else
2433 } else {
2435 }
2436
2437 // Add sanitizer ignorelists as extra dependencies.
2438 // They won't be discovered by the regular preprocessor, so
2439 // we let make / ninja to know about this implicit dependency.
2440 if (!Args.hasArg(OPT_fno_sanitize_ignorelist)) {
2441 for (const auto *A : Args.filtered(OPT_fsanitize_ignorelist_EQ)) {
2442 StringRef Val = A->getValue();
2443 if (!Val.contains('='))
2444 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_SanitizeIgnorelist);
2445 }
2446 if (Opts.IncludeSystemHeaders) {
2447 for (const auto *A : Args.filtered(OPT_fsanitize_system_ignorelist_EQ)) {
2448 StringRef Val = A->getValue();
2449 if (!Val.contains('='))
2450 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_SanitizeIgnorelist);
2451 }
2452 }
2453 }
2454
2455 // -fprofile-list= dependencies.
2456 for (const auto &Filename : Args.getAllArgValues(OPT_fprofile_list_EQ))
2457 Opts.ExtraDeps.emplace_back(Filename, EDK_ProfileList);
2458
2459 // Propagate the extra dependencies.
2460 for (const auto *A : Args.filtered(OPT_fdepfile_entry))
2461 Opts.ExtraDeps.emplace_back(A->getValue(), EDK_DepFileEntry);
2462
2463 // Only the -fmodule-file=<file> form.
2464 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
2465 StringRef Val = A->getValue();
2466 if (!Val.contains('='))
2467 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_ModuleFile);
2468 }
2469
2470 // Check for invalid combinations of header-include-format
2471 // and header-include-filtering.
2472 if (Opts.HeaderIncludeFormat == HIFMT_Textual &&
2474 if (Args.hasArg(OPT_header_include_format_EQ))
2475 Diags.Report(diag::err_drv_print_header_cc1_invalid_combination)
2478 else
2479 Diags.Report(diag::err_drv_print_header_cc1_invalid_filtering)
2481 } else if (Opts.HeaderIncludeFormat == HIFMT_JSON &&
2483 if (Args.hasArg(OPT_header_include_filtering_EQ))
2484 Diags.Report(diag::err_drv_print_header_cc1_invalid_combination)
2487 else
2488 Diags.Report(diag::err_drv_print_header_cc1_invalid_format)
2490 }
2491
2492 return Diags.getNumErrors() == NumErrorsBefore;
2493}
2494
2495static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) {
2496 // Color diagnostics default to auto ("on" if terminal supports) in the driver
2497 // but default to off in cc1, needing an explicit OPT_fdiagnostics_color.
2498 // Support both clang's -f[no-]color-diagnostics and gcc's
2499 // -f[no-]diagnostics-colors[=never|always|auto].
2500 enum {
2501 Colors_On,
2502 Colors_Off,
2503 Colors_Auto
2504 } ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
2505 for (auto *A : Args) {
2506 const Option &O = A->getOption();
2507 if (O.matches(options::OPT_fcolor_diagnostics)) {
2508 ShowColors = Colors_On;
2509 } else if (O.matches(options::OPT_fno_color_diagnostics)) {
2510 ShowColors = Colors_Off;
2511 } else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
2512 StringRef Value(A->getValue());
2513 if (Value == "always")
2514 ShowColors = Colors_On;
2515 else if (Value == "never")
2516 ShowColors = Colors_Off;
2517 else if (Value == "auto")
2518 ShowColors = Colors_Auto;
2519 }
2520 }
2521 return ShowColors == Colors_On ||
2522 (ShowColors == Colors_Auto &&
2523 llvm::sys::Process::StandardErrHasColors());
2524}
2525
2526static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
2527 DiagnosticsEngine &Diags) {
2528 bool Success = true;
2529 for (const auto &Prefix : VerifyPrefixes) {
2530 // Every prefix must start with a letter and contain only alphanumeric
2531 // characters, hyphens, and underscores.
2532 auto BadChar = llvm::find_if(Prefix, [](char C) {
2533 return !isAlphanumeric(C) && C != '-' && C != '_';
2534 });
2535 if (BadChar != Prefix.end() || !isLetter(Prefix[0])) {
2536 Success = false;
2537 Diags.Report(diag::err_drv_invalid_value) << "-verify=" << Prefix;
2538 Diags.Report(diag::note_drv_verify_prefix_spelling);
2539 }
2540 }
2541 return Success;
2542}
2543
2545 ArgumentConsumer Consumer) {
2546 const FileSystemOptions &FileSystemOpts = Opts;
2547
2548#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2549 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2550#include "clang/Driver/Options.inc"
2551#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2552}
2553
2554static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args,
2555 DiagnosticsEngine &Diags) {
2556 unsigned NumErrorsBefore = Diags.getNumErrors();
2557
2558 FileSystemOptions &FileSystemOpts = Opts;
2559
2560#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2561 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2562#include "clang/Driver/Options.inc"
2563#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2564
2565 return Diags.getNumErrors() == NumErrorsBefore;
2566}
2567
2569 ArgumentConsumer Consumer) {
2570 const MigratorOptions &MigratorOpts = Opts;
2571#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2572 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2573#include "clang/Driver/Options.inc"
2574#undef MIGRATOR_OPTION_WITH_MARSHALLING
2575}
2576
2577static bool ParseMigratorArgs(MigratorOptions &Opts, const ArgList &Args,
2578 DiagnosticsEngine &Diags) {
2579 unsigned NumErrorsBefore = Diags.getNumErrors();
2580
2581 MigratorOptions &MigratorOpts = Opts;
2582
2583#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2584 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2585#include "clang/Driver/Options.inc"
2586#undef MIGRATOR_OPTION_WITH_MARSHALLING
2587
2588 return Diags.getNumErrors() == NumErrorsBefore;
2589}
2590
2591void CompilerInvocationBase::GenerateDiagnosticArgs(
2592 const DiagnosticOptions &Opts, ArgumentConsumer Consumer,
2593 bool DefaultDiagColor) {
2594 const DiagnosticOptions *DiagnosticOpts = &Opts;
2595#define DIAG_OPTION_WITH_MARSHALLING(...) \
2596 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2597#include "clang/Driver/Options.inc"
2598#undef DIAG_OPTION_WITH_MARSHALLING
2599
2600 if (!Opts.DiagnosticSerializationFile.empty())
2601 GenerateArg(Consumer, OPT_diagnostic_serialized_file,
2603
2604 if (Opts.ShowColors)
2605 GenerateArg(Consumer, OPT_fcolor_diagnostics);
2606
2607 if (Opts.VerifyDiagnostics &&
2608 llvm::is_contained(Opts.VerifyPrefixes, "expected"))
2609 GenerateArg(Consumer, OPT_verify);
2610
2611 for (const auto &Prefix : Opts.VerifyPrefixes)
2612 if (Prefix != "expected")
2613 GenerateArg(Consumer, OPT_verify_EQ, Prefix);
2614
2615 DiagnosticLevelMask VIU = Opts.getVerifyIgnoreUnexpected();
2616 if (VIU == DiagnosticLevelMask::None) {
2617 // This is the default, don't generate anything.
2618 } else if (VIU == DiagnosticLevelMask::All) {
2619 GenerateArg(Consumer, OPT_verify_ignore_unexpected);
2620 } else {
2621 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Note) != 0)
2622 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "note");
2623 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Remark) != 0)
2624 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "remark");
2625 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Warning) != 0)
2626 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "warning");
2627 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Error) != 0)
2628 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "error");
2629 }
2630
2631 for (const auto &Warning : Opts.Warnings) {
2632 // This option is automatically generated from UndefPrefixes.
2633 if (Warning == "undef-prefix")
2634 continue;
2635 // This option is automatically generated from CheckConstexprFunctionBodies.
2636 if (Warning == "invalid-constexpr" || Warning == "no-invalid-constexpr")
2637 continue;
2638 Consumer(StringRef("-W") + Warning);
2639 }
2640
2641 for (const auto &Remark : Opts.Remarks) {
2642 // These arguments are generated from OptimizationRemark fields of
2643 // CodeGenOptions.
2644 StringRef IgnoredRemarks[] = {"pass", "no-pass",
2645 "pass-analysis", "no-pass-analysis",
2646 "pass-missed", "no-pass-missed"};
2647 if (llvm::is_contained(IgnoredRemarks, Remark))
2648 continue;
2649
2650 Consumer(StringRef("-R") + Remark);
2651 }
2652
2653 if (!Opts.DiagnosticSuppressionMappingsFile.empty()) {
2654 GenerateArg(Consumer, OPT_warning_suppression_mappings_EQ,
2656 }
2657}
2658
2659std::unique_ptr<DiagnosticOptions>
2661 auto DiagOpts = std::make_unique<DiagnosticOptions>();
2662 unsigned MissingArgIndex, MissingArgCount;
2663 InputArgList Args = getDriverOptTable().ParseArgs(
2664 Argv.slice(1), MissingArgIndex, MissingArgCount);
2665
2666 bool ShowColors = true;
2667 if (std::optional<std::string> NoColor =
2668 llvm::sys::Process::GetEnv("NO_COLOR");
2669 NoColor && !NoColor->empty()) {
2670 // If the user set the NO_COLOR environment variable, we'll honor that
2671 // unless the command line overrides it.
2672 ShowColors = false;
2673 }
2674
2675 // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
2676 // Any errors that would be diagnosed here will also be diagnosed later,
2677 // when the DiagnosticsEngine actually exists.
2678 (void)ParseDiagnosticArgs(*DiagOpts, Args, /*Diags=*/nullptr, ShowColors);
2679 return DiagOpts;
2680}
2681
2682bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
2683 DiagnosticsEngine *Diags,
2684 bool DefaultDiagColor) {
2685 std::optional<DiagnosticOptions> IgnoringDiagOpts;
2686 std::optional<DiagnosticsEngine> IgnoringDiags;
2687 if (!Diags) {
2688 IgnoringDiagOpts.emplace();
2689 IgnoringDiags.emplace(DiagnosticIDs::create(), *IgnoringDiagOpts,
2690 new IgnoringDiagConsumer());
2691 Diags = &*IgnoringDiags;
2692 }
2693
2694 unsigned NumErrorsBefore = Diags->getNumErrors();
2695
2696 // The key paths of diagnostic options defined in Options.td start with
2697 // "DiagnosticOpts->". Let's provide the expected variable name and type.
2698 DiagnosticOptions *DiagnosticOpts = &Opts;
2699
2700#define DIAG_OPTION_WITH_MARSHALLING(...) \
2701 PARSE_OPTION_WITH_MARSHALLING(Args, *Diags, __VA_ARGS__)
2702#include "clang/Driver/Options.inc"
2703#undef DIAG_OPTION_WITH_MARSHALLING
2704
2705 llvm::sys::Process::UseANSIEscapeCodes(Opts.UseANSIEscapeCodes);
2706
2707 if (Arg *A =
2708 Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))
2709 Opts.DiagnosticSerializationFile = A->getValue();
2710 Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor);
2711
2712 Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ);
2713 Opts.VerifyPrefixes = Args.getAllArgValues(OPT_verify_EQ);
2714 if (Args.hasArg(OPT_verify))
2715 Opts.VerifyPrefixes.push_back("expected");
2716 // Keep VerifyPrefixes in its original order for the sake of diagnostics, and
2717 // then sort it to prepare for fast lookup using std::binary_search.
2718 if (!checkVerifyPrefixes(Opts.VerifyPrefixes, *Diags))
2719 Opts.VerifyDiagnostics = false;
2720 else
2721 llvm::sort(Opts.VerifyPrefixes);
2724 "-verify-ignore-unexpected=",
2725 Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), *Diags, DiagMask);
2726 if (Args.hasArg(OPT_verify_ignore_unexpected))
2727 DiagMask = DiagnosticLevelMask::All;
2728 Opts.setVerifyIgnoreUnexpected(DiagMask);
2729 if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
2730 Diags->Report(diag::warn_ignoring_ftabstop_value)
2731 << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
2732 Opts.TabStop = DiagnosticOptions::DefaultTabStop;
2733 }
2734
2735 if (const Arg *A = Args.getLastArg(OPT_warning_suppression_mappings_EQ))
2736 Opts.DiagnosticSuppressionMappingsFile = A->getValue();
2737
2738 addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
2739 addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
2740
2741 return Diags->getNumErrors() == NumErrorsBefore;
2742}
2743
2744/// Parse the argument to the -ftest-module-file-extension
2745/// command-line argument.
2746///
2747/// \returns true on error, false on success.
2748static bool parseTestModuleFileExtensionArg(StringRef Arg,
2749 std::string &BlockName,
2750 unsigned &MajorVersion,
2751 unsigned &MinorVersion,
2752 bool &Hashed,
2753 std::string &UserInfo) {
2755 Arg.split(Args, ':', 5);
2756 if (Args.size() < 5)
2757 return true;
2758
2759 BlockName = std::string(Args[0]);
2760 if (Args[1].getAsInteger(10, MajorVersion)) return true;
2761 if (Args[2].getAsInteger(10, MinorVersion)) return true;
2762 if (Args[3].getAsInteger(2, Hashed)) return true;
2763 if (Args.size() > 4)
2764 UserInfo = std::string(Args[4]);
2765 return false;
2766}
2767
2768/// Return a table that associates command line option specifiers with the
2769/// frontend action. Note: The pair {frontend::PluginAction, OPT_plugin} is
2770/// intentionally missing, as this case is handled separately from other
2771/// frontend options.
2772static const auto &getFrontendActionTable() {
2773 static const std::pair<frontend::ActionKind, unsigned> Table[] = {
2774 {frontend::ASTDeclList, OPT_ast_list},
2775
2776 {frontend::ASTDump, OPT_ast_dump_all_EQ},
2777 {frontend::ASTDump, OPT_ast_dump_all},
2778 {frontend::ASTDump, OPT_ast_dump_EQ},
2779 {frontend::ASTDump, OPT_ast_dump},
2780 {frontend::ASTDump, OPT_ast_dump_lookups},
2781 {frontend::ASTDump, OPT_ast_dump_decl_types},
2782
2783 {frontend::ASTPrint, OPT_ast_print},
2784 {frontend::ASTView, OPT_ast_view},
2785 {frontend::DumpCompilerOptions, OPT_compiler_options_dump},
2786 {frontend::DumpRawTokens, OPT_dump_raw_tokens},
2787 {frontend::DumpTokens, OPT_dump_tokens},
2788 {frontend::EmitAssembly, OPT_S},
2789 {frontend::EmitBC, OPT_emit_llvm_bc},
2790 {frontend::EmitCIR, OPT_emit_cir},
2791 {frontend::EmitHTML, OPT_emit_html},
2792 {frontend::EmitLLVM, OPT_emit_llvm},
2793 {frontend::EmitLLVMOnly, OPT_emit_llvm_only},
2794 {frontend::EmitCodeGenOnly, OPT_emit_codegen_only},
2795 {frontend::EmitObj, OPT_emit_obj},
2796 {frontend::ExtractAPI, OPT_extract_api},
2797
2798 {frontend::FixIt, OPT_fixit_EQ},
2799 {frontend::FixIt, OPT_fixit},
2800
2801 {frontend::GenerateModule, OPT_emit_module},
2802 {frontend::GenerateModuleInterface, OPT_emit_module_interface},
2804 OPT_emit_reduced_module_interface},
2805 {frontend::GenerateHeaderUnit, OPT_emit_header_unit},
2806 {frontend::GeneratePCH, OPT_emit_pch},
2807 {frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs},
2808 {frontend::InitOnly, OPT_init_only},
2809 {frontend::ParseSyntaxOnly, OPT_fsyntax_only},
2810 {frontend::ModuleFileInfo, OPT_module_file_info},
2811 {frontend::VerifyPCH, OPT_verify_pch},
2812 {frontend::PrintPreamble, OPT_print_preamble},
2814 {frontend::TemplightDump, OPT_templight_dump},
2815 {frontend::RewriteMacros, OPT_rewrite_macros},
2816 {frontend::RewriteObjC, OPT_rewrite_objc},
2817 {frontend::RewriteTest, OPT_rewrite_test},
2818 {frontend::RunAnalysis, OPT_analyze},
2819 {frontend::RunPreprocessorOnly, OPT_Eonly},
2821 OPT_print_dependency_directives_minimized_source},
2822 };
2823
2824 return Table;
2825}
2826
2827/// Maps command line option to frontend action.
2828static std::optional<frontend::ActionKind>
2829getFrontendAction(OptSpecifier &Opt) {
2830 for (const auto &ActionOpt : getFrontendActionTable())
2831 if (ActionOpt.second == Opt.getID())
2832 return ActionOpt.first;
2833
2834 return std::nullopt;
2835}
2836
2837/// Maps frontend action to command line option.
2838static std::optional<OptSpecifier>
2840 for (const auto &ActionOpt : getFrontendActionTable())
2841 if (ActionOpt.first == ProgramAction)
2842 return OptSpecifier(ActionOpt.second);
2843
2844 return std::nullopt;
2845}
2846
2848 ArgumentConsumer Consumer, bool IsHeader) {
2849 const FrontendOptions &FrontendOpts = Opts;
2850#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2851 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2852#include "clang/Driver/Options.inc"
2853#undef FRONTEND_OPTION_WITH_MARSHALLING
2854
2855 std::optional<OptSpecifier> ProgramActionOpt =
2857
2858 // Generating a simple flag covers most frontend actions.
2859 std::function<void()> GenerateProgramAction = [&]() {
2860 GenerateArg(Consumer, *ProgramActionOpt);
2861 };
2862
2863 if (!ProgramActionOpt) {
2864 // PluginAction is the only program action handled separately.
2865 assert(Opts.ProgramAction == frontend::PluginAction &&
2866 "Frontend action without option.");
2867 GenerateProgramAction = [&]() {
2868 GenerateArg(Consumer, OPT_plugin, Opts.ActionName);
2869 };
2870 }
2871
2872 // FIXME: Simplify the complex 'AST dump' command line.
2873 if (Opts.ProgramAction == frontend::ASTDump) {
2874 GenerateProgramAction = [&]() {
2875 // ASTDumpLookups, ASTDumpDeclTypes and ASTDumpFilter are generated via
2876 // marshalling infrastructure.
2877
2878 if (Opts.ASTDumpFormat != ADOF_Default) {
2879 StringRef Format;
2880 switch (Opts.ASTDumpFormat) {
2881 case ADOF_Default:
2882 llvm_unreachable("Default AST dump format.");
2883 case ADOF_JSON:
2884 Format = "json";
2885 break;
2886 }
2887
2888 if (Opts.ASTDumpAll)
2889 GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);
2890 if (Opts.ASTDumpDecls)
2891 GenerateArg(Consumer, OPT_ast_dump_EQ, Format);
2892 } else {
2893 if (Opts.ASTDumpAll)
2894 GenerateArg(Consumer, OPT_ast_dump_all);
2895 if (Opts.ASTDumpDecls)
2896 GenerateArg(Consumer, OPT_ast_dump);
2897 }
2898 };
2899 }
2900
2901 if (Opts.ProgramAction == frontend::FixIt && !Opts.FixItSuffix.empty()) {
2902 GenerateProgramAction = [&]() {
2903 GenerateArg(Consumer, OPT_fixit_EQ, Opts.FixItSuffix);
2904 };
2905 }
2906
2907 GenerateProgramAction();
2908
2909 for (const auto &PluginArgs : Opts.PluginArgs) {
2910 Option Opt = getDriverOptTable().getOption(OPT_plugin_arg);
2911 for (const auto &PluginArg : PluginArgs.second)
2912 denormalizeString(Consumer,
2913 Opt.getPrefix() + Opt.getName() + PluginArgs.first,
2914 Opt.getKind(), 0, PluginArg);
2915 }
2916
2917 for (const auto &Ext : Opts.ModuleFileExtensions)
2918 if (auto *TestExt = dyn_cast_or_null<TestModuleFileExtension>(Ext.get()))
2919 GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());
2920
2921 if (!Opts.CodeCompletionAt.FileName.empty())
2922 GenerateArg(Consumer, OPT_code_completion_at,
2923 Opts.CodeCompletionAt.ToString());
2924
2925 for (const auto &Plugin : Opts.Plugins)
2926 GenerateArg(Consumer, OPT_load, Plugin);
2927
2928 // ASTDumpDecls and ASTDumpAll already handled with ProgramAction.
2929
2930 for (const auto &ModuleFile : Opts.ModuleFiles)
2931 GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);
2932
2933 if (Opts.AuxTargetCPU)
2934 GenerateArg(Consumer, OPT_aux_target_cpu, *Opts.AuxTargetCPU);
2935
2936 if (Opts.AuxTargetFeatures)
2937 for (const auto &Feature : *Opts.AuxTargetFeatures)
2938 GenerateArg(Consumer, OPT_aux_target_feature, Feature);
2939
2940 {
2941 StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";
2942 StringRef ModuleMap =
2943 Opts.DashX.getFormat() == InputKind::ModuleMap ? "-module-map" : "";
2944 StringRef HeaderUnit = "";
2945 switch (Opts.DashX.getHeaderUnitKind()) {
2947 break;
2949 HeaderUnit = "-user";
2950 break;
2952 HeaderUnit = "-system";
2953 break;
2955 HeaderUnit = "-header-unit";
2956 break;
2957 }
2958 StringRef Header = IsHeader ? "-header" : "";
2959
2960 StringRef Lang;
2961 switch (Opts.DashX.getLanguage()) {
2962 case Language::C:
2963 Lang = "c";
2964 break;
2965 case Language::OpenCL:
2966 Lang = "cl";
2967 break;
2969 Lang = "clcpp";
2970 break;
2971 case Language::CUDA:
2972 Lang = "cuda";
2973 break;
2974 case Language::HIP:
2975 Lang = "hip";
2976 break;
2977 case Language::CXX:
2978 Lang = "c++";
2979 break;
2980 case Language::ObjC:
2981 Lang = "objective-c";
2982 break;
2983 case Language::ObjCXX:
2984 Lang = "objective-c++";
2985 break;
2986 case Language::Asm:
2987 Lang = "assembler-with-cpp";
2988 break;
2989 case Language::Unknown:
2990 assert(Opts.DashX.getFormat() == InputKind::Precompiled &&
2991 "Generating -x argument for unknown language (not precompiled).");
2992 Lang = "ast";
2993 break;
2994 case Language::LLVM_IR:
2995 Lang = "ir";
2996 break;
2997 case Language::HLSL:
2998 Lang = "hlsl";
2999 break;
3000 case Language::CIR:
3001 Lang = "cir";
3002 break;
3003 }
3004
3005 GenerateArg(Consumer, OPT_x,
3006 Lang + HeaderUnit + Header + ModuleMap + Preprocessed);
3007 }
3008
3009 // OPT_INPUT has a unique class, generate it directly.
3010 for (const auto &Input : Opts.Inputs)
3011 Consumer(Input.getFile());
3012}
3013
3014static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
3015 DiagnosticsEngine &Diags, bool &IsHeaderFile) {
3016 unsigned NumErrorsBefore = Diags.getNumErrors();
3017
3018 FrontendOptions &FrontendOpts = Opts;
3019
3020#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
3021 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3022#include "clang/Driver/Options.inc"
3023#undef FRONTEND_OPTION_WITH_MARSHALLING
3024
3026 if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
3027 OptSpecifier Opt = OptSpecifier(A->getOption().getID());
3028 std::optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt);
3029 assert(ProgramAction && "Option specifier not in Action_Group.");
3030
3031 if (ProgramAction == frontend::ASTDump &&
3032 (Opt == OPT_ast_dump_all_EQ || Opt == OPT_ast_dump_EQ)) {
3033 unsigned Val = llvm::StringSwitch<unsigned>(A->getValue())
3034 .CaseLower("default", ADOF_Default)
3035 .CaseLower("json", ADOF_JSON)
3036 .Default(std::numeric_limits<unsigned>::max());
3037
3038 if (Val != std::numeric_limits<unsigned>::max())
3039 Opts.ASTDumpFormat = static_cast<ASTDumpOutputFormat>(Val);
3040 else {
3041 Diags.Report(diag::err_drv_invalid_value)
3042 << A->getAsString(Args) << A->getValue();
3044 }
3045 }
3046
3047 if (ProgramAction == frontend::FixIt && Opt == OPT_fixit_EQ)
3048 Opts.FixItSuffix = A->getValue();
3049
3050 if (ProgramAction == frontend::GenerateInterfaceStubs) {
3051 StringRef ArgStr =
3052 Args.hasArg(OPT_interface_stub_version_EQ)
3053 ? Args.getLastArgValue(OPT_interface_stub_version_EQ)
3054 : "ifs-v1";
3055 if (ArgStr == "experimental-yaml-elf-v1" ||
3056 ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-ifs-v2" ||
3057 ArgStr == "experimental-tapi-elf-v1") {
3058 std::string ErrorMessage =
3059 "Invalid interface stub format: " + ArgStr.str() +
3060 " is deprecated.";
3061 Diags.Report(diag::err_drv_invalid_value)
3062 << "Must specify a valid interface stub format type, ie: "
3063 "-interface-stub-version=ifs-v1"
3064 << ErrorMessage;
3065 ProgramAction = frontend::ParseSyntaxOnly;
3066 } else if (!ArgStr.starts_with("ifs-")) {
3067 std::string ErrorMessage =
3068 "Invalid interface stub format: " + ArgStr.str() + ".";
3069 Diags.Report(diag::err_drv_invalid_value)
3070 << "Must specify a valid interface stub format type, ie: "
3071 "-interface-stub-version=ifs-v1"
3072 << ErrorMessage;
3073 ProgramAction = frontend::ParseSyntaxOnly;
3074 }
3075 }
3076
3077 Opts.ProgramAction = *ProgramAction;
3078
3079 // Catch common mistakes when multiple actions are specified for cc1 (e.g.
3080 // -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to
3081 // support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name
3082 // X ACTION), we suppress the error when the two actions are separated by
3083 // -main-file-name.
3084 //
3085 // As an exception, accept composable -ast-dump*.
3086 if (!A->getSpelling().starts_with("-ast-dump")) {
3087 const Arg *SavedAction = nullptr;
3088 for (const Arg *AA :
3089 Args.filtered(OPT_Action_Group, OPT_main_file_name)) {
3090 if (AA->getOption().matches(OPT_main_file_name)) {
3091 SavedAction = nullptr;
3092 } else if (!SavedAction) {
3093 SavedAction = AA;
3094 } else {
3095 if (!A->getOption().matches(OPT_ast_dump_EQ))
3096 Diags.Report(diag::err_fe_invalid_multiple_actions)
3097 << SavedAction->getSpelling() << A->getSpelling();
3098 break;
3099 }
3100 }
3101 }
3102 }
3103
3104 if (const Arg* A = Args.getLastArg(OPT_plugin)) {
3105 Opts.Plugins.emplace_back(A->getValue(0));
3107 Opts.ActionName = A->getValue();
3108 }
3109 for (const auto *AA : Args.filtered(OPT_plugin_arg))
3110 Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
3111
3112 for (const std::string &Arg :
3113 Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
3114 std::string BlockName;
3115 unsigned MajorVersion;
3116 unsigned MinorVersion;
3117 bool Hashed;
3118 std::string UserInfo;
3119 if (parseTestModuleFileExtensionArg(Arg, BlockName, MajorVersion,
3120 MinorVersion, Hashed, UserInfo)) {
3121 Diags.Report(diag::err_test_module_file_extension_format) << Arg;
3122
3123 continue;
3124 }
3125
3126 // Add the testing module file extension.
3127 Opts.ModuleFileExtensions.push_back(
3128 std::make_shared<TestModuleFileExtension>(
3129 BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
3130 }
3131
3132 if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
3133 Opts.CodeCompletionAt =
3134 ParsedSourceLocation::FromString(A->getValue());
3135 if (Opts.CodeCompletionAt.FileName.empty()) {
3136 Diags.Report(diag::err_drv_invalid_value)
3137 << A->getAsString(Args) << A->getValue();
3138 Diags.Report(diag::note_command_line_code_loc_requirement);
3139 }
3140 }
3141
3142 Opts.Plugins = Args.getAllArgValues(OPT_load);
3143 Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);
3144 Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);
3145 // Only the -fmodule-file=<file> form.
3146 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3147 StringRef Val = A->getValue();
3148 if (!Val.contains('='))
3149 Opts.ModuleFiles.push_back(std::string(Val));
3150 }
3151
3153 Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"
3154 << "-emit-module";
3155 if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_cir))
3156 Opts.UseClangIRPipeline = true;
3157
3158#if CLANG_ENABLE_CIR
3159 if (Args.hasArg(OPT_clangir_disable_passes))
3160 Opts.ClangIRDisablePasses = true;
3161
3162 if (Args.hasArg(OPT_clangir_disable_verifier))
3163 Opts.ClangIRDisableCIRVerifier = true;
3164#endif // CLANG_ENABLE_CIR
3165
3166 if (Args.hasArg(OPT_aux_target_cpu))
3167 Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu));
3168 if (Args.hasArg(OPT_aux_target_feature))
3169 Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature);
3170
3172 if (const Arg *A = Args.getLastArg(OPT_x)) {
3173 StringRef XValue = A->getValue();
3174
3175 // Parse suffixes:
3176 // '<lang>(-[{header-unit,user,system}-]header|[-module-map][-cpp-output])'.
3177 // FIXME: Supporting '<lang>-header-cpp-output' would be useful.
3178 bool Preprocessed = XValue.consume_back("-cpp-output");
3179 bool ModuleMap = XValue.consume_back("-module-map");
3180 // Detect and consume the header indicator.
3181 bool IsHeader =
3182 XValue != "precompiled-header" && XValue.consume_back("-header");
3183
3184 // If we have c++-{user,system}-header, that indicates a header unit input
3185 // likewise, if the user put -fmodule-header together with a header with an
3186 // absolute path (header-unit-header).
3188 if (IsHeader || Preprocessed) {
3189 if (XValue.consume_back("-header-unit"))
3191 else if (XValue.consume_back("-system"))
3193 else if (XValue.consume_back("-user"))
3195 }
3196
3197 // The value set by this processing is an un-preprocessed source which is
3198 // not intended to be a module map or header unit.
3199 IsHeaderFile = IsHeader && !Preprocessed && !ModuleMap &&
3201
3202 // Principal languages.
3203 DashX = llvm::StringSwitch<InputKind>(XValue)
3204 .Case("c", Language::C)
3205 .Case("cl", Language::OpenCL)
3206 .Case("clcpp", Language::OpenCLCXX)
3207 .Case("cuda", Language::CUDA)
3208 .Case("hip", Language::HIP)
3209 .Case("c++", Language::CXX)
3210 .Case("objective-c", Language::ObjC)
3211 .Case("objective-c++", Language::ObjCXX)
3212 .Case("hlsl", Language::HLSL)
3213 .Default(Language::Unknown);
3214
3215 // "objc[++]-cpp-output" is an acceptable synonym for
3216 // "objective-c[++]-cpp-output".
3217 if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap &&
3219 DashX = llvm::StringSwitch<InputKind>(XValue)
3220 .Case("objc", Language::ObjC)
3221 .Case("objc++", Language::ObjCXX)
3222 .Default(Language::Unknown);
3223
3224 // Some special cases cannot be combined with suffixes.
3225 if (DashX.isUnknown() && !Preprocessed && !IsHeaderFile && !ModuleMap &&
3227 DashX = llvm::StringSwitch<InputKind>(XValue)
3228 .Case("cpp-output", InputKind(Language::C).getPreprocessed())
3229 .Case("assembler-with-cpp", Language::Asm)
3230 .Cases("ast", "pcm", "precompiled-header",
3232 .Case("ir", Language::LLVM_IR)
3233 .Case("cir", Language::CIR)
3234 .Default(Language::Unknown);
3235
3236 if (DashX.isUnknown())
3237 Diags.Report(diag::err_drv_invalid_value)
3238 << A->getAsString(Args) << A->getValue();
3239
3240 if (Preprocessed)
3241 DashX = DashX.getPreprocessed();
3242 // A regular header is considered mutually exclusive with a header unit.
3243 if (HUK != InputKind::HeaderUnit_None) {
3244 DashX = DashX.withHeaderUnit(HUK);
3245 IsHeaderFile = true;
3246 } else if (IsHeaderFile)
3247 DashX = DashX.getHeader();
3248 if (ModuleMap)
3249 DashX = DashX.withFormat(InputKind::ModuleMap);
3250 }
3251
3252 // '-' is the default input if none is given.
3253 std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
3254 Opts.Inputs.clear();
3255 if (Inputs.empty())
3256 Inputs.push_back("-");
3257
3259 Inputs.size() > 1)
3260 Diags.Report(diag::err_drv_header_unit_extra_inputs) << Inputs[1];
3261
3262 for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
3263 InputKind IK = DashX;
3264 if (IK.isUnknown()) {
3266 StringRef(Inputs[i]).rsplit('.').second);
3267 // FIXME: Warn on this?
3268 if (IK.isUnknown())
3269 IK = Language::C;
3270 // FIXME: Remove this hack.
3271 if (i == 0)
3272 DashX = IK;
3273 }
3274
3275 bool IsSystem = false;
3276
3277 // The -emit-module action implicitly takes a module map.
3279 IK.getFormat() == InputKind::Source) {
3281 IsSystem = Opts.IsSystemModule;
3282 }
3283
3284 Opts.Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem);
3285 }
3286
3287 Opts.DashX = DashX;
3288
3289 return Diags.getNumErrors() == NumErrorsBefore;
3290}
3291
3292std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
3293 void *MainAddr) {
3294 std::string ClangExecutable =
3295 llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
3296 return Driver::GetResourcesPath(ClangExecutable);
3297}
3298
3300 ArgumentConsumer Consumer) {
3301 const HeaderSearchOptions *HeaderSearchOpts = &Opts;
3302#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3303 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3304#include "clang/Driver/Options.inc"
3305#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3306
3307 if (Opts.UseLibcxx)
3308 GenerateArg(Consumer, OPT_stdlib_EQ, "libc++");
3309
3310 for (const auto &File : Opts.PrebuiltModuleFiles)
3311 GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second);
3312
3313 for (const auto &Path : Opts.PrebuiltModulePaths)
3314 GenerateArg(Consumer, OPT_fprebuilt_module_path, Path);
3315
3316 for (const auto &Macro : Opts.ModulesIgnoreMacros)
3317 GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val());
3318
3319 auto Matches = [](const HeaderSearchOptions::Entry &Entry,
3321 std::optional<bool> IsFramework,
3322 std::optional<bool> IgnoreSysRoot) {
3323 return llvm::is_contained(Groups, Entry.Group) &&
3324 (!IsFramework || (Entry.IsFramework == *IsFramework)) &&
3325 (!IgnoreSysRoot || (Entry.IgnoreSysRoot == *IgnoreSysRoot));
3326 };
3327
3328 auto It = Opts.UserEntries.begin();
3329 auto End = Opts.UserEntries.end();
3330
3331 // Add -I... and -F... options in order.
3332 for (; It < End && Matches(*It, {frontend::Angled}, std::nullopt, true);
3333 ++It) {
3334 OptSpecifier Opt = [It, Matches]() {
3335 if (Matches(*It, frontend::Angled, true, true))
3336 return OPT_F;
3337 if (Matches(*It, frontend::Angled, false, true))
3338 return OPT_I;
3339 llvm_unreachable("Unexpected HeaderSearchOptions::Entry.");
3340 }();
3341
3342 GenerateArg(Consumer, Opt, It->Path);
3343 }
3344
3345 // Note: some paths that came from "[-iprefix=xx] -iwithprefixbefore=yy" may
3346 // have already been generated as "-I[xx]yy". If that's the case, their
3347 // position on command line was such that this has no semantic impact on
3348 // include paths.
3349 for (; It < End &&
3350 Matches(*It, {frontend::After, frontend::Angled}, false, true);
3351 ++It) {
3352 OptSpecifier Opt =
3353 It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;
3354 GenerateArg(Consumer, Opt, It->Path);
3355 }
3356
3357 // Note: Some paths that came from "-idirafter=xxyy" may have already been
3358 // generated as "-iwithprefix=xxyy". If that's the case, their position on
3359 // command line was such that this has no semantic impact on include paths.
3360 for (; It < End && Matches(*It, {frontend::After}, false, true); ++It)
3361 GenerateArg(Consumer, OPT_idirafter, It->Path);
3362 for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It)
3363 GenerateArg(Consumer, OPT_iquote, It->Path);
3364 for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt);
3365 ++It)
3366 GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
3367 It->Path);
3368 for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
3369 GenerateArg(Consumer, OPT_iframework, It->Path);
3370 for (; It < End && Matches(*It, {frontend::System}, true, false); ++It)
3371 GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path);
3372
3373 // Add the paths for the various language specific isystem flags.
3374 for (; It < End && Matches(*It, {frontend::CSystem}, false, true); ++It)
3375 GenerateArg(Consumer, OPT_c_isystem, It->Path);
3376 for (; It < End && Matches(*It, {frontend::CXXSystem}, false, true); ++It)
3377 GenerateArg(Consumer, OPT_cxx_isystem, It->Path);
3378 for (; It < End && Matches(*It, {frontend::ObjCSystem}, false, true); ++It)
3379 GenerateArg(Consumer, OPT_objc_isystem, It->Path);
3380 for (; It < End && Matches(*It, {frontend::ObjCXXSystem}, false, true); ++It)
3381 GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);
3382
3383 // Add the internal paths from a driver that detects standard include paths.
3384 // Note: Some paths that came from "-internal-isystem" arguments may have
3385 // already been generated as "-isystem". If that's the case, their position on
3386 // command line was such that this has no semantic impact on include paths.
3387 for (; It < End &&
3388 Matches(*It, {frontend::System, frontend::ExternCSystem}, false, true);
3389 ++It) {
3390 OptSpecifier Opt = It->Group == frontend::System
3391 ? OPT_internal_isystem
3392 : OPT_internal_externc_isystem;
3393 GenerateArg(Consumer, Opt, It->Path);
3394 }
3395 for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
3396 GenerateArg(Consumer, OPT_internal_iframework, It->Path);
3397
3398 assert(It == End && "Unhandled HeaderSearchOption::Entry.");
3399
3400 // Add the path prefixes which are implicitly treated as being system headers.
3401 for (const auto &P : Opts.SystemHeaderPrefixes) {
3402 OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
3403 : OPT_no_system_header_prefix;
3404 GenerateArg(Consumer, Opt, P.Prefix);
3405 }
3406
3407 for (const std::string &F : Opts.VFSOverlayFiles)
3408 GenerateArg(Consumer, OPT_ivfsoverlay, F);
3409}
3410
3411static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
3412 DiagnosticsEngine &Diags) {
3413 unsigned NumErrorsBefore = Diags.getNumErrors();
3414
3415 HeaderSearchOptions *HeaderSearchOpts = &Opts;
3416
3417#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3418 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3419#include "clang/Driver/Options.inc"
3420#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3421
3422 if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
3423 Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
3424
3425 // Only the -fmodule-file=<name>=<file> form.
3426 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3427 StringRef Val = A->getValue();
3428 if (Val.contains('=')) {
3429 auto Split = Val.split('=');
3430 Opts.PrebuiltModuleFiles.insert_or_assign(
3431 std::string(Split.first), std::string(Split.second));
3432 }
3433 }
3434 for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
3435 Opts.AddPrebuiltModulePath(A->getValue());
3436
3437 for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
3438 StringRef MacroDef = A->getValue();
3439 Opts.ModulesIgnoreMacros.insert(
3440 llvm::CachedHashString(MacroDef.split('=').first));
3441 }
3442
3443 // Add -I... and -F... options in order.
3444 bool IsSysrootSpecified =
3445 Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
3446
3447 // Expand a leading `=` to the sysroot if one was passed (and it's not a
3448 // framework flag).
3449 auto PrefixHeaderPath = [IsSysrootSpecified,
3450 &Opts](const llvm::opt::Arg *A,
3451 bool IsFramework = false) -> std::string {
3452 assert(A->getNumValues() && "Unexpected empty search path flag!");
3453 if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') {
3454 SmallString<32> Buffer;
3455 llvm::sys::path::append(Buffer, Opts.Sysroot,
3456 llvm::StringRef(A->getValue()).substr(1));
3457 return std::string(Buffer);
3458 }
3459 return A->getValue();
3460 };
3461
3462 for (const auto *A : Args.filtered(OPT_I, OPT_F)) {
3463 bool IsFramework = A->getOption().matches(OPT_F);
3464 Opts.AddPath(PrefixHeaderPath(A, IsFramework), frontend::Angled,
3465 IsFramework, /*IgnoreSysroot=*/true);
3466 }
3467
3468 // Add -iprefix/-iwithprefix/-iwithprefixbefore options.
3469 StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
3470 for (const auto *A :
3471 Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
3472 if (A->getOption().matches(OPT_iprefix))
3473 Prefix = A->getValue();
3474 else if (A->getOption().matches(OPT_iwithprefix))
3475 Opts.AddPath(Prefix.str() + A->getValue(), frontend::After, false, true);
3476 else
3477 Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
3478 }
3479
3480 for (const auto *A : Args.filtered(OPT_idirafter))
3481 Opts.AddPath(PrefixHeaderPath(A), frontend::After, false, true);
3482 for (const auto *A : Args.filtered(OPT_iquote))
3483 Opts.AddPath(PrefixHeaderPath(A), frontend::Quoted, false, true);
3484
3485 for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) {
3486 if (A->getOption().matches(OPT_iwithsysroot)) {
3487 Opts.AddPath(A->getValue(), frontend::System, false,
3488 /*IgnoreSysRoot=*/false);
3489 continue;
3490 }
3491 Opts.AddPath(PrefixHeaderPath(A), frontend::System, false, true);
3492 }
3493 for (const auto *A : Args.filtered(OPT_iframework))
3494 Opts.AddPath(A->getValue(), frontend::System, true, true);
3495 for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
3496 Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
3497 /*IgnoreSysRoot=*/false);
3498
3499 // Add the paths for the various language specific isystem flags.
3500 for (const auto *A : Args.filtered(OPT_c_isystem))
3501 Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
3502 for (const auto *A : Args.filtered(OPT_cxx_isystem))
3503 Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
3504 for (const auto *A : Args.filtered(OPT_objc_isystem))
3505 Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
3506 for (const auto *A : Args.filtered(OPT_objcxx_isystem))
3507 Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
3508
3509 // Add the internal paths from a driver that detects standard include paths.
3510 for (const auto *A :
3511 Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
3513 if (A->getOption().matches(OPT_internal_externc_isystem))
3515 Opts.AddPath(A->getValue(), Group, false, true);
3516 }
3517 for (const auto *A : Args.filtered(OPT_internal_iframework))
3518 Opts.AddPath(A->getValue(), frontend::System, true, true);
3519
3520 // Add the path prefixes which are implicitly treated as being system headers.
3521 for (const auto *A :
3522 Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
3524 A->getValue(), A->getOption().matches(OPT_system_header_prefix));
3525
3526 for (const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))
3527 Opts.AddVFSOverlayFile(A->getValue());
3528
3529 return Diags.getNumErrors() == NumErrorsBefore;
3530}
3531
3533 ArgumentConsumer Consumer) {
3534 if (!Opts.SwiftVersion.empty())
3535 GenerateArg(Consumer, OPT_fapinotes_swift_version,
3536 Opts.SwiftVersion.getAsString());
3537
3538 for (const auto &Path : Opts.ModuleSearchPaths)
3539 GenerateArg(Consumer, OPT_iapinotes_modules, Path);
3540}
3541
3542static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
3543 DiagnosticsEngine &diags) {
3544 if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
3545 if (Opts.SwiftVersion.tryParse(A->getValue()))
3546 diags.Report(diag::err_drv_invalid_value)
3547 << A->getAsString(Args) << A->getValue();
3548 }
3549 for (const Arg *A : Args.filtered(OPT_iapinotes_modules))
3550 Opts.ModuleSearchPaths.push_back(A->getValue());
3551}
3552
3553static void GeneratePointerAuthArgs(const LangOptions &Opts,
3554 ArgumentConsumer Consumer) {
3555 if (Opts.PointerAuthIntrinsics)
3556 GenerateArg(Consumer, OPT_fptrauth_intrinsics);
3557 if (Opts.PointerAuthCalls)
3558 GenerateArg(Consumer, OPT_fptrauth_calls);
3559 if (Opts.PointerAuthReturns)
3560 GenerateArg(Consumer, OPT_fptrauth_returns);
3561 if (Opts.PointerAuthIndirectGotos)
3562 GenerateArg(Consumer, OPT_fptrauth_indirect_gotos);
3563 if (Opts.PointerAuthAuthTraps)
3564 GenerateArg(Consumer, OPT_fptrauth_auth_traps);
3565 if (Opts.PointerAuthVTPtrAddressDiscrimination)
3566 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
3567 if (Opts.PointerAuthVTPtrTypeDiscrimination)
3568 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
3569 if (Opts.PointerAuthTypeInfoVTPtrDiscrimination)
3570 GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination);
3571 if (Opts.PointerAuthFunctionTypeDiscrimination)
3572 GenerateArg(Consumer, OPT_fptrauth_function_pointer_type_discrimination);
3573 if (Opts.PointerAuthInitFini)
3574 GenerateArg(Consumer, OPT_fptrauth_init_fini);
3575 if (Opts.PointerAuthInitFiniAddressDiscrimination)
3576 GenerateArg(Consumer, OPT_fptrauth_init_fini_address_discrimination);
3577 if (Opts.PointerAuthELFGOT)
3578 GenerateArg(Consumer, OPT_fptrauth_elf_got);
3579 if (Opts.AArch64JumpTableHardening)
3580 GenerateArg(Consumer, OPT_faarch64_jump_table_hardening);
3581 if (Opts.PointerAuthObjcIsa)
3582 GenerateArg(Consumer, OPT_fptrauth_objc_isa);
3583 if (Opts.PointerAuthObjcInterfaceSel)
3584 GenerateArg(Consumer, OPT_fptrauth_objc_interface_sel);
3585 if (Opts.PointerAuthObjcClassROPointers)
3586 GenerateArg(Consumer, OPT_fptrauth_objc_class_ro);
3587 if (Opts.PointerAuthBlockDescriptorPointers)
3588 GenerateArg(Consumer, OPT_fptrauth_block_descriptor_pointers);
3589}
3590
3591static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
3592 DiagnosticsEngine &Diags) {
3593 Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
3594 Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
3595 Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
3596 Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
3597 Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
3598 Opts.PointerAuthVTPtrAddressDiscrimination =
3599 Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
3600 Opts.PointerAuthVTPtrTypeDiscrimination =
3601 Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
3602 Opts.PointerAuthTypeInfoVTPtrDiscrimination =
3603 Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination);
3604 Opts.PointerAuthFunctionTypeDiscrimination =
3605 Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination);
3606 Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
3607 Opts.PointerAuthInitFiniAddressDiscrimination =
3608 Args.hasArg(OPT_fptrauth_init_fini_address_discrimination);
3609 Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got);
3610 Opts.AArch64JumpTableHardening =
3611 Args.hasArg(OPT_faarch64_jump_table_hardening);
3612 Opts.PointerAuthBlockDescriptorPointers =
3613 Args.hasArg(OPT_fptrauth_block_descriptor_pointers);
3614 Opts.PointerAuthObjcIsa = Args.hasArg(OPT_fptrauth_objc_isa);
3615 Opts.PointerAuthObjcClassROPointers = Args.hasArg(OPT_fptrauth_objc_class_ro);
3616 Opts.PointerAuthObjcInterfaceSel =
3617 Args.hasArg(OPT_fptrauth_objc_interface_sel);
3618
3619 if (Opts.PointerAuthObjcInterfaceSel)
3620 Opts.PointerAuthObjcInterfaceSelKey =
3621 static_cast<unsigned>(PointerAuthSchema::ARM8_3Key::ASDB);
3622}
3623
3624/// Check if input file kind and language standard are compatible.
3626 const LangStandard &S) {
3627 switch (IK.getLanguage()) {
3628 case Language::Unknown:
3629 case Language::LLVM_IR:
3630 case Language::CIR:
3631 llvm_unreachable("should not parse language flags for this input");
3632
3633 case Language::C:
3634 case Language::ObjC:
3635 return S.getLanguage() == Language::C;
3636
3637 case Language::OpenCL:
3638 return S.getLanguage() == Language::OpenCL ||
3640
3642 return S.getLanguage() == Language::OpenCLCXX;
3643
3644 case Language::CXX:
3645 case Language::ObjCXX:
3646 return S.getLanguage() == Language::CXX;
3647
3648 case Language::CUDA:
3649 // FIXME: What -std= values should be permitted for CUDA compilations?
3650 return S.getLanguage() == Language::CUDA ||
3652
3653 case Language::HIP:
3654 return S.getLanguage() == Language::CXX || S.getLanguage() == Language::HIP;
3655
3656 case Language::Asm:
3657 // Accept (and ignore) all -std= values.
3658 // FIXME: The -std= value is not ignored; it affects the tokenization
3659 // and preprocessing rules if we're preprocessing this asm input.
3660 return true;
3661
3662 case Language::HLSL:
3663 return S.getLanguage() == Language::HLSL;
3664 }
3665
3666 llvm_unreachable("unexpected input language");
3667}
3668
3669/// Get language name for given input kind.
3670static StringRef GetInputKindName(InputKind IK) {
3671 switch (IK.getLanguage()) {
3672 case Language::C:
3673 return "C";
3674 case Language::ObjC:
3675 return "Objective-C";
3676 case Language::CXX:
3677 return "C++";
3678 case Language::ObjCXX:
3679 return "Objective-C++";
3680 case Language::OpenCL:
3681 return "OpenCL";
3683 return "C++ for OpenCL";
3684 case Language::CUDA:
3685 return "CUDA";
3686 case Language::HIP:
3687 return "HIP";
3688
3689 case Language::Asm:
3690 return "Asm";
3691 case Language::LLVM_IR:
3692 return "LLVM IR";
3693 case Language::CIR:
3694 return "Clang IR";
3695
3696 case Language::HLSL:
3697 return "HLSL";
3698
3699 case Language::Unknown:
3700 break;
3701 }
3702 llvm_unreachable("unknown input language");
3703}
3704
3705void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
3706 ArgumentConsumer Consumer,
3707 const llvm::Triple &T,
3708 InputKind IK) {
3709 if (IK.getFormat() == InputKind::Precompiled ||
3711 IK.getLanguage() == Language::CIR) {
3712 if (Opts.ObjCAutoRefCount)
3713 GenerateArg(Consumer, OPT_fobjc_arc);
3714 if (Opts.PICLevel != 0)
3715 GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));
3716 if (Opts.PIE)
3717 GenerateArg(Consumer, OPT_pic_is_pie);
3718 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3719 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3720
3721 return;
3722 }
3723
3724 OptSpecifier StdOpt;
3725 switch (Opts.LangStd) {
3726 case LangStandard::lang_opencl10:
3727 case LangStandard::lang_opencl11:
3728 case LangStandard::lang_opencl12:
3729 case LangStandard::lang_opencl20:
3730 case LangStandard::lang_opencl30:
3731 case LangStandard::lang_openclcpp10:
3732 case LangStandard::lang_openclcpp2021:
3733 StdOpt = OPT_cl_std_EQ;
3734 break;
3735 default:
3736 StdOpt = OPT_std_EQ;
3737 break;
3738 }
3739
3740 auto LangStandard = LangStandard::getLangStandardForKind(Opts.LangStd);
3741 GenerateArg(Consumer, StdOpt, LangStandard.getName());
3742
3743 if (Opts.IncludeDefaultHeader)
3744 GenerateArg(Consumer, OPT_finclude_default_header);
3745 if (Opts.DeclareOpenCLBuiltins)
3746 GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);
3747
3748 const LangOptions *LangOpts = &Opts;
3749
3750#define LANG_OPTION_WITH_MARSHALLING(...) \
3751 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3752#include "clang/Driver/Options.inc"
3753#undef LANG_OPTION_WITH_MARSHALLING
3754
3755 // The '-fcf-protection=' option is generated by CodeGenOpts generator.
3756
3757 if (Opts.ObjC) {
3758 GenerateArg(Consumer, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString());
3759
3760 if (Opts.GC == LangOptions::GCOnly)
3761 GenerateArg(Consumer, OPT_fobjc_gc_only);
3762 else if (Opts.GC == LangOptions::HybridGC)
3763 GenerateArg(Consumer, OPT_fobjc_gc);
3764 else if (Opts.ObjCAutoRefCount == 1)
3765 GenerateArg(Consumer, OPT_fobjc_arc);
3766
3767 if (Opts.ObjCWeakRuntime)
3768 GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);
3769
3770 if (Opts.ObjCWeak)
3771 GenerateArg(Consumer, OPT_fobjc_weak);
3772
3773 if (Opts.ObjCSubscriptingLegacyRuntime)
3774 GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime);
3775 }
3776
3777 if (Opts.GNUCVersion != 0) {
3778 unsigned Major = Opts.GNUCVersion / 100 / 100;
3779 unsigned Minor = (Opts.GNUCVersion / 100) % 100;
3780 unsigned Patch = Opts.GNUCVersion % 100;
3781 GenerateArg(Consumer, OPT_fgnuc_version_EQ,
3782 Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch));
3783 }
3784
3785 if (Opts.IgnoreXCOFFVisibility)
3786 GenerateArg(Consumer, OPT_mignore_xcoff_visibility);
3787
3788 if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) {
3789 GenerateArg(Consumer, OPT_ftrapv);
3790 GenerateArg(Consumer, OPT_ftrapv_handler, Opts.OverflowHandler);
3791 } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
3792 GenerateArg(Consumer, OPT_fwrapv);
3793 }
3794 if (Opts.PointerOverflowDefined)
3795 GenerateArg(Consumer, OPT_fwrapv_pointer);
3796
3797 if (Opts.MSCompatibilityVersion != 0) {
3798 unsigned Major = Opts.MSCompatibilityVersion / 10000000;
3799 unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;
3800 unsigned Subminor = Opts.MSCompatibilityVersion % 100000;
3801 GenerateArg(Consumer, OPT_fms_compatibility_version,
3802 Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor));
3803 }
3804
3805 if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
3806 T.isOSzOS()) {
3807 if (!Opts.Trigraphs)
3808 GenerateArg(Consumer, OPT_fno_trigraphs);
3809 } else {
3810 if (Opts.Trigraphs)
3811 GenerateArg(Consumer, OPT_ftrigraphs);
3812 }
3813
3814 if (T.isOSzOS() && !Opts.ZOSExt)
3815 GenerateArg(Consumer, OPT_fno_zos_extensions);
3816 else if (Opts.ZOSExt)
3817 GenerateArg(Consumer, OPT_fzos_extensions);
3818
3819 if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
3820 GenerateArg(Consumer, OPT_fblocks);
3821
3822 if (Opts.ConvergentFunctions)
3823 GenerateArg(Consumer, OPT_fconvergent_functions);
3824 else
3825 GenerateArg(Consumer, OPT_fno_convergent_functions);
3826
3827 if (Opts.NoBuiltin && !Opts.Freestanding)
3828 GenerateArg(Consumer, OPT_fno_builtin);
3829
3830 if (!Opts.NoBuiltin)
3831 for (const auto &Func : Opts.NoBuiltinFuncs)
3832 GenerateArg(Consumer, OPT_fno_builtin_, Func);
3833
3834 if (Opts.LongDoubleSize == 128)
3835 GenerateArg(Consumer, OPT_mlong_double_128);
3836 else if (Opts.LongDoubleSize == 64)
3837 GenerateArg(Consumer, OPT_mlong_double_64);
3838 else if (Opts.LongDoubleSize == 80)
3839 GenerateArg(Consumer, OPT_mlong_double_80);
3840
3841 // Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
3842
3843 // OpenMP was requested via '-fopenmp', not implied by '-fopenmp-simd' or
3844 // '-fopenmp-targets='.
3845 if (Opts.OpenMP && !Opts.OpenMPSimd) {
3846 GenerateArg(Consumer, OPT_fopenmp);
3847
3848 if (Opts.OpenMP != 51)
3849 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3850
3851 if (!Opts.OpenMPUseTLS)
3852 GenerateArg(Consumer, OPT_fnoopenmp_use_tls);
3853
3854 if (Opts.OpenMPIsTargetDevice)
3855 GenerateArg(Consumer, OPT_fopenmp_is_target_device);
3856
3857 if (Opts.OpenMPIRBuilder)
3858 GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder);
3859 }
3860
3861 if (Opts.OpenMPSimd) {
3862 GenerateArg(Consumer, OPT_fopenmp_simd);
3863
3864 if (Opts.OpenMP != 51)
3865 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3866 }
3867
3868 if (Opts.OpenMPThreadSubscription)
3869 GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription);
3870
3871 if (Opts.OpenMPTeamSubscription)
3872 GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription);
3873
3874 if (Opts.OpenMPTargetDebug != 0)
3875 GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ,
3876 Twine(Opts.OpenMPTargetDebug));
3877
3878 if (Opts.OpenMPCUDANumSMs != 0)
3879 GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ,
3880 Twine(Opts.OpenMPCUDANumSMs));
3881
3882 if (Opts.OpenMPCUDABlocksPerSM != 0)
3883 GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ,
3884 Twine(Opts.OpenMPCUDABlocksPerSM));
3885
3886 if (Opts.OpenMPCUDAReductionBufNum != 1024)
3887 GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
3888 Twine(Opts.OpenMPCUDAReductionBufNum));
3889
3890 if (!Opts.OMPTargetTriples.empty()) {
3891 std::string Targets;
3892 llvm::raw_string_ostream OS(Targets);
3893 llvm::interleave(
3894 Opts.OMPTargetTriples, OS,
3895 [&OS](const llvm::Triple &T) { OS << T.str(); }, ",");
3896 GenerateArg(Consumer, OPT_offload_targets_EQ, Targets);
3897 }
3898
3899 if (Opts.OpenMPCUDAMode)
3900 GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
3901
3902 if (Opts.OpenACC)
3903 GenerateArg(Consumer, OPT_fopenacc);
3904
3905 // The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
3906 // generated from CodeGenOptions.
3907
3908 if (Opts.DefaultFPContractMode == LangOptions::FPM_Fast)
3909 GenerateArg(Consumer, OPT_ffp_contract, "fast");
3910 else if (Opts.DefaultFPContractMode == LangOptions::FPM_On)
3911 GenerateArg(Consumer, OPT_ffp_contract, "on");
3912 else if (Opts.DefaultFPContractMode == LangOptions::FPM_Off)
3913 GenerateArg(Consumer, OPT_ffp_contract, "off");
3914 else if (Opts.DefaultFPContractMode == LangOptions::FPM_FastHonorPragmas)
3915 GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas");
3916
3917 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3918 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3919
3920 // Conflating '-fsanitize-system-ignorelist' and '-fsanitize-ignorelist'.
3921 for (const std::string &F : Opts.NoSanitizeFiles)
3922 GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);
3923
3924 switch (Opts.getClangABICompat()) {
3925#define ABI_VER_MAJOR_MINOR(Major, Minor) \
3926 case LangOptions::ClangABI::Ver##Major##_##Minor: \
3927 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major "." #Minor); \
3928 break;
3929#define ABI_VER_MAJOR(Major) \
3930 case LangOptions::ClangABI::Ver##Major: \
3931 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, #Major ".0"); \
3932 break;
3933#define ABI_VER_LATEST(Latest) \
3934 case LangOptions::ClangABI::Latest: \
3935 break;
3936#include "clang/Basic/ABIVersions.def"
3937 }
3938
3939 if (Opts.getSignReturnAddressScope() ==
3941 GenerateArg(Consumer, OPT_msign_return_address_EQ, "all");
3942 else if (Opts.getSignReturnAddressScope() ==
3944 GenerateArg(Consumer, OPT_msign_return_address_EQ, "non-leaf");
3945
3946 if (Opts.getSignReturnAddressKey() ==
3948 GenerateArg(Consumer, OPT_msign_return_address_key_EQ, "b_key");
3949
3950 if (Opts.CXXABI)
3951 GenerateArg(Consumer, OPT_fcxx_abi_EQ,
3953
3954 if (Opts.RelativeCXXABIVTables)
3955 GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables);
3956 else
3957 GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables);
3958
3959 if (Opts.UseTargetPathSeparator)
3960 GenerateArg(Consumer, OPT_ffile_reproducible);
3961 else
3962 GenerateArg(Consumer, OPT_fno_file_reproducible);
3963
3964 for (const auto &MP : Opts.MacroPrefixMap)
3965 GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second);
3966
3967 if (!Opts.RandstructSeed.empty())
3968 GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed);
3969}
3970
3971bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
3972 InputKind IK, const llvm::Triple &T,
3973 std::vector<std::string> &Includes,
3974 DiagnosticsEngine &Diags) {
3975 unsigned NumErrorsBefore = Diags.getNumErrors();
3976
3977 if (IK.getFormat() == InputKind::Precompiled ||
3979 IK.getLanguage() == Language::CIR) {
3980 // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
3981 // PassManager in BackendUtil.cpp. They need to be initialized no matter
3982 // what the input type is.
3983 if (Args.hasArg(OPT_fobjc_arc))
3984 Opts.ObjCAutoRefCount = 1;
3985 // PICLevel and PIELevel are needed during code generation and this should
3986 // be set regardless of the input type.
3987 Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
3988 Opts.PIE = Args.hasArg(OPT_pic_is_pie);
3989 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
3990 Diags, Opts.Sanitize);
3991
3992 return Diags.getNumErrors() == NumErrorsBefore;
3993 }
3994
3995 // Other LangOpts are only initialized when the input is not AST or LLVM IR.
3996 // FIXME: Should we really be parsing this for an Language::Asm input?
3997
3998 // FIXME: Cleanup per-file based stuff.
4000 if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
4001 LangStd = LangStandard::getLangKind(A->getValue());
4002 if (LangStd == LangStandard::lang_unspecified) {
4003 Diags.Report(diag::err_drv_invalid_value)
4004 << A->getAsString(Args) << A->getValue();
4005 // Report supported standards with short description.
4006 for (unsigned KindValue = 0;
4007 KindValue != LangStandard::lang_unspecified;
4008 ++KindValue) {
4009 const LangStandard &Std = LangStandard::getLangStandardForKind(
4010 static_cast<LangStandard::Kind>(KindValue));
4011 if (IsInputCompatibleWithStandard(IK, Std)) {
4012 auto Diag = Diags.Report(diag::note_drv_use_standard);
4013 Diag << Std.getName() << Std.getDescription();
4014 unsigned NumAliases = 0;
4015#define LANGSTANDARD(id, name, lang, desc, features, version)
4016#define LANGSTANDARD_ALIAS(id, alias) \
4017 if (KindValue == LangStandard::lang_##id) ++NumAliases;
4018#define LANGSTANDARD_ALIAS_DEPR(id, alias)
4019#include "clang/Basic/LangStandards.def"
4020 Diag << NumAliases;
4021#define LANGSTANDARD(id, name, lang, desc, features, version)
4022#define LANGSTANDARD_ALIAS(id, alias) \
4023 if (KindValue == LangStandard::lang_##id) Diag << alias;
4024#define LANGSTANDARD_ALIAS_DEPR(id, alias)
4025#include "clang/Basic/LangStandards.def"
4026 }
4027 }
4028 } else {
4029 // Valid standard, check to make sure language and standard are
4030 // compatible.
4031 const LangStandard &Std = LangStandard::getLangStandardForKind(LangStd);
4032 if (!IsInputCompatibleWithStandard(IK, Std)) {
4033 Diags.Report(diag::err_drv_argument_not_allowed_with)
4034 << A->getAsString(Args) << GetInputKindName(IK);
4035 }
4036 }
4037 }
4038
4039 // -cl-std only applies for OpenCL language standards.
4040 // Override the -std option in this case.
4041 if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
4042 LangStandard::Kind OpenCLLangStd
4043 = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
4044 .Cases("cl", "CL", LangStandard::lang_opencl10)
4045 .Cases("cl1.0", "CL1.0", LangStandard::lang_opencl10)
4046 .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
4047 .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
4048 .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
4049 .Cases("cl3.0", "CL3.0", LangStandard::lang_opencl30)
4050 .Cases("clc++", "CLC++", LangStandard::lang_openclcpp10)
4051 .Cases("clc++1.0", "CLC++1.0", LangStandard::lang_openclcpp10)
4052 .Cases("clc++2021", "CLC++2021", LangStandard::lang_openclcpp2021)
4054
4055 if (OpenCLLangStd == LangStandard::lang_unspecified) {
4056 Diags.Report(diag::err_drv_invalid_value)
4057 << A->getAsString(Args) << A->getValue();
4058 }
4059 else
4060 LangStd = OpenCLLangStd;
4061 }
4062
4063 // These need to be parsed now. They are used to set OpenCL defaults.
4064 Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
4065 Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
4066
4067 LangOptions::setLangDefaults(Opts, IK.getLanguage(), T, Includes, LangStd);
4068
4069 // The key paths of codegen options defined in Options.td start with
4070 // "LangOpts->". Let's provide the expected variable name and type.
4071 LangOptions *LangOpts = &Opts;
4072
4073#define LANG_OPTION_WITH_MARSHALLING(...) \
4074 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4075#include "clang/Driver/Options.inc"
4076#undef LANG_OPTION_WITH_MARSHALLING
4077
4078 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4079 StringRef Name = A->getValue();
4080 if (Name == "full") {
4081 Opts.CFProtectionBranch = 1;
4082 Opts.CFProtectionReturn = 1;
4083 } else if (Name == "branch") {
4084 Opts.CFProtectionBranch = 1;
4085 } else if (Name == "return") {
4086 Opts.CFProtectionReturn = 1;
4087 }
4088 }
4089
4090 if (Opts.CFProtectionBranch) {
4091 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
4092 const auto Scheme =
4093 llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
4094#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
4095 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
4096#include "clang/Basic/CFProtectionOptions.def"
4098 Opts.setCFBranchLabelScheme(Scheme);
4099 }
4100 }
4101
4102 if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
4103 !Args.hasArg(OPT_sycl_std_EQ)) {
4104 // If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to
4105 // provide -sycl-std=, we want to default it to whatever the default SYCL
4106 // version is. I could not find a way to express this with the options
4107 // tablegen because we still want this value to be SYCL_None when the user
4108 // is not in device or host mode.
4109 Opts.setSYCLVersion(LangOptions::SYCL_Default);
4110 }
4111
4112 if (Opts.ObjC) {
4113 if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
4114 StringRef value = arg->getValue();
4115 if (Opts.ObjCRuntime.tryParse(value))
4116 Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
4117 }
4118
4119 if (Args.hasArg(OPT_fobjc_gc_only))
4120 Opts.setGC(LangOptions::GCOnly);
4121 else if (Args.hasArg(OPT_fobjc_gc))
4122 Opts.setGC(LangOptions::HybridGC);
4123 else if (Args.hasArg(OPT_fobjc_arc)) {
4124 Opts.ObjCAutoRefCount = 1;
4125 if (!Opts.ObjCRuntime.allowsARC())
4126 Diags.Report(diag::err_arc_unsupported_on_runtime);
4127 }
4128
4129 // ObjCWeakRuntime tracks whether the runtime supports __weak, not
4130 // whether the feature is actually enabled. This is predominantly
4131 // determined by -fobjc-runtime, but we allow it to be overridden
4132 // from the command line for testing purposes.
4133 if (Args.hasArg(OPT_fobjc_runtime_has_weak))
4134 Opts.ObjCWeakRuntime = 1;
4135 else
4136 Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();
4137
4138 // ObjCWeak determines whether __weak is actually enabled.
4139 // Note that we allow -fno-objc-weak to disable this even in ARC mode.
4140 if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
4141 if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
4142 assert(!Opts.ObjCWeak);
4143 } else if (Opts.getGC() != LangOptions::NonGC) {
4144 Diags.Report(diag::err_objc_weak_with_gc);
4145 } else if (!Opts.ObjCWeakRuntime) {
4146 Diags.Report(diag::err_objc_weak_unsupported);
4147 } else {
4148 Opts.ObjCWeak = 1;
4149 }
4150 } else if (Opts.ObjCAutoRefCount) {
4151 Opts.ObjCWeak = Opts.ObjCWeakRuntime;
4152 }
4153
4154 if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
4155 Opts.ObjCSubscriptingLegacyRuntime =
4157 }
4158
4159 if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
4160 // Check that the version has 1 to 3 components and the minor and patch
4161 // versions fit in two decimal digits.
4162 VersionTuple GNUCVer;
4163 bool Invalid = GNUCVer.tryParse(A->getValue());
4164 unsigned Major = GNUCVer.getMajor();
4165 unsigned Minor = GNUCVer.getMinor().value_or(0);
4166 unsigned Patch = GNUCVer.getSubminor().value_or(0);
4167 if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
4168 Diags.Report(diag::err_drv_invalid_value)
4169 << A->getAsString(Args) << A->getValue();
4170 }
4171 Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
4172 }
4173
4174 if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility)))
4175 Opts.IgnoreXCOFFVisibility = 1;
4176
4177 if (Args.hasArg(OPT_ftrapv)) {
4178 Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
4179 // Set the handler, if one is specified.
4180 Opts.OverflowHandler =
4181 std::string(Args.getLastArgValue(OPT_ftrapv_handler));
4182 }
4183 else if (Args.hasArg(OPT_fwrapv))
4184 Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
4185 if (Args.hasArg(OPT_fwrapv_pointer))
4186 Opts.PointerOverflowDefined = true;
4187
4188 Opts.MSCompatibilityVersion = 0;
4189 if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
4190 VersionTuple VT;
4191 if (VT.tryParse(A->getValue()))
4192 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
4193 << A->getValue();
4194 Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
4195 VT.getMinor().value_or(0) * 100000 +
4196 VT.getSubminor().value_or(0);
4197 }
4198
4199 // Mimicking gcc's behavior, trigraphs are only enabled if -trigraphs
4200 // is specified, or -std is set to a conforming mode.
4201 // Trigraphs are disabled by default in C++17 and C23 onwards.
4202 // For z/OS, trigraphs are enabled by default (without regard to the above).
4203 Opts.Trigraphs =
4204 (!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
4205 T.isOSzOS();
4206 Opts.Trigraphs =
4207 Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
4208
4209 Opts.ZOSExt =
4210 Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions, T.isOSzOS());
4211
4212 Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
4213 && Opts.OpenCLVersion == 200);
4214
4215 bool HasConvergentOperations = Opts.isTargetDevice() || Opts.OpenCL ||
4216 Opts.HLSL || T.isAMDGPU() || T.isNVPTX();
4217 Opts.ConvergentFunctions =
4218 Args.hasFlag(OPT_fconvergent_functions, OPT_fno_convergent_functions,
4219 HasConvergentOperations);
4220
4221 Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
4222 if (!Opts.NoBuiltin)
4224 if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
4225 if (A->getOption().matches(options::OPT_mlong_double_64))
4226 Opts.LongDoubleSize = 64;
4227 else if (A->getOption().matches(options::OPT_mlong_double_80))
4228 Opts.LongDoubleSize = 80;
4229 else if (A->getOption().matches(options::OPT_mlong_double_128))
4230 Opts.LongDoubleSize = 128;
4231 else
4232 Opts.LongDoubleSize = 0;
4233 }
4234 if (Opts.FastRelaxedMath || Opts.CLUnsafeMath)
4235 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4236
4237 llvm::sort(Opts.ModuleFeatures);
4238
4239 // -mrtd option
4240 if (Arg *A = Args.getLastArg(OPT_mrtd)) {
4241 if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
4242 Diags.Report(diag::err_drv_argument_not_allowed_with)
4243 << A->getSpelling() << "-fdefault-calling-conv";
4244 else {
4245 switch (T.getArch()) {
4246 case llvm::Triple::x86:
4247 Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
4248 break;
4249 case llvm::Triple::m68k:
4250 Opts.setDefaultCallingConv(LangOptions::DCC_RtdCall);
4251 break;
4252 default:
4253 Diags.Report(diag::err_drv_argument_not_allowed_with)
4254 << A->getSpelling() << T.getTriple();
4255 }
4256 }
4257 }
4258
4259 // Check if -fopenmp is specified and set default version to 5.1.
4260 Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;
4261 // Check if -fopenmp-simd is specified.
4262 bool IsSimdSpecified =
4263 Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
4264 /*Default=*/false);
4265 Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;
4266 Opts.OpenMPUseTLS =
4267 Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
4268 Opts.OpenMPIsTargetDevice =
4269 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_target_device);
4270 Opts.OpenMPIRBuilder =
4271 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_enable_irbuilder);
4272 bool IsTargetSpecified =
4273 Opts.OpenMPIsTargetDevice || Args.hasArg(options::OPT_offload_targets_EQ);
4274
4275 if (Opts.OpenMP || Opts.OpenMPSimd) {
4276 if (int Version = getLastArgIntValue(
4277 Args, OPT_fopenmp_version_EQ,
4278 (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))
4279 Opts.OpenMP = Version;
4280 // Provide diagnostic when a given target is not expected to be an OpenMP
4281 // device or host.
4282 if (!Opts.OpenMPIsTargetDevice) {
4283 switch (T.getArch()) {
4284 default:
4285 break;
4286 // Add unsupported host targets here:
4287 case llvm::Triple::nvptx:
4288 case llvm::Triple::nvptx64:
4289 Diags.Report(diag::err_drv_omp_host_target_not_supported) << T.str();
4290 break;
4291 }
4292 }
4293 }
4294
4295 // Set the flag to prevent the implementation from emitting device exception
4296 // handling code for those requiring so.
4297 if ((Opts.OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) ||
4298 Opts.OpenCLCPlusPlus) {
4299
4300 Opts.Exceptions = 0;
4301 Opts.CXXExceptions = 0;
4302 }
4303 if (Opts.OpenMPIsTargetDevice && T.isNVPTX()) {
4304 Opts.OpenMPCUDANumSMs =
4305 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_number_of_sm_EQ,
4306 Opts.OpenMPCUDANumSMs, Diags);
4307 Opts.OpenMPCUDABlocksPerSM =
4308 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,
4309 Opts.OpenMPCUDABlocksPerSM, Diags);
4310 Opts.OpenMPCUDAReductionBufNum = getLastArgIntValue(
4311 Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
4312 Opts.OpenMPCUDAReductionBufNum, Diags);
4313 }
4314
4315 // Set the value of the debugging flag used in the new offloading device RTL.
4316 // Set either by a specific value or to a default if not specified.
4317 if (Opts.OpenMPIsTargetDevice && (Args.hasArg(OPT_fopenmp_target_debug) ||
4318 Args.hasArg(OPT_fopenmp_target_debug_EQ))) {
4319 Opts.OpenMPTargetDebug = getLastArgIntValue(
4320 Args, OPT_fopenmp_target_debug_EQ, Opts.OpenMPTargetDebug, Diags);
4321 if (!Opts.OpenMPTargetDebug && Args.hasArg(OPT_fopenmp_target_debug))
4322 Opts.OpenMPTargetDebug = 1;
4323 }
4324
4325 if (Opts.OpenMPIsTargetDevice) {
4326 if (Args.hasArg(OPT_fopenmp_assume_teams_oversubscription))
4327 Opts.OpenMPTeamSubscription = true;
4328 if (Args.hasArg(OPT_fopenmp_assume_threads_oversubscription))
4329 Opts.OpenMPThreadSubscription = true;
4330 }
4331
4332 // Get the OpenMP target triples if any.
4333 if (Arg *A = Args.getLastArg(options::OPT_offload_targets_EQ)) {
4334 enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
4335 auto getArchPtrSize = [](const llvm::Triple &T) {
4336 if (T.isArch16Bit())
4337 return Arch16Bit;
4338 if (T.isArch32Bit())
4339 return Arch32Bit;
4340 assert(T.isArch64Bit() && "Expected 64-bit architecture");
4341 return Arch64Bit;
4342 };
4343
4344 for (unsigned i = 0; i < A->getNumValues(); ++i) {
4345 llvm::Triple TT(A->getValue(i));
4346
4347 if (TT.getArch() == llvm::Triple::UnknownArch ||
4348 !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() ||
4349 TT.getArch() == llvm::Triple::spirv64 ||
4350 TT.getArch() == llvm::Triple::systemz ||
4351 TT.getArch() == llvm::Triple::loongarch64 ||
4352 TT.getArch() == llvm::Triple::nvptx ||
4353 TT.getArch() == llvm::Triple::nvptx64 || TT.isAMDGCN() ||
4354 TT.getArch() == llvm::Triple::x86 ||
4355 TT.getArch() == llvm::Triple::x86_64))
4356 Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
4357 else if (getArchPtrSize(T) != getArchPtrSize(TT))
4358 Diags.Report(diag::err_drv_incompatible_omp_arch)
4359 << A->getValue(i) << T.str();
4360 else
4361 Opts.OMPTargetTriples.push_back(TT);
4362 }
4363 }
4364
4365 // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options
4366 Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice &&
4367 (T.isNVPTX() || T.isAMDGCN()) &&
4368 Args.hasArg(options::OPT_fopenmp_cuda_mode);
4369
4370 // OpenACC Configuration.
4371 if (Args.hasArg(options::OPT_fopenacc))
4372 Opts.OpenACC = true;
4373
4374 if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
4375 StringRef Val = A->getValue();
4376 if (Val == "fast")
4377 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4378 else if (Val == "on")
4379 Opts.setDefaultFPContractMode(LangOptions::FPM_On);
4380 else if (Val == "off")
4381 Opts.setDefaultFPContractMode(LangOptions::FPM_Off);
4382 else if (Val == "fast-honor-pragmas")
4383 Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
4384 else
4385 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
4386 }
4387
4388 if (auto *A =
4389 Args.getLastArg(OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {
4390 for (int i = 0, n = A->getNumValues(); i != n; ++i) {
4392 llvm::StringSwitch<unsigned>(A->getValue(i))
4393 .Case("none", LangOptionsBase::None)
4394 .Case("all", LangOptionsBase::All)
4395 .Case("add-unsigned-overflow-test",
4397 .Case("add-signed-overflow-test",
4399 .Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst)
4400 .Case("unsigned-post-decr-while",
4402 .Default(0);
4403 }
4404 }
4405
4406 // Parse -fsanitize= arguments.
4407 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
4408 Diags, Opts.Sanitize);
4409 Opts.NoSanitizeFiles = Args.getAllArgValues(OPT_fsanitize_ignorelist_EQ);
4410 std::vector<std::string> systemIgnorelists =
4411 Args.getAllArgValues(OPT_fsanitize_system_ignorelist_EQ);
4412 Opts.NoSanitizeFiles.insert(Opts.NoSanitizeFiles.end(),
4413 systemIgnorelists.begin(),
4414 systemIgnorelists.end());
4415
4416 if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
4417 Opts.setClangABICompat(LangOptions::ClangABI::Latest);
4418
4419 StringRef Ver = A->getValue();
4420 std::pair<StringRef, StringRef> VerParts = Ver.split('.');
4421 int Major, Minor = 0;
4422
4423 // Check the version number is valid: either 3.x (0 <= x <= 9) or
4424 // y or y.0 (4 <= y <= current version).
4425 if (!VerParts.first.starts_with("0") &&
4426 !VerParts.first.getAsInteger(10, Major) && 3 <= Major &&
4427 Major <= MAX_CLANG_ABI_COMPAT_VERSION &&
4428 (Major == 3
4429 ? VerParts.second.size() == 1 &&
4430 !VerParts.second.getAsInteger(10, Minor)
4431 : VerParts.first.size() == Ver.size() || VerParts.second == "0")) {
4432 // Got a valid version number.
4433#define ABI_VER_MAJOR_MINOR(Major_, Minor_) \
4434 if (std::tuple(Major, Minor) <= std::tuple(Major_, Minor_)) \
4435 Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_##_##Minor_); \
4436 else
4437#define ABI_VER_MAJOR(Major_) \
4438 if (Major <= Major_) \
4439 Opts.setClangABICompat(LangOptions::ClangABI::Ver##Major_); \
4440 else
4441#define ABI_VER_LATEST(Latest) \
4442 { /* Equivalent to latest version - do nothing */ \
4443 }
4444#include "clang/Basic/ABIVersions.def"
4445 } else if (Ver != "latest") {
4446 Diags.Report(diag::err_drv_invalid_value)
4447 << A->getAsString(Args) << A->getValue();
4448 }
4449 }
4450
4451 if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) {
4452 StringRef SignScope = A->getValue();
4453
4454 if (SignScope.equals_insensitive("none"))
4455 Opts.setSignReturnAddressScope(
4457 else if (SignScope.equals_insensitive("all"))
4458 Opts.setSignReturnAddressScope(
4460 else if (SignScope.equals_insensitive("non-leaf"))
4461 Opts.setSignReturnAddressScope(
4463 else
4464 Diags.Report(diag::err_drv_invalid_value)
4465 << A->getAsString(Args) << SignScope;
4466
4467 if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
4468 StringRef SignKey = A->getValue();
4469 if (!SignScope.empty() && !SignKey.empty()) {
4470 if (SignKey == "a_key")
4471 Opts.setSignReturnAddressKey(
4473 else if (SignKey == "b_key")
4474 Opts.setSignReturnAddressKey(
4476 else
4477 Diags.Report(diag::err_drv_invalid_value)
4478 << A->getAsString(Args) << SignKey;
4479 }
4480 }
4481 }
4482
4483 // The value can be empty, which indicates the system default should be used.
4484 StringRef CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);
4485 if (!CXXABI.empty()) {
4487 Diags.Report(diag::err_invalid_cxx_abi) << CXXABI;
4488 } else {
4491 Diags.Report(diag::err_unsupported_cxx_abi) << CXXABI << T.str();
4492 else
4493 Opts.CXXABI = Kind;
4494 }
4495 }
4496
4497 Opts.RelativeCXXABIVTables =
4498 Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
4499 options::OPT_fno_experimental_relative_cxx_abi_vtables,
4501
4502 // RTTI is on by default.
4503 bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti);
4504 Opts.OmitVTableRTTI =
4505 Args.hasFlag(options::OPT_fexperimental_omit_vtable_rtti,
4506 options::OPT_fno_experimental_omit_vtable_rtti, false);
4507 if (Opts.OmitVTableRTTI && HasRTTI)
4508 Diags.Report(diag::err_drv_using_omit_rtti_component_without_no_rtti);
4509
4510 for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
4511 auto Split = StringRef(A).split('=');
4512 Opts.MacroPrefixMap.insert(
4513 {std::string(Split.first), std::string(Split.second)});
4514 }
4515
4517 !Args.getLastArg(OPT_fno_file_reproducible) &&
4518 (Args.getLastArg(OPT_ffile_compilation_dir_EQ) ||
4519 Args.getLastArg(OPT_fmacro_prefix_map_EQ) ||
4520 Args.getLastArg(OPT_ffile_reproducible));
4521
4522 // Error if -mvscale-min is unbounded.
4523 if (Arg *A = Args.getLastArg(options::OPT_mvscale_min_EQ)) {
4524 unsigned VScaleMin;
4525 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4526 Diags.Report(diag::err_cc1_unbounded_vscale_min);
4527 }
4528 if (Arg *A = Args.getLastArg(options::OPT_mvscale_streaming_min_EQ)) {
4529 unsigned VScaleMin;
4530 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4531 Diags.Report(diag::err_cc1_unbounded_vscale_min);
4532 }
4533
4534 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) {
4535 std::ifstream SeedFile(A->getValue(0));
4536
4537 if (!SeedFile.is_open())
4538 Diags.Report(diag::err_drv_cannot_open_randomize_layout_seed_file)
4539 << A->getValue(0);
4540
4541 std::getline(SeedFile, Opts.RandstructSeed);
4542 }
4543
4544 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
4545 Opts.RandstructSeed = A->getValue(0);
4546
4547 // Validate options for HLSL
4548 if (Opts.HLSL) {
4549 // TODO: Revisit restricting SPIR-V to logical once we've figured out how to
4550 // handle PhysicalStorageBuffer64 memory model
4551 if (T.isDXIL() || T.isSPIRVLogical()) {
4552 enum { ShaderModel, VulkanEnv, ShaderStage };
4553 enum { OS, Environment };
4554
4555 int ExpectedOS = T.isSPIRVLogical() ? VulkanEnv : ShaderModel;
4556
4557 if (T.getOSName().empty()) {
4558 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4559 << ExpectedOS << OS << T.str();
4560 } else if (T.getEnvironmentName().empty()) {
4561 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4562 << ShaderStage << Environment << T.str();
4563 } else if (!T.isShaderStageEnvironment()) {
4564 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4565 << ShaderStage << T.getEnvironmentName() << T.str();
4566 }
4567
4568 if (T.isDXIL()) {
4569 if (!T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
4570 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4571 << ShaderModel << T.getOSName() << T.str();
4572 }
4573 // Validate that if fnative-half-type is given, that
4574 // the language standard is at least hlsl2018, and that
4575 // the target shader model is at least 6.2.
4576 if (Args.getLastArg(OPT_fnative_half_type)) {
4577 const LangStandard &Std =
4579 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018 &&
4580 T.getOSVersion() >= VersionTuple(6, 2)))
4581 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4582 << "-enable-16bit-types" << true << Std.getName()
4583 << T.getOSVersion().getAsString();
4584 }
4585 } else if (T.isSPIRVLogical()) {
4586 if (!T.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) {
4587 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4588 << VulkanEnv << T.getOSName() << T.str();
4589 }
4590 if (Args.getLastArg(OPT_fnative_half_type)) {
4591 const LangStandard &Std =
4593 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018))
4594 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4595 << "-fnative-half-type" << false << Std.getName();
4596 }
4597 } else {
4598 llvm_unreachable("expected DXIL or SPIR-V target");
4599 }
4600 } else
4601 Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
4602
4603 if (Opts.LangStd < LangStandard::lang_hlsl202x) {
4604 const LangStandard &Requested =
4606 const LangStandard &Recommended =
4607 LangStandard::getLangStandardForKind(LangStandard::lang_hlsl202x);
4608 Diags.Report(diag::warn_hlsl_langstd_minimal)
4609 << Requested.getName() << Recommended.getName();
4610 }
4611 }
4612
4613 return Diags.getNumErrors() == NumErrorsBefore;
4614}
4615
4617 switch (Action) {
4619 case frontend::ASTDump:
4620 case frontend::ASTPrint:
4621 case frontend::ASTView:
4623 case frontend::EmitBC:
4624 case frontend::EmitCIR:
4625 case frontend::EmitHTML:
4626 case frontend::EmitLLVM:
4629 case frontend::EmitObj:
4631 case frontend::FixIt:
4646 return false;
4647
4651 case frontend::InitOnly:
4657 return true;
4658 }
4659 llvm_unreachable("invalid frontend action");
4660}
4661
4663 switch (Action) {
4665 case frontend::EmitBC:
4666 case frontend::EmitCIR:
4667 case frontend::EmitHTML:
4668 case frontend::EmitLLVM:
4671 case frontend::EmitObj:
4678 return true;
4680 case frontend::ASTDump:
4681 case frontend::ASTPrint:
4682 case frontend::ASTView:
4684 case frontend::FixIt:
4696 case frontend::InitOnly:
4702 return false;
4703 }
4704 llvm_unreachable("invalid frontend action");
4705}
4706
4708 ArgumentConsumer Consumer,
4709 const LangOptions &LangOpts,
4710 const FrontendOptions &FrontendOpts,
4711 const CodeGenOptions &CodeGenOpts) {
4712 const PreprocessorOptions *PreprocessorOpts = &Opts;
4713
4714#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4715 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4716#include "clang/Driver/Options.inc"
4717#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4718
4719 if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate)
4720 GenerateArg(Consumer, OPT_pch_through_hdrstop_use);
4721
4722 for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn)
4723 GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);
4724
4725 if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false))
4726 GenerateArg(Consumer, OPT_preamble_bytes_EQ,
4727 Twine(Opts.PrecompiledPreambleBytes.first) + "," +
4728 (Opts.PrecompiledPreambleBytes.second ? "1" : "0"));
4729
4730 for (const auto &M : Opts.Macros) {
4731 // Don't generate __CET__ macro definitions. They are implied by the
4732 // -fcf-protection option that is generated elsewhere.
4733 if (M.first == "__CET__=1" && !M.second &&
4734 !CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch)
4735 continue;
4736 if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn &&
4737 !CodeGenOpts.CFProtectionBranch)
4738 continue;
4739 if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn &&
4740 CodeGenOpts.CFProtectionBranch)
4741 continue;
4742
4743 GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first);
4744 }
4745
4746 for (const auto &I : Opts.Includes) {
4747 // Don't generate OpenCL includes. They are implied by other flags that are
4748 // generated elsewhere.
4749 if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader &&
4750 ((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") ||
4751 I == "opencl-c.h"))
4752 continue;
4753 // Don't generate HLSL includes. They are implied by other flags that are
4754 // generated elsewhere.
4755 if (LangOpts.HLSL && I == "hlsl.h")
4756 continue;
4757
4758 GenerateArg(Consumer, OPT_include, I);
4759 }
4760
4761 for (const auto &CI : Opts.ChainedIncludes)
4762 GenerateArg(Consumer, OPT_chain_include, CI);
4763
4764 for (const auto &RF : Opts.RemappedFiles)
4765 GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second);
4766
4767 if (Opts.SourceDateEpoch)
4768 GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch));
4769
4770 if (Opts.DefineTargetOSMacros)
4771 GenerateArg(Consumer, OPT_fdefine_target_os_macros);
4772
4773 for (const auto &EmbedEntry : Opts.EmbedEntries)
4774 GenerateArg(Consumer, OPT_embed_dir_EQ, EmbedEntry);
4775
4776 // Don't handle LexEditorPlaceholders. It is implied by the action that is
4777 // generated elsewhere.
4778}
4779
4780static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
4781 DiagnosticsEngine &Diags,
4783 const FrontendOptions &FrontendOpts) {
4784 unsigned NumErrorsBefore = Diags.getNumErrors();
4785
4786 PreprocessorOptions *PreprocessorOpts = &Opts;
4787
4788#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4789 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4790#include "clang/Driver/Options.inc"
4791#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4792
4793 Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) ||
4794 Args.hasArg(OPT_pch_through_hdrstop_use);
4795
4796 for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
4797 Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
4798
4799 if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
4800 StringRef Value(A->getValue());
4801 size_t Comma = Value.find(',');
4802 unsigned Bytes = 0;
4803 unsigned EndOfLine = 0;
4804
4805 if (Comma == StringRef::npos ||
4806 Value.substr(0, Comma).getAsInteger(10, Bytes) ||
4807 Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
4808 Diags.Report(diag::err_drv_preamble_format);
4809 else {
4810 Opts.PrecompiledPreambleBytes.first = Bytes;
4811 Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
4812 }
4813 }
4814
4815 // Add macros from the command line.
4816 for (const auto *A : Args.filtered(OPT_D, OPT_U)) {
4817 if (A->getOption().matches(OPT_D))
4818 Opts.addMacroDef(A->getValue());
4819 else
4820 Opts.addMacroUndef(A->getValue());
4821 }
4822
4823 // Add the ordered list of -includes.
4824 for (const auto *A : Args.filtered(OPT_include))
4825 Opts.Includes.emplace_back(A->getValue());
4826
4827 for (const auto *A : Args.filtered(OPT_chain_include))
4828 Opts.ChainedIncludes.emplace_back(A->getValue());
4829
4830 for (const auto *A : Args.filtered(OPT_remap_file)) {
4831 std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
4832
4833 if (Split.second.empty()) {
4834 Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
4835 continue;
4836 }
4837
4838 Opts.addRemappedFile(Split.first, Split.second);
4839 }
4840
4841 if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
4842 StringRef Epoch = A->getValue();
4843 // SOURCE_DATE_EPOCH, if specified, must be a non-negative decimal integer.
4844 // On time64 systems, pick 253402300799 (the UNIX timestamp of
4845 // 9999-12-31T23:59:59Z) as the upper bound.
4846 const uint64_t MaxTimestamp =
4847 std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
4848 uint64_t V;
4849 if (Epoch.getAsInteger(10, V) || V > MaxTimestamp) {
4850 Diags.Report(diag::err_fe_invalid_source_date_epoch)
4851 << Epoch << MaxTimestamp;
4852 } else {
4853 Opts.SourceDateEpoch = V;
4854 }
4855 }
4856
4857 for (const auto *A : Args.filtered(OPT_embed_dir_EQ)) {
4858 StringRef Val = A->getValue();
4859 Opts.EmbedEntries.push_back(std::string(Val));
4860 }
4861
4862 // Always avoid lexing editor placeholders when we're just running the
4863 // preprocessor as we never want to emit the
4864 // "editor placeholder in source file" error in PP only mode.
4866 Opts.LexEditorPlaceholders = false;
4867
4869 Args.hasFlag(OPT_fdefine_target_os_macros,
4870 OPT_fno_define_target_os_macros, Opts.DefineTargetOSMacros);
4871
4872 return Diags.getNumErrors() == NumErrorsBefore;
4873}
4874
4875static void
4877 ArgumentConsumer Consumer,
4879 const PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
4880
4881#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4882 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4883#include "clang/Driver/Options.inc"
4884#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4885
4886 bool Generate_dM = isStrictlyPreprocessorAction(Action) && !Opts.ShowCPP;
4887 if (Generate_dM)
4888 GenerateArg(Consumer, OPT_dM);
4889 if (!Generate_dM && Opts.ShowMacros)
4890 GenerateArg(Consumer, OPT_dD);
4891 if (Opts.DirectivesOnly)
4892 GenerateArg(Consumer, OPT_fdirectives_only);
4893}
4894
4896 ArgList &Args, DiagnosticsEngine &Diags,
4898 unsigned NumErrorsBefore = Diags.getNumErrors();
4899
4900 PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
4901
4902#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4903 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4904#include "clang/Driver/Options.inc"
4905#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4906
4907 Opts.ShowCPP = isStrictlyPreprocessorAction(Action) && !Args.hasArg(OPT_dM);
4908 Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
4909 Opts.DirectivesOnly = Args.hasArg(OPT_fdirectives_only);
4910
4911 return Diags.getNumErrors() == NumErrorsBefore;
4912}
4913
4914static void GenerateTargetArgs(const TargetOptions &Opts,
4915 ArgumentConsumer Consumer) {
4916 const TargetOptions *TargetOpts = &Opts;
4917#define TARGET_OPTION_WITH_MARSHALLING(...) \
4918 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4919#include "clang/Driver/Options.inc"
4920#undef TARGET_OPTION_WITH_MARSHALLING
4921
4922 if (!Opts.SDKVersion.empty())
4923 GenerateArg(Consumer, OPT_target_sdk_version_EQ,
4924 Opts.SDKVersion.getAsString());
4925 if (!Opts.DarwinTargetVariantSDKVersion.empty())
4926 GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,
4927 Opts.DarwinTargetVariantSDKVersion.getAsString());
4928}
4929
4930static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
4931 DiagnosticsEngine &Diags) {
4932 unsigned NumErrorsBefore = Diags.getNumErrors();
4933
4934 TargetOptions *TargetOpts = &Opts;
4935
4936#define TARGET_OPTION_WITH_MARSHALLING(...) \
4937 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4938#include "clang/Driver/Options.inc"
4939#undef TARGET_OPTION_WITH_MARSHALLING
4940
4941 if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {
4942 llvm::VersionTuple Version;
4943 if (Version.tryParse(A->getValue()))
4944 Diags.Report(diag::err_drv_invalid_value)
4945 << A->getAsString(Args) << A->getValue();
4946 else
4947 Opts.SDKVersion = Version;
4948 }
4949 if (Arg *A =
4950 Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {
4951 llvm::VersionTuple Version;
4952 if (Version.tryParse(A->getValue()))
4953 Diags.Report(diag::err_drv_invalid_value)
4954 << A->getAsString(Args) << A->getValue();
4955 else
4956 Opts.DarwinTargetVariantSDKVersion = Version;
4957 }
4958
4959 return Diags.getNumErrors() == NumErrorsBefore;
4960}
4961
4962bool CompilerInvocation::CreateFromArgsImpl(
4963 CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs,
4964 DiagnosticsEngine &Diags, const char *Argv0) {
4965 unsigned NumErrorsBefore = Diags.getNumErrors();
4966
4967 // Parse the arguments.
4968 const OptTable &Opts = getDriverOptTable();
4969 llvm::opt::Visibility VisibilityMask(options::CC1Option);
4970 unsigned MissingArgIndex, MissingArgCount;
4971 InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
4972 MissingArgCount, VisibilityMask);
4973 LangOptions &LangOpts = Res.getLangOpts();
4974
4975 // Check for missing argument error.
4976 if (MissingArgCount)
4977 Diags.Report(diag::err_drv_missing_argument)
4978 << Args.getArgString(MissingArgIndex) << MissingArgCount;
4979
4980 // Issue errors on unknown arguments.
4981 for (const auto *A : Args.filtered(OPT_UNKNOWN)) {
4982 auto ArgString = A->getAsString(Args);
4983 std::string Nearest;
4984 if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1)
4985 Diags.Report(diag::err_drv_unknown_argument) << ArgString;
4986 else
4987 Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
4988 << ArgString << Nearest;
4989 }
4990
4991 ParseFileSystemArgs(Res.getFileSystemOpts(), Args, Diags);
4992 ParseMigratorArgs(Res.getMigratorOpts(), Args, Diags);
4993 ParseAnalyzerArgs(Res.getAnalyzerOpts(), Args, Diags);
4994 ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags,
4995 /*DefaultDiagColor=*/false);
4996 ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags, LangOpts.IsHeaderFile);
4997 // FIXME: We shouldn't have to pass the DashX option around here
4998 InputKind DashX = Res.getFrontendOpts().DashX;
4999 ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
5000 llvm::Triple T(Res.getTargetOpts().Triple);
5001 ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags);
5002 if (Res.getFrontendOpts().GenReducedBMI ||
5009 }
5010 ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
5011
5012 ParsePointerAuthArgs(LangOpts, Args, Diags);
5013
5014 ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
5015 Diags);
5017 LangOpts.ObjCExceptions = 1;
5018
5019 for (auto Warning : Res.getDiagnosticOpts().Warnings) {
5020 if (Warning == "misexpect" &&
5021 !Diags.isIgnored(diag::warn_profile_data_misexpect, SourceLocation())) {
5022 Res.getCodeGenOpts().MisExpect = true;
5023 }
5024 }
5025
5026 if (LangOpts.CUDA) {
5027 // During CUDA device-side compilation, the aux triple is the
5028 // triple used for host compilation.
5029 if (LangOpts.CUDAIsDevice)
5031 }
5032
5033 if (LangOpts.OpenACC && !Res.getFrontendOpts().UseClangIRPipeline &&
5035 Diags.Report(diag::warn_drv_openacc_without_cir);
5036
5037 // Set the triple of the host for OpenMP device compile.
5038 if (LangOpts.OpenMPIsTargetDevice)
5040
5041 ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
5043
5044 // FIXME: Override value name discarding when asan or msan is used because the
5045 // backend passes depend on the name of the alloca in order to print out
5046 // names.
5047 Res.getCodeGenOpts().DiscardValueNames &=
5048 !LangOpts.Sanitize.has(SanitizerKind::Address) &&
5049 !LangOpts.Sanitize.has(SanitizerKind::KernelAddress) &&
5050 !LangOpts.Sanitize.has(SanitizerKind::Memory) &&
5051 !LangOpts.Sanitize.has(SanitizerKind::KernelMemory);
5052
5053 ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags,
5055 Res.getFrontendOpts());
5058
5062 if (!Res.getDependencyOutputOpts().OutputFile.empty() &&
5063 Res.getDependencyOutputOpts().Targets.empty())
5064 Diags.Report(diag::err_fe_dependency_file_requires_MT);
5065
5066 // If sanitizer is enabled, disable OPT_ffine_grained_bitfield_accesses.
5067 if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
5068 !Res.getLangOpts().Sanitize.empty()) {
5069 Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
5070 Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
5071 }
5072
5073 // Store the command-line for using in the CodeView backend.
5074 if (Res.getCodeGenOpts().CodeViewCommandLine) {
5075 Res.getCodeGenOpts().Argv0 = Argv0;
5076 append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
5077 }
5078
5079 if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty() &&
5080 Res.getCodeGenOpts().getProfileUse() ==
5081 llvm::driver::ProfileInstrKind::ProfileNone)
5082 Diags.Report(diag::err_drv_profile_instrument_use_path_with_no_kind);
5083
5084 FixupInvocation(Res, Diags, Args, DashX);
5085
5086 return Diags.getNumErrors() == NumErrorsBefore;
5087}
5088
5090 ArrayRef<const char *> CommandLineArgs,
5091 DiagnosticsEngine &Diags,
5092 const char *Argv0) {
5093 CompilerInvocation DummyInvocation;
5094
5095 return RoundTrip(
5096 [](CompilerInvocation &Invocation, ArrayRef<const char *> CommandLineArgs,
5097 DiagnosticsEngine &Diags, const char *Argv0) {
5098 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
5099 },
5101 StringAllocator SA) {
5102 Args.push_back("-cc1");
5103 Invocation.generateCC1CommandLine(Args, SA);
5104 },
5105 Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
5106}
5107
5109 // FIXME: Consider using SHA1 instead of MD5.
5110 llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
5111
5112 // Note: For QoI reasons, the things we use as a hash here should all be
5113 // dumped via the -module-info flag.
5114
5115 // Start the signature with the compiler version.
5116 HBuilder.add(getClangFullRepositoryVersion());
5117
5118 // Also include the serialization version, in case LLVM_APPEND_VC_REV is off
5119 // and getClangFullRepositoryVersion() doesn't include git revision.
5121
5122 // Extend the signature with the language options
5123 // FIXME: Replace with C++20 `using enum LangOptions::CompatibilityKind`.
5125#define LANGOPT(Name, Bits, Default, Compatibility, Description) \
5126 if constexpr (CK::Compatibility != CK::Benign) \
5127 HBuilder.add(LangOpts->Name);
5128#define ENUM_LANGOPT(Name, Type, Bits, Default, Compatibility, Description) \
5129 if constexpr (CK::Compatibility != CK::Benign) \
5130 HBuilder.add(static_cast<unsigned>(LangOpts->get##Name()));
5131#include "clang/Basic/LangOptions.def"
5132
5133 HBuilder.addRange(getLangOpts().ModuleFeatures);
5134
5135 HBuilder.add(getLangOpts().ObjCRuntime);
5136 HBuilder.addRange(getLangOpts().CommentOpts.BlockCommandNames);
5137
5138 // Extend the signature with the target options.
5139 HBuilder.add(getTargetOpts().Triple, getTargetOpts().CPU,
5140 getTargetOpts().TuneCPU, getTargetOpts().ABI);
5141 HBuilder.addRange(getTargetOpts().FeaturesAsWritten);
5142
5143 // Extend the signature with preprocessor options.
5144 const PreprocessorOptions &ppOpts = getPreprocessorOpts();
5145 HBuilder.add(ppOpts.UsePredefines, ppOpts.DetailedRecord);
5146
5147 const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
5148 for (const auto &Macro : getPreprocessorOpts().Macros) {
5149 // If we're supposed to ignore this macro for the purposes of modules,
5150 // don't put it into the hash.
5151 if (!hsOpts.ModulesIgnoreMacros.empty()) {
5152 // Check whether we're ignoring this macro.
5153 StringRef MacroDef = Macro.first;
5154 if (hsOpts.ModulesIgnoreMacros.count(
5155 llvm::CachedHashString(MacroDef.split('=').first)))
5156 continue;
5157 }
5158
5159 HBuilder.add(Macro);
5160 }
5161
5162 // Extend the signature with the sysroot and other header search options.
5163 HBuilder.add(hsOpts.Sysroot, hsOpts.ModuleFormat, hsOpts.UseDebugInfo,
5165 hsOpts.UseStandardCXXIncludes, hsOpts.UseLibcxx,
5167 HBuilder.add(hsOpts.ResourceDir);
5168
5169 if (hsOpts.ModulesStrictContextHash) {
5170 HBuilder.addRange(hsOpts.SystemHeaderPrefixes);
5171 HBuilder.addRange(hsOpts.UserEntries);
5172 HBuilder.addRange(hsOpts.VFSOverlayFiles);
5173
5174 const DiagnosticOptions &diagOpts = getDiagnosticOpts();
5175#define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name);
5176#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
5177 HBuilder.add(diagOpts.get##Name());
5178#include "clang/Basic/DiagnosticOptions.def"
5179#undef DIAGOPT
5180#undef ENUM_DIAGOPT
5181 }
5182
5183 // Extend the signature with the user build path.
5184 HBuilder.add(hsOpts.ModuleUserBuildPath);
5185
5186 // Extend the signature with the module file extensions.
5187 for (const auto &ext : getFrontendOpts().ModuleFileExtensions)
5188 ext->hashExtension(HBuilder);
5189
5190 // Extend the signature with the Swift version for API notes.
5192 if (!APINotesOpts.SwiftVersion.empty()) {
5193 HBuilder.add(APINotesOpts.SwiftVersion.getMajor());
5194 if (auto Minor = APINotesOpts.SwiftVersion.getMinor())
5195 HBuilder.add(*Minor);
5196 if (auto Subminor = APINotesOpts.SwiftVersion.getSubminor())
5197 HBuilder.add(*Subminor);
5198 if (auto Build = APINotesOpts.SwiftVersion.getBuild())
5199 HBuilder.add(*Build);
5200 }
5201
5202 // Extend the signature with affecting codegen options.
5203 {
5205#define CODEGENOPT(Name, Bits, Default, Compatibility) \
5206 if constexpr (CK::Compatibility != CK::Benign) \
5207 HBuilder.add(CodeGenOpts->Name);
5208#define ENUM_CODEGENOPT(Name, Type, Bits, Default, Compatibility) \
5209 if constexpr (CK::Compatibility != CK::Benign) \
5210 HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
5211#define DEBUGOPT(Name, Bits, Default, Compatibility)
5212#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility)
5213#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility)
5214#include "clang/Basic/CodeGenOptions.def"
5215 }
5216
5217 // When compiling with -gmodules, also hash -fdebug-prefix-map as it
5218 // affects the debug info in the PCM.
5219 if (getCodeGenOpts().DebugTypeExtRefs)
5220 HBuilder.addRange(getCodeGenOpts().DebugPrefixMap);
5221
5222 // Extend the signature with the affecting debug options.
5223 if (getHeaderSearchOpts().ModuleFormat == "obj") {
5224 // FIXME: Replace with C++20 `using enum CodeGenOptions::CompatibilityKind`.
5226#define DEBUGOPT(Name, Bits, Default, Compatibility) \
5227 if constexpr (CK::Compatibility != CK::Benign) \
5228 HBuilder.add(CodeGenOpts->Name);
5229#define VALUE_DEBUGOPT(Name, Bits, Default, Compatibility) \
5230 if constexpr (CK::Compatibility != CK::Benign) \
5231 HBuilder.add(CodeGenOpts->Name);
5232#define ENUM_DEBUGOPT(Name, Type, Bits, Default, Compatibility) \
5233 if constexpr (CK::Compatibility != CK::Benign) \
5234 HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
5235#include "clang/Basic/DebugOptions.def"
5236 }
5237
5238 // Extend the signature with the enabled sanitizers, if at least one is
5239 // enabled. Sanitizers which cannot affect AST generation aren't hashed.
5240 SanitizerSet SanHash = getLangOpts().Sanitize;
5242 if (!SanHash.empty())
5243 HBuilder.add(SanHash.Mask);
5244
5245 llvm::MD5::MD5Result Result;
5246 HBuilder.getHasher().final(Result);
5247 uint64_t Hash = Result.high() ^ Result.low();
5248 return toString(llvm::APInt(64, Hash), 36, /*Signed=*/false);
5249}
5250
5252 ArgumentConsumer Consumer) const {
5253 llvm::Triple T(getTargetOpts().Triple);
5254
5258 GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer,
5259 /*DefaultDiagColor=*/false);
5260 GenerateFrontendArgs(getFrontendOpts(), Consumer, getLangOpts().IsHeaderFile);
5261 GenerateTargetArgs(getTargetOpts(), Consumer);
5265 GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX);
5266 GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T,
5267 getFrontendOpts().OutputFile, &getLangOpts());
5271 getFrontendOpts().ProgramAction);
5273}
5274
5275std::vector<std::string> CompilerInvocationBase::getCC1CommandLine() const {
5276 std::vector<std::string> Args{"-cc1"};
5278 [&Args](const Twine &Arg) { Args.push_back(Arg.str()); });
5279 return Args;
5280}
5281
5287
5289 getLangOpts().ImplicitModules = false;
5294 // The specific values we canonicalize to for pruning don't affect behaviour,
5295 /// so use the default values so they may be dropped from the command-line.
5296 getHeaderSearchOpts().ModuleCachePruneInterval = 7 * 24 * 60 * 60;
5297 getHeaderSearchOpts().ModuleCachePruneAfter = 31 * 24 * 60 * 60;
5298}
5299
5302 DiagnosticsEngine &Diags) {
5303 return createVFSFromCompilerInvocation(CI, Diags,
5304 llvm::vfs::getRealFileSystem());
5305}
5306
5314
5316 ArrayRef<std::string> VFSOverlayFiles, DiagnosticsEngine &Diags,
5318 if (VFSOverlayFiles.empty())
5319 return BaseFS;
5320
5322 // earlier vfs files are on the bottom
5323 for (const auto &File : VFSOverlayFiles) {
5324 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
5325 Result->getBufferForFile(File);
5326 if (!Buffer) {
5327 Diags.Report(diag::err_missing_vfs_overlay_file) << File;
5328 continue;
5329 }
5330
5331 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = llvm::vfs::getVFSFromYAML(
5332 std::move(Buffer.get()), /*DiagHandler*/ nullptr, File,
5333 /*DiagContext*/ nullptr, Result);
5334 if (!FS) {
5335 Diags.Report(diag::err_invalid_vfs_overlay) << File;
5336 continue;
5337 }
5338
5339 Result = FS;
5340 }
5341 return Result;
5342}
#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.
std::optional< uint64_t > AllocTokenMax
Maximum number of allocation tokens (0 = no max), nullopt if none set (use pass default).
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
unsigned long uint64_t
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