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).equals("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::EmitHTML, OPT_emit_html},
2553 {frontend::EmitLLVM, OPT_emit_llvm},
2554 {frontend::EmitLLVMOnly, OPT_emit_llvm_only},
2555 {frontend::EmitCodeGenOnly, OPT_emit_codegen_only},
2556 {frontend::EmitObj, OPT_emit_obj},
2557 {frontend::ExtractAPI, OPT_extract_api},
2558
2559 {frontend::FixIt, OPT_fixit_EQ},
2560 {frontend::FixIt, OPT_fixit},
2561
2562 {frontend::GenerateModule, OPT_emit_module},
2563 {frontend::GenerateModuleInterface, OPT_emit_module_interface},
2565 OPT_emit_reduced_module_interface},
2566 {frontend::GenerateHeaderUnit, OPT_emit_header_unit},
2567 {frontend::GeneratePCH, OPT_emit_pch},
2568 {frontend::GenerateInterfaceStubs, OPT_emit_interface_stubs},
2569 {frontend::InitOnly, OPT_init_only},
2570 {frontend::ParseSyntaxOnly, OPT_fsyntax_only},
2571 {frontend::ModuleFileInfo, OPT_module_file_info},
2572 {frontend::VerifyPCH, OPT_verify_pch},
2573 {frontend::PrintPreamble, OPT_print_preamble},
2575 {frontend::TemplightDump, OPT_templight_dump},
2576 {frontend::RewriteMacros, OPT_rewrite_macros},
2577 {frontend::RewriteObjC, OPT_rewrite_objc},
2578 {frontend::RewriteTest, OPT_rewrite_test},
2579 {frontend::RunAnalysis, OPT_analyze},
2580 {frontend::MigrateSource, OPT_migrate},
2581 {frontend::RunPreprocessorOnly, OPT_Eonly},
2583 OPT_print_dependency_directives_minimized_source},
2584 };
2585
2586 return Table;
2587}
2588
2589/// Maps command line option to frontend action.
2590static std::optional<frontend::ActionKind>
2591getFrontendAction(OptSpecifier &Opt) {
2592 for (const auto &ActionOpt : getFrontendActionTable())
2593 if (ActionOpt.second == Opt.getID())
2594 return ActionOpt.first;
2595
2596 return std::nullopt;
2597}
2598
2599/// Maps frontend action to command line option.
2600static std::optional<OptSpecifier>
2602 for (const auto &ActionOpt : getFrontendActionTable())
2603 if (ActionOpt.first == ProgramAction)
2604 return OptSpecifier(ActionOpt.second);
2605
2606 return std::nullopt;
2607}
2608
2610 ArgumentConsumer Consumer, bool IsHeader) {
2611 const FrontendOptions &FrontendOpts = Opts;
2612#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2613 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
2614#include "clang/Driver/Options.inc"
2615#undef FRONTEND_OPTION_WITH_MARSHALLING
2616
2617 std::optional<OptSpecifier> ProgramActionOpt =
2619
2620 // Generating a simple flag covers most frontend actions.
2621 std::function<void()> GenerateProgramAction = [&]() {
2622 GenerateArg(Consumer, *ProgramActionOpt);
2623 };
2624
2625 if (!ProgramActionOpt) {
2626 // PluginAction is the only program action handled separately.
2627 assert(Opts.ProgramAction == frontend::PluginAction &&
2628 "Frontend action without option.");
2629 GenerateProgramAction = [&]() {
2630 GenerateArg(Consumer, OPT_plugin, Opts.ActionName);
2631 };
2632 }
2633
2634 // FIXME: Simplify the complex 'AST dump' command line.
2635 if (Opts.ProgramAction == frontend::ASTDump) {
2636 GenerateProgramAction = [&]() {
2637 // ASTDumpLookups, ASTDumpDeclTypes and ASTDumpFilter are generated via
2638 // marshalling infrastructure.
2639
2640 if (Opts.ASTDumpFormat != ADOF_Default) {
2641 StringRef Format;
2642 switch (Opts.ASTDumpFormat) {
2643 case ADOF_Default:
2644 llvm_unreachable("Default AST dump format.");
2645 case ADOF_JSON:
2646 Format = "json";
2647 break;
2648 }
2649
2650 if (Opts.ASTDumpAll)
2651 GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);
2652 if (Opts.ASTDumpDecls)
2653 GenerateArg(Consumer, OPT_ast_dump_EQ, Format);
2654 } else {
2655 if (Opts.ASTDumpAll)
2656 GenerateArg(Consumer, OPT_ast_dump_all);
2657 if (Opts.ASTDumpDecls)
2658 GenerateArg(Consumer, OPT_ast_dump);
2659 }
2660 };
2661 }
2662
2663 if (Opts.ProgramAction == frontend::FixIt && !Opts.FixItSuffix.empty()) {
2664 GenerateProgramAction = [&]() {
2665 GenerateArg(Consumer, OPT_fixit_EQ, Opts.FixItSuffix);
2666 };
2667 }
2668
2669 GenerateProgramAction();
2670
2671 for (const auto &PluginArgs : Opts.PluginArgs) {
2672 Option Opt = getDriverOptTable().getOption(OPT_plugin_arg);
2673 for (const auto &PluginArg : PluginArgs.second)
2674 denormalizeString(Consumer,
2675 Opt.getPrefix() + Opt.getName() + PluginArgs.first,
2676 Opt.getKind(), 0, PluginArg);
2677 }
2678
2679 for (const auto &Ext : Opts.ModuleFileExtensions)
2680 if (auto *TestExt = dyn_cast_or_null<TestModuleFileExtension>(Ext.get()))
2681 GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());
2682
2683 if (!Opts.CodeCompletionAt.FileName.empty())
2684 GenerateArg(Consumer, OPT_code_completion_at,
2685 Opts.CodeCompletionAt.ToString());
2686
2687 for (const auto &Plugin : Opts.Plugins)
2688 GenerateArg(Consumer, OPT_load, Plugin);
2689
2690 // ASTDumpDecls and ASTDumpAll already handled with ProgramAction.
2691
2692 for (const auto &ModuleFile : Opts.ModuleFiles)
2693 GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);
2694
2695 if (Opts.AuxTargetCPU)
2696 GenerateArg(Consumer, OPT_aux_target_cpu, *Opts.AuxTargetCPU);
2697
2698 if (Opts.AuxTargetFeatures)
2699 for (const auto &Feature : *Opts.AuxTargetFeatures)
2700 GenerateArg(Consumer, OPT_aux_target_feature, Feature);
2701
2702 {
2703 StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";
2704 StringRef ModuleMap =
2705 Opts.DashX.getFormat() == InputKind::ModuleMap ? "-module-map" : "";
2706 StringRef HeaderUnit = "";
2707 switch (Opts.DashX.getHeaderUnitKind()) {
2709 break;
2711 HeaderUnit = "-user";
2712 break;
2714 HeaderUnit = "-system";
2715 break;
2717 HeaderUnit = "-header-unit";
2718 break;
2719 }
2720 StringRef Header = IsHeader ? "-header" : "";
2721
2722 StringRef Lang;
2723 switch (Opts.DashX.getLanguage()) {
2724 case Language::C:
2725 Lang = "c";
2726 break;
2727 case Language::OpenCL:
2728 Lang = "cl";
2729 break;
2731 Lang = "clcpp";
2732 break;
2733 case Language::CUDA:
2734 Lang = "cuda";
2735 break;
2736 case Language::HIP:
2737 Lang = "hip";
2738 break;
2739 case Language::CXX:
2740 Lang = "c++";
2741 break;
2742 case Language::ObjC:
2743 Lang = "objective-c";
2744 break;
2745 case Language::ObjCXX:
2746 Lang = "objective-c++";
2747 break;
2749 Lang = "renderscript";
2750 break;
2751 case Language::Asm:
2752 Lang = "assembler-with-cpp";
2753 break;
2754 case Language::Unknown:
2755 assert(Opts.DashX.getFormat() == InputKind::Precompiled &&
2756 "Generating -x argument for unknown language (not precompiled).");
2757 Lang = "ast";
2758 break;
2759 case Language::LLVM_IR:
2760 Lang = "ir";
2761 break;
2762 case Language::HLSL:
2763 Lang = "hlsl";
2764 break;
2765 case Language::CIR:
2766 Lang = "cir";
2767 break;
2768 }
2769
2770 GenerateArg(Consumer, OPT_x,
2771 Lang + HeaderUnit + Header + ModuleMap + Preprocessed);
2772 }
2773
2774 // OPT_INPUT has a unique class, generate it directly.
2775 for (const auto &Input : Opts.Inputs)
2776 Consumer(Input.getFile());
2777}
2778
2779static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
2780 DiagnosticsEngine &Diags, bool &IsHeaderFile) {
2781 unsigned NumErrorsBefore = Diags.getNumErrors();
2782
2783 FrontendOptions &FrontendOpts = Opts;
2784
2785#define FRONTEND_OPTION_WITH_MARSHALLING(...) \
2786 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
2787#include "clang/Driver/Options.inc"
2788#undef FRONTEND_OPTION_WITH_MARSHALLING
2789
2791 if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {
2792 OptSpecifier Opt = OptSpecifier(A->getOption().getID());
2793 std::optional<frontend::ActionKind> ProgramAction = getFrontendAction(Opt);
2794 assert(ProgramAction && "Option specifier not in Action_Group.");
2795
2796 if (ProgramAction == frontend::ASTDump &&
2797 (Opt == OPT_ast_dump_all_EQ || Opt == OPT_ast_dump_EQ)) {
2798 unsigned Val = llvm::StringSwitch<unsigned>(A->getValue())
2799 .CaseLower("default", ADOF_Default)
2800 .CaseLower("json", ADOF_JSON)
2801 .Default(std::numeric_limits<unsigned>::max());
2802
2803 if (Val != std::numeric_limits<unsigned>::max())
2804 Opts.ASTDumpFormat = static_cast<ASTDumpOutputFormat>(Val);
2805 else {
2806 Diags.Report(diag::err_drv_invalid_value)
2807 << A->getAsString(Args) << A->getValue();
2809 }
2810 }
2811
2812 if (ProgramAction == frontend::FixIt && Opt == OPT_fixit_EQ)
2813 Opts.FixItSuffix = A->getValue();
2814
2815 if (ProgramAction == frontend::GenerateInterfaceStubs) {
2816 StringRef ArgStr =
2817 Args.hasArg(OPT_interface_stub_version_EQ)
2818 ? Args.getLastArgValue(OPT_interface_stub_version_EQ)
2819 : "ifs-v1";
2820 if (ArgStr == "experimental-yaml-elf-v1" ||
2821 ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-ifs-v2" ||
2822 ArgStr == "experimental-tapi-elf-v1") {
2823 std::string ErrorMessage =
2824 "Invalid interface stub format: " + ArgStr.str() +
2825 " is deprecated.";
2826 Diags.Report(diag::err_drv_invalid_value)
2827 << "Must specify a valid interface stub format type, ie: "
2828 "-interface-stub-version=ifs-v1"
2829 << ErrorMessage;
2830 ProgramAction = frontend::ParseSyntaxOnly;
2831 } else if (!ArgStr.starts_with("ifs-")) {
2832 std::string ErrorMessage =
2833 "Invalid interface stub format: " + ArgStr.str() + ".";
2834 Diags.Report(diag::err_drv_invalid_value)
2835 << "Must specify a valid interface stub format type, ie: "
2836 "-interface-stub-version=ifs-v1"
2837 << ErrorMessage;
2838 ProgramAction = frontend::ParseSyntaxOnly;
2839 }
2840 }
2841
2842 Opts.ProgramAction = *ProgramAction;
2843 }
2844
2845 if (const Arg* A = Args.getLastArg(OPT_plugin)) {
2846 Opts.Plugins.emplace_back(A->getValue(0));
2848 Opts.ActionName = A->getValue();
2849 }
2850 for (const auto *AA : Args.filtered(OPT_plugin_arg))
2851 Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));
2852
2853 for (const std::string &Arg :
2854 Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {
2855 std::string BlockName;
2856 unsigned MajorVersion;
2857 unsigned MinorVersion;
2858 bool Hashed;
2859 std::string UserInfo;
2860 if (parseTestModuleFileExtensionArg(Arg, BlockName, MajorVersion,
2861 MinorVersion, Hashed, UserInfo)) {
2862 Diags.Report(diag::err_test_module_file_extension_format) << Arg;
2863
2864 continue;
2865 }
2866
2867 // Add the testing module file extension.
2868 Opts.ModuleFileExtensions.push_back(
2869 std::make_shared<TestModuleFileExtension>(
2870 BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));
2871 }
2872
2873 if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {
2874 Opts.CodeCompletionAt =
2875 ParsedSourceLocation::FromString(A->getValue());
2876 if (Opts.CodeCompletionAt.FileName.empty())
2877 Diags.Report(diag::err_drv_invalid_value)
2878 << A->getAsString(Args) << A->getValue();
2879 }
2880
2881 Opts.Plugins = Args.getAllArgValues(OPT_load);
2882 Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);
2883 Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);
2884 // Only the -fmodule-file=<file> form.
2885 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
2886 StringRef Val = A->getValue();
2887 if (!Val.contains('='))
2888 Opts.ModuleFiles.push_back(std::string(Val));
2889 }
2890
2892 Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"
2893 << "-emit-module";
2894
2895 if (Args.hasArg(OPT_aux_target_cpu))
2896 Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu));
2897 if (Args.hasArg(OPT_aux_target_feature))
2898 Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature);
2899
2902 Diags.Report(diag::err_drv_argument_not_allowed_with)
2903 << "ARC migration" << "ObjC migration";
2904 }
2905
2907 if (const Arg *A = Args.getLastArg(OPT_x)) {
2908 StringRef XValue = A->getValue();
2909
2910 // Parse suffixes:
2911 // '<lang>(-[{header-unit,user,system}-]header|[-module-map][-cpp-output])'.
2912 // FIXME: Supporting '<lang>-header-cpp-output' would be useful.
2913 bool Preprocessed = XValue.consume_back("-cpp-output");
2914 bool ModuleMap = XValue.consume_back("-module-map");
2915 // Detect and consume the header indicator.
2916 bool IsHeader =
2917 XValue != "precompiled-header" && XValue.consume_back("-header");
2918
2919 // If we have c++-{user,system}-header, that indicates a header unit input
2920 // likewise, if the user put -fmodule-header together with a header with an
2921 // absolute path (header-unit-header).
2923 if (IsHeader || Preprocessed) {
2924 if (XValue.consume_back("-header-unit"))
2926 else if (XValue.consume_back("-system"))
2928 else if (XValue.consume_back("-user"))
2930 }
2931
2932 // The value set by this processing is an un-preprocessed source which is
2933 // not intended to be a module map or header unit.
2934 IsHeaderFile = IsHeader && !Preprocessed && !ModuleMap &&
2936
2937 // Principal languages.
2938 DashX = llvm::StringSwitch<InputKind>(XValue)
2939 .Case("c", Language::C)
2940 .Case("cl", Language::OpenCL)
2941 .Case("clcpp", Language::OpenCLCXX)
2942 .Case("cuda", Language::CUDA)
2943 .Case("hip", Language::HIP)
2944 .Case("c++", Language::CXX)
2945 .Case("objective-c", Language::ObjC)
2946 .Case("objective-c++", Language::ObjCXX)
2947 .Case("renderscript", Language::RenderScript)
2948 .Case("hlsl", Language::HLSL)
2949 .Default(Language::Unknown);
2950
2951 // "objc[++]-cpp-output" is an acceptable synonym for
2952 // "objective-c[++]-cpp-output".
2953 if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && !ModuleMap &&
2955 DashX = llvm::StringSwitch<InputKind>(XValue)
2956 .Case("objc", Language::ObjC)
2957 .Case("objc++", Language::ObjCXX)
2958 .Default(Language::Unknown);
2959
2960 // Some special cases cannot be combined with suffixes.
2961 if (DashX.isUnknown() && !Preprocessed && !IsHeaderFile && !ModuleMap &&
2963 DashX = llvm::StringSwitch<InputKind>(XValue)
2964 .Case("cpp-output", InputKind(Language::C).getPreprocessed())
2965 .Case("assembler-with-cpp", Language::Asm)
2966 .Cases("ast", "pcm", "precompiled-header",
2968 .Case("ir", Language::LLVM_IR)
2969 .Case("cir", Language::CIR)
2970 .Default(Language::Unknown);
2971
2972 if (DashX.isUnknown())
2973 Diags.Report(diag::err_drv_invalid_value)
2974 << A->getAsString(Args) << A->getValue();
2975
2976 if (Preprocessed)
2977 DashX = DashX.getPreprocessed();
2978 // A regular header is considered mutually exclusive with a header unit.
2979 if (HUK != InputKind::HeaderUnit_None) {
2980 DashX = DashX.withHeaderUnit(HUK);
2981 IsHeaderFile = true;
2982 } else if (IsHeaderFile)
2983 DashX = DashX.getHeader();
2984 if (ModuleMap)
2985 DashX = DashX.withFormat(InputKind::ModuleMap);
2986 }
2987
2988 // '-' is the default input if none is given.
2989 std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
2990 Opts.Inputs.clear();
2991 if (Inputs.empty())
2992 Inputs.push_back("-");
2993
2995 Inputs.size() > 1)
2996 Diags.Report(diag::err_drv_header_unit_extra_inputs) << Inputs[1];
2997
2998 for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {
2999 InputKind IK = DashX;
3000 if (IK.isUnknown()) {
3002 StringRef(Inputs[i]).rsplit('.').second);
3003 // FIXME: Warn on this?
3004 if (IK.isUnknown())
3005 IK = Language::C;
3006 // FIXME: Remove this hack.
3007 if (i == 0)
3008 DashX = IK;
3009 }
3010
3011 bool IsSystem = false;
3012
3013 // The -emit-module action implicitly takes a module map.
3015 IK.getFormat() == InputKind::Source) {
3017 IsSystem = Opts.IsSystemModule;
3018 }
3019
3020 Opts.Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem);
3021 }
3022
3023 Opts.DashX = DashX;
3024
3025 return Diags.getNumErrors() == NumErrorsBefore;
3026}
3027
3028std::string CompilerInvocation::GetResourcesPath(const char *Argv0,
3029 void *MainAddr) {
3030 std::string ClangExecutable =
3031 llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
3032 return Driver::GetResourcesPath(ClangExecutable, CLANG_RESOURCE_DIR);
3033}
3034
3036 ArgumentConsumer Consumer) {
3037 const HeaderSearchOptions *HeaderSearchOpts = &Opts;
3038#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3039 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3040#include "clang/Driver/Options.inc"
3041#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3042
3043 if (Opts.UseLibcxx)
3044 GenerateArg(Consumer, OPT_stdlib_EQ, "libc++");
3045
3046 if (!Opts.ModuleCachePath.empty())
3047 GenerateArg(Consumer, OPT_fmodules_cache_path, Opts.ModuleCachePath);
3048
3049 for (const auto &File : Opts.PrebuiltModuleFiles)
3050 GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second);
3051
3052 for (const auto &Path : Opts.PrebuiltModulePaths)
3053 GenerateArg(Consumer, OPT_fprebuilt_module_path, Path);
3054
3055 for (const auto &Macro : Opts.ModulesIgnoreMacros)
3056 GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val());
3057
3058 auto Matches = [](const HeaderSearchOptions::Entry &Entry,
3060 std::optional<bool> IsFramework,
3061 std::optional<bool> IgnoreSysRoot) {
3062 return llvm::is_contained(Groups, Entry.Group) &&
3063 (!IsFramework || (Entry.IsFramework == *IsFramework)) &&
3064 (!IgnoreSysRoot || (Entry.IgnoreSysRoot == *IgnoreSysRoot));
3065 };
3066
3067 auto It = Opts.UserEntries.begin();
3068 auto End = Opts.UserEntries.end();
3069
3070 // Add -I..., -F..., and -index-header-map options in order.
3071 for (; It < End && Matches(*It, {frontend::IndexHeaderMap, frontend::Angled},
3072 std::nullopt, true);
3073 ++It) {
3074 OptSpecifier Opt = [It, Matches]() {
3075 if (Matches(*It, frontend::IndexHeaderMap, true, true))
3076 return OPT_F;
3077 if (Matches(*It, frontend::IndexHeaderMap, false, true))
3078 return OPT_I;
3079 if (Matches(*It, frontend::Angled, true, true))
3080 return OPT_F;
3081 if (Matches(*It, frontend::Angled, false, true))
3082 return OPT_I;
3083 llvm_unreachable("Unexpected HeaderSearchOptions::Entry.");
3084 }();
3085
3086 if (It->Group == frontend::IndexHeaderMap)
3087 GenerateArg(Consumer, OPT_index_header_map);
3088 GenerateArg(Consumer, Opt, It->Path);
3089 };
3090
3091 // Note: some paths that came from "[-iprefix=xx] -iwithprefixbefore=yy" may
3092 // have already been generated as "-I[xx]yy". If that's the case, their
3093 // position on command line was such that this has no semantic impact on
3094 // include paths.
3095 for (; It < End &&
3096 Matches(*It, {frontend::After, frontend::Angled}, false, true);
3097 ++It) {
3098 OptSpecifier Opt =
3099 It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;
3100 GenerateArg(Consumer, Opt, It->Path);
3101 }
3102
3103 // Note: Some paths that came from "-idirafter=xxyy" may have already been
3104 // generated as "-iwithprefix=xxyy". If that's the case, their position on
3105 // command line was such that this has no semantic impact on include paths.
3106 for (; It < End && Matches(*It, {frontend::After}, false, true); ++It)
3107 GenerateArg(Consumer, OPT_idirafter, It->Path);
3108 for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It)
3109 GenerateArg(Consumer, OPT_iquote, It->Path);
3110 for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt);
3111 ++It)
3112 GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,
3113 It->Path);
3114 for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)
3115 GenerateArg(Consumer, OPT_iframework, It->Path);
3116 for (; It < End && Matches(*It, {frontend::System}, true, false); ++It)
3117 GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path);
3118
3119 // Add the paths for the various language specific isystem flags.
3120 for (; It < End && Matches(*It, {frontend::CSystem}, false, true); ++It)
3121 GenerateArg(Consumer, OPT_c_isystem, It->Path);
3122 for (; It < End && Matches(*It, {frontend::CXXSystem}, false, true); ++It)
3123 GenerateArg(Consumer, OPT_cxx_isystem, It->Path);
3124 for (; It < End && Matches(*It, {frontend::ObjCSystem}, false, true); ++It)
3125 GenerateArg(Consumer, OPT_objc_isystem, It->Path);
3126 for (; It < End && Matches(*It, {frontend::ObjCXXSystem}, false, true); ++It)
3127 GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);
3128
3129 // Add the internal paths from a driver that detects standard include paths.
3130 // Note: Some paths that came from "-internal-isystem" arguments may have
3131 // already been generated as "-isystem". 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 &&
3134 Matches(*It, {frontend::System, frontend::ExternCSystem}, false, true);
3135 ++It) {
3136 OptSpecifier Opt = It->Group == frontend::System
3137 ? OPT_internal_isystem
3138 : OPT_internal_externc_isystem;
3139 GenerateArg(Consumer, Opt, It->Path);
3140 }
3141
3142 assert(It == End && "Unhandled HeaderSearchOption::Entry.");
3143
3144 // Add the path prefixes which are implicitly treated as being system headers.
3145 for (const auto &P : Opts.SystemHeaderPrefixes) {
3146 OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix
3147 : OPT_no_system_header_prefix;
3148 GenerateArg(Consumer, Opt, P.Prefix);
3149 }
3150
3151 for (const std::string &F : Opts.VFSOverlayFiles)
3152 GenerateArg(Consumer, OPT_ivfsoverlay, F);
3153}
3154
3155static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
3156 DiagnosticsEngine &Diags,
3157 const std::string &WorkingDir) {
3158 unsigned NumErrorsBefore = Diags.getNumErrors();
3159
3160 HeaderSearchOptions *HeaderSearchOpts = &Opts;
3161
3162#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \
3163 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3164#include "clang/Driver/Options.inc"
3165#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING
3166
3167 if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
3168 Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
3169
3170 // Canonicalize -fmodules-cache-path before storing it.
3171 SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path));
3172 if (!(P.empty() || llvm::sys::path::is_absolute(P))) {
3173 if (WorkingDir.empty())
3174 llvm::sys::fs::make_absolute(P);
3175 else
3176 llvm::sys::fs::make_absolute(WorkingDir, P);
3177 }
3178 llvm::sys::path::remove_dots(P);
3179 Opts.ModuleCachePath = std::string(P);
3180
3181 // Only the -fmodule-file=<name>=<file> form.
3182 for (const auto *A : Args.filtered(OPT_fmodule_file)) {
3183 StringRef Val = A->getValue();
3184 if (Val.contains('=')) {
3185 auto Split = Val.split('=');
3186 Opts.PrebuiltModuleFiles.insert_or_assign(
3187 std::string(Split.first), std::string(Split.second));
3188 }
3189 }
3190 for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))
3191 Opts.AddPrebuiltModulePath(A->getValue());
3192
3193 for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {
3194 StringRef MacroDef = A->getValue();
3195 Opts.ModulesIgnoreMacros.insert(
3196 llvm::CachedHashString(MacroDef.split('=').first));
3197 }
3198
3199 // Add -I..., -F..., and -index-header-map options in order.
3200 bool IsIndexHeaderMap = false;
3201 bool IsSysrootSpecified =
3202 Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);
3203
3204 // Expand a leading `=` to the sysroot if one was passed (and it's not a
3205 // framework flag).
3206 auto PrefixHeaderPath = [IsSysrootSpecified,
3207 &Opts](const llvm::opt::Arg *A,
3208 bool IsFramework = false) -> std::string {
3209 assert(A->getNumValues() && "Unexpected empty search path flag!");
3210 if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') {
3211 SmallString<32> Buffer;
3212 llvm::sys::path::append(Buffer, Opts.Sysroot,
3213 llvm::StringRef(A->getValue()).substr(1));
3214 return std::string(Buffer);
3215 }
3216 return A->getValue();
3217 };
3218
3219 for (const auto *A : Args.filtered(OPT_I, OPT_F, OPT_index_header_map)) {
3220 if (A->getOption().matches(OPT_index_header_map)) {
3221 // -index-header-map applies to the next -I or -F.
3222 IsIndexHeaderMap = true;
3223 continue;
3224 }
3225
3227 IsIndexHeaderMap ? frontend::IndexHeaderMap : frontend::Angled;
3228
3229 bool IsFramework = A->getOption().matches(OPT_F);
3230 Opts.AddPath(PrefixHeaderPath(A, IsFramework), Group, IsFramework,
3231 /*IgnoreSysroot*/ true);
3232 IsIndexHeaderMap = false;
3233 }
3234
3235 // Add -iprefix/-iwithprefix/-iwithprefixbefore options.
3236 StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.
3237 for (const auto *A :
3238 Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {
3239 if (A->getOption().matches(OPT_iprefix))
3240 Prefix = A->getValue();
3241 else if (A->getOption().matches(OPT_iwithprefix))
3242 Opts.AddPath(Prefix.str() + A->getValue(), frontend::After, false, true);
3243 else
3244 Opts.AddPath(Prefix.str() + A->getValue(), frontend::Angled, false, true);
3245 }
3246
3247 for (const auto *A : Args.filtered(OPT_idirafter))
3248 Opts.AddPath(PrefixHeaderPath(A), frontend::After, false, true);
3249 for (const auto *A : Args.filtered(OPT_iquote))
3250 Opts.AddPath(PrefixHeaderPath(A), frontend::Quoted, false, true);
3251
3252 for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) {
3253 if (A->getOption().matches(OPT_iwithsysroot)) {
3254 Opts.AddPath(A->getValue(), frontend::System, false,
3255 /*IgnoreSysRoot=*/false);
3256 continue;
3257 }
3258 Opts.AddPath(PrefixHeaderPath(A), frontend::System, false, true);
3259 }
3260 for (const auto *A : Args.filtered(OPT_iframework))
3261 Opts.AddPath(A->getValue(), frontend::System, true, true);
3262 for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))
3263 Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
3264 /*IgnoreSysRoot=*/false);
3265
3266 // Add the paths for the various language specific isystem flags.
3267 for (const auto *A : Args.filtered(OPT_c_isystem))
3268 Opts.AddPath(A->getValue(), frontend::CSystem, false, true);
3269 for (const auto *A : Args.filtered(OPT_cxx_isystem))
3270 Opts.AddPath(A->getValue(), frontend::CXXSystem, false, true);
3271 for (const auto *A : Args.filtered(OPT_objc_isystem))
3272 Opts.AddPath(A->getValue(), frontend::ObjCSystem, false,true);
3273 for (const auto *A : Args.filtered(OPT_objcxx_isystem))
3274 Opts.AddPath(A->getValue(), frontend::ObjCXXSystem, false, true);
3275
3276 // Add the internal paths from a driver that detects standard include paths.
3277 for (const auto *A :
3278 Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {
3280 if (A->getOption().matches(OPT_internal_externc_isystem))
3282 Opts.AddPath(A->getValue(), Group, false, true);
3283 }
3284
3285 // Add the path prefixes which are implicitly treated as being system headers.
3286 for (const auto *A :
3287 Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))
3289 A->getValue(), A->getOption().matches(OPT_system_header_prefix));
3290
3291 for (const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))
3292 Opts.AddVFSOverlayFile(A->getValue());
3293
3294 return Diags.getNumErrors() == NumErrorsBefore;
3295}
3296
3298 ArgumentConsumer Consumer) {
3299 if (!Opts.SwiftVersion.empty())
3300 GenerateArg(Consumer, OPT_fapinotes_swift_version,
3301 Opts.SwiftVersion.getAsString());
3302
3303 for (const auto &Path : Opts.ModuleSearchPaths)
3304 GenerateArg(Consumer, OPT_iapinotes_modules, Path);
3305}
3306
3307static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
3308 DiagnosticsEngine &diags) {
3309 if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
3310 if (Opts.SwiftVersion.tryParse(A->getValue()))
3311 diags.Report(diag::err_drv_invalid_value)
3312 << A->getAsString(Args) << A->getValue();
3313 }
3314 for (const Arg *A : Args.filtered(OPT_iapinotes_modules))
3315 Opts.ModuleSearchPaths.push_back(A->getValue());
3316}
3317
3318static void GeneratePointerAuthArgs(const LangOptions &Opts,
3319 ArgumentConsumer Consumer) {
3320 if (Opts.PointerAuthIntrinsics)
3321 GenerateArg(Consumer, OPT_fptrauth_intrinsics);
3322}
3323
3324static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args,
3325 DiagnosticsEngine &Diags) {
3326 Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);
3327}
3328
3329/// Check if input file kind and language standard are compatible.
3331 const LangStandard &S) {
3332 switch (IK.getLanguage()) {
3333 case Language::Unknown:
3334 case Language::LLVM_IR:
3335 case Language::CIR:
3336 llvm_unreachable("should not parse language flags for this input");
3337
3338 case Language::C:
3339 case Language::ObjC:
3341 return S.getLanguage() == Language::C;
3342
3343 case Language::OpenCL:
3344 return S.getLanguage() == Language::OpenCL ||
3345 S.getLanguage() == Language::OpenCLCXX;
3346
3348 return S.getLanguage() == Language::OpenCLCXX;
3349
3350 case Language::CXX:
3351 case Language::ObjCXX:
3352 return S.getLanguage() == Language::CXX;
3353
3354 case Language::CUDA:
3355 // FIXME: What -std= values should be permitted for CUDA compilations?
3356 return S.getLanguage() == Language::CUDA ||
3357 S.getLanguage() == Language::CXX;
3358
3359 case Language::HIP:
3360 return S.getLanguage() == Language::CXX || S.getLanguage() == Language::HIP;
3361
3362 case Language::Asm:
3363 // Accept (and ignore) all -std= values.
3364 // FIXME: The -std= value is not ignored; it affects the tokenization
3365 // and preprocessing rules if we're preprocessing this asm input.
3366 return true;
3367
3368 case Language::HLSL:
3369 return S.getLanguage() == Language::HLSL;
3370 }
3371
3372 llvm_unreachable("unexpected input language");
3373}
3374
3375/// Get language name for given input kind.
3376static StringRef GetInputKindName(InputKind IK) {
3377 switch (IK.getLanguage()) {
3378 case Language::C:
3379 return "C";
3380 case Language::ObjC:
3381 return "Objective-C";
3382 case Language::CXX:
3383 return "C++";
3384 case Language::ObjCXX:
3385 return "Objective-C++";
3386 case Language::OpenCL:
3387 return "OpenCL";
3389 return "C++ for OpenCL";
3390 case Language::CUDA:
3391 return "CUDA";
3393 return "RenderScript";
3394 case Language::HIP:
3395 return "HIP";
3396
3397 case Language::Asm:
3398 return "Asm";
3399 case Language::LLVM_IR:
3400 return "LLVM IR";
3401 case Language::CIR:
3402 return "Clang IR";
3403
3404 case Language::HLSL:
3405 return "HLSL";
3406
3407 case Language::Unknown:
3408 break;
3409 }
3410 llvm_unreachable("unknown input language");
3411}
3412
3413void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,
3414 ArgumentConsumer Consumer,
3415 const llvm::Triple &T,
3416 InputKind IK) {
3417 if (IK.getFormat() == InputKind::Precompiled ||
3419 IK.getLanguage() == Language::CIR) {
3420 if (Opts.ObjCAutoRefCount)
3421 GenerateArg(Consumer, OPT_fobjc_arc);
3422 if (Opts.PICLevel != 0)
3423 GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));
3424 if (Opts.PIE)
3425 GenerateArg(Consumer, OPT_pic_is_pie);
3426 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3427 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3428
3429 return;
3430 }
3431
3432 OptSpecifier StdOpt;
3433 switch (Opts.LangStd) {
3434 case LangStandard::lang_opencl10:
3435 case LangStandard::lang_opencl11:
3436 case LangStandard::lang_opencl12:
3437 case LangStandard::lang_opencl20:
3438 case LangStandard::lang_opencl30:
3439 case LangStandard::lang_openclcpp10:
3440 case LangStandard::lang_openclcpp2021:
3441 StdOpt = OPT_cl_std_EQ;
3442 break;
3443 default:
3444 StdOpt = OPT_std_EQ;
3445 break;
3446 }
3447
3449 GenerateArg(Consumer, StdOpt, LangStandard.getName());
3450
3451 if (Opts.IncludeDefaultHeader)
3452 GenerateArg(Consumer, OPT_finclude_default_header);
3453 if (Opts.DeclareOpenCLBuiltins)
3454 GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);
3455
3456 const LangOptions *LangOpts = &Opts;
3457
3458#define LANG_OPTION_WITH_MARSHALLING(...) \
3459 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
3460#include "clang/Driver/Options.inc"
3461#undef LANG_OPTION_WITH_MARSHALLING
3462
3463 // The '-fcf-protection=' option is generated by CodeGenOpts generator.
3464
3465 if (Opts.ObjC) {
3466 GenerateArg(Consumer, OPT_fobjc_runtime_EQ, Opts.ObjCRuntime.getAsString());
3467
3468 if (Opts.GC == LangOptions::GCOnly)
3469 GenerateArg(Consumer, OPT_fobjc_gc_only);
3470 else if (Opts.GC == LangOptions::HybridGC)
3471 GenerateArg(Consumer, OPT_fobjc_gc);
3472 else if (Opts.ObjCAutoRefCount == 1)
3473 GenerateArg(Consumer, OPT_fobjc_arc);
3474
3475 if (Opts.ObjCWeakRuntime)
3476 GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);
3477
3478 if (Opts.ObjCWeak)
3479 GenerateArg(Consumer, OPT_fobjc_weak);
3480
3481 if (Opts.ObjCSubscriptingLegacyRuntime)
3482 GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime);
3483 }
3484
3485 if (Opts.GNUCVersion != 0) {
3486 unsigned Major = Opts.GNUCVersion / 100 / 100;
3487 unsigned Minor = (Opts.GNUCVersion / 100) % 100;
3488 unsigned Patch = Opts.GNUCVersion % 100;
3489 GenerateArg(Consumer, OPT_fgnuc_version_EQ,
3490 Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch));
3491 }
3492
3493 if (Opts.IgnoreXCOFFVisibility)
3494 GenerateArg(Consumer, OPT_mignore_xcoff_visibility);
3495
3496 if (Opts.SignedOverflowBehavior == LangOptions::SOB_Trapping) {
3497 GenerateArg(Consumer, OPT_ftrapv);
3498 GenerateArg(Consumer, OPT_ftrapv_handler, Opts.OverflowHandler);
3499 } else if (Opts.SignedOverflowBehavior == LangOptions::SOB_Defined) {
3500 GenerateArg(Consumer, OPT_fwrapv);
3501 }
3502
3503 if (Opts.MSCompatibilityVersion != 0) {
3504 unsigned Major = Opts.MSCompatibilityVersion / 10000000;
3505 unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;
3506 unsigned Subminor = Opts.MSCompatibilityVersion % 100000;
3507 GenerateArg(Consumer, OPT_fms_compatibility_version,
3508 Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor));
3509 }
3510
3511 if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
3512 T.isOSzOS()) {
3513 if (!Opts.Trigraphs)
3514 GenerateArg(Consumer, OPT_fno_trigraphs);
3515 } else {
3516 if (Opts.Trigraphs)
3517 GenerateArg(Consumer, OPT_ftrigraphs);
3518 }
3519
3520 if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))
3521 GenerateArg(Consumer, OPT_fblocks);
3522
3523 if (Opts.ConvergentFunctions &&
3524 !(Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) || Opts.SYCLIsDevice ||
3525 Opts.HLSL))
3526 GenerateArg(Consumer, OPT_fconvergent_functions);
3527
3528 if (Opts.NoBuiltin && !Opts.Freestanding)
3529 GenerateArg(Consumer, OPT_fno_builtin);
3530
3531 if (!Opts.NoBuiltin)
3532 for (const auto &Func : Opts.NoBuiltinFuncs)
3533 GenerateArg(Consumer, OPT_fno_builtin_, Func);
3534
3535 if (Opts.LongDoubleSize == 128)
3536 GenerateArg(Consumer, OPT_mlong_double_128);
3537 else if (Opts.LongDoubleSize == 64)
3538 GenerateArg(Consumer, OPT_mlong_double_64);
3539 else if (Opts.LongDoubleSize == 80)
3540 GenerateArg(Consumer, OPT_mlong_double_80);
3541
3542 // Not generating '-mrtd', it's just an alias for '-fdefault-calling-conv='.
3543
3544 // OpenMP was requested via '-fopenmp', not implied by '-fopenmp-simd' or
3545 // '-fopenmp-targets='.
3546 if (Opts.OpenMP && !Opts.OpenMPSimd) {
3547 GenerateArg(Consumer, OPT_fopenmp);
3548
3549 if (Opts.OpenMP != 51)
3550 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3551
3552 if (!Opts.OpenMPUseTLS)
3553 GenerateArg(Consumer, OPT_fnoopenmp_use_tls);
3554
3555 if (Opts.OpenMPIsTargetDevice)
3556 GenerateArg(Consumer, OPT_fopenmp_is_target_device);
3557
3558 if (Opts.OpenMPIRBuilder)
3559 GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder);
3560 }
3561
3562 if (Opts.OpenMPSimd) {
3563 GenerateArg(Consumer, OPT_fopenmp_simd);
3564
3565 if (Opts.OpenMP != 51)
3566 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));
3567 }
3568
3569 if (Opts.OpenMPThreadSubscription)
3570 GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription);
3571
3572 if (Opts.OpenMPTeamSubscription)
3573 GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription);
3574
3575 if (Opts.OpenMPTargetDebug != 0)
3576 GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ,
3577 Twine(Opts.OpenMPTargetDebug));
3578
3579 if (Opts.OpenMPCUDANumSMs != 0)
3580 GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ,
3581 Twine(Opts.OpenMPCUDANumSMs));
3582
3583 if (Opts.OpenMPCUDABlocksPerSM != 0)
3584 GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ,
3585 Twine(Opts.OpenMPCUDABlocksPerSM));
3586
3587 if (Opts.OpenMPCUDAReductionBufNum != 1024)
3588 GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
3589 Twine(Opts.OpenMPCUDAReductionBufNum));
3590
3591 if (!Opts.OMPTargetTriples.empty()) {
3592 std::string Targets;
3593 llvm::raw_string_ostream OS(Targets);
3594 llvm::interleave(
3595 Opts.OMPTargetTriples, OS,
3596 [&OS](const llvm::Triple &T) { OS << T.str(); }, ",");
3597 GenerateArg(Consumer, OPT_fopenmp_targets_EQ, OS.str());
3598 }
3599
3600 if (!Opts.OMPHostIRFile.empty())
3601 GenerateArg(Consumer, OPT_fopenmp_host_ir_file_path, Opts.OMPHostIRFile);
3602
3603 if (Opts.OpenMPCUDAMode)
3604 GenerateArg(Consumer, OPT_fopenmp_cuda_mode);
3605
3606 if (Opts.OpenACC) {
3607 GenerateArg(Consumer, OPT_fopenacc);
3608 if (!Opts.OpenACCMacroOverride.empty())
3609 GenerateArg(Consumer, OPT_openacc_macro_override,
3611 }
3612
3613 // The arguments used to set Optimize, OptimizeSize and NoInlineDefine are
3614 // generated from CodeGenOptions.
3615
3616 if (Opts.DefaultFPContractMode == LangOptions::FPM_Fast)
3617 GenerateArg(Consumer, OPT_ffp_contract, "fast");
3618 else if (Opts.DefaultFPContractMode == LangOptions::FPM_On)
3619 GenerateArg(Consumer, OPT_ffp_contract, "on");
3620 else if (Opts.DefaultFPContractMode == LangOptions::FPM_Off)
3621 GenerateArg(Consumer, OPT_ffp_contract, "off");
3622 else if (Opts.DefaultFPContractMode == LangOptions::FPM_FastHonorPragmas)
3623 GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas");
3624
3625 for (StringRef Sanitizer : serializeSanitizerKinds(Opts.Sanitize))
3626 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);
3627
3628 // Conflating '-fsanitize-system-ignorelist' and '-fsanitize-ignorelist'.
3629 for (const std::string &F : Opts.NoSanitizeFiles)
3630 GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);
3631
3632 switch (Opts.getClangABICompat()) {
3634 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "3.8");
3635 break;
3637 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "4.0");
3638 break;
3640 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "6.0");
3641 break;
3643 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "7.0");
3644 break;
3646 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "9.0");
3647 break;
3649 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "11.0");
3650 break;
3652 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "12.0");
3653 break;
3655 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "14.0");
3656 break;
3658 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "15.0");
3659 break;
3661 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0");
3662 break;
3664 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0");
3665 break;
3667 break;
3668 }
3669
3670 if (Opts.getSignReturnAddressScope() ==
3672 GenerateArg(Consumer, OPT_msign_return_address_EQ, "all");
3673 else if (Opts.getSignReturnAddressScope() ==
3675 GenerateArg(Consumer, OPT_msign_return_address_EQ, "non-leaf");
3676
3677 if (Opts.getSignReturnAddressKey() ==
3679 GenerateArg(Consumer, OPT_msign_return_address_key_EQ, "b_key");
3680
3681 if (Opts.CXXABI)
3682 GenerateArg(Consumer, OPT_fcxx_abi_EQ,
3684
3685 if (Opts.RelativeCXXABIVTables)
3686 GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables);
3687 else
3688 GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables);
3689
3690 if (Opts.UseTargetPathSeparator)
3691 GenerateArg(Consumer, OPT_ffile_reproducible);
3692 else
3693 GenerateArg(Consumer, OPT_fno_file_reproducible);
3694
3695 for (const auto &MP : Opts.MacroPrefixMap)
3696 GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second);
3697
3698 if (!Opts.RandstructSeed.empty())
3699 GenerateArg(Consumer, OPT_frandomize_layout_seed_EQ, Opts.RandstructSeed);
3700}
3701
3702bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
3703 InputKind IK, const llvm::Triple &T,
3704 std::vector<std::string> &Includes,
3705 DiagnosticsEngine &Diags) {
3706 unsigned NumErrorsBefore = Diags.getNumErrors();
3707
3708 if (IK.getFormat() == InputKind::Precompiled ||
3710 IK.getLanguage() == Language::CIR) {
3711 // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
3712 // PassManager in BackendUtil.cpp. They need to be initialized no matter
3713 // what the input type is.
3714 if (Args.hasArg(OPT_fobjc_arc))
3715 Opts.ObjCAutoRefCount = 1;
3716 // PICLevel and PIELevel are needed during code generation and this should
3717 // be set regardless of the input type.
3718 Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
3719 Opts.PIE = Args.hasArg(OPT_pic_is_pie);
3720 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
3721 Diags, Opts.Sanitize);
3722
3723 return Diags.getNumErrors() == NumErrorsBefore;
3724 }
3725
3726 // Other LangOpts are only initialized when the input is not AST or LLVM IR.
3727 // FIXME: Should we really be parsing this for an Language::Asm input?
3728
3729 // FIXME: Cleanup per-file based stuff.
3731 if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {
3732 LangStd = LangStandard::getLangKind(A->getValue());
3733 if (LangStd == LangStandard::lang_unspecified) {
3734 Diags.Report(diag::err_drv_invalid_value)
3735 << A->getAsString(Args) << A->getValue();
3736 // Report supported standards with short description.
3737 for (unsigned KindValue = 0;
3738 KindValue != LangStandard::lang_unspecified;
3739 ++KindValue) {
3741 static_cast<LangStandard::Kind>(KindValue));
3743 auto Diag = Diags.Report(diag::note_drv_use_standard);
3744 Diag << Std.getName() << Std.getDescription();
3745 unsigned NumAliases = 0;
3746#define LANGSTANDARD(id, name, lang, desc, features)
3747#define LANGSTANDARD_ALIAS(id, alias) \
3748 if (KindValue == LangStandard::lang_##id) ++NumAliases;
3749#define LANGSTANDARD_ALIAS_DEPR(id, alias)
3750#include "clang/Basic/LangStandards.def"
3751 Diag << NumAliases;
3752#define LANGSTANDARD(id, name, lang, desc, features)
3753#define LANGSTANDARD_ALIAS(id, alias) \
3754 if (KindValue == LangStandard::lang_##id) Diag << alias;
3755#define LANGSTANDARD_ALIAS_DEPR(id, alias)
3756#include "clang/Basic/LangStandards.def"
3757 }
3758 }
3759 } else {
3760 // Valid standard, check to make sure language and standard are
3761 // compatible.
3764 Diags.Report(diag::err_drv_argument_not_allowed_with)
3765 << A->getAsString(Args) << GetInputKindName(IK);
3766 }
3767 }
3768 }
3769
3770 // -cl-std only applies for OpenCL language standards.
3771 // Override the -std option in this case.
3772 if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {
3773 LangStandard::Kind OpenCLLangStd
3774 = llvm::StringSwitch<LangStandard::Kind>(A->getValue())
3775 .Cases("cl", "CL", LangStandard::lang_opencl10)
3776 .Cases("cl1.0", "CL1.0", LangStandard::lang_opencl10)
3777 .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)
3778 .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)
3779 .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)
3780 .Cases("cl3.0", "CL3.0", LangStandard::lang_opencl30)
3781 .Cases("clc++", "CLC++", LangStandard::lang_openclcpp10)
3782 .Cases("clc++1.0", "CLC++1.0", LangStandard::lang_openclcpp10)
3783 .Cases("clc++2021", "CLC++2021", LangStandard::lang_openclcpp2021)
3785
3786 if (OpenCLLangStd == LangStandard::lang_unspecified) {
3787 Diags.Report(diag::err_drv_invalid_value)
3788 << A->getAsString(Args) << A->getValue();
3789 }
3790 else
3791 LangStd = OpenCLLangStd;
3792 }
3793
3794 // These need to be parsed now. They are used to set OpenCL defaults.
3795 Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
3796 Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);
3797
3798 LangOptions::setLangDefaults(Opts, IK.getLanguage(), T, Includes, LangStd);
3799
3800 // The key paths of codegen options defined in Options.td start with
3801 // "LangOpts->". Let's provide the expected variable name and type.
3802 LangOptions *LangOpts = &Opts;
3803
3804#define LANG_OPTION_WITH_MARSHALLING(...) \
3805 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
3806#include "clang/Driver/Options.inc"
3807#undef LANG_OPTION_WITH_MARSHALLING
3808
3809 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
3810 StringRef Name = A->getValue();
3811 if (Name == "full" || Name == "branch") {
3812 Opts.CFProtectionBranch = 1;
3813 }
3814 }
3815
3816 if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&
3817 !Args.hasArg(OPT_sycl_std_EQ)) {
3818 // If the user supplied -fsycl-is-device or -fsycl-is-host, but failed to
3819 // provide -sycl-std=, we want to default it to whatever the default SYCL
3820 // version is. I could not find a way to express this with the options
3821 // tablegen because we still want this value to be SYCL_None when the user
3822 // is not in device or host mode.
3823 Opts.setSYCLVersion(LangOptions::SYCL_Default);
3824 }
3825
3826 if (Opts.ObjC) {
3827 if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
3828 StringRef value = arg->getValue();
3829 if (Opts.ObjCRuntime.tryParse(value))
3830 Diags.Report(diag::err_drv_unknown_objc_runtime) << value;
3831 }
3832
3833 if (Args.hasArg(OPT_fobjc_gc_only))
3834 Opts.setGC(LangOptions::GCOnly);
3835 else if (Args.hasArg(OPT_fobjc_gc))
3836 Opts.setGC(LangOptions::HybridGC);
3837 else if (Args.hasArg(OPT_fobjc_arc)) {
3838 Opts.ObjCAutoRefCount = 1;
3839 if (!Opts.ObjCRuntime.allowsARC())
3840 Diags.Report(diag::err_arc_unsupported_on_runtime);
3841 }
3842
3843 // ObjCWeakRuntime tracks whether the runtime supports __weak, not
3844 // whether the feature is actually enabled. This is predominantly
3845 // determined by -fobjc-runtime, but we allow it to be overridden
3846 // from the command line for testing purposes.
3847 if (Args.hasArg(OPT_fobjc_runtime_has_weak))
3848 Opts.ObjCWeakRuntime = 1;
3849 else
3850 Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak();
3851
3852 // ObjCWeak determines whether __weak is actually enabled.
3853 // Note that we allow -fno-objc-weak to disable this even in ARC mode.
3854 if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {
3855 if (!weakArg->getOption().matches(OPT_fobjc_weak)) {
3856 assert(!Opts.ObjCWeak);
3857 } else if (Opts.getGC() != LangOptions::NonGC) {
3858 Diags.Report(diag::err_objc_weak_with_gc);
3859 } else if (!Opts.ObjCWeakRuntime) {
3860 Diags.Report(diag::err_objc_weak_unsupported);
3861 } else {
3862 Opts.ObjCWeak = 1;
3863 }
3864 } else if (Opts.ObjCAutoRefCount) {
3865 Opts.ObjCWeak = Opts.ObjCWeakRuntime;
3866 }
3867
3868 if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))
3869 Opts.ObjCSubscriptingLegacyRuntime =
3871 }
3872
3873 if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
3874 // Check that the version has 1 to 3 components and the minor and patch
3875 // versions fit in two decimal digits.
3876 VersionTuple GNUCVer;
3877 bool Invalid = GNUCVer.tryParse(A->getValue());
3878 unsigned Major = GNUCVer.getMajor();
3879 unsigned Minor = GNUCVer.getMinor().value_or(0);
3880 unsigned Patch = GNUCVer.getSubminor().value_or(0);
3881 if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
3882 Diags.Report(diag::err_drv_invalid_value)
3883 << A->getAsString(Args) << A->getValue();
3884 }
3885 Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
3886 }
3887
3888 if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility)))
3889 Opts.IgnoreXCOFFVisibility = 1;
3890
3891 if (Args.hasArg(OPT_ftrapv)) {
3892 Opts.setSignedOverflowBehavior(LangOptions::SOB_Trapping);
3893 // Set the handler, if one is specified.
3894 Opts.OverflowHandler =
3895 std::string(Args.getLastArgValue(OPT_ftrapv_handler));
3896 }
3897 else if (Args.hasArg(OPT_fwrapv))
3898 Opts.setSignedOverflowBehavior(LangOptions::SOB_Defined);
3899
3900 Opts.MSCompatibilityVersion = 0;
3901 if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {
3902 VersionTuple VT;
3903 if (VT.tryParse(A->getValue()))
3904 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)
3905 << A->getValue();
3906 Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +
3907 VT.getMinor().value_or(0) * 100000 +
3908 VT.getSubminor().value_or(0);
3909 }
3910
3911 // Mimicking gcc's behavior, trigraphs are only enabled if -trigraphs
3912 // is specified, or -std is set to a conforming mode.
3913 // Trigraphs are disabled by default in C++17 and C23 onwards.
3914 // For z/OS, trigraphs are enabled by default (without regard to the above).
3915 Opts.Trigraphs =
3916 (!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||
3917 T.isOSzOS();
3918 Opts.Trigraphs =
3919 Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);
3920
3921 Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL
3922 && Opts.OpenCLVersion == 200);
3923
3924 Opts.ConvergentFunctions = Args.hasArg(OPT_fconvergent_functions) ||
3925 Opts.OpenCL || (Opts.CUDA && Opts.CUDAIsDevice) ||
3926 Opts.SYCLIsDevice || Opts.HLSL;
3927
3928 Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;
3929 if (!Opts.NoBuiltin)
3931 if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {
3932 if (A->getOption().matches(options::OPT_mlong_double_64))
3933 Opts.LongDoubleSize = 64;
3934 else if (A->getOption().matches(options::OPT_mlong_double_80))
3935 Opts.LongDoubleSize = 80;
3936 else if (A->getOption().matches(options::OPT_mlong_double_128))
3937 Opts.LongDoubleSize = 128;
3938 else
3939 Opts.LongDoubleSize = 0;
3940 }
3941 if (Opts.FastRelaxedMath || Opts.CLUnsafeMath)
3942 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
3943
3944 llvm::sort(Opts.ModuleFeatures);
3945
3946 // -mrtd option
3947 if (Arg *A = Args.getLastArg(OPT_mrtd)) {
3948 if (Opts.getDefaultCallingConv() != LangOptions::DCC_None)
3949 Diags.Report(diag::err_drv_argument_not_allowed_with)
3950 << A->getSpelling() << "-fdefault-calling-conv";
3951 else {
3952 switch (T.getArch()) {
3953 case llvm::Triple::x86:
3954 Opts.setDefaultCallingConv(LangOptions::DCC_StdCall);
3955 break;
3956 case llvm::Triple::m68k:
3957 Opts.setDefaultCallingConv(LangOptions::DCC_RtdCall);
3958 break;
3959 default:
3960 Diags.Report(diag::err_drv_argument_not_allowed_with)
3961 << A->getSpelling() << T.getTriple();
3962 }
3963 }
3964 }
3965
3966 // Check if -fopenmp is specified and set default version to 5.0.
3967 Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;
3968 // Check if -fopenmp-simd is specified.
3969 bool IsSimdSpecified =
3970 Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,
3971 /*Default=*/false);
3972 Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;
3973 Opts.OpenMPUseTLS =
3974 Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
3975 Opts.OpenMPIsTargetDevice =
3976 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_target_device);
3977 Opts.OpenMPIRBuilder =
3978 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_enable_irbuilder);
3979 bool IsTargetSpecified =
3980 Opts.OpenMPIsTargetDevice || Args.hasArg(options::OPT_fopenmp_targets_EQ);
3981
3982 Opts.ConvergentFunctions =
3983 Opts.ConvergentFunctions || Opts.OpenMPIsTargetDevice;
3984
3985 if (Opts.OpenMP || Opts.OpenMPSimd) {
3986 if (int Version = getLastArgIntValue(
3987 Args, OPT_fopenmp_version_EQ,
3988 (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))
3989 Opts.OpenMP = Version;
3990 // Provide diagnostic when a given target is not expected to be an OpenMP
3991 // device or host.
3992 if (!Opts.OpenMPIsTargetDevice) {
3993 switch (T.getArch()) {
3994 default:
3995 break;
3996 // Add unsupported host targets here:
3997 case llvm::Triple::nvptx:
3998 case llvm::Triple::nvptx64:
3999 Diags.Report(diag::err_drv_omp_host_target_not_supported) << T.str();
4000 break;
4001 }
4002 }
4003 }
4004
4005 // Set the flag to prevent the implementation from emitting device exception
4006 // handling code for those requiring so.
4007 if ((Opts.OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) ||
4008 Opts.OpenCLCPlusPlus) {
4009
4010 Opts.Exceptions = 0;
4011 Opts.CXXExceptions = 0;
4012 }
4013 if (Opts.OpenMPIsTargetDevice && T.isNVPTX()) {
4014 Opts.OpenMPCUDANumSMs =
4015 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_number_of_sm_EQ,
4016 Opts.OpenMPCUDANumSMs, Diags);
4017 Opts.OpenMPCUDABlocksPerSM =
4018 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,
4019 Opts.OpenMPCUDABlocksPerSM, Diags);
4020 Opts.OpenMPCUDAReductionBufNum = getLastArgIntValue(
4021 Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,
4022 Opts.OpenMPCUDAReductionBufNum, Diags);
4023 }
4024
4025 // Set the value of the debugging flag used in the new offloading device RTL.
4026 // Set either by a specific value or to a default if not specified.
4027 if (Opts.OpenMPIsTargetDevice && (Args.hasArg(OPT_fopenmp_target_debug) ||
4028 Args.hasArg(OPT_fopenmp_target_debug_EQ))) {
4029 Opts.OpenMPTargetDebug = getLastArgIntValue(
4030 Args, OPT_fopenmp_target_debug_EQ, Opts.OpenMPTargetDebug, Diags);
4031 if (!Opts.OpenMPTargetDebug && Args.hasArg(OPT_fopenmp_target_debug))
4032 Opts.OpenMPTargetDebug = 1;
4033 }
4034
4035 if (Opts.OpenMPIsTargetDevice) {
4036 if (Args.hasArg(OPT_fopenmp_assume_teams_oversubscription))
4037 Opts.OpenMPTeamSubscription = true;
4038 if (Args.hasArg(OPT_fopenmp_assume_threads_oversubscription))
4039 Opts.OpenMPThreadSubscription = true;
4040 }
4041
4042 // Get the OpenMP target triples if any.
4043 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
4044 enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
4045 auto getArchPtrSize = [](const llvm::Triple &T) {
4046 if (T.isArch16Bit())
4047 return Arch16Bit;
4048 if (T.isArch32Bit())
4049 return Arch32Bit;
4050 assert(T.isArch64Bit() && "Expected 64-bit architecture");
4051 return Arch64Bit;
4052 };
4053
4054 for (unsigned i = 0; i < A->getNumValues(); ++i) {
4055 llvm::Triple TT(A->getValue(i));
4056
4057 if (TT.getArch() == llvm::Triple::UnknownArch ||
4058 !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() ||
4059 TT.getArch() == llvm::Triple::systemz ||
4060 TT.getArch() == llvm::Triple::nvptx ||
4061 TT.getArch() == llvm::Triple::nvptx64 ||
4062 TT.getArch() == llvm::Triple::amdgcn ||
4063 TT.getArch() == llvm::Triple::x86 ||
4064 TT.getArch() == llvm::Triple::x86_64))
4065 Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);
4066 else if (getArchPtrSize(T) != getArchPtrSize(TT))
4067 Diags.Report(diag::err_drv_incompatible_omp_arch)
4068 << A->getValue(i) << T.str();
4069 else
4070 Opts.OMPTargetTriples.push_back(TT);
4071 }
4072 }
4073
4074 // Get OpenMP host file path if any and report if a non existent file is
4075 // found
4076 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) {
4077 Opts.OMPHostIRFile = A->getValue();
4078 if (!llvm::sys::fs::exists(Opts.OMPHostIRFile))
4079 Diags.Report(diag::err_drv_omp_host_ir_file_not_found)
4080 << Opts.OMPHostIRFile;
4081 }
4082
4083 // Set CUDA mode for OpenMP target NVPTX/AMDGCN if specified in options
4084 Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice &&
4085 (T.isNVPTX() || T.isAMDGCN()) &&
4086 Args.hasArg(options::OPT_fopenmp_cuda_mode);
4087
4088 // OpenACC Configuration.
4089 if (Args.hasArg(options::OPT_fopenacc)) {
4090 Opts.OpenACC = true;
4091
4092 if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override))
4093 Opts.OpenACCMacroOverride = A->getValue();
4094 }
4095
4096 // FIXME: Eliminate this dependency.
4097 unsigned Opt = getOptimizationLevel(Args, IK, Diags),
4098 OptSize = getOptimizationLevelSize(Args);
4099 Opts.Optimize = Opt != 0;
4100 Opts.OptimizeSize = OptSize != 0;
4101
4102 // This is the __NO_INLINE__ define, which just depends on things like the
4103 // optimization level and -fno-inline, not actually whether the backend has
4104 // inlining enabled.
4105 Opts.NoInlineDefine = !Opts.Optimize;
4106 if (Arg *InlineArg = Args.getLastArg(
4107 options::OPT_finline_functions, options::OPT_finline_hint_functions,
4108 options::OPT_fno_inline_functions, options::OPT_fno_inline))
4109 if (InlineArg->getOption().matches(options::OPT_fno_inline))
4110 Opts.NoInlineDefine = true;
4111
4112 if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
4113 StringRef Val = A->getValue();
4114 if (Val == "fast")
4115 Opts.setDefaultFPContractMode(LangOptions::FPM_Fast);
4116 else if (Val == "on")
4117 Opts.setDefaultFPContractMode(LangOptions::FPM_On);
4118 else if (Val == "off")
4119 Opts.setDefaultFPContractMode(LangOptions::FPM_Off);
4120 else if (Val == "fast-honor-pragmas")
4121 Opts.setDefaultFPContractMode(LangOptions::FPM_FastHonorPragmas);
4122 else
4123 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
4124 }
4125
4126 // Parse -fsanitize= arguments.
4127 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),
4128 Diags, Opts.Sanitize);
4129 Opts.NoSanitizeFiles = Args.getAllArgValues(OPT_fsanitize_ignorelist_EQ);
4130 std::vector<std::string> systemIgnorelists =
4131 Args.getAllArgValues(OPT_fsanitize_system_ignorelist_EQ);
4132 Opts.NoSanitizeFiles.insert(Opts.NoSanitizeFiles.end(),
4133 systemIgnorelists.begin(),
4134 systemIgnorelists.end());
4135
4136 if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
4137 Opts.setClangABICompat(LangOptions::ClangABI::Latest);
4138
4139 StringRef Ver = A->getValue();
4140 std::pair<StringRef, StringRef> VerParts = Ver.split('.');
4141 unsigned Major, Minor = 0;
4142
4143 // Check the version number is valid: either 3.x (0 <= x <= 9) or
4144 // y or y.0 (4 <= y <= current version).
4145 if (!VerParts.first.starts_with("0") &&
4146 !VerParts.first.getAsInteger(10, Major) && 3 <= Major &&
4147 Major <= CLANG_VERSION_MAJOR &&
4148 (Major == 3
4149 ? VerParts.second.size() == 1 &&
4150 !VerParts.second.getAsInteger(10, Minor)
4151 : VerParts.first.size() == Ver.size() || VerParts.second == "0")) {
4152 // Got a valid version number.
4153 if (Major == 3 && Minor <= 8)
4154 Opts.setClangABICompat(LangOptions::ClangABI::Ver3_8);
4155 else if (Major <= 4)
4156 Opts.setClangABICompat(LangOptions::ClangABI::Ver4);
4157 else if (Major <= 6)
4158 Opts.setClangABICompat(LangOptions::ClangABI::Ver6);
4159 else if (Major <= 7)
4160 Opts.setClangABICompat(LangOptions::ClangABI::Ver7);
4161 else if (Major <= 9)
4162 Opts.setClangABICompat(LangOptions::ClangABI::Ver9);
4163 else if (Major <= 11)
4164 Opts.setClangABICompat(LangOptions::ClangABI::Ver11);
4165 else if (Major <= 12)
4166 Opts.setClangABICompat(LangOptions::ClangABI::Ver12);
4167 else if (Major <= 14)
4168 Opts.setClangABICompat(LangOptions::ClangABI::Ver14);
4169 else if (Major <= 15)
4170 Opts.setClangABICompat(LangOptions::ClangABI::Ver15);
4171 else if (Major <= 17)
4172 Opts.setClangABICompat(LangOptions::ClangABI::Ver17);
4173 else if (Major <= 18)
4174 Opts.setClangABICompat(LangOptions::ClangABI::Ver18);
4175 } else if (Ver != "latest") {
4176 Diags.Report(diag::err_drv_invalid_value)
4177 << A->getAsString(Args) << A->getValue();
4178 }
4179 }
4180
4181 if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) {
4182 StringRef SignScope = A->getValue();
4183
4184 if (SignScope.equals_insensitive("none"))
4185 Opts.setSignReturnAddressScope(
4187 else if (SignScope.equals_insensitive("all"))
4188 Opts.setSignReturnAddressScope(
4190 else if (SignScope.equals_insensitive("non-leaf"))
4191 Opts.setSignReturnAddressScope(
4193 else
4194 Diags.Report(diag::err_drv_invalid_value)
4195 << A->getAsString(Args) << SignScope;
4196
4197 if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {
4198 StringRef SignKey = A->getValue();
4199 if (!SignScope.empty() && !SignKey.empty()) {
4200 if (SignKey == "a_key")
4201 Opts.setSignReturnAddressKey(
4203 else if (SignKey == "b_key")
4204 Opts.setSignReturnAddressKey(
4206 else
4207 Diags.Report(diag::err_drv_invalid_value)
4208 << A->getAsString(Args) << SignKey;
4209 }
4210 }
4211 }
4212
4213 // The value can be empty, which indicates the system default should be used.
4214 StringRef CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);
4215 if (!CXXABI.empty()) {
4217 Diags.Report(diag::err_invalid_cxx_abi) << CXXABI;
4218 } else {
4221 Diags.Report(diag::err_unsupported_cxx_abi) << CXXABI << T.str();
4222 else
4223 Opts.CXXABI = Kind;
4224 }
4225 }
4226
4227 Opts.RelativeCXXABIVTables =
4228 Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
4229 options::OPT_fno_experimental_relative_cxx_abi_vtables,
4231
4232 // RTTI is on by default.
4233 bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti);
4234 Opts.OmitVTableRTTI =
4235 Args.hasFlag(options::OPT_fexperimental_omit_vtable_rtti,
4236 options::OPT_fno_experimental_omit_vtable_rtti, false);
4237 if (Opts.OmitVTableRTTI && HasRTTI)
4238 Diags.Report(diag::err_drv_using_omit_rtti_component_without_no_rtti);
4239
4240 for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {
4241 auto Split = StringRef(A).split('=');
4242 Opts.MacroPrefixMap.insert(
4243 {std::string(Split.first), std::string(Split.second)});
4244 }
4245
4247 !Args.getLastArg(OPT_fno_file_reproducible) &&
4248 (Args.getLastArg(OPT_ffile_compilation_dir_EQ) ||
4249 Args.getLastArg(OPT_fmacro_prefix_map_EQ) ||
4250 Args.getLastArg(OPT_ffile_reproducible));
4251
4252 // Error if -mvscale-min is unbounded.
4253 if (Arg *A = Args.getLastArg(options::OPT_mvscale_min_EQ)) {
4254 unsigned VScaleMin;
4255 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)
4256 Diags.Report(diag::err_cc1_unbounded_vscale_min);
4257 }
4258
4259 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) {
4260 std::ifstream SeedFile(A->getValue(0));
4261
4262 if (!SeedFile.is_open())
4263 Diags.Report(diag::err_drv_cannot_open_randomize_layout_seed_file)
4264 << A->getValue(0);
4265
4266 std::getline(SeedFile, Opts.RandstructSeed);
4267 }
4268
4269 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))
4270 Opts.RandstructSeed = A->getValue(0);
4271
4272 // Validate options for HLSL
4273 if (Opts.HLSL) {
4274 // TODO: Revisit restricting SPIR-V to logical once we've figured out how to
4275 // handle PhysicalStorageBuffer64 memory model
4276 if (T.isDXIL() || T.isSPIRVLogical()) {
4277 enum { ShaderModel, VulkanEnv, ShaderStage };
4278 enum { OS, Environment };
4279
4280 int ExpectedOS = T.isSPIRVLogical() ? VulkanEnv : ShaderModel;
4281
4282 if (T.getOSName().empty()) {
4283 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4284 << ExpectedOS << OS << T.str();
4285 } else if (T.getEnvironmentName().empty()) {
4286 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
4287 << ShaderStage << Environment << T.str();
4288 } else if (!T.isShaderStageEnvironment()) {
4289 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4290 << ShaderStage << T.getEnvironmentName() << T.str();
4291 }
4292
4293 if (T.isDXIL()) {
4294 if (!T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
4295 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4296 << ShaderModel << T.getOSName() << T.str();
4297 }
4298 // Validate that if fnative-half-type is given, that
4299 // the language standard is at least hlsl2018, and that
4300 // the target shader model is at least 6.2.
4301 if (Args.getLastArg(OPT_fnative_half_type)) {
4302 const LangStandard &Std =
4304 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018 &&
4305 T.getOSVersion() >= VersionTuple(6, 2)))
4306 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4307 << "-enable-16bit-types" << true << Std.getName()
4308 << T.getOSVersion().getAsString();
4309 }
4310 } else if (T.isSPIRVLogical()) {
4311 if (!T.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) {
4312 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
4313 << VulkanEnv << T.getOSName() << T.str();
4314 }
4315 if (Args.getLastArg(OPT_fnative_half_type)) {
4316 const LangStandard &Std =
4318 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018))
4319 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
4320 << "-fnative-half-type" << false << Std.getName();
4321 }
4322 } else {
4323 llvm_unreachable("expected DXIL or SPIR-V target");
4324 }
4325 } else
4326 Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
4327 }
4328
4329 return Diags.getNumErrors() == NumErrorsBefore;
4330}
4331
4333 switch (Action) {
4335 case frontend::ASTDump:
4336 case frontend::ASTPrint:
4337 case frontend::ASTView:
4339 case frontend::EmitBC:
4340 case frontend::EmitHTML:
4341 case frontend::EmitLLVM:
4344 case frontend::EmitObj:
4346 case frontend::FixIt:
4362 return false;
4363
4367 case frontend::InitOnly:
4373 return true;
4374 }
4375 llvm_unreachable("invalid frontend action");
4376}
4377
4379 ArgumentConsumer Consumer,
4380 const LangOptions &LangOpts,
4381 const FrontendOptions &FrontendOpts,
4382 const CodeGenOptions &CodeGenOpts) {
4383 const PreprocessorOptions *PreprocessorOpts = &Opts;
4384
4385#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4386 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4387#include "clang/Driver/Options.inc"
4388#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4389
4390 if (Opts.PCHWithHdrStop && !Opts.PCHWithHdrStopCreate)
4391 GenerateArg(Consumer, OPT_pch_through_hdrstop_use);
4392
4393 for (const auto &D : Opts.DeserializedPCHDeclsToErrorOn)
4394 GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);
4395
4396 if (Opts.PrecompiledPreambleBytes != std::make_pair(0u, false))
4397 GenerateArg(Consumer, OPT_preamble_bytes_EQ,
4398 Twine(Opts.PrecompiledPreambleBytes.first) + "," +
4399 (Opts.PrecompiledPreambleBytes.second ? "1" : "0"));
4400
4401 for (const auto &M : Opts.Macros) {
4402 // Don't generate __CET__ macro definitions. They are implied by the
4403 // -fcf-protection option that is generated elsewhere.
4404 if (M.first == "__CET__=1" && !M.second &&
4405 !CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch)
4406 continue;
4407 if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn &&
4408 !CodeGenOpts.CFProtectionBranch)
4409 continue;
4410 if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn &&
4411 CodeGenOpts.CFProtectionBranch)
4412 continue;
4413
4414 GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first);
4415 }
4416
4417 for (const auto &I : Opts.Includes) {
4418 // Don't generate OpenCL includes. They are implied by other flags that are
4419 // generated elsewhere.
4420 if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader &&
4421 ((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") ||
4422 I == "opencl-c.h"))
4423 continue;
4424 // Don't generate HLSL includes. They are implied by other flags that are
4425 // generated elsewhere.
4426 if (LangOpts.HLSL && I == "hlsl.h")
4427 continue;
4428
4429 GenerateArg(Consumer, OPT_include, I);
4430 }
4431
4432 for (const auto &CI : Opts.ChainedIncludes)
4433 GenerateArg(Consumer, OPT_chain_include, CI);
4434
4435 for (const auto &RF : Opts.RemappedFiles)
4436 GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second);
4437
4438 if (Opts.SourceDateEpoch)
4439 GenerateArg(Consumer, OPT_source_date_epoch, Twine(*Opts.SourceDateEpoch));
4440
4441 if (Opts.DefineTargetOSMacros)
4442 GenerateArg(Consumer, OPT_fdefine_target_os_macros);
4443
4444 // Don't handle LexEditorPlaceholders. It is implied by the action that is
4445 // generated elsewhere.
4446}
4447
4448static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
4449 DiagnosticsEngine &Diags,
4451 const FrontendOptions &FrontendOpts) {
4452 unsigned NumErrorsBefore = Diags.getNumErrors();
4453
4454 PreprocessorOptions *PreprocessorOpts = &Opts;
4455
4456#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \
4457 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4458#include "clang/Driver/Options.inc"
4459#undef PREPROCESSOR_OPTION_WITH_MARSHALLING
4460
4461 Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) ||
4462 Args.hasArg(OPT_pch_through_hdrstop_use);
4463
4464 for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
4465 Opts.DeserializedPCHDeclsToErrorOn.insert(A->getValue());
4466
4467 if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {
4468 StringRef Value(A->getValue());
4469 size_t Comma = Value.find(',');
4470 unsigned Bytes = 0;
4471 unsigned EndOfLine = 0;
4472
4473 if (Comma == StringRef::npos ||
4474 Value.substr(0, Comma).getAsInteger(10, Bytes) ||
4475 Value.substr(Comma + 1).getAsInteger(10, EndOfLine))
4476 Diags.Report(diag::err_drv_preamble_format);
4477 else {
4478 Opts.PrecompiledPreambleBytes.first = Bytes;
4479 Opts.PrecompiledPreambleBytes.second = (EndOfLine != 0);
4480 }
4481 }
4482
4483 // Add the __CET__ macro if a CFProtection option is set.
4484 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {
4485 StringRef Name = A->getValue();
4486 if (Name == "branch")
4487 Opts.addMacroDef("__CET__=1");
4488 else if (Name == "return")
4489 Opts.addMacroDef("__CET__=2");
4490 else if (Name == "full")
4491 Opts.addMacroDef("__CET__=3");
4492 }
4493
4494 // Add macros from the command line.
4495 for (const auto *A : Args.filtered(OPT_D, OPT_U)) {
4496 if (A->getOption().matches(OPT_D))
4497 Opts.addMacroDef(A->getValue());
4498 else
4499 Opts.addMacroUndef(A->getValue());
4500 }
4501
4502 // Add the ordered list of -includes.
4503 for (const auto *A : Args.filtered(OPT_include))
4504 Opts.Includes.emplace_back(A->getValue());
4505
4506 for (const auto *A : Args.filtered(OPT_chain_include))
4507 Opts.ChainedIncludes.emplace_back(A->getValue());
4508
4509 for (const auto *A : Args.filtered(OPT_remap_file)) {
4510 std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');
4511
4512 if (Split.second.empty()) {
4513 Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);
4514 continue;
4515 }
4516
4517 Opts.addRemappedFile(Split.first, Split.second);
4518 }
4519
4520 if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {
4521 StringRef Epoch = A->getValue();
4522 // SOURCE_DATE_EPOCH, if specified, must be a non-negative decimal integer.
4523 // On time64 systems, pick 253402300799 (the UNIX timestamp of
4524 // 9999-12-31T23:59:59Z) as the upper bound.
4525 const uint64_t MaxTimestamp =
4526 std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);
4527 uint64_t V;
4528 if (Epoch.getAsInteger(10, V) || V > MaxTimestamp) {
4529 Diags.Report(diag::err_fe_invalid_source_date_epoch)
4530 << Epoch << MaxTimestamp;
4531 } else {
4532 Opts.SourceDateEpoch = V;
4533 }
4534 }
4535
4536 // Always avoid lexing editor placeholders when we're just running the
4537 // preprocessor as we never want to emit the
4538 // "editor placeholder in source file" error in PP only mode.
4540 Opts.LexEditorPlaceholders = false;
4541
4543 Args.hasFlag(OPT_fdefine_target_os_macros,
4544 OPT_fno_define_target_os_macros, Opts.DefineTargetOSMacros);
4545
4546 return Diags.getNumErrors() == NumErrorsBefore;
4547}
4548
4549static void
4551 ArgumentConsumer Consumer,
4553 const PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
4554
4555#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4556 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4557#include "clang/Driver/Options.inc"
4558#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4559
4560 bool Generate_dM = isStrictlyPreprocessorAction(Action) && !Opts.ShowCPP;
4561 if (Generate_dM)
4562 GenerateArg(Consumer, OPT_dM);
4563 if (!Generate_dM && Opts.ShowMacros)
4564 GenerateArg(Consumer, OPT_dD);
4565 if (Opts.DirectivesOnly)
4566 GenerateArg(Consumer, OPT_fdirectives_only);
4567}
4568
4570 ArgList &Args, DiagnosticsEngine &Diags,
4572 unsigned NumErrorsBefore = Diags.getNumErrors();
4573
4574 PreprocessorOutputOptions &PreprocessorOutputOpts = Opts;
4575
4576#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \
4577 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4578#include "clang/Driver/Options.inc"
4579#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING
4580
4581 Opts.ShowCPP = isStrictlyPreprocessorAction(Action) && !Args.hasArg(OPT_dM);
4582 Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);
4583 Opts.DirectivesOnly = Args.hasArg(OPT_fdirectives_only);
4584
4585 return Diags.getNumErrors() == NumErrorsBefore;
4586}
4587
4588static void GenerateTargetArgs(const TargetOptions &Opts,
4589 ArgumentConsumer Consumer) {
4590 const TargetOptions *TargetOpts = &Opts;
4591#define TARGET_OPTION_WITH_MARSHALLING(...) \
4592 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
4593#include "clang/Driver/Options.inc"
4594#undef TARGET_OPTION_WITH_MARSHALLING
4595
4596 if (!Opts.SDKVersion.empty())
4597 GenerateArg(Consumer, OPT_target_sdk_version_EQ,
4598 Opts.SDKVersion.getAsString());
4599 if (!Opts.DarwinTargetVariantSDKVersion.empty())
4600 GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,
4601 Opts.DarwinTargetVariantSDKVersion.getAsString());
4602}
4603
4604static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
4605 DiagnosticsEngine &Diags) {
4606 unsigned NumErrorsBefore = Diags.getNumErrors();
4607
4608 TargetOptions *TargetOpts = &Opts;
4609
4610#define TARGET_OPTION_WITH_MARSHALLING(...) \
4611 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)
4612#include "clang/Driver/Options.inc"
4613#undef TARGET_OPTION_WITH_MARSHALLING
4614
4615 if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {
4616 llvm::VersionTuple Version;
4617 if (Version.tryParse(A->getValue()))
4618 Diags.Report(diag::err_drv_invalid_value)
4619 << A->getAsString(Args) << A->getValue();
4620 else
4621 Opts.SDKVersion = Version;
4622 }
4623 if (Arg *A =
4624 Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {
4625 llvm::VersionTuple Version;
4626 if (Version.tryParse(A->getValue()))
4627 Diags.Report(diag::err_drv_invalid_value)
4628 << A->getAsString(Args) << A->getValue();
4629 else
4630 Opts.DarwinTargetVariantSDKVersion = Version;
4631 }
4632
4633 return Diags.getNumErrors() == NumErrorsBefore;
4634}
4635
4636bool CompilerInvocation::CreateFromArgsImpl(
4637 CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs,
4638 DiagnosticsEngine &Diags, const char *Argv0) {
4639 unsigned NumErrorsBefore = Diags.getNumErrors();
4640
4641 // Parse the arguments.
4642 const OptTable &Opts = getDriverOptTable();
4643 llvm::opt::Visibility VisibilityMask(options::CC1Option);
4644 unsigned MissingArgIndex, MissingArgCount;
4645 InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,
4646 MissingArgCount, VisibilityMask);
4648
4649 // Check for missing argument error.
4650 if (MissingArgCount)
4651 Diags.Report(diag::err_drv_missing_argument)
4652 << Args.getArgString(MissingArgIndex) << MissingArgCount;
4653
4654 // Issue errors on unknown arguments.
4655 for (const auto *A : Args.filtered(OPT_UNKNOWN)) {
4656 auto ArgString = A->getAsString(Args);
4657 std::string Nearest;
4658 if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1)
4659 Diags.Report(diag::err_drv_unknown_argument) << ArgString;
4660 else
4661 Diags.Report(diag::err_drv_unknown_argument_with_suggestion)
4662 << ArgString << Nearest;
4663 }
4664
4665 ParseFileSystemArgs(Res.getFileSystemOpts(), Args, Diags);
4666 ParseMigratorArgs(Res.getMigratorOpts(), Args, Diags);
4667 ParseAnalyzerArgs(Res.getAnalyzerOpts(), Args, Diags);
4668 ParseDiagnosticArgs(Res.getDiagnosticOpts(), Args, &Diags,
4669 /*DefaultDiagColor=*/false);
4670 ParseFrontendArgs(Res.getFrontendOpts(), Args, Diags, LangOpts.IsHeaderFile);
4671 // FIXME: We shouldn't have to pass the DashX option around here
4672 InputKind DashX = Res.getFrontendOpts().DashX;
4673 ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
4674 llvm::Triple T(Res.getTargetOpts().Triple);
4675 ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args, Diags,
4677 ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
4678
4679 ParsePointerAuthArgs(LangOpts, Args, Diags);
4680
4681 ParseLangArgs(LangOpts, Args, DashX, T, Res.getPreprocessorOpts().Includes,
4682 Diags);
4684 LangOpts.ObjCExceptions = 1;
4685
4686 for (auto Warning : Res.getDiagnosticOpts().Warnings) {
4687 if (Warning == "misexpect" &&
4688 !Diags.isIgnored(diag::warn_profile_data_misexpect, SourceLocation())) {
4689 Res.getCodeGenOpts().MisExpect = true;
4690 }
4691 }
4692
4693 if (LangOpts.CUDA) {
4694 // During CUDA device-side compilation, the aux triple is the
4695 // triple used for host compilation.
4696 if (LangOpts.CUDAIsDevice)
4698 }
4699
4700 // Set the triple of the host for OpenMP device compile.
4701 if (LangOpts.OpenMPIsTargetDevice)
4703
4704 ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,
4706
4707 // FIXME: Override value name discarding when asan or msan is used because the
4708 // backend passes depend on the name of the alloca in order to print out
4709 // names.
4710 Res.getCodeGenOpts().DiscardValueNames &=
4711 !LangOpts.Sanitize.has(SanitizerKind::Address) &&
4712 !LangOpts.Sanitize.has(SanitizerKind::KernelAddress) &&
4713 !LangOpts.Sanitize.has(SanitizerKind::Memory) &&
4714 !LangOpts.Sanitize.has(SanitizerKind::KernelMemory);
4715
4716 ParsePreprocessorArgs(Res.getPreprocessorOpts(), Args, Diags,
4718 Res.getFrontendOpts());
4721
4725 if (!Res.getDependencyOutputOpts().OutputFile.empty() &&
4726 Res.getDependencyOutputOpts().Targets.empty())
4727 Diags.Report(diag::err_fe_dependency_file_requires_MT);
4728
4729 // If sanitizer is enabled, disable OPT_ffine_grained_bitfield_accesses.
4730 if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&
4731 !Res.getLangOpts().Sanitize.empty()) {
4732 Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;
4733 Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);
4734 }
4735
4736 // Store the command-line for using in the CodeView backend.
4737 if (Res.getCodeGenOpts().CodeViewCommandLine) {
4738 Res.getCodeGenOpts().Argv0 = Argv0;
4739 append_range(Res.getCodeGenOpts().CommandLineArgs, CommandLineArgs);
4740 }
4741
4742 // Set PGOOptions. Need to create a temporary VFS to read the profile
4743 // to determine the PGO type.
4744 if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty()) {
4745 auto FS =
4747 Diags, llvm::vfs::getRealFileSystem());
4750 Diags);
4751 }
4752
4753 FixupInvocation(Res, Diags, Args, DashX);
4754
4755 return Diags.getNumErrors() == NumErrorsBefore;
4756}
4757
4759 ArrayRef<const char *> CommandLineArgs,
4760 DiagnosticsEngine &Diags,
4761 const char *Argv0) {
4762 CompilerInvocation DummyInvocation;
4763
4764 return RoundTrip(
4765 [](CompilerInvocation &Invocation, ArrayRef<const char *> CommandLineArgs,
4766 DiagnosticsEngine &Diags, const char *Argv0) {
4767 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);
4768 },
4770 StringAllocator SA) {
4771 Args.push_back("-cc1");
4772 Invocation.generateCC1CommandLine(Args, SA);
4773 },
4774 Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);
4775}
4776
4778 // FIXME: Consider using SHA1 instead of MD5.
4779 llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;
4780
4781 // Note: For QoI reasons, the things we use as a hash here should all be
4782 // dumped via the -module-info flag.
4783
4784 // Start the signature with the compiler version.
4785 HBuilder.add(getClangFullRepositoryVersion());
4786
4787 // Also include the serialization version, in case LLVM_APPEND_VC_REV is off
4788 // and getClangFullRepositoryVersion() doesn't include git revision.
4790
4791 // Extend the signature with the language options
4792#define LANGOPT(Name, Bits, Default, Description) HBuilder.add(LangOpts->Name);
4793#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
4794 HBuilder.add(static_cast<unsigned>(LangOpts->get##Name()));
4795#define BENIGN_LANGOPT(Name, Bits, Default, Description)
4796#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
4797#include "clang/Basic/LangOptions.def"
4798
4799 HBuilder.addRange(getLangOpts().ModuleFeatures);
4800
4801 HBuilder.add(getLangOpts().ObjCRuntime);
4802 HBuilder.addRange(getLangOpts().CommentOpts.BlockCommandNames);
4803
4804 // Extend the signature with the target options.
4805 HBuilder.add(getTargetOpts().Triple, getTargetOpts().CPU,
4806 getTargetOpts().TuneCPU, getTargetOpts().ABI);
4807 HBuilder.addRange(getTargetOpts().FeaturesAsWritten);
4808
4809 // Extend the signature with preprocessor options.
4810 const PreprocessorOptions &ppOpts = getPreprocessorOpts();
4811 HBuilder.add(ppOpts.UsePredefines, ppOpts.DetailedRecord);
4812
4813 const HeaderSearchOptions &hsOpts = getHeaderSearchOpts();
4814 for (const auto &Macro : getPreprocessorOpts().Macros) {
4815 // If we're supposed to ignore this macro for the purposes of modules,
4816 // don't put it into the hash.
4817 if (!hsOpts.ModulesIgnoreMacros.empty()) {
4818 // Check whether we're ignoring this macro.
4819 StringRef MacroDef = Macro.first;
4820 if (hsOpts.ModulesIgnoreMacros.count(
4821 llvm::CachedHashString(MacroDef.split('=').first)))
4822 continue;
4823 }
4824
4825 HBuilder.add(Macro);
4826 }
4827
4828 // Extend the signature with the sysroot and other header search options.
4829 HBuilder.add(hsOpts.Sysroot, hsOpts.ModuleFormat, hsOpts.UseDebugInfo,
4831 hsOpts.UseStandardCXXIncludes, hsOpts.UseLibcxx,
4833 HBuilder.add(hsOpts.ResourceDir);
4834
4835 if (hsOpts.ModulesStrictContextHash) {
4836 HBuilder.addRange(hsOpts.SystemHeaderPrefixes);
4837 HBuilder.addRange(hsOpts.UserEntries);
4838 HBuilder.addRange(hsOpts.VFSOverlayFiles);
4839
4840 const DiagnosticOptions &diagOpts = getDiagnosticOpts();
4841#define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name);
4842#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
4843 HBuilder.add(diagOpts.get##Name());
4844#include "clang/Basic/DiagnosticOptions.def"
4845#undef DIAGOPT
4846#undef ENUM_DIAGOPT
4847 }
4848
4849 // Extend the signature with the user build path.
4850 HBuilder.add(hsOpts.ModuleUserBuildPath);
4851
4852 // Extend the signature with the module file extensions.
4853 for (const auto &ext : getFrontendOpts().ModuleFileExtensions)
4854 ext->hashExtension(HBuilder);
4855
4856 // Extend the signature with the Swift version for API notes.
4858 if (!APINotesOpts.SwiftVersion.empty()) {
4859 HBuilder.add(APINotesOpts.SwiftVersion.getMajor());
4860 if (auto Minor = APINotesOpts.SwiftVersion.getMinor())
4861 HBuilder.add(*Minor);
4862 if (auto Subminor = APINotesOpts.SwiftVersion.getSubminor())
4863 HBuilder.add(*Subminor);
4864 if (auto Build = APINotesOpts.SwiftVersion.getBuild())
4865 HBuilder.add(*Build);
4866 }
4867
4868 // When compiling with -gmodules, also hash -fdebug-prefix-map as it
4869 // affects the debug info in the PCM.
4870 if (getCodeGenOpts().DebugTypeExtRefs)
4871 HBuilder.addRange(getCodeGenOpts().DebugPrefixMap);
4872
4873 // Extend the signature with the affecting debug options.
4874 if (getHeaderSearchOpts().ModuleFormat == "obj") {
4875#define DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);
4876#define VALUE_DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);
4877#define ENUM_DEBUGOPT(Name, Type, Bits, Default) \
4878 HBuilder.add(static_cast<unsigned>(CodeGenOpts->get##Name()));
4879#define BENIGN_DEBUGOPT(Name, Bits, Default)
4880#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default)
4881#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default)
4882#include "clang/Basic/DebugOptions.def"
4883 }
4884
4885 // Extend the signature with the enabled sanitizers, if at least one is
4886 // enabled. Sanitizers which cannot affect AST generation aren't hashed.
4887 SanitizerSet SanHash = getLangOpts().Sanitize;
4889 if (!SanHash.empty())
4890 HBuilder.add(SanHash.Mask);
4891
4892 llvm::MD5::MD5Result Result;
4893 HBuilder.getHasher().final(Result);
4894 uint64_t Hash = Result.high() ^ Result.low();
4895 return toString(llvm::APInt(64, Hash), 36, /*Signed=*/false);
4896}
4897
4899 ArgumentConsumer Consumer) const {
4900 llvm::Triple T(getTargetOpts().Triple);
4901
4905 GenerateDiagnosticArgs(getDiagnosticOpts(), Consumer,
4906 /*DefaultDiagColor=*/false);
4907 GenerateFrontendArgs(getFrontendOpts(), Consumer, getLangOpts().IsHeaderFile);
4908 GenerateTargetArgs(getTargetOpts(), Consumer);
4912 GenerateLangArgs(getLangOpts(), Consumer, T, getFrontendOpts().DashX);
4913 GenerateCodeGenArgs(getCodeGenOpts(), Consumer, T,
4914 getFrontendOpts().OutputFile, &getLangOpts());
4918 getFrontendOpts().ProgramAction);
4920}
4921
4922std::vector<std::string> CompilerInvocationBase::getCC1CommandLine() const {
4923 std::vector<std::string> Args{"-cc1"};
4925 [&Args](const Twine &Arg) { Args.push_back(Arg.str()); });
4926 return Args;
4927}
4928
4933}
4934
4936 getLangOpts().ImplicitModules = false;
4941 // The specific values we canonicalize to for pruning don't affect behaviour,
4942 /// so use the default values so they may be dropped from the command-line.
4943 getHeaderSearchOpts().ModuleCachePruneInterval = 7 * 24 * 60 * 60;
4944 getHeaderSearchOpts().ModuleCachePruneAfter = 31 * 24 * 60 * 60;
4945}
4946
4949 DiagnosticsEngine &Diags) {
4950 return createVFSFromCompilerInvocation(CI, Diags,
4951 llvm::vfs::getRealFileSystem());
4952}
4953
4956 const CompilerInvocation &CI, DiagnosticsEngine &Diags,
4959 Diags, std::move(BaseFS));
4960}
4961
4963 ArrayRef<std::string> VFSOverlayFiles, DiagnosticsEngine &Diags,
4965 if (VFSOverlayFiles.empty())
4966 return BaseFS;
4967
4969 // earlier vfs files are on the bottom
4970 for (const auto &File : VFSOverlayFiles) {
4971 llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
4972 Result->getBufferForFile(File);
4973 if (!Buffer) {
4974 Diags.Report(diag::err_missing_vfs_overlay_file) << File;
4975 continue;
4976 }
4977
4978 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = llvm::vfs::getVFSFromYAML(
4979 std::move(Buffer.get()), /*DiagHandler*/ nullptr, File,
4980 /*DiagContext*/ nullptr, Result);
4981 if (!FS) {
4982 Diags.Report(diag::err_invalid_vfs_overlay) << File;
4983 continue;
4984 }
4985
4986 Result = FS;
4987 }
4988 return Result;
4989}
#define V(N, I)
Definition: ASTContext.h:3273
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:2972
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.
ASTDumpOutputFormat ASTDumpFormat
Specifies the output format of the AST.
std::optional< std::string > AuxTargetCPU
Auxiliary target CPU for CUDA/HIP compilation.
std::string OutputFile
The output file, if any.
unsigned ShowStats
Show frontend performance metrics and statistics.
std::string ActionName
The name of the action to run when using a plugin action.
std::vector< std::shared_ptr< ModuleFileExtension > > ModuleFileExtensions
The list of module file extensions.
ParsedSourceLocation CodeCompletionAt
If given, enable code completion at the provided location.
std::string FixItSuffix
If given, the new suffix for fix-it rewritten files.
static InputKind getInputKindForExtension(StringRef Extension)
getInputKindForExtension - Return the appropriate input kind for a file extension.
std::vector< std::string > Plugins
The list of plugins to load.
unsigned ASTDumpAll
Whether we deserialize all decls when forming AST dumps.
unsigned GenerateGlobalModuleIndex
Whether we can generate the global module index if needed.
unsigned DisableFree
Disable memory freeing on exit.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
frontend::ActionKind ProgramAction
The frontend action to perform.
std::optional< std::vector< std::string > > AuxTargetFeatures
Auxiliary target features for CUDA/HIP compilation.
std::string AuxTriple
Auxiliary triple for CUDA/HIP compilation.
unsigned UseGlobalModuleIndex
Whether we can use the global module index if available.
enum clang::FrontendOptions::@196 ARCMTAction
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:454
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:542
std::vector< std::string > NoBuiltinFuncs
A list of all -fno-builtin-* function names (e.g., memset).
Definition: LangOptions.h:521
std::string ModuleName
The module currently being compiled as specified by -fmodule-name.
Definition: LangOptions.h:502
clang::ObjCRuntime ObjCRuntime
Definition: LangOptions.h:489
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:460
bool UseTargetPathSeparator
Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...
Definition: LangOptions.h:560
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:532
std::string OverflowHandler
The name of the handler function to be called when -ftrapv is specified.
Definition: LangOptions.h:499
std::string RandstructSeed
The seed used by the randomize structure layout feature.
Definition: LangOptions.h:552
std::map< std::string, std::string, std::greater< std::string > > MacroPrefixMap
A prefix map for FILE, BASE_FILE and __builtin_FILE().
Definition: LangOptions.h:524
LangStandard::Kind LangStd
The used language standard.
Definition: LangOptions.h:457
std::string OpenACCMacroOverride
Definition: LangOptions.h:569
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:462
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:528
std::vector< std::string > NoSanitizeFiles
Paths to files specifying which objects (files, functions, variables) should not be instrumented.
Definition: LangOptions.h:466
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:509
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:515
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.
@ 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:54
const unsigned VERSION_MAJOR
AST file major version number supported by this version of Clang.
Definition: ASTBitCodes.h:44
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:5394
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
Definition: complex_cmath.h:40
#define bool
Definition: stdbool.h:20
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