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