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