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 7728fbb7ccdcd..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() {} @@ -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; }); } @@ -3150,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; @@ -3211,12 +3211,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 +3232,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 27f152baf0530..87b4b717ff0e0 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -348,11 +348,17 @@ 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, - [&](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()); @@ -364,8 +370,8 @@ void ClangImporter::Implementation::forEachDistinctName( }); if (seen) return; - seenNames.push_back(key); - action(newName, nameVersion); + if (action(newName, nameVersion)) + seenNames.push_back(key); }); } @@ -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); @@ -2690,31 +2698,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 +2772,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; } @@ -4851,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); @@ -6921,9 +6932,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)); @@ -7975,9 +7984,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); + }); } } @@ -7995,29 +8004,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 * @@ -8079,26 +8089,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/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 2d40e02a89c77..161f1e9023ffb 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. @@ -318,10 +285,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 +313,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 +343,7 @@ void ClangImporter::Implementation::printSwiftName(ImportedName name, } if (fullyQualified) - printFullContextPrefix(name, os, *this); + printFullContextPrefix(name, version, os, *this); // Base name. os << name.getDeclName().getBaseName(); @@ -578,17 +545,63 @@ 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::LAST_VERSION; - return attrVersion.getMajor() == majorVersionNumberForNameVersion(version); +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; } -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,30 +609,64 @@ 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()) { + 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 @@ -843,7 +890,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 +1007,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 +1172,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 +1183,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 +1563,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); @@ -1723,7 +1770,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..f993b0292bb3c 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 -}; + /// 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::LAST_VERSION); - value = static_cast(static_cast(value) + 1); - return value; -} + action(ImportNameVersion::raw()); -static inline ImportNameVersion &operator--(ImportNameVersion &value) { - assert(value != ImportNameVersion::Raw); - value = static_cast(static_cast(value) - 1); - return value; -} - -/// 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{5, 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 { @@ -141,11 +152,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 +173,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 +195,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; } @@ -272,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. @@ -387,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 0cc02a0ea702b..cea17298611a7 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. @@ -1129,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); @@ -1220,11 +1229,14 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation /// will eventually reference that declaration, the contexts will still be /// considered distinct. /// - /// The names are generated in the same order as - /// forEachImportNameVersionFromCurrent. The current name is always first. + /// If \p action returns false, the current name will \e not be added to the + /// set of seen names. + /// + /// 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 action); /// Dump the Swift-specific name lookup tables we generate. diff --git a/lib/ClangImporter/SwiftLookupTable.cpp b/lib/ClangImporter/SwiftLookupTable.cpp index 176509e43a792..5e4d6f62feadf 100644 --- a/lib/ClangImporter/SwiftLookupTable.cpp +++ b/lib/ClangImporter/SwiftLookupTable.cpp @@ -1625,8 +1625,8 @@ void importer::addEntryToLookupTable(SwiftLookupTable &table, } // If we have a name to import as, add this entry to the table. - ImportNameVersion currentVersion = - nameVersionFromOptions(nameImporter.getLangOpts()); + auto currentVersion = + ImportNameVersion::fromOptions(nameImporter.getLangOpts()); if (auto importedName = nameImporter.importName(named, currentVersion)) { SmallPtrSet 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; 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..d479c3c9dd0dc --- /dev/null +++ b/test/APINotes/versioned-multi.swift @@ -0,0 +1,297 @@ +// 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 + +// 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 +// 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, 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") +// 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, 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 +// 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, 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