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