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