From ff31714b696c9a84137a2ae7caa08deb4bee1ff1 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 8 Sep 2017 18:32:33 -0700 Subject: [PATCH 1/5] [ClangImporter] ImportedName doesn't need to know its version. Preparation for making ImportNameVersion a generalized struct rather than an enum. We could have kept cramming it into a bitfield, sure, but we don't actually need this. No intended functionality change. --- lib/ClangImporter/ImportDecl.cpp | 4 +--- lib/ClangImporter/ImportName.cpp | 15 +++++++-------- lib/ClangImporter/ImportName.h | 21 +++------------------ lib/ClangImporter/ImporterImpl.h | 4 +++- 4 files changed, 14 insertions(+), 30 deletions(-) diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 27f152baf0530..950b6e7b29ed0 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -6921,9 +6921,7 @@ getSwiftNameFromClangName(StringRef replacement) { { // Render a swift_name string. llvm::raw_svector_ostream os(renamed); - printSwiftName(importedName, - /*fullyQualified=*/true, - os); + printSwiftName(importedName, CurrentVersion, /*fullyQualified=*/true, os); } return SwiftContext.AllocateCopy(StringRef(renamed)); diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp index 2d40e02a89c77..f76d8b894ee77 100644 --- a/lib/ClangImporter/ImportName.cpp +++ b/lib/ClangImporter/ImportName.cpp @@ -318,10 +318,9 @@ static bool shouldLowercaseValueName(StringRef name) { /// Will recursively print out the fully qualified context for the given name. /// Ends with a trailing "." -static void -printFullContextPrefix(ImportedName name, - llvm::raw_ostream &os, - ClangImporter::Implementation &Impl) { +static void printFullContextPrefix(ImportedName name, ImportNameVersion version, + llvm::raw_ostream &os, + ClangImporter::Implementation &Impl) { const clang::NamedDecl *newDeclContextNamed = nullptr; switch (name.getEffectiveContext().getKind()) { case EffectiveClangContext::UnresolvedContext: @@ -347,12 +346,13 @@ printFullContextPrefix(ImportedName name, // Now, let's print out the parent assert(newDeclContextNamed && "should of been set"); - auto parentName = Impl.importFullName(newDeclContextNamed, name.getVersion()); - printFullContextPrefix(parentName, os, Impl); + auto parentName = Impl.importFullName(newDeclContextNamed, version); + printFullContextPrefix(parentName, version, os, Impl); os << parentName.getDeclName() << "."; } void ClangImporter::Implementation::printSwiftName(ImportedName name, + ImportNameVersion version, bool fullyQualified, llvm::raw_ostream &os) { // Property accessors. @@ -376,7 +376,7 @@ void ClangImporter::Implementation::printSwiftName(ImportedName name, } if (fullyQualified) - printFullContextPrefix(name, os, *this); + printFullContextPrefix(name, version, os, *this); // Base name. os << name.getDeclName().getBaseName(); @@ -1723,7 +1723,6 @@ ImportedName NameImporter::importName(const clang::NamedDecl *decl, } ++ImportNameNumCacheMisses; auto res = importNameImpl(decl, version, givenName); - res.setVersion(version); if (!givenName) importNameCache[key] = res; return res; diff --git a/lib/ClangImporter/ImportName.h b/lib/ClangImporter/ImportName.h index b8f33cc14b77b..025c01aad87d4 100644 --- a/lib/ClangImporter/ImportName.h +++ b/lib/ClangImporter/ImportName.h @@ -141,11 +141,6 @@ class ImportedName { /// For an initializer, the kind of initializer to import. CtorInitializerKind initKind; - /// The version of Swift this name corresponds to. - /// - /// \see ImportNameVersion - unsigned rawVersion : 2; - /// What kind of accessor this name refers to, if any. ImportedAccessorKind accessorKind : NumImportedAccessorKindBits; @@ -167,9 +162,9 @@ class ImportedName { Info() : errorInfo(), selfIndex(), initKind(CtorInitializerKind::Designated), - rawVersion(), accessorKind(ImportedAccessorKind::None), - hasCustomName(false), droppedVariadic(false), importAsMember(false), - hasSelfIndex(false), hasErrorInfo(false) {} + accessorKind(ImportedAccessorKind::None), hasCustomName(false), + droppedVariadic(false), importAsMember(false), hasSelfIndex(false), + hasErrorInfo(false) {} } info; public: @@ -189,16 +184,6 @@ class ImportedName { effectiveContext = ctx; } - /// The highest version of Swift that this name comes from - ImportNameVersion getVersion() const { - return static_cast(info.rawVersion); - } - - void setVersion(ImportNameVersion version) { - info.rawVersion = static_cast(version); - assert(getVersion() == version && "not enough bits"); - } - /// For an initializer, the kind of initializer to import. CtorInitializerKind getInitKind() const { return info.initKind; } diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index 0cc02a0ea702b..1c81753d727c2 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -640,7 +640,9 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// Print an imported name as a string suitable for the swift_name attribute, /// or the 'Rename' field of AvailableAttr. - void printSwiftName(importer::ImportedName, bool fullyQualified, + void printSwiftName(importer::ImportedName name, + importer::ImportNameVersion version, + bool fullyQualified, llvm::raw_ostream &os); /// \brief Import the given Clang identifier into Swift. From 90f728a68e24c453b2e0b74581c28769228e0354 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 8 Sep 2017 18:36:25 -0700 Subject: [PATCH 2/5] [ClangImporter] Check for failure in forEachDistinctName forEachDistinctName might produce the same name for Swift 4 and Swift 5, but it's possible that for some reason the name will only work in one mode or the other. In that case, even though we're trying the "same" name again, we still want to invoke the callback once more. Add a boolean return to the callback to support this. Tests to come at the end of this patch series -- this shows up when in Swift 3 mode and the canonical version for types is set to Swift 5. --- lib/ClangImporter/ClangImporter.cpp | 21 ++++---- lib/ClangImporter/ImportDecl.cpp | 77 +++++++++++++++-------------- lib/ClangImporter/ImporterImpl.h | 14 +++++- 3 files changed, 65 insertions(+), 47 deletions(-) diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 7728fbb7ccdcd..90d4cac5bfbb6 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -2508,32 +2508,34 @@ ClangModuleUnit::lookupNestedType(Identifier name, bool anyMatching = false; TypeDecl *originalDecl = nullptr; - owner.forEachDistinctName(clangTypeDecl, [&](ImportedName newName, - ImportNameVersion nameVersion){ + owner.forEachDistinctName(clangTypeDecl, + [&](ImportedName newName, + ImportNameVersion nameVersion) -> bool { if (anyMatching) - return; + return true; if (!newName.getDeclName().isSimpleName(name)) - return; + return true; auto decl = dyn_cast_or_null( owner.importDeclReal(clangTypeDecl, nameVersion)); if (!decl) - return; + return false; if (!originalDecl) originalDecl = decl; else if (originalDecl == decl) - return; + return true; auto *importedContext = decl->getDeclContext()-> getAsNominalTypeOrNominalTypeExtensionContext(); if (importedContext != baseType) - return; + return true; assert(decl->getFullName().matchesRef(name) && "importFullName behaved differently from importDecl"); results.push_back(decl); anyMatching = true; + return true; }); } @@ -3211,12 +3213,12 @@ void ClangImporter::Implementation::lookupObjCMembers( forEachDistinctName(clangDecl, [&](ImportedName importedName, - ImportNameVersion nameVersion) { + ImportNameVersion nameVersion) -> bool { // Import the declaration. auto decl = cast_or_null(importDeclReal(clangDecl, nameVersion)); if (!decl) - return; + return false; // If the name we found matches, report the declaration. // FIXME: If we didn't need to check alternate decls here, we could avoid @@ -3232,6 +3234,7 @@ void ClangImporter::Implementation::lookupObjCMembers( consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup); } } + return true; }); } } diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 950b6e7b29ed0..6ce5d4fc230d3 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -348,7 +348,7 @@ static bool isNSDictionaryMethod(const clang::ObjCMethodDecl *MD, void ClangImporter::Implementation::forEachDistinctName( const clang::NamedDecl *decl, - llvm::function_ref action) { + llvm::function_ref action) { using ImportNameKey = std::pair; SmallVector seenNames; forEachImportNameVersionFromCurrent(CurrentVersion, @@ -364,8 +364,8 @@ void ClangImporter::Implementation::forEachDistinctName( }); if (seen) return; - seenNames.push_back(key); - action(newName, nameVersion); + if (action(newName, nameVersion)) + seenNames.push_back(key); }); } @@ -2690,31 +2690,33 @@ namespace { case EnumKind::Unknown: Impl.forEachDistinctName(constant, [&](ImportedName newName, - ImportNameVersion nameVersion) { + ImportNameVersion nameVersion) -> bool { Decl *imported = Impl.importDecl(constant, nameVersion); if (!imported) - return; + return false; if (nameVersion == getActiveSwiftVersion()) enumeratorDecl = imported; else variantDecls.push_back(imported); + return true; }); break; case EnumKind::Options: Impl.forEachDistinctName(constant, [&](ImportedName newName, - ImportNameVersion nameVersion) { + ImportNameVersion nameVersion) -> bool { if (!contextIsEnum(newName)) - return; + return true; SwiftDeclConverter converter(Impl, nameVersion); Decl *imported = converter.importOptionConstant(constant, decl, result); if (!imported) - return; + return false; if (nameVersion == getActiveSwiftVersion()) enumeratorDecl = imported; else variantDecls.push_back(imported); + return true; }); break; case EnumKind::Enum: { @@ -2762,18 +2764,19 @@ namespace { Impl.forEachDistinctName(constant, [&](ImportedName newName, - ImportNameVersion nameVersion) { + ImportNameVersion nameVersion) -> bool { if (nameVersion == getActiveSwiftVersion()) - return; + return true; if (!contextIsEnum(newName)) - return; + return true; SwiftDeclConverter converter(Impl, nameVersion); Decl *imported = converter.importEnumCase(constant, decl, cast(result), enumeratorDecl); if (!imported) - return; + return false; variantDecls.push_back(imported); + return true; }); break; } @@ -7973,9 +7976,9 @@ void ClangImporter::Implementation::loadAllMembersIntoExtension( continue; forEachDistinctName( - decl, [&](ImportedName newName, ImportNameVersion nameVersion) { - addMemberAndAlternatesToExtension(decl, newName, nameVersion, ext); - }); + decl, [&](ImportedName newName, ImportNameVersion nameVersion) -> bool { + return addMemberAndAlternatesToExtension(decl, newName, nameVersion, ext); + }); } } @@ -7993,29 +7996,30 @@ static Decl *findMemberThatWillLandInAnExtensionContext(Decl *member) { return result; } -void ClangImporter::Implementation::addMemberAndAlternatesToExtension( +bool ClangImporter::Implementation::addMemberAndAlternatesToExtension( clang::NamedDecl *decl, ImportedName newName, ImportNameVersion nameVersion, ExtensionDecl *ext) { // Quickly check the context and bail out if it obviously doesn't // belong here. if (auto *importDC = newName.getEffectiveContext().getAsDeclContext()) if (importDC->isTranslationUnit()) - return; + return true; // Then try to import the decl under the specified name. auto *member = importDecl(decl, nameVersion); if (!member) - return; + return false; member = findMemberThatWillLandInAnExtensionContext(member); if (!member || member->getDeclContext() != ext) - return; + return true; ext->addMember(member); for (auto alternate : getAlternateDecls(member)) { if (alternate->getDeclContext() == ext) ext->addMember(alternate); } + return true; } static ExtensionDecl * @@ -8077,26 +8081,27 @@ void ClangImporter::Implementation::insertMembersAndAlternates( const clang::NamedDecl *nd, SmallVectorImpl &members) { llvm::SmallPtrSet knownAlternateMembers; forEachDistinctName( - nd, [&](ImportedName name, ImportNameVersion nameVersion) { - auto member = importDecl(nd, nameVersion); - if (!member) - return; + nd, [&](ImportedName name, ImportNameVersion nameVersion) -> bool { + auto member = importDecl(nd, nameVersion); + if (!member) + return false; - // If there are alternate declarations for this member, add them. - for (auto alternate : getAlternateDecls(member)) { - if (alternate->getDeclContext() == member->getDeclContext() && - knownAlternateMembers.insert(alternate).second) { - members.push_back(alternate); - } - } + // If there are alternate declarations for this member, add them. + for (auto alternate : getAlternateDecls(member)) { + if (alternate->getDeclContext() == member->getDeclContext() && + knownAlternateMembers.insert(alternate).second) { + members.push_back(alternate); + } + } - // If this declaration shouldn't be visible, don't add it to - // the list. - if (shouldSuppressDeclImport(nd)) - return; + // If this declaration shouldn't be visible, don't add it to + // the list. + if (shouldSuppressDeclImport(nd)) + return true; - members.push_back(member); - }); + members.push_back(member); + return true; + }); } void ClangImporter::Implementation::collectMembersToAdd( diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index 1c81753d727c2..8838d09407779 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -1131,7 +1131,14 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation void insertMembersAndAlternates(const clang::NamedDecl *nd, SmallVectorImpl &members); void loadAllMembersIntoExtension(Decl *D, uint64_t extra); - void addMemberAndAlternatesToExtension( + + /// Imports \p decl under \p nameVersion with the name \p newName, and adds + /// it and its alternates to \p ext. + /// + /// \returns true if \p decl was successfully imported, whether or not it was + /// ultimately added to \p ext. This matches the behavior of + /// forEachDistinctName's callback. + bool addMemberAndAlternatesToExtension( clang::NamedDecl *decl, importer::ImportedName newName, importer::ImportNameVersion nameVersion, ExtensionDecl *ext); @@ -1222,11 +1229,14 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// will eventually reference that declaration, the contexts will still be /// considered distinct. /// + /// If \p action returns false, the current name will \e not be added to the + /// set of seen names. + /// /// The names are generated in the same order as /// forEachImportNameVersionFromCurrent. The current name is always first. void forEachDistinctName( const clang::NamedDecl *decl, - llvm::function_ref action); /// Dump the Swift-specific name lookup tables we generate. From 9a04bee421cbe8e791cd696112262fb6b10f7a3c Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Mon, 11 Sep 2017 11:15:01 -0700 Subject: [PATCH 3/5] [ClangImporter] Turn ImportNameVersion into a struct. ...so that we don't have to keep coming back to update it every major release. And also so we can actually put methods on it instead of using free functions. No intended behavior change (yet). --- include/swift/Basic/STLExtras.h | 18 ++++ lib/ClangImporter/ClangAdapter.cpp | 4 +- lib/ClangImporter/ClangImporter.cpp | 8 +- lib/ClangImporter/ImportDecl.cpp | 54 +++++----- lib/ClangImporter/ImportName.cpp | 57 +++-------- lib/ClangImporter/ImportName.h | 134 +++++++++++++------------ lib/ClangImporter/ImporterImpl.h | 4 +- lib/ClangImporter/SwiftLookupTable.cpp | 9 +- 8 files changed, 142 insertions(+), 146 deletions(-) diff --git a/include/swift/Basic/STLExtras.h b/include/swift/Basic/STLExtras.h index ce20fb698e2b1..199537f3c498c 100644 --- a/include/swift/Basic/STLExtras.h +++ b/include/swift/Basic/STLExtras.h @@ -786,6 +786,24 @@ inline OutputIterator transform(const Container &C, OutputIterator result, return std::transform(C.begin(), C.end(), result, op); } +/// Provides default implementations of !=, <=, >, and >= based on == and <. +template +class RelationalOperationsBase { +public: + friend bool operator>(const T &left, const T &right) { + return right < left; + } + friend bool operator>=(const T &left, const T &right) { + return !(left < right); + } + friend bool operator<=(const T &left, const T &right) { + return !(right < left); + } + friend bool operator!=(const T &left, const T &right) { + return !(left == right); + } +}; + } // end namespace swift #endif // SWIFT_BASIC_INTERLEAVE_H diff --git a/lib/ClangImporter/ClangAdapter.cpp b/lib/ClangImporter/ClangAdapter.cpp index e0155aa1a80d6..04daaf81ee9e1 100644 --- a/lib/ClangImporter/ClangAdapter.cpp +++ b/lib/ClangImporter/ClangAdapter.cpp @@ -437,7 +437,7 @@ clang::SwiftNewtypeAttr * importer::getSwiftNewtypeAttr(const clang::TypedefNameDecl *decl, ImportNameVersion version) { // Newtype was introduced in Swift 3 - if (version < ImportNameVersion::Swift3 ) + if (version <= ImportNameVersion::swift2()) return nullptr; return retrieveNewTypeAttr(decl); } @@ -448,7 +448,7 @@ clang::TypedefNameDecl *importer::findSwiftNewtype(const clang::NamedDecl *decl, clang::Sema &clangSema, ImportNameVersion version) { // Newtype was introduced in Swift 3 - if (version < ImportNameVersion::Swift3 ) + if (version <= ImportNameVersion::swift2()) return nullptr; auto varDecl = dyn_cast(decl); diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index 90d4cac5bfbb6..ceb704d9cd62f 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -1650,7 +1650,7 @@ ClangImporter::Implementation::Implementation(ASTContext &ctx, BridgingHeaderExplicitlyRequested(!opts.BridgingHeader.empty()), DisableAdapterModules(opts.DisableAdapterModules), IsReadingBridgingPCH(false), - CurrentVersion(nameVersionFromOptions(ctx.LangOpts)), + CurrentVersion(ImportNameVersion::fromOptions(ctx.LangOpts)), BridgingHeaderLookupTable(new SwiftLookupTable(nullptr)), platformAvailability(ctx.LangOpts), nameImporter() {} @@ -3152,10 +3152,8 @@ void ClangImporter::Implementation::lookupValue( const clang::NamedDecl *recentClangDecl = clangDecl->getMostRecentDecl(); - forEachImportNameVersionFromCurrent(CurrentVersion, - [&](ImportNameVersion nameVersion) { - if (nameVersion == CurrentVersion) - return; + CurrentVersion.forEachOtherImportNameVersion( + [&](ImportNameVersion nameVersion) { if (anyMatching) return; diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 6ce5d4fc230d3..87b4b717ff0e0 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -351,8 +351,14 @@ void ClangImporter::Implementation::forEachDistinctName( llvm::function_ref action) { using ImportNameKey = std::pair; SmallVector seenNames; - forEachImportNameVersionFromCurrent(CurrentVersion, - [&](ImportNameVersion nameVersion) { + + ImportedName newName = importFullName(decl, CurrentVersion); + ImportNameKey key(newName, newName.getEffectiveContext()); + if (action(newName, CurrentVersion)) + seenNames.push_back(key); + + CurrentVersion.forEachOtherImportNameVersion( + [&](ImportNameVersion nameVersion) { // Check to see if the name is different. ImportedName newName = importFullName(decl, nameVersion); ImportNameKey key(newName, newName.getEffectiveContext()); @@ -1947,7 +1953,7 @@ namespace { Optional &correctSwiftName) { ImportNameVersion canonicalVersion = getActiveSwiftVersion(); if (isa(D) || isa(D)) { - canonicalVersion = ImportNameVersion::ForTypes; + canonicalVersion = ImportNameVersion::forTypes(); } correctSwiftName = None; @@ -2133,36 +2139,38 @@ namespace { // If we're importing a global as a member, we need to provide the // effective context. Impl.printSwiftName( - correctSwiftName, + correctSwiftName, getActiveSwiftVersion(), /*fullyQualified=*/correctSwiftName.importAsMember(), os); } - unsigned majorVersion = majorVersionNumberForNameVersion(getVersion()); DeclAttribute *attr; - if (isActiveSwiftVersion() || getVersion() == ImportNameVersion::Raw) { + if (isActiveSwiftVersion() || getVersion() == ImportNameVersion::raw()) { // "Raw" is the Objective-C name, which was never available in Swift. // Variants within the active version are usually declarations that // have been superseded, like the accessors of a property. attr = AvailableAttr::createPlatformAgnostic( ctx, /*Message*/StringRef(), ctx.AllocateCopy(renamed.str()), PlatformAgnosticAvailabilityKind::UnavailableInSwift); - } else if (getVersion() < getActiveSwiftVersion()) { - // A Swift 2 name, for example, was obsoleted in Swift 3. - attr = AvailableAttr::createPlatformAgnostic( - ctx, /*Message*/StringRef(), ctx.AllocateCopy(renamed.str()), - PlatformAgnosticAvailabilityKind::SwiftVersionSpecific, - clang::VersionTuple(majorVersion + 1)); } else { - // Future names are introduced in their future version. - assert(getVersion() > getActiveSwiftVersion()); - attr = new (ctx) AvailableAttr( - SourceLoc(), SourceRange(), PlatformKind::none, - /*Message*/StringRef(), ctx.AllocateCopy(renamed.str()), - /*Introduced*/clang::VersionTuple(majorVersion), SourceRange(), - /*Deprecated*/clang::VersionTuple(), SourceRange(), - /*Obsoleted*/clang::VersionTuple(), SourceRange(), - PlatformAgnosticAvailabilityKind::SwiftVersionSpecific, - /*Implicit*/false); + unsigned majorVersion = getVersion().majorVersionNumber(); + if (getVersion() < getActiveSwiftVersion()) { + // A Swift 2 name, for example, was obsoleted in Swift 3. + attr = AvailableAttr::createPlatformAgnostic( + ctx, /*Message*/StringRef(), ctx.AllocateCopy(renamed.str()), + PlatformAgnosticAvailabilityKind::SwiftVersionSpecific, + clang::VersionTuple(majorVersion + 1)); + } else { + // Future names are introduced in their future version. + assert(getVersion() > getActiveSwiftVersion()); + attr = new (ctx) AvailableAttr( + SourceLoc(), SourceRange(), PlatformKind::none, + /*Message*/StringRef(), ctx.AllocateCopy(renamed.str()), + /*Introduced*/clang::VersionTuple(majorVersion), SourceRange(), + /*Deprecated*/clang::VersionTuple(), SourceRange(), + /*Obsoleted*/clang::VersionTuple(), SourceRange(), + PlatformAgnosticAvailabilityKind::SwiftVersionSpecific, + /*Implicit*/false); + } } decl->getAttrs().add(attr); @@ -4854,7 +4862,7 @@ Decl *SwiftDeclConverter::importCompatibilityTypeAlias( // we don't care. Decl *importedDecl = nullptr; if (getVersion() >= getActiveSwiftVersion()) - importedDecl = Impl.importDecl(decl, ImportNameVersion::ForTypes); + importedDecl = Impl.importDecl(decl, ImportNameVersion::forTypes()); if (!importedDecl && getVersion() != getActiveSwiftVersion()) importedDecl = Impl.importDecl(decl, getActiveSwiftVersion()); auto typeDecl = dyn_cast_or_null(importedDecl); diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp index f76d8b894ee77..a69a4f4457d7d 100644 --- a/lib/ClangImporter/ImportName.cpp +++ b/lib/ClangImporter/ImportName.cpp @@ -54,39 +54,6 @@ using namespace importer; using clang::CompilerInstance; using clang::CompilerInvocation; -ImportNameVersion -importer::nameVersionFromOptions(const LangOptions &langOpts) { - auto languageVersion = langOpts.EffectiveLanguageVersion; - switch (languageVersion[0]) { - default: - llvm_unreachable("unknown swift language version"); - case 1: - case 2: - return ImportNameVersion::Swift2; - case 3: - return ImportNameVersion::Swift3; - // Fixme: Figure out the importing story for 5 instead of falling back to 4. - case 4: - case 5: - return ImportNameVersion::Swift4; - } -} - -unsigned importer::majorVersionNumberForNameVersion(ImportNameVersion version) { - switch (version) { - case ImportNameVersion::Raw: - return 0; - case ImportNameVersion::Swift2: - return 2; - case ImportNameVersion::Swift3: - return 3; - case ImportNameVersion::Swift4: - return 4; - } - - llvm_unreachable("Unhandled ImportNameVersion in switch."); -} - /// Determine whether the given Clang selector matches the given /// selector pieces. @@ -582,13 +549,13 @@ template static bool matchesVersion(A *versionedAttr, ImportNameVersion version) { clang::VersionTuple attrVersion = versionedAttr->getVersion(); if (attrVersion.empty()) - return version == ImportNameVersion::LAST_VERSION; - return attrVersion.getMajor() == majorVersionNumberForNameVersion(version); + return version == ImportNameVersion::maxVersion(); + return attrVersion.getMajor() == version.majorVersionNumber(); } -const clang::SwiftNameAttr * -importer::findSwiftNameAttr(const clang::Decl *decl, - ImportNameVersion version) { + +static const clang::SwiftNameAttr * +findSwiftNameAttr(const clang::Decl *decl, ImportNameVersion version) { #ifndef NDEBUG if (Optional def = getDefinitionForClangTypeDecl(decl)) { assert((*def == nullptr || *def == decl) && @@ -596,11 +563,11 @@ importer::findSwiftNameAttr(const clang::Decl *decl, } #endif - if (version == ImportNameVersion::Raw) + if (version == ImportNameVersion::raw()) return nullptr; // Handle versioned API notes for Swift 3 and later. This is the common case. - if (version != ImportNameVersion::Swift2) { + if (version != ImportNameVersion::swift2()) { for (auto *attr : decl->attrs()) { if (auto *versionedAttr = dyn_cast(attr)) { if (!matchesVersion(versionedAttr, version)) @@ -843,7 +810,7 @@ NameImporter::determineEffectiveContext(const clang::NamedDecl *decl, case EnumKind::Enum: case EnumKind::Options: // Enums are mapped to Swift enums, Options to Swift option sets. - if (version != ImportNameVersion::Raw) { + if (version != ImportNameVersion::raw()) { res = cast(enumDecl); break; } @@ -960,7 +927,7 @@ static bool shouldBeSwiftPrivate(NameImporter &nameImporter, switch (nameImporter.getEnumKind(ED)) { case EnumKind::Enum: case EnumKind::Options: - if (version != ImportNameVersion::Raw) + if (version != ImportNameVersion::raw()) break; LLVM_FALLTHROUGH; case EnumKind::Constants: @@ -1125,7 +1092,7 @@ bool NameImporter::hasErrorMethodNameCollision( static bool suppressFactoryMethodAsInit(const clang::ObjCMethodDecl *method, ImportNameVersion version, CtorInitializerKind initKind) { - return (version == ImportNameVersion::Raw || method->isPropertyAccessor()) && + return (version == ImportNameVersion::raw() || method->isPropertyAccessor()) && (initKind == CtorInitializerKind::Factory || initKind == CtorInitializerKind::ConvenienceFactory); } @@ -1136,7 +1103,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D, ImportedName result; /// Whether we want a Swift 3 or later name - bool swift3OrLaterName = version >= ImportNameVersion::Swift3; + bool swift3OrLaterName = version > ImportNameVersion::swift2(); // Objective-C categories and extensions don't have names, despite // being "named" declarations. @@ -1516,7 +1483,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D, // Enumeration constants may have common prefixes stripped. bool strippedPrefix = false; - if (version != ImportNameVersion::Raw && isa(D)) { + if (version != ImportNameVersion::raw() && isa(D)) { auto enumDecl = cast(D->getDeclContext()); auto enumInfo = getEnumInfo(enumDecl); diff --git a/lib/ClangImporter/ImportName.h b/lib/ClangImporter/ImportName.h index 025c01aad87d4..420ea477b3583 100644 --- a/lib/ClangImporter/ImportName.h +++ b/lib/ClangImporter/ImportName.h @@ -20,6 +20,7 @@ #include "ImportEnumInfo.h" #include "SwiftLookupTable.h" #include "swift/Basic/StringExtras.h" +#include "swift/Basic/Version.h" #include "swift/AST/ASTContext.h" #include "swift/AST/Decl.h" #include "swift/AST/ForeignErrorConvention.h" @@ -40,77 +41,87 @@ enum class ImportedAccessorKind : unsigned { enum { NumImportedAccessorKindBits = 3 }; /// The name version -enum class ImportNameVersion : unsigned { - /// Names as they appear in C/ObjC - Raw = 0, +class ImportNameVersion : public RelationalOperationsBase { + unsigned rawValue; + friend llvm::DenseMapInfo; - /// Names as they appeared in Swift 2 family - Swift2, + enum AsConstExpr_t { AsConstExpr }; - /// Names as they appeared in Swift 3 family - Swift3, + constexpr ImportNameVersion() : rawValue(0) {} + constexpr ImportNameVersion(unsigned version, AsConstExpr_t) + : rawValue(version) {} + explicit ImportNameVersion(unsigned version) : rawValue(version) { + assert(version >= 2 && "only Swift 2 and later are supported"); + } +public: + /// Map a language version into an import name version. + static ImportNameVersion fromOptions(const LangOptions &langOpts) { + return ImportNameVersion(langOpts.EffectiveLanguageVersion[0]); + } - /// Names as they appeared in Swift 4 family - Swift4, + unsigned majorVersionNumber() const { + assert(*this != ImportNameVersion::raw()); + return rawValue; + } - /// A placeholder for the latest version, to be used in loops and such. - LAST_VERSION = Swift4, + bool operator==(ImportNameVersion other) const { + return rawValue == other.rawValue; + } + bool operator<(ImportNameVersion other) const { + return rawValue < other.rawValue; + } - /// The version which should be used for importing types, which need to have - /// one canonical definition. + /// Calls \p action for each name version other than this one, first going + /// backwards until ImportNameVersion::raw(), and then going forwards to + /// ImportNameVersion::maxVersion(). /// - /// FIXME: Is this supposed to be the /newest/ version, or a canonical - /// version that lasts forever as part of the ABI? - ForTypes = Swift4 -}; - -static inline ImportNameVersion &operator++(ImportNameVersion &value) { - assert(value != ImportNameVersion::LAST_VERSION); - value = static_cast(static_cast(value) + 1); - return value; -} + /// This is the most useful order for importing compatibility stubs. + void forEachOtherImportNameVersion( + llvm::function_ref action) const { + assert(*this >= ImportNameVersion::swift2()); + + ImportNameVersion nameVersion = *this; + while (nameVersion > ImportNameVersion::swift2()) { + --nameVersion.rawValue; + action(nameVersion); + } -static inline ImportNameVersion &operator--(ImportNameVersion &value) { - assert(value != ImportNameVersion::Raw); - value = static_cast(static_cast(value) - 1); - return value; -} + action(ImportNameVersion::raw()); -/// Calls \p action for each name version, starting with \p current, then going -/// backwards until ImportNameVersion::Raw, and then finally going forwards to -/// ImportNameVersion::LAST_VERSION. -/// -/// This is the most useful order for importing compatibility stubs. -static inline void forEachImportNameVersionFromCurrent( - ImportNameVersion current, - llvm::function_ref action) { - action(current); - ImportNameVersion nameVersion = current; - while (nameVersion != ImportNameVersion::Raw) { - --nameVersion; - action(nameVersion); + nameVersion = *this; + while (nameVersion < ImportNameVersion::maxVersion()) { + ++nameVersion.rawValue; + action(nameVersion); + } } - nameVersion = current; - while (nameVersion != ImportNameVersion::LAST_VERSION) { - ++nameVersion; - action(nameVersion); + + /// Names as they appear in C/ObjC. + static constexpr inline ImportNameVersion raw() { + return ImportNameVersion{}; } -} -/// Calls \p action for each name version, starting with ImportNameVersion::Raw -/// and going forwards. -static inline void -forEachImportNameVersion(llvm::function_ref action) { - auto limit = static_cast(ImportNameVersion::LAST_VERSION); - for (unsigned raw = 0; raw <= limit; ++raw) - action(static_cast(raw)); -} + /// Names as they appeared in Swift 2 family. + static constexpr inline ImportNameVersion swift2() { + return ImportNameVersion{2, AsConstExpr}; + } -/// Map a language version into an import name version. -ImportNameVersion nameVersionFromOptions(const LangOptions &langOpts); + /// The latest supported version. + /// + /// FIXME: All other version information is in Version.h. Can this go there + /// instead? + static constexpr inline ImportNameVersion maxVersion() { + return ImportNameVersion{4, AsConstExpr}; + } -/// Map an import name version into a language version. -unsigned majorVersionNumberForNameVersion(ImportNameVersion version); + /// The version which should be used for importing types, which need to have + /// one canonical definition. + /// + /// FIXME: Is this supposed to be the /newest/ version, or a canonical + /// version that lasts forever as part of the ABI? + static constexpr inline ImportNameVersion forTypes() { + return ImportNameVersion::maxVersion(); + } +}; /// Describes a name that was imported from Clang. class ImportedName { @@ -257,11 +268,6 @@ class ImportedName { /// in "Notification", or it there would be nothing left. StringRef stripNotification(StringRef name); -/// Find the swift_name attribute associated with this declaration, if any, -/// appropriate for \p version. -const clang::SwiftNameAttr *findSwiftNameAttr(const clang::Decl *decl, - ImportNameVersion version); - /// Class to determine the Swift name of foreign entities. Currently fairly /// stateless and borrows from the ClangImporter::Implementation, but in the /// future will be more self-contained and encapsulated. @@ -372,7 +378,7 @@ template <> struct DenseMapInfo { return (ImportNameVersion)DMIU::getTombstoneKey(); } static unsigned getHashValue(const ImportNameVersion &Val) { - return DMIU::getHashValue((unsigned)Val); + return DMIU::getHashValue(Val.rawValue); } static bool isEqual(const ImportNameVersion &LHS, const ImportNameVersion &RHS) { diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index 8838d09407779..cea17298611a7 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -1232,8 +1232,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// If \p action returns false, the current name will \e not be added to the /// set of seen names. /// - /// The names are generated in the same order as - /// forEachImportNameVersionFromCurrent. The current name is always first. + /// The active name is always first, followed by the other names in the order + /// of ImportNameVersion::forEachOtherImportNameVersion. void forEachDistinctName( const clang::NamedDecl *decl, llvm::function_ref distinctNames; distinctNames.insert(importedName.getDeclName()); @@ -1640,9 +1640,8 @@ void importer::addEntryToLookupTable(SwiftLookupTable &table, ArrayRef()), named, importedName.getEffectiveContext()); - forEachImportNameVersion([&] (ImportNameVersion alternateVersion) { - if (alternateVersion == currentVersion) - return; + currentVersion.forEachOtherImportNameVersion( + [&](ImportNameVersion alternateVersion) { auto alternateName = nameImporter.importName(named, alternateVersion); if (!alternateName) return; From 8a9495a3d13799e1a0e35edfb2b7c1d6a75054e7 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Mon, 11 Sep 2017 17:35:55 -0700 Subject: [PATCH 4/5] [ClangImporter] Honor Swift 4 API notes in Swift 3 mode *** Depends on Clang change "[APINotes] Record what version caused *** *** an annotation to get replaced." Update your Clang checkout! *** More generally, change the meaning of the SwiftVersions section in API notes to be "this version or earlier" rather than "exactly this version". We mostly get this behavior for free from the Clang-side changes, but for SwiftName and the enum annotations we look at inactive attributes as well. The latter is simple, but the former means being careful about finding the annotation we /would/ have picked, i.e. the one closest to the version we requested. --- lib/ClangImporter/ImportEnumInfo.cpp | 2 +- lib/ClangImporter/ImportName.cpp | 116 +++++++++++--- .../Headers/APINotesFrameworkTest.apinotes | 86 +++++++++++ .../Headers/APINotesFrameworkTest.h | 1 + .../Headers/Globals.h | 23 +++ test/APINotes/versioned-multi.swift | 142 ++++++++++++++++++ 6 files changed, 351 insertions(+), 19 deletions(-) create mode 100644 test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Globals.h create mode 100644 test/APINotes/versioned-multi.swift diff --git a/lib/ClangImporter/ImportEnumInfo.cpp b/lib/ClangImporter/ImportEnumInfo.cpp index 4dfb3eee6963c..f9ac7ccfd3b25 100644 --- a/lib/ClangImporter/ImportEnumInfo.cpp +++ b/lib/ClangImporter/ImportEnumInfo.cpp @@ -68,7 +68,7 @@ void EnumInfo::classifyEnum(ASTContext &ctx, const clang::EnumDecl *decl, // If API notes have /removed/ a FlagEnum or EnumExtensibility attribute, // then we don't need to check the macros. for (auto *attr : decl->specific_attrs()) { - if (!attr->getVersion().empty()) + if (!attr->getIsReplacedByActive()) continue; if (isa(attr->getAttrToAdd()) || isa(attr->getAttrToAdd())) { diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp index a69a4f4457d7d..161f1e9023ffb 100644 --- a/lib/ClangImporter/ImportName.cpp +++ b/lib/ClangImporter/ImportName.cpp @@ -545,12 +545,58 @@ determineCtorInitializerKind(const clang::ObjCMethodDecl *method) { return None; } -template -static bool matchesVersion(A *versionedAttr, ImportNameVersion version) { - clang::VersionTuple attrVersion = versionedAttr->getVersion(); - if (attrVersion.empty()) - return version == ImportNameVersion::maxVersion(); - return attrVersion.getMajor() == version.majorVersionNumber(); +namespace { +/// Aggregate struct for the common members of clang::SwiftVersionedAttr and +/// clang::SwiftVersionedRemovalAttr. +/// +/// For a SwiftVersionedRemovalAttr, the Attr member will be null. +struct VersionedSwiftNameInfo { + const clang::SwiftNameAttr *Attr; + clang::VersionTuple Version; + bool IsReplacedByActive; +}; + +/// The action to take upon seeing a particular versioned swift_name annotation. +enum class VersionedSwiftNameAction { + /// This annotation is not interesting. + Ignore, + /// This annotation is better than whatever we have so far. + Use, + /// This annotation is better than nothing, but that's all; don't bother + /// recording its version. + UseAsFallback, + /// This annotation itself isn't interesting, but its version shows that the + /// correct answer is whatever's currently active. + ResetToActive +}; +} // end anonymous namespace + +static VersionedSwiftNameAction +checkVersionedSwiftName(VersionedSwiftNameInfo info, + clang::VersionTuple bestSoFar, + ImportNameVersion requestedVersion) { + if (!bestSoFar.empty() && bestSoFar <= info.Version) + return VersionedSwiftNameAction::Ignore; + + if (info.IsReplacedByActive) { + // We know that there are no versioned names between the active version and + // a replacement version, because otherwise /that/ name would be active. + // So if replacement < requested, we want to use the old value that was + // replaced (but with very low priority), and otherwise we want to use the + // new value that is now active. (Special case: replacement = 0 means that + // a header annotation was replaced by an unversioned API notes annotation.) + if (info.Version.empty() || + info.Version.getMajor() >= requestedVersion.majorVersionNumber()) { + return VersionedSwiftNameAction::ResetToActive; + } + if (bestSoFar.empty()) + return VersionedSwiftNameAction::UseAsFallback; + return VersionedSwiftNameAction::Ignore; + } + + if (info.Version.getMajor() < requestedVersion.majorVersionNumber()) + return VersionedSwiftNameAction::Ignore; + return VersionedSwiftNameAction::Use; } @@ -567,26 +613,60 @@ findSwiftNameAttr(const clang::Decl *decl, ImportNameVersion version) { return nullptr; // Handle versioned API notes for Swift 3 and later. This is the common case. - if (version != ImportNameVersion::swift2()) { + if (version > ImportNameVersion::swift2()) { + const auto *activeAttr = decl->getAttr(); + const clang::SwiftNameAttr *result = activeAttr; + clang::VersionTuple bestSoFar; for (auto *attr : decl->attrs()) { + VersionedSwiftNameInfo info; + if (auto *versionedAttr = dyn_cast(attr)) { - if (!matchesVersion(versionedAttr, version)) + auto *added = + dyn_cast(versionedAttr->getAttrToAdd()); + if (!added) continue; - if (auto *added = - dyn_cast(versionedAttr->getAttrToAdd())) { - return added; - } - } - if (auto *removeAttr = dyn_cast(attr)) { - if (!matchesVersion(removeAttr, version)) + info = {added, versionedAttr->getVersion(), + versionedAttr->getIsReplacedByActive()}; + + } else if (auto *removeAttr = + dyn_cast(attr)) { + if (removeAttr->getAttrKindToRemove() != clang::attr::SwiftName) continue; - if (removeAttr->getAttrKindToRemove() == clang::attr::SwiftName) - return nullptr; + info = {nullptr, removeAttr->getVersion(), + removeAttr->getIsReplacedByActive()}; + + } else { + continue; + } + + switch (checkVersionedSwiftName(info, bestSoFar, version)) { + case VersionedSwiftNameAction::Ignore: + continue; + case VersionedSwiftNameAction::Use: + result = info.Attr; + bestSoFar = info.Version; + break; + case VersionedSwiftNameAction::UseAsFallback: + // HACK: If there's a swift_name attribute in the headers /and/ in the + // unversioned API notes /and/ in the active versioned API notes, there + // will be two "replacement" attributes, one for each of the first two + // cases. Prefer the first one we see, because that turns out to be the + // one from the API notes, which matches the semantics when there are no + // versioned API notes. (This isn't very principled but there's at least + // a test to tell us if it changes.) + if (result == activeAttr) + result = info.Attr; + assert(bestSoFar.empty()); + break; + case VersionedSwiftNameAction::ResetToActive: + result = activeAttr; + bestSoFar = info.Version; + break; } } - return decl->getAttr(); + return result; } // The remainder of this function emulates the limited form of swift_name diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes index 6fd1676b11e49..af8b3b3eb5cae 100644 --- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes +++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes @@ -65,6 +65,23 @@ Functions: Tags: - Name: InnerInSwift4 SwiftName: Outer.Inner +Globals: + - Name: multiVersionedGlobal34Notes + SwiftName: multiVersionedGlobal34Notes_NEW + - Name: multiVersionedGlobal34Both + SwiftName: multiVersionedGlobal34Both_NEW + - Name: multiVersionedGlobal345Notes + SwiftName: multiVersionedGlobal345Notes_NEW + - Name: multiVersionedGlobal345Both + SwiftName: multiVersionedGlobal345Both_NEW + - Name: multiVersionedGlobal4Notes + SwiftName: multiVersionedGlobal4Notes_NEW + - Name: multiVersionedGlobal4Both + SwiftName: multiVersionedGlobal4Both_NEW + - Name: multiVersionedGlobal45Notes + SwiftName: multiVersionedGlobal45Notes_NEW + - Name: multiVersionedGlobal45Both + SwiftName: multiVersionedGlobal45Both_NEW SwiftVersions: - Version: 3.0 Classes: @@ -207,3 +224,72 @@ SwiftVersions: SwiftName: aliasRenamedSwift3 - Name: OptionyEnumRenamed SwiftName: renamedSwift3 + Globals: + - Name: multiVersionedGlobal34 + SwiftName: multiVersionedGlobal34_3 + - Name: multiVersionedGlobal34Header + SwiftName: multiVersionedGlobal34Header_3 + - Name: multiVersionedGlobal34Notes + SwiftName: multiVersionedGlobal34Notes_3 + - Name: multiVersionedGlobal34Both + SwiftName: multiVersionedGlobal34Both_3 + - Name: multiVersionedGlobal345 + SwiftName: multiVersionedGlobal345_3 + - Name: multiVersionedGlobal345Header + SwiftName: multiVersionedGlobal345Header_3 + - Name: multiVersionedGlobal345Notes + SwiftName: multiVersionedGlobal345Notes_3 + - Name: multiVersionedGlobal345Both + SwiftName: multiVersionedGlobal345Both_3 + - Version: 5 + Globals: + - Name: multiVersionedGlobal345 + SwiftName: multiVersionedGlobal345_5 + - Name: multiVersionedGlobal345Header + SwiftName: multiVersionedGlobal345Header_5 + - Name: multiVersionedGlobal345Notes + SwiftName: multiVersionedGlobal345Notes_5 + - Name: multiVersionedGlobal345Both + SwiftName: multiVersionedGlobal345Both_5 + - Name: multiVersionedGlobal45 + SwiftName: multiVersionedGlobal45_5 + - Name: multiVersionedGlobal45Header + SwiftName: multiVersionedGlobal45Header_5 + - Name: multiVersionedGlobal45Notes + SwiftName: multiVersionedGlobal45Notes_5 + - Name: multiVersionedGlobal45Both + SwiftName: multiVersionedGlobal45Both_5 + - Version: 4 # Versions are deliberately ordered as "3, 5, 4" to catch bugs. + Globals: + - Name: multiVersionedGlobal34 + SwiftName: multiVersionedGlobal34_4 + - Name: multiVersionedGlobal34Header + SwiftName: multiVersionedGlobal34Header_4 + - Name: multiVersionedGlobal34Notes + SwiftName: multiVersionedGlobal34Notes_4 + - Name: multiVersionedGlobal34Both + SwiftName: multiVersionedGlobal34Both_4 + - Name: multiVersionedGlobal345 + SwiftName: multiVersionedGlobal345_4 + - Name: multiVersionedGlobal345Header + SwiftName: multiVersionedGlobal345Header_4 + - Name: multiVersionedGlobal345Notes + SwiftName: multiVersionedGlobal345Notes_4 + - Name: multiVersionedGlobal345Both + SwiftName: multiVersionedGlobal345Both_4 + - Name: multiVersionedGlobal4 + SwiftName: multiVersionedGlobal4_4 + - Name: multiVersionedGlobal4Header + SwiftName: multiVersionedGlobal4Header_4 + - Name: multiVersionedGlobal4Notes + SwiftName: multiVersionedGlobal4Notes_4 + - Name: multiVersionedGlobal4Both + SwiftName: multiVersionedGlobal4Both_4 + - Name: multiVersionedGlobal45 + SwiftName: multiVersionedGlobal45_4 + - Name: multiVersionedGlobal45Header + SwiftName: multiVersionedGlobal45Header_4 + - Name: multiVersionedGlobal45Notes + SwiftName: multiVersionedGlobal45Notes_4 + - Name: multiVersionedGlobal45Both + SwiftName: multiVersionedGlobal45Both_4 diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h index c3a23fd931ced..43c932c55074c 100644 --- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h +++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h @@ -32,6 +32,7 @@ __attribute__((objc_root_class)) #import #import +#import #import #import #import diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Globals.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Globals.h new file mode 100644 index 0000000000000..059ecd7dded97 --- /dev/null +++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Globals.h @@ -0,0 +1,23 @@ +#pragma clang assume_nonnull begin + +int multiVersionedGlobal4; +int multiVersionedGlobal4Notes; +int multiVersionedGlobal4Header __attribute__((swift_name("multiVersionedGlobal4Header_NEW"))); +int multiVersionedGlobal4Both __attribute__((swift_name("multiVersionedGlobal4Both_OLD"))); + +int multiVersionedGlobal34; +int multiVersionedGlobal34Notes; +int multiVersionedGlobal34Header __attribute__((swift_name("multiVersionedGlobal34Header_NEW"))); +int multiVersionedGlobal34Both __attribute__((swift_name("multiVersionedGlobal34Both_OLD"))); + +int multiVersionedGlobal45; +int multiVersionedGlobal45Notes; +int multiVersionedGlobal45Header __attribute__((swift_name("multiVersionedGlobal45Header_NEW"))); +int multiVersionedGlobal45Both __attribute__((swift_name("multiVersionedGlobal45Both_OLD"))); + +int multiVersionedGlobal345; +int multiVersionedGlobal345Notes; +int multiVersionedGlobal345Header __attribute__((swift_name("multiVersionedGlobal345Header_NEW"))); +int multiVersionedGlobal345Both __attribute__((swift_name("multiVersionedGlobal345Both_OLD"))); + +#pragma clang assume_nonnull end diff --git a/test/APINotes/versioned-multi.swift b/test/APINotes/versioned-multi.swift new file mode 100644 index 0000000000000..7ebf5ec7901e6 --- /dev/null +++ b/test/APINotes/versioned-multi.swift @@ -0,0 +1,142 @@ +// RUN: %empty-directory(%t) + +// RUN: %target-swift-ide-test -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -print-regular-comments -swift-version 3 | %FileCheck -check-prefix=CHECK-SWIFT-3 %s + +// RUN: %target-swift-ide-test -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -swift-version 4 | %FileCheck -check-prefix=CHECK-SWIFT-4 %s + +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4_4") +// CHECK-SWIFT-3: var multiVersionedGlobal4: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal4_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Notes_4") +// CHECK-SWIFT-3: var multiVersionedGlobal4Notes: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal4Notes_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Header_4") +// CHECK-SWIFT-3: var multiVersionedGlobal4Header: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal4Header_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Both_4") +// CHECK-SWIFT-3: var multiVersionedGlobal4Both: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal4Both_4: Int32 + +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal34_3: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal34_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Notes_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Notes: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal34Notes_3: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal34Notes_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Notes_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Header_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Header: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal34Header_3: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal34Header_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Header_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Both_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Both: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal34Both_3: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal34Both_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Both_4: Int32 + +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45_4") +// CHECK-SWIFT-3: var multiVersionedGlobal45: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal45_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Notes_4") +// CHECK-SWIFT-3: var multiVersionedGlobal45Notes: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal45Notes_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Header_4") +// CHECK-SWIFT-3: var multiVersionedGlobal45Header: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal45Header_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Both_4") +// CHECK-SWIFT-3: var multiVersionedGlobal45Both: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal45Both_4: Int32 + +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal345_3: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal345_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Notes_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Notes: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal345Notes_3: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal345Notes_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Notes_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Header_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Header: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal345Header_3: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal345Header_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Header_4: Int32 +// CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Both_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Both: Int32 +// CHECK-SWIFT-3: var multiVersionedGlobal345Both_3: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal345Both_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Both_4: Int32 + + +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4_4") +// CHECK-SWIFT-4: var multiVersionedGlobal4: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal4_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal4Notes: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal4Notes_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal4Header: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal4Header_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal4Both: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal4Both_4: Int32 + +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34_3: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal34_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Notes: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Notes_3: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal34Notes_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Header: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Header_3: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal34Header_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Both: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Both_3: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal34Both_4: Int32 + +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45_4") +// CHECK-SWIFT-4: var multiVersionedGlobal45: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal45_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal45Notes: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal45Notes_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal45Header: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal45Header_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal45Both: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal45Both_4: Int32 + +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345_3: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal345_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Notes: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Notes_3: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal345Notes_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Header: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Header_3: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal345Header_4: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Both: Int32 +// CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Both_3: Int32 +// CHECK-SWIFT-4: var multiVersionedGlobal345Both_4: Int32 From a0117b0cd0b885f8582350e78cf3d13a6a0d05f9 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Mon, 11 Sep 2017 17:49:13 -0700 Subject: [PATCH 5/5] [ClangImporter] Bump the maximum supported version to Swift 5 "...finally." This was technically enabled two commits ago, since nothing checks that you're not /over/ maxVersion(). This is only used for - deciding the canonical way to import renamed types - trying to import things in multiple ways ...and so there are very few observable differences, especially before anyone has added any API notes that differentiate Swift 4 and Swift 5. At some point we should start encoding name versions in the lookup tables so that we only have to try all the names /once/, but the test suite doesn't seem to get measureably slower with this change, probably because it's pretty quick to decide that most things don't have multiple names. So we can put that off until later. --- lib/ClangImporter/ImportName.h | 2 +- test/APINotes/versioned-multi.swift | 155 ++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/lib/ClangImporter/ImportName.h b/lib/ClangImporter/ImportName.h index 420ea477b3583..f993b0292bb3c 100644 --- a/lib/ClangImporter/ImportName.h +++ b/lib/ClangImporter/ImportName.h @@ -110,7 +110,7 @@ class ImportNameVersion : public RelationalOperationsBase { /// FIXME: All other version information is in Version.h. Can this go there /// instead? static constexpr inline ImportNameVersion maxVersion() { - return ImportNameVersion{4, AsConstExpr}; + return ImportNameVersion{5, AsConstExpr}; } /// The version which should be used for importing types, which need to have diff --git a/test/APINotes/versioned-multi.swift b/test/APINotes/versioned-multi.swift index 7ebf5ec7901e6..d479c3c9dd0dc 100644 --- a/test/APINotes/versioned-multi.swift +++ b/test/APINotes/versioned-multi.swift @@ -4,18 +4,26 @@ // RUN: %target-swift-ide-test -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -swift-version 4 | %FileCheck -check-prefix=CHECK-SWIFT-4 %s +// RUN: %target-swift-ide-test -F %S/Inputs/custom-frameworks -print-module -source-filename %s -module-to-print=APINotesFrameworkTest -function-definitions=false -swift-version 5 | %FileCheck -check-prefix=CHECK-SWIFT-5 %s + // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4_4") // CHECK-SWIFT-3: var multiVersionedGlobal4: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal4_4: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Notes_4") // CHECK-SWIFT-3: var multiVersionedGlobal4Notes: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal4Notes_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal4Notes_4") +// CHECK-SWIFT-3: var multiVersionedGlobal4Notes_NEW: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Header_4") // CHECK-SWIFT-3: var multiVersionedGlobal4Header: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal4Header_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal4Header_4") +// CHECK-SWIFT-3: var multiVersionedGlobal4Header_NEW: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Both_4") // CHECK-SWIFT-3: var multiVersionedGlobal4Both: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal4Both_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal4Both_4") +// CHECK-SWIFT-3: var multiVersionedGlobal4Both_NEW: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34_3") // CHECK-SWIFT-3: var multiVersionedGlobal34: Int32 @@ -27,50 +35,72 @@ // CHECK-SWIFT-3: var multiVersionedGlobal34Notes_3: Int32 // CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal34Notes_3") // CHECK-SWIFT-3: var multiVersionedGlobal34Notes_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal34Notes_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Notes_NEW: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Header_3") // CHECK-SWIFT-3: var multiVersionedGlobal34Header: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal34Header_3: Int32 // CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal34Header_3") // CHECK-SWIFT-3: var multiVersionedGlobal34Header_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal34Header_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Header_NEW: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Both_3") // CHECK-SWIFT-3: var multiVersionedGlobal34Both: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal34Both_3: Int32 // CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal34Both_3") // CHECK-SWIFT-3: var multiVersionedGlobal34Both_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal34Both_3") +// CHECK-SWIFT-3: var multiVersionedGlobal34Both_NEW: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45_4") // CHECK-SWIFT-3: var multiVersionedGlobal45: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal45_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal45_4") +// CHECK-SWIFT-3: var multiVersionedGlobal45_5: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Notes_4") // CHECK-SWIFT-3: var multiVersionedGlobal45Notes: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal45Notes_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal45Notes_4") +// CHECK-SWIFT-3: var multiVersionedGlobal45Notes_5: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Header_4") // CHECK-SWIFT-3: var multiVersionedGlobal45Header: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal45Header_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal45Header_4") +// CHECK-SWIFT-3: var multiVersionedGlobal45Header_5: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Both_4") // CHECK-SWIFT-3: var multiVersionedGlobal45Both: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal45Both_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal45Both_4") +// CHECK-SWIFT-3: var multiVersionedGlobal45Both_5: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345_3") // CHECK-SWIFT-3: var multiVersionedGlobal345: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal345_3: Int32 // CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal345_3") // CHECK-SWIFT-3: var multiVersionedGlobal345_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal345_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345_5: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Notes_3") // CHECK-SWIFT-3: var multiVersionedGlobal345Notes: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal345Notes_3: Int32 // CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal345Notes_3") // CHECK-SWIFT-3: var multiVersionedGlobal345Notes_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal345Notes_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Notes_5: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Header_3") // CHECK-SWIFT-3: var multiVersionedGlobal345Header: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal345Header_3: Int32 // CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal345Header_3") // CHECK-SWIFT-3: var multiVersionedGlobal345Header_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal345Header_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Header_5: Int32 // CHECK-SWIFT-3: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Both_3") // CHECK-SWIFT-3: var multiVersionedGlobal345Both: Int32 // CHECK-SWIFT-3: var multiVersionedGlobal345Both_3: Int32 // CHECK-SWIFT-3: @available(swift, introduced: 4, renamed: "multiVersionedGlobal345Both_3") // CHECK-SWIFT-3: var multiVersionedGlobal345Both_4: Int32 +// CHECK-SWIFT-3: @available(swift, introduced: 5, renamed: "multiVersionedGlobal345Both_3") +// CHECK-SWIFT-3: var multiVersionedGlobal345Both_5: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4_4") @@ -79,12 +109,18 @@ // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Notes_4") // CHECK-SWIFT-4: var multiVersionedGlobal4Notes: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal4Notes_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal4Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal4Notes_NEW: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Header_4") // CHECK-SWIFT-4: var multiVersionedGlobal4Header: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal4Header_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal4Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal4Header_NEW: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Both_4") // CHECK-SWIFT-4: var multiVersionedGlobal4Both: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal4Both_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal4Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal4Both_NEW: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34_4") // CHECK-SWIFT-4: var multiVersionedGlobal34: Int32 @@ -96,47 +132,166 @@ // CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Notes_4") // CHECK-SWIFT-4: var multiVersionedGlobal34Notes_3: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal34Notes_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal34Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Notes_NEW: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Header_4") // CHECK-SWIFT-4: var multiVersionedGlobal34Header: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Header_4") // CHECK-SWIFT-4: var multiVersionedGlobal34Header_3: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal34Header_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal34Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Header_NEW: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Both_4") // CHECK-SWIFT-4: var multiVersionedGlobal34Both: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Both_4") // CHECK-SWIFT-4: var multiVersionedGlobal34Both_3: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal34Both_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal34Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal34Both_NEW: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45_4") // CHECK-SWIFT-4: var multiVersionedGlobal45: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal45_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal45_4") +// CHECK-SWIFT-4: var multiVersionedGlobal45_5: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Notes_4") // CHECK-SWIFT-4: var multiVersionedGlobal45Notes: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal45Notes_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal45Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal45Notes_5: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Header_4") // CHECK-SWIFT-4: var multiVersionedGlobal45Header: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal45Header_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal45Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal45Header_5: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Both_4") // CHECK-SWIFT-4: var multiVersionedGlobal45Both: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal45Both_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal45Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal45Both_5: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345_4") // CHECK-SWIFT-4: var multiVersionedGlobal345: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345_4") // CHECK-SWIFT-4: var multiVersionedGlobal345_3: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal345_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal345_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345_5: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Notes_4") // CHECK-SWIFT-4: var multiVersionedGlobal345Notes: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Notes_4") // CHECK-SWIFT-4: var multiVersionedGlobal345Notes_3: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal345Notes_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal345Notes_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Notes_5: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Header_4") // CHECK-SWIFT-4: var multiVersionedGlobal345Header: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Header_4") // CHECK-SWIFT-4: var multiVersionedGlobal345Header_3: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal345Header_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal345Header_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Header_5: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Both_4") // CHECK-SWIFT-4: var multiVersionedGlobal345Both: Int32 // CHECK-SWIFT-4: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Both_4") // CHECK-SWIFT-4: var multiVersionedGlobal345Both_3: Int32 // CHECK-SWIFT-4: var multiVersionedGlobal345Both_4: Int32 +// CHECK-SWIFT-4: @available(swift, introduced: 5, renamed: "multiVersionedGlobal345Both_4") +// CHECK-SWIFT-4: var multiVersionedGlobal345Both_5: Int32 + + +// CHECK-SWIFT-5: var multiVersionedGlobal4: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal4") +// CHECK-SWIFT-5: var multiVersionedGlobal4_4: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Notes_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal4Notes: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal4Notes_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal4Notes_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal4Notes_NEW: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Header_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal4Header: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal4Header_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal4Header_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal4Header_NEW: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal4Both_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal4Both: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal4Both_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal4Both_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal4Both_NEW: Int32 + +// CHECK-SWIFT-5: var multiVersionedGlobal34: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34") +// CHECK-SWIFT-5: var multiVersionedGlobal34_3: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal34") +// CHECK-SWIFT-5: var multiVersionedGlobal34_4: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Notes_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Notes: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Notes_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Notes_3: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal34Notes_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Notes_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal34Notes_NEW: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Header_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Header: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Header_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Header_3: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal34Header_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Header_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal34Header_NEW: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal34Both_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Both: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal34Both_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Both_3: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal34Both_NEW") +// CHECK-SWIFT-5: var multiVersionedGlobal34Both_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal34Both_NEW: Int32 + +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45_5") +// CHECK-SWIFT-5: var multiVersionedGlobal45: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal45_5") +// CHECK-SWIFT-5: var multiVersionedGlobal45_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal45_5: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Notes_5") +// CHECK-SWIFT-5: var multiVersionedGlobal45Notes: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal45Notes_5") +// CHECK-SWIFT-5: var multiVersionedGlobal45Notes_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal45Notes_5: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Header_5") +// CHECK-SWIFT-5: var multiVersionedGlobal45Header: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal45Header_5") +// CHECK-SWIFT-5: var multiVersionedGlobal45Header_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal45Header_5: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal45Both_5") +// CHECK-SWIFT-5: var multiVersionedGlobal45Both: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal45Both_5") +// CHECK-SWIFT-5: var multiVersionedGlobal45Both_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal45Both_5: Int32 + +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345_3: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal345_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal345_5: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Notes_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Notes: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Notes_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Notes_3: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal345Notes_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Notes_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal345Notes_5: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Header_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Header: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Header_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Header_3: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal345Header_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Header_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal345Header_5: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 3, renamed: "multiVersionedGlobal345Both_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Both: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 4, renamed: "multiVersionedGlobal345Both_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Both_3: Int32 +// CHECK-SWIFT-5: @available(swift, obsoleted: 5, renamed: "multiVersionedGlobal345Both_5") +// CHECK-SWIFT-5: var multiVersionedGlobal345Both_4: Int32 +// CHECK-SWIFT-5: var multiVersionedGlobal345Both_5: Int32