]> granicus.if.org Git - clang/commitdiff
Driver/Darwin: Track target platform more explicitly in tool chain, eventually
authorDaniel Dunbar <daniel@zuster.org>
Wed, 27 Jan 2010 00:56:25 +0000 (00:56 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 27 Jan 2010 00:56:25 +0000 (00:56 +0000)
this should just be part of the tool chain itself once we have eliminated
argument translation.

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

lib/Driver/HostInfo.cpp
lib/Driver/ToolChains.cpp
lib/Driver/ToolChains.h

index ed73b17d75f1c3431511d4d93e1b87467cbccb2c..01fd32d1db20df24a9f5d125682456a6bd2557ae 100644 (file)
@@ -106,7 +106,7 @@ ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args,
     if (Arg *A = Args.getLastArg(options::OPT_arch)) {
       // The gcc driver behavior with multiple -arch flags wasn't consistent for
       // things which rely on a default architecture. We just use the last -arch
-      // to find the default tool chain (assuming it is valid..
+      // to find the default tool chain (assuming it is valid).
       Arch = llvm::Triple::getArchTypeForDarwinArchName(A->getValue(Args));
 
       // If it was invalid just use the host, we will reject this command line
@@ -159,8 +159,7 @@ ToolChain *DarwinHostInfo::CreateToolChain(const ArgList &Args,
 
 // Unknown Host Info
 
-/// UnknownHostInfo - Generic host information to use for unknown
-/// hosts.
+/// UnknownHostInfo - Generic host information to use for unknown hosts.
 class UnknownHostInfo : public HostInfo {
   /// Cache of tool chains we have created.
   mutable llvm::StringMap<ToolChain*> ToolChains;
index 355dbe4052d31b912bceee760f79ef4609e96d15..db3e7a82219b031ef63d8e9b54560d21ed8abc8b 100644 (file)
@@ -32,8 +32,7 @@ using namespace clang::driver::toolchains;
 
 Darwin::Darwin(const HostInfo &Host, const llvm::Triple& Triple,
                const unsigned (&_DarwinVersion)[3], bool _IsIPhoneOS)
-  : ToolChain(Host, Triple),
-    IsIPhoneOS(_IsIPhoneOS)
+  : ToolChain(Host, Triple), TargetInitialized(false), IsIPhoneOS(_IsIPhoneOS)
 {
   DarwinVersion[0] = _DarwinVersion[0];
   DarwinVersion[1] = _DarwinVersion[1];
@@ -394,14 +393,13 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
   // have something that works, we should reevaluate each translation
   // and try to push it down into tool specific logic.
 
-  Arg *OSXVersion =
-    Args.getLastArgNoClaim(options::OPT_mmacosx_version_min_EQ);
-  Arg *iPhoneVersion =
-    Args.getLastArgNoClaim(options::OPT_miphoneos_version_min_EQ);
+  Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
+  Arg *iPhoneVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
   if (OSXVersion && iPhoneVersion) {
     getDriver().Diag(clang::diag::err_drv_argument_not_allowed_with)
           << OSXVersion->getAsString(Args)
           << iPhoneVersion->getAsString(Args);
+    iPhoneVersion = 0;
   } else if (!OSXVersion && !iPhoneVersion) {
     // If neither OS X nor iPhoneOS targets were specified, check for
     // environment defines.
@@ -419,10 +417,12 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
         << OSXTarget << iPhoneOSTarget;
     } else if (OSXTarget) {
       const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
-      DAL->append(DAL->MakeJoinedArg(0, O, OSXTarget));
+      OSXVersion = DAL->MakeJoinedArg(0, O, OSXTarget);
+      DAL->append(OSXVersion);
     } else if (iPhoneOSTarget) {
       const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
-      DAL->append(DAL->MakeJoinedArg(0, O, iPhoneOSTarget));
+      iPhoneVersion = DAL->MakeJoinedArg(0, O, iPhoneOSTarget);
+      DAL->append(iPhoneVersion);
     } else {
       // Otherwise, choose the default version based on the toolchain.
 
@@ -430,14 +430,36 @@ DerivedArgList *Darwin::TranslateArgs(InputArgList &Args,
       // target is.
       if (isIPhoneOS()) {
         const Option *O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
-        DAL->append(DAL->MakeJoinedArg(0, O, IPhoneOSVersionMin));
+        iPhoneVersion = DAL->MakeJoinedArg(0, O, IPhoneOSVersionMin) ;
+        DAL->append(iPhoneVersion);
       } else {
         const Option *O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
-        DAL->append(DAL->MakeJoinedArg(0, O, MacosxVersionMin));
+        OSXVersion = DAL->MakeJoinedArg(0, O, MacosxVersionMin);
+        DAL->append(OSXVersion);
       }
     }
   }
 
+  // Set the tool chain target information.
+  unsigned Major, Minor, Micro;
+  bool HadExtra;
+  if (OSXVersion) {
+    assert(!iPhoneVersion && "Unknown target platform!");
+    if (!Driver::GetReleaseVersion(OSXVersion->getValue(Args), Major, Minor,
+                                   Micro, HadExtra) || HadExtra ||
+        Major != 10 || Minor >= 10 || Micro >= 10)
+      getDriver().Diag(clang::diag::err_drv_invalid_version_number)
+        << OSXVersion->getAsString(Args);
+  } else {
+    assert(iPhoneVersion && "Unknown target platform!");
+    if (!Driver::GetReleaseVersion(iPhoneVersion->getValue(Args), Major, Minor,
+                                   Micro, HadExtra) || HadExtra ||
+        Major >= 10 || Minor >= 100 || Micro >= 100)
+      getDriver().Diag(clang::diag::err_drv_invalid_version_number)
+        << iPhoneVersion->getAsString(Args);
+  }
+  setTarget(iPhoneVersion, Major, Minor, Micro);
+
   for (ArgList::iterator it = Args.begin(), ie = Args.end(); it != ie; ++it) {
     Arg *A = *it;
 
index 82fdf825d07dca0f394213da7c38e41583f3e834..b6cdacac300b4d3f69e4e44b8f32f8aebd295d00 100644 (file)
@@ -50,6 +50,19 @@ class VISIBILITY_HIDDEN Darwin : public ToolChain {
   /// Darwin version of tool chain.
   unsigned DarwinVersion[3];
 
+  /// Whether the information on the target has been initialized.
+  //
+  // FIXME: This should be eliminated. What we want to do is make this part of
+  // the "default target for arguments" selection process, once we get out of
+  // the argument translation business.
+  mutable bool TargetInitialized;
+
+  /// Whether we are targetting iPhoneOS target.
+  mutable bool TargetIsIPhoneOS;
+  
+  /// The OS version we are targetting.
+  mutable unsigned TargetVersion[3];
+
   /// Whether this is this an iPhoneOS toolchain.
   //
   // FIXME: This should go away, such differences should be completely
@@ -75,6 +88,37 @@ public:
   /// @name Darwin Specific Toolchain API
   /// {
 
+  // FIXME: Eliminate these ...Target functions and derive separate tool chains
+  // for these targets and put version in constructor.
+  void setTarget(bool isIPhoneOS, unsigned Major, unsigned Minor,
+                 unsigned Micro) const {
+    // FIXME: For now, allow reinitialization as long as values don't
+    // change. This will go away when we move away from argument translation.
+    if (TargetInitialized && TargetIsIPhoneOS == isIPhoneOS &&
+        TargetVersion[0] == Major && TargetVersion[1] == Minor &&
+        TargetVersion[2] == Micro)
+      return;
+
+    assert(!TargetInitialized && "Target already initialized!");
+    TargetInitialized = true;
+    TargetIsIPhoneOS = isIPhoneOS;
+    TargetVersion[0] = Major;
+    TargetVersion[1] = Minor;
+    TargetVersion[2] = Micro;
+  }
+
+  bool isTargetIPhoneOS() const {
+    assert(TargetInitialized && "Target not initialized!");
+    return TargetIsIPhoneOS;
+  }
+
+  void getTargetVersion(unsigned (&Res)[3]) const {
+    assert(TargetInitialized && "Target not initialized!");
+    Res[0] = TargetVersion[0];
+    Res[1] = TargetVersion[1];
+    Res[2] = TargetVersion[2];
+  }
+
   void getDarwinVersion(unsigned (&Res)[3]) const {
     Res[0] = DarwinVersion[0];
     Res[1] = DarwinVersion[1];