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