beanz updated this revision to Diff 55472.
beanz added a comment.

Use llvm::sys::path::const_iterator instead of hand slicing the paths, based on 
feedback from @rsmith.

Thanks,
-Chris


http://reviews.llvm.org/D18088

Files:
  include/clang/Basic/DiagnosticDriverKinds.td
  lib/Driver/ToolChains.cpp
  lib/Driver/ToolChains.h
  test/Driver/incompatible_sysroot.c

Index: test/Driver/incompatible_sysroot.c
===================================================================
--- /dev/null
+++ test/Driver/incompatible_sysroot.c
@@ -0,0 +1,12 @@
+// RUN: %clang -Wincompatible-sysroot -isysroot SDKs/MacOSX10.9.sdk -mios-version-min=9.0 -S -o - %s 2>&1 | FileCheck -check-prefix CHECK-OSX-IOS %s
+// RUN: %clang -Wincompatible-sysroot -isysroot SDKs/iPhoneOS9.2.sdk -mwatchos-version-min=2.0 -S -o - %s 2>&1 | FileCheck -check-prefix CHECK-IOS-WATCHOS %s
+// RUN: %clang -Wincompatible-sysroot -isysroot SDKs/iPhoneOS9.2.sdk -mtvos-version-min=9.0 -S -o - %s 2>&1 | FileCheck -check-prefix CHECK-IOS-TVOS %s
+// RUN: %clang -Wincompatible-sysroot -isysroot SDKs/iPhoneSimulator9.2.sdk -mios-version-min=9.0 -S -o - %s 2>&1 | FileCheck -check-prefix CHECK-IOS-IOSSIM %s
+// RUN: %clang -Wno-incompatible-sysroot -isysroot SDKs/MacOSX10.9.sdk -mios-version-min=9.0 -S -o - %s 2>&1 | FileCheck -check-prefix CHECK-OSX-IOS-DISABLED %s
+
+int main() { return 0; }
+// CHECK-OSX-IOS: warning: using sysroot for 'MacOSX10.9' but targeting 'iPhone'
+// CHECK-IOS-WATCHOS: warning: using sysroot for 'iPhoneOS9.2' but targeting 'Watch'
+// CHECK-IOS-TVOS: warning: using sysroot for 'iPhoneOS9.2' but targeting 'AppleTV'
+// CHECK-IOS-IOSSIM-NOT: warning: using sysroot for '{{.*}}' but targeting '{{.*}}'
+// CHECK-OSX-IOS-DISABLED-NOT: warning: using sysroot for '{{.*}}' but targeting '{{.*}}'
Index: lib/Driver/ToolChains.h
===================================================================
--- lib/Driver/ToolChains.h
+++ lib/Driver/ToolChains.h
@@ -496,6 +496,7 @@
     return TargetVersion < VersionTuple(V0, V1, V2);
   }
 
+  StringRef getPlatformFamily() const;
   StringRef getOSLibraryNameSuffix() const;
 
 public:
Index: lib/Driver/ToolChains.cpp
===================================================================
--- lib/Driver/ToolChains.cpp
+++ lib/Driver/ToolChains.cpp
@@ -329,6 +329,23 @@
   }
 }
 
+StringRef Darwin::getPlatformFamily() const {
+  switch (TargetPlatform) {
+    case DarwinPlatformKind::MacOS:
+      return "MacOSX";
+    case DarwinPlatformKind::IPhoneOS:
+    case DarwinPlatformKind::IPhoneOSSimulator:
+      return "iPhone";
+    case DarwinPlatformKind::TvOS:
+    case DarwinPlatformKind::TvOSSimulator:
+      return "AppleTV";
+    case DarwinPlatformKind::WatchOS:
+    case DarwinPlatformKind::WatchOSSimulator:
+      return "Watch";
+  }
+  llvm_unreachable("Unsupported platform");
+}
+
 StringRef Darwin::getOSLibraryNameSuffix() const {
   switch(TargetPlatform) {
   case DarwinPlatformKind::MacOS:
@@ -541,27 +558,31 @@
       if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
         StringRef isysroot = A->getValue();
         // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
-        size_t BeginSDK = isysroot.rfind("SDKs/");
-        size_t EndSDK = isysroot.rfind(".sdk");
-        if (BeginSDK != StringRef::npos && EndSDK != StringRef::npos) {
-          StringRef SDK = isysroot.slice(BeginSDK + 5, EndSDK);
-          // Slice the version number out.
-          // Version number is between the first and the last number.
-          size_t StartVer = SDK.find_first_of("0123456789");
-          size_t EndVer = SDK.find_last_of("0123456789");
-          if (StartVer != StringRef::npos && EndVer > StartVer) {
-            StringRef Version = SDK.slice(StartVer, EndVer + 1);
-            if (SDK.startswith("iPhoneOS") ||
-                SDK.startswith("iPhoneSimulator"))
-              iOSTarget = Version;
-            else if (SDK.startswith("MacOSX"))
-              OSXTarget = Version;
-            else if (SDK.startswith("WatchOS") ||
-                     SDK.startswith("WatchSimulator"))
-              WatchOSTarget = Version;
-            else if (SDK.startswith("AppleTVOS") ||
-                     SDK.startswith("AppleTVSimulator"))
-              TvOSTarget = Version;
+        llvm::sys::path::const_iterator SDKDir;
+        auto BeginSDK = llvm::sys::path::begin(isysroot);
+        auto EndSDK = llvm::sys::path::end(isysroot);
+        for (auto IT = BeginSDK; IT != EndSDK; ++IT) {
+          StringRef SDK = *IT;
+          if (SDK.endswith(".sdk")) {
+            // Slice the version number out.
+            // Version number is between the first and the last number.
+            size_t StartVer = SDK.find_first_of("0123456789");
+            size_t EndVer = SDK.find_last_of("0123456789");
+            if (StartVer != StringRef::npos && EndVer > StartVer) {
+              StringRef Version = SDK.slice(StartVer, EndVer + 1);
+              if (SDK.startswith("iPhoneOS") ||
+                  SDK.startswith("iPhoneSimulator"))
+                iOSTarget = Version;
+              else if (SDK.startswith("MacOSX"))
+                OSXTarget = Version;
+              else if (SDK.startswith("WatchOS") ||
+                       SDK.startswith("WatchSimulator"))
+                WatchOSTarget = Version;
+              else if (SDK.startswith("AppleTVOS") ||
+                       SDK.startswith("AppleTVSimulator"))
+                TvOSTarget = Version;
+            }
+            break;
           }
         }
       }
@@ -697,6 +718,19 @@
     Platform = WatchOSSimulator;
 
   setTarget(Platform, Major, Minor, Micro);
+
+  if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+    StringRef isysroot = A->getValue();
+    // Assume SDK has path: SOME_PATH/SDKs/PlatformXX.YY.sdk
+    size_t BeginSDK = isysroot.rfind("SDKs/");
+    size_t EndSDK = isysroot.rfind(".sdk");
+    if (BeginSDK != StringRef::npos && EndSDK != StringRef::npos) {
+      StringRef SDK = isysroot.slice(BeginSDK + 5, EndSDK);
+      if (!SDK.startswith(getPlatformFamily()))
+        getDriver().Diag(diag::warn_incompatible_sysroot)
+            << SDK << getPlatformFamily();
+    }
+  }
 }
 
 void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
Index: include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- include/clang/Basic/DiagnosticDriverKinds.td
+++ include/clang/Basic/DiagnosticDriverKinds.td
@@ -198,6 +198,8 @@
   "precompiled header '%0' was ignored because '%1' is not first '-include'">;
 def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">,
   InGroup<DiagGroup<"missing-sysroot">>;
+def warn_incompatible_sysroot : Warning<"using sysroot for '%0' but targeting '%1'">,
+  InGroup<DiagGroup<"incompatible-sysroot">>;
 def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">,
   InGroup<DiagGroup<"debug-compression-unavailable">>;
 def warn_drv_enabling_rtti_with_exceptions : Warning<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to