clang 20.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 auto Default = PositiveAnalyzerOption::create(DefaultVal);
1278 assert(Default.has_value());
1279 OptionField = Default.value();
1280}
1281
1283 DiagnosticsEngine *Diags) {
1284 // TODO: There's no need to store the entire configtable, it'd be plenty
1285 // enough to store checker options.
1286
1287#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \
1288 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEFAULT_VAL);
1289#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(...)
1290#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1291
1292 assert(AnOpts.UserMode == "shallow" || AnOpts.UserMode == "deep");
1293 const bool InShallowMode = AnOpts.UserMode == "shallow";
1294
1295#define ANALYZER_OPTION(...)
1296#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \
1297 SHALLOW_VAL, DEEP_VAL) \
1298 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, \
1299 InShallowMode ? SHALLOW_VAL : DEEP_VAL);
1300#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
1301
1302 // At this point, AnalyzerOptions is configured. Let's validate some options.
1303
1304 // FIXME: Here we try to validate the silenced checkers or packages are valid.
1305 // The current approach only validates the registered checkers which does not
1306 // contain the runtime enabled checkers and optimally we would validate both.
1307 if (!AnOpts.RawSilencedCheckersAndPackages.empty()) {
1308 std::vector<StringRef> Checkers =
1309 AnOpts.getRegisteredCheckers(/*IncludeExperimental=*/true);
1310 std::vector<StringRef> Packages =
1311 AnOpts.getRegisteredPackages(/*IncludeExperimental=*/true);
1312
1313 SmallVector<StringRef, 16> CheckersAndPackages;
1314 AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages, ";");
1315
1316 for (const StringRef &CheckerOrPackage : CheckersAndPackages) {
1317 if (Diags) {
1318 bool IsChecker = CheckerOrPackage.contains('.');
1319 bool IsValidName = IsChecker
1320 ? llvm::is_contained(Checkers, CheckerOrPackage)
1321 : llvm::is_contained(Packages, CheckerOrPackage);
1322
1323 if (!IsValidName)
1324 Diags->Report(diag::err_unknown_analyzer_checker_or_package)
1325 << CheckerOrPackage;
1326 }
1327
1328 AnOpts.SilencedCheckersAndPackages.emplace_back(CheckerOrPackage);
1329 }
1330 }
1331
1332 if (!Diags)
1333 return;
1334
1335 if (AnOpts.ShouldTrackConditionsDebug && !AnOpts.ShouldTrackConditions)
1336 Diags->Report(diag::err_analyzer_config_invalid_input)
1337 << "track-conditions-debug" << "'track-conditions' to also be enabled";
1338
1339 if (!AnOpts.CTUDir.empty() && !llvm::sys::fs::is_directory(AnOpts.CTUDir))
1340 Diags->Report(diag::err_analyzer_config_invalid_input) << "ctu-dir"
1341 << "a filename";
1342
1343 if (!AnOpts.ModelPath.empty() &&
1344 !llvm::sys::fs::is_directory(AnOpts.ModelPath))
1345 Diags->Report(diag::err_analyzer_config_invalid_input) << "model-path"
1346 << "a filename";
1347}
1348
1349/// Generate a remark argument. This is an inverse of `ParseOptimizationRemark`.
1350static void
1352 StringRef Name,
1354 if (Remark.hasValidPattern()) {
1355 GenerateArg(Consumer, OptEQ, Remark.Pattern);
1356 } else if (Remark.Kind == CodeGenOptions::RK_Enabled) {
1357 GenerateArg(Consumer, OPT_R_Joined, Name);
1358 } else if (Remark.Kind == CodeGenOptions::RK_Disabled) {
1359 GenerateArg(Consumer, OPT_R_Joined, StringRef("no-") + Name);
1360 }
1361}
1362
1363/// Parse a remark command line argument. It may be missing, disabled/enabled by
1364/// '-R[no-]group' or specified with a regular expression by '-Rgroup=regexp'.
1365/// On top of that, it can be disabled/enabled globally by '-R[no-]everything'.
1368 OptSpecifier OptEQ, StringRef Name) {
1370
1371 auto InitializeResultPattern = [&Diags, &Args, &Result](const Arg *A,
1372 StringRef Pattern) {
1373 Result.Pattern = Pattern.str();
1374
1375 std::string RegexError;
1376 Result.Regex = std::make_shared<llvm::Regex>(Result.Pattern);
1377 if (!Result.Regex->isValid(RegexError)) {
1378 Diags.Report(diag::err_drv_optimization_remark_pattern)
1379 << RegexError << A->getAsString(Args);
1380 return false;
1381 }
1382
1383 return true;
1384 };
1385
1386 for (Arg *A : Args) {
1387 if (A->getOption().matches(OPT_R_Joined)) {
1388 StringRef Value = A->getValue();
1389
1390 if (Value == Name)
1392 else if (Value == "everything")
1394 else if (Value.split('-') == std::make_pair(StringRef("no"), Name))
1396 else if (Value == "no-everything")
1398 else
1399 continue;
1400
1401 if (Result.Kind == CodeGenOptions::RK_Disabled ||
1403 Result.Pattern = "";
1404 Result.Regex = nullptr;
1405 } else {
1406 InitializeResultPattern(A, ".*");
1407 }
1408 } else if (A->getOption().matches(OptEQ)) {
1410 if (!InitializeResultPattern(A, A->getValue()))
1412 }
1413 }
1414
1415 return Result;
1416}
1417
1418static bool parseDiagnosticLevelMask(StringRef FlagName,
1419 const std::vector<std::string> &Levels,
1420 DiagnosticsEngine &Diags,
1422 bool Success = true;
1423 for (const auto &Level : Levels) {
1424 DiagnosticLevelMask const PM =
1425 llvm::StringSwitch<DiagnosticLevelMask>(Level)
1426 .Case("note", DiagnosticLevelMask::Note)
1427 .Case("remark", DiagnosticLevelMask::Remark)
1428 .Case("warning", DiagnosticLevelMask::Warning)
1429 .Case("error", DiagnosticLevelMask::Error)
1430 .Default(DiagnosticLevelMask::None);
1431 if (PM == DiagnosticLevelMask::None) {
1432 Success = false;
1433 Diags.Report(diag::err_drv_invalid_value) << FlagName << Level;
1434 }
1435 M = M | PM;
1436 }
1437 return Success;
1438}
1439
1440static void parseSanitizerKinds(StringRef FlagName,
1441 const std::vector<std::string> &Sanitizers,
1442 DiagnosticsEngine &Diags, SanitizerSet &S) {
1443 for (const auto &Sanitizer : Sanitizers) {
1444 SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false);
1445 if (K == SanitizerMask())
1446 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;
1447 else
1448 S.set(K, true);
1449 }
1450}
1451
1454 serializeSanitizerSet(S, Values);
1455 return Values;
1456}
1457
1458static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle,
1459 ArgList &Args, DiagnosticsEngine &D,
1460 XRayInstrSet &S) {
1462 llvm::SplitString(Bundle, BundleParts, ",");
1463 for (const auto &B : BundleParts) {
1464 auto Mask = parseXRayInstrValue(B);
1465 if (Mask == XRayInstrKind::None)
1466 if (B != "none")
1467 D.Report(diag::err_drv_invalid_value) << FlagName << Bundle;
1468 else
1469 S.Mask = Mask;
1470 else if (Mask == XRayInstrKind::All)
1471 S.Mask = Mask;
1472 else
1473 S.set(Mask, true);
1474 }
1475}
1476
1479 serializeXRayInstrValue(S, BundleParts);
1480 std::string Buffer;
1481 llvm::raw_string_ostream OS(Buffer);
1482 llvm::interleave(BundleParts, OS, [&OS](StringRef Part) { OS << Part; }, ",");
1483 return Buffer;
1484}
1485
1486// Set the profile kind using fprofile-instrument-use-path.
1488 const Twine &ProfileName,
1489 llvm::vfs::FileSystem &FS,
1490 DiagnosticsEngine &Diags) {
1491 auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName, FS);
1492 if (auto E = ReaderOrErr.takeError()) {
1493 unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error,
1494 "Error in reading profile %0: %1");
1495 llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {
1496 Diags.Report(DiagID) << ProfileName.str() << EI.message();
1497 });
1498 return;
1499 }
1500 std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader =
1501 std::move(ReaderOrErr.get());
1502 // Currently memprof profiles are only added at the IR level. Mark the profile
1503 // type as IR in that case as well and the subsequent matching needs to detect
1504 // which is available (might be one or both).
1505 if (PGOReader->isIRLevelProfile() || PGOReader->hasMemoryProfile()) {
1506 if (PGOReader->hasCSIRLevelProfile())
1507 Opts.setProfileUse(CodeGenOptions::ProfileCSIRInstr);
1508 else
1509 Opts.setProfileUse(CodeGenOptions::ProfileIRInstr);
1510 } else
1511 Opts.setProfileUse(CodeGenOptions::ProfileClangInstr);
1512}
1513
1515 PointerAuthOptions &Opts, const LangOptions &LangOpts,
1516 const llvm::Triple &Triple) {
1517 assert(Triple.getArch() == llvm::Triple::aarch64);
1518 if (LangOpts.PointerAuthCalls) {
1519 using Key = PointerAuthSchema::ARM8_3Key;
1520 using Discrimination = PointerAuthSchema::Discrimination;
1521 // If you change anything here, be sure to update <ptrauth.h>.
1523 Key::ASIA, false,
1524 LangOpts.PointerAuthFunctionTypeDiscrimination ? Discrimination::Type
1525 : Discrimination::None);
1526
1528 Key::ASDA, LangOpts.PointerAuthVTPtrAddressDiscrimination,
1529 LangOpts.PointerAuthVTPtrTypeDiscrimination ? Discrimination::Type
1530 : Discrimination::None);
1531
1532 if (LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)
1534 PointerAuthSchema(Key::ASDA, true, Discrimination::Constant,
1536 else
1538 PointerAuthSchema(Key::ASDA, false, Discrimination::None);
1539
1541 PointerAuthSchema(Key::ASDA, false, Discrimination::None);
1543 PointerAuthSchema(Key::ASIA, true, Discrimination::Decl);
1545 PointerAuthSchema(Key::ASIA, false, Discrimination::Type);
1546
1547 if (LangOpts.PointerAuthInitFini) {
1549 Key::ASIA, LangOpts.PointerAuthInitFiniAddressDiscrimination,
1550 Discrimination::Constant, InitFiniPointerConstantDiscriminator);
1551 }
1552 }
1553 Opts.ReturnAddresses = LangOpts.PointerAuthReturns;
1554 Opts.AuthTraps = LangOpts.PointerAuthAuthTraps;
1555 Opts.IndirectGotos = LangOpts.PointerAuthIndirectGotos;
1556 Opts.AArch64JumpTableHardening = LangOpts.AArch64JumpTableHardening;
1557}
1558
1560 const LangOptions &LangOpts,
1561 const llvm::Triple &Triple,
1562 DiagnosticsEngine &Diags) {
1563 if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthReturns &&
1564 !LangOpts.PointerAuthAuthTraps && !LangOpts.PointerAuthIndirectGotos &&
1565 !LangOpts.AArch64JumpTableHardening)
1566 return;
1567
1569}
1570
1571void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,
1572 ArgumentConsumer Consumer,
1573 const llvm::Triple &T,
1574 const std::string &OutputFile,
1575 const LangOptions *LangOpts) {
1576 const CodeGenOptions &CodeGenOpts = Opts;
1577
1578 if (Opts.OptimizationLevel == 0)
1579 GenerateArg(Consumer, OPT_O0);
1580 else
1581 GenerateArg(Consumer, OPT_O, Twine(Opts.OptimizationLevel));
1582
1583#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1584 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
1585#include "clang/Driver/Options.inc"
1586#undef CODEGEN_OPTION_WITH_MARSHALLING
1587
1588 if (Opts.OptimizationLevel > 0) {
1589 if (Opts.Inlining == CodeGenOptions::NormalInlining)
1590 GenerateArg(Consumer, OPT_finline_functions);
1591 else if (Opts.Inlining == CodeGenOptions::OnlyHintInlining)
1592 GenerateArg(Consumer, OPT_finline_hint_functions);
1593 else if (Opts.Inlining == CodeGenOptions::OnlyAlwaysInlining)
1594 GenerateArg(Consumer, OPT_fno_inline);
1595 }
1596
1597 if (Opts.DirectAccessExternalData && LangOpts->PICLevel != 0)
1598 GenerateArg(Consumer, OPT_fdirect_access_external_data);
1599 else if (!Opts.DirectAccessExternalData && LangOpts->PICLevel == 0)
1600 GenerateArg(Consumer, OPT_fno_direct_access_external_data);
1601
1602 std::optional<StringRef> DebugInfoVal;
1603 switch (Opts.DebugInfo) {
1604 case llvm::codegenoptions::DebugLineTablesOnly:
1605 DebugInfoVal = "line-tables-only";
1606 break;
1607 case llvm::codegenoptions::DebugDirectivesOnly:
1608 DebugInfoVal = "line-directives-only";
1609 break;
1610 case llvm::codegenoptions::DebugInfoConstructor:
1611 DebugInfoVal = "constructor";
1612 break;
1613 case llvm::codegenoptions::LimitedDebugInfo:
1614 DebugInfoVal = "limited";
1615 break;
1616 case llvm::codegenoptions::FullDebugInfo:
1617 DebugInfoVal = "standalone";
1618 break;
1619 case llvm::codegenoptions::UnusedTypeInfo:
1620 DebugInfoVal = "unused-types";
1621 break;
1622 case llvm::codegenoptions::NoDebugInfo: // default value
1623 DebugInfoVal = std::nullopt;
1624 break;
1625 case llvm::codegenoptions::LocTrackingOnly: // implied value
1626 DebugInfoVal = std::nullopt;
1627 break;
1628 }
1629 if (DebugInfoVal)
1630 GenerateArg(Consumer, OPT_debug_info_kind_EQ, *DebugInfoVal);
1631
1632 for (const auto &Prefix : Opts.DebugPrefixMap)
1633 GenerateArg(Consumer, OPT_fdebug_prefix_map_EQ,
1634 Prefix.first + "=" + Prefix.second);
1635
1636 for (const auto &Prefix : Opts.CoveragePrefixMap)
1637 GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,
1638 Prefix.first + "=" + Prefix.second);
1639
1640 if (Opts.NewStructPathTBAA)
1641 GenerateArg(Consumer, OPT_new_struct_path_tbaa);
1642
1643 if (Opts.OptimizeSize == 1)
1644 GenerateArg(Consumer, OPT_O, "s");
1645 else if (Opts.OptimizeSize == 2)
1646 GenerateArg(Consumer, OPT_O, "z");
1647
1648 // SimplifyLibCalls is set only in the absence of -fno-builtin and
1649 // -ffreestanding. We'll consider that when generating them.
1650
1651 // NoBuiltinFuncs are generated by LangOptions.
1652
1653 if (Opts.UnrollLoops && Opts.OptimizationLevel <= 1)
1654 GenerateArg(Consumer, OPT_funroll_loops);
1655 else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1)
1656 GenerateArg(Consumer, OPT_fno_unroll_loops);
1657
1658 if (!Opts.BinutilsVersion.empty())
1659 GenerateArg(Consumer, OPT_fbinutils_version_EQ, Opts.BinutilsVersion);
1660
1661 if (Opts.DebugNameTable ==
1662 static_cast<unsigned>(llvm::DICompileUnit::DebugNameTableKind::GNU))
1663 GenerateArg(Consumer, OPT_ggnu_pubnames);
1664 else if (Opts.DebugNameTable ==
1665 static_cast<unsigned>(
1666 llvm::DICompileUnit::DebugNameTableKind::Default))
1667 GenerateArg(Consumer, OPT_gpubnames);
1668
1669 if (Opts.DebugTemplateAlias)
1670 GenerateArg(Consumer, OPT_gtemplate_alias);
1671
1672 auto TNK = Opts.getDebugSimpleTemplateNames();
1673 if (TNK != llvm::codegenoptions::DebugTemplateNamesKind::Full) {
1674 if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Simple)
1675 GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "simple");
1676 else if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Mangled)
1677 GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "mangled");
1678 }
1679 // ProfileInstrumentUsePath is marshalled automatically, no need to generate
1680 // it or PGOUseInstrumentor.
1681
1682 if (Opts.TimePasses) {
1683 if (Opts.TimePassesPerRun)
1684 GenerateArg(Consumer, OPT_ftime_report_EQ, "per-pass-run");
1685 else
1686 GenerateArg(Consumer, OPT_ftime_report);
1687 }
1688
1689 if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)
1690 GenerateArg(Consumer, OPT_flto_EQ, "full");
1691
1692 if (Opts.PrepareForThinLTO)
1693 GenerateArg(Consumer, OPT_flto_EQ, "thin");
1694
1695 if (!Opts.ThinLTOIndexFile.empty())
1696 GenerateArg(Consumer, OPT_fthinlto_index_EQ, Opts.ThinLTOIndexFile);
1697
1698 if (Opts.SaveTempsFilePrefix == OutputFile)
1699 GenerateArg(Consumer, OPT_save_temps_EQ, "obj");
1700
1701 StringRef MemProfileBasename("memprof.profraw");
1702 if (!Opts.MemoryProfileOutput.empty()) {
1703 if (Opts.MemoryProfileOutput == MemProfileBasename) {
1704 GenerateArg(Consumer, OPT_fmemory_profile);
1705 } else {
1706 size_t ArgLength =
1707 Opts.MemoryProfileOutput.size() - MemProfileBasename.size();
1708 GenerateArg(Consumer, OPT_fmemory_profile_EQ,
1709 Opts.MemoryProfileOutput.substr(0, ArgLength));
1710 }
1711 }
1712
1713 if (memcmp(Opts.CoverageVersion, "0000", 4))
1714 GenerateArg(Consumer, OPT_coverage_version_EQ,
1715 StringRef(Opts.CoverageVersion, 4));
1716
1717 // TODO: Check if we need to generate arguments stored in CmdArgs. (Namely
1718 // '-fembed_bitcode', which does not map to any CompilerInvocation field and
1719 // won't be generated.)
1720
1722 std::string InstrBundle =
1724 if (!InstrBundle.empty())
1725 GenerateArg(Consumer, OPT_fxray_instrumentation_bundle, InstrBundle);
1726 }
1727
1728 if (Opts.CFProtectionReturn && Opts.CFProtectionBranch)
1729 GenerateArg(Consumer, OPT_fcf_protection_EQ, "full");
1730 else if (Opts.CFProtectionReturn)
1731 GenerateArg(Consumer, OPT_fcf_protection_EQ, "return");
1732 else if (Opts.CFProtectionBranch)
1733 GenerateArg(Consumer, OPT_fcf_protection_EQ, "branch");
1734
1735 if (Opts.CFProtectionBranch) {
1736 switch (Opts.getCFBranchLabelScheme()) {
1738 break;
1739#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
1740 case CFBranchLabelSchemeKind::Kind: \
1741 GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, #FlagVal); \
1742 break;
1743#include "clang/Basic/CFProtectionOptions.def"
1744 }
1745 }
1746
1747 if (Opts.FunctionReturnThunks)
1748 GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern");
1749
1750 for (const auto &F : Opts.LinkBitcodeFiles) {
1751 bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded &&
1752 F.PropagateAttrs && F.Internalize;
1753 GenerateArg(Consumer,
1754 Builtint ? OPT_mlink_builtin_bitcode : OPT_mlink_bitcode_file,
1755 F.Filename);
1756 }
1757
1758 if (Opts.EmulatedTLS)
1759 GenerateArg(Consumer, OPT_femulated_tls);
1760
1761 if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE())
1762 GenerateArg(Consumer, OPT_fdenormal_fp_math_EQ, Opts.FPDenormalMode.str());
1763
1764 if ((Opts.FPDenormalMode != Opts.FP32DenormalMode) ||
1765 (Opts.FP32DenormalMode != llvm::DenormalMode::getIEEE()))
1766 GenerateArg(Consumer, OPT_fdenormal_fp_math_f32_EQ,
1767 Opts.FP32DenormalMode.str());
1768
1769 if (Opts.StructReturnConvention == CodeGenOptions::SRCK_OnStack) {
1770 OptSpecifier Opt =
1771 T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return;
1772 GenerateArg(Consumer, Opt);
1773 } else if (Opts.StructReturnConvention == CodeGenOptions::SRCK_InRegs) {
1774 OptSpecifier Opt =
1775 T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return;
1776 GenerateArg(Consumer, Opt);
1777 }
1778
1779 if (Opts.EnableAIXExtendedAltivecABI)
1780 GenerateArg(Consumer, OPT_mabi_EQ_vec_extabi);
1781
1782 if (Opts.XCOFFReadOnlyPointers)
1783 GenerateArg(Consumer, OPT_mxcoff_roptr);
1784
1785 if (!Opts.OptRecordPasses.empty())
1786 GenerateArg(Consumer, OPT_opt_record_passes, Opts.OptRecordPasses);
1787
1788 if (!Opts.OptRecordFormat.empty())
1789 GenerateArg(Consumer, OPT_opt_record_format, Opts.OptRecordFormat);
1790
1791 GenerateOptimizationRemark(Consumer, OPT_Rpass_EQ, "pass",
1792 Opts.OptimizationRemark);
1793
1794 GenerateOptimizationRemark(Consumer, OPT_Rpass_missed_EQ, "pass-missed",
1796
1797 GenerateOptimizationRemark(Consumer, OPT_Rpass_analysis_EQ, "pass-analysis",
1799
1800 GenerateArg(Consumer, OPT_fdiagnostics_hotness_threshold_EQ,
1802 ? Twine(*Opts.DiagnosticsHotnessThreshold)
1803 : "auto");
1804
1805 GenerateArg(Consumer, OPT_fdiagnostics_misexpect_tolerance_EQ,
1806 Twine(*Opts.DiagnosticsMisExpectTolerance));
1807
1808 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeRecover))
1809 GenerateArg(Consumer, OPT_fsanitize_recover_EQ, Sanitizer);
1810
1811 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.SanitizeTrap))
1812 GenerateArg(Consumer, OPT_fsanitize_trap_EQ, Sanitizer);
1813
1814 for (StringRef Sanitizer :
1816 GenerateArg(Consumer, OPT_fsanitize_merge_handlers_EQ, Sanitizer);
1817
1818 if (!Opts.EmitVersionIdentMetadata)
1819 GenerateArg(Consumer, OPT_Qn);
1820
1821 switch (Opts.FiniteLoops) {
1823 break;
1825 GenerateArg(Consumer, OPT_ffinite_loops);
1826 break;
1828 GenerateArg(Consumer, OPT_fno_finite_loops);
1829 break;
1830 }
1831}
1832
1833bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,
1834 InputKind IK,
1835 DiagnosticsEngine &Diags,
1836 const llvm::Triple &T,
1837 const std::string &OutputFile,
1838 const LangOptions &LangOptsRef) {
1839 unsigned NumErrorsBefore = Diags.getNumErrors();
1840
1841 unsigned OptimizationLevel = getOptimizationLevel(Args, IK, Diags);
1842 // TODO: This could be done in Driver
1843 unsigned MaxOptLevel = 3;
1844 if (OptimizationLevel > MaxOptLevel) {
1845 // If the optimization level is not supported, fall back on the default
1846 // optimization
1847 Diags.Report(diag::warn_drv_optimization_value)
1848 << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;
1849 OptimizationLevel = MaxOptLevel;
1850 }
1851 Opts.OptimizationLevel = OptimizationLevel;
1852
1853 // The key paths of codegen options defined in Options.td start with
1854 // "CodeGenOpts.". Let's provide the expected variable name and type.
1856 // Some codegen options depend on language options. Let's provide the expected
1857 // variable name and type.
1858 const LangOptions *LangOpts = &LangOptsRef;
1859
1860#define CODEGEN_OPTION_WITH_MARSHALLING(...) \
1861 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
1862#include "clang/Driver/Options.inc"
1863#undef CODEGEN_OPTION_WITH_MARSHALLING
1864
1865 // At O0 we want to fully disable inlining outside of cases marked with
1866 // 'alwaysinline' that are required for correctness.
1867 if (Opts.OptimizationLevel == 0) {
1868 Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
1869 } else if (const Arg *A = Args.getLastArg(options::OPT_finline_functions,
1870 options::OPT_finline_hint_functions,
1871 options::OPT_fno_inline_functions,
1872 options::OPT_fno_inline)) {
1873 // Explicit inlining flags can disable some or all inlining even at
1874 // optimization levels above zero.
1875 if (A->getOption().matches(options::OPT_finline_functions))
1876 Opts.setInlining(CodeGenOptions::NormalInlining);
1877 else if (A->getOption().matches(options::OPT_finline_hint_functions))
1878 Opts.setInlining(CodeGenOptions::OnlyHintInlining);
1879 else
1880 Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
1881 } else {
1882 Opts.setInlining(CodeGenOptions::NormalInlining);
1883 }
1884
1885 // PIC defaults to -fno-direct-access-external-data while non-PIC defaults to
1886 // -fdirect-access-external-data.
1887 Opts.DirectAccessExternalData =
1888 Args.hasArg(OPT_fdirect_access_external_data) ||
1889 (!Args.hasArg(OPT_fno_direct_access_external_data) &&
1890 LangOpts->PICLevel == 0);
1891
1892 if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {
1893 unsigned Val =
1894 llvm::StringSwitch<unsigned>(A->getValue())
1895 .Case("line-tables-only", llvm::codegenoptions::DebugLineTablesOnly)
1896 .Case("line-directives-only",
1897 llvm::codegenoptions::DebugDirectivesOnly)
1898 .Case("constructor", llvm::codegenoptions::DebugInfoConstructor)
1899 .Case("limited", llvm::codegenoptions::LimitedDebugInfo)
1900 .Case("standalone", llvm::codegenoptions::FullDebugInfo)
1901 .Case("unused-types", llvm::codegenoptions::UnusedTypeInfo)
1902 .Default(~0U);
1903 if (Val == ~0U)
1904 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
1905 << A->getValue();
1906 else
1907 Opts.setDebugInfo(static_cast<llvm::codegenoptions::DebugInfoKind>(Val));
1908 }
1909
1910 // If -fuse-ctor-homing is set and limited debug info is already on, then use
1911 // constructor homing, and vice versa for -fno-use-ctor-homing.
1912 if (const Arg *A =
1913 Args.getLastArg(OPT_fuse_ctor_homing, OPT_fno_use_ctor_homing)) {
1914 if (A->getOption().matches(OPT_fuse_ctor_homing) &&
1915 Opts.getDebugInfo() == llvm::codegenoptions::LimitedDebugInfo)
1916 Opts.setDebugInfo(llvm::codegenoptions::DebugInfoConstructor);
1917 if (A->getOption().matches(OPT_fno_use_ctor_homing) &&
1918 Opts.getDebugInfo() == llvm::codegenoptions::DebugInfoConstructor)
1919 Opts.setDebugInfo(llvm::codegenoptions::LimitedDebugInfo);
1920 }
1921
1922 for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) {
1923 auto Split = StringRef(Arg).split('=');
1924 Opts.DebugPrefixMap.emplace_back(Split.first, Split.second);
1925 }
1926
1927 for (const auto &Arg : Args.getAllArgValues(OPT_fcoverage_prefix_map_EQ)) {
1928 auto Split = StringRef(Arg).split('=');
1929 Opts.CoveragePrefixMap.emplace_back(Split.first, Split.second);
1930 }
1931
1932 const llvm::Triple::ArchType DebugEntryValueArchs[] = {
1933 llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64,
1934 llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips,
1935 llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el};
1936
1937 if (Opts.OptimizationLevel > 0 && Opts.hasReducedDebugInfo() &&
1938 llvm::is_contained(DebugEntryValueArchs, T.getArch()))
1939 Opts.EmitCallSiteInfo = true;
1940
1941 if (!Opts.EnableDIPreservationVerify && Opts.DIBugsReportFilePath.size()) {
1942 Diags.Report(diag::warn_ignoring_verify_debuginfo_preserve_export)
1943 << Opts.DIBugsReportFilePath;
1944 Opts.DIBugsReportFilePath = "";
1945 }
1946
1947 Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&
1948 Args.hasArg(OPT_new_struct_path_tbaa);
1949 Opts.OptimizeSize = getOptimizationLevelSize(Args);
1950 Opts.SimplifyLibCalls = !LangOpts->NoBuiltin;
1951 if (Opts.SimplifyLibCalls)
1952 Opts.NoBuiltinFuncs = LangOpts->NoBuiltinFuncs;
1953 Opts.UnrollLoops =
1954 Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,
1955 (Opts.OptimizationLevel > 1));
1956 Opts.BinutilsVersion =
1957 std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));
1958
1959 Opts.DebugTemplateAlias = Args.hasArg(OPT_gtemplate_alias);
1960
1961 Opts.DebugNameTable = static_cast<unsigned>(
1962 Args.hasArg(OPT_ggnu_pubnames)
1963 ? llvm::DICompileUnit::DebugNameTableKind::GNU
1964 : Args.hasArg(OPT_gpubnames)
1965 ? llvm::DICompileUnit::DebugNameTableKind::Default
1966 : llvm::DICompileUnit::DebugNameTableKind::None);
1967 if (const Arg *A = Args.getLastArg(OPT_gsimple_template_names_EQ)) {
1968 StringRef Value = A->getValue();
1969 if (Value != "simple" && Value != "mangled")
1970 Diags.Report(diag::err_drv_unsupported_option_argument)
1971 << A->getSpelling() << A->getValue();
1972 Opts.setDebugSimpleTemplateNames(
1973 StringRef(A->getValue()) == "simple"
1974 ? llvm::codegenoptions::DebugTemplateNamesKind::Simple
1975 : llvm::codegenoptions::DebugTemplateNamesKind::Mangled);
1976 }
1977
1978 if (const Arg *A = Args.getLastArg(OPT_ftime_report, OPT_ftime_report_EQ)) {
1979 Opts.TimePasses = true;
1980
1981 // -ftime-report= is only for new pass manager.
1982 if (A->getOption().getID() == OPT_ftime_report_EQ) {
1983 StringRef Val = A->getValue();
1984 if (Val == "per-pass")
1985 Opts.TimePassesPerRun = false;
1986 else if (Val == "per-pass-run")
1987 Opts.TimePassesPerRun = true;
1988 else
1989 Diags.Report(diag::err_drv_invalid_value)
1990 << A->getAsString(Args) << A->getValue();
1991 }
1992 }
1993
1994 Opts.PrepareForLTO = false;
1995 Opts.PrepareForThinLTO = false;
1996 if (Arg *A = Args.getLastArg(OPT_flto_EQ)) {
1997 Opts.PrepareForLTO = true;
1998 StringRef S = A->getValue();
1999 if (S == "thin")
2000 Opts.PrepareForThinLTO = true;
2001 else if (S != "full")
2002 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;
2003 if (Args.hasArg(OPT_funified_lto))
2004 Opts.PrepareForThinLTO = true;
2005 }
2006 if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {
2007 if (IK.getLanguage() != Language::LLVM_IR)
2008 Diags.Report(diag::err_drv_argument_only_allowed_with)
2009 << A->getAsString(Args) << "-x ir";
2010 Opts.ThinLTOIndexFile =
2011 std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ));
2012 }
2013 if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))
2014 Opts.SaveTempsFilePrefix =
2015 llvm::StringSwitch<std::string>(A->getValue())
2016 .Case("obj", OutputFile)
2017 .Default(llvm::sys::path::filename(OutputFile).str());
2018
2019 // The memory profile runtime appends the pid to make this name more unique.
2020 const char *MemProfileBasename = "memprof.profraw";
2021 if (Args.hasArg(OPT_fmemory_profile_EQ)) {
2023 std::string(Args.getLastArgValue(OPT_fmemory_profile_EQ)));
2024 llvm::sys::path::append(Path, MemProfileBasename);
2025 Opts.MemoryProfileOutput = std::string(Path);
2026 } else if (Args.hasArg(OPT_fmemory_profile))
2027 Opts.MemoryProfileOutput = MemProfileBasename;
2028
2029 if (Opts.CoverageNotesFile.size() || Opts.CoverageDataFile.size()) {
2030 if (Args.hasArg(OPT_coverage_version_EQ)) {
2031 StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
2032 if (CoverageVersion.size() != 4) {
2033 Diags.Report(diag::err_drv_invalid_value)
2034 << Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)
2035 << CoverageVersion;
2036 } else {
2037 memcpy(Opts.CoverageVersion, CoverageVersion.data(), 4);
2038 }
2039 }
2040 }
2041 // FIXME: For backend options that are not yet recorded as function
2042 // attributes in the IR, keep track of them so we can embed them in a
2043 // separate data section and use them when building the bitcode.
2044 for (const auto &A : Args) {
2045 // Do not encode output and input.
2046 if (A->getOption().getID() == options::OPT_o ||
2047 A->getOption().getID() == options::OPT_INPUT ||
2048 A->getOption().getID() == options::OPT_x ||
2049 A->getOption().getID() == options::OPT_fembed_bitcode ||
2050 A->getOption().matches(options::OPT_W_Group))
2051 continue;
2052 ArgStringList ASL;
2053 A->render(Args, ASL);
2054 for (const auto &arg : ASL) {
2055 StringRef ArgStr(arg);
2056 Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end());
2057 // using \00 to separate each commandline options.
2058 Opts.CmdArgs.push_back('\0');
2059 }
2060 }
2061
2062 auto XRayInstrBundles =
2063 Args.getAllArgValues(OPT_fxray_instrumentation_bundle);
2064 if (XRayInstrBundles.empty())
2066 else
2067 for (const auto &A : XRayInstrBundles)
2068 parseXRayInstrumentationBundle("-fxray-instrumentation-bundle=", A, Args,
2069 Diags, Opts.XRayInstrumentationBundle);
2070
2071 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
2072 StringRef Name = A->getValue();
2073 if (Name == "full") {
2074 Opts.CFProtectionReturn = 1;
2075 Opts.CFProtectionBranch = 1;
2076 } else if (Name == "return")
2077 Opts.CFProtectionReturn = 1;
2078 else if (Name == "branch")
2079 Opts.CFProtectionBranch = 1;
2080 else if (Name != "none")
2081 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
2082 }
2083
2084 if (Opts.CFProtectionBranch && T.isRISCV()) {
2085 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
2086 const auto Scheme =
2087 llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
2088#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
2089 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
2090#include "clang/Basic/CFProtectionOptions.def"
2093 Opts.setCFBranchLabelScheme(Scheme);
2094 else
2095 Diags.Report(diag::err_drv_invalid_value)
2096 << A->getAsString(Args) << A->getValue();
2097 }
2098 }
2099
2100 if (const Arg *A = Args.getLastArg(OPT_mfunction_return_EQ)) {
2101 auto Val = llvm::StringSwitch<llvm::FunctionReturnThunksKind>(A->getValue())
2102 .Case("keep", llvm::FunctionReturnThunksKind::Keep)
2103 .Case("thunk-extern", llvm::FunctionReturnThunksKind::Extern)
2104 .Default(llvm::FunctionReturnThunksKind::Invalid);
2105 // SystemZ might want to add support for "expolines."
2106 if (!T.isX86())
2107 Diags.Report(diag::err_drv_argument_not_allowed_with)
2108 << A->getSpelling() << T.getTriple();
2109 else if (Val == llvm::FunctionReturnThunksKind::Invalid)
2110 Diags.Report(diag::err_drv_invalid_value)
2111 << A->getAsString(Args) << A->getValue();
2112 else if (Val == llvm::FunctionReturnThunksKind::Extern &&
2113 Args.getLastArgValue(OPT_mcmodel_EQ) == "large")
2114 Diags.Report(diag::err_drv_argument_not_allowed_with)
2115 << A->getAsString(Args)
2116 << Args.getLastArg(OPT_mcmodel_EQ)->getAsString(Args);
2117 else
2118 Opts.FunctionReturnThunks = static_cast<unsigned>(Val);
2119 }
2120
2121 for (auto *A :
2122 Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {
2124 F.Filename = A->getValue();
2125 if (A->getOption().matches(OPT_mlink_builtin_bitcode)) {
2126 F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;
2127 // When linking CUDA bitcode, propagate function attributes so that
2128 // e.g. libdevice gets fast-math attrs if we're building with fast-math.
2129 F.PropagateAttrs = true;
2130 F.Internalize = true;
2131 }
2132 Opts.LinkBitcodeFiles.push_back(F);
2133 }
2134
2135 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
2136 StringRef Val = A->getValue();
2137 Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);
2138 Opts.FP32DenormalMode = Opts.FPDenormalMode;
2139 if (!Opts.FPDenormalMode.isValid())
2140 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2141 }
2142
2143 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_f32_EQ)) {
2144 StringRef Val = A->getValue();
2145 Opts.FP32DenormalMode = llvm::parseDenormalFPAttribute(Val);
2146 if (!Opts.FP32DenormalMode.isValid())
2147 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
2148 }
2149
2150 // X86_32 has -fppc-struct-return and -freg-struct-return.
2151 // PPC32 has -maix-struct-return and -msvr4-struct-return.
2152 if (Arg *A =
2153 Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return,
2154 OPT_maix_struct_return, OPT_msvr4_struct_return)) {
2155 // TODO: We might want to consider enabling these options on AIX in the
2156 // future.
2157 if (T.isOSAIX())
2158 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2159 << A->getSpelling() << T.str();
2160
2161 const Option &O = A->getOption();
2162 if (O.matches(OPT_fpcc_struct_return) ||
2163 O.matches(OPT_maix_struct_return)) {
2164 Opts.setStructReturnConvention(CodeGenOptions::SRCK_OnStack);
2165 } else {
2166 assert(O.matches(OPT_freg_struct_return) ||
2167 O.matches(OPT_msvr4_struct_return));
2168 Opts.setStructReturnConvention(CodeGenOptions::SRCK_InRegs);
2169 }
2170 }
2171
2172 if (Arg *A = Args.getLastArg(OPT_mxcoff_roptr)) {
2173 if (!T.isOSAIX())
2174 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2175 << A->getSpelling() << T.str();
2176
2177 // Since the storage mapping class is specified per csect,
2178 // without using data sections, it is less effective to use read-only
2179 // pointers. Using read-only pointers may cause other RO variables in the
2180 // same csect to become RW when the linker acts upon `-bforceimprw`;
2181 // therefore, we require that separate data sections
2182 // are used when `-mxcoff-roptr` is in effect. We respect the setting of
2183 // data-sections since we have not found reasons to do otherwise that
2184 // overcome the user surprise of not respecting the setting.
2185 if (!Args.hasFlag(OPT_fdata_sections, OPT_fno_data_sections, false))
2186 Diags.Report(diag::err_roptr_requires_data_sections);
2187
2188 Opts.XCOFFReadOnlyPointers = true;
2189 }
2190
2191 if (Arg *A = Args.getLastArg(OPT_mabi_EQ_quadword_atomics)) {
2192 if (!T.isOSAIX() || T.isPPC32())
2193 Diags.Report(diag::err_drv_unsupported_opt_for_target)
2194 << A->getSpelling() << T.str();
2195 }
2196
2197 bool NeedLocTracking = false;
2198
2199 if (!Opts.OptRecordFile.empty())
2200 NeedLocTracking = true;
2201
2202 if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {
2203 Opts.OptRecordPasses = A->getValue();
2204 NeedLocTracking = true;
2205 }
2206
2207 if (Arg *A = Args.getLastArg(OPT_opt_record_format)) {
2208 Opts.OptRecordFormat = A->getValue();
2209 NeedLocTracking = true;
2210 }
2211
2212 Opts.OptimizationRemark =
2213 ParseOptimizationRemark(Diags, Args, OPT_Rpass_EQ, "pass");
2214
2216 ParseOptimizationRemark(Diags, Args, OPT_Rpass_missed_EQ, "pass-missed");
2217
2219 Diags, Args, OPT_Rpass_analysis_EQ, "pass-analysis");
2220
2221 NeedLocTracking |= Opts.OptimizationRemark.hasValidPattern() ||
2224
2225 bool UsingSampleProfile = !Opts.SampleProfileFile.empty();
2226 bool UsingProfile =
2227 UsingSampleProfile || !Opts.ProfileInstrumentUsePath.empty();
2228
2229 if (Opts.DiagnosticsWithHotness && !UsingProfile &&
2230 // An IR file will contain PGO as metadata
2232 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2233 << "-fdiagnostics-show-hotness";
2234
2235 // Parse remarks hotness threshold. Valid value is either integer or 'auto'.
2236 if (auto *arg =
2237 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {
2238 auto ResultOrErr =
2239 llvm::remarks::parseHotnessThresholdOption(arg->getValue());
2240
2241 if (!ResultOrErr) {
2242 Diags.Report(diag::err_drv_invalid_diagnotics_hotness_threshold)
2243 << "-fdiagnostics-hotness-threshold=";
2244 } else {
2245 Opts.DiagnosticsHotnessThreshold = *ResultOrErr;
2246 if ((!Opts.DiagnosticsHotnessThreshold ||
2247 *Opts.DiagnosticsHotnessThreshold > 0) &&
2248 !UsingProfile)
2249 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)
2250 << "-fdiagnostics-hotness-threshold=";
2251 }
2252 }
2253
2254 if (auto *arg =
2255 Args.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ)) {
2256 auto ResultOrErr = parseToleranceOption(arg->getValue());
2257
2258 if (!ResultOrErr) {
2259 Diags.Report(diag::err_drv_invalid_diagnotics_misexpect_tolerance)
2260 << "-fdiagnostics-misexpect-tolerance=";
2261 } else {
2262 Opts.DiagnosticsMisExpectTolerance = *ResultOrErr;
2263 if ((!Opts.DiagnosticsMisExpectTolerance ||
2264 *Opts.DiagnosticsMisExpectTolerance > 0) &&
2265 !UsingProfile)
2266 Diags.Report(diag::warn_drv_diagnostics_misexpect_requires_pgo)
2267 << "-fdiagnostics-misexpect-tolerance=";
2268 }
2269 }
2270
2271 // If the user requested to use a sample profile for PGO, then the
2272 // backend will need to track source location information so the profile
2273 // can be incorporated into the IR.
2274 if (UsingSampleProfile)
2275 NeedLocTracking = true;
2276
2277 if (!Opts.StackUsageOutput.empty())
2278 NeedLocTracking = true;
2279
2280 // If the user requested a flag that requires source locations available in
2281 // the backend, make sure that the backend tracks source location information.
2282 if (NeedLocTracking &&
2283 Opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo)
2284 Opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
2285
2286 // Parse -fsanitize-recover= arguments.
2287 // FIXME: Report unrecoverable sanitizers incorrectly specified here.
2288 parseSanitizerKinds("-fsanitize-recover=",
2289 Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,
2290 Opts.SanitizeRecover);
2291 parseSanitizerKinds("-fsanitize-trap=",
2292 Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,
2293 Opts.SanitizeTrap);
2294 parseSanitizerKinds("-fsanitize-merge=",
2295 Args.getAllArgValues(OPT_fsanitize_merge_handlers_EQ),
2296 Diags, Opts.SanitizeMergeHandlers);
2297
2298 Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);
2299
2300 if (!LangOpts->CUDAIsDevice)
2302
2303 if (Args.hasArg(options::OPT_ffinite_loops))
2304 Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Always;
2305 else if (Args.hasArg(options::OPT_fno_finite_loops))
2306 Opts.FiniteLoops = CodeGenOptions::FiniteLoopsKind::Never;
2307
2308 Opts.EmitIEEENaNCompliantInsts = Args.hasFlag(
2309 options::OPT_mamdgpu_ieee, options::OPT_mno_amdgpu_ieee, true);
2310 if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs)
2311 Diags.Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans);
2312
2313 return Diags.getNumErrors() == NumErrorsBefore;
2314}
2315
2317 ArgumentConsumer Consumer) {
2318 const DependencyOutputOptions &DependencyOutputOpts = Opts;
2319#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2320 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2321#include "clang/Driver/Options.inc"
2322#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2323
2325 GenerateArg(Consumer, OPT_show_includes);
2326
2327 for (const auto &Dep : Opts.ExtraDeps) {
2328 switch (Dep.second) {
2330 // Sanitizer ignorelist arguments are generated from LanguageOptions.
2331 continue;
2332 case EDK_ModuleFile:
2333 // Module file arguments are generated from FrontendOptions and
2334 // HeaderSearchOptions.
2335 continue;
2336 case EDK_ProfileList:
2337 // Profile list arguments are generated from LanguageOptions via the
2338 // marshalling infrastructure.
2339 continue;
2340 case EDK_DepFileEntry:
2341 GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first);
2342 break;
2343 }
2344 }
2345}
2346
2348 ArgList &Args, DiagnosticsEngine &Diags,
2350 bool ShowLineMarkers) {
2351 unsigned NumErrorsBefore = Diags.getNumErrors();
2352
2353 DependencyOutputOptions &DependencyOutputOpts = Opts;
2354#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \
2355 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2356#include "clang/Driver/Options.inc"
2357#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING
2358
2359 if (Args.hasArg(OPT_show_includes)) {
2360 // Writing both /showIncludes and preprocessor output to stdout
2361 // would produce interleaved output, so use stderr for /showIncludes.
2362 // This behaves the same as cl.exe, when /E, /EP or /P are passed.
2363 if (Action == frontend::PrintPreprocessedInput || !ShowLineMarkers)
2365 else
2367 } else {
2369 }
2370
2371 // Add sanitizer ignorelists as extra dependencies.
2372 // They won't be discovered by the regular preprocessor, so
2373 // we let make / ninja to know about this implicit dependency.
2374 if (!Args.hasArg(OPT_fno_sanitize_ignorelist)) {
2375 for (const auto *A : Args.filtered(OPT_fsanitize_ignorelist_EQ)) {
2376 StringRef Val = A->getValue();
2377 if (!Val.contains('='))
2378 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_SanitizeIgnorelist);
2379 }
2380 if (Opts.IncludeSystemHeaders) {
2381 for (const auto *A : Args.filtered(OPT_fsanitize_system_ignorelist_EQ)) {
2382 StringRef Val = A->getValue();
2383 if (!Val.contains('='))
2384 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_SanitizeIgnorelist);
2385 }
2386 }
2387 }
2388
2389 // -fprofile-list= dependencies.
2390 for (const auto &Filename : Args.getAllArgValues(OPT_fprofile_list_EQ))
2391 Opts.ExtraDeps.emplace_back(Filename, EDK_ProfileList);
2392
2393 // Propagate the extra dependencies.
2394 for (const auto *A : Args.filtered(OPT_fdepfile_entry))
2395 Opts.ExtraDeps.emplace_back(A->getValue(), EDK_DepFileEntry);
2396
2397 // Only the -fmodule-file=<file> form.
2398 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
2399 StringRef Val = A->getValue();
2400 if (!Val.contains('='))
2401 Opts.ExtraDeps.emplace_back(std::string(Val), EDK_ModuleFile);
2402 }
2403
2404 // Check for invalid combinations of header-include-format
2405 // and header-include-filtering.
2406 if ((Opts.HeaderIncludeFormat == HIFMT_Textual &&
2410 Diags.Report(diag::err_drv_print_header_env_var_combination_cc1)
2411 << Args.getLastArg(OPT_header_include_format_EQ)->getValue()
2412 << Args.getLastArg(OPT_header_include_filtering_EQ)->getValue();
2413
2414 return Diags.getNumErrors() == NumErrorsBefore;
2415}
2416
2417static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor) {
2418 // Color diagnostics default to auto ("on" if terminal supports) in the driver
2419 // but default to off in cc1, needing an explicit OPT_fdiagnostics_color.
2420 // Support both clang's -f[no-]color-diagnostics and gcc's
2421 // -f[no-]diagnostics-colors[=never|always|auto].
2422 enum {
2423 Colors_On,
2424 Colors_Off,
2425 Colors_Auto
2426 } ShowColors = DefaultColor ? Colors_Auto : Colors_Off;
2427 for (auto *A : Args) {
2428 const Option &O = A->getOption();
2429 if (O.matches(options::OPT_fcolor_diagnostics)) {
2430 ShowColors = Colors_On;
2431 } else if (O.matches(options::OPT_fno_color_diagnostics)) {
2432 ShowColors = Colors_Off;
2433 } else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {
2434 StringRef Value(A->getValue());
2435 if (Value == "always")
2436 ShowColors = Colors_On;
2437 else if (Value == "never")
2438 ShowColors = Colors_Off;
2439 else if (Value == "auto")
2440 ShowColors = Colors_Auto;
2441 }
2442 }
2443 return ShowColors == Colors_On ||
2444 (ShowColors == Colors_Auto &&
2445 llvm::sys::Process::StandardErrHasColors());
2446}
2447
2448static bool checkVerifyPrefixes(const std::vector<std::string> &VerifyPrefixes,
2449 DiagnosticsEngine &Diags) {
2450 bool Success = true;
2451 for (const auto &Prefix : VerifyPrefixes) {
2452 // Every prefix must start with a letter and contain only alphanumeric
2453 // characters, hyphens, and underscores.
2454 auto BadChar = llvm::find_if(Prefix, [](char C) {
2455 return !isAlphanumeric(C) && C != '-' && C != '_';
2456 });
2457 if (BadChar != Prefix.end() || !isLetter(Prefix[0])) {
2458 Success = false;
2459 Diags.Report(diag::err_drv_invalid_value) << "-verify=" << Prefix;
2460 Diags.Report(diag::note_drv_verify_prefix_spelling);
2461 }
2462 }
2463 return Success;
2464}
2465
2467 ArgumentConsumer Consumer) {
2468 const FileSystemOptions &FileSystemOpts = Opts;
2469
2470#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2471 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2472#include "clang/Driver/Options.inc"
2473#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2474}
2475
2476static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args,
2477 DiagnosticsEngine &Diags) {
2478 unsigned NumErrorsBefore = Diags.getNumErrors();
2479
2480 FileSystemOptions &FileSystemOpts = Opts;
2481
2482#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \
2483 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2484#include "clang/Driver/Options.inc"
2485#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
2486
2487 return Diags.getNumErrors() == NumErrorsBefore;
2488}
2489
2491 ArgumentConsumer Consumer) {
2492 const MigratorOptions &MigratorOpts = Opts;
2493#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2494 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2495#include "clang/Driver/Options.inc"
2496#undef MIGRATOR_OPTION_WITH_MARSHALLING
2497}
2498
2499static bool ParseMigratorArgs(MigratorOptions &Opts, const ArgList &Args,
2500 DiagnosticsEngine &Diags) {
2501 unsigned NumErrorsBefore = Diags.getNumErrors();
2502
2503 MigratorOptions &MigratorOpts = Opts;
2504
2505#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \
2506 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2507#include "clang/Driver/Options.inc"
2508#undef MIGRATOR_OPTION_WITH_MARSHALLING
2509
2510 return Diags.getNumErrors() == NumErrorsBefore;
2511}
2512
2513void CompilerInvocationBase::GenerateDiagnosticArgs(
2514 const DiagnosticOptions &Opts, ArgumentConsumer Consumer,
2515 bool DefaultDiagColor) {
2516 const DiagnosticOptions *DiagnosticOpts = &Opts;
2517#define DIAG_OPTION_WITH_MARSHALLING(...) \
2518 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2519#include "clang/Driver/Options.inc"
2520#undef DIAG_OPTION_WITH_MARSHALLING
2521
2522 if (!Opts.DiagnosticSerializationFile.empty())
2523 GenerateArg(Consumer, OPT_diagnostic_serialized_file,
2525
2526 if (Opts.ShowColors)
2527 GenerateArg(Consumer, OPT_fcolor_diagnostics);
2528
2529 if (Opts.VerifyDiagnostics &&
2530 llvm::is_contained(Opts.VerifyPrefixes, "expected"))
2531 GenerateArg(Consumer, OPT_verify);
2532
2533 for (const auto &Prefix : Opts.VerifyPrefixes)
2534 if (Prefix != "expected")
2535 GenerateArg(Consumer, OPT_verify_EQ, Prefix);
2536
2537 DiagnosticLevelMask VIU = Opts.getVerifyIgnoreUnexpected();
2538 if (VIU == DiagnosticLevelMask::None) {
2539 // This is the default, don't generate anything.
2540 } else if (VIU == DiagnosticLevelMask::All) {
2541 GenerateArg(Consumer, OPT_verify_ignore_unexpected);
2542 } else {
2543 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Note) != 0)
2544 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "note");
2545 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Remark) != 0)
2546 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "remark");
2547 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Warning) != 0)
2548 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "warning");
2549 if (static_cast<unsigned>(VIU & DiagnosticLevelMask::Error) != 0)
2550 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "error");
2551 }
2552
2553 for (const auto &Warning : Opts.Warnings) {
2554 // This option is automatically generated from UndefPrefixes.
2555 if (Warning == "undef-prefix")
2556 continue;
2557 // This option is automatically generated from CheckConstexprFunctionBodies.
2558 if (Warning == "invalid-constexpr" || Warning == "no-invalid-constexpr")
2559 continue;
2560 Consumer(StringRef("-W") + Warning);
2561 }
2562
2563 for (const auto &Remark : Opts.Remarks) {
2564 // These arguments are generated from OptimizationRemark fields of
2565 // CodeGenOptions.
2566 StringRef IgnoredRemarks[] = {"pass", "no-pass",
2567 "pass-analysis", "no-pass-analysis",
2568 "pass-missed", "no-pass-missed"};
2569 if (llvm::is_contained(IgnoredRemarks, Remark))
2570 continue;
2571
2572 Consumer(StringRef("-R") + Remark);
2573 }
2574
2575 if (!Opts.DiagnosticSuppressionMappingsFile.empty()) {
2576 GenerateArg(Consumer, OPT_warning_suppression_mappings_EQ,
2578 }
2579}
2580
2581std::unique_ptr<DiagnosticOptions>
2583 auto DiagOpts = std::make_unique<DiagnosticOptions>();
2584 unsigned MissingArgIndex, MissingArgCount;
2585 InputArgList Args = getDriverOptTable().ParseArgs(
2586 Argv.slice(1), MissingArgIndex, MissingArgCount);
2587
2588 bool ShowColors = true;
2589 if (std::optional<std::string> NoColor =
2590 llvm::sys::Process::GetEnv("NO_COLOR");
2591 NoColor && !NoColor->empty()) {
2592 // If the user set the NO_COLOR environment variable, we'll honor that
2593 // unless the command line overrides it.
2594 ShowColors = false;
2595 }
2596
2597 // We ignore MissingArgCount and the return value of ParseDiagnosticArgs.
2598 // Any errors that would be diagnosed here will also be diagnosed later,
2599 // when the DiagnosticsEngine actually exists.
2600 (void)ParseDiagnosticArgs(*DiagOpts, Args, /*Diags=*/nullptr, ShowColors);
2601 return DiagOpts;
2602}
2603
2604bool clang::ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
2605 DiagnosticsEngine *Diags,
2606 bool DefaultDiagColor) {
2607 std::optional<DiagnosticsEngine> IgnoringDiags;
2608 if (!Diags) {
2609 IgnoringDiags.emplace(new DiagnosticIDs(), new DiagnosticOptions(),
2610 new IgnoringDiagConsumer());
2611 Diags = &*IgnoringDiags;
2612 }
2613
2614 unsigned NumErrorsBefore = Diags->getNumErrors();
2615
2616 // The key paths of diagnostic options defined in Options.td start with
2617 // "DiagnosticOpts->". Let's provide the expected variable name and type.
2618 DiagnosticOptions *DiagnosticOpts = &Opts;
2619
2620#define DIAG_OPTION_WITH_MARSHALLING(...) \
2621 PARSE_OPTION_WITH_MARSHALLING(Args, *Diags, __VA_ARGS__)
2622#include "clang/Driver/Options.inc"
2623#undef DIAG_OPTION_WITH_MARSHALLING
2624
2625 llvm::sys::Process::UseANSIEscapeCodes(Opts.UseANSIEscapeCodes);
2626
2627 if (Arg *A =
2628 Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))
2629 Opts.DiagnosticSerializationFile = A->getValue();
2630 Opts.ShowColors = parseShowColorsArgs(Args, DefaultDiagColor);
2631
2632 Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ);
2633 Opts.VerifyPrefixes = Args.getAllArgValues(OPT_verify_EQ);
2634 if (Args.hasArg(OPT_verify))
2635 Opts.VerifyPrefixes.push_back("expected");
2636 // Keep VerifyPrefixes in its original order for the sake of diagnostics, and
2637 // then sort it to prepare for fast lookup using std::binary_search.
2638 if (!checkVerifyPrefixes(Opts.VerifyPrefixes, *Diags))
2639 Opts.VerifyDiagnostics = false;
2640 else
2641 llvm::sort(Opts.VerifyPrefixes);
2644 "-verify-ignore-unexpected=",
2645 Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), *Diags, DiagMask);
2646 if (Args.hasArg(OPT_verify_ignore_unexpected))
2647 DiagMask = DiagnosticLevelMask::All;
2648 Opts.setVerifyIgnoreUnexpected(DiagMask);
2649 if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {
2650 Diags->Report(diag::warn_ignoring_ftabstop_value)
2651 << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
2652 Opts.TabStop = DiagnosticOptions::DefaultTabStop;
2653 }
2654
2655 if (const Arg *A = Args.getLastArg(OPT_warning_suppression_mappings_EQ))
2656 Opts.DiagnosticSuppressionMappingsFile = A->getValue();
2657
2658 addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
2659 addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
2660
2661 return Diags->getNumErrors() == NumErrorsBefore;
2662}
2663
2664/// Parse the argument to the -ftest-module-file-extension
2665/// command-line argument.
2666///
2667/// \returns true on error, false on success.
2668static bool parseTestModuleFileExtensionArg(StringRef Arg,
2669 std::string &BlockName,
2670 unsigned &MajorVersion,
2671 unsigned &MinorVersion,
2672 bool &Hashed,
2673 std::string &UserInfo) {
2675 Arg.split(Args, ':', 5);
2676 if (Args.size() < 5)
2677 return true;
2678
2679 BlockName = std::string(Args[0]);
2680 if (Args[1].getAsInteger(10, MajorVersion)) return true;
2681 if (Args[2].getAsInteger(10, MinorVersion)) return true;
2682 if (Args[3].getAsInteger(2, Hashed)) return true;
2683 if (Args.size() > 4)
2684 UserInfo = std::string(Args[4]);
2685 return false;
2686}
2687
2688/// Return a table that associates command line option specifiers with the
2689/// frontend action. Note: The pair {frontend::PluginAction, OPT_plugin} is
2690/// intentionally missing, as this case is handled separately from other
2691/// frontend options.
2692static const auto &getFrontendActionTable() {
2693 static const std::pair<frontend::ActionKind, unsigned> Table[] = {
2694 {frontend::ASTDeclList, OPT_ast_list},
2695
2696 {frontend::ASTDump, OPT_ast_dump_all_EQ},
2697 {frontend::ASTDump, OPT_ast_dump_all},
2698 {frontend::ASTDump, OPT_ast_dump_EQ},
2699 {frontend::ASTDump, OPT_ast_dump},
2700 {frontend::ASTDump, OPT_ast_dump_lookups},
2701 {frontend::ASTDump, OPT_ast_dump_decl_types},
2702
2703 {frontend::ASTPrint, OPT_ast_print},
2704 {frontend::ASTView, OPT_ast_view},
2705 {frontend::DumpCompilerOptions, OPT_compiler_options_dump},
2706 {frontend::DumpRawTokens, OPT_dump_raw_tokens},
2707 {frontend::DumpTokens, OPT_dump_tokens},
2708 {frontend::EmitAssembly, OPT_S},
2709 {frontend::EmitBC, OPT_emit_llvm_bc},
2710 {frontend::EmitCIR, OPT_emit_cir},
2711 {frontend::EmitHTML, OPT_emit_html},
2712 {frontend::EmitLLVM, OPT_emit_llvm},
2713 {frontend::EmitLLVMOnly, OPT_emit_llvm_only},
2714 {frontend::EmitCodeGenOnly, OPT_emit_codegen_only},
2715 {frontend::EmitObj, OPT_emit_obj},
2716 {frontend::ExtractAPI, OPT_extract_api},
2717
2718 {frontend::FixIt, OPT_fixit_EQ},
2719 {frontend::FixIt, OPT_fixit},
2720
2721 {frontend::GenerateModule, OPT_emit_module},
2722 {frontend::GenerateModuleInterface, OPT_emit_module_interface},
2724 OPT_emit_reduced_module_interface},
2725 {frontend::GenerateHeaderUnit, OPT_emit_header_unit},
2726 {frontend::GeneratePCH, OPT_emit_pch},
2727 {frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs},
2728 {frontend::InitOnly, OPT_init_only},
2729 {frontend::ParseSyntaxOnly, OPT_fsyntax_only},
2730 {frontend::ModuleFileInfo, OPT_module_file_info},
2731 {frontend::VerifyPCH, OPT_verify_pch},
2732 {frontend::PrintPreamble, OPT_print_preamble},
2734 {frontend::TemplightDump, OPT_templight_dump},
2735 {frontend::RewriteMacros, OPT_rewrite_macros},
2736 {frontend::RewriteObjC, OPT_rewrite_objc},
2737 {frontend::RewriteTest, OPT_rewrite_test},
2738 {frontend::RunAnalysis, OPT_analyze},
2739 {frontend::MigrateSource, OPT_migrate},
2740 {frontend::RunPreprocessorOnly, OPT_Eonly},
2742 OPT_print_dependency_directives_minimized_source},
2743 };
2744
2745 return Table;
2746}
2747
2748/// Maps command line option to frontend action.
2749static std::optional<frontend::ActionKind>
2750getFrontendAction(OptSpecifier &Opt) {
2751 for (const auto &ActionOpt : getFrontendActionTable())
2752 if (ActionOpt.second == Opt.getID())
2753 return ActionOpt.first;
2754
2755 return std::nullopt;
2756}
2757
2758/// Maps frontend action to command line option.
2759static std::optional<OptSpecifier>
2761 for (const auto &ActionOpt : getFrontendActionTable())
2762 if (ActionOpt.first == ProgramAction)
2763 return OptSpecifier(ActionOpt.second);
2764
2765 return std::nullopt;
2766}
2767
2769 ArgumentConsumer Consumer, bool IsHeader) {
2770 const FrontendOptions &FrontendOpts = Opts;
2771#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2772 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2773#include "clang/Driver/Options.inc"
2774#undef FRONTEND_OPTION_WITH_MARSHALLING
2775
2776 std::optional<OptSpecifier> ProgramActionOpt =
2778
2779 // Generating a simple flag covers most frontend actions.
2780 std::function<void()> GenerateProgramAction = [&]() {
2781 GenerateArg(Consumer, *ProgramActionOpt);
2782 };
2783
2784 if (!ProgramActionOpt) {
2785 // PluginAction is the only program action handled separately.
2786 assert(Opts.ProgramAction == frontend::PluginAction &&
2787 "Frontend action without option.");
2788 GenerateProgramAction = [&]() {
2789 GenerateArg(Consumer, OPT_plugin, Opts.ActionName);
2790 };
2791 }
2792
2793 // FIXME: Simplify the complex 'AST dump' command line.
2794 if (Opts.ProgramAction == frontend::ASTDump) {
2795 GenerateProgramAction = [&]() {
2796 // ASTDumpLookups, ASTDumpDeclTypes and ASTDumpFilter are generated via
2797 // marshalling infrastructure.
2798
2799 if (Opts.ASTDumpFormat != ADOF_Default) {
2800 StringRef Format;
2801 switch (Opts.ASTDumpFormat) {
2802 case ADOF_Default:
2803 llvm_unreachable("Default AST dump format.");
2804 case ADOF_JSON:
2805 Format = "json";
2806 break;
2807 }
2808
2809 if (Opts.ASTDumpAll)
2810 GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);
2811 if (Opts.ASTDumpDecls)
2812 GenerateArg(Consumer, OPT_ast_dump_EQ, Format);
2813 } else {
2814 if (Opts.ASTDumpAll)
2815 GenerateArg(Consumer, OPT_ast_dump_all);
2816 if (Opts.ASTDumpDecls)
2817 GenerateArg(Consumer, OPT_ast_dump);
2818 }
2819 };
2820 }
2821
2822 if (Opts.ProgramAction == frontend::FixIt && !Opts.FixItSuffix.empty()) {
2823 GenerateProgramAction = [&]() {
2824 GenerateArg(Consumer, OPT_fixit_EQ, Opts.FixItSuffix);
2825 };
2826 }
2827
2828 GenerateProgramAction();
2829
2830 for (const auto &PluginArgs : Opts.PluginArgs) {
2831 Option Opt = getDriverOptTable().getOption(OPT_plugin_arg);
2832 for (const auto &PluginArg : PluginArgs.second)
2833 denormalizeString(Consumer,
2834 Opt.getPrefix() + Opt.getName() + PluginArgs.first,
2835 Opt.getKind(), 0, PluginArg);
2836 }
2837
2838 for (const auto &Ext : Opts.ModuleFileExtensions)
2839 if (auto *TestExt = dyn_cast_or_null<TestModuleFileExtension>(Ext.get()))
2840 GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());
2841
2842 if (!Opts.CodeCompletionAt.FileName.empty())
2843 GenerateArg(Consumer, OPT_code_completion_at,
2844 Opts.CodeCompletionAt.ToString());
2845
2846 for (const auto &Plugin : Opts.Plugins)
2847 GenerateArg(Consumer, OPT_load, Plugin);
2848
2849 // ASTDumpDecls and ASTDumpAll already handled with ProgramAction.
2850
2851 for (const auto &ModuleFile : Opts.ModuleFiles)
2852 GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);
2853
2854 if (Opts.AuxTargetCPU)
2855 GenerateArg(Consumer, OPT_aux_target_cpu, *Opts.AuxTargetCPU);
2856
2857 if (Opts.AuxTargetFeatures)
2858 for (const auto &Feature : *Opts.AuxTargetFeatures)
2859 GenerateArg(Consumer, OPT_aux_target_feature, Feature);
2860
2861 {
2862 StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";
2863 StringRef ModuleMap =
2864 Opts.DashX.getFormat() == InputKind::ModuleMap ? "-module-map" : "";
2865 StringRef HeaderUnit = "";
2866 switch (Opts.DashX.getHeaderUnitKind()) {
2868 break;
2870 HeaderUnit = "-user";
2871 break;
2873 HeaderUnit = "-system";
2874 break;
2876 HeaderUnit = "-header-unit";
2877 break;
2878 }
2879 StringRef Header = IsHeader ? "-header" : "";
2880
2881 StringRef Lang;
2882 switch (Opts.DashX.getLanguage()) {
2883 case Language::C:
2884 Lang = "c";
2885 break;
2886 case Language::OpenCL:
2887 Lang = "cl";
2888 break;
2890 Lang = "clcpp";
2891 break;
2892 case Language::CUDA:
2893 Lang = "cuda";
2894 break;
2895 case Language::HIP:
2896 Lang = "hip";
2897 break;
2898 case Language::CXX:
2899 Lang = "c++";
2900 break;
2901 case Language::ObjC:
2902 Lang = "objective-c";
2903 break;
2904 case Language::ObjCXX:
2905 Lang = "objective-c++";
2906 break;
2907 case Language::Asm:
2908 Lang = "assembler-with-cpp";
2909 break;
2910 case Language::Unknown:
2911 assert(Opts.DashX.getFormat() == InputKind::Precompiled &&
2912 "Generating -x argument for unknown language (not precompiled).");
2913 Lang = "ast";
2914 break;
2915 case Language::LLVM_IR:
2916 Lang = "ir";
2917 break;
2918 case Language::HLSL:
2919 Lang = "hlsl";
2920 break;
2921 case Language::CIR:
2922 Lang = "cir";
2923 break;
2924 }
2925
2926 GenerateArg(Consumer, OPT_x,
2927 Lang + HeaderUnit + Header + ModuleMap + Preprocessed);
2928 }
2929
2930 // OPT_INPUT has a unique class, generate it directly.
2931 for (const auto &Input : Opts.Inputs)
2932 Consumer(Input.getFile());
2933}
2934
2935static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
2936 DiagnosticsEngine &Diags, bool &IsHeaderFile) {
2937 unsigned NumErrorsBefore = Diags.getNumErrors();
2938
2939 FrontendOptions &FrontendOpts = Opts;
2940
2941#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2942 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2943#include "clang/Driver/Options.inc"
2944#undef FRONTEND_OPTION_WITH_MARSHALLING
2945
2947 if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
2948 OptSpecifier Opt = OptSpecifier(A->getOption().getID());
2949 std::optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt);
2950 assert(ProgramAction && "Option specifier not in Action_Group.");
2951
2952 if (ProgramAction == frontend::ASTDump &&
2953 (Opt == OPT_ast_dump_all_EQ || Opt == OPT_ast_dump_EQ)) {
2954 unsigned Val = llvm::StringSwitch<unsigned>(A->getValue())
2955 .CaseLower("default", ADOF_Default)
2956 .CaseLower("json", ADOF_JSON)
2957 .Default(std::numeric_limits<unsigned>::max());
2958
2959 if (Val != std::numeric_limits<unsigned>::max())
2960 Opts.ASTDumpFormat = static_cast<ASTDumpOutputFormat>(Val);
2961 else {
2962 Diags.Report(diag::err_drv_invalid_value)
2963 << A->getAsString(Args) << A->getValue();
2965 }
2966 }
2967
2968 if (ProgramAction == frontend::FixIt && Opt == OPT_fixit_EQ)
2969 Opts.FixItSuffix = A->getValue();
2970
2971 if (ProgramAction == frontend::GenerateInterfaceStubs) {
2972 StringRef ArgStr =
2973 Args.hasArg(OPT_interface_stub_version_EQ)
2974 ? Args.getLastArgValue(OPT_interface_stub_version_EQ)
2975 : "ifs-v1";
2976 if (ArgStr == "experimental-yaml-elf-v1" ||
2977 ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-ifs-v2" ||
2978 ArgStr == "experimental-tapi-elf-v1") {
2979 std::string ErrorMessage =
2980 "Invalid interface stub format: " + ArgStr.str() +
2981 " is deprecated.";
2982 Diags.Report(diag::err_drv_invalid_value)
2983 << "Must specify a valid interface stub format type, ie: "
2984 "-interface-stub-version=ifs-v1"
2985 << ErrorMessage;
2986 ProgramAction = frontend::ParseSyntaxOnly;
2987 } else if (!ArgStr.starts_with("ifs-")) {
2988 std::string ErrorMessage =
2989 "Invalid interface stub format: " + ArgStr.str() + ".";
2990 Diags.Report(diag::err_drv_invalid_value)
2991 << "Must specify a valid interface stub format type, ie: "
2992 "-interface-stub-version=ifs-v1"
2993 << ErrorMessage;
2994 ProgramAction = frontend::ParseSyntaxOnly;
2995 }
2996 }
2997
2998 Opts.ProgramAction = *ProgramAction;
2999
3000 // Catch common mistakes when multiple actions are specified for cc1 (e.g.
3001 // -S -emit-llvm means -emit-llvm while -emit-llvm -S means -S). However, to
3002 // support driver `-c -Xclang ACTION` (-cc1 -emit-llvm file -main-file-name
3003 // X ACTION), we suppress the error when the two actions are separated by
3004 // -main-file-name.
3005 //
3006 // As an exception, accept composable -ast-dump*.
3007 if (!A->getSpelling().starts_with("-ast-dump")) {
3008 const Arg *SavedAction = nullptr;
3009 for (const Arg *AA :
3010 Args.filtered(OPT_Action_Group, OPT_main_file_name)) {
3011 if (AA->getOption().matches(OPT_main_file_name)) {
3012 SavedAction = nullptr;
3013 } else if (!SavedAction) {
3014 SavedAction = AA;
3015 } else {
3016 if (!A->getOption().matches(OPT_ast_dump_EQ))
3017 Diags.Report(diag::err_fe_invalid_multiple_actions)
3018 << SavedAction->getSpelling() << A->getSpelling();
3019 break;
3020 }
3021 }
3022 }
3023 }
3024
3025 if (const Arg* A = Args.getLastArg(OPT_plugin)) {
3026 Opts.Plugins.emplace_back(A->getValue(0));
3028 Opts.ActionName = A->getValue();
3029 }
3030 for (const auto *AA : Args.filtered(OPT_plugin_arg))
3031 Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
3032
3033 for (const std::string &Arg :
3034 Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
3035 std::string BlockName;
3036 unsigned MajorVersion;
3037 unsigned MinorVersion;
3038 bool Hashed;
3039 std::string UserInfo;
3040 if (parseTestModuleFileExtensionArg(Arg, BlockName, MajorVersion,
3041 MinorVersion, Hashed, UserInfo)) {
3042 Diags.Report(diag::err_test_module_file_extension_format) << Arg;
3043
3044 continue;
3045 }
3046
3047 // Add the testing module file extension.
3048 Opts.ModuleFileExtensions.push_back(
3049 std::make_shared<TestModuleFileExtension>(
3050 BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
3051 }
3052
3053 if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
3054 Opts.CodeCompletionAt =
3055 ParsedSourceLocation::FromString(A->getValue());
3056 if (Opts.CodeCompletionAt.FileName.empty())
3057 Diags.Report(diag::err_drv_invalid_value)
3058 << A->getAsString(Args) << A->getValue();
3059 }
3060
3061 Opts.Plugins = Args.getAllArgValues(OPT_load);
3062 Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);
3063 Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);
3064 // Only the -fmodule-file=<file> form.
3065 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3066 StringRef Val = A->getValue();
3067 if (!Val.contains('='))
3068 Opts.ModuleFiles.push_back(std::string(Val));
3069 }
3070
3072 Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"
3073 << "-emit-module";
3074 if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_cir))
3075 Opts.UseClangIRPipeline = true;
3076
3077 if (Args.hasArg(OPT_aux_target_cpu))
3078 Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu));
3079 if (Args.hasArg(OPT_aux_target_feature))
3080 Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature);
3081
3084 Diags.Report(diag::err_drv_argument_not_allowed_with)
3085 << "ARC migration" << "ObjC migration";
3086 }
3087
3089 if (const Arg *A = Args.getLastArg(OPT_x)) {
3090 StringRef XValue = A->getValue();
3091
3092 // Parse suffixes:
3093 // '<lang>(-[{header-unit,user,system}-]header|[-module-map][-cpp-output])'.
3094 // FIXME: Supporting '<lang>-header-cpp-output' would be useful.
3095 bool Preprocessed = XValue.consume_back("-cpp-output");
3096 bool ModuleMap = XValue.consume_back("-module-map");
3097 // Detect and consume the header indicator.
3098 bool IsHeader =
3099 XValue != "precompiled-header" && XValue.consume_back("-header");
3100
3101 // If we have c++-{user,system}-header, that indicates a header unit input
3102 // likewise, if the user put -fmodule-header together with a header with an
3103 // absolute path (header-unit-header).
3105 if (IsHeader || Preprocessed) {
3106 if (XValue.consume_back("-header-unit"))
3108 else if (XValue.consume_back("-system"))
3110 else if (XValue.consume_back("-user"))
3112 }
3113
3114 // The value set by this processing is an un-preprocessed source which is
3115 // not intended to be a module map or header unit.
3116 IsHeaderFile = IsHeader && !Preprocessed && !ModuleMap &&
3118
3119 // Principal languages.
3120 DashX = llvm::StringSwitch<InputKind>(XValue)
3121 .Case("c", Language::C)
3122 .Case("cl", Language::OpenCL)
3123 .Case("clcpp", Language::OpenCLCXX)
3124 .Case("cuda", Language::CUDA)
3125 .Case("hip", Language::HIP)
3126 .Case("c++", Language::CXX)
3127 .Case("objective-c", Language::ObjC)
3128 .Case("objective-c++", Language::ObjCXX)
3129 .Case("hlsl", Language::HLSL)
3130 .Default(Language::Unknown);
3131
3132 // "objc[++]-cpp-output" is an acceptable synonym for
3133 // "objective-c[++]-cpp-output".
3134 if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap &&
3136 DashX = llvm::StringSwitch<InputKind>(XValue)
3137 .Case("objc", Language::ObjC)
3138 .Case("objc++", Language::ObjCXX)
3139 .Default(Language::Unknown);
3140
3141 // Some special cases cannot be combined with suffixes.
3142 if (DashX.isUnknown() && !Preprocessed && !IsHeaderFile && !ModuleMap &&
3144 DashX = llvm::StringSwitch<InputKind>(XValue)
3145 .Case("cpp-output", InputKind(Language::C).getPreprocessed())
3146 .Case("assembler-with-cpp", Language::Asm)
3147 .Cases("ast", "pcm", "precompiled-header",
3149 .Case("ir", Language::LLVM_IR)
3150 .Case("cir", Language::CIR)
3151 .Default(Language::Unknown);
3152
3153 if (DashX.isUnknown())
3154 Diags.Report(diag::err_drv_invalid_value)
3155 << A->getAsString(Args) << A->getValue();
3156
3157 if (Preprocessed)
3158 DashX = DashX.getPreprocessed();
3159 // A regular header is considered mutually exclusive with a header unit.
3160 if (HUK != InputKind::HeaderUnit_None) {
3161 DashX = DashX.withHeaderUnit(HUK);
3162 IsHeaderFile = true;
3163 } else if (IsHeaderFile)
3164 DashX = DashX.getHeader();
3165 if (ModuleMap)
3166 DashX = DashX.withFormat(InputKind::ModuleMap);
3167 }
3168
3169 // '-' is the default input if none is given.
3170 std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
3171 Opts.Inputs.clear();
3172 if (Inputs.empty())
3173 Inputs.push_back("-");
3174
3176 Inputs.size() > 1)
3177 Diags.Report(diag::err_drv_header_unit_extra_inputs) << Inputs[1];
3178
3179 for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
3180 InputKind IK = DashX;
3181 if (IK.isUnknown()) {
3183 StringRef(Inputs[i]).rsplit('.').second);
3184 // FIXME: Warn on this?
3185 if (IK.isUnknown())
3186 IK = Language::C;
3187 // FIXME: Remove this hack.
3188 if (i == 0)
3189 DashX = IK;
3190 }
3191
3192 bool IsSystem = false;
3193
3194 // The -emit-module action implicitly takes a module map.
3196 IK.getFormat() == InputKind::Source) {
3198 IsSystem = Opts.IsSystemModule;
3199 }
3200
3201 Opts.Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem);
3202 }
3203
3204 Opts.DashX = DashX;
3205
3206 return Diags.getNumErrors() == NumErrorsBefore;
3207}
3208
3209std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
3210 void *MainAddr) {
3211 std::string ClangExecutable =
3212 llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
3213 return Driver::GetResourcesPath(ClangExecutable);
3214}
3215
3217 ArgumentConsumer Consumer) {
3218 const HeaderSearchOptions *HeaderSearchOpts = &Opts;
3219#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3220 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3221#include "clang/Driver/Options.inc"
3222#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3223
3224 if (Opts.UseLibcxx)
3225 GenerateArg(Consumer, OPT_stdlib_EQ, "libc++");
3226
3227 if (!Opts.ModuleCachePath.empty())
3228 GenerateArg(Consumer, OPT_fmodules_cache_path, Opts.ModuleCachePath);
3229
3230 for (const auto &File : Opts.PrebuiltModuleFiles)
3231 GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second);
3232
3233 for (const auto &Path : Opts.PrebuiltModulePaths)
3234 GenerateArg(Consumer, OPT_fprebuilt_module_path, Path);
3235
3236 for (const auto &Macro : Opts.ModulesIgnoreMacros)
3237 GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val());
3238
3239 auto Matches = [](const HeaderSearchOptions::Entry &Entry,
3241 std::optional<bool> IsFramework,
3242 std::optional<bool> IgnoreSysRoot) {
3243 return llvm::is_contained(Groups, Entry.Group) &&
3244 (!IsFramework || (Entry.IsFramework == *IsFramework)) &&
3245 (!IgnoreSysRoot || (Entry.IgnoreSysRoot == *IgnoreSysRoot));
3246 };
3247
3248 auto It = Opts.UserEntries.begin();
3249 auto End = Opts.UserEntries.end();
3250
3251 // Add -I... and -F... options in order.
3252 for (; It < End && Matches(*It, {frontend::Angled}, std::nullopt, true);
3253 ++It) {
3254 OptSpecifier Opt = [It, Matches]() {
3255 if (Matches(*It, frontend::Angled, true, true))
3256 return OPT_F;
3257 if (Matches(*It, frontend::Angled, false, true))
3258 return OPT_I;
3259 llvm_unreachable("Unexpected HeaderSearchOptions::Entry.");
3260 }();
3261
3262 GenerateArg(Consumer, Opt, It->Path);
3263 };
3264
3265 // Note: some paths that came from "[-iprefix=xx] -iwithprefixbefore=yy" may
3266 // have already been generated as "-I[xx]yy". If that's the case, their
3267 // position on command line was such that this has no semantic impact on
3268 // include paths.
3269 for (; It < End &&
3270 Matches(*It, {frontend::After, frontend::Angled}, false, true);
3271 ++It) {
3272 OptSpecifier Opt =
3273 It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;
3274 GenerateArg(Consumer, Opt, It->Path);
3275 }
3276
3277 // Note: Some paths that came from "-idirafter=xxyy" may have already been
3278 // generated as "-iwithprefix=xxyy". If that's the case, their position on
3279 // command line was such that this has no semantic impact on include paths.
3280 for (; It < End && Matches(*It, {frontend::After}, false, true); ++It)
3281 GenerateArg(Consumer, OPT_idirafter, It->Path);
3282 for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It)
3283 GenerateArg(Consumer, OPT_iquote, It->Path);
3284 for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt);
3285 ++It)
3286 GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
3287 It->Path);
3288 for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
3289 GenerateArg(Consumer, OPT_iframework, It->Path);
3290 for (; It < End && Matches(*It, {frontend::System}, true, false); ++It)
3291 GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path);
3292
3293 // Add the paths for the various language specific isystem flags.
3294 for (; It < End && Matches(*It, {frontend::CSystem}, false, true); ++It)
3295 GenerateArg(Consumer, OPT_c_isystem, It->Path);
3296 for (; It < End && Matches(*It, {frontend::CXXSystem}, false, true); ++It)
3297 GenerateArg(Consumer, OPT_cxx_isystem, It->Path);
3298 for (; It < End && Matches(*It, {frontend::ObjCSystem}, false, true); ++It)
3299 GenerateArg(Consumer, OPT_objc_isystem, It->Path);
3300 for (; It < End && Matches(*It, {frontend::ObjCXXSystem}, false, true); ++It)
3301 GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);
3302
3303 // Add the internal paths from a driver that detects standard include paths.
3304 // Note: Some paths that came from "-internal-isystem" arguments may have
3305 // already been generated as "-isystem". If that's the case, their position on
3306 // command line was such that this has no semantic impact on include paths.
3307 for (; It < End &&
3308 Matches(*It, {frontend::System, frontend::ExternCSystem}, false, true);
3309 ++It) {
3310 OptSpecifier Opt = It->Group == frontend::System
3311 ? OPT_internal_isystem
3312 : OPT_internal_externc_isystem;
3313 GenerateArg(Consumer, Opt, It->Path);
3314 }
3315
3316 assert(It == End && "Unhandled HeaderSearchOption::Entry.");
3317
3318 // Add the path prefixes which are implicitly treated as being system headers.
3319 for (const auto &P : Opts.SystemHeaderPrefixes) {
3320 OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
3321 : OPT_no_system_header_prefix;
3322 GenerateArg(Consumer, Opt, P.Prefix);
3323 }
3324
3325 for (const std::string &F : Opts.VFSOverlayFiles)
3326 GenerateArg(Consumer, OPT_ivfsoverlay, F);
3327}
3328
3329static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
3330 DiagnosticsEngine &Diags,
3331 const std::string &WorkingDir) {
3332 unsigned NumErrorsBefore = Diags.getNumErrors();
3333
3334 HeaderSearchOptions *HeaderSearchOpts = &Opts;
3335
3336#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3337 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3338#include "clang/Driver/Options.inc"
3339#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3340
3341 if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
3342 Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
3343
3344 // Canonicalize -fmodules-cache-path before storing it.
3345 SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path));
3346 if (!(P.empty() || llvm::sys::path::is_absolute(P))) {
3347 if (WorkingDir.empty())
3348 llvm::sys::fs::make_absolute(P);
3349 else
3350 llvm::sys::fs::make_absolute(WorkingDir, P);
3351 }
3352 llvm::sys::path::remove_dots(P);
3353 Opts.ModuleCachePath = std::string(P);
3354
3355 // Only the -fmodule-file=<name>=<file> form.
3356 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3357 StringRef Val = A->getValue();
3358 if (Val.contains('=')) {
3359 auto Split = Val.split('=');
3360 Opts.PrebuiltModuleFiles.insert_or_assign(
3361 std::string(Split.first), std::string(Split.second));
3362 }
3363 }
3364 for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
3365 Opts.AddPrebuiltModulePath(A->getValue());
3366
3367 for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
3368 StringRef MacroDef = A->getValue();
3369 Opts.ModulesIgnoreMacros.insert(
3370 llvm::CachedHashString(MacroDef.split('=').first));
3371 }
3372
3373 // Add -I... and -F... options in order.
3374 bool IsSysrootSpecified =
3375 Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
3376
3377 // Expand a leading `=` to the sysroot if one was passed (and it's not a
3378 // framework flag).
3379 auto PrefixHeaderPath = [IsSysrootSpecified,
3380 &Opts](const llvm::opt::Arg *A,
3381 bool IsFramework = false) -> std::string {
3382 assert(A->getNumValues() && "Unexpected empty search path flag!");
3383 if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') {
3384 SmallString<32> Buffer;
3385 llvm::sys::path::append(Buffer, Opts.Sysroot,
3386 llvm::StringRef(A->getValue()).substr(1));
3387 return std::string(Buffer);
3388 }
3389 return A->getValue();
3390 };
3391
3392 for (const auto *A : Args.filtered(OPT_I, OPT_F)) {
3393 bool IsFramework = A->getOption().matches(OPT_F);
3394 Opts.AddPath(PrefixHeaderPath(A, IsFramework), frontend::Angled,
3395 IsFramework, /*IgnoreSysroot=*/true);
3396 }
3397
3398 // Add -iprefix/-iwithprefix/-iwithprefixbefore options.
3399 StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
3400 for (const auto *A :
3401 Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
3402 if (A->getOption().matches(OPT_iprefix))
3403 Prefix = A->getValue();
3404 else if (A->getOption().matches(OPT_iwithprefix))
3405 Opts.AddPath(Prefix.str() + A->getValue(), frontend::After, false, true);
3406 else
3407 Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
3408 }
3409
3410 for (const auto *A : Args.filtered(OPT_idirafter))
3411 Opts.AddPath(PrefixHeaderPath(A), frontend::After, false, true);
3412 for (const auto *A : Args.filtered(OPT_iquote))
3413 Opts.AddPath(PrefixHeaderPath(A), frontend::Quoted, false, true);
3414
3415 for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) {
3416 if (A->getOption().matches(OPT_iwithsysroot)) {
3417 Opts.AddPath(A->getValue(), frontend::System, false,
3418 /*IgnoreSysRoot=*/false);
3419 continue;
3420 }
3421 Opts.AddPath(PrefixHeaderPath(A), frontend::System, false, true);
3422 }
3423 for (const auto *A : Args.filtered(OPT_iframework))
3424 Opts.AddPath(A->getValue(), frontend::System, true, true);
3425 for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
3426 Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
3427 /*IgnoreSysRoot=*/false);
3428
3429 // Add the paths for the various language specific isystem flags.
3430 for (const auto *A : Args.filtered(OPT_c_isystem))
3431 Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
3432 for (const auto *A : Args.filtered(OPT_cxx_isystem))
3433 Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
3434 for (const auto *A : Args.filtered(OPT_objc_isystem))
3435 Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
3436 for (const auto *A : Args.filtered(OPT_objcxx_isystem))
3437 Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
3438
3439 // Add the internal paths from a driver that detects standard include paths.
3440 for (const auto *A :
3441 Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
3443 if (A->getOption().matches(OPT_internal_externc_isystem))
3445 Opts.AddPath(A->getValue(), Group, false, true);
3446 }
3447
3448 // Add the path prefixes which are implicitly treated as being system headers.
3449 for (const auto *A :
3450 Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
3452 A->getValue(), A->getOption().matches(OPT_system_header_prefix));
3453
3454 for (const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))
3455 Opts.AddVFSOverlayFile(A->getValue());
3456
3457 return Diags.getNumErrors() == NumErrorsBefore;
3458}
3459
3461 ArgumentConsumer Consumer) {
3462 if (!Opts.SwiftVersion.empty())
3463 GenerateArg(Consumer, OPT_fapinotes_swift_version,
3464 Opts.SwiftVersion.getAsString());
3465
3466 for (const auto &Path : Opts.ModuleSearchPaths)
3467 GenerateArg(Consumer, OPT_iapinotes_modules, Path);
3468}
3469
3470static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
3471 DiagnosticsEngine &diags) {
3472 if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
3473 if (Opts.SwiftVersion.tryParse(A->getValue()))
3474 diags.Report(diag::err_drv_invalid_value)
3475 << A->getAsString(Args) << A->getValue();
3476 }
3477 for (const Arg *A : Args.filtered(OPT_iapinotes_modules))
3478 Opts.ModuleSearchPaths.push_back(A->getValue());
3479}
3480
3481static void GeneratePointerAuthArgs(const LangOptions &Opts,
3482 ArgumentConsumer Consumer) {
3483 if (Opts.PointerAuthIntrinsics)
3484 GenerateArg(Consumer, OPT_fptrauth_intrinsics);
3485 if (Opts.PointerAuthCalls)
3486 GenerateArg(Consumer, OPT_fptrauth_calls);
3487 if (Opts.PointerAuthReturns)
3488 GenerateArg(Consumer, OPT_fptrauth_returns);
3489 if (Opts.PointerAuthIndirectGotos)
3490 GenerateArg(Consumer, OPT_fptrauth_indirect_gotos);
3491 if (Opts.PointerAuthAuthTraps)
3492 GenerateArg(Consumer, OPT_fptrauth_auth_traps);
3493 if (Opts.PointerAuthVTPtrAddressDiscrimination)
3494 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);
3495 if (Opts.PointerAuthVTPtrTypeDiscrimination)
3496 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);
3497 if (Opts.PointerAuthTypeInfoVTPtrDiscrimination)
3498 GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination);
3499 if (Opts.PointerAuthFunctionTypeDiscrimination)
3500 GenerateArg(Consumer, OPT_fptrauth_function_pointer_type_discrimination);
3501 if (Opts.PointerAuthInitFini)
3502 GenerateArg(Consumer, OPT_fptrauth_init_fini);
3503 if (Opts.PointerAuthInitFiniAddressDiscrimination)
3504 GenerateArg(Consumer, OPT_fptrauth_init_fini_address_discrimination);
3505 if (Opts.PointerAuthELFGOT)
3506 GenerateArg(Consumer, OPT_fptrauth_elf_got);
3507 if (Opts.AArch64JumpTableHardening)
3508 GenerateArg(Consumer, OPT_faarch64_jump_table_hardening);
3509}
3510
3511static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
3512 DiagnosticsEngine &Diags) {
3513 Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
3514 Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);
3515 Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);
3516 Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);
3517 Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);
3518 Opts.PointerAuthVTPtrAddressDiscrimination =
3519 Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);
3520 Opts.PointerAuthVTPtrTypeDiscrimination =
3521 Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);
3522 Opts.PointerAuthTypeInfoVTPtrDiscrimination =
3523 Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination);
3524 Opts.PointerAuthFunctionTypeDiscrimination =
3525 Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination);
3526 Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);
3527 Opts.PointerAuthInitFiniAddressDiscrimination =
3528 Args.hasArg(OPT_fptrauth_init_fini_address_discrimination);
3529 Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got);
3530 Opts.AArch64JumpTableHardening =
3531 Args.hasArg(OPT_faarch64_jump_table_hardening);
3532}
3533
3534/// Check if input file kind and language standard are compatible.
3536 const LangStandard &S) {
3537 switch (IK.getLanguage()) {
3538 case Language::Unknown:
3539 case Language::LLVM_IR:
3540 case Language::CIR:
3541 llvm_unreachable("should not parse language flags for this input");
3542
3543 case Language::C:
3544 case Language::ObjC:
3545 return S.getLanguage() == Language::C;
3546
3547 case Language::OpenCL:
3548 return S.getLanguage() == Language::OpenCL ||
3549 S.getLanguage() == Language::OpenCLCXX;
3550
3552 return S.getLanguage() == Language::OpenCLCXX;
3553
3554 case Language::CXX:
3555 case Language::ObjCXX:
3556 return S.getLanguage() == Language::CXX;
3557
3558 case Language::CUDA:
3559 // FIXME: What -std= values should be permitted for CUDA compilations?
3560 return S.getLanguage() == Language::CUDA ||
3561 S.getLanguage() == Language::CXX;
3562
3563 case Language::HIP:
3564 return S.getLanguage() == Language::CXX || S.getLanguage() == Language::HIP;
3565
3566 case Language::Asm:
3567 // Accept (and ignore) all -std= values.
3568 // FIXME: The -std= value is not ignored; it affects the tokenization
3569 // and preprocessing rules if we're preprocessing this asm input.
3570 return true;
3571
3572 case Language::HLSL:
3573 return S.getLanguage() == Language::HLSL;
3574 }
3575
3576 llvm_unreachable("unexpected input language");
3577}
3578
3579/// Get language name for given input kind.
3580static StringRef GetInputKindName(InputKind IK) {
3581 switch (IK.getLanguage()) {
3582 case Language::C:
3583 return "C";
3584 case Language::ObjC:
3585 return "Objective-C";
3586 case Language::CXX:
3587 return "C++";
3588 case Language::ObjCXX:
3589 return "Objective-C++";
3590 case Language::OpenCL:
3591 return "OpenCL";
3593 return "C++ for OpenCL";
3594 case Language::CUDA:
3595 return "CUDA";
3596 case Language::HIP:
3597 return "HIP";
3598
3599 case Language::Asm:
3600 return "Asm";
3601 case Language::LLVM_IR:
3602 return "LLVM IR";
3603 case Language::CIR:
3604 return "Clang IR";
3605
3606 case Language::HLSL:
3607 return "HLSL";
3608
3609 case Language::Unknown:
3610 break;
3611 }
3612 llvm_unreachable("unknown input language");
3613}
3614
3615void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
3616 ArgumentConsumer Consumer,
3617 const llvm::Triple &T,
3618 InputKind IK) {
3619 if (IK.getFormat() == InputKind::Precompiled ||
3621 IK.getLanguage() == Language::CIR) {
3622 if (Opts.ObjCAutoRefCount)
3623 GenerateArg(Consumer, OPT_fobjc_arc);
3624 if (Opts.PICLevel != 0)
3625 GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));
3626 if (Opts.PIE)
3627 GenerateArg(Consumer, OPT_pic_is_pie);
3628 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3629 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3630
3631 return;
3632 }
3633
3634 OptSpecifier StdOpt;
3635 switch (Opts.LangStd) {
3636 case LangStandard::lang_opencl10:
3637 case LangStandard::lang_opencl11:
3638 case LangStandard::lang_opencl12:
3639 case LangStandard::lang_opencl20:
3640 case LangStandard::lang_opencl30:
3641 case LangStandard::lang_openclcpp10:
3642 case LangStandard::lang_openclcpp2021:
3643 StdOpt = OPT_cl_std_EQ;
3644 break;
3645 default:
3646 StdOpt = OPT_std_EQ;
3647 break;
3648 }
3649
3651 GenerateArg(Consumer, StdOpt, LangStandard.getName());
3652
3653 if (Opts.IncludeDefaultHeader)
3654 GenerateArg(Consumer, OPT_finclude_default_header);
3655 if (Opts.DeclareOpenCLBuiltins)
3656 GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);
3657
3658 const LangOptions *LangOpts = &Opts;
3659
3660#define LANG_OPTION_WITH_MARSHALLING(...) \
3661 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3662#include "clang/Driver/Options.inc"
3663#undef LANG_OPTION_WITH_MARSHALLING
3664
3665 // The '-fcf-protection=' option is generated by CodeGenOpts generator.
3666
3667 if (Opts.ObjC) {
3668 GenerateArg(Consumer, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString());
3669
3670 if (Opts.GC == LangOptions::GCOnly)
3671 GenerateArg(Consumer, OPT_fobjc_gc_only);
3672 else if (Opts.GC == LangOptions::HybridGC)
3673 GenerateArg(Consumer, OPT_fobjc_gc);
3674 else if (Opts.ObjCAutoRefCount == 1)
3675 GenerateArg(Consumer, OPT_fobjc_arc);
3676
3677 if (Opts.ObjCWeakRuntime)
3678 GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);
3679
3680 if (Opts.ObjCWeak)
3681 GenerateArg(Consumer, OPT_fobjc_weak);
3682
3683 if (Opts.ObjCSubscriptingLegacyRuntime)
3684 GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime);
3685 }
3686
3687 if (Opts.GNUCVersion != 0) {
3688 unsigned Major = Opts.GNUCVersion / 100 / 100;
3689 unsigned Minor = (Opts.GNUCVersion / 100) % 100;
3690 unsigned Patch = Opts.GNUCVersion % 100;
3691 GenerateArg(Consumer, OPT_fgnuc_version_EQ,
3692 Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch));
3693 }
3694
3695 if (Opts.IgnoreXCOFFVisibility)
3696 GenerateArg(Consumer, OPT_mignore_xcoff_visibility);
3697
3698 if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) {
3699 GenerateArg(Consumer, OPT_ftrapv);
3700 GenerateArg(Consumer, OPT_ftrapv_handler, Opts.OverflowHandler);
3701 } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
3702 GenerateArg(Consumer, OPT_fwrapv);
3703 }
3704
3705 if (Opts.MSCompatibilityVersion != 0) {
3706 unsigned Major = Opts.MSCompatibilityVersion / 10000000;
3707 unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;
3708 unsigned Subminor = Opts.MSCompatibilityVersion % 100000;
3709 GenerateArg(Consumer, OPT_fms_compatibility_version,
3710 Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor));
3711 }
3712
3713 if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
3714 T.isOSzOS()) {
3715 if (!Opts.Trigraphs)
3716 GenerateArg(Consumer, OPT_fno_trigraphs);
3717 } else {
3718 if (Opts.Trigraphs)
3719 GenerateArg(Consumer, OPT_ftrigraphs);
3720 }
3721
3722 if (T.isOSzOS() && !Opts.ZOSExt)
3723 GenerateArg(Consumer, OPT_fno_zos_extensions);
3724 else if (Opts.ZOSExt)
3725 GenerateArg(Consumer, OPT_fzos_extensions);
3726
3727 if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
3728 GenerateArg(Consumer, OPT_fblocks);
3729
3730 if (Opts.ConvergentFunctions)
3731 GenerateArg(Consumer, OPT_fconvergent_functions);
3732 else
3733 GenerateArg(Consumer, OPT_fno_convergent_functions);
3734
3735 if (Opts.NoBuiltin && !Opts.Freestanding)
3736 GenerateArg(Consumer, OPT_fno_builtin);
3737
3738 if (!Opts.NoBuiltin)
3739 for (const auto &Func : Opts.NoBuiltinFuncs)
3740 GenerateArg(Consumer, OPT_fno_builtin_, Func);
3741
3742 if (Opts.LongDoubleSize == 128)
3743 GenerateArg(Consumer, OPT_mlong_double_128);
3744 else if (Opts.LongDoubleSize == 64)
3745 GenerateArg(Consumer, OPT_mlong_double_64);
3746 else if (Opts.LongDoubleSize == 80)
3747 GenerateArg(Consumer, OPT_mlong_double_80);
3748
3749 // Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
3750
3751 // OpenMP was requested via '-fopenmp', not implied by '-fopenmp-simd' or
3752 // '-fopenmp-targets='.
3753 if (Opts.OpenMP && !Opts.OpenMPSimd) {
3754 GenerateArg(Consumer, OPT_fopenmp);
3755
3756 if (Opts.OpenMP != 51)
3757 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3758
3759 if (!Opts.OpenMPUseTLS)
3760 GenerateArg(Consumer, OPT_fnoopenmp_use_tls);
3761
3762 if (Opts.OpenMPIsTargetDevice)
3763 GenerateArg(Consumer, OPT_fopenmp_is_target_device);
3764
3765 if (Opts.OpenMPIRBuilder)
3766 GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder);
3767 }
3768
3769 if (Opts.OpenMPSimd) {
3770 GenerateArg(Consumer, OPT_fopenmp_simd);
3771
3772 if (Opts.OpenMP != 51)
3773 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3774 }
3775
3776 if (Opts.OpenMPThreadSubscription)
3777 GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription);
3778
3779 if (Opts.OpenMPTeamSubscription)
3780 GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription);
3781
3782 if (Opts.OpenMPTargetDebug != 0)
3783 GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ,
3784 Twine(Opts.OpenMPTargetDebug));
3785
3786 if (Opts.OpenMPCUDANumSMs != 0)
3787 GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ,
3788 Twine(Opts.OpenMPCUDANumSMs));
3789
3790 if (Opts.OpenMPCUDABlocksPerSM != 0)
3791 GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ,
3792 Twine(Opts.OpenMPCUDABlocksPerSM));
3793
3794 if (Opts.OpenMPCUDAReductionBufNum != 1024)
3795 GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
3796 Twine(Opts.OpenMPCUDAReductionBufNum));
3797
3798 if (!Opts.OMPTargetTriples.empty()) {
3799 std::string Targets;
3800 llvm::raw_string_ostream OS(Targets);
3801 llvm::interleave(
3802 Opts.OMPTargetTriples, OS,
3803 [&OS](const llvm::Triple &T) { OS << T.str(); }, ",");
3804 GenerateArg(Consumer, OPT_fopenmp_targets_EQ, Targets);
3805 }
3806
3807 if (!Opts.OMPHostIRFile.empty())
3808 GenerateArg(Consumer, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile);
3809
3810 if (Opts.OpenMPCUDAMode)
3811 GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
3812
3813 if (Opts.OpenACC) {
3814 GenerateArg(Consumer, OPT_fopenacc);
3815 if (!Opts.OpenACCMacroOverride.empty())
3816 GenerateArg(Consumer, OPT_openacc_macro_override,
3818 }
3819
3820 // The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
3821 // generated from CodeGenOptions.
3822
3823 if (Opts.DefaultFPContractMode == LangOptions::FPM_Fast)
3824 GenerateArg(Consumer, OPT_ffp_contract, "fast");
3825 else if (Opts.DefaultFPContractMode == LangOptions::FPM_On)
3826 GenerateArg(Consumer, OPT_ffp_contract, "on");
3827 else if (Opts.DefaultFPContractMode == LangOptions::FPM_Off)
3828 GenerateArg(Consumer, OPT_ffp_contract, "off");
3829 else if (Opts.DefaultFPContractMode == LangOptions::FPM_FastHonorPragmas)
3830 GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas");
3831
3832 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3833 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3834
3835 // Conflating '-fsanitize-system-ignorelist' and '-fsanitize-ignorelist'.
3836 for (const std::string &F : Opts.NoSanitizeFiles)
3837 GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);
3838
3839 switch (Opts.getClangABICompat()) {
3841 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "3.8");
3842 break;
3844 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "4.0");
3845 break;
3847 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "6.0");
3848 break;
3850 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "7.0");
3851 break;
3853 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "9.0");
3854 break;
3856 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "11.0");
3857 break;
3859 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "12.0");
3860 break;
3862 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "14.0");
3863 break;
3865 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "15.0");
3866 break;
3868 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0");
3869 break;
3871 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0");
3872 break;
3874 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "19.0");
3875 break;
3877 break;
3878 }
3879
3880 if (Opts.getSignReturnAddressScope() ==
3882 GenerateArg(Consumer, OPT_msign_return_address_EQ, "all");
3883 else if (Opts.getSignReturnAddressScope() ==
3885 GenerateArg(Consumer, OPT_msign_return_address_EQ, "non-leaf");
3886
3887 if (Opts.getSignReturnAddressKey() ==
3889 GenerateArg(Consumer, OPT_msign_return_address_key_EQ, "b_key");
3890
3891 if (Opts.CXXABI)
3892 GenerateArg(Consumer, OPT_fcxx_abi_EQ,
3894
3895 if (Opts.RelativeCXXABIVTables)
3896 GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables);
3897 else
3898 GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables);
3899
3900 if (Opts.UseTargetPathSeparator)
3901 GenerateArg(Consumer, OPT_ffile_reproducible);
3902 else
3903 GenerateArg(Consumer, OPT_fno_file_reproducible);
3904
3905 for (const auto &MP : Opts.MacroPrefixMap)
3906 GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second);
3907
3908 if (!Opts.RandstructSeed.empty())
3909 GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed);
3910}
3911
3912bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
3913 InputKind IK, const llvm::Triple &T,
3914 std::vector<std::string> &Includes,
3915 DiagnosticsEngine &Diags) {
3916 unsigned NumErrorsBefore = Diags.getNumErrors();
3917
3918 if (IK.getFormat() == InputKind::Precompiled ||
3920 IK.getLanguage() == Language::CIR) {
3921 // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
3922 // PassManager in BackendUtil.cpp. They need to be initialized no matter
3923 // what the input type is.
3924 if (Args.hasArg(OPT_fobjc_arc))
3925 Opts.ObjCAutoRefCount = 1;
3926 // PICLevel and PIELevel are needed during code generation and this should
3927 // be set regardless of the input type.
3928 Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
3929 Opts.PIE = Args.hasArg(OPT_pic_is_pie);
3930 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
3931 Diags, Opts.Sanitize);
3932
3933 return Diags.getNumErrors() == NumErrorsBefore;
3934 }
3935
3936 // Other LangOpts are only initialized when the input is not AST or LLVM IR.
3937 // FIXME: Should we really be parsing this for an Language::Asm input?
3938
3939 // FIXME: Cleanup per-file based stuff.
3941 if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
3942 LangStd = LangStandard::getLangKind(A->getValue());
3943 if (LangStd == LangStandard::lang_unspecified) {
3944 Diags.Report(diag::err_drv_invalid_value)
3945 << A->getAsString(Args) << A->getValue();
3946 // Report supported standards with short description.
3947 for (unsigned KindValue = 0;
3948 KindValue != LangStandard::lang_unspecified;
3949 ++KindValue) {
3951 static_cast<LangStandard::Kind>(KindValue));
3953 auto Diag = Diags.Report(diag::note_drv_use_standard);
3954 Diag << Std.getName() << Std.getDescription();
3955 unsigned NumAliases = 0;
3956#define LANGSTANDARD(id, name, lang, desc, features)
3957#define LANGSTANDARD_ALIAS(id, alias) \
3958 if (KindValue == LangStandard::lang_##id) ++NumAliases;
3959#define LANGSTANDARD_ALIAS_DEPR(id, alias)
3960#include "clang/Basic/LangStandards.def"
3961 Diag << NumAliases;
3962#define LANGSTANDARD(id, name, lang, desc, features)
3963#define LANGSTANDARD_ALIAS(id, alias) \
3964 if (KindValue == LangStandard::lang_##id) Diag << alias;
3965#define LANGSTANDARD_ALIAS_DEPR(id, alias)
3966#include "clang/Basic/LangStandards.def"
3967 }
3968 }
3969 } else {
3970 // Valid standard, check to make sure language and standard are
3971 // compatible.
3974 Diags.Report(diag::err_drv_argument_not_allowed_with)
3975 << A->getAsString(Args) << GetInputKindName(IK);
3976 }
3977 }
3978 }
3979
3980 // -cl-std only applies for OpenCL language standards.
3981 // Override the -std option in this case.
3982 if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
3983 LangStandard::Kind OpenCLLangStd
3984 = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
3985 .Cases("cl", "CL", LangStandard::lang_opencl10)
3986 .Cases("cl1.0", "CL1.0", LangStandard::lang_opencl10)
3987 .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
3988 .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
3989 .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
3990 .Cases("cl3.0", "CL3.0", LangStandard::lang_opencl30)
3991 .Cases("clc++", "CLC++", LangStandard::lang_openclcpp10)
3992 .Cases("clc++1.0", "CLC++1.0", LangStandard::lang_openclcpp10)
3993 .Cases("clc++2021", "CLC++2021", LangStandard::lang_openclcpp2021)
3995
3996 if (OpenCLLangStd == LangStandard::lang_unspecified) {
3997 Diags.Report(diag::err_drv_invalid_value)
3998 << A->getAsString(Args) << A->getValue();
3999 }
4000 else
4001 LangStd = OpenCLLangStd;
4002 }
4003
4004 // These need to be parsed now. They are used to set OpenCL defaults.
4005 Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
4006 Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
4007
4008 LangOptions::setLangDefaults(Opts, IK.getLanguage(), T, Includes, LangStd);
4009
4010 // The key paths of codegen options defined in Options.td start with
4011 // "LangOpts->". Let's provide the expected variable name and type.
4012 LangOptions *LangOpts = &Opts;
4013
4014#define LANG_OPTION_WITH_MARSHALLING(...) \
4015 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4016#include "clang/Driver/Options.inc"
4017#undef LANG_OPTION_WITH_MARSHALLING
4018
4019 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4020 StringRef Name = A->getValue();
4021 if (Name == "full" || Name == "branch") {
4022 Opts.CFProtectionBranch = 1;
4023 }
4024 }
4025
4026 if (Opts.CFProtectionBranch) {
4027 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {
4028 const auto Scheme =
4029 llvm::StringSwitch<CFBranchLabelSchemeKind>(A->getValue())
4030#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \
4031 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)
4032#include "clang/Basic/CFProtectionOptions.def"
4034 Opts.setCFBranchLabelScheme(Scheme);
4035 }
4036 }
4037
4038 if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
4039 !Args.hasArg(OPT_sycl_std_EQ)) {
4040 // If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to
4041 // provide -sycl-std=, we want to default it to whatever the default SYCL
4042 // version is. I could not find a way to express this with the options
4043 // tablegen because we still want this value to be SYCL_None when the user
4044 // is not in device or host mode.
4045 Opts.setSYCLVersion(LangOptions::SYCL_Default);
4046 }
4047
4048 if (Opts.ObjC) {
4049 if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
4050 StringRef value = arg->getValue();
4051 if (Opts.ObjCRuntime.tryParse(value))
4052 Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
4053 }
4054
4055 if (Args.hasArg(OPT_fobjc_gc_only))
4056 Opts.setGC(LangOptions::GCOnly);
4057 else if (Args.hasArg(OPT_fobjc_gc))
4058 Opts.setGC(LangOptions::HybridGC);
4059 else if (Args.hasArg(OPT_fobjc_arc)) {
4060 Opts.ObjCAutoRefCount = 1;
4061 if (!Opts.ObjCRuntime.allowsARC())
4062 Diags.Report(diag::err_arc_unsupported_on_runtime);
4063 }
4064
4065 // ObjCWeakRuntime tracks whether the runtime supports __weak, not
4066 // whether the feature is actually enabled. This is predominantly
4067 // determined by -fobjc-runtime, but we allow it to be overridden
4068 // from the command line for testing purposes.
4069 if (Args.hasArg(OPT_fobjc_runtime_has_weak))
4070 Opts.ObjCWeakRuntime = 1;
4071 else
4072 Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();
4073
4074 // ObjCWeak determines whether __weak is actually enabled.
4075 // Note that we allow -fno-objc-weak to disable this even in ARC mode.
4076 if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
4077 if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
4078 assert(!Opts.ObjCWeak);
4079 } else if (Opts.getGC() != LangOptions::NonGC) {
4080 Diags.Report(diag::err_objc_weak_with_gc);
4081 } else if (!Opts.ObjCWeakRuntime) {
4082 Diags.Report(diag::err_objc_weak_unsupported);
4083 } else {
4084 Opts.ObjCWeak = 1;
4085 }
4086 } else if (Opts.ObjCAutoRefCount) {
4087 Opts.ObjCWeak = Opts.ObjCWeakRuntime;
4088 }
4089
4090 if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
4091 Opts.ObjCSubscriptingLegacyRuntime =
4093 }
4094
4095 if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
4096 // Check that the version has 1 to 3 components and the minor and patch
4097 // versions fit in two decimal digits.
4098 VersionTuple GNUCVer;
4099 bool Invalid = GNUCVer.tryParse(A->getValue());
4100 unsigned Major = GNUCVer.getMajor();
4101 unsigned Minor = GNUCVer.getMinor().value_or(0);
4102 unsigned Patch = GNUCVer.getSubminor().value_or(0);
4103 if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
4104 Diags.Report(diag::err_drv_invalid_value)
4105 << A->getAsString(Args) << A->getValue();
4106 }
4107 Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
4108 }
4109
4110 if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility)))
4111 Opts.IgnoreXCOFFVisibility = 1;
4112
4113 if (Args.hasArg(OPT_ftrapv)) {
4114 Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
4115 // Set the handler, if one is specified.
4116 Opts.OverflowHandler =
4117 std::string(Args.getLastArgValue(OPT_ftrapv_handler));
4118 }
4119 else if (Args.hasArg(OPT_fwrapv))
4120 Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
4121
4122 Opts.MSCompatibilityVersion = 0;
4123 if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
4124 VersionTuple VT;
4125 if (VT.tryParse(A->getValue()))
4126 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
4127 << A->getValue();
4128 Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
4129 VT.getMinor().value_or(0) * 100000 +
4130 VT.getSubminor().value_or(0);
4131 }
4132
4133 // Mimicking gcc's behavior, trigraphs are only enabled if -trigraphs
4134 // is specified, or -std is set to a conforming mode.
4135 // Trigraphs are disabled by default in C++17 and C23 onwards.
4136 // For z/OS, trigraphs are enabled by default (without regard to the above).
4137 Opts.Trigraphs =
4138 (!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
4139 T.isOSzOS();
4140 Opts.Trigraphs =
4141 Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
4142
4143 Opts.ZOSExt =
4144 Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions, T.isOSzOS());
4145
4146 Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
4147 && Opts.OpenCLVersion == 200);
4148
4149 bool HasConvergentOperations = Opts.OpenMPIsTargetDevice || Opts.OpenCL ||
4150 Opts.CUDAIsDevice || Opts.SYCLIsDevice ||
4151 Opts.HLSL || T.isAMDGPU() || T.isNVPTX();
4152 Opts.ConvergentFunctions =
4153 Args.hasFlag(OPT_fconvergent_functions, OPT_fno_convergent_functions,
4154 HasConvergentOperations);
4155
4156 Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
4157 if (!Opts.NoBuiltin)
4159 if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
4160 if (A->getOption().matches(options::OPT_mlong_double_64))
4161 Opts.LongDoubleSize = 64;
4162 else if (A->getOption().matches(options::OPT_mlong_double_80))
4163 Opts.LongDoubleSize = 80;
4164 else if (A->getOption().matches(options::OPT_mlong_double_128))
4165 Opts.LongDoubleSize = 128;
4166 else
4167 Opts.LongDoubleSize = 0;
4168 }
4169 if (Opts.FastRelaxedMath || Opts.CLUnsafeMath)
4170 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4171
4172 llvm::sort(Opts.ModuleFeatures);
4173
4174 // -mrtd option
4175 if (Arg *A = Args.getLastArg(OPT_mrtd)) {
4176 if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
4177 Diags.Report(diag::err_drv_argument_not_allowed_with)
4178 << A->getSpelling() << "-fdefault-calling-conv";
4179 else {
4180 switch (T.getArch()) {
4181 case llvm::Triple::x86:
4182 Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
4183 break;
4184 case llvm::Triple::m68k:
4185 Opts.setDefaultCallingConv(LangOptions::DCC_RtdCall);
4186 break;
4187 default:
4188 Diags.Report(diag::err_drv_argument_not_allowed_with)
4189 << A->getSpelling() << T.getTriple();
4190 }
4191 }
4192 }
4193
4194 // Check if -fopenmp is specified and set default version to 5.0.
4195 Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;
4196 // Check if -fopenmp-simd is specified.
4197 bool IsSimdSpecified =
4198 Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
4199 /*Default=*/false);
4200 Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;
4201 Opts.OpenMPUseTLS =
4202 Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
4203 Opts.OpenMPIsTargetDevice =
4204 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_target_device);
4205 Opts.OpenMPIRBuilder =
4206 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_enable_irbuilder);
4207 bool IsTargetSpecified =
4208 Opts.OpenMPIsTargetDevice || Args.hasArg(options::OPT_fopenmp_targets_EQ);
4209
4210 if (Opts.OpenMP || Opts.OpenMPSimd) {
4211 if (int Version = getLastArgIntValue(
4212 Args, OPT_fopenmp_version_EQ,
4213 (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))
4214 Opts.OpenMP = Version;
4215 // Provide diagnostic when a given target is not expected to be an OpenMP
4216 // device or host.
4217 if (!Opts.OpenMPIsTargetDevice) {
4218 switch (T.getArch()) {
4219 default:
4220 break;
4221 // Add unsupported host targets here:
4222 case llvm::Triple::nvptx:
4223 case llvm::Triple::nvptx64:
4224 Diags.Report(diag::err_drv_omp_host_target_not_supported) << T.str();
4225 break;
4226 }
4227 }
4228 }
4229
4230 // Set the flag to prevent the implementation from emitting device exception
4231 // handling code for those requiring so.
4232 if ((Opts.OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) ||
4233 Opts.OpenCLCPlusPlus) {
4234
4235 Opts.Exceptions = 0;
4236 Opts.CXXExceptions = 0;
4237 }
4238 if (Opts.OpenMPIsTargetDevice && T.isNVPTX()) {
4239 Opts.OpenMPCUDANumSMs =
4240 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_number_of_sm_EQ,
4241 Opts.OpenMPCUDANumSMs, Diags);
4242 Opts.OpenMPCUDABlocksPerSM =
4243 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,
4244 Opts.OpenMPCUDABlocksPerSM, Diags);
4245 Opts.OpenMPCUDAReductionBufNum = getLastArgIntValue(
4246 Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
4247 Opts.OpenMPCUDAReductionBufNum, Diags);
4248 }
4249
4250 // Set the value of the debugging flag used in the new offloading device RTL.
4251 // Set either by a specific value or to a default if not specified.
4252 if (Opts.OpenMPIsTargetDevice && (Args.hasArg(OPT_fopenmp_target_debug) ||
4253 Args.hasArg(OPT_fopenmp_target_debug_EQ))) {
4254 Opts.OpenMPTargetDebug = getLastArgIntValue(
4255 Args, OPT_fopenmp_target_debug_EQ, Opts.OpenMPTargetDebug, Diags);
4256 if (!Opts.OpenMPTargetDebug && Args.hasArg(OPT_fopenmp_target_debug))
4257 Opts.OpenMPTargetDebug = 1;
4258 }
4259
4260 if (Opts.OpenMPIsTargetDevice) {
4261 if (Args.hasArg(OPT_fopenmp_assume_teams_oversubscription))
4262 Opts.OpenMPTeamSubscription = true;
4263 if (Args.hasArg(OPT_fopenmp_assume_threads_oversubscription))
4264 Opts.OpenMPThreadSubscription = true;
4265 }
4266
4267 // Get the OpenMP target triples if any.
4268 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
4269 enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
4270 auto getArchPtrSize = [](const llvm::Triple &T) {
4271 if (T.isArch16Bit())
4272 return Arch16Bit;
4273 if (T.isArch32Bit())
4274 return Arch32Bit;
4275 assert(T.isArch64Bit() && "Expected 64-bit architecture");
4276 return Arch64Bit;
4277 };
4278
4279 for (unsigned i = 0; i < A->getNumValues(); ++i) {
4280 llvm::Triple TT(A->getValue(i));
4281
4282 if (TT.getArch() == llvm::Triple::UnknownArch ||
4283 !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() ||
4284 TT.getArch() == llvm::Triple::spirv64 ||
4285 TT.getArch() == llvm::Triple::systemz ||
4286 TT.getArch() == llvm::Triple::loongarch64 ||
4287 TT.getArch() == llvm::Triple::nvptx ||
4288 TT.getArch() == llvm::Triple::nvptx64 ||
4289 TT.getArch() == llvm::Triple::amdgcn ||
4290 TT.getArch() == llvm::Triple::x86 ||
4291 TT.getArch() == llvm::Triple::x86_64))
4292 Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
4293 else if (getArchPtrSize(T) != getArchPtrSize(TT))
4294 Diags.Report(diag::err_drv_incompatible_omp_arch)
4295 << A->getValue(i) << T.str();
4296 else
4297 Opts.OMPTargetTriples.push_back(TT);
4298 }
4299 }
4300
4301 // Get OpenMP host file path if any and report if a non existent file is
4302 // found
4303 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) {
4304 Opts.OMPHostIRFile = A->getValue();
4305 if (!llvm::sys::fs::exists(Opts.OMPHostIRFile))
4306 Diags.Report(diag::err_drv_omp_host_ir_file_not_found)
4307 << Opts.OMPHostIRFile;
4308 }
4309
4310 // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options
4311 Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice &&
4312 (T.isNVPTX() || T.isAMDGCN()) &&
4313 Args.hasArg(options::OPT_fopenmp_cuda_mode);
4314
4315 // OpenACC Configuration.
4316 if (Args.hasArg(options::OPT_fopenacc)) {
4317 Opts.OpenACC = true;
4318
4319 if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override))
4320 Opts.OpenACCMacroOverride = A->getValue();
4321 }
4322
4323 // FIXME: Eliminate this dependency.
4324 unsigned Opt = getOptimizationLevel(Args, IK, Diags),
4325 OptSize = getOptimizationLevelSize(Args);
4326 Opts.Optimize = Opt != 0;
4327 Opts.OptimizeSize = OptSize != 0;
4328
4329 // This is the __NO_INLINE__ define, which just depends on things like the
4330 // optimization level and -fno-inline, not actually whether the backend has
4331 // inlining enabled.
4332 Opts.NoInlineDefine = !Opts.Optimize;
4333 if (Arg *InlineArg = Args.getLastArg(
4334 options::OPT_finline_functions, options::OPT_finline_hint_functions,
4335 options::OPT_fno_inline_functions, options::OPT_fno_inline))
4336 if (InlineArg->getOption().matches(options::OPT_fno_inline))
4337 Opts.NoInlineDefine = true;
4338
4339 if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
4340 StringRef Val = A->getValue();
4341 if (Val == "fast")
4342 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4343 else if (Val == "on")
4344 Opts.setDefaultFPContractMode(LangOptions::FPM_On);
4345 else if (Val == "off")
4346 Opts.setDefaultFPContractMode(LangOptions::FPM_Off);
4347 else if (Val == "fast-honor-pragmas")
4348 Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
4349 else
4350 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
4351 }
4352
4353 if (auto *A =
4354 Args.getLastArg(OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {
4355 for (int i = 0, n = A->getNumValues(); i != n; ++i) {
4357 llvm::StringSwitch<unsigned>(A->getValue(i))
4358 .Case("none", LangOptionsBase::None)
4359 .Case("all", LangOptionsBase::All)
4360 .Case("add-unsigned-overflow-test",
4362 .Case("add-signed-overflow-test",
4364 .Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst)
4365 .Case("unsigned-post-decr-while",
4367 .Default(0);
4368 }
4369 }
4370
4371 // Parse -fsanitize= arguments.
4372 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
4373 Diags, Opts.Sanitize);
4374 Opts.NoSanitizeFiles = Args.getAllArgValues(OPT_fsanitize_ignorelist_EQ);
4375 std::vector<std::string> systemIgnorelists =
4376 Args.getAllArgValues(OPT_fsanitize_system_ignorelist_EQ);
4377 Opts.NoSanitizeFiles.insert(Opts.NoSanitizeFiles.end(),
4378 systemIgnorelists.begin(),
4379 systemIgnorelists.end());
4380
4381 if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
4382 Opts.setClangABICompat(LangOptions::ClangABI::Latest);
4383
4384 StringRef Ver = A->getValue();
4385 std::pair<StringRef, StringRef> VerParts = Ver.split('.');
4386 unsigned Major, Minor = 0;
4387
4388 // Check the version number is valid: either 3.x (0 <= x <= 9) or
4389 // y or y.0 (4 <= y <= current version).
4390 if (!VerParts.first.starts_with("0") &&
4391 !VerParts.first.getAsInteger(10, Major) && 3 <= Major &&
4392 Major <= CLANG_VERSION_MAJOR &&
4393 (Major == 3
4394 ? VerParts.second.size() == 1 &&
4395 !VerParts.second.getAsInteger(10, Minor)
4396 : VerParts.first.size() == Ver.size() || VerParts.second == "0")) {
4397 // Got a valid version number.
4398 if (Major == 3 && Minor <= 8)
4399 Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8);
4400 else if (Major <= 4)
4401 Opts.setClangABICompat(LangOptions::ClangABI::Ver4);
4402 else if (Major <= 6)
4403 Opts.setClangABICompat(LangOptions::ClangABI::Ver6);
4404 else if (Major <= 7)
4405 Opts.setClangABICompat(LangOptions::ClangABI::Ver7);
4406 else if (Major <= 9)
4407 Opts.setClangABICompat(LangOptions::ClangABI::Ver9);
4408 else if (Major <= 11)
4409 Opts.setClangABICompat(LangOptions::ClangABI::Ver11);
4410 else if (Major <= 12)
4411 Opts.setClangABICompat(LangOptions::ClangABI::Ver12);
4412 else if (Major <= 14)
4413 Opts.setClangABICompat(LangOptions::ClangABI::Ver14);
4414 else if (Major <= 15)
4415 Opts.setClangABICompat(LangOptions::ClangABI::Ver15);
4416 else if (Major <= 17)
4417 Opts.setClangABICompat(LangOptions::ClangABI::Ver17);
4418 else if (Major <= 18)
4419 Opts.setClangABICompat(LangOptions::ClangABI::Ver18);
4420 else if (Major <= 19)
4421 Opts.setClangABICompat(LangOptions::ClangABI::Ver19);
4422 } else if (Ver != "latest") {
4423 Diags.Report(diag::err_drv_invalid_value)
4424 << A->getAsString(Args) << A->getValue();
4425 }
4426 }
4427
4428 if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) {
4429 StringRef SignScope = A->getValue();
4430
4431 if (SignScope.equals_insensitive("none"))
4432 Opts.setSignReturnAddressScope(
4434 else if (SignScope.equals_insensitive("all"))
4435 Opts.setSignReturnAddressScope(
4437 else if (SignScope.equals_insensitive("non-leaf"))
4438 Opts.setSignReturnAddressScope(
4440 else
4441 Diags.Report(diag::err_drv_invalid_value)
4442 << A->getAsString(Args) << SignScope;
4443
4444 if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
4445 StringRef SignKey = A->getValue();
4446 if (!SignScope.empty() && !SignKey.empty()) {
4447 if (SignKey == "a_key")
4448 Opts.setSignReturnAddressKey(
4450 else if (SignKey == "b_key")
4451 Opts.setSignReturnAddressKey(
4453 else
4454 Diags.Report(diag::err_drv_invalid_value)
4455 << A->getAsString(Args) << SignKey;
4456 }
4457 }
4458 }
4459
4460 // The value can be empty, which indicates the system default should be used.
4461 StringRef CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);
4462 if (!CXXABI.empty()) {
4464 Diags.Report(diag::err_invalid_cxx_abi) << CXXABI;
4465 } else {
4468 Diags.Report(diag::err_unsupported_cxx_abi) << CXXABI << T.str();
4469 else
4470 Opts.CXXABI = Kind;
4471 }
4472 }
4473
4474 Opts.RelativeCXXABIVTables =
4475 Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
4476 options::OPT_fno_experimental_relative_cxx_abi_vtables,
4478
4479 // RTTI is on by default.
4480 bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti);
4481 Opts.OmitVTableRTTI =
4482 Args.hasFlag(options::OPT_fexperimental_omit_vtable_rtti,
4483 options::OPT_fno_experimental_omit_vtable_rtti, false);
4484 if (Opts.OmitVTableRTTI && HasRTTI)
4485 Diags.Report(diag::err_drv_using_omit_rtti_component_without_no_rtti);
4486
4487 for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
4488 auto Split = StringRef(A).split('=');
4489 Opts.MacroPrefixMap.insert(
4490 {std::string(Split.first), std::string(Split.second)});
4491 }
4492
4494 !Args.getLastArg(OPT_fno_file_reproducible) &&
4495 (Args.getLastArg(OPT_ffile_compilation_dir_EQ) ||
4496 Args.getLastArg(OPT_fmacro_prefix_map_EQ) ||
4497 Args.getLastArg(OPT_ffile_reproducible));
4498
4499 // Error if -mvscale-min is unbounded.
4500 if (Arg *A = Args.getLastArg(options::OPT_mvscale_min_EQ)) {
4501 unsigned VScaleMin;
4502 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4503 Diags.Report(diag::err_cc1_unbounded_vscale_min);
4504 }
4505
4506 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) {
4507 std::ifstream SeedFile(A->getValue(0));
4508
4509 if (!SeedFile.is_open())
4510 Diags.Report(diag::err_drv_cannot_open_randomize_layout_seed_file)
4511 << A->getValue(0);
4512
4513 std::getline(SeedFile, Opts.RandstructSeed);
4514 }
4515
4516 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
4517 Opts.RandstructSeed = A->getValue(0);
4518
4519 // Validate options for HLSL
4520 if (Opts.HLSL) {
4521 // TODO: Revisit restricting SPIR-V to logical once we've figured out how to
4522 // handle PhysicalStorageBuffer64 memory model
4523 if (T.isDXIL() || T.isSPIRVLogical()) {
4524 enum { ShaderModel, VulkanEnv, ShaderStage };
4525 enum { OS, Environment };
4526
4527 int ExpectedOS = T.isSPIRVLogical() ? VulkanEnv : ShaderModel;
4528
4529 if (T.getOSName().empty()) {
4530 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4531 << ExpectedOS << OS << T.str();
4532 } else if (T.getEnvironmentName().empty()) {
4533 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4534 << ShaderStage << Environment << T.str();
4535 } else if (!T.isShaderStageEnvironment()) {
4536 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4537 << ShaderStage << T.getEnvironmentName() << T.str();
4538 }
4539
4540 if (T.isDXIL()) {
4541 if (!T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
4542 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4543 << ShaderModel << T.getOSName() << T.str();
4544 }
4545 // Validate that if fnative-half-type is given, that
4546 // the language standard is at least hlsl2018, and that
4547 // the target shader model is at least 6.2.
4548 if (Args.getLastArg(OPT_fnative_half_type)) {
4549 const LangStandard &Std =
4551 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018 &&
4552 T.getOSVersion() >= VersionTuple(6, 2)))
4553 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4554 << "-enable-16bit-types" << true << Std.getName()
4555 << T.getOSVersion().getAsString();
4556 }
4557 } else if (T.isSPIRVLogical()) {
4558 if (!T.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) {
4559 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4560 << VulkanEnv << T.getOSName() << T.str();
4561 }
4562 if (Args.getLastArg(OPT_fnative_half_type)) {
4563 const LangStandard &Std =
4565 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018))
4566 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4567 << "-fnative-half-type" << false << Std.getName();
4568 }
4569 } else {
4570 llvm_unreachable("expected DXIL or SPIR-V target");
4571 }
4572 } else
4573 Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
4574
4575 if (Opts.LangStd < LangStandard::lang_hlsl202x) {
4576 const LangStandard &Requested =
4578 const LangStandard &Recommended =
4579 LangStandard::getLangStandardForKind(LangStandard::lang_hlsl202x);
4580 Diags.Report(diag::warn_hlsl_langstd_minimal)
4581 << Requested.getName() << Recommended.getName();
4582 }
4583 }
4584
4585 return Diags.getNumErrors() == NumErrorsBefore;
4586}
4587
4589 switch (Action) {
4591 case frontend::ASTDump:
4592 case frontend::ASTPrint:
4593 case frontend::ASTView:
4595 case frontend::EmitBC:
4596 case frontend::EmitCIR:
4597 case frontend::EmitHTML:
4598 case frontend::EmitLLVM:
4601 case frontend::EmitObj:
4603 case frontend::FixIt:
4619 return false;
4620
4624 case frontend::InitOnly:
4630 return true;
4631 }
4632 llvm_unreachable("invalid frontend action");
4633}
4634
4636 ArgumentConsumer Consumer,
4637 const LangOptions &LangOpts,
4638 const FrontendOptions &FrontendOpts,
4639 const CodeGenOptions &CodeGenOpts) {
4640 const PreprocessorOptions *PreprocessorOpts = &Opts;
4641
4642#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4643 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4644#include "clang/Driver/Options.inc"
4645#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4646
4647 if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate)
4648 GenerateArg(Consumer, OPT_pch_through_hdrstop_use);
4649
4650 for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn)
4651 GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);
4652
4653 if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false))
4654 GenerateArg(Consumer, OPT_preamble_bytes_EQ,
4655 Twine(Opts.PrecompiledPreambleBytes.first) + "," +
4656 (Opts.PrecompiledPreambleBytes.second ? "1" : "0"));
4657
4658 for (const auto &M : Opts.Macros) {
4659 // Don't generate __CET__ macro definitions. They are implied by the
4660 // -fcf-protection option that is generated elsewhere.
4661 if (M.first == "__CET__=1" && !M.second &&
4662 !CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch)
4663 continue;
4664 if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn &&
4665 !CodeGenOpts.CFProtectionBranch)
4666 continue;
4667 if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn &&
4668 CodeGenOpts.CFProtectionBranch)
4669 continue;
4670
4671 GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first);
4672 }
4673
4674 for (const auto &I : Opts.Includes) {
4675 // Don't generate OpenCL includes. They are implied by other flags that are
4676 // generated elsewhere.
4677 if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader &&
4678 ((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") ||
4679 I == "opencl-c.h"))
4680 continue;
4681 // Don't generate HLSL includes. They are implied by other flags that are
4682 // generated elsewhere.
4683 if (LangOpts.HLSL && I == "hlsl.h")
4684 continue;
4685
4686 GenerateArg(Consumer, OPT_include, I);
4687 }
4688
4689 for (const auto &CI : Opts.ChainedIncludes)
4690 GenerateArg(Consumer, OPT_chain_include, CI);
4691
4692 for (const auto &RF : Opts.RemappedFiles)
4693 GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second);
4694
4695 if (Opts.SourceDateEpoch)
4696 GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch));
4697
4698 if (Opts.DefineTargetOSMacros)
4699 GenerateArg(Consumer, OPT_fdefine_target_os_macros);
4700
4701 for (const auto &EmbedEntry : Opts.EmbedEntries)
4702 GenerateArg(Consumer, OPT_embed_dir_EQ, EmbedEntry);
4703
4704 // Don't handle LexEditorPlaceholders. It is implied by the action that is
4705 // generated elsewhere.
4706}
4707
4708static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
4709 DiagnosticsEngine &Diags,
4711 const FrontendOptions &FrontendOpts) {
4712 unsigned NumErrorsBefore = Diags.getNumErrors();
4713
4714 PreprocessorOptions *PreprocessorOpts = &Opts;
4715
4716#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4717 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4718#include "clang/Driver/Options.inc"
4719#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4720
4721 Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) ||
4722 Args.hasArg(OPT_pch_through_hdrstop_use);
4723
4724 for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
4725 Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
4726
4727 if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
4728 StringRef Value(A->getValue());
4729 size_t Comma = Value.find(',');
4730 unsigned Bytes = 0;
4731 unsigned EndOfLine = 0;
4732
4733 if (Comma == StringRef::npos ||
4734 Value.substr(0, Comma).getAsInteger(10, Bytes) ||
4735 Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
4736 Diags.Report(diag::err_drv_preamble_format);
4737 else {
4738 Opts.PrecompiledPreambleBytes.first = Bytes;
4739 Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
4740 }
4741 }
4742
4743 // Add the __CET__ macro if a CFProtection option is set.
4744 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4745 StringRef Name = A->getValue();
4746 if (Name == "branch")
4747 Opts.addMacroDef("__CET__=1");
4748 else if (Name == "return")
4749 Opts.addMacroDef("__CET__=2");
4750 else if (Name == "full")
4751 Opts.addMacroDef("__CET__=3");
4752 }
4753
4754 // Add macros from the command line.
4755 for (const auto *A : Args.filtered(OPT_D, OPT_U)) {
4756 if (A->getOption().matches(OPT_D))
4757 Opts.addMacroDef(A->getValue());
4758 else
4759 Opts.addMacroUndef(A->getValue());
4760 }
4761
4762 // Add the ordered list of -includes.
4763 for (const auto *A : Args.filtered(OPT_include))
4764 Opts.Includes.emplace_back(A->getValue());
4765
4766 for (const auto *A : Args.filtered(OPT_chain_include))
4767 Opts.ChainedIncludes.emplace_back(A->getValue());
4768
4769 for (const auto *A : Args.filtered(OPT_remap_file)) {
4770 std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
4771
4772 if (Split.second.empty()) {
4773 Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
4774 continue;
4775 }
4776
4777 Opts.addRemappedFile(Split.first, Split.second);
4778 }
4779
4780 if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
4781 StringRef Epoch = A->getValue();
4782 // SOURCE_DATE_EPOCH, if specified, must be a non-negative decimal integer.
4783 // On time64 systems, pick 253402300799 (the UNIX timestamp of
4784 // 9999-12-31T23:59:59Z) as the upper bound.
4785 const uint64_t MaxTimestamp =
4786 std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
4787 uint64_t V;
4788 if (Epoch.getAsInteger(10, V) || V > MaxTimestamp) {
4789 Diags.Report(diag::err_fe_invalid_source_date_epoch)
4790 << Epoch << MaxTimestamp;
4791 } else {
4792 Opts.SourceDateEpoch = V;
4793 }
4794 }
4795
4796 for (const auto *A : Args.filtered(OPT_embed_dir_EQ)) {
4797 StringRef Val = A->getValue();
4798 Opts.EmbedEntries.push_back(std::string(Val));
4799 }
4800
4801 // Always avoid lexing editor placeholders when we're just running the
4802 // preprocessor as we never want to emit the
4803 // "editor placeholder in source file" error in PP only mode.
4805 Opts.LexEditorPlaceholders = false;
4806
4808 Args.hasFlag(OPT_fdefine_target_os_macros,
4809 OPT_fno_define_target_os_macros, Opts.DefineTargetOSMacros);
4810
4811 return Diags.getNumErrors() == NumErrorsBefore;
4812}
4813
4814static void
4816 ArgumentConsumer Consumer,
4818 const PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
4819
4820#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4821 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4822#include "clang/Driver/Options.inc"
4823#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4824
4825 bool Generate_dM = isStrictlyPreprocessorAction(Action) && !Opts.ShowCPP;
4826 if (Generate_dM)
4827 GenerateArg(Consumer, OPT_dM);
4828 if (!Generate_dM && Opts.ShowMacros)
4829 GenerateArg(Consumer, OPT_dD);
4830 if (Opts.DirectivesOnly)
4831 GenerateArg(Consumer, OPT_fdirectives_only);
4832}
4833
4835 ArgList &Args, DiagnosticsEngine &Diags,
4837 unsigned NumErrorsBefore = Diags.getNumErrors();
4838
4839 PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
4840
4841#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4842 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4843#include "clang/Driver/Options.inc"
4844#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4845
4846 Opts.ShowCPP = isStrictlyPreprocessorAction(Action) && !Args.hasArg(OPT_dM);
4847 Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
4848 Opts.DirectivesOnly = Args.hasArg(OPT_fdirectives_only);
4849
4850 return Diags.getNumErrors() == NumErrorsBefore;
4851}
4852
4853static void GenerateTargetArgs(const TargetOptions &Opts,
4854 ArgumentConsumer Consumer) {
4855 const TargetOptions *TargetOpts = &Opts;
4856#define TARGET_OPTION_WITH_MARSHALLING(...) \
4857 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4858#include "clang/Driver/Options.inc"
4859#undef TARGET_OPTION_WITH_MARSHALLING
4860
4861 if (!Opts.SDKVersion.empty())
4862 GenerateArg(Consumer, OPT_target_sdk_version_EQ,
4863 Opts.SDKVersion.getAsString());
4864 if (!Opts.DarwinTargetVariantSDKVersion.empty())
4865 GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,
4866 Opts.DarwinTargetVariantSDKVersion.getAsString());
4867}
4868
4869static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
4870 DiagnosticsEngine &Diags) {
4871 unsigned NumErrorsBefore = Diags.getNumErrors();
4872
4873 TargetOptions *TargetOpts = &Opts;
4874
4875#define TARGET_OPTION_WITH_MARSHALLING(...) \
4876 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4877#include "clang/Driver/Options.inc"
4878#undef TARGET_OPTION_WITH_MARSHALLING
4879
4880 if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {
4881 llvm::VersionTuple Version;
4882 if (Version.tryParse(A->getValue()))
4883 Diags.Report(diag::err_drv_invalid_value)
4884 << A->getAsString(Args) << A->getValue();
4885 else
4886 Opts.SDKVersion = Version;
4887 }
4888 if (Arg *A =
4889 Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {
4890 llvm::VersionTuple Version;
4891 if (Version.tryParse(A->getValue()))
4892 Diags.Report(diag::err_drv_invalid_value)
4893 << A->getAsString(Args) << A->getValue();
4894 else
4895 Opts.DarwinTargetVariantSDKVersion = Version;
4896 }
4897
4898 return Diags.getNumErrors() == NumErrorsBefore;
4899}
4900
4901bool CompilerInvocation::CreateFromArgsImpl(
4902 CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs,
4903 DiagnosticsEngine &Diags, const char *Argv0) {
4904 unsigned NumErrorsBefore = Diags.getNumErrors();
4905
4906 // Parse the arguments.
4907 const OptTable &Opts = getDriverOptTable();
4908 llvm::opt::Visibility VisibilityMask(options::CC1Option);
4909 unsigned MissingArgIndex, MissingArgCount;
4910 InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
4911 MissingArgCount, VisibilityMask);
4913
4914 // Check for missing argument error.
4915 if (MissingArgCount)
4916 Diags.Report(diag::err_drv_missing_argument)
4917 << Args.getArgString(MissingArgIndex) << MissingArgCount;
4918
4919 // Issue errors on unknown arguments.
4920 for (const auto *A : Args.filtered(OPT_UNKNOWN)) {
4921 auto ArgString = A->getAsString(Args);
4922 std::string Nearest;
4923 if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1)
4924 Diags.Report(diag::err_drv_unknown_argument) << ArgString;
4925 else
4926 Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
4927 << ArgString << Nearest;
4928 }
4929
4930 ParseFileSystemArgs(Res.getFileSystemOpts(), Args, Diags);
4931 ParseMigratorArgs(Res.getMigratorOpts(), Args, Diags);
4932 ParseAnalyzerArgs(Res.getAnalyzerOpts(), Args, Diags);
4933 ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags,
4934 /*DefaultDiagColor=*/false);
4935 ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags, LangOpts.IsHeaderFile);
4936 // FIXME: We shouldn't have to pass the DashX option around here
4937 InputKind DashX = Res.getFrontendOpts().DashX;
4938 ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
4939 llvm::Triple T(Res.getTargetOpts().Triple);
4940 ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
4942 ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
4943
4944 ParsePointerAuthArgs(LangOpts, Args, Diags);
4945
4946 ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
4947 Diags);
4949 LangOpts.ObjCExceptions = 1;
4950
4951 for (auto Warning : Res.getDiagnosticOpts().Warnings) {
4952 if (Warning == "misexpect" &&
4953 !Diags.isIgnored(diag::warn_profile_data_misexpect, SourceLocation())) {
4954 Res.getCodeGenOpts().MisExpect = true;
4955 }
4956 }
4957
4958 if (LangOpts.CUDA) {
4959 // During CUDA device-side compilation, the aux triple is the
4960 // triple used for host compilation.
4961 if (LangOpts.CUDAIsDevice)
4963 }
4964
4965 // Set the triple of the host for OpenMP device compile.
4966 if (LangOpts.OpenMPIsTargetDevice)
4968
4969 ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
4971
4972 // FIXME: Override value name discarding when asan or msan is used because the
4973 // backend passes depend on the name of the alloca in order to print out
4974 // names.
4975 Res.getCodeGenOpts().DiscardValueNames &=
4976 !LangOpts.Sanitize.has(SanitizerKind::Address) &&
4977 !LangOpts.Sanitize.has(SanitizerKind::KernelAddress) &&
4978 !LangOpts.Sanitize.has(SanitizerKind::Memory) &&
4979 !LangOpts.Sanitize.has(SanitizerKind::KernelMemory);
4980
4981 ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags,
4983 Res.getFrontendOpts());
4986
4990 if (!Res.getDependencyOutputOpts().OutputFile.empty() &&
4991 Res.getDependencyOutputOpts().Targets.empty())
4992 Diags.Report(diag::err_fe_dependency_file_requires_MT);
4993
4994 // If sanitizer is enabled, disable OPT_ffine_grained_bitfield_accesses.
4995 if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
4996 !Res.getLangOpts().Sanitize.empty()) {
4997 Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
4998 Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
4999 }
5000
5001 // Store the command-line for using in the CodeView backend.
5002 if (Res.getCodeGenOpts().CodeViewCommandLine) {
5003 Res.getCodeGenOpts().Argv0 = Argv0;
5004 append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
5005 }
5006
5007 // Set PGOOptions. Need to create a temporary VFS to read the profile
5008 // to determine the PGO type.
5009 if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty()) {
5010 auto FS =
5012 Diags, llvm::vfs::getRealFileSystem());
5015 Diags);
5016 }
5017
5018 FixupInvocation(Res, Diags, Args, DashX);
5019
5020 return Diags.getNumErrors() == NumErrorsBefore;
5021}
5022
5024 ArrayRef<const char *> CommandLineArgs,
5025 DiagnosticsEngine &Diags,
5026 const char *Argv0) {
5027 CompilerInvocation DummyInvocation;
5028
5029 return RoundTrip(
5030 [](CompilerInvocation &Invocation, ArrayRef<const char *> CommandLineArgs,
5031 DiagnosticsEngine &Diags, const char *Argv0) {
5032 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
5033 },
5035 StringAllocator SA) {
5036 Args.push_back("-cc1");
5037 Invocation.generateCC1CommandLine(Args, SA);
5038 },
5039 Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
5040}
5041
5043 // FIXME: Consider using SHA1 instead of MD5.
5044 llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
5045
5046 // Note: For QoI reasons, the things we use as a hash here should all be
5047 // dumped via the -module-info flag.
5048
5049 // Start the signature with the compiler version.
5050 HBuilder.add(getClangFullRepositoryVersion());
5051
5052 // Also include the serialization version, in case LLVM_APPEND_VC_REV is off
5053 // and getClangFullRepositoryVersion() doesn't include git revision.
5055
5056 // Extend the signature with the language options
5057#define LANGOPT(Name, Bits, Default, Description) HBuilder.add(LangOpts->Name);
5058#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
5059 HBuilder.add(static_cast<unsigned>(LangOpts->get##Name()));
5060#define BENIGN_LANGOPT(Name, Bits, Default, Description)
5061#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
5062#include "clang/Basic/LangOptions.def"
5063
5064 HBuilder.addRange(getLangOpts().ModuleFeatures);
5065
5066 HBuilder.add(getLangOpts().ObjCRuntime);
5067 HBuilder.addRange(getLangOpts().CommentOpts.BlockCommandNames);
5068
5069 // Extend the signature with the target options.
5070 HBuilder.add(getTargetOpts().Triple, getTargetOpts().CPU,
5071 getTargetOpts().TuneCPU, getTargetOpts().ABI);
5072 HBuilder.addRange(getTargetOpts().FeaturesAsWritten);
5073
5074 // Extend the signature with preprocessor options.
5075 const PreprocessorOptions &ppOpts = getPreprocessorOpts();
5076 HBuilder.add(ppOpts.UsePredefines, ppOpts.DetailedRecord);
5077
5078 const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
5079 for (const auto &Macro : getPreprocessorOpts().Macros) {
5080 // If we're supposed to ignore this macro for the purposes of modules,
5081 // don't put it into the hash.
5082 if (!hsOpts.ModulesIgnoreMacros.empty()) {
5083 // Check whether we're ignoring this macro.
5084 StringRef MacroDef = Macro.first;
5085 if (hsOpts.ModulesIgnoreMacros.count(
5086 llvm::CachedHashString(MacroDef.split('=').first)))
5087 continue;
5088 }
5089
5090 HBuilder.add(Macro);
5091 }
5092
5093 // Extend the signature with the sysroot and other header search options.
5094 HBuilder.add(hsOpts.Sysroot, hsOpts.ModuleFormat, hsOpts.UseDebugInfo,
5096 hsOpts.UseStandardCXXIncludes, hsOpts.UseLibcxx,
5098 HBuilder.add(hsOpts.ResourceDir);
5099
5100 if (hsOpts.ModulesStrictContextHash) {
5101 HBuilder.addRange(hsOpts.SystemHeaderPrefixes);
5102 HBuilder.addRange(hsOpts.UserEntries);
5103 HBuilder.addRange(hsOpts.VFSOverlayFiles);
5104
5105 const DiagnosticOptions &diagOpts = getDiagnosticOpts();
5106#define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name);
5107#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
5108 HBuilder.add(diagOpts.get##Name());
5109#include "clang/Basic/DiagnosticOptions.def"
5110#undef DIAGOPT
5111#undef ENUM_DIAGOPT
5112 }
5113
5114 // Extend the signature with the user build path.
5115 HBuilder.add(hsOpts.ModuleUserBuildPath);
5116
5117 // Extend the signature with the module file extensions.
5118 for (const auto &ext : getFrontendOpts().ModuleFileExtensions)
5119 ext->hashExtension(HBuilder);
5120
5121 // Extend the signature with the Swift version for API notes.
5123 if (!APINotesOpts.SwiftVersion.empty()) {
5124 HBuilder.add(APINotesOpts.SwiftVersion.getMajor());
5125 if (auto Minor = APINotesOpts.SwiftVersion.getMinor())
5126 HBuilder.add(*Minor);
5127 if (auto Subminor = APINotesOpts.SwiftVersion.getSubminor())
5128 HBuilder.add(*Subminor);
5129 if (auto Build = APINotesOpts.SwiftVersion.getBuild())
5130 HBuilder.add(*Build);
5131 }
5132
5133 // When compiling with -gmodules, also hash -fdebug-prefix-map as it
5134 // affects the debug info in the PCM.
5135 if (getCodeGenOpts().DebugTypeExtRefs)
5136 HBuilder.addRange(getCodeGenOpts().DebugPrefixMap);
5137
5138 // Extend the signature with the affecting debug options.
5139 if (getHeaderSearchOpts().ModuleFormat == "obj") {
5140#define DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);
5141#define VALUE_DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);
5142#define ENUM_DEBUGOPT(Name, Type, Bits, Default) \
5143 HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
5144#define BENIGN_DEBUGOPT(Name, Bits, Default)
5145#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default)
5146#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default)
5147#include "clang/Basic/DebugOptions.def"
5148 }
5149
5150 // Extend the signature with the enabled sanitizers, if at least one is
5151 // enabled. Sanitizers which cannot affect AST generation aren't hashed.
5152 SanitizerSet SanHash = getLangOpts().Sanitize;
5154 if (!SanHash.empty())
5155 HBuilder.add(SanHash.Mask);
5156
5157 llvm::MD5::MD5Result Result;
5158 HBuilder.getHasher().final(Result);
5159 uint64_t Hash = Result.high() ^ Result.low();
5160 return toString(llvm::APInt(64, Hash), 36, /*Signed=*/false);
5161}
5162
5164 ArgumentConsumer Consumer) const {
5165 llvm::Triple T(getTargetOpts().Triple);
5166
5170 GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer,
5171 /*DefaultDiagColor=*/false);
5172 GenerateFrontendArgs(getFrontendOpts(), Consumer, getLangOpts().IsHeaderFile);
5173 GenerateTargetArgs(getTargetOpts(), Consumer);
5177 GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX);
5178 GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T,
5179 getFrontendOpts().OutputFile, &getLangOpts());
5183 getFrontendOpts().ProgramAction);
5185}
5186
5187std::vector<std::string> CompilerInvocationBase::getCC1CommandLine() const {
5188 std::vector<std::string> Args{"-cc1"};
5190 [&Args](const Twine &Arg) { Args.push_back(Arg.str()); });
5191 return Args;
5192}
5193
5198}
5199
5201 getLangOpts().ImplicitModules = false;
5206 // The specific values we canonicalize to for pruning don't affect behaviour,
5207 /// so use the default values so they may be dropped from the command-line.
5208 getHeaderSearchOpts().ModuleCachePruneInterval = 7 * 24 * 60 * 60;
5209 getHeaderSearchOpts().ModuleCachePruneAfter = 31 * 24 * 60 * 60;
5210}
5211
5214 DiagnosticsEngine &Diags) {
5215 return createVFSFromCompilerInvocation(CI, Diags,
5216 llvm::vfs::getRealFileSystem());
5217}
5218
5221 const CompilerInvocation &CI, DiagnosticsEngine &Diags,
5224 Diags, std::move(BaseFS));
5225}
5226
5228 ArrayRef<std::string> VFSOverlayFiles, DiagnosticsEngine &Diags,
5230 if (VFSOverlayFiles.empty())
5231 return BaseFS;
5232
5234 // earlier vfs files are on the bottom
5235 for (const auto &File : VFSOverlayFiles) {
5236 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
5237 Result->getBufferForFile(File);
5238 if (!Buffer) {
5239 Diags.Report(diag::err_missing_vfs_overlay_file) << File;
5240 continue;
5241 }
5242
5243 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = llvm::vfs::getVFSFromYAML(
5244 std::move(Buffer.get()), /*DiagHandler*/ nullptr, File,
5245 /*DiagContext*/ nullptr, Result);
5246 if (!FS) {
5247 Diags.Report(diag::err_invalid_vfs_overlay) << File;
5248 continue;
5249 }
5250
5251 Result = FS;
5252 }
5253 return Result;
5254}
#define V(N, I)
Definition: ASTContext.h:3443
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 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:3051
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.
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:1493
unsigned getCustomDiagID(Level L, const char(&FormatString)[N])
Return an ID for a diagnostic with the specified format string and level.
Definition: Diagnostic.h:896
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:880
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
Definition: Diagnostic.h:939
unsigned getNumWarnings() const
Definition: Diagnostic.h:881
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.
enum clang::FrontendOptions::@200 ARCMTAction
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:1739
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:385
@ AddUnsignedOverflowTest
if (a + b < a)
Definition: LangOptions.h:391
@ All
Exclude all overflow patterns (below)
Definition: LangOptions.h:387
@ AddSignedOverflowTest
if (a + b < a)
Definition: LangOptions.h:389
@ PostDecrInWhile
while (count–)
Definition: LangOptions.h:395
@ 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:499
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:587
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
Definition: LangOptions.h:566
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Definition: LangOptions.h:547
clang::ObjCRuntime ObjCRuntime
Definition: LangOptions.h:534
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:597
SanitizerSet Sanitize
Set of enabled sanitizers.
Definition: LangOptions.h:505
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
Definition: LangOptions.h:610
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:577
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Definition: LangOptions.h:544
std::string RandstructSeed
The seed used by the randomize structure layout feature.
Definition: LangOptions.h:602
std::map< std::string, std::string, std::greater< std::string > > MacroPrefixMap
A prefix map for FILE, BASE_FILE and __builtin_FILE().
Definition: LangOptions.h:569
LangStandard::Kind LangStd
The used language standard.
Definition: LangOptions.h:502
std::string OpenACCMacroOverride
Definition: LangOptions.h:619
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:507
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:573
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
Definition: LangOptions.h:511
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:554
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:560
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 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.
@ MigrateSource
Run migrator.
@ 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:198
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:39
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.
@ 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
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:29
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:176
bool empty() const
Returns true if no sanitizers are enabled.
Definition: Sanitizers.h:179
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:182
XRayInstrMask Mask
Definition: XRayInstr.h:65