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