@@ -560,13 +560,18 @@ static std::string lowerDash(StringRef s) {
560
560
map_iterator (s.end (), toLowerDash));
561
561
}
562
562
563
- static void handlePlatformVersion (const opt::Arg *arg) {
563
+ static PlatformInfo getPlatformVersion (const opt::ArgList &args) {
564
+ const opt::Arg *arg = args.getLastArg (OPT_platform_version);
565
+ PlatformInfo platform;
566
+ if (!arg)
567
+ return platform;
568
+
564
569
StringRef platformStr = arg->getValue (0 );
565
570
StringRef minVersionStr = arg->getValue (1 );
566
571
StringRef sdkVersionStr = arg->getValue (2 );
567
572
568
573
// TODO(compnerd) see if we can generate this case list via XMACROS
569
- config-> platform .kind =
574
+ platform.kind =
570
575
StringSwitch<PlatformKind>(lowerDash (platformStr))
571
576
.Cases (" macos" , " 1" , PlatformKind::macOS)
572
577
.Cases (" ios" , " 2" , PlatformKind::iOS)
@@ -579,23 +584,25 @@ static void handlePlatformVersion(const opt::Arg *arg) {
579
584
.Cases (" watchos-simulator" , " 9" , PlatformKind::watchOSSimulator)
580
585
.Cases (" driverkit" , " 10" , PlatformKind::driverKit)
581
586
.Default (PlatformKind::unknown);
582
- if (config-> platform .kind == PlatformKind::unknown)
587
+ if (platform.kind == PlatformKind::unknown)
583
588
error (Twine (" malformed platform: " ) + platformStr);
584
589
// TODO: check validity of version strings, which varies by platform
585
590
// NOTE: ld64 accepts version strings with 5 components
586
591
// llvm::VersionTuple accepts no more than 4 components
587
592
// Has Apple ever published version strings with 5 components?
588
- if (config-> platform .minimum .tryParse (minVersionStr))
593
+ if (platform.minimum .tryParse (minVersionStr))
589
594
error (Twine (" malformed minimum version: " ) + minVersionStr);
590
- if (config-> platform .sdk .tryParse (sdkVersionStr))
595
+ if (platform.sdk .tryParse (sdkVersionStr))
591
596
error (Twine (" malformed sdk version: " ) + sdkVersionStr);
597
+ return platform;
592
598
}
593
599
594
- static void handleUndefined (const opt::Arg *arg) {
595
- StringRef treatmentStr = arg->getValue (0 );
600
+ static UndefinedSymbolTreatment
601
+ getUndefinedSymbolTreatment (const opt::ArgList &args) {
602
+ StringRef treatmentStr = args.getLastArgValue (OPT_undefined);
596
603
auto treatment =
597
604
StringSwitch<UndefinedSymbolTreatment>(treatmentStr)
598
- .Case (" error" , UndefinedSymbolTreatment::error)
605
+ .Cases (" error" , " " , UndefinedSymbolTreatment::error)
599
606
.Case (" warning" , UndefinedSymbolTreatment::warning)
600
607
.Case (" suppress" , UndefinedSymbolTreatment::suppress)
601
608
.Case (" dynamic_lookup" , UndefinedSymbolTreatment::dynamic_lookup)
@@ -613,7 +620,7 @@ static void handleUndefined(const opt::Arg *arg) {
613
620
error (" '-undefined suppress' only valid with '-flat_namespace'" );
614
621
treatment = UndefinedSymbolTreatment::error;
615
622
}
616
- config-> undefinedSymbolTreatment = treatment;
623
+ return treatment;
617
624
}
618
625
619
626
static void warnIfDeprecatedOption (const opt::Option &opt) {
@@ -752,6 +759,7 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
752
759
config = make<Configuration>();
753
760
symtab = make<SymbolTable>();
754
761
target = createTargetInfo (args);
762
+ config->platform = getPlatformVersion (args);
755
763
756
764
config->entry = symtab->addUndefined (args.getLastArgValue (OPT_e, " _main" ),
757
765
/* file=*/ nullptr ,
@@ -792,11 +800,12 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
792
800
config->staticLink = (arg->getOption ().getID () == OPT_static);
793
801
794
802
if (const opt::Arg *arg =
795
- args.getLastArg (OPT_flat_namespace, OPT_twolevel_namespace)) {
803
+ args.getLastArg (OPT_flat_namespace, OPT_twolevel_namespace))
796
804
config->namespaceKind = arg->getOption ().getID () == OPT_twolevel_namespace
797
805
? NamespaceKind::twolevel
798
806
: NamespaceKind::flat;
799
- }
807
+
808
+ config->undefinedSymbolTreatment = getUndefinedSymbolTreatment (args);
800
809
801
810
config->systemLibraryRoots = getSystemLibraryRoots (args);
802
811
config->librarySearchPaths =
@@ -846,12 +855,13 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
846
855
847
856
initLLVM (); // must be run before any call to addFile()
848
857
858
+ // This loop should be reserved for options whose exact ordering matters.
859
+ // Other options should be handled via filtered() and/or getLastArg().
849
860
for (const auto &arg : args) {
850
861
const auto &opt = arg->getOption ();
851
862
warnIfDeprecatedOption (opt);
852
863
warnIfUnimplementedOption (opt);
853
864
854
- // TODO: are any of these better handled via filtered() or getLastArg()?
855
865
switch (opt.getID ()) {
856
866
case OPT_INPUT:
857
867
addFile (arg->getValue (), false );
@@ -875,12 +885,6 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
875
885
case OPT_weak_framework:
876
886
addFramework (arg->getValue (), opt.getID () == OPT_weak_framework);
877
887
break ;
878
- case OPT_platform_version:
879
- handlePlatformVersion (arg);
880
- break ;
881
- case OPT_undefined:
882
- handleUndefined (arg);
883
- break ;
884
888
default :
885
889
break ;
886
890
}
0 commit comments