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