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