Hoist the logic for selecting the Objective-C dispatch method into the runtime
class, from the target.  No functionality change, just less duplicated logic.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@159710 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index 10922ed..228135d 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_OBJCRUNTIME_H
 
 #include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/Support/ErrorHandling.h"
 
 namespace clang {
@@ -84,6 +85,21 @@
   /// implied behaviors for a "fragile" ABI?
   bool isFragile() const { return !isNonFragile(); }
 
+  /// The default dispatch mechanism to use for the specified architecture
+  bool isLegacyDispatchDefaultForArch(llvm::Triple::ArchType Arch) {
+    // The GNUstep runtime uses a newer dispatch method by default from
+    // version 1.6 onwards
+    if (getKind() == GNUstep && getVersion() >= VersionTuple(1, 6)) {
+      if (Arch == llvm::Triple::arm ||
+          Arch == llvm::Triple::x86 ||
+          Arch == llvm::Triple::x86_64)
+        return false;
+      // Mac runtimes use legacy dispatch everywhere except x86-64
+    } else if (isNeXTFamily() && isNonFragile())
+        return Arch != llvm::Triple::x86_64;
+    return true;
+  }
+
   /// \brief Is this runtime basically of the GNUstep family of runtimes?
   bool isGNUFamily() const {
     switch (getKind()) {
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 642d8a4..ab417bb 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -149,11 +149,6 @@
   /// -fobjc-nonfragile-abi by default.
   virtual bool IsObjCNonFragileABIDefault() const { return false; }
 
-  /// IsObjCLegacyDispatchDefault - Does this tool chain set
-  /// -fobjc-legacy-dispatch by default (this is only used with the non-fragile
-  /// ABI).
-  virtual bool IsObjCLegacyDispatchDefault() const { return true; }
-
   /// UseObjCMixedDispatchDefault - When using non-legacy dispatch, should the
   /// mixed dispatch method be used?
   virtual bool UseObjCMixedDispatch() const { return false; }
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index dce3b6d..7c163a0 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -329,12 +329,7 @@
     // Non-fragile ABI is default for everything but i386.
     return getTriple().getArch() != llvm::Triple::x86;
   }
-  virtual bool IsObjCLegacyDispatchDefault() const {
-    // This is only used with the non-fragile ABI.
 
-    // Legacy dispatch is used everywhere except on x86_64.
-    return getTriple().getArch() != llvm::Triple::x86_64;
-  }
   virtual bool UseObjCMixedDispatch() const {
     // This is only used with the non-fragile ABI and non-legacy dispatch.
 
@@ -445,14 +440,6 @@
 
   virtual bool IsMathErrnoDefault() const { return false; }
   virtual bool IsObjCNonFragileABIDefault() const { return true; }
-  virtual bool IsObjCLegacyDispatchDefault() const {
-    llvm::Triple::ArchType Arch = getTriple().getArch();
-    if (Arch == llvm::Triple::arm ||
-        Arch == llvm::Triple::x86 ||
-        Arch == llvm::Triple::x86_64)
-     return false;
-    return true;
-  }
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
@@ -464,14 +451,6 @@
 
   virtual bool IsMathErrnoDefault() const { return false; }
   virtual bool IsObjCNonFragileABIDefault() const { return true; }
-  virtual bool IsObjCLegacyDispatchDefault() const {
-    llvm::Triple::ArchType Arch = getTriple().getArch();
-    if (Arch == llvm::Triple::arm ||
-        Arch == llvm::Triple::x86 ||
-        Arch == llvm::Triple::x86_64)
-     return false;
-    return true;
-  }
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
@@ -483,14 +462,6 @@
 
   virtual bool IsMathErrnoDefault() const { return false; }
   virtual bool IsObjCNonFragileABIDefault() const { return true; }
-  virtual bool IsObjCLegacyDispatchDefault() const {
-    llvm::Triple::ArchType Arch = getTriple().getArch();
-    if (Arch == llvm::Triple::arm ||
-        Arch == llvm::Triple::x86 ||
-        Arch == llvm::Triple::x86_64)
-     return false;
-    return true;
-  }
 
   virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
                            const ActionList &Inputs) const;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 3b15d12..a5e2e40 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -2467,7 +2467,8 @@
   if (objcRuntime.isNonFragile()) {
     if (!Args.hasFlag(options::OPT_fobjc_legacy_dispatch,
                       options::OPT_fno_objc_legacy_dispatch,
-                      getToolChain().IsObjCLegacyDispatchDefault())) {
+                      objcRuntime.isLegacyDispatchDefaultForArch(
+                        getToolChain().getTriple().getArch()))) {
       if (getToolChain().UseObjCMixedDispatch())
         CmdArgs.push_back("-fobjc-dispatch-method=mixed");
       else