/// Darwin provides an ARC runtime starting in MacOS X 10.7 and iOS 5.0.
ObjCRuntime Darwin::getDefaultObjCRuntime(bool isNonFragile) const {
- if (isTargetIPhoneOS())
+ if (isTargetIOSBased())
return ObjCRuntime(ObjCRuntime::iOS, TargetVersion);
if (isNonFragile)
return ObjCRuntime(ObjCRuntime::MacOSX, TargetVersion);
/// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2.
bool Darwin::hasBlocksRuntime() const {
- if (isTargetIPhoneOS())
+ if (isTargetIOSBased())
return !isIPhoneOSVersionLT(3, 2);
- else
+ else if (isTargetMacOS())
return !isMacosxVersionLT(10, 6);
+ else {
+ assert(isTargetEmbedded() && "unexpected target platform");
+ return false;
+ }
}
static const char *GetArmArchForMArch(StringRef Value) {
.Default(0);
}
+static bool isSoftFloatABI(const ArgList &Args) {
+ Arg *A = Args.getLastArg(options::OPT_msoft_float,
+ options::OPT_mhard_float,
+ options::OPT_mfloat_abi_EQ);
+ if (!A) return false;
+
+ return A->getOption().matches(options::OPT_msoft_float) ||
+ (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
+ A->getValue() == StringRef("soft"));
+}
+
StringRef Darwin::getDarwinArchName(const ArgList &Args) const {
switch (getTriple().getArch()) {
default:
Triple.setEnvironment(llvm::Triple::EABI);
} else {
SmallString<16> Str;
- Str += isTargetIPhoneOS() ? "ios" : "macosx";
+ Str += isTargetIOSBased() ? "ios" : "macosx";
Str += getTargetVersion().getAsString();
Triple.setOSName(Str);
}
void DarwinClang::AddLinkRuntimeLib(const ArgList &Args,
ArgStringList &CmdArgs,
- const char *DarwinStaticLib,
- bool AlwaysLink) const {
+ StringRef DarwinStaticLib,
+ bool AlwaysLink,
+ bool IsEmbedded) const {
SmallString<128> P(getDriver().ResourceDir);
- llvm::sys::path::append(P, "lib", "darwin", DarwinStaticLib);
+ llvm::sys::path::append(P, "lib", IsEmbedded ? "darwin_embedded" : "darwin",
+ DarwinStaticLib);
// For now, allow missing resource libraries to support developers who may
// not have compiler-rt checked out or integrated into their build (unless
return;
}
+ if (isTargetEmbedded()) {
+ // Embedded targets are simple at the moment, not supporting sanitizers and
+ // with different libraries for each member of the product { static, PIC } x
+ // { hard-float, soft-float }
+ llvm::SmallString<32> CompilerRT = StringRef("libclang_rt.");
+ CompilerRT +=
+ tools::arm::getARMFloatABI(getDriver(), Args, getTriple()) == "hard"
+ ? "hard"
+ : "soft";
+ CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a";
+
+ AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
+ return;
+ }
+
// Darwin doesn't support real static executables, don't link any runtime
// libraries with -static.
if (Args.hasArg(options::OPT_static) ||
Args.hasArg(options::OPT_fcreate_profile) ||
Args.hasArg(options::OPT_coverage)) {
// Select the appropriate runtime library for the target.
- if (isTargetIPhoneOS()) {
+ if (isTargetIOSBased()) {
AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_ios.a");
} else {
AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.profile_osx.a");
// Add Ubsan runtime library, if required.
if (Sanitize.needsUbsanRt()) {
// FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
- if (isTargetIPhoneOS()) {
+ if (isTargetIOSBased()) {
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
<< "-fsanitize=undefined";
} else {
+ assert(isTargetMacOS() && "unexpected non OS X target");
AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ubsan_osx.a", true);
// The Ubsan runtime library requires C++.
// should not be linked with the runtime library.
if (Sanitize.needsAsanRt()) {
// FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
- if (isTargetIPhoneOS() && !isTargetIOSSimulator()) {
+ if (isTargetIPhoneOS()) {
getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
<< "-fsanitize=address";
} else {
CmdArgs.push_back("-lSystem");
// Select the dynamic runtime library and the target specific static library.
- if (isTargetIPhoneOS()) {
+ if (isTargetIOSBased()) {
// If we are compiling as iOS / simulator, don't attempt to link libgcc_s.1,
// it never went into the SDK.
// Linking against libgcc_s.1 isn't needed for iOS 5.0+
// We currently always need a static runtime library for iOS.
AddLinkRuntimeLib(Args, CmdArgs, "libclang_rt.ios.a");
} else {
+ assert(isTargetMacOS() && "unexpected non MacOS platform");
// The dynamic runtime library was merged with libSystem for 10.6 and
// beyond; only 10.4 and 10.5 need an additional runtime library.
if (isMacosxVersionLT(10, 5))
// If no OSX or iOS target has been specified and we're compiling for armv7,
// go ahead as assume we're targeting iOS.
+ StringRef DarwinArchName = getDarwinArchName(Args);
if (OSXTarget.empty() && iOSTarget.empty() &&
- (getDarwinArchName(Args) == "armv7" ||
- getDarwinArchName(Args) == "armv7s"))
+ (DarwinArchName == "armv7" || DarwinArchName == "armv7s"))
iOSTarget = iOSVersionMin;
// Handle conflicting deployment targets
options::OPT_mios_simulator_version_min_EQ);
iOSSimVersion = Args.MakeJoinedArg(0, O, iOSSimTarget);
Args.append(iOSSimVersion);
- } else {
+ } else if (DarwinArchName != "armv6m" && DarwinArchName != "armv7m" &&
+ DarwinArchName != "armv7em") {
// Otherwise, assume we are targeting OS X.
const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
OSXVersion = Args.MakeJoinedArg(0, O, MacosxVersionMin);
}
}
+ DarwinPlatformKind Platform;
+ if (OSXVersion)
+ Platform = MacOS;
+ else if (iOSVersion)
+ Platform = IPhoneOS;
+ else if (iOSSimVersion)
+ Platform = IPhoneOSSimulator;
+ else
+ Platform = Embedded;
+
// Reject invalid architecture combinations.
if (iOSSimVersion && (getTriple().getArch() != llvm::Triple::x86 &&
getTriple().getArch() != llvm::Triple::x86_64)) {
// Set the tool chain target information.
unsigned Major, Minor, Micro;
bool HadExtra;
- if (OSXVersion) {
+ if (Platform == MacOS) {
assert((!iOSVersion && !iOSSimVersion) && "Unknown target platform!");
if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor,
Micro, HadExtra) || HadExtra ||
Major != 10 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
<< OSXVersion->getAsString(Args);
- } else {
+ } else if (Platform == IPhoneOS || Platform == IPhoneOSSimulator) {
const Arg *Version = iOSVersion ? iOSVersion : iOSSimVersion;
assert(Version && "Unknown target platform!");
if (!Driver::GetReleaseVersion(Version->getValue(), Major, Minor,
Major >= 10 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
<< Version->getAsString(Args);
+ } else {
+ assert(Platform == Embedded && "unexpected platform");
+ Major = Minor = Micro = 0;
}
- bool IsIOSSim = bool(iOSSimVersion);
-
// In GCC, the simulator historically was treated as being OS X in some
// contexts, like determining the link logic, despite generally being called
// with an iOS deployment target. For compatibility, we detect the
// simulator as iOS + x86, and treat it differently in a few contexts.
if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
getTriple().getArch() == llvm::Triple::x86_64))
- IsIOSSim = true;
+ Platform = IPhoneOSSimulator;
- setTarget(/*IsIPhoneOS=*/ !OSXVersion, Major, Minor, Micro, IsIOSSim);
+ setTarget(Platform, Major, Minor, Micro);
}
void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args,
// FIXME: It would be far better to avoid inserting those -static arguments,
// but we can't check the deployment target in the translation code until
// it is set here.
- if (isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) {
+ if (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0)) {
for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) {
Arg *A = *it;
++it;
// Default to use libc++ on OS X 10.9+ and iOS 7+.
if (((isTargetMacOS() && !isMacosxVersionLT(10, 9)) ||
- (isTargetIPhoneOS() && !isIPhoneOSVersionLT(7, 0))) &&
+ (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0))) &&
!Args.getLastArg(options::OPT_stdlib_EQ))
DAL->AddJoinedArg(0, Opts.getOption(options::OPT_stdlib_EQ), "libc++");
StringRef where;
// Complain about targeting iOS < 5.0 in any way.
- if (isTargetIPhoneOS() && isIPhoneOSVersionLT(5, 0))
+ if (isTargetIOSBased() && isIPhoneOSVersionLT(5, 0))
where = "iOS 5.0";
if (where != StringRef()) {
}
bool Darwin::SupportsObjCGC() const {
- // Garbage collection is supported everywhere except on iPhone OS.
- return !isTargetIPhoneOS();
+ return isTargetMacOS();
}
void Darwin::CheckObjCARC() const {
- if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6))
+ if (isTargetIOSBased()|| (isTargetMacOS() && !isMacosxVersionLT(10, 6)))
return;
getDriver().Diag(diag::err_arc_unsupported_on_toolchain);
}
BiarchTripleAliases.push_back(BiarchTriple.str());
}
-static bool isSoftFloatABI(const ArgList &Args) {
- Arg *A = Args.getLastArg(options::OPT_msoft_float,
- options::OPT_mhard_float,
- options::OPT_mfloat_abi_EQ);
- if (!A) return false;
-
- return A->getOption().matches(options::OPT_msoft_float) ||
- (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
- A->getValue() == StringRef("soft"));
-}
-
static bool isMipsArch(llvm::Triple::ArchType Arch) {
return Arch == llvm::Triple::mips ||
Arch == llvm::Triple::mipsel ||
// the argument translation business.
mutable bool TargetInitialized;
- /// Whether we are targeting iPhoneOS target.
- mutable bool TargetIsIPhoneOS;
+ enum DarwinPlatformKind {
+ MacOS,
+ IPhoneOS,
+ IPhoneOSSimulator,
+ Embedded // FIXME: embedded isn't really a Darwin platform.
+ };
- /// Whether we are targeting the iPhoneOS simulator target.
- mutable bool TargetIsIPhoneOSSimulator;
+ mutable DarwinPlatformKind TargetPlatform;
/// The OS version we are targeting.
mutable VersionTuple TargetVersion;
// 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, bool IsIOSSim) const {
- assert((!IsIOSSim || IsIPhoneOS) && "Unexpected deployment target!");
-
+ void setTarget(DarwinPlatformKind Platform, 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 &&
- TargetIsIPhoneOSSimulator == IsIOSSim &&
+ if (TargetInitialized && TargetPlatform == Platform &&
TargetVersion == VersionTuple(Major, Minor, Micro))
return;
assert(!TargetInitialized && "Target already initialized!");
TargetInitialized = true;
- TargetIsIPhoneOS = IsIPhoneOS;
- TargetIsIPhoneOSSimulator = IsIOSSim;
+ TargetPlatform = Platform;
TargetVersion = VersionTuple(Major, Minor, Micro);
}
bool isTargetIPhoneOS() const {
assert(TargetInitialized && "Target not initialized!");
- return TargetIsIPhoneOS;
+ return TargetPlatform == IPhoneOS;
}
bool isTargetIOSSimulator() const {
assert(TargetInitialized && "Target not initialized!");
- return TargetIsIPhoneOSSimulator;
+ return TargetPlatform == IPhoneOSSimulator;
+ }
+
+ bool isTargetIOSBased() const {
+ assert(TargetInitialized && "Target not initialized!");
+ return isTargetIPhoneOS() || isTargetIOSSimulator();
}
bool isTargetMacOS() const {
- return !isTargetIOSSimulator() && !isTargetIPhoneOS();
+ return TargetPlatform == MacOS;
+ }
+
+ bool isTargetEmbedded() const {
+ assert(TargetInitialized && "Target not initialized!");
+ return TargetPlatform == Embedded;
}
bool isTargetInitialized() const { return TargetInitialized; }
StringRef getDarwinArchName(const llvm::opt::ArgList &Args) const;
bool isIPhoneOSVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
- assert(isTargetIPhoneOS() && "Unexpected call for OS X target!");
+ assert(isTargetIOSBased() && "Unexpected call for non iOS target!");
return TargetVersion < VersionTuple(V0, V1, V2);
}
bool isMacosxVersionLT(unsigned V0, unsigned V1=0, unsigned V2=0) const {
- assert(!isTargetIPhoneOS() && "Unexpected call for iPhoneOS target!");
+ assert(isTargetMacOS() && "Unexpected call for non OS X target!");
return TargetVersion < VersionTuple(V0, V1, V2);
}
// This is only used with the non-fragile ABI and non-legacy dispatch.
// Mixed dispatch is used everywhere except OS X before 10.6.
- return !(!isTargetIPhoneOS() && isMacosxVersionLT(10, 6));
+ return !(isTargetMacOS() && isMacosxVersionLT(10, 6));
}
virtual bool IsUnwindTablesDefault() const;
virtual unsigned GetDefaultStackProtectorLevel(bool KernelOrKext) const {
// Stack protectors default to on for user code on 10.5,
// and for everything in 10.6 and beyond
- return isTargetIPhoneOS() ||
- (!isMacosxVersionLT(10, 6) ||
- (!isMacosxVersionLT(10, 5) && !KernelOrKext));
+ if (isTargetIOSBased())
+ return 1;
+ else if (isTargetMacOS() && !isMacosxVersionLT(10, 6))
+ return 1;
+ else if (isTargetMacOS() && !isMacosxVersionLT(10, 5) && !KernelOrKext)
+ return 1;
+
+ return 0;
}
virtual RuntimeLibType GetDefaultRuntimeLibType() const {
return ToolChain::RLT_CompilerRT;
llvm::opt::ArgStringList &CmdArgs) const;
void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs,
- const char *DarwinStaticLib,
- bool AlwaysLink = false) const;
+ StringRef DarwinStaticLib,
+ bool AlwaysLink = false,
+ bool IsEmbedded = false) const;
virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const;
// Select the float ABI as determined by -msoft-float, -mhard-float, and
// -mfloat-abi=.
-static StringRef getARMFloatABI(const Driver &D,
- const ArgList &Args,
- const llvm::Triple &Triple) {
+StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,
+ const llvm::Triple &Triple) {
StringRef FloatABI;
if (Arg *A = Args.getLastArg(options::OPT_msoft_float,
options::OPT_mhard_float,
const ArgList &Args,
std::vector<const char *> &Features,
bool ForAS) {
- StringRef FloatABI = getARMFloatABI(D, Args, Triple);
+ StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple);
if (!ForAS) {
// FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
// yet (it uses the -mfloat-abi and -msoft-float options), and it is
CmdArgs.push_back(ABIName);
// Determine floating point ABI from the options & target defaults.
- StringRef FloatABI = getARMFloatABI(D, Args, Triple);
+ StringRef FloatABI = tools::arm::getARMFloatABI(D, Args, Triple);
if (FloatABI == "soft") {
// Floating point operations and argument passing are soft.
//
Args.AddLastArg(CmdArgs, options::OPT_all__load);
Args.AddAllArgs(CmdArgs, options::OPT_allowable__client);
Args.AddLastArg(CmdArgs, options::OPT_bind__at__load);
- if (DarwinTC.isTargetIPhoneOS())
+ if (DarwinTC.isTargetIOSBased())
Args.AddLastArg(CmdArgs, options::OPT_arch__errors__fatal);
Args.AddLastArg(CmdArgs, options::OPT_dead__strip);
Args.AddLastArg(CmdArgs, options::OPT_no__dead__strip__inits__and__terms);
//
// FIXME: We may be able to remove this, once we can verify no one depends on
// it.
- if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ))
+ if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ)) {
CmdArgs.push_back("-ios_simulator_version_min");
- else if (DarwinTC.isTargetIPhoneOS())
+ CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
+ } else if (DarwinTC.isTargetIOSBased()) {
CmdArgs.push_back("-iphoneos_version_min");
- else
+ CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
+ } else if (DarwinTC.isTargetMacOS()) {
CmdArgs.push_back("-macosx_version_min");
- CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
+ CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
+ }
Args.AddLastArg(CmdArgs, options::OPT_nomultidefs);
Args.AddLastArg(CmdArgs, options::OPT_multi__module);
} else if (getDarwinToolChain().isTargetIPhoneOS()) {
if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
CmdArgs.push_back("-ldylib1.o");
- } else {
+ } else if (getDarwinToolChain().isTargetMacOS()) {
if (getDarwinToolChain().isMacosxVersionLT(10, 5))
CmdArgs.push_back("-ldylib1.o");
else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
} else if (getDarwinToolChain().isTargetIPhoneOS()) {
if (getDarwinToolChain().isIPhoneOSVersionLT(3, 1))
CmdArgs.push_back("-lbundle1.o");
- } else {
+ } else if (getDarwinToolChain().isTargetMacOS()) {
if (getDarwinToolChain().isMacosxVersionLT(10, 6))
CmdArgs.push_back("-lbundle1.o");
}
CmdArgs.push_back("-lcrt1.o");
else if (getDarwinToolChain().isIPhoneOSVersionLT(6, 0))
CmdArgs.push_back("-lcrt1.3.1.o");
- } else {
+ } else if (getDarwinToolChain().isTargetMacOS()) {
if (getDarwinToolChain().isMacosxVersionLT(10, 5))
CmdArgs.push_back("-lcrt1.o");
else if (getDarwinToolChain().isMacosxVersionLT(10, 6))
}
}
- if (!getDarwinToolChain().isTargetIPhoneOS() &&
+ if (getDarwinToolChain().isTargetMacOS() &&
Args.hasArg(options::OPT_shared_libgcc) &&
getDarwinToolChain().isMacosxVersionLT(10, 5)) {
const char *Str =
if (MArch == "armv8" || MArch == "armv8a" || MArch == "armv8-a")
CmdArgs.push_back("-mfpu=crypto-neon-fp-armv8");
- StringRef ARMFloatABI = getARMFloatABI(getToolChain().getDriver(), Args,
- getToolChain().getTriple());
+ StringRef ARMFloatABI = tools::arm::getARMFloatABI(
+ getToolChain().getDriver(), Args, getToolChain().getTriple());
CmdArgs.push_back(Args.MakeArgString("-mfloat-abi=" + ARMFloatABI));
Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
};
} // end namespace visualstudio
+namespace arm {
+ StringRef getARMFloatABI(const Driver &D, const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple);
+}
namespace XCore {
// For XCore, we do not need to instantiate tools for PreProcess, PreCompile and Compile.
// We simply use "clang -cc1" for those actions.
--- /dev/null
+// RUN: %clang -target x86_64-apple-darwin -arch armv6m -resource-dir=%S/Inputs/resource_dir %s -### 2> %t
+// RUN: %clang -target x86_64-apple-darwin -arch armv7em -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+// RUN: %clang -target x86_64-apple-darwin -arch armv7em -mhard-float -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+
+// RUN: %clang -target x86_64-apple-darwin -arch armv7m -fPIC -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+// RUN: %clang -target x86_64-apple-darwin -arch armv7 -fPIC -mfloat-abi=hard -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+// RUN: %clang -target x86_64-apple-darwin-eabi -arch armv7em -fPIC -mfloat-abi=softfp -resource-dir=%S/Inputs/resource_dir %s -### 2>> %t
+
+// ARMv6m has no float
+// CHECK: libclang_rt.soft_static.a
+
+// ARMv7em does, but defaults to soft
+// CHECK: libclang_rt.soft_static.a
+
+// Which can be overridden
+// CHECK: libclang_rt.hard_static.a
+
+// ARMv7m has no float either
+// CHECK: libclang_rt.soft_pic.a
+
+// But it can be enabled on ARMv7
+// CHECK: libclang_rt.hard_pic.a
+
+// "softfp" must link against a soft-float library since that's what the
+// callers we're compiling will expect.
+// CHECK: libclang_rt.soft_pic.a