ARM: support .watchos_version_min and .tvos_version_min.
authorTim Northover <tnorthover@apple.com>
Wed, 28 Oct 2015 22:36:05 +0000 (22:36 +0000)
committerTim Northover <tnorthover@apple.com>
Wed, 28 Oct 2015 22:36:05 +0000 (22:36 +0000)
These MachO file directives are used by linkers and other tools to provide
compatibility information, much like the existing .ios_version_min and
.macosx_version_min.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251569 91177308-0d34-0410-b5e6-96231b3b80d8

19 files changed:
include/llvm/ADT/Triple.h
include/llvm/MC/MCDirectives.h
include/llvm/MC/MCParser/MCAsmParserExtension.h
include/llvm/Support/ARMTargetParser.def
include/llvm/Support/MachO.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/MC/MCAsmStreamer.cpp
lib/MC/MCMachOStreamer.cpp
lib/MC/MCParser/DarwinAsmParser.cpp
lib/MC/MachObjectWriter.cpp
lib/Support/TargetParser.cpp
lib/Support/Triple.cpp
lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
test/MC/MachO/ARM/tvos-version-min-load-command.s [new file with mode: 0644]
test/MC/MachO/ARM/version-min-diagnostics.s
test/MC/MachO/ARM/version-min-diagnostics2.s [new file with mode: 0644]
test/MC/MachO/ARM/version-min.s
test/MC/MachO/darwin-version-min-load-command.s
tools/llvm-readobj/MachODumper.cpp

index 5f3742c..4ed694c 100644 (file)
@@ -99,6 +99,7 @@ public:
     ARMSubArch_v7em,
     ARMSubArch_v7m,
     ARMSubArch_v7s,
+    ARMSubArch_v7k,
     ARMSubArch_v6,
     ARMSubArch_v6m,
     ARMSubArch_v6k,
@@ -156,7 +157,9 @@ public:
     AMDHSA,     // AMD HSA Runtime
     PS4,
     ELFIAMCU,
-    LastOSType = ELFIAMCU
+    TvOS,       // Apple tvOS
+    WatchOS,    // Apple watchOS
+    LastOSType = WatchOS
   };
   enum EnvironmentType {
     UnknownEnvironment,
@@ -401,13 +404,27 @@ public:
   }
 
   /// Is this an iOS triple.
+  /// Note: This identifies tvOS as a variant of iOS. If that ever
+  /// changes, i.e., if the two operating systems diverge or their version
+  /// numbers get out of sync, that will need to be changed.
+  /// watchOS has completely different version numbers so it is not included.
   bool isiOS() const {
-    return getOS() == Triple::IOS;
+    return getOS() == Triple::IOS || isTvOS();
   }
 
-  /// isOSDarwin - Is this a "Darwin" OS (OS X or iOS).
+  /// Is this an Apple tvOS triple.
+  bool isTvOS() const {
+    return getOS() == Triple::TvOS;
+  }
+
+  /// Is this an Apple watchOS triple.
+  bool isWatchOS() const {
+    return getOS() == Triple::WatchOS;
+  }
+
+  /// isOSDarwin - Is this a "Darwin" OS (OS X, iOS, or watchOS).
   bool isOSDarwin() const {
-    return isMacOSX() || isiOS();
+    return isMacOSX() || isiOS() || isWatchOS();
   }
 
   bool isOSNetBSD() const {
index f9d66e0..326b2a1 100644 (file)
@@ -62,7 +62,9 @@ enum MCDataRegionType {
 
 enum MCVersionMinType {
   MCVM_IOSVersionMin,         ///< .ios_version_min
-  MCVM_OSXVersionMin          ///< .macosx_version_min
+  MCVM_OSXVersionMin,         ///< .macosx_version_min
+  MCVM_TvOSVersionMin,        ///< .tvos_version_min
+  MCVM_WatchOSVersionMin,     ///< .watchos_version_min
 };
 
 } // end namespace llvm
index 077fd21..30b25dc 100644 (file)
@@ -71,6 +71,9 @@ public:
   bool Error(SMLoc L, const Twine &Msg) {
     return getParser().Error(L, Msg);
   }
+  void Note(SMLoc L, const Twine &Msg) {
+    getParser().Note(L, Msg);
+  }
   bool TokError(const Twine &Msg) {
     return getParser().TokError(Msg);
   }
index 39979d0..523a5ed 100644 (file)
@@ -241,6 +241,7 @@ ARM_CPU_NAME("cortex-a8", AK_ARMV7HL, FK_NEON, true, AEK_SEC)
 ARM_CPU_NAME("cortex-m4", AK_ARMV7EM, FK_NONE, true, AEK_NONE)
 ARM_CPU_NAME("swift", AK_ARMV7S, FK_NEON_VFPV4, true,
              (AEK_HWDIVARM | AEK_HWDIV))
+ARM_CPU_NAME("cortex-a7", AK_ARMV7K, FK_NONE, true, AEK_HWDIVARM | AEK_HWDIV)
 // Invalid CPU
 ARM_CPU_NAME("invalid", AK_INVALID, FK_INVALID, true, AEK_INVALID)
 #undef ARM_CPU_NAME
index 0428198..54b8745 100644 (file)
@@ -132,7 +132,9 @@ namespace llvm {
       LC_DYLIB_CODE_SIGN_DRS  = 0x0000002Bu,
       LC_ENCRYPTION_INFO_64   = 0x0000002Cu,
       LC_LINKER_OPTION        = 0x0000002Du,
-      LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu
+      LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu,
+      LC_VERSION_MIN_TVOS     = 0x0000002Fu,
+      LC_VERSION_MIN_WATCHOS  = 0x00000030u,
     };
 
     enum : uint32_t {
index f073118..00762ca 100644 (file)
@@ -196,10 +196,18 @@ bool AsmPrinter::doInitialization(Module &M) {
     unsigned Major, Minor, Update;
     TT.getOSVersion(Major, Minor, Update);
     // If there is a version specified, Major will be non-zero.
-    if (Major)
-      OutStreamer->EmitVersionMin((TT.isMacOSX() ?
-                                   MCVM_OSXVersionMin : MCVM_IOSVersionMin),
-                                  Major, Minor, Update);
+    if (Major) {
+      MCVersionMinType VersionType;
+      if (TT.isWatchOS())
+        VersionType = MCVM_WatchOSVersionMin;
+      else if (TT.isTvOS())
+        VersionType = MCVM_TvOSVersionMin;
+      else if (TT.isMacOSX())
+        VersionType = MCVM_OSXVersionMin;
+      else
+        VersionType = MCVM_IOSVersionMin;
+      OutStreamer->EmitVersionMin(VersionType, Major, Minor, Update);
+    }
   }
 
   // Allow the target to emit any magic that it wants at the start of the file.
index a6c4e28..2f06415 100644 (file)
@@ -369,6 +369,8 @@ void MCAsmStreamer::EmitDataRegion(MCDataRegionType Kind) {
 void MCAsmStreamer::EmitVersionMin(MCVersionMinType Kind, unsigned Major,
                                    unsigned Minor, unsigned Update) {
   switch (Kind) {
+  case MCVM_WatchOSVersionMin:    OS << "\t.watchos_version_min"; break;
+  case MCVM_TvOSVersionMin:       OS << "\t.tvos_version_min"; break;
   case MCVM_IOSVersionMin:        OS << "\t.ios_version_min"; break;
   case MCVM_OSXVersionMin:        OS << "\t.macosx_version_min"; break;
   }
index 03868b0..52ecf9f 100644 (file)
@@ -490,10 +490,20 @@ MCStreamer *llvm::createMachOStreamer(MCContext &Context, MCAsmBackend &MAB,
     unsigned Major, Minor, Update;
     TT.getOSVersion(Major, Minor, Update);
     // If there is a version specified, Major will be non-zero.
-    if (Major)
-      S->EmitVersionMin((TT.isMacOSX() ?
-                        MCVM_OSXVersionMin : MCVM_IOSVersionMin),
-                        Major, Minor, Update);
+    if (Major) {
+      MCVersionMinType VersionType;
+      if (TT.isWatchOS())
+        VersionType = MCVM_WatchOSVersionMin;
+      else if (TT.isTvOS())
+        VersionType = MCVM_TvOSVersionMin;
+      else if (TT.isMacOSX())
+        VersionType = MCVM_OSXVersionMin;
+      else {
+        assert(TT.isiOS() && "Must only be iOS platform left");
+        VersionType = MCVM_IOSVersionMin;
+      }
+      S->EmitVersionMin(VersionType, Major, Minor, Update);
+    }
   }
   if (RelaxAll)
     S->getAssembler().setRelaxAll(true);
index 5e99ad0..582d436 100644 (file)
@@ -40,6 +40,8 @@ class DarwinAsmParser : public MCAsmParserExtension {
                           unsigned TAA = 0, unsigned ImplicitAlign = 0,
                           unsigned StubSize = 0);
 
+  SMLoc LastVersionMinDirective;
+
 public:
   DarwinAsmParser() {}
 
@@ -166,9 +168,14 @@ public:
     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveTLV>(".tlv");
 
     addDirectiveHandler<&DarwinAsmParser::parseSectionDirectiveIdent>(".ident");
+    addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
+      ".watchos_version_min");
+    addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".tvos_version_min");
     addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(".ios_version_min");
     addDirectiveHandler<&DarwinAsmParser::parseVersionMin>(
       ".macosx_version_min");
+
+    LastVersionMinDirective = SMLoc();
   }
 
   bool parseDirectiveDesc(StringRef, SMLoc);
@@ -892,9 +899,11 @@ bool DarwinAsmParser::parseDirectiveDataRegionEnd(StringRef, SMLoc) {
 /// parseVersionMin
 ///  ::= .ios_version_min major,minor[,update]
 ///  ::= .macosx_version_min major,minor[,update]
-bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
+bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc Loc) {
   int64_t Major = 0, Minor = 0, Update = 0;
   int Kind = StringSwitch<int>(Directive)
+    .Case(".watchos_version_min", MCVM_WatchOSVersionMin)
+    .Case(".tvos_version_min", MCVM_TvOSVersionMin)
     .Case(".ios_version_min", MCVM_IOSVersionMin)
     .Case(".macosx_version_min", MCVM_OSXVersionMin);
   // Get the major version number.
@@ -927,6 +936,24 @@ bool DarwinAsmParser::parseVersionMin(StringRef Directive, SMLoc) {
     Lex();
   }
 
+  const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
+  Triple::OSType ExpectedOS = Triple::UnknownOS;
+  switch ((MCVersionMinType)Kind) {
+  case MCVM_WatchOSVersionMin: ExpectedOS = Triple::WatchOS; break;
+  case MCVM_TvOSVersionMin:    ExpectedOS = Triple::TvOS;    break;
+  case MCVM_IOSVersionMin:     ExpectedOS = Triple::IOS;     break;
+  case MCVM_OSXVersionMin:     ExpectedOS = Triple::MacOSX;  break;
+  }
+  if (T.getOS() != ExpectedOS)
+    Warning(Loc, Directive + " should only be used for " +
+            Triple::getOSTypeName(ExpectedOS) + " targets");
+
+  if (LastVersionMinDirective.isValid()) {
+    Warning(Loc, "overriding previous version_min directive");
+    Note(LastVersionMinDirective, "previous definition is here");
+  }
+  LastVersionMinDirective = Loc;
+
   // We've parsed a correct version specifier, so send it to the streamer.
   getStreamer().EmitVersionMin((MCVersionMinType)Kind, Major, Minor, Update);
 
index 17023d8..324385f 100644 (file)
@@ -815,8 +815,22 @@ void MachObjectWriter::writeObject(MCAssembler &Asm,
     assert(VersionInfo.Major < 65536 && "unencodable major target version");
     uint32_t EncodedVersion = VersionInfo.Update | (VersionInfo.Minor << 8) |
       (VersionInfo.Major << 16);
-    write32(VersionInfo.Kind == MCVM_OSXVersionMin ? MachO::LC_VERSION_MIN_MACOSX :
-            MachO::LC_VERSION_MIN_IPHONEOS);
+    MachO::LoadCommandType LCType;
+    switch (VersionInfo.Kind) {
+    case MCVM_OSXVersionMin:
+      LCType = MachO::LC_VERSION_MIN_MACOSX;
+      break;
+    case MCVM_IOSVersionMin:
+      LCType = MachO::LC_VERSION_MIN_IPHONEOS;
+      break;
+    case MCVM_TvOSVersionMin:
+      LCType = MachO::LC_VERSION_MIN_TVOS;
+      break;
+    case MCVM_WatchOSVersionMin:
+      LCType = MachO::LC_VERSION_MIN_WATCHOS;
+      break;
+    }
+    write32(LCType);
     write32(sizeof(MachO::version_min_command));
     write32(EncodedVersion);
     write32(0);         // reserved.
index 7a87077..b6cb198 100644 (file)
@@ -520,6 +520,7 @@ unsigned llvm::ARM::parseArchProfile(StringRef Arch) {
     return ARM::PK_R;
   case ARM::AK_ARMV7:
   case ARM::AK_ARMV7A:
+  case ARM::AK_ARMV7K:
   case ARM::AK_ARMV7L:
   case ARM::AK_ARMV8A:
   case ARM::AK_ARMV8_1A:
index 142a9b9..8964fc0 100644 (file)
@@ -182,6 +182,8 @@ const char *Triple::getOSTypeName(OSType Kind) {
   case AMDHSA: return "amdhsa";
   case PS4: return "ps4";
   case ELFIAMCU: return "elfiamcu";
+  case TvOS: return "tvos";
+  case WatchOS: return "watchos";
   }
 
   llvm_unreachable("Invalid OSType");
@@ -437,6 +439,8 @@ static Triple::OSType parseOS(StringRef OSName) {
     .StartsWith("amdhsa", Triple::AMDHSA)
     .StartsWith("ps4", Triple::PS4)
     .StartsWith("elfiamcu", Triple::ELFIAMCU)
+    .StartsWith("tvos", Triple::TvOS)
+    .StartsWith("watchos", Triple::WatchOS)
     .Default(Triple::UnknownOS);
 }
 
@@ -512,6 +516,8 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
   case ARM::AK_ARMV7L:
   case ARM::AK_ARMV7HL:
     return Triple::ARMSubArch_v7;
+  case ARM::AK_ARMV7K:
+    return Triple::ARMSubArch_v7k;
   case ARM::AK_ARMV7M:
     return Triple::ARMSubArch_v7m;
   case ARM::AK_ARMV7S:
@@ -932,6 +938,8 @@ bool Triple::getMacOSXVersion(unsigned &Major, unsigned &Minor,
       return false;
     break;
   case IOS:
+  case TvOS:
+  case WatchOS:
     // Ignore the version from the triple.  This is only handled because the
     // the clang driver combines OS X and IOS support into a common Darwin
     // toolchain that wants to know the OS X version number even when targeting
@@ -950,6 +958,7 @@ void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
   default: llvm_unreachable("unexpected OS for Darwin triple");
   case Darwin:
   case MacOSX:
+  case WatchOS:
     // Ignore the version from the triple.  This is only handled because the
     // the clang driver combines OS X and IOS support into a common Darwin
     // toolchain that wants to know the iOS version number even when targeting
@@ -959,6 +968,7 @@ void Triple::getiOSVersion(unsigned &Major, unsigned &Minor,
     Micro = 0;
     break;
   case IOS:
+  case TvOS:
     getOSVersion(Major, Minor, Micro);
     // Default to 5.0 (or 7.0 for arm64).
     if (Major == 0)
index 79d9cef..097b683 100644 (file)
@@ -188,7 +188,15 @@ std::string ARM_MC::ParseARMTriple(const Triple &TT, StringRef CPU) {
       // Use CPU to figure out the exact features.
       ARMArchFeature = "+v7";
     break;
-  case Triple::ARMSubArch_v7:
+  case Triple::ARMSubArch_v7k:
+    if (NoCPU)
+      // v7k: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureHasRAS
+      //      A7
+      ARMArchFeature = "+v7,+a7,+neon,+db,+t2dsp,+ras";
+    else
+      // Use CPU to figure out the exact features.
+      ARMArchFeature = "+v7";
+    break;  case Triple::ARMSubArch_v7:
     // v7 CPUs have lots of different feature sets. If no CPU is specified,
     // then assume v7a (e.g. cortex-a8) feature set. Otherwise, return
     // the "minimum" feature set and use CPU string to figure out the exact
diff --git a/test/MC/MachO/ARM/tvos-version-min-load-command.s b/test/MC/MachO/ARM/tvos-version-min-load-command.s
new file mode 100644 (file)
index 0000000..3c9b237
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: llvm-mc -triple armv7-apple-tvos %s -filetype=obj -o - | llvm-readobj --macho-version-min | FileCheck %s
+
+
+// Test the formation of the version-min load command in the MachO.
+// use a nonsense but well formed version.
+.tvos_version_min 99,8,7
+
+// CHECK: MinVersion {
+// CHECK-NEXT:   Cmd: LC_VERSION_MIN_TVOS
+// CHECK-NEXT:   Size: 16
+// CHECK-NEXT:   Version: 99.8.7
+// CHECK-NEXT:   SDK: n/a
+// CHECK-NEXT: }
index 15d44d3..76c3268 100644 (file)
 .macosx_version_min 10,-1,1
 .macosx_version_min 0,1,1
 .macosx_version_min 70000,1
+.tvos_version_min 99,2,257
+.tvos_version_min 50,256,1
+.tvos_version_min 10,-1,1
+.tvos_version_min 0,1,1
+.tvos_version_min 70000,1
+.watchos_version_min 99,2,257
+.watchos_version_min 50,256,1
+.watchos_version_min 10,-1,1
+.watchos_version_min 0,1,1
+.watchos_version_min 70000,1
 
 
 // CHECK: error: invalid OS update number
 // CHECK: error: invalid OS major version number
 // CHECK: .macosx_version_min 70000,1
 // CHECK:                     ^
+// CHECK: error: invalid OS update number
+// CHECK: .tvos_version_min 99,2,257
+// CHECK:                          ^
+// CHECK: error: invalid OS minor version number
+// CHECK: .tvos_version_min 50,256,1
+// CHECK:                        ^
+// CHECK: error: invalid OS minor version number
+// CHECK: .tvos_version_min 10,-1,1
+// CHECK:                        ^
+// CHECK: error: invalid OS major version number
+// CHECK: .tvos_version_min 0,1,1
+// CHECK:                     ^
+// CHECK: error: invalid OS major version number
+// CHECK: .tvos_version_min 70000,1
+// CHECK:                     ^
+// CHECK: error: invalid OS update number
+// CHECK: .watchos_version_min 99,2,257
+// CHECK:                          ^
+// CHECK: error: invalid OS minor version number
+// CHECK: .watchos_version_min 50,256,1
+// CHECK:                        ^
+// CHECK: error: invalid OS minor version number
+// CHECK: .watchos_version_min 10,-1,1
+// CHECK:                        ^
+// CHECK: error: invalid OS major version number
+// CHECK: .watchos_version_min 0,1,1
+// CHECK:                     ^
+// CHECK: error: invalid OS major version number
+// CHECK: .watchos_version_min 70000,1
+// CHECK:                     ^
diff --git a/test/MC/MachO/ARM/version-min-diagnostics2.s b/test/MC/MachO/ARM/version-min-diagnostics2.s
new file mode 100644 (file)
index 0000000..0689cd4
--- /dev/null
@@ -0,0 +1,34 @@
+// RUN: llvm-mc -triple i386-apple-ios %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=IOS
+// RUN: llvm-mc -triple i386-apple-watchos %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=WATCHOS
+// RUN: llvm-mc -triple i386-apple-tvos %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=TVOS
+// RUN: llvm-mc -triple i386-apple-macosx %s 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MACOSX
+
+.ios_version_min 1,2,3
+// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .ios_version_min should only be used for ios targets
+// TVOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .ios_version_min should only be used for ios targets
+// MACOSX: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .ios_version_min should only be used for ios targets
+// IOS-NOT: warning: .ios_version_min should only be used for ios targets
+
+.macosx_version_min 4,5,6
+// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .macosx_version_min should only be used for macosx targets
+// TVOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .macosx_version_min should only be used for macosx targets
+// IOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .macosx_version_min should only be used for macosx targets
+// MACOSX-NOT: warning: .macosx_version_min should only be used for macosx targets
+// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
+// CHECK: version-min-diagnostics2.s:[[@LINE-12]]:1: note: previous definition is here
+
+.tvos_version_min 7,8,9
+// WATCHOS: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .tvos_version_min should only be used for tvos targets
+// MACOSX: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .tvos_version_min should only be used for tvos targets
+// IOS: version-min-diagnostics2.s:[[@LINE-3]]:1: warning: .tvos_version_min should only be used for tvos targets
+// TVOS-NOT: warning: .tvos_version_min should only be used for tvos targets
+// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
+// CHECK: version-min-diagnostics2.s:[[@LINE-14]]:1: note: previous definition is here
+
+.watchos_version_min 10,11,12
+// MACOSX: version-min-diagnostics2.s:[[@LINE-1]]:1: warning: .watchos_version_min should only be used for watchos targets
+// IOS: version-min-diagnostics2.s:[[@LINE-2]]:1: warning: .watchos_version_min should only be used for watchos targets
+// TVOS-NOT: warning: .tvos_version_min should only be used for tvos targets
+// WATCHOS-NOT: warning: .watchos_version_min should only be used for watchos targets
+// CHECK: version-min-diagnostics2.s:[[@LINE-5]]:1: warning: overriding previous version_min directive
+// CHECK: version-min-diagnostics2.s:[[@LINE-14]]:1: note: previous definition is here
index 0a40338..d4840db 100644 (file)
 // CHECK: .macosx_version_min 10, 2
 // CHECK: .macosx_version_min 10, 8, 1
 // CHECK: .macosx_version_min 2, 0
+
+.tvos_version_min 5,2,0
+.tvos_version_min 3,2,1
+.tvos_version_min 5,0
+
+// CHECK: .tvos_version_min 5, 2
+// CHECK: .tvos_version_min 3, 2, 1
+// CHECK: .tvos_version_min 5, 0
+
+.watchos_version_min 5,2,0
+.watchos_version_min 3,2,1
+.watchos_version_min 5,0
+
+// CHECK: .watchos_version_min 5, 2
+// CHECK: .watchos_version_min 3, 2, 1
+// CHECK: .watchos_version_min 5, 0
index c836484..3c4df0f 100644 (file)
@@ -3,12 +3,22 @@
 // RUN: llvm-mc -triple x86_64-apple-darwin %s -filetype=obj -o - | llvm-objdump -macho -private-headers - | FileCheck %s --check-prefix=CHECK-DARWIN
 
 // Test version-min load command should be inferred from triple and should always be generated on Darwin
-// CHECK:           cmd LC_VERSION_MIN_MACOSX
-// CHECK-NEXT:   cmdsize 16
-// CHECK-NEXT:   version 10.10
+// CHECK: Load command
+// CHECK:       cmd LC_VERSION_MIN_MACOSX
+// CHECK:   cmdsize 16
+// CHECK:   version 10.10
 
-// CHECK-IOS:           cmd LC_VERSION_MIN_IPHONEOS
-// CHECK-IOS-NEXT:   cmdsize 16
-// CHECK-IOS-NEXT:   version 8.0
+// CHECK-IOS: Load command
+// CHECK-IOS:       cmd LC_VERSION_MIN_IPHONEOS
+// CHECK-IOS:   cmdsize 16
+// CHECK-IOS:   version 8.0
 
 // CHECK-DARWIN-NOT: LC_VERSION_MIN
+
+
+// FIXME: llvm-objdump doesn't know about WATCHOS LC yet
+// FIXME: llvm-mc -triple x86_64-apple-watchos1.0.0 %s -filetype=obj -o - | llvm-objdump -macho -private-headers - | FileCheck %s --check-prefix=CHECK-WATCHOS
+// CHECK-WATCHOS: Load command
+// CHECK-WATCHOS:       cmd LC_VERSION_MIN_WATCHOS
+// CHECK-WATCHOS:   cmdsize 16
+// CHECK-WATCHOS:   version 1.0
index ab77fdc..58d2c9f 100644 (file)
@@ -694,38 +694,46 @@ void MachODumper::printMachODataInCode() {
 
 void MachODumper::printMachOVersionMin() {
   for (const auto &Load : Obj->load_commands()) {
-    if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX ||
-        Load.C.cmd == MachO::LC_VERSION_MIN_IPHONEOS) {
-      MachO::version_min_command VMC = Obj->getVersionMinLoadCommand(Load);
-      DictScope Group(W, "MinVersion");
-      StringRef Cmd;
-      if (Load.C.cmd == MachO::LC_VERSION_MIN_MACOSX)
-        Cmd = "LC_VERSION_MIN_MACOSX";
-      else
-        Cmd = "LC_VERSION_MIN_IPHONEOS";
-      W.printString("Cmd", Cmd);
-      W.printNumber("Size", VMC.cmdsize);
-      SmallString<32> Version;
-      Version = utostr(MachOObjectFile::getVersionMinMajor(VMC, false)) + "." +
-        utostr(MachOObjectFile::getVersionMinMinor(VMC, false));
-      uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, false);
+    StringRef Cmd;
+    switch (Load.C.cmd) {
+    case MachO::LC_VERSION_MIN_MACOSX:
+      Cmd = "LC_VERSION_MIN_MACOSX";
+      break;
+    case MachO::LC_VERSION_MIN_IPHONEOS:
+      Cmd = "LC_VERSION_MIN_IPHONEOS";
+      break;
+    case MachO::LC_VERSION_MIN_TVOS:
+      Cmd = "LC_VERSION_MIN_TVOS";
+      break;
+    case MachO::LC_VERSION_MIN_WATCHOS:
+      Cmd = "LC_VERSION_MIN_WATCHOS";
+      break;
+    default:
+      continue;
+    }
+
+    MachO::version_min_command VMC = Obj->getVersionMinLoadCommand(Load);
+    DictScope Group(W, "MinVersion");
+    W.printString("Cmd", Cmd);
+    W.printNumber("Size", VMC.cmdsize);
+    SmallString<32> Version;
+    Version = utostr(MachOObjectFile::getVersionMinMajor(VMC, false)) + "." +
+              utostr(MachOObjectFile::getVersionMinMinor(VMC, false));
+    uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, false);
+    if (Update != 0)
+      Version += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC, false));
+    W.printString("Version", Version);
+    SmallString<32> SDK;
+    if (VMC.sdk == 0)
+      SDK = "n/a";
+    else {
+      SDK = utostr(MachOObjectFile::getVersionMinMajor(VMC, true)) + "." +
+            utostr(MachOObjectFile::getVersionMinMinor(VMC, true));
+      uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, true);
       if (Update != 0)
-        Version += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC,
-                                                                     false));
-      W.printString("Version", Version);
-      SmallString<32> SDK;
-      if (VMC.sdk == 0)
-        SDK = "n/a";
-      else {
-        SDK = utostr(MachOObjectFile::getVersionMinMajor(VMC, true)) + "." +
-          utostr(MachOObjectFile::getVersionMinMinor(VMC, true));
-        uint32_t Update = MachOObjectFile::getVersionMinUpdate(VMC, true);
-        if (Update != 0)
-          SDK += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC,
-                                                                   true));
-      }
-      W.printString("SDK", SDK);
+        SDK += "." + utostr(MachOObjectFile::getVersionMinUpdate(VMC, true));
     }
+    W.printString("SDK", SDK);
   }
 }