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