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