diff --git a/clang/include/clang/Analysis/RetainSummaryManager.h b/clang/include/clang/Analysis/RetainSummaryManager.h --- a/clang/include/clang/Analysis/RetainSummaryManager.h +++ b/clang/include/clang/Analysis/RetainSummaryManager.h @@ -495,12 +495,36 @@ /// effects. llvm::FoldingSet SimpleSummaries; + /// Create arg effects to all OS object out parameters. + ArgEffects getOSOutParametersMap(const FunctionDecl *FD, ArgEffectKind AEK); + + /// Create +1 arg effects to all OS object out parameters. Takes return type + /// into account if it's a kern_return_t or an OSObject *. + ArgEffects getOSOutParamsCreateRuleMap(const FunctionDecl *FD); + + /// Create +0 arg effects to all OS object out parameters. + ArgEffects getOSOutParamsGetRuleMap(const FunctionDecl *FD); + /// Create an OS object at +1. const RetainSummary *getOSSummaryCreateRule(const FunctionDecl *FD); + /// Create an OS object at +1 and create out-parameters at +1. + const RetainSummary * + getOSSummaryCreateRuleWithOutParams(const FunctionDecl *FD); + + /// Create an OS object at +0 and create out-parameters at +0. + const RetainSummary *getOSSummaryGetRuleWithOutParams(const FunctionDecl *FD); + /// Get an OS object at +0. const RetainSummary *getOSSummaryGetRule(const FunctionDecl *FD); + /// Create out-parameters at +1, don't care about the return value. + const RetainSummary * + getOSSummaryCreateRuleOutParamsOnly(const FunctionDecl *FD); + + /// Create out-parameters at +0, don't care about the return value. + const RetainSummary *getOSSummaryGetRuleOutParamsOnly(const FunctionDecl *FD); + /// Increment the reference count on OS object. const RetainSummary *getOSSummaryRetainRule(const FunctionDecl *FD); diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -860,6 +860,7 @@ .Case("macos", "macOS") .Case("tvos", "tvOS") .Case("watchos", "watchOS") + .Case("driverkit", "DriverKit") .Case("ios_app_extension", "iOS (App Extension)") .Case("macos_app_extension", "macOS (App Extension)") .Case("tvos_app_extension", "tvOS (App Extension)") diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -1551,6 +1551,10 @@ ``watchos`` Apple's watchOS operating system. The minimum deployment target is specified by the ``-mwatchos-version-min=*version*`` command-line argument. + +``driverkit`` + Apple's DriverKit userspace kernel extensions. The minimum deployment target + is specified as part of the triple. A declaration can typically be used even when deploying back to a platform version prior to when the declaration was introduced. When this happens, the diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -58,6 +58,7 @@ FEATURE(attribute_availability_with_version_underscores, true) FEATURE(attribute_availability_tvos, true) FEATURE(attribute_availability_watchos, true) +FEATURE(attribute_availability_driverkit, true) FEATURE(attribute_availability_with_strict, true) FEATURE(attribute_availability_with_replacement, true) FEATURE(attribute_availability_in_templates, true) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3850,6 +3850,7 @@ HelpText<"Do not link device library for CUDA/HIP device compilation">; def : Flag<["-"], "nocudalib">, Alias; def nodefaultlibs : Flag<["-"], "nodefaultlibs">; +def nodriverkitlib : Flag<["-"], "nodriverkitlib">; def nofixprebinding : Flag<["-"], "nofixprebinding">; def nolibc : Flag<["-"], "nolibc">; def nomultidefs : Flag<["-"], "nomultidefs">; diff --git a/clang/lib/Analysis/RetainSummaryManager.cpp b/clang/lib/Analysis/RetainSummaryManager.cpp --- a/clang/lib/Analysis/RetainSummaryManager.cpp +++ b/clang/lib/Analysis/RetainSummaryManager.cpp @@ -19,6 +19,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/ParentMap.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/TargetInfo.h" using namespace clang; using namespace ento; @@ -238,12 +239,25 @@ return false; } +static bool isDriverKitGetter(StringRef FName) { + llvm::Regex Re("(.*)Get([A-Z_]|$)(.*)"); + return FName.startswith("get") || Re.match(FName); +} + const RetainSummary * RetainSummaryManager::getSummaryForOSObject(const FunctionDecl *FD, StringRef FName, QualType RetTy) { assert(TrackOSObjects && "Requesting a summary for an OSObject but OSObjects are not tracked"); + if (Ctx.getTargetInfo().getTriple().isDriverKit()) { + const FunctionType *FT = FD->getType()->getAs(); + if (FName == "OSObjectRetain") + return getUnarySummary(FT, IncRef); + if (FName == "OSObjectRelease") + return getUnarySummary(FT, DecRef); + } + if (RetTy->isPointerType()) { const CXXRecordDecl *PD = RetTy->getPointeeType()->getAsCXXRecordDecl(); if (PD && isOSObjectSubclass(PD)) { @@ -258,15 +272,32 @@ return getPersistentStopSummary(); } - // All objects returned with functions *not* starting with 'get', - // or iterators, are returned at +1. - if ((!FName.startswith("get") && !FName.startswith("Get")) || - isOSIteratorSubclass(PD)) { - return getOSSummaryCreateRule(FD); + if (Ctx.getTargetInfo().getTriple().isDriverKit()) { + if (isDriverKitGetter(FName) || isOSIteratorSubclass(PD)) + return getOSSummaryGetRuleWithOutParams(FD); + else + return getOSSummaryCreateRuleWithOutParams(FD); } else { - return getOSSummaryGetRule(FD); + // All objects returned with functions *not* starting with 'get', + // or iterators, are returned at +1. + if ((!FName.startswith("get") && !FName.startswith("Get")) || + isOSIteratorSubclass(PD)) { + return getOSSummaryCreateRule(FD); + } else { + return getOSSummaryGetRule(FD); + } } } + } else if (Ctx.getTargetInfo().getTriple().isDriverKit()) { + // Under DriverKit we assume the create rule (depending on return values) + // for out-parameters by default. + if (isDriverKitGetter(FName)) { + if (const RetainSummary *Summ = getOSSummaryGetRuleOutParamsOnly(FD)) + return Summ; + } else { + if (const RetainSummary *Summ = getOSSummaryCreateRuleOutParamsOnly(FD)) + return Summ; + } } if (const auto *MD = dyn_cast(FD)) { @@ -757,6 +788,9 @@ // or that it returns zero (when the cast failed, or the input // was zero). if (TrackOSObjects) { + if (FName == "OSObjectRetain" || FName == "OSObjectRelease") + return BehaviorSummary::NoOp; + if (isOSObjectDynamicCast(FName) && FD->param_size() >= 1) { return BehaviorSummary::IdentityOrZero; } else if (isOSObjectRequiredCast(FName) && FD->param_size() >= 1) { @@ -805,6 +839,58 @@ ArgEffect(DoNothing), ArgEffect(DoNothing)); } +/// \return Whether the chain of typedefs starting from @c QT +/// has a typedef with a given name @c Name. +static bool hasTypedefNamed(QualType QT, + StringRef Name) { + while (auto *T = dyn_cast(QT)) { + const auto &Context = T->getDecl()->getASTContext(); + if (T->getDecl()->getIdentifier() == &Context.Idents.get(Name)) + return true; + QT = T->getDecl()->getUnderlyingType(); + } + return false; +} + +ArgEffects RetainSummaryManager::getOSOutParametersMap(const FunctionDecl *FD, + ArgEffectKind AEK) { + ArgEffects AE = AF.getEmptyMap(); + for (unsigned I = 0, E = FD->getNumParams(); I != E; ++I) { + QualType T = FD->parameters()[I]->getType(); + if (!T->isPointerType()) + continue; + + T = T->getPointeeType(); + // If it's a const pointer, it's not an out-parameter, + // because you cannot write into a const pointer. + if (T.isConstQualified() || !isOSObjectPtr(T)) + continue; + + AE = AF.add(AE, I, ArgEffect(AEK, ObjKind::OS)); + } + return AE; +} + +ArgEffects +RetainSummaryManager::getOSOutParamsCreateRuleMap(const FunctionDecl *FD) { + QualType RT = FD->getReturnType(); + ArgEffectKind AEK = hasTypedefNamed(RT, "kern_return_t") + ? RetainedOutParameterOnZero + : (isOSObjectPtr(RT) || RT->isBooleanType()) + ? RetainedOutParameterOnNonZero + : RetainedOutParameter; + return getOSOutParametersMap(FD, AEK); +} + +ArgEffects +RetainSummaryManager::getOSOutParamsGetRuleMap(const FunctionDecl *FD) { + // Here we assume that if the function follows the "Get" rule, + // the rule is also applied to out-parameters. It sounds intuitive + // and easy to remember that the same rules apply regardless of + // how is the value returned. + return getOSOutParametersMap(FD, UnretainedOutParameter); +} + const RetainSummary * RetainSummaryManager::getOSSummaryRetainRule(const FunctionDecl *FD) { return getPersistentSummary(RetEffect::MakeNoRet(), @@ -838,12 +924,44 @@ AF.getEmptyMap()); } +const RetainSummary *RetainSummaryManager::getOSSummaryCreateRuleWithOutParams( + const FunctionDecl *FD) { + return getPersistentSummary(RetEffect::MakeOwned(ObjKind::OS), + getOSOutParamsCreateRuleMap(FD)); +} + const RetainSummary * RetainSummaryManager::getOSSummaryGetRule(const FunctionDecl *FD) { return getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::OS), AF.getEmptyMap()); } +const RetainSummary * +RetainSummaryManager::getOSSummaryGetRuleWithOutParams(const FunctionDecl *FD) { + return getPersistentSummary(RetEffect::MakeNotOwned(ObjKind::OS), + getOSOutParamsGetRuleMap(FD)); +} + +const RetainSummary *RetainSummaryManager::getOSSummaryCreateRuleOutParamsOnly( + const FunctionDecl *FD) { + ArgEffects AE = getOSOutParamsCreateRuleMap(FD); + // If this function has no OSObject out-parameters, we shouldn't model it, + // because there's nothing remaining to model. + if (AE.isEmpty()) + return nullptr; + return getPersistentSummary(RetEffect::MakeNoRet(), AE); +} + +const RetainSummary *RetainSummaryManager::getOSSummaryGetRuleOutParamsOnly( + const FunctionDecl *FD) { + ArgEffects AE = getOSOutParamsGetRuleMap(FD); + // If this function has no OSObject out-parameters, we shouldn't model it, + // because there's nothing remaining to model. + if (AE.isEmpty()) + return nullptr; + return getPersistentSummary(RetEffect::MakeNoRet(), AE); +} + const RetainSummary * RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) { return getPersistentSummary(RetEffect::MakeOwned(ObjKind::CF), @@ -888,19 +1006,6 @@ return None; } -/// \return Whether the chain of typedefs starting from @c QT -/// has a typedef with a given name @c Name. -static bool hasTypedefNamed(QualType QT, - StringRef Name) { - while (auto *T = dyn_cast(QT)) { - const auto &Context = T->getDecl()->getASTContext(); - if (T->getDecl()->getIdentifier() == &Context.Idents.get(Name)) - return true; - QT = T->getDecl()->getUnderlyingType(); - } - return false; -} - static QualType getCallableReturnType(const NamedDecl *ND) { if (const auto *FD = dyn_cast(ND)) { return FD->getReturnType(); diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -108,6 +108,8 @@ this->TLSSupported = !Triple.isOSVersionLT(2); else this->TLSSupported = !Triple.isOSVersionLT(3); + } else if (Triple.isDriverKit()) { + // No TLS on DriverKit. } this->MCountName = "\01mcount"; diff --git a/clang/lib/Basic/Targets/OSTargets.cpp b/clang/lib/Basic/Targets/OSTargets.cpp --- a/clang/lib/Basic/Targets/OSTargets.cpp +++ b/clang/lib/Basic/Targets/OSTargets.cpp @@ -104,6 +104,19 @@ Str[4] = '0' + (OsVersion.getSubminor().getValueOr(0) % 10); Str[5] = '\0'; Builder.defineMacro("__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__", Str); + } else if (Triple.isDriverKit()) { + assert(OsVersion.getMajor() < 100 && + OsVersion.getMinor().getValueOr(0) < 100 && + OsVersion.getSubminor().getValueOr(0) < 100 && "Invalid version!"); + char Str[7]; + Str[0] = '0' + (OsVersion.getMajor() / 10); + Str[1] = '0' + (OsVersion.getMajor() % 10); + Str[2] = '0' + (OsVersion.getMinor().getValueOr(0) / 10); + Str[3] = '0' + (OsVersion.getMinor().getValueOr(0) % 10); + Str[4] = '0' + (OsVersion.getSubminor().getValueOr(0) / 10); + Str[5] = '0' + (OsVersion.getSubminor().getValueOr(0) % 10); + Str[6] = '\0'; + Builder.defineMacro("__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__", Str); } else if (Triple.isMacOSX()) { // Note that the Driver allows versions which aren't representable in the // define (because we only get a single digit for the minor and micro diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -3896,6 +3896,8 @@ return llvm::MachO::PLATFORM_TVOS; case llvm::Triple::WatchOS: return llvm::MachO::PLATFORM_WATCHOS; + case llvm::Triple::DriverKit: + return llvm::MachO::PLATFORM_DRIVERKIT; default: return /*Unknown platform*/ 0; } @@ -3976,6 +3978,9 @@ case llvm::Triple::MacOSX: FoundationDroppedInVersion = VersionTuple(/*Major=*/10, /*Minor=*/15); break; + case llvm::Triple::DriverKit: + // DriverKit doesn't need Foundation. + return false; default: llvm_unreachable("Unexpected OS"); } diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -5564,6 +5564,7 @@ case llvm::Triple::IOS: case llvm::Triple::TvOS: case llvm::Triple::WatchOS: + case llvm::Triple::DriverKit: TC = std::make_unique(*this, Target, Args); break; case llvm::Triple::DragonFly: diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -67,8 +67,9 @@ return ToolChain::RM_Disabled; } - // -frtti is default, except for the PS4. - return (Triple.isPS4()) ? ToolChain::RM_Disabled : ToolChain::RM_Enabled; + // -frtti is default, except for the PS4 and DriverKit. + bool NoRTTI = Triple.isPS4() || Triple.isDriverKit(); + return NoRTTI ? ToolChain::RM_Disabled : ToolChain::RM_Enabled; } ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -320,6 +320,7 @@ case llvm::Triple::MacOSX: case llvm::Triple::IOS: case llvm::Triple::TvOS: + case llvm::Triple::DriverKit: // Darwin defaults to "softfp" for v6 and v7. if (Triple.isWatchABI()) return FloatABI::Hard; diff --git a/clang/lib/Driver/ToolChains/Arch/X86.cpp b/clang/lib/Driver/ToolChains/Arch/X86.cpp --- a/clang/lib/Driver/ToolChains/Arch/X86.cpp +++ b/clang/lib/Driver/ToolChains/Arch/X86.cpp @@ -84,6 +84,10 @@ // Simulators can still run on 10.11 though, like Xcode. if (Triple.isMacOSX() && !Triple.isOSVersionLT(10, 12)) return "penryn"; + + if (Triple.isDriverKit()) + return "nehalem"; + // The oldest x86_64 Macs have core2/Merom; the oldest x86 Macs have Yonah. return Is64Bit ? "core2" : "yonah"; } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -451,7 +451,7 @@ if (types::isCXX(InputType)) { // Disable C++ EH by default on XCore and PS4. bool CXXExceptionsEnabled = - Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4(); + Triple.getArch() != llvm::Triple::xcore && !Triple.isPS4() && !Triple.isDriverKit(); Arg *ExceptionArg = Args.getLastArg( options::OPT_fcxx_exceptions, options::OPT_fno_cxx_exceptions, options::OPT_fexceptions, options::OPT_fno_exceptions); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1249,7 +1249,7 @@ // generation, independent of the argument order. if (KernelOrKext && ((!EffectiveTriple.isiOS() || EffectiveTriple.isOSVersionLT(6)) && - !EffectiveTriple.isWatchOS())) + !EffectiveTriple.isWatchOS() && !EffectiveTriple.isDriverKit())) PIC = PIE = false; if (Arg *A = Args.getLastArg(options::OPT_mdynamic_no_pic)) { diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -299,7 +299,8 @@ IPhoneOS, TvOS, WatchOS, - LastDarwinPlatform = WatchOS + DriverKit, + LastDarwinPlatform = DriverKit }; enum DarwinEnvironmentKind { NativeEnvironment, @@ -349,7 +350,7 @@ bool isKernelStatic() const override { return (!(isTargetIPhoneOS() && !isIPhoneOSVersionLT(6, 0)) && - !isTargetWatchOS()); + !isTargetWatchOS() && !isTargetDriverKit()); } void addProfileRTLibs(const llvm::opt::ArgList &Args, @@ -435,6 +436,11 @@ return TargetPlatform == WatchOS; } + bool isTargetDriverKit() const { + assert(TargetInitialized && "Target not initialized!"); + return TargetPlatform == DriverKit; + } + bool isTargetMacCatalyst() const { return TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst; } @@ -538,7 +544,7 @@ GetDefaultStackProtectorLevel(bool KernelOrKext) const override { // Stack protectors default to on for user code on 10.5, // and for everything in 10.6 and beyond - if (isTargetIOSBased() || isTargetWatchOSBased()) + if (isTargetIOSBased() || isTargetWatchOSBased() || isTargetDriverKit()) return LangOptions::SSPOn; else if (isTargetMacOSBased() && !isMacosxVersionLT(10, 6)) return LangOptions::SSPOn; diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -712,6 +712,26 @@ } } + // DriverKit's framework doesn't have the same layout as other frameworks. + // Add missing search paths if necessary. + if (getToolChain().getTriple().getOS() == llvm::Triple::DriverKit) { + if (const Arg *Root = Args.getLastArg(options::OPT_isysroot)) { + // ld64 fixed the implicit -F and -L paths in ld64-605.1+. + if (Version.getMajor() < 605 || + (Version.getMajor() == 605 && Version.getMinor().getValueOr(0) < 1)) { + + SmallString<128> L(Root->getValue()); + llvm::sys::path::append(L, "System", "DriverKit", "usr", "lib"); + CmdArgs.push_back(Args.MakeArgString(std::string("-L") + L)); + + SmallString<128> F(Root->getValue()); + llvm::sys::path::append(F, "System", "DriverKit"); + llvm::sys::path::append(F, "System", "Library", "Frameworks"); + CmdArgs.push_back(Args.MakeArgString(std::string("-F") + F)); + } + } + } + ResponseFileSupport ResponseSupport; if (Version >= VersionTuple(705) || LinkerIsLLD) { ResponseSupport = ResponseFileSupport::AtFileUTF8(); @@ -872,7 +892,7 @@ // Default to use libc++ on OS X 10.9+ and iOS 7+. if ((isTargetMacOSBased() && !isMacosxVersionLT(10, 9)) || (isTargetIOSBased() && !isIPhoneOSVersionLT(7, 0)) || - isTargetWatchOSBased()) + isTargetWatchOSBased() || isTargetDriverKit()) return ToolChain::CST_Libcxx; return ToolChain::CST_Libstdcxx; @@ -891,7 +911,7 @@ /// Darwin provides a blocks runtime starting in MacOS X 10.6 and iOS 3.2. bool Darwin::hasBlocksRuntime() const { - if (isTargetWatchOSBased()) + if (isTargetWatchOSBased() || isTargetDriverKit()) return true; else if (isTargetIOSBased()) return !isIPhoneOSVersionLT(3, 2); @@ -1018,6 +1038,8 @@ Str += "watchos"; else if (isTargetTvOSBased()) Str += "tvos"; + else if (isTargetDriverKit()) + Str += "driverkit"; else if (isTargetIOSBased() || isTargetMacCatalyst()) Str += "ios"; else @@ -1219,6 +1241,8 @@ return "AppleTV"; case DarwinPlatformKind::WatchOS: return "Watch"; + case DarwinPlatformKind::DriverKit: + return "DriverKit"; } llvm_unreachable("Unsupported platform"); } @@ -1250,6 +1274,8 @@ case DarwinPlatformKind::WatchOS: return TargetEnvironment == NativeEnvironment || IgnoreSim ? "watchos" : "watchossim"; + case DarwinPlatformKind::DriverKit: + return "driverkit"; } llvm_unreachable("Unsupported platform"); } @@ -1407,9 +1433,15 @@ AddLinkRuntimeLib(Args, CmdArgs, "xray-fdr"); } + if (isTargetDriverKit() && !Args.hasArg(options::OPT_nodriverkitlib)) { + CmdArgs.push_back("-framework"); + CmdArgs.push_back("DriverKit"); + } + // Otherwise link libSystem, then the dynamic runtime library, and finally any // target specific static runtime library. - CmdArgs.push_back("-lSystem"); + if (!isTargetDriverKit()) + CmdArgs.push_back("-lSystem"); // Select the dynamic runtime library and the target specific static library. if (isTargetIOSBased()) { @@ -1524,6 +1556,9 @@ case DarwinPlatformKind::WatchOS: Opt = options::OPT_mwatchos_version_min_EQ; break; + case DarwinPlatformKind::DriverKit: + // DriverKit always explicitly provides a version in the triple. + return; } Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersion); Args.append(Argument); @@ -1663,6 +1698,8 @@ return DarwinPlatformKind::TvOS; case llvm::Triple::WatchOS: return DarwinPlatformKind::WatchOS; + case llvm::Triple::DriverKit: + return DarwinPlatformKind::DriverKit; default: llvm_unreachable("Unable to infer Darwin variant"); } @@ -1732,6 +1769,7 @@ "IPHONEOS_DEPLOYMENT_TARGET", "TVOS_DEPLOYMENT_TARGET", "WATCHOS_DEPLOYMENT_TARGET", + "DRIVERKIT_DEPLOYMENT_TARGET", }; static_assert(llvm::array_lengthof(EnvVars) == Darwin::LastDarwinPlatform + 1, "Missing platform"); @@ -1830,6 +1868,8 @@ return DarwinPlatform::createFromSDK( Darwin::TvOS, Version, /*IsSimulator=*/SDK.startswith("AppleTVSimulator")); + else if (SDK.startswith("DriverKit")) + return DarwinPlatform::createFromSDK(Darwin::DriverKit, Version); return None; }; if (auto Result = CreatePlatformFromSDKName(SDK)) @@ -1866,6 +1906,9 @@ case llvm::Triple::WatchOS: OsVersion = Triple.getWatchOSVersion(); break; + case llvm::Triple::DriverKit: + OsVersion = Triple.getDriverKitVersion(); + break; default: llvm_unreachable("Unexpected OS type"); break; @@ -2167,12 +2210,19 @@ HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100) getDriver().Diag(diag::err_drv_invalid_version_number) << OSTarget->getAsString(Args, Opts); + } else if (Platform == DriverKit) { + if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor, + Micro, HadExtra) || + HadExtra || Major < 19 || Major >= 100 || Minor >= 100 || Micro >= 100) + getDriver().Diag(diag::err_drv_invalid_version_number) + << OSTarget->getAsString(Args, Opts); } else llvm_unreachable("unknown kind of Darwin platform"); DarwinEnvironmentKind Environment = OSTarget->getEnvironment(); // Recognize iOS targets with an x86 architecture as the iOS simulator. if (Environment == NativeEnvironment && Platform != MacOS && + Platform != DriverKit && OSTarget->canInferSimulatorFromArch() && getTriple().isX86()) Environment = Simulator; @@ -2460,6 +2510,8 @@ llvm::sys::path::append(P, "libclang_rt.cc_kext_tvos.a"); } else if (isTargetIPhoneOS()) { llvm::sys::path::append(P, "libclang_rt.cc_kext_ios.a"); + } else if (isTargetDriverKit()) { + // DriverKit doesn't want extra runtime support. } else { llvm::sys::path::append(P, "libclang_rt.cc_kext.a"); } @@ -2682,6 +2734,8 @@ case WatchOS: // Earlier than 4.0. OS = llvm::Triple::WatchOS; break; + case DriverKit: // Always available. + return false; } return TargetVersion < alignedAllocMinVersion(OS); @@ -2781,7 +2835,7 @@ // 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 (isTargetWatchOSBased() || + if (isTargetWatchOSBased() || isTargetDriverKit() || (isTargetIOSBased() && !isIPhoneOSVersionLT(6, 0))) { for (ArgList::iterator it = DAL->begin(), ie = DAL->end(); it != ie; ) { Arg *A = *it; @@ -2897,6 +2951,8 @@ CmdArgs.push_back("-tvos_version_min"); else if (isTargetTvOSSimulator()) CmdArgs.push_back("-tvos_simulator_version_min"); + else if (isTargetDriverKit()) + CmdArgs.push_back("-driverkit_version_min"); else if (isTargetIOSSimulator()) CmdArgs.push_back("-ios_simulator_version_min"); else if (isTargetIOSBased()) @@ -2946,6 +3002,8 @@ return "tvos"; case Darwin::WatchOS: return "watchos"; + case Darwin::DriverKit: + return "driverkit"; } llvm_unreachable("invalid platform"); } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3163,7 +3163,10 @@ #if defined(CLANG_DEFAULT_STD_CXX) LangStd = CLANG_DEFAULT_STD_CXX; #else - LangStd = LangStandard::lang_gnucxx14; + if (T.isDriverKit()) + LangStd = LangStandard::lang_gnucxx17; + else + LangStd = LangStandard::lang_gnucxx14; #endif break; case Language::RenderScript: diff --git a/clang/test/Analysis/driverkit_base.h b/clang/test/Analysis/driverkit_base.h new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/driverkit_base.h @@ -0,0 +1,22 @@ +#ifndef _DRIVERKIT_BASE +#define _DRIVERKIT_BASE + +using OSObjectPtr = OSObject *; + +void OSObjectRetain(OSObjectPtr container); +void OSObjectRelease(OSObjectPtr container); + +#define OSObjectSafeReleaseNULL(ptr) \ + do { \ + if ((ptr)) { \ + OSObjectRelease(ptr); \ + (ptr) = NULL; \ + } \ + } while (0) + +class OSDictionary : public OSObject {}; +using OSDictionaryPtr = OSDictionary *; +OSDictionaryPtr OSDictionaryCreate(); +OSObjectPtr OSDictionaryGetValue(OSDictionaryPtr obj, const char *key); + +#endif // _DRIVERKIT_BASE diff --git a/clang/test/Analysis/retain-release-driverkit.cpp b/clang/test/Analysis/retain-release-driverkit.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Analysis/retain-release-driverkit.cpp @@ -0,0 +1,76 @@ +// RUN: %clang_analyze_cc1 -w -triple x86_64-apple-driverkit19.0 \ +// RUN: -analyzer-checker=core,osx -verify %s + +#include "os_object_base.h" +#include "driverkit_base.h" + +typedef kern_return_t IOReturn; +#define kIOReturnSuccess 0 + +void test_driverkit_naming_conventions(OSDictionary *Dict) { + OSDictionaryGetValue(Dict, "key"); // no-warning + OSDictionaryPtr Dict2 = OSDictionaryCreate(); // expected-warning{{Potential leak of an object stored into 'Dict2'}} +} + +void test_driverkit_retain_release() { + OSDictionaryPtr Dict = OSDictionaryCreate(); + OSObjectRetain(Dict); + OSObjectRelease(Dict); + OSObjectRelease(Dict); +} + +IOReturn make_out_param_and_ioreturn(OSObject **obj); +OSObject *make_out_param_and_osobject(OSObject **obj); +bool make_out_param_and_bool(OSObject **obj); +void just_make_out_param(OSObject **obj); +void get_out_param(OSObject **obj); +void get_out_param_annotated(__attribute__((os_returns_retained)) OSObject **obj); +IOReturn get_out_param_and_ioreturn(OSObject **obj); + +void test_out_param_conventions() { + OSObject *Obj = nullptr; + // Don't warn when the function returned a failure. + IOReturn ret = make_out_param_and_ioreturn(&Obj); // no-warning + if (ret == kIOReturnSuccess) + OSObjectRelease(Obj); + + // Warn if the return value is unchecked. + make_out_param_and_ioreturn(&Obj); // expected-warning{{Potential leak of an object stored into 'Obj'}} + + // If it looks like a getter, treat it as +0. + OSObject *Obj2; + ret = get_out_param_and_ioreturn(&Obj2); + if (ret == kIOReturnSuccess) + OSObjectRelease(Obj2); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} + + // Treat "true" as success, "false" as failure by default. + bool b = make_out_param_and_bool(&Obj2); // no-warning + if (b) + OSObjectRelease(Obj2); + + // Warn only when the object that was returned directly + // has turned out to be valid (or nobody cared). + OSObject *Obj3; // Let's also see what happens if it's uninitialized. + OSObject *Obj4 = make_out_param_and_osobject(&Obj3); // no-warning + if (Obj4) { + OSObjectRelease(Obj3); // no-warning + OSObjectRelease(Obj4); // no-warning + } + + make_out_param_and_osobject(&Obj3); // expected-warning{{Potential leak of an object of type 'OSObject'}} + // expected-warning@-1{{Potential leak of an object stored into 'Obj3'}} + + // When there's no return value, always treat it as +1... + OSObject *Obj5 = nullptr; + just_make_out_param(&Obj5); // expected-warning{{Potential leak of an object stored into 'Obj5'}} + + // ...unless it looks like a getter, in this case treat it as +0. + OSObject *Obj6 = nullptr; + get_out_param(&Obj6); // no-warning + if (Obj6) + OSObjectRelease(Obj6); // expected-warning{{Incorrect decrement of the reference count of an object that is not owned at this point by the caller}} + + OSObject *Obj7 = nullptr; + get_out_param_annotated(&Obj7); + OSObjectRelease(Obj7); // no-warning +} diff --git a/clang/test/CodeGen/availability-check-driverkit.c b/clang/test/CodeGen/availability-check-driverkit.c new file mode 100644 --- /dev/null +++ b/clang/test/CodeGen/availability-check-driverkit.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple x86_64-apple-driverkit19.0 -emit-llvm -o - %s | FileCheck %s + +void use_at_available() { + // CHECK: call i32 @__isPlatformVersionAtLeast(i32 10, i32 19, i32 1, i32 0) + // CHECK-NEXT: icmp ne + if (__builtin_available(driverkit 19.1, *)) + ; +} + +// CHECK: declare i32 @__isPlatformVersionAtLeast(i32, i32, i32, i32) diff --git a/clang/test/Driver/Inputs/DriverKit19.0.sdk/SDKSettings.plist b/clang/test/Driver/Inputs/DriverKit19.0.sdk/SDKSettings.plist new file mode 100644 diff --git a/clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/usr/include/.keep b/clang/test/Driver/Inputs/DriverKit19.0.sdk/System/DriverKit/usr/include/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_darwin_driverkit_sdk_usr_cxx_v1/System/DriverKit/usr/include/c++/v1/.keep b/clang/test/Driver/Inputs/basic_darwin_driverkit_sdk_usr_cxx_v1/System/DriverKit/usr/include/c++/v1/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/basic_darwin_driverkit_sdk_usr_cxx_v1/System/DriverKit/usr/lib/.keep b/clang/test/Driver/Inputs/basic_darwin_driverkit_sdk_usr_cxx_v1/System/DriverKit/usr/lib/.keep new file mode 100644 diff --git a/clang/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.driverkit.a b/clang/test/Driver/Inputs/resource_dir/lib/darwin/libclang_rt.driverkit.a new file mode 100644 diff --git a/clang/test/Driver/darwin-ld-platform-version-driverkit.c b/clang/test/Driver/darwin-ld-platform-version-driverkit.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/darwin-ld-platform-version-driverkit.c @@ -0,0 +1,20 @@ +// RUN: touch %t.o + +// RUN: %clang -target x86_64-apple-driverkit10.15 -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=520 -### %t.o 2>&1 \ +// RUN: | FileCheck %s +// RUN: mkdir -p %t.sdk +// RUN: %clang -target x86_64-apple-driverkit19 -isysroot %t.sdk -mlinker-version=520 -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=MISSING-SDK-JSON-WORKAROUND %s + +// RUN: %clang -target arm64-apple-driverkit19 -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=520 -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=ARM64_NEW %s +// RUN: %clang -target arm64-apple-driverkit19 -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=400 -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=ARM64_OLD %s +// RUN: %clang -target arm64e-apple-driverkit19 -isysroot %S/Inputs/MacOSX10.14.sdk -mlinker-version=520 -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=ARM64_NEW %s + +// CHECK: "-platform_version" "driverkit" "10.15.0" "10.14" +// MISSING-SDK-JSON-WORKAROUND: "-platform_version" "driverkit" "19.0.0" "19.0.0" + +// ARM64_NEW: "-platform_version" "driverkit" "20.0.0" "10.14" +// ARM64_OLD: "-driverkit_version_min" "20.0.0" diff --git a/clang/test/Driver/darwin-ld.c b/clang/test/Driver/darwin-ld.c --- a/clang/test/Driver/darwin-ld.c +++ b/clang/test/Driver/darwin-ld.c @@ -185,6 +185,15 @@ // LINK_TVOS_KEXT: libclang_rt.cc_kext_tvos.a // LINK_TVOS_KEXT: libclang_rt.tvos.a +// RUN: %clang -target x86-64-apple-driverkit19.0 -mlinker-version=400 -resource-dir=%S/Inputs/resource_dir -### %t.o 2> %t.log +// RUN: FileCheck -check-prefix=LINK_DRIVERKIT %s < %t.log +// LINK_DRIVERKIT: {{ld(.exe)?"}} +// LINK_DRIVERKIT: -driverkit_version_min +// LINK_DRIVERKIT-NOT: crt +// LINK_DRIVERKIT-NOT: lgcc_s.1 +// LINK_DRIVERKIT-NOT: lSystem +// LINK_DRIVERKIT: libclang_rt.driverkit.a + // RUN: %clang -target armv7k-apple-watchos2.0 -fuse-ld= -mlinker-version=400 -mwatchos-version-min=2.0 -resource-dir=%S/Inputs/resource_dir -### %t.o 2> %t.log // RUN: FileCheck -check-prefix=LINK_WATCHOS_ARM %s < %t.log // LINK_WATCHOS_ARM: {{ld(.exe)?"}} diff --git a/clang/test/Driver/darwin-version.c b/clang/test/Driver/darwin-version.c --- a/clang/test/Driver/darwin-version.c +++ b/clang/test/Driver/darwin-version.c @@ -98,6 +98,10 @@ // RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHSIM20 %s // CHECK-VERSION-WATCHSIM20: "i386-apple-watchos2.0.0-simulator" +// RUN: %clang -target x86_64-apple-driverkit19.0 -c %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-VERSION-DRIVERKIT190 %s +// CHECK-VERSION-DRIVERKIT190: "x86_64-apple-driverkit19.0.0" + // Check environment variable gets interpreted correctly // RUN: env MACOSX_DEPLOYMENT_TARGET=10.5 IPHONEOS_DEPLOYMENT_TARGET=2.0 \ // RUN: %clang -target i686-apple-darwin9 -c %s -### 2>&1 | \ @@ -145,6 +149,15 @@ // RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHOS-TARGET %s // CHECK-VERSION-WATCHOS-TARGET: "x86_64-apple-watchos4.0.0-simulator" +// RUN: env DRIVERKIT_DEPLOYMENT_TARGET=19.0 \ +// RUN: %clang -target x86_64-apple-darwin -c %s -### 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-VERSION-DRIVERKIT %s +// CHECK-VERSION-DRIVERKIT: "x86_64-apple-driverkit19.0.0" +// +// Make sure stdlib is not mistaken +// RUN: env DRIVERKIT_DEPLOYMENT_TARGET=2.0 \ +// RUN: %clang -target arm64-apple-darwin -c -x c++ %s -stdlib=libc++ -### 2>&1 + // RUN: env MACOSX_DEPLOYMENT_TARGET=1000.1000 \ // RUN: %clang -target x86_64-apple-darwin -c %s -### 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK-VERSION-INVALID-ENV %s diff --git a/clang/test/Driver/debug-options.c b/clang/test/Driver/debug-options.c --- a/clang/test/Driver/debug-options.c +++ b/clang/test/Driver/debug-options.c @@ -66,6 +66,9 @@ // RUN: %clang -### -c -g %s -target arm64-apple-tvos9.0 2>&1 \ // RUN: | FileCheck -check-prefix=G_STANDALONE \ // RUN: -check-prefix=G_DWARF4 %s +// RUN: %clang -### -c -g %s -target x86_64-apple-driverkit19.0 2>&1 \ +// RUN: | FileCheck -check-prefix=G_STANDALONE \ +// RUN: -check-prefix=G_DWARF4 %s // RUN: %clang -### -c -fsave-optimization-record %s \ // RUN: -target x86_64-apple-darwin 2>&1 \ // RUN: | FileCheck -check-prefix=GLTO_ONLY %s diff --git a/clang/test/Driver/driverkit-arm64.c b/clang/test/Driver/driverkit-arm64.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-arm64.c @@ -0,0 +1,4 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang %s -target arm64-apple-driverkit -### 2>&1 | FileCheck %s + +// CHECK: "-target-cpu" "apple-a7" diff --git a/clang/test/Driver/driverkit-arm64e.c b/clang/test/Driver/driverkit-arm64e.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-arm64e.c @@ -0,0 +1,4 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang %s -target arm64e-apple-driverkit -### 2>&1 | FileCheck %s + +// CHECK: "-target-cpu" "apple-a12" diff --git a/clang/test/Driver/driverkit-armv7k.s b/clang/test/Driver/driverkit-armv7k.s new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-armv7k.s @@ -0,0 +1,5 @@ +// RUN: %clang -c -x assembler-with-cpp -target armv7k-apple-driverkit21.0 -### %s 2>&1 | FileCheck %s +// CHECK: -cc1as +// CHECK-SAME: "-target-cpu" "cortex-a7" +.foo: +vfms.f64 d1, d0, d3 \ No newline at end of file diff --git a/clang/test/Driver/driverkit-cplusplus.cpp b/clang/test/Driver/driverkit-cplusplus.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-cplusplus.cpp @@ -0,0 +1,8 @@ +// REQUIRES: x86-registered-target +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -fsyntax-only + +#if __cplusplus != 201703L +#error DriverKit should be on C++17. +#endif + +int main() { return 0; } diff --git a/clang/test/Driver/driverkit-exceptions.cpp b/clang/test/Driver/driverkit-exceptions.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-exceptions.cpp @@ -0,0 +1,9 @@ +// REQUIRES: x86-registered-target +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -### 2>&1 | FileCheck %s -check-prefix=DEFAULT +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -fexceptions -### 2>&1 | FileCheck %s -check-prefix=USERPROVIDED + +int main() { return 0; } +// DEFAULT-NOT: "-fcxx-exceptions" +// DEFAULT-NOT: "-fexceptions" +// USERPROVIDED: "-fcxx-exceptions" +// USERPROVIDED: "-fexceptions" diff --git a/clang/test/Driver/driverkit-framework.c b/clang/test/Driver/driverkit-framework.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-framework.c @@ -0,0 +1,13 @@ +// RUN: %clang %s -target x86_64-apple-driverkit19.0 \ +// RUN: -isysroot %S/Inputs/DriverKit19.0.sdk -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-DEFAULT + +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -nodriverkitlib \ +// RUN: -isysroot %S/Inputs/DriverKit19.0.sdk -### 2>&1 \ +// RUN: | FileCheck %s -check-prefix=CHECK-NO-DRIVERKIT + +int main() { return 0; } + +// CHECK-DEFAULT: "-framework" "DriverKit" + +// CHECK-NO-DRIVERKIT-NOT: "-framework" "DriverKit" diff --git a/clang/test/Driver/driverkit-rtti.cpp b/clang/test/Driver/driverkit-rtti.cpp new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-rtti.cpp @@ -0,0 +1,5 @@ +// REQUIRES: x86-registered-target +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -### 2>&1 | FileCheck %s + +int main() { return 0; } +// CHECK: "-fno-rtti" diff --git a/clang/test/Driver/driverkit-target-cpu.c b/clang/test/Driver/driverkit-target-cpu.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-target-cpu.c @@ -0,0 +1,5 @@ +// REQUIRES: x86-registered-target +// RUN: %clang %s -target x86_64-apple-driverkit19.0 -### 2>&1 | FileCheck %s + +int main() { return 0; } +// CHECK: "-target-cpu" "nehalem" diff --git a/clang/test/Driver/driverkit-version-min.c b/clang/test/Driver/driverkit-version-min.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/driverkit-version-min.c @@ -0,0 +1,5 @@ +// REQUIRES: x86-registered-target +// RUN: %clang -target x86_64-apple-driverkit19.0 -S -o - %s | FileCheck %s + +int main() { return 0; } +// CHECK: .build_version driverkit, 19, 0 diff --git a/clang/test/Driver/incompatible_sysroot.c b/clang/test/Driver/incompatible_sysroot.c --- a/clang/test/Driver/incompatible_sysroot.c +++ b/clang/test/Driver/incompatible_sysroot.c @@ -4,6 +4,8 @@ // RUN: %clang -target x86_64-apple-darwin -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 -target arm64-apple-darwin -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 -target arm64-apple-darwin -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 -target x86_64-apple-driverkit19.0 -Wincompatible-sysroot -isysroot SDKs/MacOSX10.9.sdk -S -o - %s 2>&1 | FileCheck -check-prefix CHECK-OSX-DRIVERKIT %s +// RUN: %clang -target x86_64-apple-driverkit19.0 -Wincompatible-sysroot -isysroot SDKs/iPhoneOS9.2.sdk -S -o - %s 2>&1 | FileCheck -check-prefix CHECK-IOS-DRIVERKIT %s // RUN: %clang -target x86_64-apple-darwin -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 -target x86_64-apple-darwin -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 @@ -11,5 +13,7 @@ // CHECK-OSX-IOS: warning: using sysroot for 'MacOSX' but targeting 'iPhone' // CHECK-IOS-WATCHOS: warning: using sysroot for 'iPhoneOS' but targeting 'Watch' // CHECK-IOS-TVOS: warning: using sysroot for 'iPhoneOS' but targeting 'AppleTV' +// CHECK-OSX-DRIVERKIT: warning: using sysroot for 'MacOSX' but targeting 'DriverKit' +// CHECK-IOS-DRIVERKIT: warning: using sysroot for 'iPhoneOS' but targeting 'DriverKit' // CHECK-IOS-IOSSIM-NOT: warning: using sysroot for '{{.*}}' but targeting '{{.*}}' // CHECK-OSX-IOS-DISABLED-NOT: warning: using sysroot for '{{.*}}' but targeting '{{.*}}' diff --git a/clang/test/Driver/instrprof-ld.c b/clang/test/Driver/instrprof-ld.c --- a/clang/test/Driver/instrprof-ld.c +++ b/clang/test/Driver/instrprof-ld.c @@ -107,6 +107,14 @@ // CHECK-WATCHOS-ARMV7: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}darwin{{/|\\\\}}libclang_rt.profile_watchos.a" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target x86_64-apple-driverkit19.0 -arch x86_64 -fprofile-instr-generate -fuse-ld=ld \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: | FileCheck --check-prefix=CHECK-DRIVERKIT-X86_64 %s +// +// CHECK-DRIVERKIT-X86_64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-DRIVERKIT-X86_64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}darwin{{/|\\\\}}libclang_rt.profile_driverkit.a" +// +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target i386-pc-win32 -fprofile-instr-generate \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: | FileCheck --check-prefix=CHECK-WINDOWS-I386 %s diff --git a/clang/test/Driver/pic.c b/clang/test/Driver/pic.c --- a/clang/test/Driver/pic.c +++ b/clang/test/Driver/pic.c @@ -231,6 +231,8 @@ // RUN: | FileCheck %s --check-prefix=CHECK-NO-STATIC // RUN: %clang -c %s -target armv7k-apple-watchos1 -fapple-kext -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-PIC2 +// RUN: %clang -c %s -target x86_64-apple-driverkit -fapple-kext -### 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-PIC2 // RUN: %clang -c %s -target armv7-apple-ios5 -fapple-kext -### 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-NO-PIC // RUN: %clang -c %s -target armv7-apple-ios6 -fapple-kext -static -### 2>&1 \ diff --git a/clang/test/Driver/stack-protector.c b/clang/test/Driver/stack-protector.c --- a/clang/test/Driver/stack-protector.c +++ b/clang/test/Driver/stack-protector.c @@ -38,6 +38,8 @@ // RUN: %clang -target armv7k-apple-watchos2.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_WATCHOS // RUN: %clang -ffreestanding -target armv7k-apple-watchos2.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_WATCHOS // SSP_WATCHOS: "-stack-protector" "1" +// RUN: %clang -target x86_64-apple-driverkit19.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_DRIVERKIT +// SSP_DRIVERKIT: "-stack-protector" "1" // RUN: %clang -target arm64-apple-ios8.0.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_IOS // RUN: %clang -ffreestanding -target arm64-apple-ios8.0.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_IOS // SSP_IOS: "-stack-protector" "1" diff --git a/clang/test/Frontend/darwin-version.c b/clang/test/Frontend/darwin-version.c --- a/clang/test/Frontend/darwin-version.c +++ b/clang/test/Frontend/darwin-version.c @@ -51,3 +51,8 @@ // RUN: grep '__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__' %t | grep '20100' | count 1 // RUN: not grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t // RUN: not grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t + +// RUN: %clang_cc1 -triple x86_64-apple-driverkit19.0 -dM -E -o %t %s +// RUN: grep '__ENVIRONMENT_DRIVERKIT_VERSION_MIN_REQUIRED__' %t | grep '1900' | count 1 +// RUN: not grep '__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__' %t +// RUN: not grep '__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__' %t diff --git a/clang/test/Preprocessor/arm-target-features.c b/clang/test/Preprocessor/arm-target-features.c --- a/clang/test/Preprocessor/arm-target-features.c +++ b/clang/test/Preprocessor/arm-target-features.c @@ -834,6 +834,9 @@ // CHECK-V82A: #define __ARM_FEATURE_QRDMX 1 // CHECK-V82A: #define __ARM_FP 0xe +// RUN: %clang -target armv7-apple-driverkit21.0 -x c %s -dM -E -o - | FileCheck -match-full-lines --check-prefix=CHECK-DRIVERKIT %s +// CHECK-DRIVERKIT-NOT: #define __ARM_PCS_VFP 1 + // RUN: %clang -target armv8.3a-none-none-eabi -x c -E -dM %s -o - | FileCheck -match-full-lines --check-prefix=CHECK-V83A %s // CHECK-V83A: #define __ARM_ARCH 8 // CHECK-V83A: #define __ARM_ARCH_8_3A__ 1 diff --git a/clang/test/Sema/attr-availability-driverkit.c b/clang/test/Sema/attr-availability-driverkit.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/attr-availability-driverkit.c @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 "-triple" "x86_64-apple-driverkit20.0" -fsyntax-only -verify %s + +void f0(int) __attribute__((availability(driverkit,introduced=19.0,deprecated=20.0))); // expected-note {{'f0' has been explicitly marked deprecated here}} +void f1(int) __attribute__((availability(driverkit,introduced=20.0))); +void f2(int) __attribute__((availability(driverkit,introduced=19.0,deprecated=20.0))); // expected-note {{'f2' has been explicitly marked deprecated here}} +void f3(int) __attribute__((availability(driverkit,introduced=20.0))); +void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(driverkit,introduced=19.0,deprecated=19.5,obsoleted=20.0))); // expected-note{{explicitly marked unavailable}} + +void f5(int) __attribute__((availability(driverkit,introduced=19.0))) __attribute__((availability(driverkit,deprecated=20.0))); // expected-note {{'f5' has been explicitly marked deprecated here}} +void f6(int) __attribute__((availability(driverkit,deprecated=20.0))); // expected-note {{'f6' has been explicitly marked deprecated here}} +void f7(int) __attribute__((availability(driverkit,introduced=19.0))); + +void test() { + f0(0); // expected-warning{{'f0' is deprecated: first deprecated in DriverKit 20.0}} + f1(0); + f2(0); // expected-warning{{'f2' is deprecated: first deprecated in DriverKit 20.0}} + f3(0); + f4(0); // expected-error{{f4' is unavailable: obsoleted in DriverKit 20.0}} + f5(0); // expected-warning{{'f5' is deprecated: first deprecated in DriverKit 20.0}} + f6(0); // expected-warning{{'f6' is deprecated: first deprecated in DriverKit 20.0}} + f7(0); +}