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