clang: lib/Frontend/CompilerInvocation.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

29#include "clang/Config/config.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

90#include

91#include

92#include

93#include

94#include

95#include

96#include

97#include

98#include

99#include

100#include

101#include <type_traits>

102#include

103#include

104

105using namespace clang;

106using namespace driver;

107using namespace options;

109

110

111

112

113

114

115

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

126

127

128namespace {

129template std::shared_ptr make_shared_copy(const T &X) {

130 return std::make_shared(X);

131}

132

133template

135 return llvm::makeIntrusiveRefCnt(X);

136}

137}

138

153

156 if (this != &X) {

157 LangOpts = make_shared_copy(X.getLangOpts());

158 TargetOpts = make_shared_copy(X.getTargetOpts());

159 DiagnosticOpts = makeIntrusiveRefCntCopy(X.getDiagnosticOpts());

160 HSOpts = make_shared_copy(X.getHeaderSearchOpts());

161 PPOpts = make_shared_copy(X.getPreprocessorOpts());

162 AnalyzerOpts = makeIntrusiveRefCntCopy(X.getAnalyzerOpts());

163 MigratorOpts = make_shared_copy(X.getMigratorOpts());

164 APINotesOpts = make_shared_copy(X.getAPINotesOpts());

165 CodeGenOpts = make_shared_copy(X.getCodeGenOpts());

166 FSOpts = make_shared_copy(X.getFileSystemOpts());

167 FrontendOpts = make_shared_copy(X.getFrontendOpts());

170 }

171 return *this;

172}

173

176 if (this != &X) {

190 }

191 return *this;

192}

193

197}

198

202 return *this;

203}

204

205namespace {

206template

207T &ensureOwned(std::shared_ptr &Storage) {

208 if (Storage.use_count() > 1)

209 Storage = std::make_shared(*Storage);

210 return *Storage;

211}

212

213template

215 if (Storage.useCount() > 1)

216 Storage = llvm::makeIntrusiveRefCnt(*Storage);

217 return *Storage;

218}

219}

220

222 return ensureOwned(LangOpts);

223}

224

227}

228

231}

232

234 return ensureOwned(HSOpts);

235}

236

238 return ensureOwned(PPOpts);

239}

240

243}

244

247}

248

251}

252

255}

256

258 return ensureOwned(FSOpts);

259}

260

263}

264

267}

268

272}

273

274

275

276

277

279

280#define OPTTABLE_STR_TABLE_CODE

281#include "clang/Driver/Options.inc"

282#undef OPTTABLE_STR_TABLE_CODE

283

285 return &OptionStrTable[Offset];

286}

287

288#define SIMPLE_ENUM_VALUE_TABLE

289#include "clang/Driver/Options.inc"

290#undef SIMPLE_ENUM_VALUE_TABLE

291

293 unsigned TableIndex,

294 const ArgList &Args,

296 if (Args.hasArg(Opt))

297 return true;

298 return std::nullopt;

299}

300

302 unsigned,

303 const ArgList &Args,

305 if (Args.hasArg(Opt))

306 return false;

307 return std::nullopt;

308}

309

310

311

312

313

315 unsigned SpellingOffset, Option::OptionClass,

316 unsigned, ...) {

318}

320 const Twine &Spelling, Option::OptionClass,

321 unsigned, ...) {

322 Consumer(Spelling);

323}

324

326 return !std::is_same_v<T, uint64_t> && llvm::is_integral_or_enum::value;

327}

328

329template <typename T,

330 std::enable_if_t<!is_uint64_t_convertible(), bool> = false>

332 return [Value](OptSpecifier Opt, unsigned, const ArgList &Args,

334 if (Args.hasArg(Opt))

336 return std::nullopt;

337 };

338}

339

340template <typename T,

341 std::enable_if_t<is_uint64_t_convertible(), bool> = false>

344}

345

347 OptSpecifier OtherOpt) {

348 return [Value, OtherValue,

349 OtherOpt](OptSpecifier Opt, unsigned, const ArgList &Args,

351 if (const Arg *A = Args.getLastArg(Opt, OtherOpt)) {

352 return A->getOption().matches(Opt) ? Value : OtherValue;

353 }

354 return std::nullopt;

355 };

356}

357

360 Option::OptionClass, unsigned, bool KeyPath) {

361 if (KeyPath == Value)

363 };

364}

365

367 const Twine &Spelling,

368 Option::OptionClass OptClass, unsigned,

369 const Twine &Value) {

370 switch (OptClass) {

371 case Option::SeparateClass:

372 case Option::JoinedOrSeparateClass:

373 case Option::JoinedAndSeparateClass:

374 Consumer(Spelling);

376 break;

377 case Option::JoinedClass:

378 case Option::CommaJoinedClass:

379 Consumer(Spelling + Value);

380 break;

381 default:

382 llvm_unreachable("Cannot denormalize an option with option class "

383 "incompatible with string denormalization.");

384 }

385}

386

387template

388static void

390 Option::OptionClass OptClass, unsigned TableIndex, T Value) {

392 TableIndex, Twine(Value));

393}

394

395template

397 Option::OptionClass OptClass, unsigned TableIndex,

400}

401

402static std::optional

404 for (int I = 0, E = Table.Size; I != E; ++I)

405 if (Name == Table.Table[I].Name)

406 return Table.Table[I];

407

408 return std::nullopt;

409}

410

411static std::optional

413 for (int I = 0, E = Table.Size; I != E; ++I)

415 return Table.Table[I];

416

417 return std::nullopt;

418}

419

421 unsigned TableIndex,

422 const ArgList &Args,

424 assert(TableIndex < SimpleEnumValueTablesSize);

425 const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];

426

427 auto *Arg = Args.getLastArg(Opt);

428 if (!Arg)

429 return std::nullopt;

430

431 StringRef ArgValue = Arg->getValue();

433 return MaybeEnumVal->Value;

434

435 Diags.Report(diag::err_drv_invalid_value)

436 << Arg->getAsString(Args) << ArgValue;

437 return std::nullopt;

438}

439

441 unsigned SpellingOffset,

442 Option::OptionClass OptClass,

443 unsigned TableIndex, unsigned Value) {

444 assert(TableIndex < SimpleEnumValueTablesSize);

445 const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex];

448 TableIndex, MaybeEnumVal->Name);

449 } else {

450 llvm_unreachable("The simple enum value was not correctly defined in "

451 "the tablegen option description");

452 }

453}

454

455template

457 unsigned SpellingOffset,

458 Option::OptionClass OptClass,

459 unsigned TableIndex, T Value) {

461 TableIndex, static_cast<unsigned>(Value));

462}

463

465 int TableIndex,

466 const ArgList &Args,

468 auto *Arg = Args.getLastArg(Opt);

469 if (!Arg)

470 return std::nullopt;

471 return std::string(Arg->getValue());

472}

473

474template

476 const ArgList &Args,

478 auto *Arg = Args.getLastArg(Opt);

479 if (!Arg)

480 return std::nullopt;

481 IntTy Res;

482 if (StringRef(Arg->getValue()).getAsInteger(0, Res)) {

483 Diags.Report(diag::err_drv_invalid_int_value)

484 << Arg->getAsString(Args) << Arg->getValue();

485 return std::nullopt;

486 }

487 return Res;

488}

489

490static std::optional<std::vectorstd::string>

493 return Args.getAllArgValues(Opt);

494}

495

497 unsigned SpellingOffset,

498 Option::OptionClass OptClass,

499 unsigned TableIndex,

500 const std::vectorstd::string &Values) {

501 switch (OptClass) {

502 case Option::CommaJoinedClass: {

503 std::string CommaJoinedValue;

504 if (!Values.empty()) {

505 CommaJoinedValue.append(Values.front());

506 for (const std::string &Value : llvm::drop_begin(Values, 1)) {

507 CommaJoinedValue.append(",");

508 CommaJoinedValue.append(Value);

509 }

510 }

512 Option::OptionClass::JoinedClass, TableIndex,

513 CommaJoinedValue);

514 break;

515 }

516 case Option::JoinedClass:

517 case Option::SeparateClass:

518 case Option::JoinedOrSeparateClass:

519 for (const std::string &Value : Values)

521 break;

522 default:

523 llvm_unreachable("Cannot denormalize an option with option class "

524 "incompatible with string vector denormalization.");

525 }

526}

527

529 int TableIndex,

530 const ArgList &Args,

532 auto *Arg = Args.getLastArg(Opt);

533 if (!Arg)

534 return std::nullopt;

535 return llvm::Triple::normalize(Arg->getValue());

536}

537

538template <typename T, typename U>

540 return static_cast<T>(Value);

541}

542

544 return KeyPath | Value;

545}

546

548 return KeyPath;

549}

550

551template <typename T, typename U, U Value>

553 return ((KeyPath & Value) == Value) ? static_cast<T>(Value) : T();

554}

555

556#define PARSE_OPTION_WITH_MARSHALLING( \

557 ARGS, DIAGS, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, \

558 ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \

559 METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \

560 IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \

561 TABLE_INDEX) \

562 if ((VISIBILITY) & options::CC1Option) { \

563 KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \

564 if (IMPLIED_CHECK) \

565 KEYPATH = MERGER(KEYPATH, IMPLIED_VALUE); \

566 if (SHOULD_PARSE) \

567 if (auto MaybeValue = NORMALIZER(OPT_##ID, TABLE_INDEX, ARGS, DIAGS)) \

568 KEYPATH = \

569 MERGER(KEYPATH, static_cast<decltype(KEYPATH)>(*MaybeValue)); \

570 }

571

572

573

574#define GENERATE_OPTION_WITH_MARSHALLING( \

575 CONSUMER, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, ALIASARGS, \

576 FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \

577 SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \

578 IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \

579 if ((VISIBILITY) & options::CC1Option) { \

580 [&](const auto &Extracted) { \

581 if (ALWAYS_EMIT || \

582 (Extracted != \

583 static_cast<decltype(KEYPATH)>((IMPLIED_CHECK) ? (IMPLIED_VALUE) \

584 : (DEFAULT_VALUE)))) \

585 DENORMALIZER(CONSUMER, SPELLING_OFFSET, Option::KIND##Class, \

586 TABLE_INDEX, Extracted); \

587 }(EXTRACTOR(KEYPATH)); \

588 }

589

591

595 unsigned NumErrorsBefore = Diags.getNumErrors();

596

601 CodeGenOpts.XRayInstrumentFunctions = LangOpts.XRayInstrument;

602 CodeGenOpts.XRayAlwaysEmitCustomEvents = LangOpts.XRayAlwaysEmitCustomEvents;

603 CodeGenOpts.XRayAlwaysEmitTypedEvents = LangOpts.XRayAlwaysEmitTypedEvents;

604 CodeGenOpts.DisableFree = FrontendOpts.DisableFree;

607 CodeGenOpts.ClearASTBeforeBackend = false;

609 LangOpts.ForceEmitVTables = CodeGenOpts.ForceEmitVTables;

610 LangOpts.SpeculativeLoadHardening = CodeGenOpts.SpeculativeLoadHardening;

612

613 llvm::Triple T(TargetOpts.Triple);

614 llvm::Triple::ArchType Arch = T.getArch();

615

618

619 if (LangOpts.getExceptionHandling() !=

621 T.isWindowsMSVCEnvironment())

622 Diags.Report(diag::err_fe_invalid_exception_model)

623 << static_cast<unsigned>(LangOpts.getExceptionHandling()) << T.str();

624

625 if (LangOpts.AppleKext && !LangOpts.CPlusPlus)

626 Diags.Report(diag::warn_c_kext);

627

628 if (LangOpts.NewAlignOverride &&

629 !llvm::isPowerOf2_32(LangOpts.NewAlignOverride)) {

630 Arg *A = Args.getLastArg(OPT_fnew_alignment_EQ);

631 Diags.Report(diag::err_fe_invalid_alignment)

632 << A->getAsString(Args) << A->getValue();

633 LangOpts.NewAlignOverride = 0;

634 }

635

636

637

638 if (LangOpts.CPlusPlus11) {

639 if (Args.hasArg(OPT_fraw_string_literals, OPT_fno_raw_string_literals)) {

640 Args.claimAllArgs(OPT_fraw_string_literals, OPT_fno_raw_string_literals);

641 Diags.Report(diag::warn_drv_fraw_string_literals_in_cxx11)

642 << bool(LangOpts.RawStringLiterals);

643 }

644

645

646 LangOpts.RawStringLiterals = true;

647 }

648

649

650 if (LangOpts.SYCLIsDevice && LangOpts.SYCLIsHost)

651 Diags.Report(diag::err_drv_argument_not_allowed_with) << "-fsycl-is-device"

652 << "-fsycl-is-host";

653

654 if (Args.hasArg(OPT_fgnu89_inline) && LangOpts.CPlusPlus)

655 Diags.Report(diag::err_drv_argument_not_allowed_with)

657

658 if (Args.hasArg(OPT_hlsl_entrypoint) && !LangOpts.HLSL)

659 Diags.Report(diag::err_drv_argument_not_allowed_with)

661

662 if (Args.hasArg(OPT_fgpu_allow_device_init) && !LangOpts.HIP)

663 Diags.Report(diag::warn_ignored_hip_only_option)

664 << Args.getLastArg(OPT_fgpu_allow_device_init)->getAsString(Args);

665

666 if (Args.hasArg(OPT_gpu_max_threads_per_block_EQ) && !LangOpts.HIP)

667 Diags.Report(diag::warn_ignored_hip_only_option)

668 << Args.getLastArg(OPT_gpu_max_threads_per_block_EQ)->getAsString(Args);

669

670

671

672

673

674

675

676

677 if (Args.hasArg(OPT_ffp_eval_method_EQ)) {

678 if (LangOpts.ApproxFunc)

679 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 0;

680 if (LangOpts.AllowFPReassoc)

681 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 1;

682 if (LangOpts.AllowRecip)

683 Diags.Report(diag::err_incompatible_fp_eval_method_options) << 2;

684 }

685

686

687

688

689 if (Args.getLastArg(OPT_cl_strict_aliasing) &&

691 Diags.Report(diag::warn_option_invalid_ocl_version)

693 << Args.getLastArg(OPT_cl_strict_aliasing)->getAsString(Args);

694

695 if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) {

696 auto DefaultCC = LangOpts.getDefaultCallingConv();

697

700 Arch != llvm::Triple::x86;

703 T.isX86();

705 if (emitError)

706 Diags.Report(diag::err_drv_argument_not_allowed_with)

707 << A->getSpelling() << T.getTriple();

708 }

709

710 return Diags.getNumErrors() == NumErrorsBefore;

711}

712

713

714

715

716

719 unsigned DefaultOpt = 0;

722 !Args.hasArg(OPT_cl_opt_disable))

723 DefaultOpt = 2;

724

725 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {

726 if (A->getOption().matches(options::OPT_O0))

727 return 0;

728

729 if (A->getOption().matches(options::OPT_Ofast))

730 return 3;

731

732 assert(A->getOption().matches(options::OPT_O));

733

734 StringRef S(A->getValue());

735 if (S == "s" || S == "z")

736 return 2;

737

738 if (S == "g")

739 return 1;

740

742 }

743

744 return DefaultOpt;

745}

746

748 if (Arg *A = Args.getLastArg(options::OPT_O_Group)) {

749 if (A->getOption().matches(options::OPT_O)) {

750 switch (A->getValue()[0]) {

751 default:

752 return 0;

753 case 's':

754 return 1;

755 case 'z':

756 return 2;

757 }

758 }

759 }

760 return 0;

761}

762

764 llvm::opt::OptSpecifier OptSpecifier) {

767 Option::OptionClass::FlagClass, 0);

768}

769

771 llvm::opt::OptSpecifier OptSpecifier,

772 const Twine &Value) {

775}

776

777

781

782

786

787

788

789

790

791

792

793

794

795

796

797

798

799

800

801

802

803

804

810 bool CheckAgainstOriginalInvocation = false,

811 bool ForceRoundTrip = false) {

812#ifndef NDEBUG

813 bool DoRoundTripDefault = true;

814#else

815 bool DoRoundTripDefault = false;

816#endif

817

818 bool DoRoundTrip = DoRoundTripDefault;

819 if (ForceRoundTrip) {

820 DoRoundTrip = true;

821 } else {

822 for (const auto *Arg : CommandLineArgs) {

823 if (Arg == StringRef("-round-trip-args"))

824 DoRoundTrip = true;

825 if (Arg == StringRef("-no-round-trip-args"))

826 DoRoundTrip = false;

827 }

828 }

829

830

831

832 if (!DoRoundTrip)

833 return Parse(RealInvocation, CommandLineArgs, Diags, Argv0);

834

835

837 std::string Buffer;

838 llvm::raw_string_ostream OS(Buffer);

839 for (const char *Arg : Args) {

840 llvm::sys::printArg(OS, Arg, true);

841 OS << ' ';

842 }

843 return Buffer;

844 };

845

846

849

850

851

852 if (!Parse(DummyInvocation, CommandLineArgs, DummyDiags, Argv0) ||

854

855

856

857

859 auto Success = Parse(RealInvocation, CommandLineArgs, Diags, Argv0);

862

863

864

865 Diags.Report(diag::err_cc1_round_trip_fail_then_ok);

866 Diags.Report(diag::note_cc1_round_trip_original)

867 << SerializeArgs(CommandLineArgs);

868 return false;

869 }

870

871

872 llvm::BumpPtrAllocator Alloc;

873 llvm::StringSaver StringPool(Alloc);

874 auto SA = [&StringPool](const Twine &Arg) {

875 return StringPool.save(Arg).data();

876 };

877

878

879

880

882 Generate(DummyInvocation, GeneratedArgs, SA);

883

884

885

886

887

888 bool Success2 = Parse(RealInvocation, GeneratedArgs, Diags, Argv0);

889

890

891

892 if (!Success2) {

893 Diags.Report(diag::err_cc1_round_trip_ok_then_fail);

894 Diags.Report(diag::note_cc1_round_trip_generated)

895 << 1 << SerializeArgs(GeneratedArgs);

896 return false;

897 }

898

900 if (CheckAgainstOriginalInvocation)

901

902 ComparisonArgs.assign(CommandLineArgs.begin(), CommandLineArgs.end());

903 else

904

905

906 Generate(RealInvocation, ComparisonArgs, SA);

907

908

911 return std::equal(A.begin(), A.end(), B.begin(), B.end(),

912 [](const char *AElem, const char *BElem) {

913 return StringRef(AElem) == StringRef(BElem);

914 });

915 };

916

917

918

919

920 if (Equal(GeneratedArgs, ComparisonArgs)) {

921 Diags.Report(diag::err_cc1_round_trip_mismatch);

922 Diags.Report(diag::note_cc1_round_trip_generated)

923 << 1 << SerializeArgs(GeneratedArgs);

924 Diags.Report(diag::note_cc1_round_trip_generated)

925 << 2 << SerializeArgs(ComparisonArgs);

926 return false;

927 }

928

929 Diags.Report(diag::remark_cc1_round_trip_generated)

930 << 1 << SerializeArgs(GeneratedArgs);

931 Diags.Report(diag::remark_cc1_round_trip_generated)

932 << 2 << SerializeArgs(ComparisonArgs);

933

934 return Success2;

935}

936

939 const char *Argv0) {

944 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);

945 },

948 Args.push_back("-cc1");

950 },

951 DummyInvocation1, DummyInvocation2, Args, Diags, Argv0,

952 true, true);

953}

954

956 OptSpecifier GroupWithValue,

957 std::vectorstd::string &Diagnostics) {

958 for (auto *A : Args.filtered(Group)) {

959 if (A->getOption().getKind() == Option::FlagClass) {

960

961

962 Diagnostics.push_back(

963 std::string(A->getOption().getName().drop_front(1)));

964 } else if (A->getOption().matches(GroupWithValue)) {

965

966

967 Diagnostics.push_back(

968 std::string(A->getOption().getName().drop_front(1).rtrim("=-")));

969 } else {

970

971 Diagnostics.push_back(A->getValue());

972 }

973 }

974}

975

976

977

980

982 std::vectorstd::string &Funcs) {

983 std::vectorstd::string Values = Args.getAllArgValues(OPT_fno_builtin_);

985 Funcs.insert(Funcs.end(), Values.begin(), BuiltinEnd);

986}

987

991

992#define ANALYZER_OPTION_WITH_MARSHALLING(...) \

993 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

994#include "clang/Driver/Options.inc"

995#undef ANALYZER_OPTION_WITH_MARSHALLING

996

999#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \

1000 case NAME##Model: \

1001 GenerateArg(Consumer, OPT_analyzer_constraints, CMDFLAG); \

1002 break;

1003#include "clang/StaticAnalyzer/Core/Analyses.def"

1004 default:

1005 llvm_unreachable("Tried to generate unknown analysis constraint.");

1006 }

1007 }

1008

1011#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \

1012 case PD_##NAME: \

1013 GenerateArg(Consumer, OPT_analyzer_output, CMDFLAG); \

1014 break;

1015#include "clang/StaticAnalyzer/Core/Analyses.def"

1016 default:

1017 llvm_unreachable("Tried to generate unknown analysis diagnostic client.");

1018 }

1019 }

1020

1023#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \

1024 case NAME: \

1025 GenerateArg(Consumer, OPT_analyzer_purge, CMDFLAG); \

1026 break;

1027#include "clang/StaticAnalyzer/Core/Analyses.def"

1028 default:

1029 llvm_unreachable("Tried to generate unknown analysis purge mode.");

1030 }

1031 }

1032

1035#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \

1036 case NAME: \

1037 GenerateArg(Consumer, OPT_analyzer_inlining_mode, CMDFLAG); \

1038 break;

1039#include "clang/StaticAnalyzer/Core/Analyses.def"

1040 default:

1041 llvm_unreachable("Tried to generate unknown analysis inlining mode.");

1042 }

1043 }

1044

1046 OptSpecifier Opt =

1047 CP.second ? OPT_analyzer_checker : OPT_analyzer_disable_checker;

1049 }

1050

1053

1054

1056 for (const auto &C : Opts.Config)

1057 SortedConfigOpts.emplace_back(C.getKey(), C.getValue());

1058 llvm::sort(SortedConfigOpts, llvm::less_first());

1059

1060 for (const auto &[Key, Value] : SortedConfigOpts) {

1061

1062

1063 auto Entry = ConfigOpts.Config.find(Key);

1064 if (Entry != ConfigOpts.Config.end() && Entry->getValue() == Value)

1065 continue;

1066

1067 GenerateArg(Consumer, OPT_analyzer_config, Key + "=" + Value);

1068 }

1069

1070

1071}

1072

1075 unsigned NumErrorsBefore = Diags.getNumErrors();

1076

1078

1079#define ANALYZER_OPTION_WITH_MARSHALLING(...) \

1080 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

1081#include "clang/Driver/Options.inc"

1082#undef ANALYZER_OPTION_WITH_MARSHALLING

1083

1084 if (Arg *A = Args.getLastArg(OPT_analyzer_constraints)) {

1085 StringRef Name = A->getValue();

1087#define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) \

1088 .Case(CMDFLAG, NAME##Model)

1089#include "clang/StaticAnalyzer/Core/Analyses.def"

1092 Diags.Report(diag::err_drv_invalid_value)

1093 << A->getAsString(Args) << Name;

1094 } else {

1095#ifndef LLVM_WITH_Z3

1096 if (Value == AnalysisConstraints::Z3ConstraintsModel) {

1097 Diags.Report(diag::err_analyzer_not_built_with_z3);

1098 }

1099#endif

1101 }

1102 }

1103

1104 if (Arg *A = Args.getLastArg(OPT_analyzer_output)) {

1105 StringRef Name = A->getValue();

1107#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) \

1108 .Case(CMDFLAG, PD_##NAME)

1109#include "clang/StaticAnalyzer/Core/Analyses.def"

1112 Diags.Report(diag::err_drv_invalid_value)

1113 << A->getAsString(Args) << Name;

1114 } else {

1116 }

1117 }

1118

1119 if (Arg *A = Args.getLastArg(OPT_analyzer_purge)) {

1120 StringRef Name = A->getValue();

1122#define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) \

1123 .Case(CMDFLAG, NAME)

1124#include "clang/StaticAnalyzer/Core/Analyses.def"

1127 Diags.Report(diag::err_drv_invalid_value)

1128 << A->getAsString(Args) << Name;

1129 } else {

1131 }

1132 }

1133

1134 if (Arg *A = Args.getLastArg(OPT_analyzer_inlining_mode)) {

1135 StringRef Name = A->getValue();

1137#define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) \

1138 .Case(CMDFLAG, NAME)

1139#include "clang/StaticAnalyzer/Core/Analyses.def"

1142 Diags.Report(diag::err_drv_invalid_value)

1143 << A->getAsString(Args) << Name;

1144 } else {

1146 }

1147 }

1148

1150 for (const Arg *A :

1151 Args.filtered(OPT_analyzer_checker, OPT_analyzer_disable_checker)) {

1152 A->claim();

1153 bool IsEnabled = A->getOption().getID() == OPT_analyzer_checker;

1154

1155

1156 StringRef CheckerAndPackageList = A->getValue();

1158 CheckerAndPackageList.split(CheckersAndPackages, ",");

1159 for (const StringRef &CheckerOrPackage : CheckersAndPackages)

1161 IsEnabled);

1162 }

1163

1164

1165 for (const auto *A : Args.filtered(OPT_analyzer_config)) {

1166

1167

1168

1169 StringRef configList = A->getValue();

1171 configList.split(configVals, ",");

1172 for (const auto &configVal : configVals) {

1173 StringRef key, val;

1174 std::tie(key, val) = configVal.split("=");

1175 if (val.empty()) {

1177 diag::err_analyzer_config_no_value) << configVal;

1178 break;

1179 }

1180 if (val.contains('=')) {

1182 diag::err_analyzer_config_multiple_values)

1183 << configVal;

1184 break;

1185 }

1186

1187

1188

1191 Diags.Report(diag::err_analyzer_config_unknown) << key;

1192 continue;

1193 }

1194

1195 A->claim();

1196 Opts.Config[key] = std::string(val);

1197 }

1198 }

1199

1202 else

1204

1206 for (unsigned i = 0; i < Args.getNumInputArgStrings(); ++i) {

1207 if (i != 0)

1208 os << " ";

1209 os << Args.getArgString(i);

1210 }

1211

1212 return Diags.getNumErrors() == NumErrorsBefore;

1213}

1214

1216 StringRef OptionName, StringRef DefaultVal) {

1217 return Config.insert({OptionName, std::string(DefaultVal)}).first->second;

1218}

1219

1222 StringRef &OptionField, StringRef Name,

1223 StringRef DefaultVal) {

1224

1225

1226

1227 OptionField = getStringOption(Config, Name, DefaultVal);

1228}

1229

1232 bool &OptionField, StringRef Name, bool DefaultVal) {

1233 auto PossiblyInvalidVal =

1234 llvm::StringSwitch<std::optional>(

1235 getStringOption(Config, Name, (DefaultVal ? "true" : "false")))

1236 .Case("true", true)

1237 .Case("false", false)

1238 .Default(std::nullopt);

1239

1240 if (!PossiblyInvalidVal) {

1241 if (Diags)

1242 Diags->Report(diag::err_analyzer_config_invalid_input)

1243 << Name << "a boolean";

1244 else

1245 OptionField = DefaultVal;

1246 } else

1247 OptionField = *PossiblyInvalidVal;

1248}

1249

1252 unsigned &OptionField, StringRef Name,

1253 unsigned DefaultVal) {

1254

1255 OptionField = DefaultVal;

1256 bool HasFailed = getStringOption(Config, Name, std::to_string(DefaultVal))

1257 .getAsInteger(0, OptionField);

1258 if (Diags && HasFailed)

1259 Diags->Report(diag::err_analyzer_config_invalid_input)

1260 << Name << "an unsigned";

1261}

1262

1266 unsigned DefaultVal) {

1268 getStringOption(Config, Name, std::to_string(DefaultVal)));

1269 if (Parsed.has_value()) {

1270 OptionField = Parsed.value();

1271 return;

1272 }

1273 if (Diags && !Parsed.has_value())

1274 Diags->Report(diag::err_analyzer_config_invalid_input)

1275 << Name << "a positive";

1276

1277 OptionField = DefaultVal;

1278}

1279

1282

1283

1284

1285#define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL) \

1286 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, DEFAULT_VAL);

1287#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(...)

1288#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"

1289

1290 assert(AnOpts.UserMode == "shallow" || AnOpts.UserMode == "deep");

1291 const bool InShallowMode = AnOpts.UserMode == "shallow";

1292

1293#define ANALYZER_OPTION(...)

1294#define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC, \

1295 SHALLOW_VAL, DEEP_VAL) \

1296 initOption(AnOpts.Config, Diags, AnOpts.NAME, CMDFLAG, \

1297 InShallowMode ? SHALLOW_VAL : DEEP_VAL);

1298#include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"

1299

1300

1301

1302

1303

1304

1305 if (!AnOpts.RawSilencedCheckersAndPackages.empty()) {

1306 std::vector Checkers =

1308 std::vector Packages =

1310

1312 AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages, ";");

1313

1314 for (const StringRef &CheckerOrPackage : CheckersAndPackages) {

1315 if (Diags) {

1316 bool IsChecker = CheckerOrPackage.contains('.');

1317 bool IsValidName = IsChecker

1318 ? llvm::is_contained(Checkers, CheckerOrPackage)

1319 : llvm::is_contained(Packages, CheckerOrPackage);

1320

1321 if (!IsValidName)

1322 Diags->Report(diag::err_unknown_analyzer_checker_or_package)

1323 << CheckerOrPackage;

1324 }

1325

1327 }

1328 }

1329

1330 if (!Diags)

1331 return;

1332

1333 if (AnOpts.ShouldTrackConditionsDebug && !AnOpts.ShouldTrackConditions)

1334 Diags->Report(diag::err_analyzer_config_invalid_input)

1335 << "track-conditions-debug" << "'track-conditions' to also be enabled";

1336

1337 if (!AnOpts.CTUDir.empty() && !llvm::sys::fs::is_directory(AnOpts.CTUDir))

1338 Diags->Report(diag::err_analyzer_config_invalid_input) << "ctu-dir"

1339 << "a filename";

1340

1341 if (!AnOpts.ModelPath.empty() &&

1342 !llvm::sys::fs::is_directory(AnOpts.ModelPath))

1343 Diags->Report(diag::err_analyzer_config_invalid_input) << "model-path"

1344 << "a filename";

1345}

1346

1347

1348static void

1350 StringRef Name,

1352 if (Remark.hasValidPattern()) {

1355 GenerateArg(Consumer, OPT_R_Joined, Name);

1357 GenerateArg(Consumer, OPT_R_Joined, StringRef("no-") + Name);

1358 }

1359}

1360

1361

1362

1363

1366 OptSpecifier OptEQ, StringRef Name) {

1368

1369 auto InitializeResultPattern = [&Diags, &Args, &Result](const Arg *A,

1370 StringRef Pattern) {

1371 Result.Pattern = Pattern.str();

1372

1373 std::string RegexError;

1374 Result.Regex = std::make_sharedllvm::Regex(Result.Pattern);

1375 if (Result.Regex->isValid(RegexError)) {

1376 Diags.Report(diag::err_drv_optimization_remark_pattern)

1377 << RegexError << A->getAsString(Args);

1378 return false;

1379 }

1380

1381 return true;

1382 };

1383

1384 for (Arg *A : Args) {

1385 if (A->getOption().matches(OPT_R_Joined)) {

1386 StringRef Value = A->getValue();

1387

1388 if (Value == Name)

1390 else if (Value == "everything")

1392 else if (Value.split('-') == std::make_pair(StringRef("no"), Name))

1394 else if (Value == "no-everything")

1396 else

1397 continue;

1398

1401 Result.Pattern = "";

1402 Result.Regex = nullptr;

1403 } else {

1404 InitializeResultPattern(A, ".*");

1405 }

1406 } else if (A->getOption().matches(OptEQ)) {

1408 if (!InitializeResultPattern(A, A->getValue()))

1410 }

1411 }

1412

1414}

1415

1417 const std::vectorstd::string &Levels,

1421 for (const auto &Level : Levels) {

1423 llvm::StringSwitch(Level)

1431 Diags.Report(diag::err_drv_invalid_value) << FlagName << Level;

1432 }

1433 M = M | PM;

1434 }

1436}

1437

1439 const std::vectorstd::string &Sanitizers,

1441 for (const auto &Sanitizer : Sanitizers) {

1444 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;

1445 else

1446 S.set(K, true);

1447 }

1448}

1449

1453 return Values;

1454}

1455

1458 const std::vectorstd::string &Sanitizers,

1461 for (const auto &Sanitizer : Sanitizers) {

1463 Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer;

1464 }

1465 return Cutoffs;

1466}

1467

1472 llvm::SplitString(Bundle, BundleParts, ",");

1473 for (const auto &B : BundleParts) {

1476 if (B != "none")

1477 D.Report(diag::err_drv_invalid_value) << FlagName << Bundle;

1478 else

1479 S.Mask = Mask;

1481 S.Mask = Mask;

1482 else

1483 S.set(Mask, true);

1484 }

1485}

1486

1490 std::string Buffer;

1491 llvm::raw_string_ostream OS(Buffer);

1492 llvm::interleave(BundleParts, OS, [&OS](StringRef Part) { OS << Part; }, ",");

1493 return Buffer;

1494}

1495

1496

1498 const Twine &ProfileName,

1499 llvm::vfs::FileSystem &FS,

1501 auto ReaderOrErr = llvm::IndexedInstrProfReader::create(ProfileName, FS);

1502 if (auto E = ReaderOrErr.takeError()) {

1504 "Error in reading profile %0: %1");

1505 llvm::handleAllErrors(std::move(E), [&](const llvm::ErrorInfoBase &EI) {

1506 Diags.Report(DiagID) << ProfileName.str() << EI.message();

1507 });

1508 return;

1509 }

1510 std::unique_ptrllvm::IndexedInstrProfReader PGOReader =

1511 std::move(ReaderOrErr.get());

1512

1513

1514

1515 if (PGOReader->isIRLevelProfile() || PGOReader->hasMemoryProfile()) {

1516 if (PGOReader->hasCSIRLevelProfile())

1518 else

1520 } else

1522}

1523

1526 const llvm::Triple &Triple) {

1527 assert(Triple.getArch() == llvm::Triple::aarch64);

1528 if (LangOpts.PointerAuthCalls) {

1531

1533 Key::ASIA, false,

1534 LangOpts.PointerAuthFunctionTypeDiscrimination ? Discrimination::Type

1535 : Discrimination::None);

1536

1538 Key::ASDA, LangOpts.PointerAuthVTPtrAddressDiscrimination,

1539 LangOpts.PointerAuthVTPtrTypeDiscrimination ? Discrimination::Type

1540 : Discrimination::None);

1541

1542 if (LangOpts.PointerAuthTypeInfoVTPtrDiscrimination)

1546 else

1549

1556

1557 if (LangOpts.PointerAuthInitFini) {

1559 Key::ASIA, LangOpts.PointerAuthInitFiniAddressDiscrimination,

1561 }

1562 }

1567}

1568

1571 const llvm::Triple &Triple,

1573 if (!LangOpts.PointerAuthCalls && !LangOpts.PointerAuthReturns &&

1574 !LangOpts.PointerAuthAuthTraps && !LangOpts.PointerAuthIndirectGotos &&

1575 !LangOpts.AArch64JumpTableHardening)

1576 return;

1577

1579}

1580

1581void CompilerInvocationBase::GenerateCodeGenArgs(const CodeGenOptions &Opts,

1583 const llvm::Triple &T,

1584 const std::string &OutputFile,

1587

1588 if (Opts.OptimizationLevel == 0)

1590 else

1591 GenerateArg(Consumer, OPT_O, Twine(Opts.OptimizationLevel));

1592

1593#define CODEGEN_OPTION_WITH_MARSHALLING(...) \

1594 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

1595#include "clang/Driver/Options.inc"

1596#undef CODEGEN_OPTION_WITH_MARSHALLING

1597

1598 if (Opts.OptimizationLevel > 0) {

1600 GenerateArg(Consumer, OPT_finline_functions);

1602 GenerateArg(Consumer, OPT_finline_hint_functions);

1605 }

1606

1607 if (Opts.DirectAccessExternalData && LangOpts->PICLevel != 0)

1608 GenerateArg(Consumer, OPT_fdirect_access_external_data);

1609 else if (!Opts.DirectAccessExternalData && LangOpts->PICLevel == 0)

1610 GenerateArg(Consumer, OPT_fno_direct_access_external_data);

1611

1612 std::optional DebugInfoVal;

1613 switch (Opts.DebugInfo) {

1614 case llvm::codegenoptions::DebugLineTablesOnly:

1615 DebugInfoVal = "line-tables-only";

1616 break;

1617 case llvm::codegenoptions::DebugDirectivesOnly:

1618 DebugInfoVal = "line-directives-only";

1619 break;

1620 case llvm::codegenoptions::DebugInfoConstructor:

1621 DebugInfoVal = "constructor";

1622 break;

1623 case llvm::codegenoptions::LimitedDebugInfo:

1624 DebugInfoVal = "limited";

1625 break;

1626 case llvm::codegenoptions::FullDebugInfo:

1627 DebugInfoVal = "standalone";

1628 break;

1629 case llvm::codegenoptions::UnusedTypeInfo:

1630 DebugInfoVal = "unused-types";

1631 break;

1632 case llvm::codegenoptions::NoDebugInfo:

1633 DebugInfoVal = std::nullopt;

1634 break;

1635 case llvm::codegenoptions::LocTrackingOnly:

1636 DebugInfoVal = std::nullopt;

1637 break;

1638 }

1639 if (DebugInfoVal)

1640 GenerateArg(Consumer, OPT_debug_info_kind_EQ, *DebugInfoVal);

1641

1643 GenerateArg(Consumer, OPT_fdebug_prefix_map_EQ,

1644 Prefix.first + "=" + Prefix.second);

1645

1647 GenerateArg(Consumer, OPT_fcoverage_prefix_map_EQ,

1648 Prefix.first + "=" + Prefix.second);

1649

1650 if (Opts.NewStructPathTBAA)

1651 GenerateArg(Consumer, OPT_new_struct_path_tbaa);

1652

1653 if (Opts.OptimizeSize == 1)

1655 else if (Opts.OptimizeSize == 2)

1657

1658

1659

1660

1661

1662

1663 if (Opts.UnrollLoops && Opts.OptimizationLevel <= 1)

1664 GenerateArg(Consumer, OPT_funroll_loops);

1665 else if (!Opts.UnrollLoops && Opts.OptimizationLevel > 1)

1666 GenerateArg(Consumer, OPT_fno_unroll_loops);

1667

1670

1671 if (Opts.DebugNameTable ==

1672 static_cast<unsigned>(llvm::DICompileUnit::DebugNameTableKind::GNU))

1673 GenerateArg(Consumer, OPT_ggnu_pubnames);

1674 else if (Opts.DebugNameTable ==

1675 static_cast<unsigned>(

1676 llvm::DICompileUnit::DebugNameTableKind::Default))

1678

1679 if (Opts.DebugTemplateAlias)

1680 GenerateArg(Consumer, OPT_gtemplate_alias);

1681

1682 auto TNK = Opts.getDebugSimpleTemplateNames();

1683 if (TNK != llvm::codegenoptions::DebugTemplateNamesKind::Full) {

1684 if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Simple)

1685 GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "simple");

1686 else if (TNK == llvm::codegenoptions::DebugTemplateNamesKind::Mangled)

1687 GenerateArg(Consumer, OPT_gsimple_template_names_EQ, "mangled");

1688 }

1689

1690

1691

1692 if (Opts.TimePasses) {

1693 if (Opts.TimePassesPerRun)

1694 GenerateArg(Consumer, OPT_ftime_report_EQ, "per-pass-run");

1695 else

1696 GenerateArg(Consumer, OPT_ftime_report);

1697 }

1698

1699 if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO)

1700 GenerateArg(Consumer, OPT_flto_EQ, "full");

1701

1702 if (Opts.PrepareForThinLTO)

1703 GenerateArg(Consumer, OPT_flto_EQ, "thin");

1704

1707

1709 GenerateArg(Consumer, OPT_save_temps_EQ, "obj");

1710

1711 StringRef MemProfileBasename("memprof.profraw");

1714 GenerateArg(Consumer, OPT_fmemory_profile);

1715 } else {

1716 size_t ArgLength =

1718 GenerateArg(Consumer, OPT_fmemory_profile_EQ,

1720 }

1721 }

1722

1724 GenerateArg(Consumer, OPT_coverage_version_EQ,

1726

1727

1728

1729

1730

1732 std::string InstrBundle =

1734 if (!InstrBundle.empty())

1735 GenerateArg(Consumer, OPT_fxray_instrumentation_bundle, InstrBundle);

1736 }

1737

1738 if (Opts.CFProtectionReturn && Opts.CFProtectionBranch)

1739 GenerateArg(Consumer, OPT_fcf_protection_EQ, "full");

1740 else if (Opts.CFProtectionReturn)

1741 GenerateArg(Consumer, OPT_fcf_protection_EQ, "return");

1742 else if (Opts.CFProtectionBranch)

1743 GenerateArg(Consumer, OPT_fcf_protection_EQ, "branch");

1744

1745 if (Opts.CFProtectionBranch) {

1746 switch (Opts.getCFBranchLabelScheme()) {

1748 break;

1749#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \

1750 case CFBranchLabelSchemeKind::Kind: \

1751 GenerateArg(Consumer, OPT_mcf_branch_label_scheme_EQ, #FlagVal); \

1752 break;

1753#include "clang/Basic/CFProtectionOptions.def"

1754 }

1755 }

1756

1757 if (Opts.FunctionReturnThunks)

1758 GenerateArg(Consumer, OPT_mfunction_return_EQ, "thunk-extern");

1759

1761 bool Builtint = F.LinkFlags == llvm::Linker::Flags::LinkOnlyNeeded &&

1762 F.PropagateAttrs && F.Internalize;

1764 Builtint ? OPT_mlink_builtin_bitcode : OPT_mlink_bitcode_file,

1765 F.Filename);

1766 }

1767

1768 if (Opts.EmulatedTLS)

1769 GenerateArg(Consumer, OPT_femulated_tls);

1770

1771 if (Opts.FPDenormalMode != llvm::DenormalMode::getIEEE())

1773

1776 GenerateArg(Consumer, OPT_fdenormal_fp_math_f32_EQ,

1778

1780 OptSpecifier Opt =

1781 T.isPPC32() ? OPT_maix_struct_return : OPT_fpcc_struct_return;

1784 OptSpecifier Opt =

1785 T.isPPC32() ? OPT_msvr4_struct_return : OPT_freg_struct_return;

1787 }

1788

1789 if (Opts.EnableAIXExtendedAltivecABI)

1790 GenerateArg(Consumer, OPT_mabi_EQ_vec_extabi);

1791

1792 if (Opts.XCOFFReadOnlyPointers)

1793 GenerateArg(Consumer, OPT_mxcoff_roptr);

1794

1797

1800

1803

1806

1809

1810 GenerateArg(Consumer, OPT_fdiagnostics_hotness_threshold_EQ,

1813 : "auto");

1814

1815 GenerateArg(Consumer, OPT_fdiagnostics_misexpect_tolerance_EQ,

1817

1819 GenerateArg(Consumer, OPT_fsanitize_recover_EQ, Sanitizer);

1820

1822 GenerateArg(Consumer, OPT_fsanitize_trap_EQ, Sanitizer);

1823

1824 for (StringRef Sanitizer :

1826 GenerateArg(Consumer, OPT_fsanitize_merge_handlers_EQ, Sanitizer);

1827

1830 for (std::string Sanitizer : Values)

1831 GenerateArg(Consumer, OPT_fsanitize_skip_hot_cutoff_EQ, Sanitizer);

1832

1833 if (!Opts.EmitVersionIdentMetadata)

1835

1836 switch (Opts.FiniteLoops) {

1838 break;

1840 GenerateArg(Consumer, OPT_ffinite_loops);

1841 break;

1843 GenerateArg(Consumer, OPT_fno_finite_loops);

1844 break;

1845 }

1846}

1847

1848bool CompilerInvocation::ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args,

1851 const llvm::Triple &T,

1852 const std::string &OutputFile,

1854 unsigned NumErrorsBefore = Diags.getNumErrors();

1855

1857

1858 unsigned MaxOptLevel = 3;

1859 if (OptimizationLevel > MaxOptLevel) {

1860

1861

1862 Diags.Report(diag::warn_drv_optimization_value)

1863 << Args.getLastArg(OPT_O)->getAsString(Args) << "-O" << MaxOptLevel;

1864 OptimizationLevel = MaxOptLevel;

1865 }

1866 Opts.OptimizationLevel = OptimizationLevel;

1867

1868

1869

1871

1872

1874

1875#define CODEGEN_OPTION_WITH_MARSHALLING(...) \

1876 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

1877#include "clang/Driver/Options.inc"

1878#undef CODEGEN_OPTION_WITH_MARSHALLING

1879

1880

1881

1882 if (Opts.OptimizationLevel == 0) {

1884 } else if (const Arg *A = Args.getLastArg(options::OPT_finline_functions,

1885 options::OPT_finline_hint_functions,

1886 options::OPT_fno_inline_functions,

1887 options::OPT_fno_inline)) {

1888

1889

1890 if (A->getOption().matches(options::OPT_finline_functions))

1892 else if (A->getOption().matches(options::OPT_finline_hint_functions))

1894 else

1896 } else {

1898 }

1899

1900

1901

1902 Opts.DirectAccessExternalData =

1903 Args.hasArg(OPT_fdirect_access_external_data) ||

1904 (!Args.hasArg(OPT_fno_direct_access_external_data) &&

1906

1907 if (Arg *A = Args.getLastArg(OPT_debug_info_kind_EQ)) {

1908 unsigned Val =

1909 llvm::StringSwitch(A->getValue())

1910 .Case("line-tables-only", llvm::codegenoptions::DebugLineTablesOnly)

1911 .Case("line-directives-only",

1912 llvm::codegenoptions::DebugDirectivesOnly)

1913 .Case("constructor", llvm::codegenoptions::DebugInfoConstructor)

1914 .Case("limited", llvm::codegenoptions::LimitedDebugInfo)

1915 .Case("standalone", llvm::codegenoptions::FullDebugInfo)

1916 .Case("unused-types", llvm::codegenoptions::UnusedTypeInfo)

1917 .Default(~0U);

1918 if (Val == ~0U)

1919 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)

1920 << A->getValue();

1921 else

1922 Opts.setDebugInfo(static_castllvm::codegenoptions::DebugInfoKind\(Val));

1923 }

1924

1925

1926

1927 if (const Arg *A =

1928 Args.getLastArg(OPT_fuse_ctor_homing, OPT_fno_use_ctor_homing)) {

1929 if (A->getOption().matches(OPT_fuse_ctor_homing) &&

1930 Opts.getDebugInfo() == llvm::codegenoptions::LimitedDebugInfo)

1931 Opts.setDebugInfo(llvm::codegenoptions::DebugInfoConstructor);

1932 if (A->getOption().matches(OPT_fno_use_ctor_homing) &&

1933 Opts.getDebugInfo() == llvm::codegenoptions::DebugInfoConstructor)

1934 Opts.setDebugInfo(llvm::codegenoptions::LimitedDebugInfo);

1935 }

1936

1937 for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) {

1938 auto Split = StringRef(Arg).split('=');

1940 }

1941

1942 for (const auto &Arg : Args.getAllArgValues(OPT_fcoverage_prefix_map_EQ)) {

1943 auto Split = StringRef(Arg).split('=');

1945 }

1946

1947 const llvm::Triple::ArchType DebugEntryValueArchs[] = {

1948 llvm::Triple::x86, llvm::Triple::x86_64, llvm::Triple::aarch64,

1949 llvm::Triple::arm, llvm::Triple::armeb, llvm::Triple::mips,

1950 llvm::Triple::mipsel, llvm::Triple::mips64, llvm::Triple::mips64el};

1951

1953 llvm::is_contained(DebugEntryValueArchs, T.getArch()))

1954 Opts.EmitCallSiteInfo = true;

1955

1957 Diags.Report(diag::warn_ignoring_verify_debuginfo_preserve_export)

1960 }

1961

1962 Opts.NewStructPathTBAA = !Args.hasArg(OPT_no_struct_path_tbaa) &&

1963 Args.hasArg(OPT_new_struct_path_tbaa);

1965 Opts.SimplifyLibCalls = LangOpts->NoBuiltin;

1966 if (Opts.SimplifyLibCalls)

1968 Opts.UnrollLoops =

1969 Args.hasFlag(OPT_funroll_loops, OPT_fno_unroll_loops,

1970 (Opts.OptimizationLevel > 1));

1972 std::string(Args.getLastArgValue(OPT_fbinutils_version_EQ));

1973

1974 Opts.DebugTemplateAlias = Args.hasArg(OPT_gtemplate_alias);

1975

1976 Opts.DebugNameTable = static_cast<unsigned>(

1977 Args.hasArg(OPT_ggnu_pubnames)

1978 ? llvm::DICompileUnit::DebugNameTableKind::GNU

1979 : Args.hasArg(OPT_gpubnames)

1980 ? llvm::DICompileUnit::DebugNameTableKind::Default

1981 : llvm::DICompileUnit::DebugNameTableKind::None);

1982 if (const Arg *A = Args.getLastArg(OPT_gsimple_template_names_EQ)) {

1983 StringRef Value = A->getValue();

1984 if (Value != "simple" && Value != "mangled")

1985 Diags.Report(diag::err_drv_unsupported_option_argument)

1986 << A->getSpelling() << A->getValue();

1987 Opts.setDebugSimpleTemplateNames(

1988 StringRef(A->getValue()) == "simple"

1989 ? llvm::codegenoptions::DebugTemplateNamesKind::Simple

1990 : llvm::codegenoptions::DebugTemplateNamesKind::Mangled);

1991 }

1992

1993 if (const Arg *A = Args.getLastArg(OPT_ftime_report, OPT_ftime_report_EQ)) {

1994 Opts.TimePasses = true;

1995

1996

1997 if (A->getOption().getID() == OPT_ftime_report_EQ) {

1998 StringRef Val = A->getValue();

1999 if (Val == "per-pass")

2000 Opts.TimePassesPerRun = false;

2001 else if (Val == "per-pass-run")

2002 Opts.TimePassesPerRun = true;

2003 else

2004 Diags.Report(diag::err_drv_invalid_value)

2005 << A->getAsString(Args) << A->getValue();

2006 }

2007 }

2008

2009 Opts.PrepareForLTO = false;

2010 Opts.PrepareForThinLTO = false;

2011 if (Arg *A = Args.getLastArg(OPT_flto_EQ)) {

2012 Opts.PrepareForLTO = true;

2013 StringRef S = A->getValue();

2014 if (S == "thin")

2015 Opts.PrepareForThinLTO = true;

2016 else if (S != "full")

2017 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << S;

2018 if (Args.hasArg(OPT_funified_lto))

2019 Opts.PrepareForThinLTO = true;

2020 }

2021 if (Arg *A = Args.getLastArg(OPT_fthinlto_index_EQ)) {

2023 Diags.Report(diag::err_drv_argument_only_allowed_with)

2024 << A->getAsString(Args) << "-x ir";

2026 std::string(Args.getLastArgValue(OPT_fthinlto_index_EQ));

2027 }

2028 if (Arg *A = Args.getLastArg(OPT_save_temps_EQ))

2030 llvm::StringSwitchstd::string(A->getValue())

2031 .Case("obj", OutputFile)

2032 .Default(llvm::sys::path::filename(OutputFile).str());

2033

2034

2035 const char *MemProfileBasename = "memprof.profraw";

2036 if (Args.hasArg(OPT_fmemory_profile_EQ)) {

2038 std::string(Args.getLastArgValue(OPT_fmemory_profile_EQ)));

2039 llvm::sys::path::append(Path, MemProfileBasename);

2041 } else if (Args.hasArg(OPT_fmemory_profile))

2043

2045 if (Args.hasArg(OPT_coverage_version_EQ)) {

2046 StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);

2047 if (CoverageVersion.size() != 4) {

2048 Diags.Report(diag::err_drv_invalid_value)

2049 << Args.getLastArg(OPT_coverage_version_EQ)->getAsString(Args)

2050 << CoverageVersion;

2051 } else {

2053 }

2054 }

2055 }

2056

2057

2058

2059 for (const auto &A : Args) {

2060

2061 if (A->getOption().getID() == options::OPT_o ||

2062 A->getOption().getID() == options::OPT_INPUT ||

2063 A->getOption().getID() == options::OPT_x ||

2064 A->getOption().getID() == options::OPT_fembed_bitcode ||

2065 A->getOption().matches(options::OPT_W_Group))

2066 continue;

2067 ArgStringList ASL;

2068 A->render(Args, ASL);

2069 for (const auto &arg : ASL) {

2070 StringRef ArgStr(arg);

2071 Opts.CmdArgs.insert(Opts.CmdArgs.end(), ArgStr.begin(), ArgStr.end());

2072

2073 Opts.CmdArgs.push_back('\0');

2074 }

2075 }

2076

2077 auto XRayInstrBundles =

2078 Args.getAllArgValues(OPT_fxray_instrumentation_bundle);

2079 if (XRayInstrBundles.empty())

2081 else

2082 for (const auto &A : XRayInstrBundles)

2085

2086 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {

2087 StringRef Name = A->getValue();

2088 if (Name == "full") {

2089 Opts.CFProtectionReturn = 1;

2090 Opts.CFProtectionBranch = 1;

2091 } else if (Name == "return")

2092 Opts.CFProtectionReturn = 1;

2093 else if (Name == "branch")

2094 Opts.CFProtectionBranch = 1;

2095 else if (Name != "none")

2096 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;

2097 }

2098

2099 if (Opts.CFProtectionBranch && T.isRISCV()) {

2100 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {

2101 const auto Scheme =

2102 llvm::StringSwitch(A->getValue())

2103#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \

2104 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)

2105#include "clang/Basic/CFProtectionOptions.def"

2108 Opts.setCFBranchLabelScheme(Scheme);

2109 else

2110 Diags.Report(diag::err_drv_invalid_value)

2111 << A->getAsString(Args) << A->getValue();

2112 }

2113 }

2114

2115 if (const Arg *A = Args.getLastArg(OPT_mfunction_return_EQ)) {

2116 auto Val = llvm::StringSwitchllvm::FunctionReturnThunksKind(A->getValue())

2117 .Case("keep", llvm::FunctionReturnThunksKind::Keep)

2118 .Case("thunk-extern", llvm::FunctionReturnThunksKind::Extern)

2119 .Default(llvm::FunctionReturnThunksKind::Invalid);

2120

2121 if (T.isX86())

2122 Diags.Report(diag::err_drv_argument_not_allowed_with)

2123 << A->getSpelling() << T.getTriple();

2124 else if (Val == llvm::FunctionReturnThunksKind::Invalid)

2125 Diags.Report(diag::err_drv_invalid_value)

2126 << A->getAsString(Args) << A->getValue();

2127 else if (Val == llvm::FunctionReturnThunksKind::Extern &&

2128 Args.getLastArgValue(OPT_mcmodel_EQ) == "large")

2129 Diags.Report(diag::err_drv_argument_not_allowed_with)

2130 << A->getAsString(Args)

2131 << Args.getLastArg(OPT_mcmodel_EQ)->getAsString(Args);

2132 else

2133 Opts.FunctionReturnThunks = static_cast<unsigned>(Val);

2134 }

2135

2136 for (auto *A :

2137 Args.filtered(OPT_mlink_bitcode_file, OPT_mlink_builtin_bitcode)) {

2140 if (A->getOption().matches(OPT_mlink_builtin_bitcode)) {

2141 F.LinkFlags = llvm::Linker::Flags::LinkOnlyNeeded;

2142

2143

2146 }

2148 }

2149

2150 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {

2151 StringRef Val = A->getValue();

2152 Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);

2155 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;

2156 }

2157

2158 if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_f32_EQ)) {

2159 StringRef Val = A->getValue();

2160 Opts.FP32DenormalMode = llvm::parseDenormalFPAttribute(Val);

2162 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;

2163 }

2164

2165

2166

2167 if (Arg *A =

2168 Args.getLastArg(OPT_fpcc_struct_return, OPT_freg_struct_return,

2169 OPT_maix_struct_return, OPT_msvr4_struct_return)) {

2170

2171

2172 if (T.isOSAIX())

2173 Diags.Report(diag::err_drv_unsupported_opt_for_target)

2174 << A->getSpelling() << T.str();

2175

2176 const Option &O = A->getOption();

2177 if (O.matches(OPT_fpcc_struct_return) ||

2178 O.matches(OPT_maix_struct_return)) {

2180 } else {

2181 assert(O.matches(OPT_freg_struct_return) ||

2182 O.matches(OPT_msvr4_struct_return));

2184 }

2185 }

2186

2187 if (Arg *A = Args.getLastArg(OPT_mxcoff_roptr)) {

2188 if (T.isOSAIX())

2189 Diags.Report(diag::err_drv_unsupported_opt_for_target)

2190 << A->getSpelling() << T.str();

2191

2192

2193

2194

2195

2196

2197

2198

2199

2200 if (!Args.hasFlag(OPT_fdata_sections, OPT_fno_data_sections, false))

2201 Diags.Report(diag::err_roptr_requires_data_sections);

2202

2203 Opts.XCOFFReadOnlyPointers = true;

2204 }

2205

2206 if (Arg *A = Args.getLastArg(OPT_mabi_EQ_quadword_atomics)) {

2207 if (T.isOSAIX() || T.isPPC32())

2208 Diags.Report(diag::err_drv_unsupported_opt_for_target)

2209 << A->getSpelling() << T.str();

2210 }

2211

2212 bool NeedLocTracking = false;

2213

2215 NeedLocTracking = true;

2216

2217 if (Arg *A = Args.getLastArg(OPT_opt_record_passes)) {

2219 NeedLocTracking = true;

2220 }

2221

2222 if (Arg *A = Args.getLastArg(OPT_opt_record_format)) {

2224 NeedLocTracking = true;

2225 }

2226

2229

2232

2234 Diags, Args, OPT_Rpass_analysis_EQ, "pass-analysis");

2235

2239

2241 bool UsingProfile =

2243

2244 if (Opts.DiagnosticsWithHotness && !UsingProfile &&

2245

2247 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)

2248 << "-fdiagnostics-show-hotness";

2249

2250

2251 if (auto *arg =

2252 Args.getLastArg(options::OPT_fdiagnostics_hotness_threshold_EQ)) {

2253 auto ResultOrErr =

2254 llvm::remarks::parseHotnessThresholdOption(arg->getValue());

2255

2256 if (!ResultOrErr) {

2257 Diags.Report(diag::err_drv_invalid_diagnotics_hotness_threshold)

2258 << "-fdiagnostics-hotness-threshold=";

2259 } else {

2263 !UsingProfile)

2264 Diags.Report(diag::warn_drv_diagnostics_hotness_requires_pgo)

2265 << "-fdiagnostics-hotness-threshold=";

2266 }

2267 }

2268

2269 if (auto *arg =

2270 Args.getLastArg(options::OPT_fdiagnostics_misexpect_tolerance_EQ)) {

2272

2273 if (!ResultOrErr) {

2274 Diags.Report(diag::err_drv_invalid_diagnotics_misexpect_tolerance)

2275 << "-fdiagnostics-misexpect-tolerance=";

2276 } else {

2280 !UsingProfile)

2281 Diags.Report(diag::warn_drv_diagnostics_misexpect_requires_pgo)

2282 << "-fdiagnostics-misexpect-tolerance=";

2283 }

2284 }

2285

2286

2287

2288

2289 if (UsingSampleProfile)

2290 NeedLocTracking = true;

2291

2293 NeedLocTracking = true;

2294

2295

2296

2297 if (NeedLocTracking &&

2298 Opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo)

2299 Opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);

2300

2301

2302

2304 Args.getAllArgValues(OPT_fsanitize_recover_EQ), Diags,

2307 Args.getAllArgValues(OPT_fsanitize_trap_EQ), Diags,

2310 Args.getAllArgValues(OPT_fsanitize_merge_handlers_EQ),

2312

2313

2315 "-fsanitize-skip-hot-cutoff=",

2316 Args.getAllArgValues(OPT_fsanitize_skip_hot_cutoff_EQ), Diags);

2317

2318 Opts.EmitVersionIdentMetadata = Args.hasFlag(OPT_Qy, OPT_Qn, true);

2319

2320 if (LangOpts->CUDAIsDevice)

2322

2323 if (Args.hasArg(options::OPT_ffinite_loops))

2325 else if (Args.hasArg(options::OPT_fno_finite_loops))

2327

2328 Opts.EmitIEEENaNCompliantInsts = Args.hasFlag(

2329 options::OPT_mamdgpu_ieee, options::OPT_mno_amdgpu_ieee, true);

2330 if (!Opts.EmitIEEENaNCompliantInsts && !LangOptsRef.NoHonorNaNs)

2331 Diags.Report(diag::err_drv_amdgpu_ieee_without_no_honor_nans);

2332

2333 return Diags.getNumErrors() == NumErrorsBefore;

2334}

2335

2339#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \

2340 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

2341#include "clang/Driver/Options.inc"

2342#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING

2343

2345 GenerateArg(Consumer, OPT_show_includes);

2346

2347 for (const auto &Dep : Opts.ExtraDeps) {

2348 switch (Dep.second) {

2350

2351 continue;

2353

2354

2355 continue;

2357

2358

2359 continue;

2361 GenerateArg(Consumer, OPT_fdepfile_entry, Dep.first);

2362 break;

2363 }

2364 }

2365}

2366

2370 bool ShowLineMarkers) {

2371 unsigned NumErrorsBefore = Diags.getNumErrors();

2372

2374#define DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING(...) \

2375 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

2376#include "clang/Driver/Options.inc"

2377#undef DEPENDENCY_OUTPUT_OPTION_WITH_MARSHALLING

2378

2379 if (Args.hasArg(OPT_show_includes)) {

2380

2381

2382

2385 else

2387 } else {

2389 }

2390

2391

2392

2393

2394 if (!Args.hasArg(OPT_fno_sanitize_ignorelist)) {

2395 for (const auto *A : Args.filtered(OPT_fsanitize_ignorelist_EQ)) {

2396 StringRef Val = A->getValue();

2397 if (!Val.contains('='))

2399 }

2401 for (const auto *A : Args.filtered(OPT_fsanitize_system_ignorelist_EQ)) {

2402 StringRef Val = A->getValue();

2403 if (!Val.contains('='))

2405 }

2406 }

2407 }

2408

2409

2410 for (const auto &Filename : Args.getAllArgValues(OPT_fprofile_list_EQ))

2412

2413

2414 for (const auto *A : Args.filtered(OPT_fdepfile_entry))

2416

2417

2418 for (const auto *A : Args.filtered(OPT_fmodule_file)) {

2419 StringRef Val = A->getValue();

2420 if (!Val.contains('='))

2422 }

2423

2424

2425

2430 Diags.Report(diag::err_drv_print_header_env_var_combination_cc1)

2431 << Args.getLastArg(OPT_header_include_format_EQ)->getValue()

2432 << Args.getLastArg(OPT_header_include_filtering_EQ)->getValue();

2433

2434 return Diags.getNumErrors() == NumErrorsBefore;

2435}

2436

2438

2439

2440

2441

2442 enum {

2443 Colors_On,

2444 Colors_Off,

2445 Colors_Auto

2446 } ShowColors = DefaultColor ? Colors_Auto : Colors_Off;

2447 for (auto *A : Args) {

2448 const Option &O = A->getOption();

2449 if (O.matches(options::OPT_fcolor_diagnostics)) {

2451 } else if (O.matches(options::OPT_fno_color_diagnostics)) {

2453 } else if (O.matches(options::OPT_fdiagnostics_color_EQ)) {

2454 StringRef Value(A->getValue());

2455 if (Value == "always")

2457 else if (Value == "never")

2459 else if (Value == "auto")

2461 }

2462 }

2465 llvm::sys::Process::StandardErrHasColors());

2466}

2467

2471 for (const auto &Prefix : VerifyPrefixes) {

2472

2473

2474 auto BadChar = llvm::find_if(Prefix, [](char C) {

2476 });

2477 if (BadChar != Prefix.end() || isLetter(Prefix[0])) {

2479 Diags.Report(diag::err_drv_invalid_value) << "-verify=" << Prefix;

2480 Diags.Report(diag::note_drv_verify_prefix_spelling);

2481 }

2482 }

2484}

2485

2489

2490#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \

2491 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

2492#include "clang/Driver/Options.inc"

2493#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING

2494}

2495

2498 unsigned NumErrorsBefore = Diags.getNumErrors();

2499

2501

2502#define FILE_SYSTEM_OPTION_WITH_MARSHALLING(...) \

2503 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

2504#include "clang/Driver/Options.inc"

2505#undef FILE_SYSTEM_OPTION_WITH_MARSHALLING

2506

2507 return Diags.getNumErrors() == NumErrorsBefore;

2508}

2509

2513#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \

2514 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

2515#include "clang/Driver/Options.inc"

2516#undef MIGRATOR_OPTION_WITH_MARSHALLING

2517}

2518

2521 unsigned NumErrorsBefore = Diags.getNumErrors();

2522

2524

2525#define MIGRATOR_OPTION_WITH_MARSHALLING(...) \

2526 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

2527#include "clang/Driver/Options.inc"

2528#undef MIGRATOR_OPTION_WITH_MARSHALLING

2529

2530 return Diags.getNumErrors() == NumErrorsBefore;

2531}

2532

2533void CompilerInvocationBase::GenerateDiagnosticArgs(

2535 bool DefaultDiagColor) {

2537#define DIAG_OPTION_WITH_MARSHALLING(...) \

2538 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

2539#include "clang/Driver/Options.inc"

2540#undef DIAG_OPTION_WITH_MARSHALLING

2541

2543 GenerateArg(Consumer, OPT_diagnostic_serialized_file,

2545

2546 if (Opts.ShowColors)

2547 GenerateArg(Consumer, OPT_fcolor_diagnostics);

2548

2549 if (Opts.VerifyDiagnostics &&

2550 llvm::is_contained(Opts.VerifyPrefixes, "expected"))

2552

2554 if (Prefix != "expected")

2555 GenerateArg(Consumer, OPT_verify_EQ, Prefix);

2556

2559

2561 GenerateArg(Consumer, OPT_verify_ignore_unexpected);

2562 } else {

2564 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "note");

2566 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "remark");

2568 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "warning");

2570 GenerateArg(Consumer, OPT_verify_ignore_unexpected_EQ, "error");

2571 }

2572

2574

2575 if (Warning == "undef-prefix")

2576 continue;

2577

2578 if (Warning == "invalid-constexpr" || Warning == "no-invalid-constexpr")

2579 continue;

2580 Consumer(StringRef("-W") + Warning);

2581 }

2582

2584

2585

2586 StringRef IgnoredRemarks[] = {"pass", "no-pass",

2587 "pass-analysis", "no-pass-analysis",

2588 "pass-missed", "no-pass-missed"};

2589 if (llvm::is_contained(IgnoredRemarks, Remark))

2590 continue;

2591

2592 Consumer(StringRef("-R") + Remark);

2593 }

2594

2596 GenerateArg(Consumer, OPT_warning_suppression_mappings_EQ,

2598 }

2599}

2600

2601std::unique_ptr

2603 auto DiagOpts = std::make_unique();

2604 unsigned MissingArgIndex, MissingArgCount;

2606 Argv.slice(1), MissingArgIndex, MissingArgCount);

2607

2609 if (std::optionalstd::string NoColor =

2610 llvm::sys::Process::GetEnv("NO_COLOR");

2611 NoColor && !NoColor->empty()) {

2612

2613

2615 }

2616

2617

2618

2619

2621 return DiagOpts;

2622}

2623

2626 bool DefaultDiagColor) {

2627 std::optional IgnoringDiags;

2628 if (!Diags) {

2631 Diags = &*IgnoringDiags;

2632 }

2633

2634 unsigned NumErrorsBefore = Diags->getNumErrors();

2635

2636

2637

2639

2640#define DIAG_OPTION_WITH_MARSHALLING(...) \

2641 PARSE_OPTION_WITH_MARSHALLING(Args, *Diags, __VA_ARGS__)

2642#include "clang/Driver/Options.inc"

2643#undef DIAG_OPTION_WITH_MARSHALLING

2644

2645 llvm::sys::Process::UseANSIEscapeCodes(Opts.UseANSIEscapeCodes);

2646

2647 if (Arg *A =

2648 Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))

2651

2652 Opts.VerifyDiagnostics = Args.hasArg(OPT_verify) || Args.hasArg(OPT_verify_EQ);

2653 Opts.VerifyPrefixes = Args.getAllArgValues(OPT_verify_EQ);

2654 if (Args.hasArg(OPT_verify))

2656

2657

2659 Opts.VerifyDiagnostics = false;

2660 else

2664 "-verify-ignore-unexpected=",

2665 Args.getAllArgValues(OPT_verify_ignore_unexpected_EQ), *Diags, DiagMask);

2666 if (Args.hasArg(OPT_verify_ignore_unexpected))

2668 Opts.setVerifyIgnoreUnexpected(DiagMask);

2670 Diags->Report(diag::warn_ignoring_ftabstop_value)

2673 }

2674

2675 if (const Arg *A = Args.getLastArg(OPT_warning_suppression_mappings_EQ))

2677

2680

2681 return Diags->getNumErrors() == NumErrorsBefore;

2682}

2683

2684

2685

2686

2687

2689 std::string &BlockName,

2690 unsigned &MajorVersion,

2691 unsigned &MinorVersion,

2692 bool &Hashed,

2693 std::string &UserInfo) {

2695 Arg.split(Args, ':', 5);

2696 if (Args.size() < 5)

2697 return true;

2698

2699 BlockName = std::string(Args[0]);

2700 if (Args[1].getAsInteger(10, MajorVersion)) return true;

2701 if (Args[2].getAsInteger(10, MinorVersion)) return true;

2702 if (Args[3].getAsInteger(2, Hashed)) return true;

2703 if (Args.size() > 4)

2704 UserInfo = std::string(Args[4]);

2705 return false;

2706}

2707

2708

2709

2710

2711

2713 static const std::pair<frontend::ActionKind, unsigned> Table[] = {

2715

2722

2737

2740

2744 OPT_emit_reduced_module_interface},

2762 OPT_print_dependency_directives_minimized_source},

2763 };

2764

2765 return Table;

2766}

2767

2768

2769static std::optionalfrontend::ActionKind

2772 if (ActionOpt.second == Opt.getID())

2773 return ActionOpt.first;

2774

2775 return std::nullopt;

2776}

2777

2778

2779static std::optional

2782 if (ActionOpt.first == ProgramAction)

2783 return OptSpecifier(ActionOpt.second);

2784

2785 return std::nullopt;

2786}

2787

2791#define FRONTEND_OPTION_WITH_MARSHALLING(...) \

2792 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

2793#include "clang/Driver/Options.inc"

2794#undef FRONTEND_OPTION_WITH_MARSHALLING

2795

2796 std::optional ProgramActionOpt =

2798

2799

2800 std::function<void()> GenerateProgramAction = [&]() {

2801 GenerateArg(Consumer, *ProgramActionOpt);

2802 };

2803

2804 if (!ProgramActionOpt) {

2805

2807 "Frontend action without option.");

2808 GenerateProgramAction = [&]() {

2810 };

2811 }

2812

2813

2815 GenerateProgramAction = [&]() {

2816

2817

2818

2820 StringRef Format;

2823 llvm_unreachable("Default AST dump format.");

2825 Format = "json";

2826 break;

2827 }

2828

2830 GenerateArg(Consumer, OPT_ast_dump_all_EQ, Format);

2832 GenerateArg(Consumer, OPT_ast_dump_EQ, Format);

2833 } else {

2835 GenerateArg(Consumer, OPT_ast_dump_all);

2838 }

2839 };

2840 }

2841

2843 GenerateProgramAction = [&]() {

2845 };

2846 }

2847

2848 GenerateProgramAction();

2849

2850 for (const auto &PluginArgs : Opts.PluginArgs) {

2852 for (const auto &PluginArg : PluginArgs.second)

2854 Opt.getPrefix() + Opt.getName() + PluginArgs.first,

2855 Opt.getKind(), 0, PluginArg);

2856 }

2857

2859 if (auto *TestExt = dyn_cast_or_null(Ext.get()))

2860 GenerateArg(Consumer, OPT_ftest_module_file_extension_EQ, TestExt->str());

2861

2863 GenerateArg(Consumer, OPT_code_completion_at,

2865

2866 for (const auto &Plugin : Opts.Plugins)

2867 GenerateArg(Consumer, OPT_load, Plugin);

2868

2869

2870

2871 for (const auto &ModuleFile : Opts.ModuleFiles)

2872 GenerateArg(Consumer, OPT_fmodule_file, ModuleFile);

2873

2876

2879 GenerateArg(Consumer, OPT_aux_target_feature, Feature);

2880

2881 {

2882 StringRef Preprocessed = Opts.DashX.isPreprocessed() ? "-cpp-output" : "";

2885 StringRef HeaderUnit = "";

2888 break;

2890 HeaderUnit = "-user";

2891 break;

2893 HeaderUnit = "-system";

2894 break;

2896 HeaderUnit = "-header-unit";

2897 break;

2898 }

2899 StringRef Header = IsHeader ? "-header" : "";

2900

2901 StringRef Lang;

2904 Lang = "c";

2905 break;

2907 Lang = "cl";

2908 break;

2910 Lang = "clcpp";

2911 break;

2913 Lang = "cuda";

2914 break;

2916 Lang = "hip";

2917 break;

2919 Lang = "c++";

2920 break;

2922 Lang = "objective-c";

2923 break;

2925 Lang = "objective-c++";

2926 break;

2928 Lang = "assembler-with-cpp";

2929 break;

2932 "Generating -x argument for unknown language (not precompiled).");

2933 Lang = "ast";

2934 break;

2936 Lang = "ir";

2937 break;

2939 Lang = "hlsl";

2940 break;

2942 Lang = "cir";

2943 break;

2944 }

2945

2947 Lang + HeaderUnit + Header + ModuleMap + Preprocessed);

2948 }

2949

2950

2951 for (const auto &Input : Opts.Inputs)

2952 Consumer(Input.getFile());

2953}

2954

2957 unsigned NumErrorsBefore = Diags.getNumErrors();

2958

2960

2961#define FRONTEND_OPTION_WITH_MARSHALLING(...) \

2962 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

2963#include "clang/Driver/Options.inc"

2964#undef FRONTEND_OPTION_WITH_MARSHALLING

2965

2967 if (const Arg *A = Args.getLastArg(OPT_Action_Group)) {

2968 OptSpecifier Opt = OptSpecifier(A->getOption().getID());

2969 std::optionalfrontend::ActionKind ProgramAction = getFrontendAction(Opt);

2970 assert(ProgramAction && "Option specifier not in Action_Group.");

2971

2973 (Opt == OPT_ast_dump_all_EQ || Opt == OPT_ast_dump_EQ)) {

2974 unsigned Val = llvm::StringSwitch(A->getValue())

2977 .Default(std::numeric_limits::max());

2978

2979 if (Val != std::numeric_limits::max())

2981 else {

2982 Diags.Report(diag::err_drv_invalid_value)

2983 << A->getAsString(Args) << A->getValue();

2985 }

2986 }

2987

2988 if (ProgramAction == frontend::FixIt && Opt == OPT_fixit_EQ)

2990

2992 StringRef ArgStr =

2993 Args.hasArg(OPT_interface_stub_version_EQ)

2994 ? Args.getLastArgValue(OPT_interface_stub_version_EQ)

2995 : "ifs-v1";

2996 if (ArgStr == "experimental-yaml-elf-v1" ||

2997 ArgStr == "experimental-ifs-v1" || ArgStr == "experimental-ifs-v2" ||

2998 ArgStr == "experimental-tapi-elf-v1") {

2999 std::string ErrorMessage =

3000 "Invalid interface stub format: " + ArgStr.str() +

3001 " is deprecated.";

3002 Diags.Report(diag::err_drv_invalid_value)

3003 << "Must specify a valid interface stub format type, ie: "

3004 "-interface-stub-version=ifs-v1"

3005 << ErrorMessage;

3007 } else if (!ArgStr.starts_with("ifs-")) {

3008 std::string ErrorMessage =

3009 "Invalid interface stub format: " + ArgStr.str() + ".";

3010 Diags.Report(diag::err_drv_invalid_value)

3011 << "Must specify a valid interface stub format type, ie: "

3012 "-interface-stub-version=ifs-v1"

3013 << ErrorMessage;

3015 }

3016 }

3017

3019

3020

3021

3022

3023

3024

3025

3026

3027 if (!A->getSpelling().starts_with("-ast-dump")) {

3028 const Arg *SavedAction = nullptr;

3029 for (const Arg *AA :

3030 Args.filtered(OPT_Action_Group, OPT_main_file_name)) {

3031 if (AA->getOption().matches(OPT_main_file_name)) {

3032 SavedAction = nullptr;

3033 } else if (!SavedAction) {

3034 SavedAction = AA;

3035 } else {

3036 if (!A->getOption().matches(OPT_ast_dump_EQ))

3037 Diags.Report(diag::err_fe_invalid_multiple_actions)

3038 << SavedAction->getSpelling() << A->getSpelling();

3039 break;

3040 }

3041 }

3042 }

3043 }

3044

3045 if (const Arg* A = Args.getLastArg(OPT_plugin)) {

3046 Opts.Plugins.emplace_back(A->getValue(0));

3049 }

3050 for (const auto *AA : Args.filtered(OPT_plugin_arg))

3051 Opts.PluginArgs[AA->getValue(0)].emplace_back(AA->getValue(1));

3052

3053 for (const std::string &Arg :

3054 Args.getAllArgValues(OPT_ftest_module_file_extension_EQ)) {

3055 std::string BlockName;

3056 unsigned MajorVersion;

3057 unsigned MinorVersion;

3058 bool Hashed;

3059 std::string UserInfo;

3061 MinorVersion, Hashed, UserInfo)) {

3062 Diags.Report(diag::err_test_module_file_extension_format) << Arg;

3063

3064 continue;

3065 }

3066

3067

3069 std::make_shared(

3070 BlockName, MajorVersion, MinorVersion, Hashed, UserInfo));

3071 }

3072

3073 if (const Arg *A = Args.getLastArg(OPT_code_completion_at)) {

3077 Diags.Report(diag::err_drv_invalid_value)

3078 << A->getAsString(Args) << A->getValue();

3079 }

3080

3081 Opts.Plugins = Args.getAllArgValues(OPT_load);

3082 Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump, OPT_ast_dump_EQ);

3083 Opts.ASTDumpAll = Args.hasArg(OPT_ast_dump_all, OPT_ast_dump_all_EQ);

3084

3085 for (const auto *A : Args.filtered(OPT_fmodule_file)) {

3086 StringRef Val = A->getValue();

3087 if (!Val.contains('='))

3088 Opts.ModuleFiles.push_back(std::string(Val));

3089 }

3090

3092 Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"

3093 << "-emit-module";

3094 if (Args.hasArg(OPT_fclangir) || Args.hasArg(OPT_emit_cir))

3096

3097 if (Args.hasArg(OPT_aux_target_cpu))

3098 Opts.AuxTargetCPU = std::string(Args.getLastArgValue(OPT_aux_target_cpu));

3099 if (Args.hasArg(OPT_aux_target_feature))

3100 Opts.AuxTargetFeatures = Args.getAllArgValues(OPT_aux_target_feature);

3101

3104 Diags.Report(diag::err_drv_argument_not_allowed_with)

3105 << "ARC migration" << "ObjC migration";

3106 }

3107

3109 if (const Arg *A = Args.getLastArg(OPT_x)) {

3110 StringRef XValue = A->getValue();

3111

3112

3113

3114

3115 bool Preprocessed = XValue.consume_back("-cpp-output");

3116 bool ModuleMap = XValue.consume_back("-module-map");

3117

3118 bool IsHeader =

3119 XValue != "precompiled-header" && XValue.consume_back("-header");

3120

3121

3122

3123

3125 if (IsHeader || Preprocessed) {

3126 if (XValue.consume_back("-header-unit"))

3128 else if (XValue.consume_back("-system"))

3130 else if (XValue.consume_back("-user"))

3132 }

3133

3134

3135

3136 IsHeaderFile = IsHeader && !Preprocessed && ModuleMap &&

3138

3139

3140 DashX = llvm::StringSwitch(XValue)

3151

3152

3153

3154 if (DashX.isUnknown() && Preprocessed && !IsHeaderFile && ModuleMap &&

3156 DashX = llvm::StringSwitch(XValue)

3160

3161

3162 if (DashX.isUnknown() && !Preprocessed && !IsHeaderFile && ModuleMap &&

3164 DashX = llvm::StringSwitch(XValue)

3167 .Cases("ast", "pcm", "precompiled-header",

3172

3174 Diags.Report(diag::err_drv_invalid_value)

3175 << A->getAsString(Args) << A->getValue();

3176

3177 if (Preprocessed)

3179

3182 IsHeaderFile = true;

3183 } else if (IsHeaderFile)

3187 }

3188

3189

3190 std::vectorstd::string Inputs = Args.getAllArgValues(OPT_INPUT);

3191 Opts.Inputs.clear();

3192 if (Inputs.empty())

3193 Inputs.push_back("-");

3194

3196 Inputs.size() > 1)

3197 Diags.Report(diag::err_drv_header_unit_extra_inputs) << Inputs[1];

3198

3199 for (unsigned i = 0, e = Inputs.size(); i != e; ++i) {

3203 StringRef(Inputs[i]).rsplit('.').second);

3204

3207

3208 if (i == 0)

3209 DashX = IK;

3210 }

3211

3212 bool IsSystem = false;

3213

3214

3219 }

3220

3221 Opts.Inputs.emplace_back(std::move(Inputs[i]), IK, IsSystem);

3222 }

3223

3224 Opts.DashX = DashX;

3225

3226 return Diags.getNumErrors() == NumErrorsBefore;

3227}

3228

3230 void *MainAddr) {

3231 std::string ClangExecutable =

3232 llvm::sys::fs::getMainExecutable(Argv0, MainAddr);

3234}

3235

3239#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \

3240 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

3241#include "clang/Driver/Options.inc"

3242#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING

3243

3245 GenerateArg(Consumer, OPT_stdlib_EQ, "libc++");

3246

3249

3251 GenerateArg(Consumer, OPT_fmodule_file, File.first + "=" + File.second);

3252

3255

3257 GenerateArg(Consumer, OPT_fmodules_ignore_macro, Macro.val());

3258

3261 std::optional IsFramework,

3262 std::optional IgnoreSysRoot) {

3263 return llvm::is_contained(Groups, Entry.Group) &&

3264 (!IsFramework || (Entry.IsFramework == *IsFramework)) &&

3265 (!IgnoreSysRoot || (Entry.IgnoreSysRoot == *IgnoreSysRoot));

3266 };

3267

3270

3271

3272 for (; It < End && Matches(*It, {frontend::Angled}, std::nullopt, true);

3273 ++It) {

3274 OptSpecifier Opt = [It, Matches]() {

3276 return OPT_F;

3278 return OPT_I;

3279 llvm_unreachable("Unexpected HeaderSearchOptions::Entry.");

3280 }();

3281

3283 }

3284

3285

3286

3287

3288

3289 for (; It < End &&

3291 ++It) {

3292 OptSpecifier Opt =

3293 It->Group == frontend::After ? OPT_iwithprefix : OPT_iwithprefixbefore;

3295 }

3296

3297

3298

3299

3300 for (; It < End && Matches(*It, {frontend::After}, false, true); ++It)

3301 GenerateArg(Consumer, OPT_idirafter, It->Path);

3302 for (; It < End && Matches(*It, {frontend::Quoted}, false, true); ++It)

3303 GenerateArg(Consumer, OPT_iquote, It->Path);

3304 for (; It < End && Matches(*It, {frontend::System}, false, std::nullopt);

3305 ++It)

3306 GenerateArg(Consumer, It->IgnoreSysRoot ? OPT_isystem : OPT_iwithsysroot,

3307 It->Path);

3308 for (; It < End && Matches(*It, {frontend::System}, true, true); ++It)

3309 GenerateArg(Consumer, OPT_iframework, It->Path);

3310 for (; It < End && Matches(*It, {frontend::System}, true, false); ++It)

3311 GenerateArg(Consumer, OPT_iframeworkwithsysroot, It->Path);

3312

3313

3314 for (; It < End && Matches(*It, {frontend::CSystem}, false, true); ++It)

3315 GenerateArg(Consumer, OPT_c_isystem, It->Path);

3316 for (; It < End && Matches(*It, {frontend::CXXSystem}, false, true); ++It)

3317 GenerateArg(Consumer, OPT_cxx_isystem, It->Path);

3319 GenerateArg(Consumer, OPT_objc_isystem, It->Path);

3321 GenerateArg(Consumer, OPT_objcxx_isystem, It->Path);

3322

3323

3324

3325

3326

3327 for (; It < End &&

3329 ++It) {

3331 ? OPT_internal_isystem

3332 : OPT_internal_externc_isystem;

3334 }

3335

3336 assert(It == End && "Unhandled HeaderSearchOption::Entry.");

3337

3338

3340 OptSpecifier Opt = P.IsSystemHeader ? OPT_system_header_prefix

3341 : OPT_no_system_header_prefix;

3343 }

3344

3346 GenerateArg(Consumer, OPT_ivfsoverlay, F);

3347}

3348

3351 const std::string &WorkingDir) {

3352 unsigned NumErrorsBefore = Diags.getNumErrors();

3353

3355

3356#define HEADER_SEARCH_OPTION_WITH_MARSHALLING(...) \

3357 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

3358#include "clang/Driver/Options.inc"

3359#undef HEADER_SEARCH_OPTION_WITH_MARSHALLING

3360

3361 if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))

3362 Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);

3363

3364

3365 SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path));

3366 if (!(P.empty() || llvm::sys::path::is_absolute(P))) {

3367 if (WorkingDir.empty())

3368 llvm::sys::fs::make_absolute(P);

3369 else

3370 llvm::sys::fs::make_absolute(WorkingDir, P);

3371 }

3372 llvm::sys::path::remove_dots(P);

3374

3375

3376 for (const auto *A : Args.filtered(OPT_fmodule_file)) {

3377 StringRef Val = A->getValue();

3378 if (Val.contains('=')) {

3379 auto Split = Val.split('=');

3381 std::string(Split.first), std::string(Split.second));

3382 }

3383 }

3384 for (const auto *A : Args.filtered(OPT_fprebuilt_module_path))

3386

3387 for (const auto *A : Args.filtered(OPT_fmodules_ignore_macro)) {

3388 StringRef MacroDef = A->getValue();

3390 llvm::CachedHashString(MacroDef.split('=').first));

3391 }

3392

3393

3394 bool IsSysrootSpecified =

3395 Args.hasArg(OPT__sysroot_EQ) || Args.hasArg(OPT_isysroot);

3396

3397

3398

3399 auto PrefixHeaderPath = [IsSysrootSpecified,

3400 &Opts](const llvm::opt::Arg *A,

3401 bool IsFramework = false) -> std::string {

3402 assert(A->getNumValues() && "Unexpected empty search path flag!");

3403 if (IsSysrootSpecified && !IsFramework && A->getValue()[0] == '=') {

3405 llvm::sys::path::append(Buffer, Opts.Sysroot,

3406 llvm::StringRef(A->getValue()).substr(1));

3407 return std::string(Buffer);

3408 }

3409 return A->getValue();

3410 };

3411

3412 for (const auto *A : Args.filtered(OPT_I, OPT_F)) {

3413 bool IsFramework = A->getOption().matches(OPT_F);

3415 IsFramework, true);

3416 }

3417

3418

3419 StringRef Prefix = "";

3420 for (const auto *A :

3421 Args.filtered(OPT_iprefix, OPT_iwithprefix, OPT_iwithprefixbefore)) {

3422 if (A->getOption().matches(OPT_iprefix))

3423 Prefix = A->getValue();

3424 else if (A->getOption().matches(OPT_iwithprefix))

3426 else

3428 }

3429

3430 for (const auto *A : Args.filtered(OPT_idirafter))

3432 for (const auto *A : Args.filtered(OPT_iquote))

3434

3435 for (const auto *A : Args.filtered(OPT_isystem, OPT_iwithsysroot)) {

3436 if (A->getOption().matches(OPT_iwithsysroot)) {

3438 false);

3439 continue;

3440 }

3442 }

3443 for (const auto *A : Args.filtered(OPT_iframework))

3445 for (const auto *A : Args.filtered(OPT_iframeworkwithsysroot))

3447 false);

3448

3449

3450 for (const auto *A : Args.filtered(OPT_c_isystem))

3452 for (const auto *A : Args.filtered(OPT_cxx_isystem))

3454 for (const auto *A : Args.filtered(OPT_objc_isystem))

3456 for (const auto *A : Args.filtered(OPT_objcxx_isystem))

3458

3459

3460 for (const auto *A :

3461 Args.filtered(OPT_internal_isystem, OPT_internal_externc_isystem)) {

3463 if (A->getOption().matches(OPT_internal_externc_isystem))

3465 Opts.AddPath(A->getValue(), Group, false, true);

3466 }

3467

3468

3469 for (const auto *A :

3470 Args.filtered(OPT_system_header_prefix, OPT_no_system_header_prefix))

3472 A->getValue(), A->getOption().matches(OPT_system_header_prefix));

3473

3474 for (const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))

3476

3477 return Diags.getNumErrors() == NumErrorsBefore;

3478}

3479

3483 GenerateArg(Consumer, OPT_fapinotes_swift_version,

3485

3488}

3489

3492 if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {

3493 if (Opts.SwiftVersion.tryParse(A->getValue()))

3494 diags.Report(diag::err_drv_invalid_value)

3495 << A->getAsString(Args) << A->getValue();

3496 }

3497 for (const Arg *A : Args.filtered(OPT_iapinotes_modules))

3499}

3500

3503 if (Opts.PointerAuthIntrinsics)

3504 GenerateArg(Consumer, OPT_fptrauth_intrinsics);

3505 if (Opts.PointerAuthCalls)

3506 GenerateArg(Consumer, OPT_fptrauth_calls);

3507 if (Opts.PointerAuthReturns)

3508 GenerateArg(Consumer, OPT_fptrauth_returns);

3509 if (Opts.PointerAuthIndirectGotos)

3510 GenerateArg(Consumer, OPT_fptrauth_indirect_gotos);

3511 if (Opts.PointerAuthAuthTraps)

3512 GenerateArg(Consumer, OPT_fptrauth_auth_traps);

3513 if (Opts.PointerAuthVTPtrAddressDiscrimination)

3514 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_address_discrimination);

3515 if (Opts.PointerAuthVTPtrTypeDiscrimination)

3516 GenerateArg(Consumer, OPT_fptrauth_vtable_pointer_type_discrimination);

3517 if (Opts.PointerAuthTypeInfoVTPtrDiscrimination)

3518 GenerateArg(Consumer, OPT_fptrauth_type_info_vtable_pointer_discrimination);

3519 if (Opts.PointerAuthFunctionTypeDiscrimination)

3520 GenerateArg(Consumer, OPT_fptrauth_function_pointer_type_discrimination);

3521 if (Opts.PointerAuthInitFini)

3522 GenerateArg(Consumer, OPT_fptrauth_init_fini);

3523 if (Opts.PointerAuthInitFiniAddressDiscrimination)

3524 GenerateArg(Consumer, OPT_fptrauth_init_fini_address_discrimination);

3525 if (Opts.PointerAuthELFGOT)

3526 GenerateArg(Consumer, OPT_fptrauth_elf_got);

3527 if (Opts.AArch64JumpTableHardening)

3528 GenerateArg(Consumer, OPT_faarch64_jump_table_hardening);

3529}

3530

3533 Opts.PointerAuthIntrinsics = Args.hasArg(OPT_fptrauth_intrinsics);

3534 Opts.PointerAuthCalls = Args.hasArg(OPT_fptrauth_calls);

3535 Opts.PointerAuthReturns = Args.hasArg(OPT_fptrauth_returns);

3536 Opts.PointerAuthIndirectGotos = Args.hasArg(OPT_fptrauth_indirect_gotos);

3537 Opts.PointerAuthAuthTraps = Args.hasArg(OPT_fptrauth_auth_traps);

3538 Opts.PointerAuthVTPtrAddressDiscrimination =

3539 Args.hasArg(OPT_fptrauth_vtable_pointer_address_discrimination);

3540 Opts.PointerAuthVTPtrTypeDiscrimination =

3541 Args.hasArg(OPT_fptrauth_vtable_pointer_type_discrimination);

3542 Opts.PointerAuthTypeInfoVTPtrDiscrimination =

3543 Args.hasArg(OPT_fptrauth_type_info_vtable_pointer_discrimination);

3544 Opts.PointerAuthFunctionTypeDiscrimination =

3545 Args.hasArg(OPT_fptrauth_function_pointer_type_discrimination);

3546 Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini);

3547 Opts.PointerAuthInitFiniAddressDiscrimination =

3548 Args.hasArg(OPT_fptrauth_init_fini_address_discrimination);

3549 Opts.PointerAuthELFGOT = Args.hasArg(OPT_fptrauth_elf_got);

3550 Opts.AArch64JumpTableHardening =

3551 Args.hasArg(OPT_faarch64_jump_table_hardening);

3552}

3553

3554

3561 llvm_unreachable("should not parse language flags for this input");

3562

3566

3570

3573

3577

3579

3582

3585

3587

3588

3589

3590 return true;

3591

3594 }

3595

3596 llvm_unreachable("unexpected input language");

3597}

3598

3599

3603 return "C";

3605 return "Objective-C";

3607 return "C++";

3609 return "Objective-C++";

3611 return "OpenCL";

3613 return "C++ for OpenCL";

3615 return "CUDA";

3617 return "HIP";

3618

3620 return "Asm";

3622 return "LLVM IR";

3624 return "Clang IR";

3625

3627 return "HLSL";

3628

3630 break;

3631 }

3632 llvm_unreachable("unknown input language");

3633}

3634

3635void CompilerInvocationBase::GenerateLangArgs(const LangOptions &Opts,

3637 const llvm::Triple &T,

3642 if (Opts.ObjCAutoRefCount)

3644 if (Opts.PICLevel != 0)

3645 GenerateArg(Consumer, OPT_pic_level, Twine(Opts.PICLevel));

3646 if (Opts.PIE)

3649 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);

3650

3651 return;

3652 }

3653

3654 OptSpecifier StdOpt;

3656 case LangStandard::lang_opencl10:

3657 case LangStandard::lang_opencl11:

3658 case LangStandard::lang_opencl12:

3659 case LangStandard::lang_opencl20:

3660 case LangStandard::lang_opencl30:

3661 case LangStandard::lang_openclcpp10:

3662 case LangStandard::lang_openclcpp2021:

3663 StdOpt = OPT_cl_std_EQ;

3664 break;

3665 default:

3666 StdOpt = OPT_std_EQ;

3667 break;

3668 }

3669

3672

3673 if (Opts.IncludeDefaultHeader)

3674 GenerateArg(Consumer, OPT_finclude_default_header);

3675 if (Opts.DeclareOpenCLBuiltins)

3676 GenerateArg(Consumer, OPT_fdeclare_opencl_builtins);

3677

3679

3680#define LANG_OPTION_WITH_MARSHALLING(...) \

3681 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

3682#include "clang/Driver/Options.inc"

3683#undef LANG_OPTION_WITH_MARSHALLING

3684

3685

3686

3687 if (Opts.ObjC) {

3689

3691 GenerateArg(Consumer, OPT_fobjc_gc_only);

3694 else if (Opts.ObjCAutoRefCount == 1)

3696

3697 if (Opts.ObjCWeakRuntime)

3698 GenerateArg(Consumer, OPT_fobjc_runtime_has_weak);

3699

3700 if (Opts.ObjCWeak)

3702

3703 if (Opts.ObjCSubscriptingLegacyRuntime)

3704 GenerateArg(Consumer, OPT_fobjc_subscripting_legacy_runtime);

3705 }

3706

3707 if (Opts.GNUCVersion != 0) {

3708 unsigned Major = Opts.GNUCVersion / 100 / 100;

3709 unsigned Minor = (Opts.GNUCVersion / 100) % 100;

3710 unsigned Patch = Opts.GNUCVersion % 100;

3711 GenerateArg(Consumer, OPT_fgnuc_version_EQ,

3712 Twine(Major) + "." + Twine(Minor) + "." + Twine(Patch));

3713 }

3714

3715 if (Opts.IgnoreXCOFFVisibility)

3716 GenerateArg(Consumer, OPT_mignore_xcoff_visibility);

3717

3723 }

3724

3725 if (Opts.MSCompatibilityVersion != 0) {

3726 unsigned Major = Opts.MSCompatibilityVersion / 10000000;

3727 unsigned Minor = (Opts.MSCompatibilityVersion / 100000) % 100;

3728 unsigned Subminor = Opts.MSCompatibilityVersion % 100000;

3729 GenerateArg(Consumer, OPT_fms_compatibility_version,

3730 Twine(Major) + "." + Twine(Minor) + "." + Twine(Subminor));

3731 }

3732

3733 if ((!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||

3734 T.isOSzOS()) {

3735 if (!Opts.Trigraphs)

3736 GenerateArg(Consumer, OPT_fno_trigraphs);

3737 } else {

3738 if (Opts.Trigraphs)

3740 }

3741

3742 if (T.isOSzOS() && !Opts.ZOSExt)

3743 GenerateArg(Consumer, OPT_fno_zos_extensions);

3744 else if (Opts.ZOSExt)

3745 GenerateArg(Consumer, OPT_fzos_extensions);

3746

3747 if (Opts.Blocks && !(Opts.OpenCL && Opts.OpenCLVersion == 200))

3749

3750 if (Opts.ConvergentFunctions)

3751 GenerateArg(Consumer, OPT_fconvergent_functions);

3752 else

3753 GenerateArg(Consumer, OPT_fno_convergent_functions);

3754

3755 if (Opts.NoBuiltin && !Opts.Freestanding)

3757

3758 if (!Opts.NoBuiltin)

3761

3762 if (Opts.LongDoubleSize == 128)

3763 GenerateArg(Consumer, OPT_mlong_double_128);

3764 else if (Opts.LongDoubleSize == 64)

3765 GenerateArg(Consumer, OPT_mlong_double_64);

3766 else if (Opts.LongDoubleSize == 80)

3767 GenerateArg(Consumer, OPT_mlong_double_80);

3768

3769

3770

3771

3772

3773 if (Opts.OpenMP && !Opts.OpenMPSimd) {

3775

3776 if (Opts.OpenMP != 51)

3777 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));

3778

3779 if (!Opts.OpenMPUseTLS)

3780 GenerateArg(Consumer, OPT_fnoopenmp_use_tls);

3781

3782 if (Opts.OpenMPIsTargetDevice)

3783 GenerateArg(Consumer, OPT_fopenmp_is_target_device);

3784

3785 if (Opts.OpenMPIRBuilder)

3786 GenerateArg(Consumer, OPT_fopenmp_enable_irbuilder);

3787 }

3788

3789 if (Opts.OpenMPSimd) {

3790 GenerateArg(Consumer, OPT_fopenmp_simd);

3791

3792 if (Opts.OpenMP != 51)

3793 GenerateArg(Consumer, OPT_fopenmp_version_EQ, Twine(Opts.OpenMP));

3794 }

3795

3796 if (Opts.OpenMPThreadSubscription)

3797 GenerateArg(Consumer, OPT_fopenmp_assume_threads_oversubscription);

3798

3799 if (Opts.OpenMPTeamSubscription)

3800 GenerateArg(Consumer, OPT_fopenmp_assume_teams_oversubscription);

3801

3802 if (Opts.OpenMPTargetDebug != 0)

3803 GenerateArg(Consumer, OPT_fopenmp_target_debug_EQ,

3804 Twine(Opts.OpenMPTargetDebug));

3805

3806 if (Opts.OpenMPCUDANumSMs != 0)

3807 GenerateArg(Consumer, OPT_fopenmp_cuda_number_of_sm_EQ,

3808 Twine(Opts.OpenMPCUDANumSMs));

3809

3810 if (Opts.OpenMPCUDABlocksPerSM != 0)

3811 GenerateArg(Consumer, OPT_fopenmp_cuda_blocks_per_sm_EQ,

3812 Twine(Opts.OpenMPCUDABlocksPerSM));

3813

3814 if (Opts.OpenMPCUDAReductionBufNum != 1024)

3815 GenerateArg(Consumer, OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,

3816 Twine(Opts.OpenMPCUDAReductionBufNum));

3817

3819 std::string Targets;

3820 llvm::raw_string_ostream OS(Targets);

3821 llvm::interleave(

3823 [&OS](const llvm::Triple &T) { OS << T.str(); }, ",");

3824 GenerateArg(Consumer, OPT_fopenmp_targets_EQ, Targets);

3825 }

3826

3829

3830 if (Opts.OpenMPCUDAMode)

3831 GenerateArg(Consumer, OPT_fopenmp_cuda_mode);

3832

3833 if (Opts.OpenACC) {

3836 GenerateArg(Consumer, OPT_openacc_macro_override,

3838 }

3839

3840

3841

3842

3844 GenerateArg(Consumer, OPT_ffp_contract, "fast");

3846 GenerateArg(Consumer, OPT_ffp_contract, "on");

3848 GenerateArg(Consumer, OPT_ffp_contract, "off");

3850 GenerateArg(Consumer, OPT_ffp_contract, "fast-honor-pragmas");

3851

3853 GenerateArg(Consumer, OPT_fsanitize_EQ, Sanitizer);

3854

3855

3857 GenerateArg(Consumer, OPT_fsanitize_ignorelist_EQ, F);

3858

3859 switch (Opts.getClangABICompat()) {

3861 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "3.8");

3862 break;

3864 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "4.0");

3865 break;

3867 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "6.0");

3868 break;

3870 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "7.0");

3871 break;

3873 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "9.0");

3874 break;

3876 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "11.0");

3877 break;

3879 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "12.0");

3880 break;

3882 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "14.0");

3883 break;

3885 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "15.0");

3886 break;

3888 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "17.0");

3889 break;

3891 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "18.0");

3892 break;

3894 GenerateArg(Consumer, OPT_fclang_abi_compat_EQ, "19.0");

3895 break;

3897 break;

3898 }

3899

3900 if (Opts.getSignReturnAddressScope() ==

3902 GenerateArg(Consumer, OPT_msign_return_address_EQ, "all");

3903 else if (Opts.getSignReturnAddressScope() ==

3905 GenerateArg(Consumer, OPT_msign_return_address_EQ, "non-leaf");

3906

3907 if (Opts.getSignReturnAddressKey() ==

3909 GenerateArg(Consumer, OPT_msign_return_address_key_EQ, "b_key");

3910

3914

3915 if (Opts.RelativeCXXABIVTables)

3916 GenerateArg(Consumer, OPT_fexperimental_relative_cxx_abi_vtables);

3917 else

3918 GenerateArg(Consumer, OPT_fno_experimental_relative_cxx_abi_vtables);

3919

3921 GenerateArg(Consumer, OPT_ffile_reproducible);

3922 else

3923 GenerateArg(Consumer, OPT_fno_file_reproducible);

3924

3926 GenerateArg(Consumer, OPT_fmacro_prefix_map_EQ, MP.first + "=" + MP.second);

3927

3930}

3931

3932bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,

3933 InputKind IK, const llvm::Triple &T,

3934 std::vectorstd::string &Includes,

3936 unsigned NumErrorsBefore = Diags.getNumErrors();

3937

3941

3942

3943

3944 if (Args.hasArg(OPT_fobjc_arc))

3945 Opts.ObjCAutoRefCount = 1;

3946

3947

3949 Opts.PIE = Args.hasArg(OPT_pic_is_pie);

3950 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),

3952

3953 return Diags.getNumErrors() == NumErrorsBefore;

3954 }

3955

3956

3957

3958

3959

3961 if (const Arg *A = Args.getLastArg(OPT_std_EQ)) {

3964 Diags.Report(diag::err_drv_invalid_value)

3965 << A->getAsString(Args) << A->getValue();

3966

3967 for (unsigned KindValue = 0;

3969 ++KindValue) {

3973 auto Diag = Diags.Report(diag::note_drv_use_standard);

3974 Diag << Std.getName() << Std.getDescription();

3975 unsigned NumAliases = 0;

3976#define LANGSTANDARD(id, name, lang, desc, features)

3977#define LANGSTANDARD_ALIAS(id, alias) \

3978 if (KindValue == LangStandard::lang_##id) ++NumAliases;

3979#define LANGSTANDARD_ALIAS_DEPR(id, alias)

3980#include "clang/Basic/LangStandards.def"

3981 Diag << NumAliases;

3982#define LANGSTANDARD(id, name, lang, desc, features)

3983#define LANGSTANDARD_ALIAS(id, alias) \

3984 if (KindValue == LangStandard::lang_##id) Diag << alias;

3985#define LANGSTANDARD_ALIAS_DEPR(id, alias)

3986#include "clang/Basic/LangStandards.def"

3987 }

3988 }

3989 } else {

3990

3991

3994 Diags.Report(diag::err_drv_argument_not_allowed_with)

3996 }

3997 }

3998 }

3999

4000

4001

4002 if (const Arg *A = Args.getLastArg(OPT_cl_std_EQ)) {

4004 = llvm::StringSwitchLangStandard::Kind(A->getValue())

4005 .Cases("cl", "CL", LangStandard::lang_opencl10)

4006 .Cases("cl1.0", "CL1.0", LangStandard::lang_opencl10)

4007 .Cases("cl1.1", "CL1.1", LangStandard::lang_opencl11)

4008 .Cases("cl1.2", "CL1.2", LangStandard::lang_opencl12)

4009 .Cases("cl2.0", "CL2.0", LangStandard::lang_opencl20)

4010 .Cases("cl3.0", "CL3.0", LangStandard::lang_opencl30)

4011 .Cases("clc++", "CLC++", LangStandard::lang_openclcpp10)

4012 .Cases("clc++1.0", "CLC++1.0", LangStandard::lang_openclcpp10)

4013 .Cases("clc++2021", "CLC++2021", LangStandard::lang_openclcpp2021)

4015

4017 Diags.Report(diag::err_drv_invalid_value)

4018 << A->getAsString(Args) << A->getValue();

4019 }

4020 else

4021 LangStd = OpenCLLangStd;

4022 }

4023

4024

4025 Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);

4026 Opts.DeclareOpenCLBuiltins = Args.hasArg(OPT_fdeclare_opencl_builtins);

4027

4029

4030

4031

4033

4034#define LANG_OPTION_WITH_MARSHALLING(...) \

4035 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

4036#include "clang/Driver/Options.inc"

4037#undef LANG_OPTION_WITH_MARSHALLING

4038

4039 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {

4040 StringRef Name = A->getValue();

4041 if (Name == "full" || Name == "branch") {

4042 Opts.CFProtectionBranch = 1;

4043 }

4044 }

4045

4046 if (Opts.CFProtectionBranch) {

4047 if (const Arg *A = Args.getLastArg(OPT_mcf_branch_label_scheme_EQ)) {

4048 const auto Scheme =

4049 llvm::StringSwitch(A->getValue())

4050#define CF_BRANCH_LABEL_SCHEME(Kind, FlagVal) \

4051 .Case(#FlagVal, CFBranchLabelSchemeKind::Kind)

4052#include "clang/Basic/CFProtectionOptions.def"

4054 Opts.setCFBranchLabelScheme(Scheme);

4055 }

4056 }

4057

4058 if ((Args.hasArg(OPT_fsycl_is_device) || Args.hasArg(OPT_fsycl_is_host)) &&

4059 !Args.hasArg(OPT_sycl_std_EQ)) {

4060

4061

4062

4063

4064

4066 }

4067

4068 if (Opts.ObjC) {

4069 if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {

4070 StringRef value = arg->getValue();

4072 Diags.Report(diag::err_drv_unknown_objc_runtime) << value;

4073 }

4074

4075 if (Args.hasArg(OPT_fobjc_gc_only))

4077 else if (Args.hasArg(OPT_fobjc_gc))

4079 else if (Args.hasArg(OPT_fobjc_arc)) {

4080 Opts.ObjCAutoRefCount = 1;

4082 Diags.Report(diag::err_arc_unsupported_on_runtime);

4083 }

4084

4085

4086

4087

4088

4089 if (Args.hasArg(OPT_fobjc_runtime_has_weak))

4090 Opts.ObjCWeakRuntime = 1;

4091 else

4093

4094

4095

4096 if (auto weakArg = Args.getLastArg(OPT_fobjc_weak, OPT_fno_objc_weak)) {

4097 if (!weakArg->getOption().matches(OPT_fobjc_weak)) {

4098 assert(!Opts.ObjCWeak);

4100 Diags.Report(diag::err_objc_weak_with_gc);

4101 } else if (!Opts.ObjCWeakRuntime) {

4102 Diags.Report(diag::err_objc_weak_unsupported);

4103 } else {

4104 Opts.ObjCWeak = 1;

4105 }

4106 } else if (Opts.ObjCAutoRefCount) {

4107 Opts.ObjCWeak = Opts.ObjCWeakRuntime;

4108 }

4109

4110 if (Args.hasArg(OPT_fobjc_subscripting_legacy_runtime))

4111 Opts.ObjCSubscriptingLegacyRuntime =

4113 }

4114

4115 if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {

4116

4117

4118 VersionTuple GNUCVer;

4119 bool Invalid = GNUCVer.tryParse(A->getValue());

4120 unsigned Major = GNUCVer.getMajor();

4121 unsigned Minor = GNUCVer.getMinor().value_or(0);

4122 unsigned Patch = GNUCVer.getSubminor().value_or(0);

4123 if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {

4124 Diags.Report(diag::err_drv_invalid_value)

4125 << A->getAsString(Args) << A->getValue();

4126 }

4127 Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;

4128 }

4129

4130 if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility)))

4131 Opts.IgnoreXCOFFVisibility = 1;

4132

4133 if (Args.hasArg(OPT_ftrapv)) {

4135

4137 std::string(Args.getLastArgValue(OPT_ftrapv_handler));

4138 }

4139 else if (Args.hasArg(OPT_fwrapv))

4141

4142 Opts.MSCompatibilityVersion = 0;

4143 if (const Arg *A = Args.getLastArg(OPT_fms_compatibility_version)) {

4144 VersionTuple VT;

4145 if (VT.tryParse(A->getValue()))

4146 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args)

4147 << A->getValue();

4148 Opts.MSCompatibilityVersion = VT.getMajor() * 10000000 +

4149 VT.getMinor().value_or(0) * 100000 +

4150 VT.getSubminor().value_or(0);

4151 }

4152

4153

4154

4155

4156

4157 Opts.Trigraphs =

4158 (!Opts.GNUMode && !Opts.MSVCCompat && !Opts.CPlusPlus17 && !Opts.C23) ||

4159 T.isOSzOS();

4160 Opts.Trigraphs =

4161 Args.hasFlag(OPT_ftrigraphs, OPT_fno_trigraphs, Opts.Trigraphs);

4162

4163 Opts.ZOSExt =

4164 Args.hasFlag(OPT_fzos_extensions, OPT_fno_zos_extensions, T.isOSzOS());

4165

4166 Opts.Blocks = Args.hasArg(OPT_fblocks) || (Opts.OpenCL

4167 && Opts.OpenCLVersion == 200);

4168

4169 bool HasConvergentOperations = Opts.OpenMPIsTargetDevice || Opts.OpenCL ||

4170 Opts.CUDAIsDevice || Opts.SYCLIsDevice ||

4171 Opts.HLSL || T.isAMDGPU() || T.isNVPTX();

4172 Opts.ConvergentFunctions =

4173 Args.hasFlag(OPT_fconvergent_functions, OPT_fno_convergent_functions,

4174 HasConvergentOperations);

4175

4176 Opts.NoBuiltin = Args.hasArg(OPT_fno_builtin) || Opts.Freestanding;

4177 if (!Opts.NoBuiltin)

4179 if (Arg *A = Args.getLastArg(options::OPT_LongDouble_Group)) {

4180 if (A->getOption().matches(options::OPT_mlong_double_64))

4181 Opts.LongDoubleSize = 64;

4182 else if (A->getOption().matches(options::OPT_mlong_double_80))

4183 Opts.LongDoubleSize = 80;

4184 else if (A->getOption().matches(options::OPT_mlong_double_128))

4185 Opts.LongDoubleSize = 128;

4186 else

4187 Opts.LongDoubleSize = 0;

4188 }

4189 if (Opts.FastRelaxedMath || Opts.CLUnsafeMath)

4191

4193

4194

4195 if (Arg *A = Args.getLastArg(OPT_mrtd)) {

4197 Diags.Report(diag::err_drv_argument_not_allowed_with)

4198 << A->getSpelling() << "-fdefault-calling-conv";

4199 else {

4200 switch (T.getArch()) {

4201 case llvm::Triple::x86:

4203 break;

4204 case llvm::Triple::m68k:

4206 break;

4207 default:

4208 Diags.Report(diag::err_drv_argument_not_allowed_with)

4209 << A->getSpelling() << T.getTriple();

4210 }

4211 }

4212 }

4213

4214

4215 Opts.OpenMP = Args.hasArg(OPT_fopenmp) ? 51 : 0;

4216

4217 bool IsSimdSpecified =

4218 Args.hasFlag(options::OPT_fopenmp_simd, options::OPT_fno_openmp_simd,

4219 false);

4220 Opts.OpenMPSimd = !Opts.OpenMP && IsSimdSpecified;

4221 Opts.OpenMPUseTLS =

4222 Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);

4223 Opts.OpenMPIsTargetDevice =

4224 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_is_target_device);

4225 Opts.OpenMPIRBuilder =

4226 Opts.OpenMP && Args.hasArg(options::OPT_fopenmp_enable_irbuilder);

4227 bool IsTargetSpecified =

4228 Opts.OpenMPIsTargetDevice || Args.hasArg(options::OPT_fopenmp_targets_EQ);

4229

4230 if (Opts.OpenMP || Opts.OpenMPSimd) {

4232 Args, OPT_fopenmp_version_EQ,

4233 (IsSimdSpecified || IsTargetSpecified) ? 51 : Opts.OpenMP, Diags))

4234 Opts.OpenMP = Version;

4235

4236

4237 if (!Opts.OpenMPIsTargetDevice) {

4238 switch (T.getArch()) {

4239 default:

4240 break;

4241

4242 case llvm::Triple::nvptx:

4243 case llvm::Triple::nvptx64:

4244 Diags.Report(diag::err_drv_omp_host_target_not_supported) << T.str();

4245 break;

4246 }

4247 }

4248 }

4249

4250

4251

4252 if ((Opts.OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN())) ||

4253 Opts.OpenCLCPlusPlus) {

4254

4255 Opts.Exceptions = 0;

4256 Opts.CXXExceptions = 0;

4257 }

4258 if (Opts.OpenMPIsTargetDevice && T.isNVPTX()) {

4259 Opts.OpenMPCUDANumSMs =

4261 Opts.OpenMPCUDANumSMs, Diags);

4262 Opts.OpenMPCUDABlocksPerSM =

4263 getLastArgIntValue(Args, options::OPT_fopenmp_cuda_blocks_per_sm_EQ,

4264 Opts.OpenMPCUDABlocksPerSM, Diags);

4266 Args, options::OPT_fopenmp_cuda_teams_reduction_recs_num_EQ,

4267 Opts.OpenMPCUDAReductionBufNum, Diags);

4268 }

4269

4270

4271

4272 if (Opts.OpenMPIsTargetDevice && (Args.hasArg(OPT_fopenmp_target_debug) ||

4273 Args.hasArg(OPT_fopenmp_target_debug_EQ))) {

4275 Args, OPT_fopenmp_target_debug_EQ, Opts.OpenMPTargetDebug, Diags);

4276 if (!Opts.OpenMPTargetDebug && Args.hasArg(OPT_fopenmp_target_debug))

4277 Opts.OpenMPTargetDebug = 1;

4278 }

4279

4280 if (Opts.OpenMPIsTargetDevice) {

4281 if (Args.hasArg(OPT_fopenmp_assume_teams_oversubscription))

4282 Opts.OpenMPTeamSubscription = true;

4283 if (Args.hasArg(OPT_fopenmp_assume_threads_oversubscription))

4284 Opts.OpenMPThreadSubscription = true;

4285 }

4286

4287

4288 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {

4289 enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };

4290 auto getArchPtrSize = [](const llvm::Triple &T) {

4291 if (T.isArch16Bit())

4292 return Arch16Bit;

4293 if (T.isArch32Bit())

4294 return Arch32Bit;

4295 assert(T.isArch64Bit() && "Expected 64-bit architecture");

4296 return Arch64Bit;

4297 };

4298

4299 for (unsigned i = 0; i < A->getNumValues(); ++i) {

4300 llvm::Triple TT(A->getValue(i));

4301

4302 if (TT.getArch() == llvm::Triple::UnknownArch ||

4303 !(TT.getArch() == llvm::Triple::aarch64 || TT.isPPC() ||

4304 TT.getArch() == llvm::Triple::spirv64 ||

4305 TT.getArch() == llvm::Triple::systemz ||

4306 TT.getArch() == llvm::Triple::loongarch64 ||

4307 TT.getArch() == llvm::Triple::nvptx ||

4308 TT.getArch() == llvm::Triple::nvptx64 ||

4309 TT.getArch() == llvm::Triple::amdgcn ||

4310 TT.getArch() == llvm::Triple::x86 ||

4311 TT.getArch() == llvm::Triple::x86_64))

4312 Diags.Report(diag::err_drv_invalid_omp_target) << A->getValue(i);

4313 else if (getArchPtrSize(T) != getArchPtrSize(TT))

4314 Diags.Report(diag::err_drv_incompatible_omp_arch)

4315 << A->getValue(i) << T.str();

4316 else

4318 }

4319 }

4320

4321

4322

4323 if (Arg *A = Args.getLastArg(options::OPT_fopenmp_host_ir_file_path)) {

4326 Diags.Report(diag::err_drv_omp_host_ir_file_not_found)

4328 }

4329

4330

4331 Opts.OpenMPCUDAMode = Opts.OpenMPIsTargetDevice &&

4332 (T.isNVPTX() || T.isAMDGCN()) &&

4333 Args.hasArg(options::OPT_fopenmp_cuda_mode);

4334

4335

4336 if (Args.hasArg(options::OPT_fopenacc)) {

4337 Opts.OpenACC = true;

4338

4339 if (Arg *A = Args.getLastArg(options::OPT_openacc_macro_override))

4341 }

4342

4343

4346 Opts.Optimize = Opt != 0;

4347 Opts.OptimizeSize = OptSize != 0;

4348

4349

4350

4351

4352 Opts.NoInlineDefine = !Opts.Optimize;

4353 if (Arg *InlineArg = Args.getLastArg(

4354 options::OPT_finline_functions, options::OPT_finline_hint_functions,

4355 options::OPT_fno_inline_functions, options::OPT_fno_inline))

4356 if (InlineArg->getOption().matches(options::OPT_fno_inline))

4357 Opts.NoInlineDefine = true;

4358

4359 if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {

4360 StringRef Val = A->getValue();

4361 if (Val == "fast")

4363 else if (Val == "on")

4365 else if (Val == "off")

4367 else if (Val == "fast-honor-pragmas")

4369 else

4370 Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;

4371 }

4372

4373 if (auto *A =

4374 Args.getLastArg(OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {

4375 for (int i = 0, n = A->getNumValues(); i != n; ++i) {

4377 llvm::StringSwitch(A->getValue(i))

4380 .Case("add-unsigned-overflow-test",

4382 .Case("add-signed-overflow-test",

4385 .Case("unsigned-post-decr-while",

4387 .Default(0);

4388 }

4389 }

4390

4391

4392 parseSanitizerKinds("-fsanitize=", Args.getAllArgValues(OPT_fsanitize_EQ),

4394 Opts.NoSanitizeFiles = Args.getAllArgValues(OPT_fsanitize_ignorelist_EQ);

4395 std::vectorstd::string systemIgnorelists =

4396 Args.getAllArgValues(OPT_fsanitize_system_ignorelist_EQ);

4398 systemIgnorelists.begin(),

4399 systemIgnorelists.end());

4400

4401 if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {

4403

4404 StringRef Ver = A->getValue();

4405 std::pair<StringRef, StringRef> VerParts = Ver.split('.');

4406 unsigned Major, Minor = 0;

4407

4408

4409

4410 if (!VerParts.first.starts_with("0") &&

4411 !VerParts.first.getAsInteger(10, Major) && 3 <= Major &&

4412 Major <= CLANG_VERSION_MAJOR &&

4413 (Major == 3

4414 ? VerParts.second.size() == 1 &&

4415 !VerParts.second.getAsInteger(10, Minor)

4416 : VerParts.first.size() == Ver.size() || VerParts.second == "0")) {

4417

4418 if (Major == 3 && Minor <= 8)

4420 else if (Major <= 4)

4422 else if (Major <= 6)

4424 else if (Major <= 7)

4426 else if (Major <= 9)

4428 else if (Major <= 11)

4430 else if (Major <= 12)

4432 else if (Major <= 14)

4434 else if (Major <= 15)

4436 else if (Major <= 17)

4438 else if (Major <= 18)

4440 else if (Major <= 19)

4442 } else if (Ver != "latest") {

4443 Diags.Report(diag::err_drv_invalid_value)

4444 << A->getAsString(Args) << A->getValue();

4445 }

4446 }

4447

4448 if (Arg *A = Args.getLastArg(OPT_msign_return_address_EQ)) {

4449 StringRef SignScope = A->getValue();

4450

4451 if (SignScope.equals_insensitive("none"))

4452 Opts.setSignReturnAddressScope(

4454 else if (SignScope.equals_insensitive("all"))

4455 Opts.setSignReturnAddressScope(

4457 else if (SignScope.equals_insensitive("non-leaf"))

4458 Opts.setSignReturnAddressScope(

4460 else

4461 Diags.Report(diag::err_drv_invalid_value)

4462 << A->getAsString(Args) << SignScope;

4463

4464 if (Arg *A = Args.getLastArg(OPT_msign_return_address_key_EQ)) {

4465 StringRef SignKey = A->getValue();

4466 if (!SignScope.empty() && !SignKey.empty()) {

4467 if (SignKey == "a_key")

4468 Opts.setSignReturnAddressKey(

4470 else if (SignKey == "b_key")

4471 Opts.setSignReturnAddressKey(

4473 else

4474 Diags.Report(diag::err_drv_invalid_value)

4475 << A->getAsString(Args) << SignKey;

4476 }

4477 }

4478 }

4479

4480

4481 StringRef CXXABI = Args.getLastArgValue(OPT_fcxx_abi_EQ);

4482 if (CXXABI.empty()) {

4484 Diags.Report(diag::err_invalid_cxx_abi) << CXXABI;

4485 } else {

4488 Diags.Report(diag::err_unsupported_cxx_abi) << CXXABI << T.str();

4489 else

4491 }

4492 }

4493

4494 Opts.RelativeCXXABIVTables =

4495 Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,

4496 options::OPT_fno_experimental_relative_cxx_abi_vtables,

4498

4499

4500 bool HasRTTI = !Args.hasArg(options::OPT_fno_rtti);

4501 Opts.OmitVTableRTTI =

4502 Args.hasFlag(options::OPT_fexperimental_omit_vtable_rtti,

4503 options::OPT_fno_experimental_omit_vtable_rtti, false);

4504 if (Opts.OmitVTableRTTI && HasRTTI)

4505 Diags.Report(diag::err_drv_using_omit_rtti_component_without_no_rtti);

4506

4507 for (const auto &A : Args.getAllArgValues(OPT_fmacro_prefix_map_EQ)) {

4508 auto Split = StringRef(A).split('=');

4510 {std::string(Split.first), std::string(Split.second)});

4511 }

4512

4514 !Args.getLastArg(OPT_fno_file_reproducible) &&

4515 (Args.getLastArg(OPT_ffile_compilation_dir_EQ) ||

4516 Args.getLastArg(OPT_fmacro_prefix_map_EQ) ||

4517 Args.getLastArg(OPT_ffile_reproducible));

4518

4519

4520 if (Arg *A = Args.getLastArg(options::OPT_mvscale_min_EQ)) {

4521 unsigned VScaleMin;

4522 if (StringRef(A->getValue()).getAsInteger(10, VScaleMin) || VScaleMin == 0)

4523 Diags.Report(diag::err_cc1_unbounded_vscale_min);

4524 }

4525

4526 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_file_EQ)) {

4527 std::ifstream SeedFile(A->getValue(0));

4528

4529 if (!SeedFile.is_open())

4530 Diags.Report(diag::err_drv_cannot_open_randomize_layout_seed_file)

4531 << A->getValue(0);

4532

4534 }

4535

4536 if (const Arg *A = Args.getLastArg(OPT_frandomize_layout_seed_EQ))

4538

4539

4540 if (Opts.HLSL) {

4541

4542

4543 if (T.isDXIL() || T.isSPIRVLogical()) {

4544 enum { ShaderModel, VulkanEnv, ShaderStage };

4545 enum { OS, Environment };

4546

4547 int ExpectedOS = T.isSPIRVLogical() ? VulkanEnv : ShaderModel;

4548

4549 if (T.getOSName().empty()) {

4550 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)

4551 << ExpectedOS << OS << T.str();

4552 } else if (T.getEnvironmentName().empty()) {

4553 Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)

4555 } else if (T.isShaderStageEnvironment()) {

4556 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)

4557 << ShaderStage << T.getEnvironmentName() << T.str();

4558 }

4559

4560 if (T.isDXIL()) {

4561 if (T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {

4562 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)

4563 << ShaderModel << T.getOSName() << T.str();

4564 }

4565

4566

4567

4568 if (Args.getLastArg(OPT_fnative_half_type)) {

4571 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018 &&

4572 T.getOSVersion() >= VersionTuple(6, 2)))

4573 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)

4574 << "-enable-16bit-types" << true << Std.getName()

4575 << T.getOSVersion().getAsString();

4576 }

4577 } else if (T.isSPIRVLogical()) {

4578 if (T.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) {

4579 Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)

4580 << VulkanEnv << T.getOSName() << T.str();

4581 }

4582 if (Args.getLastArg(OPT_fnative_half_type)) {

4585 if (!(Opts.LangStd >= LangStandard::lang_hlsl2018))

4586 Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)

4587 << "-fnative-half-type" << false << Std.getName();

4588 }

4589 } else {

4590 llvm_unreachable("expected DXIL or SPIR-V target");

4591 }

4592 } else

4593 Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();

4594

4595 if (Opts.LangStd < LangStandard::lang_hlsl202x) {

4600 Diags.Report(diag::warn_hlsl_langstd_minimal)

4602 }

4603 }

4604

4605 return Diags.getNumErrors() == NumErrorsBefore;

4606}

4607

4639 return false;

4640

4650 return true;

4651 }

4652 llvm_unreachable("invalid frontend action");

4653}

4654

4661

4662#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \

4663 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

4664#include "clang/Driver/Options.inc"

4665#undef PREPROCESSOR_OPTION_WITH_MARSHALLING

4666

4668 GenerateArg(Consumer, OPT_pch_through_hdrstop_use);

4669

4671 GenerateArg(Consumer, OPT_error_on_deserialized_pch_decl, D);

4672

4674 GenerateArg(Consumer, OPT_preamble_bytes_EQ,

4677

4678 for (const auto &M : Opts.Macros) {

4679

4680

4681 if (M.first == "__CET__=1" && !M.second &&

4682 !CodeGenOpts.CFProtectionReturn && CodeGenOpts.CFProtectionBranch)

4683 continue;

4684 if (M.first == "__CET__=2" && !M.second && CodeGenOpts.CFProtectionReturn &&

4685 !CodeGenOpts.CFProtectionBranch)

4686 continue;

4687 if (M.first == "__CET__=3" && !M.second && CodeGenOpts.CFProtectionReturn &&

4688 CodeGenOpts.CFProtectionBranch)

4689 continue;

4690

4691 GenerateArg(Consumer, M.second ? OPT_U : OPT_D, M.first);

4692 }

4693

4694 for (const auto &I : Opts.Includes) {

4695

4696

4697 if (LangOpts.OpenCL && LangOpts.IncludeDefaultHeader &&

4698 ((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") ||

4699 I == "opencl-c.h"))

4700 continue;

4701

4702

4703 if (LangOpts.HLSL && I == "hlsl.h")

4704 continue;

4705

4707 }

4708

4710 GenerateArg(Consumer, OPT_chain_include, CI);

4711

4713 GenerateArg(Consumer, OPT_remap_file, RF.first + ";" + RF.second);

4714

4717

4719 GenerateArg(Consumer, OPT_fdefine_target_os_macros);

4720

4721 for (const auto &EmbedEntry : Opts.EmbedEntries)

4722 GenerateArg(Consumer, OPT_embed_dir_EQ, EmbedEntry);

4723

4724

4725

4726}

4727

4732 unsigned NumErrorsBefore = Diags.getNumErrors();

4733

4735

4736#define PREPROCESSOR_OPTION_WITH_MARSHALLING(...) \

4737 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

4738#include "clang/Driver/Options.inc"

4739#undef PREPROCESSOR_OPTION_WITH_MARSHALLING

4740

4741 Opts.PCHWithHdrStop = Args.hasArg(OPT_pch_through_hdrstop_create) ||

4742 Args.hasArg(OPT_pch_through_hdrstop_use);

4743

4744 for (const auto *A : Args.filtered(OPT_error_on_deserialized_pch_decl))

4746

4747 if (const Arg *A = Args.getLastArg(OPT_preamble_bytes_EQ)) {

4748 StringRef Value(A->getValue());

4749 size_t Comma = Value.find(',');

4750 unsigned Bytes = 0;

4751 unsigned EndOfLine = 0;

4752

4753 if (Comma == StringRef::npos ||

4754 Value.substr(0, Comma).getAsInteger(10, Bytes) ||

4755 Value.substr(Comma + 1).getAsInteger(10, EndOfLine))

4756 Diags.Report(diag::err_drv_preamble_format);

4757 else {

4760 }

4761 }

4762

4763

4764 if (const Arg *A = Args.getLastArg(OPT_fcf_protection_EQ)) {

4765 StringRef Name = A->getValue();

4766 if (Name == "branch")

4768 else if (Name == "return")

4770 else if (Name == "full")

4772 }

4773

4774

4775 for (const auto *A : Args.filtered(OPT_D, OPT_U)) {

4776 if (A->getOption().matches(OPT_D))

4778 else

4780 }

4781

4782

4783 for (const auto *A : Args.filtered(OPT_include))

4784 Opts.Includes.emplace_back(A->getValue());

4785

4786 for (const auto *A : Args.filtered(OPT_chain_include))

4788

4789 for (const auto *A : Args.filtered(OPT_remap_file)) {

4790 std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';');

4791

4792 if (Split.second.empty()) {

4793 Diags.Report(diag::err_drv_invalid_remap_file) << A->getAsString(Args);

4794 continue;

4795 }

4796

4798 }

4799

4800 if (const Arg *A = Args.getLastArg(OPT_source_date_epoch)) {

4801 StringRef Epoch = A->getValue();

4802

4803

4804

4805 const uint64_t MaxTimestamp =

4806 std::min<uint64_t>(std::numeric_limits<time_t>::max(), 253402300799);

4807 uint64_t V;

4808 if (Epoch.getAsInteger(10, V) || V > MaxTimestamp) {

4809 Diags.Report(diag::err_fe_invalid_source_date_epoch)

4810 << Epoch << MaxTimestamp;

4811 } else {

4813 }

4814 }

4815

4816 for (const auto *A : Args.filtered(OPT_embed_dir_EQ)) {

4817 StringRef Val = A->getValue();

4818 Opts.EmbedEntries.push_back(std::string(Val));

4819 }

4820

4821

4822

4823

4826

4828 Args.hasFlag(OPT_fdefine_target_os_macros,

4830

4831 return Diags.getNumErrors() == NumErrorsBefore;

4832}

4833

4834static void

4839

4840#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \

4841 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

4842#include "clang/Driver/Options.inc"

4843#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING

4844

4846 if (Generate_dM)

4848 if (!Generate_dM && Opts.ShowMacros)

4851 GenerateArg(Consumer, OPT_fdirectives_only);

4852}

4853

4857 unsigned NumErrorsBefore = Diags.getNumErrors();

4858

4860

4861#define PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING(...) \

4862 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

4863#include "clang/Driver/Options.inc"

4864#undef PREPROCESSOR_OUTPUT_OPTION_WITH_MARSHALLING

4865

4867 Opts.ShowMacros = Args.hasArg(OPT_dM) || Args.hasArg(OPT_dD);

4868 Opts.DirectivesOnly = Args.hasArg(OPT_fdirectives_only);

4869

4870 return Diags.getNumErrors() == NumErrorsBefore;

4871}

4872

4876#define TARGET_OPTION_WITH_MARSHALLING(...) \

4877 GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)

4878#include "clang/Driver/Options.inc"

4879#undef TARGET_OPTION_WITH_MARSHALLING

4880

4882 GenerateArg(Consumer, OPT_target_sdk_version_EQ,

4885 GenerateArg(Consumer, OPT_darwin_target_variant_sdk_version_EQ,

4887}

4888

4891 unsigned NumErrorsBefore = Diags.getNumErrors();

4892

4894

4895#define TARGET_OPTION_WITH_MARSHALLING(...) \

4896 PARSE_OPTION_WITH_MARSHALLING(Args, Diags, __VA_ARGS__)

4897#include "clang/Driver/Options.inc"

4898#undef TARGET_OPTION_WITH_MARSHALLING

4899

4900 if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version_EQ)) {

4901 llvm::VersionTuple Version;

4902 if (Version.tryParse(A->getValue()))

4903 Diags.Report(diag::err_drv_invalid_value)

4904 << A->getAsString(Args) << A->getValue();

4905 else

4907 }

4908 if (Arg *A =

4909 Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {

4910 llvm::VersionTuple Version;

4911 if (Version.tryParse(A->getValue()))

4912 Diags.Report(diag::err_drv_invalid_value)

4913 << A->getAsString(Args) << A->getValue();

4914 else

4916 }

4917

4918 return Diags.getNumErrors() == NumErrorsBefore;

4919}

4920

4921bool CompilerInvocation::CreateFromArgsImpl(

4924 unsigned NumErrorsBefore = Diags.getNumErrors();

4925

4926

4929 unsigned MissingArgIndex, MissingArgCount;

4930 InputArgList Args = Opts.ParseArgs(CommandLineArgs, MissingArgIndex,

4931 MissingArgCount, VisibilityMask);

4933

4934

4935 if (MissingArgCount)

4936 Diags.Report(diag::err_drv_missing_argument)

4937 << Args.getArgString(MissingArgIndex) << MissingArgCount;

4938

4939

4940 for (const auto *A : Args.filtered(OPT_UNKNOWN)) {

4941 auto ArgString = A->getAsString(Args);

4942 std::string Nearest;

4943 if (Opts.findNearest(ArgString, Nearest, VisibilityMask) > 1)

4944 Diags.Report(diag::err_drv_unknown_argument) << ArgString;

4945 else

4946 Diags.Report(diag::err_drv_unknown_argument_with_suggestion)

4947 << ArgString << Nearest;

4948 }

4949

4954 false);

4956

4963

4965

4967 Diags);

4969 LangOpts.ObjCExceptions = 1;

4970

4972 if (Warning == "misexpect" &&

4975 }

4976 }

4977

4979

4980

4983 }

4984

4985

4986 if (LangOpts.OpenMPIsTargetDevice)

4988

4989 ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,

4991

4992

4993

4994

4996 LangOpts.Sanitize.has(SanitizerKind::Address) &&

4997 LangOpts.Sanitize.has(SanitizerKind::KernelAddress) &&

4998 LangOpts.Sanitize.has(SanitizerKind::Memory) &&

4999 LangOpts.Sanitize.has(SanitizerKind::KernelMemory);

5000

5006

5012 Diags.Report(diag::err_fe_dependency_file_requires_MT);

5013

5014

5015 if (Res.getCodeGenOpts().FineGrainedBitfieldAccesses &&

5017 Res.getCodeGenOpts().FineGrainedBitfieldAccesses = false;

5018 Diags.Report(diag::warn_drv_fine_grained_bitfield_accesses_ignored);

5019 }

5020

5021

5025 }

5026

5027

5028

5030 auto FS =

5032 Diags, llvm::vfs::getRealFileSystem());

5035 Diags);

5036 }

5037

5039

5040 return Diags.getNumErrors() == NumErrorsBefore;

5041}

5042

5046 const char *Argv0) {

5048

5052 return CreateFromArgsImpl(Invocation, CommandLineArgs, Diags, Argv0);

5053 },

5056 Args.push_back("-cc1");

5058 },

5059 Invocation, DummyInvocation, CommandLineArgs, Diags, Argv0);

5060}

5061

5063

5064 llvm::HashBuilder<llvm::MD5, llvm::endianness::native> HBuilder;

5065

5066

5067

5068

5069

5071

5072

5073

5075

5076

5077#define LANGOPT(Name, Bits, Default, Description) HBuilder.add(LangOpts->Name);

5078#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \

5079 HBuilder.add(static_cast(LangOpts->get##Name()));

5080#define BENIGN_LANGOPT(Name, Bits, Default, Description)

5081#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)

5082#include "clang/Basic/LangOptions.def"

5083

5084 HBuilder.addRange(getLangOpts().ModuleFeatures);

5085

5087 HBuilder.addRange(getLangOpts().CommentOpts.BlockCommandNames);

5088

5089

5092 HBuilder.addRange(getTargetOpts().FeaturesAsWritten);

5093

5094

5097

5100

5101

5103

5104 StringRef MacroDef = Macro.first;

5106 llvm::CachedHashString(MacroDef.split('=').first)))

5107 continue;

5108 }

5109

5110 HBuilder.add(Macro);

5111 }

5112

5113

5119

5124

5126#define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name);

5127#define ENUM_DIAGOPT(Name, Type, Bits, Default) \

5128 HBuilder.add(diagOpts.get##Name());

5129#include "clang/Basic/DiagnosticOptions.def"

5130#undef DIAGOPT

5131#undef ENUM_DIAGOPT

5132 }

5133

5134

5136

5137

5138 for (const auto &ext : getFrontendOpts().ModuleFileExtensions)

5139 ext->hashExtension(HBuilder);

5140

5141

5144 HBuilder.add(APINotesOpts.SwiftVersion.getMajor());

5145 if (auto Minor = APINotesOpts.SwiftVersion.getMinor())

5146 HBuilder.add(*Minor);

5147 if (auto Subminor = APINotesOpts.SwiftVersion.getSubminor())

5148 HBuilder.add(*Subminor);

5149 if (auto Build = APINotesOpts.SwiftVersion.getBuild())

5150 HBuilder.add(*Build);

5151 }

5152

5153

5154

5157

5158

5160#define DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);

5161#define VALUE_DEBUGOPT(Name, Bits, Default) HBuilder.add(CodeGenOpts->Name);

5162#define ENUM_DEBUGOPT(Name, Type, Bits, Default) \

5163 HBuilder.add(static_cast(CodeGenOpts->get##Name()));

5164#define BENIGN_DEBUGOPT(Name, Bits, Default)

5165#define BENIGN_VALUE_DEBUGOPT(Name, Bits, Default)

5166#define BENIGN_ENUM_DEBUGOPT(Name, Type, Bits, Default)

5167#include "clang/Basic/DebugOptions.def"

5168 }

5169

5170

5171

5174 if (!SanHash.empty())

5175 HBuilder.add(SanHash.Mask);

5176

5177 llvm::MD5::MD5Result Result;

5178 HBuilder.getHasher().final(Result);

5179 uint64_t Hash = Result.high() ^ Result.low();

5180 return toString(llvm::APInt(64, Hash), 36, false);

5181}

5182

5186

5191 false);

5205}

5206

5208 std::vectorstd::string Args{"-cc1"};

5210 [&Args](const Twine &Arg) { Args.push_back(Arg.str()); });

5211 return Args;

5212}

5213

5218}

5219

5226

5227

5230}

5231

5236 llvm::vfs::getRealFileSystem());

5237}

5238

5244 Diags, std::move(BaseFS));

5245}

5246

5250 if (VFSOverlayFiles.empty())

5251 return BaseFS;

5252

5254

5255 for (const auto &File : VFSOverlayFiles) {

5256 llvm::ErrorOr<std::unique_ptrllvm::MemoryBuffer> Buffer =

5258 if (!Buffer) {

5259 Diags.Report(diag::err_missing_vfs_overlay_file) << File;

5260 continue;

5261 }

5262

5264 std::move(Buffer.get()), nullptr, File,

5265 nullptr, Result);

5266 if (!FS) {

5267 Diags.Report(diag::err_invalid_vfs_overlay) << File;

5268 continue;

5269 }

5270

5272 }

5274}

Defines the Diagnostic-related interfaces.

Defines enum values for all the target-independent builtin functions.

static void getAllNoBuiltinFuncValues(ArgList &Args, std::vector< std::string > &Funcs)

static T extractMaskValue(T KeyPath)

static std::optional< IntTy > normalizeStringIntegral(OptSpecifier Opt, int, const ArgList &Args, DiagnosticsEngine &Diags)

static T mergeMaskValue(T KeyPath, U Value)

static std::optional< std::string > normalizeString(OptSpecifier Opt, int TableIndex, const ArgList &Args, DiagnosticsEngine &Diags)

static auto makeBooleanOptionNormalizer(bool Value, bool OtherValue, OptSpecifier OtherOpt)

static void parsePointerAuthOptions(PointerAuthOptions &Opts, const LangOptions &LangOpts, const llvm::Triple &Triple, DiagnosticsEngine &Diags)

static void denormalizeString(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, T Value)

static SmallVector< StringRef, 4 > serializeSanitizerKinds(SanitizerSet S)

static void parseXRayInstrumentationBundle(StringRef FlagName, StringRef Bundle, ArgList &Args, DiagnosticsEngine &D, XRayInstrSet &S)

static unsigned getOptimizationLevelSize(ArgList &Args)

static void GenerateFrontendArgs(const FrontendOptions &Opts, ArgumentConsumer Consumer, bool IsHeader)

static std::optional< SimpleEnumValue > findValueTableByValue(const SimpleEnumValueTable &Table, unsigned Value)

static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags)

static auto makeFlagToValueNormalizer(T Value)

static CodeGenOptions::OptRemark ParseOptimizationRemark(DiagnosticsEngine &Diags, ArgList &Args, OptSpecifier OptEQ, StringRef Name)

Parse a remark command line argument.

static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args, DiagnosticsEngine &Diags)

static constexpr bool is_uint64_t_convertible()

static void GeneratePointerAuthArgs(const LangOptions &Opts, ArgumentConsumer Consumer)

static std::optional< SimpleEnumValue > findValueTableByName(const SimpleEnumValueTable &Table, StringRef Name)

static std::optional< OptSpecifier > getProgramActionOpt(frontend::ActionKind ProgramAction)

Maps frontend action to command line option.

static bool parseDiagnosticLevelMask(StringRef FlagName, const std::vector< std::string > &Levels, DiagnosticsEngine &Diags, DiagnosticLevelMask &M)

static std::optional< bool > normalizeSimpleFlag(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, DiagnosticsEngine &Diags)

CompilerInvocation::ArgumentConsumer ArgumentConsumer

static void denormalizeSimpleEnumImpl(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, unsigned Value)

static void GenerateArg(ArgumentConsumer Consumer, llvm::opt::OptSpecifier OptSpecifier)

static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group, OptSpecifier GroupWithValue, std::vector< std::string > &Diagnostics)

static bool ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags)

static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags)

static void parseAnalyzerConfigs(AnalyzerOptions &AnOpts, DiagnosticsEngine *Diags)

static void denormalizeSimpleFlag(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass, unsigned,...)

The tblgen-erated code passes in a fifth parameter of an arbitrary type, but denormalizeSimpleFlags n...

static bool ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action, const FrontendOptions &FrontendOpts)

static std::optional< unsigned > normalizeSimpleEnum(OptSpecifier Opt, unsigned TableIndex, const ArgList &Args, DiagnosticsEngine &Diags)

static StringRef GetInputKindName(InputKind IK)

Get language name for given input kind.

static void initOption(AnalyzerOptions::ConfigTable &Config, DiagnosticsEngine *Diags, StringRef &OptionField, StringRef Name, StringRef DefaultVal)

static std::optional< std::string > normalizeTriple(OptSpecifier Opt, int TableIndex, const ArgList &Args, DiagnosticsEngine &Diags)

llvm::function_ref< bool(CompilerInvocation &, ArrayRef< const char * >, DiagnosticsEngine &, const char *)> ParseFn

llvm::function_ref< void(CompilerInvocation &, SmallVectorImpl< const char * > &, CompilerInvocation::StringAllocator)> GenerateFn

static void GenerateMigratorArgs(const MigratorOptions &Opts, ArgumentConsumer Consumer)

static const auto & getFrontendActionTable()

Return a table that associates command line option specifiers with the frontend action.

static void GenerateTargetArgs(const TargetOptions &Opts, ArgumentConsumer Consumer)

static std::optional< frontend::ActionKind > getFrontendAction(OptSpecifier &Opt)

Maps command line option to frontend action.

static bool checkVerifyPrefixes(const std::vector< std::string > &VerifyPrefixes, DiagnosticsEngine &Diags)

static SanitizerMaskCutoffs parseSanitizerWeightedKinds(StringRef FlagName, const std::vector< std::string > &Sanitizers, DiagnosticsEngine &Diags)

static void GenerateAPINotesArgs(const APINotesOptions &Opts, ArgumentConsumer Consumer)

static std::optional< bool > normalizeSimpleNegativeFlag(OptSpecifier Opt, unsigned, const ArgList &Args, DiagnosticsEngine &)

static void GenerateFileSystemArgs(const FileSystemOptions &Opts, ArgumentConsumer Consumer)

static bool IsInputCompatibleWithStandard(InputKind IK, const LangStandard &S)

Check if input file kind and language standard are compatible.

static void denormalizeStringImpl(ArgumentConsumer Consumer, const Twine &Spelling, Option::OptionClass OptClass, unsigned, const Twine &Value)

static void setPGOUseInstrumentor(CodeGenOptions &Opts, const Twine &ProfileName, llvm::vfs::FileSystem &FS, DiagnosticsEngine &Diags)

static llvm::StringRef lookupStrInTable(unsigned Offset)

static void GeneratePreprocessorArgs(const PreprocessorOptions &Opts, ArgumentConsumer Consumer, const LangOptions &LangOpts, const FrontendOptions &FrontendOpts, const CodeGenOptions &CodeGenOpts)

static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, const std::string &WorkingDir)

static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, bool &IsHeaderFile)

static auto makeBooleanOptionDenormalizer(bool Value)

static void GeneratePreprocessorOutputArgs(const PreprocessorOutputOptions &Opts, ArgumentConsumer Consumer, frontend::ActionKind Action)

static bool isStrictlyPreprocessorAction(frontend::ActionKind Action)

static std::string serializeXRayInstrumentationBundle(const XRayInstrSet &S)

static bool ParseMigratorArgs(MigratorOptions &Opts, const ArgList &Args, DiagnosticsEngine &Diags)

static bool parseShowColorsArgs(const ArgList &Args, bool DefaultColor)

static T mergeForwardValue(T KeyPath, U Value)

static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args, DiagnosticsEngine &diags)

static void denormalizeStringVector(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, const std::vector< std::string > &Values)

static bool ParseDependencyOutputArgs(DependencyOutputOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action, bool ShowLineMarkers)

static Expected< std::optional< uint32_t > > parseToleranceOption(StringRef Arg)

static std::optional< std::vector< std::string > > normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args, DiagnosticsEngine &)

static void GenerateAnalyzerArgs(const AnalyzerOptions &Opts, ArgumentConsumer Consumer)

static void GenerateOptimizationRemark(ArgumentConsumer Consumer, OptSpecifier OptEQ, StringRef Name, const CodeGenOptions::OptRemark &Remark)

Generate a remark argument. This is an inverse of ParseOptimizationRemark.

static bool ParsePreprocessorOutputArgs(PreprocessorOutputOptions &Opts, ArgList &Args, DiagnosticsEngine &Diags, frontend::ActionKind Action)

static bool RoundTrip(ParseFn Parse, GenerateFn Generate, CompilerInvocation &RealInvocation, CompilerInvocation &DummyInvocation, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0, bool CheckAgainstOriginalInvocation=false, bool ForceRoundTrip=false)

May perform round-trip of command line arguments.

static T extractForwardValue(T KeyPath)

static void denormalizeSimpleEnum(ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, T Value)

static unsigned getOptimizationLevel(ArgList &Args, InputKind IK, DiagnosticsEngine &Diags)

static bool parseTestModuleFileExtensionArg(StringRef Arg, std::string &BlockName, unsigned &MajorVersion, unsigned &MinorVersion, bool &Hashed, std::string &UserInfo)

Parse the argument to the -ftest-module-file-extension command-line argument.

static void GenerateDependencyOutputArgs(const DependencyOutputOptions &Opts, ArgumentConsumer Consumer)

static StringRef getStringOption(AnalyzerOptions::ConfigTable &Config, StringRef OptionName, StringRef DefaultVal)

static bool FixupInvocation(CompilerInvocation &Invocation, DiagnosticsEngine &Diags, const ArgList &Args, InputKind IK)

static void parseSanitizerKinds(StringRef FlagName, const std::vector< std::string > &Sanitizers, DiagnosticsEngine &Diags, SanitizerSet &S)

static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts, ArgumentConsumer Consumer)

Defines the clang::FileSystemOptions interface.

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::LangOptions interface.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

Defines types useful for describing an Objective-C runtime.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

Defines the clang::SanitizerKind enum.

Defines the clang::SourceLocation class and associated facilities.

Defines the clang::TargetOptions class.

Defines version macros and version-related utility functions for Clang.

Defines the clang::Visibility enumeration and various utility functions.

Defines the clang::XRayInstrKind enum.

__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)

Tracks various options which control how API notes are found and handled.

llvm::VersionTuple SwiftVersion

The Swift version which should be used for API notes.

std::vector< std::string > ModuleSearchPaths

The set of search paths where we API notes can be found for particular modules.

Stores options for the analyzer from the command line.

static std::vector< StringRef > getRegisteredPackages(bool IncludeExperimental=false)

Retrieves the list of packages generated from Checkers.td.

std::vector< std::pair< std::string, bool > > CheckersAndPackages

Pairs of checker/package name and enable/disable.

std::vector< std::string > SilencedCheckersAndPackages

Vector of checker/package names which will not emit warnings.

AnalysisDiagClients AnalysisDiagOpt

AnalysisConstraints AnalysisConstraintsOpt

ConfigTable Config

A key-value table of use-specified configuration values.

unsigned ShouldEmitErrorsOnInvalidConfigValue

AnalysisPurgeMode AnalysisPurgeOpt

bool isUnknownAnalyzerConfig(llvm::StringRef Name)

static std::vector< StringRef > getRegisteredCheckers(bool IncludeExperimental=false)

Retrieves the list of checkers generated from Checkers.td.

llvm::StringMap< std::string > ConfigTable

std::string FullCompilerInvocation

Store full compiler invocation for reproducible instructions in the generated report.

AnalysisInliningMode InliningMode

The mode of function selection used during inlining.

static bool isBuiltinFunc(llvm::StringRef Name)

Returns true if this is a libc/libm function without the '__builtin_' prefix.

Implements C++ ABI-specific semantic analysis functions.

CodeGenOptions - Track various options which control how the code is optimized and passed to the back...

llvm::SmallVector< std::pair< std::string, std::string >, 0 > CoveragePrefixMap

Prefix replacement map for source-based code coverage to remap source file paths in coverage mapping.

SanitizerSet SanitizeMergeHandlers

Set of sanitizer checks that can merge handlers (smaller code size at the expense of debuggability).

llvm::SmallVector< std::pair< std::string, std::string >, 0 > DebugPrefixMap

std::string OptRecordFile

The name of the file to which the backend should save YAML optimization records.

std::string BinutilsVersion

std::vector< BitcodeFileToLink > LinkBitcodeFiles

The files specified here are linked in to the module before optimizations.

std::optional< uint64_t > DiagnosticsHotnessThreshold

The minimum hotness value a diagnostic needs in order to be included in optimization diagnostics.

char CoverageVersion[4]

The version string to put into coverage files.

llvm::DenormalMode FPDenormalMode

The floating-point denormal mode to use.

std::string CoverageNotesFile

The filename with path we use for coverage notes files.

std::string ProfileInstrumentUsePath

Name of the profile file to use as input for -fprofile-instr-use.

std::string SampleProfileFile

Name of the profile file to use with -fprofile-sample-use.

uint64_t LargeDataThreshold

The code model-specific large data threshold to use (-mlarge-data-threshold).

std::string MemoryProfileOutput

Name of the profile file to use as output for with -fmemory-profile.

std::string CodeModel

The code model to use (-mcmodel).

std::string CoverageDataFile

The filename with path we use for coverage data files.

std::optional< uint32_t > DiagnosticsMisExpectTolerance

The maximum percentage profiling weights can deviate from the expected values in order to be included...

std::string StackUsageOutput

Name of the stack usage file (i.e., .su file) if user passes -fstack-usage.

std::string OptRecordPasses

The regex that filters the passes that should be saved to the optimization records.

std::string SaveTempsFilePrefix

Prefix to use for -save-temps output.

XRayInstrSet XRayInstrumentationBundle

Set of XRay instrumentation kinds to emit.

bool hasSanitizeCoverage() const

PointerAuthOptions PointerAuth

Configuration for pointer-signing.

llvm::DenormalMode FP32DenormalMode

The floating-point denormal mode to use, for float.

SanitizerSet SanitizeTrap

Set of sanitizer checks that trap rather than diagnose.

SanitizerSet SanitizeRecover

Set of sanitizer checks that are non-fatal (i.e.

bool hasReducedDebugInfo() const

Check if type and variable info should be emitted.

OptRemark OptimizationRemark

Selected optimizations for which we should enable optimization remarks.

std::string ThinLTOIndexFile

Name of the function summary index file to use for ThinLTO function importing.

const char * Argv0

Executable and command-line used to create a given CompilerInvocation.

SanitizerMaskCutoffs SanitizeSkipHotCutoffs

Set of thresholds in a range [0.0, 1.0]: the top hottest code responsible for the given fraction of P...

std::vector< std::string > NoBuiltinFuncs

A list of all -fno-builtin-* function names (e.g., memset).

std::vector< uint8_t > CmdArgs

List of backend command-line options for -fembed-bitcode.

OptRemark OptimizationRemarkAnalysis

Selected optimizations for which we should enable optimization analyses.

std::vector< std::string > CommandLineArgs

void resetNonModularOptions(StringRef ModuleFormat)

Reset all of the options that are not considered when building a module.

std::string OptRecordFormat

The format used for serializing remarks (default: YAML)

std::string DIBugsReportFilePath

The file to use for dumping bug report by Debugify for original debug info.

OptRemark OptimizationRemarkMissed

Selected optimizations for which we should enable missed optimization remarks.

The base class of CompilerInvocation.

std::shared_ptr< MigratorOptions > MigratorOpts

std::shared_ptr< PreprocessorOutputOptions > PreprocessorOutputOpts

Options controlling preprocessed output.

std::shared_ptr< APINotesOptions > APINotesOpts

Options controlling API notes.

std::shared_ptr< TargetOptions > TargetOpts

Options controlling the target.

const FrontendOptions & getFrontendOpts() const

const CodeGenOptions & getCodeGenOpts() const

llvm::function_ref< const char *(const Twine &)> StringAllocator

Command line generation.

const FileSystemOptions & getFileSystemOpts() const

std::shared_ptr< PreprocessorOptions > PPOpts

Options controlling the preprocessor (aside from #include handling).

const PreprocessorOutputOptions & getPreprocessorOutputOpts() const

std::vector< std::string > getCC1CommandLine() const

Generate cc1-compatible command line arguments from this instance, wrapping the result as a std::vect...

std::shared_ptr< FileSystemOptions > FSOpts

Options controlling file system operations.

const AnalyzerOptions & getAnalyzerOpts() const

const MigratorOptions & getMigratorOpts() const

void generateCC1CommandLine(llvm::SmallVectorImpl< const char * > &Args, StringAllocator SA) const

Generate cc1-compatible command line arguments from this instance.

CompilerInvocationBase & deep_copy_assign(const CompilerInvocationBase &X)

const DependencyOutputOptions & getDependencyOutputOpts() const

AnalyzerOptionsRef AnalyzerOpts

Options controlling the static analyzer.

IntrusiveRefCntPtr< DiagnosticOptions > DiagnosticOpts

Options controlling the diagnostic engine.

CompilerInvocationBase & shallow_copy_assign(const CompilerInvocationBase &X)

const TargetOptions & getTargetOpts() const

std::shared_ptr< CodeGenOptions > CodeGenOpts

Options controlling IRgen and the backend.

std::shared_ptr< LangOptions > LangOpts

Options controlling the language variant.

const APINotesOptions & getAPINotesOpts() const

const HeaderSearchOptions & getHeaderSearchOpts() const

std::shared_ptr< HeaderSearchOptions > HSOpts

Options controlling the #include directive.

const PreprocessorOptions & getPreprocessorOpts() const

const DiagnosticOptions & getDiagnosticOpts() const

const LangOptions & getLangOpts() const

Const getters.

std::shared_ptr< FrontendOptions > FrontendOpts

Options controlling the frontend itself.

llvm::function_ref< void(const Twine &)> ArgumentConsumer

std::shared_ptr< DependencyOutputOptions > DependencyOutputOpts

Options controlling dependency output.

Helper class for holding the data necessary to invoke the compiler.

PreprocessorOptions & getPreprocessorOpts()

void clearImplicitModuleBuildOptions()

Disable implicit modules and canonicalize options that are only used by implicit modules.

MigratorOptions & getMigratorOpts()

AnalyzerOptions & getAnalyzerOpts()

APINotesOptions & getAPINotesOpts()

static std::string GetResourcesPath(const char *Argv0, void *MainAddr)

Get the directory where the compiler headers reside, relative to the compiler binary (found by the pa...

static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0=nullptr)

Create a compiler invocation from a list of input options.

LangOptions & getLangOpts()

Mutable getters.

static bool checkCC1RoundTrip(ArrayRef< const char * > Args, DiagnosticsEngine &Diags, const char *Argv0=nullptr)

Check that Args can be parsed and re-serialized without change, emiting diagnostics for any differenc...

DependencyOutputOptions & getDependencyOutputOpts()

CompilerInvocation()=default

void resetNonModularOptions()

Reset all of the options that are not considered when building a module.

FrontendOptions & getFrontendOpts()

std::string getModuleHash() const

Retrieve a module hash string that is suitable for uniquely identifying the conditions under which th...

FileSystemOptions & getFileSystemOpts()

CompilerInvocation & operator=(const CompilerInvocation &X)

static void setDefaultPointerAuthOptions(PointerAuthOptions &Opts, const LangOptions &LangOpts, const llvm::Triple &Triple)

Populate Opts with the default set of pointer authentication-related options given LangOpts and Tripl...

CodeGenOptions & getCodeGenOpts()

std::shared_ptr< LangOptions > LangOpts

Base class internals.

TargetOptions & getTargetOpts()

HeaderSearchOptions & getHeaderSearchOpts()

DiagnosticOptions & getDiagnosticOpts()

PreprocessorOutputOptions & getPreprocessorOutputOpts()

Same as CompilerInvocation, but with copy-on-write optimization.

FrontendOptions & getMutFrontendOpts()

LangOptions & getMutLangOpts()

Mutable getters.

HeaderSearchOptions & getMutHeaderSearchOpts()

MigratorOptions & getMutMigratorOpts()

PreprocessorOptions & getMutPreprocessorOpts()

APINotesOptions & getMutAPINotesOpts()

PreprocessorOutputOptions & getMutPreprocessorOutputOpts()

CodeGenOptions & getMutCodeGenOpts()

TargetOptions & getMutTargetOpts()

FileSystemOptions & getMutFileSystemOpts()

AnalyzerOptions & getMutAnalyzerOpts()

DiagnosticOptions & getMutDiagnosticOpts()

DependencyOutputOptions & getMutDependencyOutputOpts()

DependencyOutputOptions - Options for controlling the compiler dependency file generation.

ShowIncludesDestination ShowIncludesDest

Destination of cl.exe style /showIncludes info.

HeaderIncludeFormatKind HeaderIncludeFormat

The format of header information.

std::string OutputFile

The file to write dependency output to.

HeaderIncludeFilteringKind HeaderIncludeFiltering

Determine whether header information should be filtered.

std::vector< std::string > Targets

A list of names to use as the targets in the dependency file; this list must contain at least one ent...

std::vector< std::pair< std::string, ExtraDepKind > > ExtraDeps

A list of extra dependencies (filename and kind) to be used for every target.

unsigned IncludeSystemHeaders

Include system header dependencies.

Used for handling and querying diagnostic IDs.

Options for controlling the compiler diagnostics engine.

std::string DiagnosticSuppressionMappingsFile

Path for the file that defines diagnostic suppression mappings.

std::vector< std::string > Remarks

The list of -R... options used to alter the diagnostic mappings, with the prefixes removed.

std::vector< std::string > Warnings

The list of -W... options used to alter the diagnostic mappings, with the prefixes removed.

std::vector< std::string > VerifyPrefixes

The prefixes for comment directives sought by -verify ("expected" by default).

std::string DiagnosticSerializationFile

The file to serialize diagnostics to (non-appending).

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

unsigned getCustomDiagID(Level L, const char(&FormatString)[N])

Return an ID for a diagnostic with the specified format string and level.

void setClient(DiagnosticConsumer *client, bool ShouldOwnClient=true)

Set the diagnostic client associated with this diagnostic object.

unsigned getNumErrors() const

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

unsigned getNumWarnings() const

Keeps track of options that affect how file operations are performed.

std::string WorkingDir

If set, paths are resolved as if the working directory was set to the value of WorkingDir.

FrontendOptions - Options for controlling the behavior of the frontend.

InputKind DashX

The input kind, either specified via -x argument or deduced from the input file name.

std::vector< std::string > ModuleFiles

The list of additional prebuilt module files to load before processing the input.

enum clang::FrontendOptions::@202 ARCMTAction

std::map< std::string, std::vector< std::string > > PluginArgs

Args to pass to the plugins.

unsigned IsSystemModule

When using -emit-module, treat the modulemap as a system module.

unsigned UseClangIRPipeline

Use Clang IR pipeline to emit code.

ASTDumpOutputFormat ASTDumpFormat

Specifies the output format of the AST.

std::optional< std::string > AuxTargetCPU

Auxiliary target CPU for CUDA/HIP compilation.

std::string OutputFile

The output file, if any.

unsigned ShowStats

Show frontend performance metrics and statistics.

std::string ActionName

The name of the action to run when using a plugin action.

std::vector< std::shared_ptr< ModuleFileExtension > > ModuleFileExtensions

The list of module file extensions.

ParsedSourceLocation CodeCompletionAt

If given, enable code completion at the provided location.

std::string FixItSuffix

If given, the new suffix for fix-it rewritten files.

static InputKind getInputKindForExtension(StringRef Extension)

getInputKindForExtension - Return the appropriate input kind for a file extension.

std::vector< std::string > Plugins

The list of plugins to load.

unsigned ASTDumpAll

Whether we deserialize all decls when forming AST dumps.

unsigned GenerateGlobalModuleIndex

Whether we can generate the global module index if needed.

unsigned DisableFree

Disable memory freeing on exit.

SmallVector< FrontendInputFile, 0 > Inputs

The input files and their types.

frontend::ActionKind ProgramAction

The frontend action to perform.

std::optional< std::vector< std::string > > AuxTargetFeatures

Auxiliary target features for CUDA/HIP compilation.

std::string AuxTriple

Auxiliary triple for CUDA/HIP compilation.

unsigned UseGlobalModuleIndex

Whether we can use the global module index if available.

unsigned ASTDumpDecls

Whether we include declaration dumps in AST dumps.

A diagnostic client that ignores all diagnostics.

The kind of a file that we've been handed as an input.

bool isPreprocessed() const

InputKind withHeaderUnit(HeaderUnitKind HU) const

bool isUnknown() const

Is the input kind fully-unknown?

InputKind getPreprocessed() const

HeaderUnitKind getHeaderUnitKind() const

InputKind getHeader() const

InputKind withFormat(Format F) const

Language getLanguage() const

@ None

No signing for any function.

@ NonLeaf

Sign the return address of functions that spill LR.

@ All

Sign the return address of all functions,.

@ BKey

Return address signing uses APIB key.

@ AKey

Return address signing uses APIA key.

@ None

Don't exclude any overflow patterns from sanitizers.

@ AddUnsignedOverflowTest

if (a + b < a)

@ All

Exclude all overflow patterns (below)

@ AddSignedOverflowTest

if (a + b < a)

@ PostDecrInWhile

while (count–)

@ Ver6

Attempt to be ABI-compatible with code generated by Clang 6.0.x (SVN r321711).

@ Ver18

Attempt to be ABI-compatible with code generated by Clang 18.0.x.

@ Ver4

Attempt to be ABI-compatible with code generated by Clang 4.0.x (SVN r291814).

@ Ver14

Attempt to be ABI-compatible with code generated by Clang 14.0.x.

@ Ver11

Attempt to be ABI-compatible with code generated by Clang 11.0.x (git 2e10b7a39b93).

@ Ver19

Attempt to be ABI-compatible with code generated by Clang 19.0.x.

@ Ver15

Attempt to be ABI-compatible with code generated by Clang 15.0.x.

@ Ver17

Attempt to be ABI-compatible with code generated by Clang 17.0.x.

@ Ver7

Attempt to be ABI-compatible with code generated by Clang 7.0.x (SVN r338536).

@ Latest

Conform to the underlying platform's C and C++ ABIs as closely as we can.

@ Ver3_8

Attempt to be ABI-compatible with code generated by Clang 3.8.x (SVN r257626).

@ Ver12

Attempt to be ABI-compatible with code generated by Clang 12.0.x (git 8e464dd76bef).

@ Ver9

Attempt to be ABI-compatible with code generated by Clang 9.0.x (SVN r351319).

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

void resetNonModularOptions()

Reset all of the options that are not considered when building a module.

std::optional< TargetCXXABI::Kind > CXXABI

C++ ABI to compile with, if specified by the frontend through -fc++-abi=.

std::vector< std::string > NoBuiltinFuncs

A list of all -fno-builtin-* function names (e.g., memset).

std::string ModuleName

The module currently being compiled as specified by -fmodule-name.

clang::ObjCRuntime ObjCRuntime

std::string getOpenCLVersionString() const

Return the OpenCL C or C++ for OpenCL language name and version as a string.

unsigned OverflowPatternExclusionMask

Which overflow patterns should be excluded from sanitizer instrumentation.

SanitizerSet Sanitize

Set of enabled sanitizers.

bool UseTargetPathSeparator

Indicates whether to use target's platform-specific file separator when FILE macro is used and when c...

static void setLangDefaults(LangOptions &Opts, Language Lang, const llvm::Triple &T, std::vector< std::string > &Includes, LangStandard::Kind LangStd=LangStandard::lang_unspecified)

Set language defaults for the given input language and language standard in the given LangOptions obj...

std::string OMPHostIRFile

Name of the IR file that contains the result of the OpenMP target host code generation.

std::string OverflowHandler

The name of the handler function to be called when -ftrapv is specified.

std::string RandstructSeed

The seed used by the randomize structure layout feature.

std::map< std::string, std::string, std::greater< std::string > > MacroPrefixMap

A prefix map for FILE, BASE_FILE and __builtin_FILE().

LangStandard::Kind LangStd

The used language standard.

std::string OpenACCMacroOverride

unsigned getOpenCLCompatibleVersion() const

Return the OpenCL version that kernel language is compatible with.

bool SanitizeCoverage

Is at least one coverage instrumentation type enabled.

std::vector< llvm::Triple > OMPTargetTriples

Triples of the OpenMP targets that the host code codegen should take into account in order to generat...

std::vector< std::string > NoSanitizeFiles

Paths to files specifying which objects (files, functions, variables) should not be instrumented.

std::string CurrentModule

The name of the current module, of which the main source file is a part.

std::vector< std::string > ModuleFeatures

The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...

The basic abstraction for the target Objective-C runtime.

bool allowsWeak() const

Does this runtime allow the use of __weak?

bool tryParse(StringRef input)

Try to parse an Objective-C runtime specification from the given string.

std::string getAsString() const

bool allowsARC() const

Does this runtime allow ARC at all?

@ FragileMacOSX

'macosx-fragile' is the Apple-provided NeXT-derived runtime on Mac OS X platforms that use the fragil...

Discrimination

Forms of extra discrimination.

ARM8_3Key

Hardware pointer-signing keys in ARM8.3.

static constexpr std::optional< PositiveAnalyzerOption > create(unsigned Val)

PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...

std::vector< std::pair< std::string, std::string > > RemappedFiles

The set of file remappings, which take existing files on the system (the first part of each pair) and...

bool PCHWithHdrStopCreate

When true, we are creating a PCH or creating the PCH object while expecting a #pragma hdrstop to sepa...

std::vector< std::string > Includes

std::pair< unsigned, bool > PrecompiledPreambleBytes

If non-zero, the implicit PCH include is actually a precompiled preamble that covers this number of b...

bool LexEditorPlaceholders

When enabled, the preprocessor will construct editor placeholder tokens.

void resetNonModularOptions()

Reset any options that are not considered when building a module.

void addMacroUndef(StringRef Name)

std::set< std::string > DeserializedPCHDeclsToErrorOn

This is a set of names for decls that we do not want to be deserialized, and we emit an error if they...

std::vector< std::string > EmbedEntries

User specified embed entries.

void addMacroDef(StringRef Name)

bool DefineTargetOSMacros

Indicates whether to predefine target OS macros.

bool DetailedRecord

Whether we should maintain a detailed record of all macro definitions and expansions.

std::vector< std::string > ChainedIncludes

Headers that will be converted to chained PCHs in memory.

bool PCHWithHdrStop

When true, we are creating or using a PCH where a #pragma hdrstop is expected to indicate the beginni...

std::optional< uint64_t > SourceDateEpoch

If set, the UNIX timestamp specified by SOURCE_DATE_EPOCH.

bool UsePredefines

Initialize the preprocessor with the compiler and target specific predefines.

void addRemappedFile(StringRef From, StringRef To)

std::vector< std::pair< std::string, bool > > Macros

PreprocessorOutputOptions - Options for controlling the C preprocessor output (e.g....

unsigned ShowMacros

Print macro definitions.

unsigned ShowCPP

Print normal preprocessed output.

unsigned ShowLineMarkers

Show #line markers.

unsigned DirectivesOnly

Process directives but do not expand macros.

Encodes a location in the source.

static bool isSupportedCXXABI(const llvm::Triple &T, Kind Kind)

static const auto & getSpelling(Kind ABIKind)

static bool usesRelativeVTables(const llvm::Triple &T)

static bool isABI(StringRef Name)

Options for controlling the target.

std::string Triple

The name of the target triple to compile for.

llvm::VersionTuple SDKVersion

The version of the SDK which was used during the compilation.

uint64_t LargeDataThreshold

llvm::VersionTuple DarwinTargetVariantSDKVersion

The version of the darwin target variant SDK which was used during the compilation.

std::string HostTriple

When compiling for the device side, contains the triple used to compile for the host.

Action - Represent an abstract compilation step to perform.

static std::string GetResourcesPath(StringRef BinaryPath)

Takes the path to a binary that's either in bin/ or lib/ and returns the path to clang's resource dir...

constexpr XRayInstrMask None

constexpr XRayInstrMask All

const llvm::opt::OptTable & getDriverOptTable()

IncludeDirGroup

IncludeDirGroup - Identifies the group an include Entry belongs to, representing its relative positiv...

@ CXXSystem

Like System, but only used for C++.

@ Angled

Paths for '#include <>' added by '-I'.

@ CSystem

Like System, but only used for C.

@ System

Like Angled, but marks system directories.

@ Quoted

'#include ""' paths, added by 'gcc -iquote'.

@ ExternCSystem

Like System, but headers are implicitly wrapped in extern "C".

@ ObjCSystem

Like System, but only used for ObjC.

@ ObjCXXSystem

Like System, but only used for ObjC++.

@ After

Like System, but searched after the system directories.

@ GenerateHeaderUnit

Generate a C++20 header unit module from a header file.

@ VerifyPCH

Load and verify that a PCH file is usable.

@ PrintPreprocessedInput

-E mode.

@ RewriteTest

Rewriter playground.

@ ParseSyntaxOnly

Parse and perform semantic analysis.

@ TemplightDump

Dump template instantiations.

@ GenerateModuleInterface

Generate pre-compiled module from a standard C++ module interface unit.

@ EmitLLVM

Emit a .ll file.

@ PrintPreamble

Print the "preamble" of the input file.

@ MigrateSource

Run migrator.

@ InitOnly

Only execute frontend initialization.

@ ASTView

Parse ASTs and view them in Graphviz.

@ PluginAction

Run a plugin action,.

@ DumpRawTokens

Dump out raw tokens.

@ PrintDependencyDirectivesSourceMinimizerOutput

Print the output of the dependency directives source minimizer.

@ RewriteObjC

ObjC->C Rewriter.

@ RunPreprocessorOnly

Just lex, no output.

@ ModuleFileInfo

Dump information about a module file.

@ EmitCIR

Emit a .cir file.

@ DumpCompilerOptions

Dump the compiler configuration.

@ RunAnalysis

Run one or more source code analyses.

@ ASTPrint

Parse ASTs and print them.

@ GenerateReducedModuleInterface

Generate reduced module interface for a standard C++ module interface unit.

@ GenerateInterfaceStubs

Generate Interface Stub Files.

@ ASTDump

Parse ASTs and dump them.

@ DumpTokens

Dump out preprocessed tokens.

@ FixIt

Parse and apply any fixits to the source.

@ EmitAssembly

Emit a .s file.

@ EmitCodeGenOnly

Generate machine code, but don't emit anything.

@ RewriteMacros

Expand macros but not #includes.

@ EmitHTML

Translate input source into HTML.

@ GeneratePCH

Generate pre-compiled header.

@ EmitLLVMOnly

Generate LLVM IR, but do not emit anything.

@ GenerateModule

Generate pre-compiled module from a module map.

@ ASTDeclList

Parse ASTs and list Decl nodes.

const unsigned VERSION_MINOR

AST file minor version number supported by this version of Clang.

const unsigned VERSION_MAJOR

AST file major version number supported by this version of Clang.

The JSON file list parser is used to communicate input to InstallAPI.

ASTDumpOutputFormat

Used to specify the format for printing AST dump information.

SanitizerMask getPPTransparentSanitizers()

Return the sanitizers which do not affect preprocessing.

IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromOverlayFiles(ArrayRef< std::string > VFSOverlayFiles, DiagnosticsEngine &Diags, IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS)

DiagnosticLevelMask

A bitmask representing the diagnostic levels used by VerifyDiagnosticConsumer.

std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)

AnalysisConstraints

AnalysisConstraints - Set of available constraint models.

@ HIFIL_Only_Direct_System

void serializeSanitizerSet(SanitizerSet Set, SmallVectorImpl< StringRef > &Values)

Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.

LLVM_READONLY bool isLetter(unsigned char c)

Return true if this character is an ASCII letter: [a-zA-Z].

LLVM_READONLY bool isAlphanumeric(unsigned char c)

Return true if this character is an ASCII letter or digit: [a-zA-Z0-9].

constexpr uint16_t InitFiniPointerConstantDiscriminator

Constant discriminator to be used with function pointers in .init_array and .fini_array.

@ C

Languages that the frontend can parse and compile.

@ CIR

LLVM IR & CIR: we accept these so that we can run the optimizer on them, and compile them to assembly...

@ Asm

Assembly: we accept this only so that we can preprocess it.

bool parseSanitizerWeightedValue(StringRef Value, bool AllowGroups, SanitizerMaskCutoffs &Cutoffs)

Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= or -fno-sanitize= value lis...

@ Result

The result type of a method or function.

XRayInstrMask parseXRayInstrValue(StringRef Value)

Parses a command line argument into a mask.

IntrusiveRefCntPtr< llvm::vfs::FileSystem > createVFSFromCompilerInvocation(const CompilerInvocation &CI, DiagnosticsEngine &Diags)

void serializeXRayInstrValue(XRayInstrSet Set, SmallVectorImpl< StringRef > &Values)

Serializes a set into a list of command line arguments.

AnalysisPurgeMode

AnalysisPurgeModes - Set of available strategies for dead symbol removal.

void serializeSanitizerMaskCutoffs(const SanitizerMaskCutoffs &Cutoffs, SmallVectorImpl< std::string > &Values)

Serialize a SanitizerMaskCutoffs into values for -fsanitize= or -fno-sanitize=.

ShaderStage

Shader programs run in specific pipeline stages.

constexpr uint16_t StdTypeInfoVTablePointerConstantDiscrimination

Constant discriminator for std::type_info vtable pointers: 0xB1EA/45546 The value is ptrauth_string_d...

SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)

Parse a single value from a -fsanitize= or -fno-sanitize= value list.

const FunctionProtoType * T

AnalysisDiagClients

AnalysisDiagClients - Set of available diagnostic clients for rendering analysis results.

@ NUM_ANALYSIS_DIAG_CLIENTS

std::string getClangFullRepositoryVersion()

Retrieves the full repository version that is an amalgamation of the information in getClangRepositor...

int getLastArgIntValue(const llvm::opt::ArgList &Args, llvm::opt::OptSpecifier Id, int Default, DiagnosticsEngine *Diags=nullptr, unsigned Base=0)

Return the value of the last argument as an integer, or a default.

bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags=nullptr, bool DefaultDiagColor=true)

Fill out Opts based on the options given in Args.

@ Success

Template argument deduction was successful.

AnalysisInliningMode

AnalysisInlineFunctionSelection - Set of inlining function selection heuristics.

Diagnostic wrappers for TextAPI types for error reporting.

__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)

bool Internalize

If true, we use LLVM module internalizer.

bool PropagateAttrs

If true, we set attributes functions in the bitcode library according to our CodeGenOptions,...

std::string Filename

The filename of the bitcode file to link in.

unsigned LinkFlags

Bitwise combination of llvm::Linker::Flags, passed to the LLVM linker.

Dummy tag type whose instance can be passed into the constructor to prevent creation of the reference...

LangStandard - Information about the properties of a particular language standard.

static const LangStandard & getLangStandardForKind(Kind K)

const char * getName() const

getName - Get the name of this standard.

static Kind getLangKind(StringRef Name)

static ParsedSourceLocation FromString(StringRef Str)

Construct a parsed source location from a string; the Filename is empty on error.

std::string ToString() const

Serialize ParsedSourceLocation back to a string.

PointerAuthSchema CXXVTablePointers

The ABI for C++ virtual table pointers (the pointer to the table itself) as installed in an actual cl...

PointerAuthSchema InitFiniPointers

The ABI for function addresses in .init_array and .fini_array.

PointerAuthSchema CXXVTTVTablePointers

The ABI for C++ virtual table pointers as installed in a VTT.

bool ReturnAddresses

Should return addresses be authenticated?

PointerAuthSchema CXXTypeInfoVTablePointer

TypeInfo has external ABI requirements and is emitted without actually having parsed the libcxx defin...

bool AArch64JumpTableHardening

Use hardened lowering for jump-table dispatch?

PointerAuthSchema FunctionPointers

The ABI for C function pointers.

bool AuthTraps

Do authentication failures cause a trap?

PointerAuthSchema CXXMemberFunctionPointers

The ABI for C++ member function pointers.

PointerAuthSchema CXXVirtualVariadicFunctionPointers

The ABI for variadic C++ virtual function pointers.

PointerAuthSchema CXXVirtualFunctionPointers

The ABI for most C++ virtual function pointers, i.e. v-table entries.

bool IndirectGotos

Do indirect goto label addresses need to be authenticated?

void clear(SanitizerMask K=SanitizerKind::All)

Disable the sanitizers specified in K.

bool empty() const

Returns true if no sanitizers are enabled.

SanitizerMask Mask

Bitmask of enabled sanitizers.