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