diff options
-rw-r--r-- | lib/Driver/HostInfo.cpp | 5 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 42 | ||||
-rw-r--r-- | lib/Driver/ToolChains.h | 44 |
3 files changed, 78 insertions, 13 deletions
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp index ed73b17d75..01fd32d1db 100644 --- a/lib/Driver/HostInfo.cpp +++ b/lib/Driver/HostInfo.cpp @@ -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; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 355dbe4052..db3e7a8221 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -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; diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 82fdf825d0..b6cdacac30 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -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]; |