llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Ian Anderson (ian-twilightcoder) <details> <summary>Changes</summary> Swift carries a few API notes in its resource directory that moved to the SDK several releases ago. Swift can't delete its obsolete API notes because it has to support older SDKs. The SDK API notes have since been converted to attributes in the headers themselves. The SDK can't delete the API notes though because they're currently overriding the obsolete Swift API notes. Add a ValidSDKs map to the API notes format so that the API notes file can state the versions where it's obsoleted and should be ignored. Assisted-by: Claude Opus 5 (1M context) <noreply@<!-- -->anthropic.com> rdar://188239796 --- Patch is 40.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/226041.diff 28 Files Affected: - (modified) clang/docs/APINotes.md (+27) - (modified) clang/include/clang/APINotes/APINotesManager.h (+14-7) - (modified) clang/include/clang/APINotes/APINotesYAMLCompiler.h (+19-4) - (modified) clang/include/clang/Basic/DarwinSDKInfo.h (+2) - (modified) clang/include/clang/Sema/Sema.h (+1-1) - (modified) clang/lib/APINotes/APINotesManager.cpp (+40-31) - (modified) clang/lib/APINotes/APINotesYAMLCompiler.cpp (+61-7) - (modified) clang/lib/Basic/DarwinSDKInfo.cpp (+7) - (modified) clang/lib/Frontend/CompilerInstance.cpp (+4) - (modified) clang/lib/Sema/Sema.cpp (+2-2) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+2-2) - (added) clang/test/APINotes/Inputs/APINotesAged/SomeOtherKit.apinotes (+14) - (modified) clang/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes (+5) - (modified) clang/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h (+1) - (added) clang/test/APINotes/Inputs/Headers/AgingLib.h (+8) - (added) clang/test/APINotes/Inputs/Headers/PublicPrivateLib.apinotes (+14) - (added) clang/test/APINotes/Inputs/Headers/PublicPrivateLib.h (+10) - (added) clang/test/APINotes/Inputs/Headers/PublicPrivateLib_private.apinotes (+13) - (modified) clang/test/APINotes/Inputs/Headers/module.modulemap (+8) - (modified) clang/test/APINotes/Inputs/Headers/module.private.modulemap (+4) - (added) clang/test/APINotes/Inputs/ValidSDKs/device-only/AgingLib.apinotes (+9) - (added) clang/test/APINotes/Inputs/ValidSDKs/different-simulator-version/AgingLib.apinotes (+11) - (added) clang/test/APINotes/Inputs/ValidSDKs/multiple-sdks/AgingLib.apinotes (+11) - (modified) clang/test/APINotes/search-order.m (+24-2) - (added) clang/test/APINotes/valid-sdks-implicit-search.c (+60) - (added) clang/test/APINotes/valid-sdks-private-notes.c (+45) - (added) clang/test/APINotes/valid-sdks.c (+98) - (added) clang/test/APINotes/yaml-roundtrip-valid-sdks.test (+17) ``````````diff diff --git a/clang/docs/APINotes.md b/clang/docs/APINotes.md index 4d8646ec36c27..473199ea6fdd7 100644 --- a/clang/docs/APINotes.md +++ b/clang/docs/APINotes.md @@ -71,6 +71,33 @@ entries: Name: MyFramework +:ValidSDKs: + + An exhaustive list of the SDKs this file is still valid on, each with the SDK + version at which it stops being valid. A file that declares 'ValidSDKs' is + used only when the SDK being compiled against is listed *and* older than that + entry's 'ValidUntil'; otherwise the whole file is ignored. This lets an API + notes file outside of the SDK be phased out for new SDKs while still + supporting old SDKs. The SDK list is exhaustive so that new SDKs don't need to + be added to an API notes file that is being phased out already. + + :: + + ValidSDKs: + - Name: macosx + ValidUntil: 14.0 + - Name: iphoneos + ValidUntil: 17.0 + + 'Name' is an Xcode SDK name as might be passed to `xcrun --sdk`, e.g. macosx, + iphoneos, iphonesimulator, et al. + + 'ValidUntil' is exclusive, and is compared against the SDK's version, *not* + against the deployment target. + + If Clang cannot identify an SDK at all -- no '-isysroot', missing + 'SDKSettings.json', etc. -- the file applies. + :Classes, Protocols, Tags, Typedefs, Globals, Enumerators, Functions, Namespaces: Arrays of top-level declarations. Each entry in the array must have a diff --git a/clang/include/clang/APINotes/APINotesManager.h b/clang/include/clang/APINotes/APINotesManager.h index aaf48706fb26b..93e3e23d0fa37 100644 --- a/clang/include/clang/APINotes/APINotesManager.h +++ b/clang/include/clang/APINotes/APINotesManager.h @@ -12,6 +12,7 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/VersionTuple.h" @@ -20,6 +21,7 @@ namespace clang { +class DarwinSDKInfo; class DirectoryEntry; class FileEntry; class LangOptions; @@ -46,6 +48,11 @@ class APINotesManager { SourceManager &SM; + /// Resolves the SDK being compiled against when an API notes file declares + /// 'ValidSDKs'. Unset, or returning null, means there is no SDK to compare + /// against, in which case no file is skipped. + llvm::unique_function<const DarwinSDKInfo *()> SDKInfoProvider; + /// Whether to implicitly search for API notes files based on the /// source file from which an entity was declared. bool ImplicitAPINotes; @@ -135,6 +142,12 @@ class APINotesManager { this->SwiftVersion = Version; } + /// Set the callback used to resolve the SDK being compiled against, for API + /// notes files that declare 'ValidSDKs'. + void setSDKInfoProvider(llvm::unique_function<const DarwinSDKInfo *()> P) { + SDKInfoProvider = std::move(P); + } + /// Load the API notes for the current module. /// /// \param M The current module. @@ -150,15 +163,9 @@ class APINotesManager { /// compiled. /// /// \param M The current module. - /// \param LookInModule Whether to look inside the directory of the current - /// module. - /// \param SearchPaths The paths in which we should search for API - /// notes for the current module. /// /// \returns a vector of FileEntry where APINotes files are. - llvm::SmallVector<FileEntryRef, 2> - getCurrentModuleAPINotes(Module *M, bool LookInModule, - ArrayRef<std::string> SearchPaths); + llvm::SmallVector<FileEntryRef, 2> getCurrentModuleAPINotes(Module *M); /// Load Compiled API notes for current module. /// diff --git a/clang/include/clang/APINotes/APINotesYAMLCompiler.h b/clang/include/clang/APINotes/APINotesYAMLCompiler.h index 9c24ed85b6a12..891832c237b43 100644 --- a/clang/include/clang/APINotes/APINotesYAMLCompiler.h +++ b/clang/include/clang/APINotes/APINotesYAMLCompiler.h @@ -9,11 +9,13 @@ #ifndef LLVM_CLANG_APINOTES_APINOTESYAMLCOMPILER_H #define LLVM_CLANG_APINOTES_APINOTESYAMLCOMPILER_H +#include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" namespace clang { +class DarwinSDKInfo; class FileEntry; } // namespace clang @@ -24,11 +26,24 @@ namespace api_notes { /// the APINotes format. bool parseAndDumpAPINotes(llvm::StringRef YI, llvm::raw_ostream &OS); +/// Resolves the SDK being compiled against, on demand. Returns null when the +/// SDK cannot be identified (no sysroot, no SDKSettings.json, ...), which means +/// "apply the API notes" rather than "skip them". +using DarwinSDKInfoProviderRef = llvm::function_ref<const DarwinSDKInfo *()>; + +enum class CompileResult { + Success, + Error, + /// The file declares 'ValidSDKs' and the SDK being compiled against isn't one + /// of them, so nothing was written. + Skipped, +}; + /// Converts API notes from YAML format to binary format. -bool compileAPINotes(llvm::StringRef YAMLInput, const FileEntry *SourceFile, - llvm::raw_ostream &OS, - llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr, - void *DiagHandlerCtxt = nullptr); +CompileResult compileAPINotes( + llvm::StringRef YAMLInput, const FileEntry *SourceFile, + llvm::raw_ostream &OS, llvm::SourceMgr::DiagHandlerTy DiagHandler = nullptr, + void *DiagHandlerCtxt = nullptr, DarwinSDKInfoProviderRef GetSDKInfo = {}); } // namespace api_notes } // namespace clang diff --git a/clang/include/clang/Basic/DarwinSDKInfo.h b/clang/include/clang/Basic/DarwinSDKInfo.h index 3c8297569180f..fe750734f58e4 100644 --- a/clang/include/clang/Basic/DarwinSDKInfo.h +++ b/clang/include/clang/Basic/DarwinSDKInfo.h @@ -203,6 +203,8 @@ class DarwinSDKInfo { llvm::Triple::EnvironmentType getEnvironment() const { return Environment; } + bool matchesSDKName(StringRef Name) const; + const llvm::VersionTuple &getVersion() const { return Version; } const llvm::VersionTuple &getDefaultDeploymentTarget() const { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5f24adbf9e9cf..3a7bc5d820f3c 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -939,7 +939,7 @@ class Sema final : public SemaBase { DarwinSDKInfo *getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc, StringRef Platform); - DarwinSDKInfo *getDarwinSDKInfoForAvailabilityChecking(); + DarwinSDKInfo *getDarwinSDKInfo(); /// Registers an external source. If an external source already exists, /// creates a multiplex external source and appends to it. diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index 2cc801d5415b8..7ae04973c9757 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -48,6 +48,15 @@ class PrettyStackTraceDoubleString : public llvm::PrettyStackTraceEntry { }; } // namespace +/// Adapts an SDK info provider for passing down to the API notes YAML +/// compiler, or an empty reference if no provider has been set. +static DarwinSDKInfoProviderRef +asProviderRef(llvm::unique_function<const DarwinSDKInfo *()> &Provider) { + if (!Provider) + return {}; + return Provider; +} + APINotesManager::APINotesManager(SourceManager &SM, const LangOptions &LangOpts) : SM(SM), ImplicitAPINotes(LangOpts.APINotes), HasAPINotes(LangOpts.APINotes), @@ -89,7 +98,8 @@ APINotesManager::loadAPINotes(FileEntryRef APINotesFile) { llvm::raw_svector_ostream OS(APINotesBuffer); if (api_notes::compileAPINotes( SourceBuffer->getBuffer(), SM.getFileEntryForID(SourceFileID), OS, - SMAdapter.getDiagHandler(), SMAdapter.getDiagContext())) + SMAdapter.getDiagHandler(), SMAdapter.getDiagContext(), + asProviderRef(SDKInfoProvider)) != CompileResult::Success) return nullptr; // Make a copy of the compiled form into the buffer. @@ -115,9 +125,10 @@ APINotesManager::loadAPINotes(StringRef Buffer) { diag::warn_apinotes_message, diag::note_apinotes_message, std::nullopt); llvm::raw_svector_ostream OS(APINotesBuffer); - if (api_notes::compileAPINotes(Buffer, nullptr, OS, - SMAdapter.getDiagHandler(), - SMAdapter.getDiagContext())) + if (api_notes::compileAPINotes( + Buffer, nullptr, OS, SMAdapter.getDiagHandler(), + SMAdapter.getDiagContext(), + asProviderRef(SDKInfoProvider)) != CompileResult::Success) return nullptr; CompiledBuffer = llvm::MemoryBuffer::getMemBufferCopy( @@ -225,15 +236,13 @@ static bool hasPrivateSubmodules(const Module *M) { } llvm::SmallVector<FileEntryRef, 2> -APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule, - ArrayRef<std::string> SearchPaths) { +APINotesManager::getCurrentModuleAPINotes(Module *M) { FileManager &FM = SM.getFileManager(); auto ModuleName = M->getTopLevelModuleName(); auto ExportedModuleName = M->getTopLevelModule()->ExportAsModule; llvm::SmallVector<FileEntryRef, 2> APINotes; - // First, look relative to the module itself. - if (LookInModule && M->Directory) { + if (M->Directory) { // Local function to try loading an API notes file in the given directory. auto tryAPINotes = [&](DirectoryEntryRef Dir, bool WantPublic) { if (auto File = findAPINotesFile(Dir, ModuleName, WantPublic)) { @@ -287,23 +296,8 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule, if (!M->ModuleMapIsPrivate && hasPrivateSubmodules(M)) tryAPINotes(*M->Directory, /*wantPublic=*/false); } - - if (!APINotes.empty()) - return APINotes; - } - - // Second, look for API notes for this module in the module API - // notes search paths. - for (const auto &SearchPath : SearchPaths) { - if (auto SearchDir = FM.getOptionalDirectoryRef(SearchPath)) { - if (auto File = findAPINotesFile(*SearchDir, ModuleName)) { - APINotes.push_back(*File); - return APINotes; - } - } } - // Didn't find any API notes. return APINotes; } @@ -312,12 +306,29 @@ bool APINotesManager::loadCurrentModuleAPINotes( assert(!CurrentModuleReaders[ReaderKind::Public] && "Already loaded API notes for the current module?"); - auto APINotes = getCurrentModuleAPINotes(M, LookInModule, SearchPaths); unsigned NumReaders = 0; - for (auto File : APINotes) { - CurrentModuleReaders[NumReaders++] = loadAPINotes(File).release(); - if (!getCurrentModuleReaders().empty()) + auto tryLoad = [&](FileEntryRef File) { + if (auto Reader = loadAPINotes(File)) { + CurrentModuleReaders[NumReaders++] = Reader.release(); M->APINotesFile = File.getName().str(); + } + }; + + // First, look relative to the module itself. + if (LookInModule) + for (FileEntryRef File : getCurrentModuleAPINotes(M)) + tryLoad(File); + + // Second, look for API notes for this module in the module API + // notes search paths. + FileManager &FM = SM.getFileManager(); + for (const auto &SearchPath : SearchPaths) { + if (NumReaders > 0) + break; + + if (auto SearchDir = FM.getOptionalDirectoryRef(SearchPath)) + if (auto File = findAPINotesFile(*SearchDir, M->getTopLevelModuleName())) + tryLoad(*File); } if (NumReaders > 0) @@ -329,10 +340,8 @@ bool APINotesManager::loadCurrentModuleAPINotesFromBuffer( ArrayRef<StringRef> Buffers) { unsigned NumReader = 0; for (auto Buf : Buffers) { - auto Reader = loadAPINotes(Buf); - assert(Reader && "Could not load the API notes we just generated?"); - - CurrentModuleReaders[NumReader++] = Reader.release(); + if (auto Reader = loadAPINotes(Buf)) + CurrentModuleReaders[NumReader++] = Reader.release(); } if (NumReader > 0) HasAPINotes = true; diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp index 4079675228a21..81d211c64d296 100644 --- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp +++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp @@ -16,6 +16,7 @@ #include "clang/APINotes/APINotesYAMLCompiler.h" #include "clang/APINotes/APINotesWriter.h" #include "clang/APINotes/Types.h" +#include "clang/Basic/DarwinSDKInfo.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/STLExtras.h" @@ -731,10 +732,35 @@ template <> struct MappingTraits<Versioned> { } // namespace yaml } // namespace llvm +namespace { +struct ValidSDK { + StringRef Name; + VersionTuple ValidUntil; +}; + +typedef std::vector<ValidSDK> ValidSDKsSeq; +} // namespace + +LLVM_YAML_IS_SEQUENCE_VECTOR(ValidSDK) + +namespace llvm { +namespace yaml { +template <> struct MappingTraits<ValidSDK> { + static void mapping(IO &IO, ValidSDK &S) { + // Name is a plain string rather than an enumeration. Unrecognized SDK names + // are handled by clients. + IO.mapRequired("Name", S.Name); + IO.mapRequired("ValidUntil", S.ValidUntil); + } +}; +} // namespace yaml +} // namespace llvm + namespace { struct Module { StringRef Name; AvailabilityItem Availability; + ValidSDKsSeq ValidSDKs; TopLevelItems TopLevel; VersionedSeq SwiftVersions; @@ -755,6 +781,7 @@ template <> struct MappingTraits<Module> { APIAvailability::Available); IO.mapOptional("AvailabilityMsg", M.Availability.Msg, StringRef("")); IO.mapOptional("SwiftInferImportAsMember", M.SwiftInferImportAsMember); + IO.mapOptional("ValidSDKs", M.ValidSDKs); mapTopLevelItems(IO, M.TopLevel); IO.mapOptional("SwiftVersions", M.SwiftVersions); } @@ -1392,18 +1419,45 @@ static void printDiagnostic(const llvm::SMDiagnostic &Diag, void *Context) { Diag.print(nullptr, llvm::errs()); } -bool api_notes::compileAPINotes(StringRef YAMLInput, - const FileEntry *SourceFile, - llvm::raw_ostream &OS, - llvm::SourceMgr::DiagHandlerTy DiagHandler, - void *DiagHandlerCtxt) { +static bool isValidForSDK(const ValidSDKsSeq &ValidSDKs, + DarwinSDKInfoProviderRef GetSDKInfo) { + if (ValidSDKs.empty() || !GetSDKInfo) + return true; + + // If there's no SDK info, assume an old SDK and apply the API notes. + const DarwinSDKInfo *SDK = GetSDKInfo(); + if (!SDK) + return true; + + const auto Entry = llvm::find_if(ValidSDKs, [SDK](const ValidSDK &S) { + return SDK->matchesSDKName(S.Name); + }); + + // If the SDK doesn't match any of the valid SDKs, assume a new SDK that + // should skip the obsolete API notes. + if (Entry == ValidSDKs.end()) + return false; + + return SDK->getVersion() < Entry->ValidUntil; +} + +CompileResult api_notes::compileAPINotes( + StringRef YAMLInput, const FileEntry *SourceFile, llvm::raw_ostream &OS, + llvm::SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt, + DarwinSDKInfoProviderRef GetSDKInfo) { Module TheModule; if (!DiagHandler) DiagHandler = &printDiagnostic; if (parseAPINotes(YAMLInput, TheModule, DiagHandler, DiagHandlerCtxt)) - return true; + return CompileResult::Error; + + if (!isValidForSDK(TheModule.ValidSDKs, GetSDKInfo)) + return CompileResult::Skipped; + + if (compile(TheModule, SourceFile, OS, DiagHandler, DiagHandlerCtxt)) + return CompileResult::Error; - return compile(TheModule, SourceFile, OS, DiagHandler, DiagHandlerCtxt); + return CompileResult::Success; } diff --git a/clang/lib/Basic/DarwinSDKInfo.cpp b/clang/lib/Basic/DarwinSDKInfo.cpp index 63608e3e4ad8b..5004e5b165ab5 100644 --- a/clang/lib/Basic/DarwinSDKInfo.cpp +++ b/clang/lib/Basic/DarwinSDKInfo.cpp @@ -397,6 +397,13 @@ findPlatformInfo(const DarwinSDKInfo::PlatformInfoStorageType &PlatformInfos, return PlatformInfoIt; } +bool DarwinSDKInfo::matchesSDKName(StringRef Name) const { + std::pair<llvm::Triple::OSType, llvm::Triple::EnvironmentType> + OSAndEnvironment = parseOSAndEnvironment(Name); + return (OSAndEnvironment.first == OS) && + (OSAndEnvironment.second == Environment); +} + bool DarwinSDKInfo::supportsTriple(const llvm::Triple &Triple) const { return findPlatformInfo(PlatformInfos, Triple) != PlatformInfos.end(); } diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 87abcd38c1a92..0dce1e86e560e 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -775,6 +775,10 @@ void CompilerInstance::createSema(TranslationUnitKind TUKind, // Set up API notes. TheSema->APINotes.setSwiftVersion(getAPINotesOpts().SwiftVersion); + // Resolve the SDK lazily, since only an API notes file that declares + // 'ValidSDKs' needs it. + TheSema->APINotes.setSDKInfoProvider( + [&S = *TheSema]() { return S.getDarwinSDKInfo(); }); // Attach the external sema source if there is any. if (ExternalSemaSrc) { diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 21f71d7f8b40e..3b997f478769a 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -112,7 +112,7 @@ ModuleLoader &Sema::getModuleLoader() const { return PP.getModuleLoader(); } DarwinSDKInfo * Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc, StringRef Platform) { - auto *SDKInfo = getDarwinSDKInfoForAvailabilityChecking(); + auto *SDKInfo = getDarwinSDKInfo(); if (!SDKInfo && !WarnedDarwinSDKInfoMissing) { Diag(Loc, diag::warn_missing_sdksettings_for_availability_checking) << Platform; @@ -121,7 +121,7 @@ Sema::getDarwinSDKInfoForAvailabilityChecking(SourceLocation Loc, return SDKInfo; } -DarwinSDKInfo *Sema::getDarwinSDKInfoForAvailabilityChecking() { +DarwinSDKInfo *Sema::getDarwinSDKInfo() { if (CachedDarwinSDKInfo) return CachedDarwinSDKInfo->get(); auto SDKInfo = parseDarwinSDKInfo( diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index eb4a8c2ab9ae0..2d06d0ec51521 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2904,7 +2904,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { NewII = &S.Context.Idents.get("watchos_app_extension"); if (NewII) { - const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking(); + const auto *SDKInfo = S.getDarwinSDKInfo(); const auto *IOSToWatchOSMapping = SDKInfo ? SDKInfo->getVersionMapping( DarwinSDKInfo::OSEnvPair::iOStoWatchOSPair()) @@ -2965,7 +2965,7 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) { NewII = &S.Context.Idents.get("tvos_app_extension"); if (NewII) { - const auto *SDKInfo = S.getDarwinSDKInfoForAvailabilityChecking(); + const auto *SDKInfo = S.getDarwinSDKInfo(); const auto *IOSToTvOSMapping = SDKInfo ? SDKInfo->getVersionMapping( DarwinSDKInfo::OSEnvPair::iOStoTvOSPair()) diff --git a/clang/test/APINotes/Inputs/APINotesAged/SomeOtherKit.apinotes b/clang/test/APINotes/Inputs/APINotesAged/SomeOtherKit.apinotes new file mode 100644 index 0000000000000..a782f439b247c --- /dev/null +++ b/clang/test/APINotes/Inputs/APINotesAged/SomeOtherKit.apinotes @@ -0,0 +1,14 @@ +Name: SomeOtherKit +# Stands in for a search path whose notes are no longer valid: ages out on the +# macOS 15.0 SDK. Annotates methodC rather than methodB so that it is observable +# which of several search paths was used. +ValidSDKs: + - Name: macosx + ValidUntil: 15.0 +Classes: + - Name: A + Methods: + - Selector: "methodC" + MethodKind: Instance + Availability: none + AvailabilityMsg: "anything but this" diff --git a/clang/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes b/clang/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes index 2ad546b8f8bcc..6ee7a258cb590 100644 --- a/clang/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes +++ b/clang/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/226041 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
