Merge pull request #9673 from DougGregor/lazy-generic-env-deserialization-4.0
[4.0] [Serialization] Stop pre-loading generic environments.
diff --git a/include/swift/IDE/Utils.h b/include/swift/IDE/Utils.h
index 66c42a7..c4bea80 100644
--- a/include/swift/IDE/Utils.h
+++ b/include/swift/IDE/Utils.h
@@ -250,7 +250,7 @@
struct ResolvedRangeInfo {
RangeKind Kind;
ReturnTyAndWhetherExit ExitInfo;
- StringRef Content;
+ CharSourceRange Content;
bool HasSingleEntry;
bool ThrowingUnhandledError;
OrphanKind Orphan;
@@ -260,8 +260,8 @@
ArrayRef<DeclaredDecl> DeclaredDecls;
ArrayRef<ReferencedDecl> ReferencedDecls;
DeclContext* RangeContext;
- ResolvedRangeInfo(RangeKind Kind, ReturnTyAndWhetherExit ExitInfo, StringRef Content,
- DeclContext* RangeContext,
+ ResolvedRangeInfo(RangeKind Kind, ReturnTyAndWhetherExit ExitInfo,
+ CharSourceRange Content, DeclContext* RangeContext,
bool HasSingleEntry, bool ThrowingUnhandledError,
OrphanKind Orphan, ArrayRef<ASTNode> ContainedNodes,
ArrayRef<DeclaredDecl> DeclaredDecls,
@@ -273,7 +273,7 @@
DeclaredDecls(DeclaredDecls),
ReferencedDecls(ReferencedDecls),
RangeContext(RangeContext) {}
- ResolvedRangeInfo(StringRef Content) :
+ ResolvedRangeInfo(CharSourceRange Content) :
ResolvedRangeInfo(RangeKind::Invalid, {nullptr, false}, Content, nullptr,
/*Single entry*/true, /*unhandled error*/false,
OrphanKind::None, {}, {}, {}) {}
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index 171e28d..ccaf626 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -3041,37 +3041,30 @@
// If the entry is not visible, skip it.
if (!isVisibleClangEntry(clangCtx, clangDecl)) continue;
- // Import the declaration.
- auto decl =
- cast_or_null<ValueDecl>(importDeclReal(clangDecl, CurrentVersion));
- if (!decl)
- continue;
+ forEachDistinctName(clangDecl,
+ [&](ImportedName importedName,
+ ImportNameVersion nameVersion) {
+ // Import the declaration.
+ auto decl =
+ cast_or_null<ValueDecl>(importDeclReal(clangDecl, nameVersion));
+ if (!decl)
+ return;
- // If the name we found matches, report the declaration.
- bool matchedAny = false;
- if (decl->getFullName().matchesRef(name)) {
- consumer.foundDecl(decl, DeclVisibilityKind::DynamicLookup);
- matchedAny = true;
- }
-
- // Check for an alternate declaration; if it's name matches,
- // report it.
- for (auto alternate : getAlternateDecls(decl)) {
- if (alternate->getFullName().matchesRef(name)) {
- consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup);
- matchedAny = true;
+ // If the name we found matches, report the declaration.
+ // FIXME: If we didn't need to check alternate decls here, we could avoid
+ // importing the member at all by checking importedName ahead of time.
+ if (decl->getFullName().matchesRef(name)) {
+ consumer.foundDecl(decl, DeclVisibilityKind::DynamicLookup);
}
- }
- // If we didn't find anything, try under the Swift 2 name.
- if (!matchedAny) {
- if (auto swift2Decl = cast_or_null<ValueDecl>(
- importDeclReal(clangDecl, Version::Swift2))) {
- if (swift2Decl->getFullName().matchesRef(name)) {
- consumer.foundDecl(swift2Decl, DeclVisibilityKind::DynamicLookup);
+ // Check for an alternate declaration; if its name matches,
+ // report it.
+ for (auto alternate : getAlternateDecls(decl)) {
+ if (alternate->getFullName().matchesRef(name)) {
+ consumer.foundDecl(alternate, DeclVisibilityKind::DynamicLookup);
}
}
- }
+ });
}
}
diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
index 64016d2..d06378e 100644
--- a/lib/ClangImporter/ImportDecl.cpp
+++ b/lib/ClangImporter/ImportDecl.cpp
@@ -345,6 +345,29 @@
return true;
}
+void ClangImporter::Implementation::forEachDistinctName(
+ const clang::NamedDecl *decl,
+ llvm::function_ref<void(ImportedName, ImportNameVersion)> action) {
+ using ImportNameKey = std::pair<DeclName, EffectiveClangContext>;
+ SmallVector<ImportNameKey, 8> seenNames;
+ forEachImportNameVersionFromCurrent(CurrentVersion,
+ [&](ImportNameVersion nameVersion) {
+ // Check to see if the name is different.
+ ImportedName newName = importFullName(decl, nameVersion);
+ ImportNameKey key(newName, newName.getEffectiveContext());
+ bool seen = llvm::any_of(seenNames,
+ [&key](const ImportNameKey &existing) -> bool {
+ if (key.first != existing.first)
+ return false;
+ return key.second.equalsWithoutResolving(existing.second);
+ });
+ if (seen)
+ return;
+ seenNames.push_back(key);
+ action(newName, nameVersion);
+ });
+}
+
// Build the init(rawValue:) initializer for an imported NS_ENUM.
// enum NSSomeEnum: RawType {
// init?(rawValue: RawType) {
@@ -2139,7 +2162,7 @@
if (Name.empty())
return nullptr;
- // If we've been asked to produce a Swift 2 stub, handle it via a
+ // If we've been asked to produce a compatibility stub, handle it via a
// typealias.
if (correctSwiftName)
return importCompatibilityTypeAlias(Decl, importedName,
@@ -2350,7 +2373,7 @@
if (!importedName)
return nullptr;
- // If we've been asked to produce a Swift 2 stub, handle it via a
+ // If we've been asked to produce a compatibility stub, handle it via a
// typealias.
if (correctSwiftName)
return importCompatibilityTypeAlias(decl, importedName,
@@ -2581,7 +2604,9 @@
break;
}
}
- Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
+
+ const clang::EnumDecl *canonicalClangDecl = decl->getCanonicalDecl();
+ Impl.ImportedDecls[{canonicalClangDecl, getVersion()}] = result;
// Import each of the enumerators.
@@ -2610,23 +2635,56 @@
}
}
+ auto contextIsEnum = [&](const ImportedName &name) -> bool {
+ EffectiveClangContext importContext = name.getEffectiveContext();
+ switch (importContext.getKind()) {
+ case EffectiveClangContext::DeclContext:
+ return importContext.getAsDeclContext() == canonicalClangDecl;
+ case EffectiveClangContext::TypedefContext: {
+ auto *typedefName = importContext.getTypedefName();
+ clang::QualType underlyingTy = typedefName->getUnderlyingType();
+ return underlyingTy->getAsTagDecl() == canonicalClangDecl;
+ }
+ case EffectiveClangContext::UnresolvedContext:
+ // Assume this is a context other than the enum.
+ return false;
+ }
+ };
+
for (auto constant : decl->enumerators()) {
- Decl *enumeratorDecl;
- Decl *swift2EnumeratorDecl = nullptr;
+ Decl *enumeratorDecl = nullptr;
+ TinyPtrVector<Decl *> variantDecls;
switch (enumKind) {
case EnumKind::Constants:
case EnumKind::Unknown:
- enumeratorDecl = Impl.importDecl(constant, getActiveSwiftVersion());
- swift2EnumeratorDecl =
- Impl.importDecl(constant, ImportNameVersion::Swift2);
+ Impl.forEachDistinctName(constant,
+ [&](ImportedName newName,
+ ImportNameVersion nameVersion) {
+ Decl *imported = Impl.importDecl(constant, nameVersion);
+ if (!imported)
+ return;
+ if (nameVersion == getActiveSwiftVersion())
+ enumeratorDecl = imported;
+ else
+ variantDecls.push_back(imported);
+ });
break;
case EnumKind::Options:
- enumeratorDecl =
- SwiftDeclConverter(Impl, getActiveSwiftVersion())
- .importOptionConstant(constant, decl, result);
- swift2EnumeratorDecl =
- SwiftDeclConverter(Impl, ImportNameVersion::Swift2)
- .importOptionConstant(constant, decl, result);
+ Impl.forEachDistinctName(constant,
+ [&](ImportedName newName,
+ ImportNameVersion nameVersion) {
+ if (!contextIsEnum(newName))
+ return;
+ SwiftDeclConverter converter(Impl, nameVersion);
+ Decl *imported =
+ converter.importOptionConstant(constant, decl, result);
+ if (!imported)
+ return;
+ if (nameVersion == getActiveSwiftVersion())
+ enumeratorDecl = imported;
+ else
+ variantDecls.push_back(imported);
+ });
break;
case EnumKind::Enum: {
auto canonicalCaseIter =
@@ -2671,10 +2729,21 @@
}
}
- swift2EnumeratorDecl =
- SwiftDeclConverter(Impl, ImportNameVersion::Swift2)
- .importEnumCase(constant, decl, cast<EnumDecl>(result),
- enumeratorDecl);
+ Impl.forEachDistinctName(constant,
+ [&](ImportedName newName,
+ ImportNameVersion nameVersion) {
+ if (nameVersion == getActiveSwiftVersion())
+ return;
+ if (!contextIsEnum(newName))
+ return;
+ SwiftDeclConverter converter(Impl, nameVersion);
+ Decl *imported =
+ converter.importEnumCase(constant, decl, cast<EnumDecl>(result),
+ enumeratorDecl);
+ if (!imported)
+ return;
+ variantDecls.push_back(imported);
+ });
break;
}
}
@@ -2691,7 +2760,8 @@
};
addDecl(result, enumeratorDecl);
- addDecl(result, swift2EnumeratorDecl);
+ for (auto *variant : variantDecls)
+ addDecl(result, variant);
// If there is an error wrapper, add an alias within the
// wrapper to the corresponding value within the enumerator
@@ -2757,7 +2827,7 @@
if (!importedName)
return nullptr;
- // If we've been asked to produce a Swift 2 stub, handle it via a
+ // If we've been asked to produce a compatibility stub, handle it via a
// typealias.
if (correctSwiftName)
return importCompatibilityTypeAlias(decl, importedName,
@@ -3000,7 +3070,7 @@
/*static*/ false, decl);
Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
- // If this is a Swift 2 stub, mark it as such.
+ // If this is a compatibility stub, mark it as such.
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
@@ -3039,7 +3109,7 @@
/*static*/ false, decl);
Impl.ImportedDecls[{decl->getCanonicalDecl(), getVersion()}] = result;
- // If this is a Swift 2 stub, mark it as such.
+ // If this is a compatibility stub, mark it as such.
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
@@ -3096,7 +3166,7 @@
name, type, dc);
result->setInterfaceType(type);
- // If this is a Swift 2 stub, mark is as such.
+ // If this is a compatibility stub, mark is as such.
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
@@ -3233,7 +3303,7 @@
result->setAccessibility(Accessibility::Public);
finishFuncDecl(decl, result);
- // If this is a Swift 2 stub, mark it as such.
+ // If this is a compatibility stub, mark it as such.
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
@@ -3323,7 +3393,7 @@
new (Impl.SwiftContext) IBOutletAttr(/*IsImplicit=*/false));
// FIXME: Handle IBOutletCollection.
- // If this is a Swift 2 stub, handle it as such.
+ // If this is a compatibility stub, handle it as such.
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
@@ -3401,7 +3471,7 @@
if (!decl->hasExternalStorage())
Impl.registerExternalDecl(result);
- // If this is a Swift 2 stub, mark it as such.
+ // If this is a compatibility stub, mark it as such.
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
@@ -3579,12 +3649,6 @@
{decl->param_begin(), decl->param_size()},
decl->isVariadic(), redundant);
- if (auto rawDecl = Impl.importDecl(decl, ImportNameVersion::Raw)) {
- // We expect the raw decl to always be a method.
- assert(isa<FuncDecl>(rawDecl));
- Impl.addAlternateDecl(result, cast<ValueDecl>(rawDecl));
- }
-
return result;
}
@@ -3853,13 +3917,6 @@
importObjCGenericParams(const clang::ObjCInterfaceDecl *decl,
DeclContext *dc);
- /// Import members of the given Objective-C container and add them to the
- /// list of corresponding Swift members.
- void importObjCMembers(const clang::ObjCContainerDecl *decl,
- DeclContext *swiftContext,
- llvm::SmallPtrSet<Decl *, 4> &knownMembers,
- SmallVectorImpl<Decl *> &members);
-
/// \brief Import the members of all of the protocols to which the given
/// Objective-C class, category, or extension explicitly conforms into
/// the given list of members, so long as the method was not already
@@ -4031,7 +4088,7 @@
auto importedName = importFullName(decl, correctSwiftName);
if (!importedName) return nullptr;
- // If we've been asked to produce a Swift 2 stub, handle it via a
+ // If we've been asked to produce a compatibility stub, handle it via a
// typealias.
if (correctSwiftName)
return importCompatibilityTypeAlias(decl, importedName,
@@ -4169,7 +4226,7 @@
auto importedName = importFullName(decl, correctSwiftName);
if (!importedName) return nullptr;
- // If we've been asked to produce a Swift 2 stub, handle it via a
+ // If we've been asked to produce a compatibility stub, handle it via a
// typealias.
if (correctSwiftName)
return importCompatibilityTypeAlias(decl, importedName,
@@ -4498,7 +4555,7 @@
setter->setOverriddenDecl(parentSetter);
}
- // If this is a Swift 2 stub, mark it as such.
+ // If this is a compatibility stub, mark it as such.
if (correctSwiftName)
markAsVariant(result, *correctSwiftName);
@@ -4962,7 +5019,7 @@
Decl *SwiftDeclConverter::importEnumCase(const clang::EnumConstantDecl *decl,
const clang::EnumDecl *clangEnum,
EnumDecl *theEnum,
- Decl *swift3Decl) {
+ Decl *correctDecl) {
auto &context = Impl.SwiftContext;
Optional<ImportedName> correctSwiftName;
auto name =
@@ -4971,25 +5028,22 @@
return nullptr;
if (correctSwiftName) {
- // We're creating a Swift 2 stub. Treat it as an enum case alias.
- if (!swift3Decl)
+ // We're creating a compatibility stub. Treat it as an enum case alias.
+ auto correctCase = dyn_cast_or_null<EnumElementDecl>(correctDecl);
+ if (!correctCase)
return nullptr;
- // If the Swift 3 declaration was unavailable, don't map to it.
+ // If the correct declaration was unavailable, don't map to it.
// FIXME: This eliminates spurious errors, but affects QoI.
- if (swift3Decl->getAttrs().isUnavailable(Impl.SwiftContext))
+ if (correctCase->getAttrs().isUnavailable(Impl.SwiftContext))
return nullptr;
- auto swift3Case = dyn_cast<EnumElementDecl>(swift3Decl);
- if (!swift3Case)
- return nullptr;
+ auto compatibilityCase =
+ importEnumCaseAlias(name, decl, correctCase, clangEnum, theEnum);
+ if (compatibilityCase)
+ markAsVariant(compatibilityCase, *correctSwiftName);
- auto swift2Case =
- importEnumCaseAlias(name, decl, swift3Case, clangEnum, theEnum);
- if (swift2Case)
- markAsVariant(swift2Case, *correctSwiftName);
-
- return swift2Case;
+ return compatibilityCase;
}
// Use the constant's underlying value as its raw value in Swift.
@@ -5053,7 +5107,7 @@
CD->getAttrs().add(attr);
}
- // If this is a Swift 2 stub, mark it as such.
+ // If this is a compatibility stub, mark it as such.
if (correctSwiftName)
markAsVariant(CD, *correctSwiftName);
@@ -5496,7 +5550,7 @@
importConstructor(objcMethod, dc, implicit, kind, required, selector,
importedName, params, variadic, redundant);
- // If this is a Swift 2 stub, mark it as such.
+ // If this is a compatibility stub, mark it as such.
if (result && correctSwiftName)
markAsVariant(result, *correctSwiftName);
@@ -6342,37 +6396,6 @@
genericParams, Impl.importSourceLoc(typeParamList->getRAngleLoc()));
}
-void SwiftDeclConverter::importObjCMembers(
- const clang::ObjCContainerDecl *decl, DeclContext *swiftContext,
- llvm::SmallPtrSet<Decl *, 4> &knownMembers,
- SmallVectorImpl<Decl *> &members) {
- for (auto m = decl->decls_begin(), mEnd = decl->decls_end(); m != mEnd; ++m) {
- auto nd = dyn_cast<clang::NamedDecl>(*m);
- if (!nd || nd != nd->getCanonicalDecl())
- continue;
-
- auto member = Impl.importDecl(nd, getVersion());
- if (!member)
- continue;
-
- if (auto objcMethod = dyn_cast<clang::ObjCMethodDecl>(nd)) {
- // If there is are alternate declarations for this member, add it.
- for (auto alternate : Impl.getAlternateDecls(member)) {
- if (alternate->getDeclContext() == member->getDeclContext() &&
- knownMembers.insert(alternate).second)
- members.push_back(alternate);
- }
-
- // If this declaration shouldn't be visible, don't add it to
- // the list.
- if (shouldSuppressDeclImport(objcMethod))
- continue;
- }
-
- members.push_back(member);
- }
-}
-
void SwiftDeclConverter::importMirroredProtocolMembers(
const clang::ObjCContainerDecl *decl, DeclContext *dc,
ArrayRef<ProtocolDecl *> protocols, SmallVectorImpl<Decl *> &members,
@@ -6412,7 +6435,7 @@
const auto &languageVersion =
Impl.SwiftContext.LangOpts.EffectiveLanguageVersion;
for (auto member : proto->getMembers()) {
- // Skip Swift 2 stubs; there's no reason to mirror them.
+ // Skip compatibility stubs; there's no reason to mirror them.
if (member->getAttrs().isUnavailableInSwiftVersion(languageVersion))
continue;
@@ -6512,7 +6535,7 @@
if (!ctor)
continue;
- // Don't inherit Swift 2 stubs.
+ // Don't inherit compatibility stubs.
if (ctor->getAttrs().isUnavailableInSwiftVersion(languageVersion))
continue;
@@ -6557,7 +6580,7 @@
/*required=*/false, ctor->getObjCSelector(),
importedName, objcMethod->parameters(),
objcMethod->isVariadic(), redundant)) {
- // If this is a Swift 2 stub, mark it as such.
+ // If this is a compatibility stub, mark it as such.
if (correctSwiftName)
markAsVariant(newCtor, *correctSwiftName);
@@ -7700,14 +7723,8 @@
// Only continue members in the same submodule as this extension.
if (decl->getImportedOwningModule() != submodule) continue;
- SmallPtrSet<DeclName, 8> seenNames;
- forEachImportNameVersionFromCurrent(CurrentVersion,
- [&](ImportNameVersion nameVersion) {
- // Check to see if the name is different.
- ImportedName newName = importFullName(decl, nameVersion);
- if (!seenNames.insert(newName).second)
- return;
-
+ forEachDistinctName(decl, [&](ImportedName newName,
+ ImportNameVersion nameVersion) {
// Quickly check the context and bail out if it obviously doesn't
// belong here.
if (auto *importDC = newName.getEffectiveContext().getAsDeclContext())
@@ -7735,10 +7752,6 @@
Instance->getSourceManager(),
"loading members for");
- // TODO: accommodate deprecated versions as well
- SwiftDeclConverter converter(*this, CurrentVersion);
- SwiftDeclConverter swift2Converter(*this, ImportNameVersion::Swift2);
-
DeclContext *DC;
IterableDeclContext *IDC;
SmallVector<ProtocolDecl *, 4> protos;
@@ -7773,9 +7786,36 @@
ImportingEntityRAII Importing(*this);
SmallVector<Decl *, 16> members;
- llvm::SmallPtrSet<Decl *, 4> knownMembers;
- converter.importObjCMembers(objcContainer, DC, knownMembers, members);
- swift2Converter.importObjCMembers(objcContainer, DC, knownMembers, members);
+ llvm::SmallPtrSet<Decl *, 4> knownAlternateMembers;
+ for (const clang::Decl *m : objcContainer->decls()) {
+ auto nd = dyn_cast<clang::NamedDecl>(m);
+ if (!nd || nd != nd->getCanonicalDecl())
+ continue;
+
+ forEachDistinctName(nd,
+ [&](ImportedName name, ImportNameVersion nameVersion) {
+ auto member = importDecl(nd, nameVersion);
+ if (!member)
+ return;
+
+ // 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;
+
+ members.push_back(member);
+ });
+ }
+
+ SwiftDeclConverter converter(*this, CurrentVersion);
protos = takeImportedProtocols(D);
if (auto clangClass = dyn_cast<clang::ObjCInterfaceDecl>(objcContainer)) {
@@ -7804,7 +7844,6 @@
for (auto member : members) {
IDC->addMember(member);
}
-
}
void ClangImporter::Implementation::loadAllConformances(
diff --git a/lib/ClangImporter/ImportName.cpp b/lib/ClangImporter/ImportName.cpp
index a7a92e9..5f9e227 100644
--- a/lib/ClangImporter/ImportName.cpp
+++ b/lib/ClangImporter/ImportName.cpp
@@ -834,9 +834,11 @@
case EnumKind::Enum:
case EnumKind::Options:
// Enums are mapped to Swift enums, Options to Swift option sets.
- res = cast<clang::DeclContext>(enumDecl);
- break;
-
+ if (version != ImportNameVersion::Raw) {
+ res = cast<clang::DeclContext>(enumDecl);
+ break;
+ }
+ LLVM_FALLTHROUGH;
case EnumKind::Constants:
case EnumKind::Unknown:
// The enum constant goes into the redeclaration context of the
@@ -935,9 +937,9 @@
return false;
}
-bool NameImporter::shouldBeSwiftPrivate(const clang::NamedDecl *decl,
- clang::Sema &clangSema) {
-
+static bool shouldBeSwiftPrivate(NameImporter &nameImporter,
+ const clang::NamedDecl *decl,
+ ImportNameVersion version) {
// Decl with the attribute are obviously private
if (decl->hasAttr<clang::SwiftPrivateAttr>())
return true;
@@ -946,7 +948,12 @@
// private if the parent enum is marked private.
if (auto *ECD = dyn_cast<clang::EnumConstantDecl>(decl)) {
auto *ED = cast<clang::EnumDecl>(ECD->getDeclContext());
- switch (getEnumKind(ED)) {
+ switch (nameImporter.getEnumKind(ED)) {
+ case EnumKind::Enum:
+ case EnumKind::Options:
+ if (version != ImportNameVersion::Raw)
+ break;
+ LLVM_FALLTHROUGH;
case EnumKind::Constants:
case EnumKind::Unknown:
if (ED->hasAttr<clang::SwiftPrivateAttr>())
@@ -955,10 +962,6 @@
if (enumTypedef->hasAttr<clang::SwiftPrivateAttr>())
return true;
break;
-
- case EnumKind::Enum:
- case EnumKind::Options:
- break;
}
}
@@ -1503,7 +1506,7 @@
// Enumeration constants may have common prefixes stripped.
bool strippedPrefix = false;
- if (isa<clang::EnumConstantDecl>(D)) {
+ if (version != ImportNameVersion::Raw && isa<clang::EnumConstantDecl>(D)) {
auto enumDecl = cast<clang::EnumDecl>(D->getDeclContext());
auto enumInfo = getEnumInfo(enumDecl);
@@ -1625,7 +1628,7 @@
// If this declaration has the swift_private attribute, prepend "__" to the
// appropriate place.
SmallString<16> swiftPrivateScratch;
- if (shouldBeSwiftPrivate(D, clangSema)) {
+ if (shouldBeSwiftPrivate(*this, D, version)) {
// Special case: empty arg factory, "for historical reasons", is not private
if (isInitializer && argumentNames.empty() &&
(result.getInitKind() == CtorInitializerKind::Factory ||
diff --git a/lib/ClangImporter/ImportName.h b/lib/ClangImporter/ImportName.h
index cab8794..b8f33cc 100644
--- a/lib/ClangImporter/ImportName.h
+++ b/lib/ClangImporter/ImportName.h
@@ -363,9 +363,6 @@
ArrayRef<const clang::ParmVarDecl *> params,
bool isInitializer, bool hasCustomName);
- /// Whether we should import this as Swift Private
- bool shouldBeSwiftPrivate(const clang::NamedDecl *, clang::Sema &clangSema);
-
EffectiveClangContext determineEffectiveContext(const clang::NamedDecl *,
const clang::DeclContext *,
ImportNameVersion version);
diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h
index b70a7b1..32f7c33 100644
--- a/lib/ClangImporter/ImporterImpl.h
+++ b/lib/ClangImporter/ImporterImpl.h
@@ -1169,6 +1169,23 @@
/// Determine the effective Clang context for the given Swift nominal type.
EffectiveClangContext getEffectiveClangContext(NominalTypeDecl *nominal);
+ /// Attempts to import the name of \p decl with each possible
+ /// ImportNameVersion. \p action will be called with each unique name.
+ ///
+ /// In this case, "unique" means either the full name is distinct or the
+ /// effective context is distinct. This method does not attempt to handle
+ /// "unresolved" contexts in any special way---if one name references a
+ /// particular Clang declaration and the other has an unresolved context that
+ /// 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.
+ void forEachDistinctName(
+ const clang::NamedDecl *decl,
+ llvm::function_ref<void(importer::ImportedName,
+ importer::ImportNameVersion)> action);
+
/// Dump the Swift-specific name lookup tables we generate.
void dumpSwiftLookupTables();
diff --git a/lib/ClangImporter/SwiftLookupTable.h b/lib/ClangImporter/SwiftLookupTable.h
index a7f5e05..ef315b7 100644
--- a/lib/ClangImporter/SwiftLookupTable.h
+++ b/lib/ClangImporter/SwiftLookupTable.h
@@ -56,10 +56,10 @@
/// Swift name, this will be recorded as
class EffectiveClangContext {
public:
- enum Kind {
+ enum Kind : uint8_t {
DeclContext,
TypedefContext,
- UnresolvedContext,
+ UnresolvedContext, // must be last
};
private:
@@ -70,15 +70,19 @@
const char *Data;
} Unresolved;
};
- Kind TheKind;
- unsigned UnresolvedLength;
-
+
+ /// If KindOrBiasedLength < Kind::UnresolvedContext, this represents a Kind.
+ /// Otherwise it's (uintptr_t)Kind::UnresolvedContext plus the length of
+ /// Unresolved.Data.
+ uintptr_t KindOrBiasedLength;
+
public:
- EffectiveClangContext() : TheKind(DeclContext) {
+ EffectiveClangContext() : KindOrBiasedLength(DeclContext) {
DC = nullptr;
}
- EffectiveClangContext(const clang::DeclContext *dc) : TheKind(DeclContext) {
+ EffectiveClangContext(const clang::DeclContext *dc)
+ : KindOrBiasedLength(DeclContext) {
assert(dc != nullptr && "use null constructor instead");
if (auto tagDecl = dyn_cast<clang::TagDecl>(dc)) {
DC = tagDecl->getCanonicalDecl();
@@ -99,14 +103,13 @@
}
EffectiveClangContext(const clang::TypedefNameDecl *typedefName)
- : TheKind(TypedefContext)
- {
+ : KindOrBiasedLength(TypedefContext) {
Typedef = typedefName->getCanonicalDecl();
}
- EffectiveClangContext(StringRef unresolved) : TheKind(UnresolvedContext) {
+ EffectiveClangContext(StringRef unresolved)
+ : KindOrBiasedLength(UnresolvedContext + unresolved.size()) {
Unresolved.Data = unresolved.data();
- UnresolvedLength = unresolved.size();
}
/// Determine whether this effective Clang context was set.
@@ -115,7 +118,12 @@
}
/// Determine the kind of effective Clang context.
- Kind getKind() const { return TheKind; }
+ Kind getKind() const {
+ if (KindOrBiasedLength >= UnresolvedContext)
+ return UnresolvedContext;
+ return static_cast<Kind>(KindOrBiasedLength);
+
+ }
/// Retrieve the declaration context.
const clang::DeclContext *getAsDeclContext() const {
@@ -131,17 +139,26 @@
/// Retrieve the unresolved context name.
StringRef getUnresolvedName() const {
assert(getKind() == UnresolvedContext);
- return StringRef(Unresolved.Data, UnresolvedLength);
+ return StringRef(Unresolved.Data, KindOrBiasedLength - UnresolvedContext);
+ }
+
+ /// Compares two EffectiveClangContexts without resolving unresolved names.
+ bool equalsWithoutResolving(const EffectiveClangContext &other) const {
+ if (getKind() != other.getKind())
+ return false;
+ switch (getKind()) {
+ case DeclContext:
+ return DC == other.DC;
+ case TypedefContext:
+ return Typedef == other.Typedef;
+ case UnresolvedContext:
+ return getUnresolvedName() == other.getUnresolvedName();
+ }
}
};
-#if LLVM_PTR_SIZE == 4
-static_assert(sizeof(EffectiveClangContext) <= 4 * sizeof(void *),
- "should fit in four pointers");
-#else
static_assert(sizeof(EffectiveClangContext) <= 2 * sizeof(void *),
- "should fit in a couple pointers");
-#endif
+ "should be small");
class SwiftLookupTableReader;
class SwiftLookupTableWriter;
diff --git a/lib/IDE/SwiftSourceDocInfo.cpp b/lib/IDE/SwiftSourceDocInfo.cpp
index 88778ef..8bf94ff 100644
--- a/lib/IDE/SwiftSourceDocInfo.cpp
+++ b/lib/IDE/SwiftSourceDocInfo.cpp
@@ -226,7 +226,7 @@
}
OS << "</Kind>\n";
- OS << "<Content>" << Content << "</Content>\n";
+ OS << "<Content>" << Content.str() << "</Content>\n";
if (auto Ty = ExitInfo.getPointer()) {
OS << "<Type>";
@@ -372,7 +372,7 @@
Token &EndTok;
SourceLoc Start;
SourceLoc End;
- StringRef Content;
+ CharSourceRange Content;
Optional<ResolvedRangeInfo> Result;
std::vector<ContextInfo> ContextStack;
ContextInfo &getCurrentDC() {
@@ -498,7 +498,7 @@
File(File), Ctx(File.getASTContext()), SM(Ctx.SourceMgr),
AllTokens(AllTokens), StartTok(AllTokens[StartIdx]), EndTok(AllTokens[EndIdx]),
Start(StartTok.getLoc()), End(EndTok.getLoc()),
- Content(getContent()) {
+ Content(getContentRange()) {
assert(Start.isValid() && End.isValid());
}
@@ -815,11 +815,11 @@
return RangeMatchKind::NoneMatch;
}
- StringRef getContent() {
+ CharSourceRange getContentRange() {
SourceManager &SM = File.getASTContext().SourceMgr;
return CharSourceRange(SM, StartTok.hasComment() ?
StartTok.getCommentStart() : StartTok.getLoc(),
- Lexer::getLocForEndOfToken(SM, End)).str();
+ Lexer::getLocForEndOfToken(SM, End));
}
};
@@ -882,7 +882,7 @@
ResolvedRangeInfo RangeResolver::resolve() {
if (!Impl)
- return ResolvedRangeInfo(StringRef());
+ return ResolvedRangeInfo(CharSourceRange());
Impl->enter(ASTNode());
walk(Impl->File);
return Impl->getResult();
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 16e7a8f..79ce060 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.apinotes
@@ -88,12 +88,42 @@
SwiftImportAsNonGeneric: true
- Name: RenamedGeneric
SwiftName: OldRenamedGeneric
+ - Name: ClassWithManyRenames
+ Methods:
+ - Selector: "classWithManyRenamesForInt:"
+ MethodKind: Class
+ SwiftName: "init(swift3Factory:)"
+ - Selector: "initWithBoolean:"
+ MethodKind: Instance
+ SwiftName: "init(swift3Boolean:)"
+ - Selector: "doImportantThings"
+ MethodKind: Instance
+ SwiftName: "swift3DoImportantThings()"
+ Properties:
+ - Name: "importantClassProperty"
+ PropertyKind: Class
+ SwiftName: "swift3ClassProperty"
+ - Name: "importantInstanceProperty"
+ PropertyKind: Instance
+ SwiftName: "swift3InstanceProperty"
Protocols:
- Name: ProtoWithVersionedUnavailableMember
Methods:
- Selector: requirement
MethodKind: Instance
ResultType: 'ForwardClass * _Nullable'
+ - Name: ProtoWithManyRenames
+ Methods:
+ - Selector: "initWithBoolean:"
+ MethodKind: Instance
+ SwiftName: "init(swift3Boolean:)"
+ - Selector: "doImportantThings"
+ MethodKind: Instance
+ SwiftName: "swift3DoImportantThings()"
+ Properties:
+ - Name: "importantClassProperty"
+ PropertyKind: Class
+ SwiftName: "swift3ClassProperty"
Functions:
- Name: acceptDoublePointer
SwiftName: 'acceptPointer(_:)'
@@ -116,3 +146,14 @@
SwiftName: ImportantCAlias
- Name: EnclosingStructIdentifier
SwiftName: EnclosingStructIdentifier
+ Enumerators:
+ - Name: AnonymousEnumRenamed
+ SwiftName: AnonymousEnumRenamedSwift3
+ - Name: UnknownEnumRenamed
+ SwiftName: UnknownEnumRenamedSwift3
+ - Name: TrueEnumRenamed
+ SwiftName: renamedSwift3
+ - Name: TrueEnumAliasRenamed
+ SwiftName: aliasRenamedSwift3
+ - Name: OptionyEnumRenamed
+ SwiftName: renamedSwift3
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 97b1d2e..c0f387e 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/APINotesFrameworkTest.h
@@ -25,6 +25,7 @@
#endif // __OBJC__
#import <APINotesFrameworkTest/Classes.h>
+#import <APINotesFrameworkTest/Enums.h>
#import <APINotesFrameworkTest/ImportAsMember.h>
#import <APINotesFrameworkTest/Properties.h>
#import <APINotesFrameworkTest/Protocols.h>
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Classes.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Classes.h
index c74a642..73e44fa 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Classes.h
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Classes.h
@@ -8,5 +8,14 @@
@interface RenamedGeneric<Element: Base *> : Base
@end
+@interface ClassWithManyRenames : Base
++ (instancetype)classWithManyRenamesForInt:(int)value;
+- (instancetype)initWithBoolean:(_Bool)value __attribute__((swift_name("init(finalBoolean:)")));
+
+- (void)doImportantThings __attribute__((swift_name("finalDoImportantThings()")));
+@property (class, nullable) id importantClassProperty __attribute__((swift_name("finalClassProperty")));
+@property (nullable) id importantInstanceProperty __attribute__((swift_name("finalInstanceProperty")));
+@end
+
#pragma clang assume_nonnull end
#endif // __OBJC__
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Enums.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Enums.h
new file mode 100644
index 0000000..bfe32fc
--- /dev/null
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Enums.h
@@ -0,0 +1,24 @@
+#pragma clang assume_nonnull begin
+
+enum {
+ AnonymousEnumValue,
+ AnonymousEnumRenamed __attribute__((swift_name("AnonymousEnumRenamedSwiftUnversioned")))
+};
+
+enum UnknownEnum {
+ UnknownEnumValue,
+ UnknownEnumRenamed __attribute__((swift_name("UnknownEnumRenamedSwiftUnversioned")))
+};
+
+enum __attribute__((enum_extensibility(open))) TrueEnum {
+ TrueEnumValue,
+ TrueEnumRenamed __attribute__((swift_name("renamedSwiftUnversioned"))),
+ TrueEnumAliasRenamed __attribute__((swift_name("aliasRenamedSwiftUnversioned")))
+};
+
+enum __attribute__((flag_enum)) OptionyEnum {
+ OptionyEnumValue = 1,
+ OptionyEnumRenamed __attribute__((swift_name("renamedSwiftUnversioned"))) = 2
+};
+
+#pragma clang assume_nonnull end
diff --git a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Protocols.h b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Protocols.h
index 6a8840c..1e66303 100644
--- a/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Protocols.h
+++ b/test/APINotes/Inputs/custom-frameworks/APINotesFrameworkTest.framework/Headers/Protocols.h
@@ -7,5 +7,11 @@
- (nullable id)requirement;
@end
+@protocol ProtoWithManyRenames
+- (instancetype)initWithBoolean:(_Bool)value __attribute__((swift_name("init(finalBoolean:)")));
+- (void)doImportantThings __attribute__((swift_name("finalDoImportantThings()")));
+@property (class, nullable) id importantClassProperty __attribute__((swift_name("finalClassProperty")));
+@end
+
#pragma clang assume_nonnull end
#endif // __OBJC__
diff --git a/test/APINotes/versioned-objc-dynamic-lookup.swift b/test/APINotes/versioned-objc-dynamic-lookup.swift
new file mode 100644
index 0000000..d3bf2b6
--- /dev/null
+++ b/test/APINotes/versioned-objc-dynamic-lookup.swift
@@ -0,0 +1,35 @@
+// RUN: rm -rf %t && mkdir -p %t
+
+// RUN: not %target-swift-frontend -typecheck -F %S/Inputs/custom-frameworks -swift-version 4 %s 2>&1 | %FileCheck -check-prefix=CHECK-DIAGS -check-prefix=CHECK-DIAGS-4 %s
+// RUN: not %target-swift-frontend -typecheck -F %S/Inputs/custom-frameworks -swift-version 3 %s 2>&1 | %FileCheck -check-prefix=CHECK-DIAGS -check-prefix=CHECK-DIAGS-3 %s
+
+// REQUIRES: objc_interop
+
+import APINotesFrameworkTest
+
+func testRenamedClassMembers(obj: AnyObject) {
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'doImportantThings()' has been renamed to 'swift3DoImportantThings()'
+ obj.doImportantThings()
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'doImportantThings()' has been renamed to 'finalDoImportantThings()'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ obj.swift3DoImportantThings()
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'swift3DoImportantThings()' has been renamed to 'finalDoImportantThings()'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'finalDoImportantThings()' has been renamed to 'swift3DoImportantThings()'
+ obj.finalDoImportantThings()
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'importantInstanceProperty' has been renamed to 'swift3InstanceProperty'
+ _ = obj.importantInstanceProperty
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'importantInstanceProperty' has been renamed to 'finalInstanceProperty'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ _ = obj.swift3InstanceProperty
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'swift3InstanceProperty' has been renamed to 'finalInstanceProperty'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'finalInstanceProperty' has been renamed to 'swift3InstanceProperty'
+ _ = obj.finalInstanceProperty
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+}
\ No newline at end of file
diff --git a/test/APINotes/versioned-objc.swift b/test/APINotes/versioned-objc.swift
index 9cf44f4..bb6258a 100644
--- a/test/APINotes/versioned-objc.swift
+++ b/test/APINotes/versioned-objc.swift
@@ -43,4 +43,101 @@
// CHECK-DIAGS-4:[[@LINE-1]]:{{[0-9]+}}: error: 'RenamedGeneric' requires that 'SwiftClass' inherit from 'Base'
}
+func testRenamedClassMembers(obj: ClassWithManyRenames) {
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'classWithManyRenamesForInt' has been replaced by 'init(swift3Factory:)'
+ _ = ClassWithManyRenames.classWithManyRenamesForInt(0)
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'classWithManyRenamesForInt' has been replaced by 'init(for:)'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(forInt:)' has been replaced by 'init(swift3Factory:)'
+ _ = ClassWithManyRenames(forInt: 0)
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(forInt:)' has been replaced by 'init(for:)'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ _ = ClassWithManyRenames(swift3Factory: 0)
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(swift3Factory:)' has been replaced by 'init(for:)'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(for:)' has been replaced by 'init(swift3Factory:)'
+ _ = ClassWithManyRenames(for: 0)
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(boolean:)' has been renamed to 'init(swift3Boolean:)'
+ _ = ClassWithManyRenames(boolean: false)
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(boolean:)' has been renamed to 'init(finalBoolean:)'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ _ = ClassWithManyRenames(swift3Boolean: false)
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(swift3Boolean:)' has been renamed to 'init(finalBoolean:)'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(finalBoolean:)' has been renamed to 'init(swift3Boolean:)'
+ _ = ClassWithManyRenames(finalBoolean: false)
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'doImportantThings()' has been renamed to 'swift3DoImportantThings()'
+ obj.doImportantThings()
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'doImportantThings()' has been renamed to 'finalDoImportantThings()'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ obj.swift3DoImportantThings()
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'swift3DoImportantThings()' has been renamed to 'finalDoImportantThings()'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'finalDoImportantThings()' has been renamed to 'swift3DoImportantThings()'
+ obj.finalDoImportantThings()
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'importantClassProperty' has been renamed to 'swift3ClassProperty'
+ _ = ClassWithManyRenames.importantClassProperty
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'importantClassProperty' has been renamed to 'finalClassProperty'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ _ = ClassWithManyRenames.swift3ClassProperty
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'swift3ClassProperty' has been renamed to 'finalClassProperty'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'finalClassProperty' has been renamed to 'swift3ClassProperty'
+ _ = ClassWithManyRenames.finalClassProperty
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+}
+
+func testRenamedProtocolMembers(obj: ProtoWithManyRenames) {
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(boolean:)' has been renamed to 'init(swift3Boolean:)'
+ _ = type(of: obj).init(boolean: false)
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(boolean:)' has been renamed to 'init(finalBoolean:)'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ _ = type(of: obj).init(swift3Boolean: false)
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'init(swift3Boolean:)' has been renamed to 'init(finalBoolean:)'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'init(finalBoolean:)' has been renamed to 'init(swift3Boolean:)'
+ _ = type(of: obj).init(finalBoolean: false)
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'doImportantThings()' has been renamed to 'swift3DoImportantThings()'
+ obj.doImportantThings()
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'doImportantThings()' has been renamed to 'finalDoImportantThings()'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ obj.swift3DoImportantThings()
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'swift3DoImportantThings()' has been renamed to 'finalDoImportantThings()'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'finalDoImportantThings()' has been renamed to 'swift3DoImportantThings()'
+ obj.finalDoImportantThings()
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'importantClassProperty' has been renamed to 'swift3ClassProperty'
+ _ = type(of: obj).importantClassProperty
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'importantClassProperty' has been renamed to 'finalClassProperty'
+
+ // CHECK-DIAGS-3-NOT: :[[@LINE+1]]:{{[0-9]+}}:
+ _ = type(of: obj).swift3ClassProperty
+ // CHECK-DIAGS-4: [[@LINE-1]]:{{[0-9]+}}: error: 'swift3ClassProperty' has been renamed to 'finalClassProperty'
+
+ // CHECK-DIAGS-3: [[@LINE+1]]:{{[0-9]+}}: error: 'finalClassProperty' has been renamed to 'swift3ClassProperty'
+ _ = type(of: obj).finalClassProperty
+ // CHECK-DIAGS-4-NOT: :[[@LINE-1]]:{{[0-9]+}}:
+}
+
let unrelatedDiagnostic: Int = nil
diff --git a/test/APINotes/versioned.swift b/test/APINotes/versioned.swift
index 34f6e49..17c16ba 100644
--- a/test/APINotes/versioned.swift
+++ b/test/APINotes/versioned.swift
@@ -125,6 +125,127 @@
// CHECK-DIAGS-3: versioned.swift:[[@LINE-1]]:16: error: cannot convert value of type 'Optional<ImportantCAlias>' (aka 'Optional<Int32>') to specified type 'Int'
}
+func testRenamedEnumConstants() {
+ _ = AnonymousEnumValue // okay
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:7: error: 'AnonymousEnumRenamed' has been renamed to 'AnonymousEnumRenamedSwiftUnversioned'
+ _ = AnonymousEnumRenamed
+ // CHECK-DIAGS-3: [[@LINE-1]]:7: error: 'AnonymousEnumRenamed' has been renamed to 'AnonymousEnumRenamedSwift3'
+
+ // CHECK-DIAGS-4-NOT: :[[@LINE+1]]:7:
+ _ = AnonymousEnumRenamedSwiftUnversioned
+ // CHECK-DIAGS-3: [[@LINE-1]]:7: error: 'AnonymousEnumRenamedSwiftUnversioned' has been renamed to 'AnonymousEnumRenamedSwift3'
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:7: error: 'AnonymousEnumRenamedSwift3' has been renamed to 'AnonymousEnumRenamedSwiftUnversioned'
+ _ = AnonymousEnumRenamedSwift3
+ // CHECK-DIAGS-3-NOT: :[[@LINE-1]]:7:
+}
+
+func testRenamedUnknownEnum() {
+ _ = UnknownEnumValue // okay
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:7: error: 'UnknownEnumRenamed' has been renamed to 'UnknownEnumRenamedSwiftUnversioned'
+ _ = UnknownEnumRenamed
+ // CHECK-DIAGS-3: [[@LINE-1]]:7: error: 'UnknownEnumRenamed' has been renamed to 'UnknownEnumRenamedSwift3'
+
+ // CHECK-DIAGS-4-NOT: :[[@LINE+1]]:7:
+ _ = UnknownEnumRenamedSwiftUnversioned
+ // CHECK-DIAGS-3: [[@LINE-1]]:7: error: 'UnknownEnumRenamedSwiftUnversioned' has been renamed to 'UnknownEnumRenamedSwift3'
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:7: error: 'UnknownEnumRenamedSwift3' has been renamed to 'UnknownEnumRenamedSwiftUnversioned'
+ _ = UnknownEnumRenamedSwift3
+ // CHECK-DIAGS-3-NOT: :[[@LINE-1]]:7:
+}
+
+func testRenamedTrueEnum() {
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: use of unresolved identifier 'TrueEnumValue'
+ _ = TrueEnumValue
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: type 'TrueEnum' has no member 'TrueEnumValue'
+ _ = TrueEnum.TrueEnumValue
+
+ // CHECK-DIAGS: [[@LINE+1]]:16: error: 'Value' has been renamed to 'value'
+ _ = TrueEnum.Value
+
+ _ = TrueEnum.value // okay
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: use of unresolved identifier 'TrueEnumRenamed'
+ _ = TrueEnumRenamed
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: type 'TrueEnum' has no member 'TrueEnumRenamed'
+ _ = TrueEnum.TrueEnumRenamed
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:16: error: 'Renamed' has been renamed to 'renamedSwiftUnversioned'
+ _ = TrueEnum.Renamed
+ // CHECK-DIAGS-3: [[@LINE-1]]:16: error: 'Renamed' has been renamed to 'renamedSwift3'
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: type 'TrueEnum' has no member 'renamed'
+ _ = TrueEnum.renamed
+
+ // CHECK-DIAGS-4-NOT: :[[@LINE+1]]:16:
+ _ = TrueEnum.renamedSwiftUnversioned
+ // CHECK-DIAGS-3: [[@LINE-1]]:16: error: 'renamedSwiftUnversioned' has been renamed to 'renamedSwift3'
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:16: error: 'renamedSwift3' has been renamed to 'renamedSwiftUnversioned'
+ _ = TrueEnum.renamedSwift3
+ // CHECK-DIAGS-3-NOT: :[[@LINE-1]]:16:
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: use of unresolved identifier 'TrueEnumAliasRenamed'
+ _ = TrueEnumAliasRenamed
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: type 'TrueEnum' has no member 'TrueEnumAliasRenamed'
+ _ = TrueEnum.TrueEnumAliasRenamed
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:16: error: 'AliasRenamed' has been renamed to 'aliasRenamedSwiftUnversioned'
+ _ = TrueEnum.AliasRenamed
+ // CHECK-DIAGS-3: [[@LINE-1]]:16: error: 'AliasRenamed' has been renamed to 'aliasRenamedSwift3'
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: type 'TrueEnum' has no member 'aliasRenamed'
+ _ = TrueEnum.aliasRenamed
+
+ // CHECK-DIAGS-4-NOT: :[[@LINE+1]]:16:
+ _ = TrueEnum.aliasRenamedSwiftUnversioned
+ // CHECK-DIAGS-3: [[@LINE-1]]:16: error: 'aliasRenamedSwiftUnversioned' has been renamed to 'aliasRenamedSwift3'
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:16: error: 'aliasRenamedSwift3' has been renamed to 'aliasRenamedSwiftUnversioned'
+ _ = TrueEnum.aliasRenamedSwift3
+ // CHECK-DIAGS-3-NOT: :[[@LINE-1]]:16:
+}
+
+func testRenamedOptionyEnum() {
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: use of unresolved identifier 'OptionyEnumValue'
+ _ = OptionyEnumValue
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: type 'OptionyEnum' has no member 'OptionyEnumValue'
+ _ = OptionyEnum.OptionyEnumValue
+
+ // CHECK-DIAGS: [[@LINE+1]]:19: error: 'Value' has been renamed to 'value'
+ _ = OptionyEnum.Value
+
+ _ = OptionyEnum.value // okay
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: use of unresolved identifier 'OptionyEnumRenamed'
+ _ = OptionyEnumRenamed
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: type 'OptionyEnum' has no member 'OptionyEnumRenamed'
+ _ = OptionyEnum.OptionyEnumRenamed
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:19: error: 'Renamed' has been renamed to 'renamedSwiftUnversioned'
+ _ = OptionyEnum.Renamed
+ // CHECK-DIAGS-3: [[@LINE-1]]:19: error: 'Renamed' has been renamed to 'renamedSwift3'
+
+ // CHECK-DIAGS: [[@LINE+1]]:7: error: type 'OptionyEnum' has no member 'renamed'
+ _ = OptionyEnum.renamed
+
+ // CHECK-DIAGS-4-NOT: :[[@LINE+1]]:19:
+ _ = OptionyEnum.renamedSwiftUnversioned
+ // CHECK-DIAGS-3: [[@LINE-1]]:19: error: 'renamedSwiftUnversioned' has been renamed to 'renamedSwift3'
+
+ // CHECK-DIAGS-4: [[@LINE+1]]:19: error: 'renamedSwift3' has been renamed to 'renamedSwiftUnversioned'
+ _ = OptionyEnum.renamedSwift3
+ // CHECK-DIAGS-3-NOT: :[[@LINE-1]]:19:
+}
+
#endif
#if !swift(>=4)
diff --git a/test/ClangImporter/Inputs/SwiftPrivateAttr.txt b/test/ClangImporter/Inputs/SwiftPrivateAttr.txt
index 5572fbd..6ea47fa 100644
--- a/test/ClangImporter/Inputs/SwiftPrivateAttr.txt
+++ b/test/ClangImporter/Inputs/SwiftPrivateAttr.txt
@@ -9,21 +9,21 @@
func __oneArg(_ arg: Int32)
func __twoArgs(_ arg: Int32, other arg2: Int32)
class func __withNoArgs() -> Self!
+ @available(swift, obsoleted: 3, renamed: "__withNoArgs()")
+ class func __fooWithNoArgs() -> Self!
+ convenience init!(__oneArg arg: Int32)
@available(*, unavailable, renamed: "init(__oneArg:)", message: "Not available in Swift")
class func __fooWithOneArg(_ arg: Int32) -> Self!
- convenience init!(__oneArg arg: Int32)
+ convenience init!(__twoArgs arg: Int32, other arg2: Int32)
@available(*, unavailable, renamed: "init(__twoArgs:other:)", message: "Not available in Swift")
class func __fooWithTwoArgs(_ arg: Int32, other arg2: Int32) -> Self!
- convenience init!(__twoArgs arg: Int32, other arg2: Int32)
+ convenience init!(__ arg: Int32)
@available(*, unavailable, renamed: "init(__:)", message: "Not available in Swift")
class func __foo(_ arg: Int32) -> Self!
- convenience init!(__ arg: Int32)
func objectForKeyedSubscript(_ index: Any!) -> Any!
func __setObject(_ object: Any!, forKeyedSubscript index: Any!)
func __objectAtIndexedSubscript(_ index: Int32) -> Any!
func setObject(_ object: Any!, atIndexedSubscript index: Int32)
- @available(swift, obsoleted: 3, renamed: "__withNoArgs()")
- class func __fooWithNoArgs() -> Self!
init()
}
class Bar : NSObject {
diff --git a/test/IDE/print_clang_decls_AppKit.swift b/test/IDE/print_clang_decls_AppKit.swift
index 1167e5d..0cbb1a4 100644
--- a/test/IDE/print_clang_decls_AppKit.swift
+++ b/test/IDE/print_clang_decls_AppKit.swift
@@ -20,7 +20,11 @@
// APPKIT-LABEL: {{^}}class NSView : NSObject, NSCoding, NSAccessibility {{{$}}
// APPKIT-NEXT: init?(coder aDecoder: NSCoder)
// APPKIT-NEXT: func isDescendant(of aView: NSView) -> Bool
+// APPKIT-NEXT: @available(swift, obsoleted: 3, renamed: "isDescendant(of:)")
+// APPKIT-NEXT: func isDescendantOf(_ aView: NSView) -> Bool
// APPKIT-NEXT: func ancestorShared(with aView: NSView) -> NSView?
+// APPKIT-NEXT: @available(swift, obsoleted: 3, renamed: "ancestorShared(with:)")
+// APPKIT-NEXT: func ancestorSharedWithView(_ aView: NSView) -> NSView?
// APPKIT-NEXT: func addSubview(_ aView: NSView)
// APPKIT-NEXT: func addSubview(_ aView: NSView, positioned place: UInt32, relativeTo otherView: NSView?)
// APPKIT-NEXT: unowned(unsafe) var superview: @sil_unmanaged NSView? { get }
diff --git a/test/IDE/print_clang_swift_name.swift b/test/IDE/print_clang_swift_name.swift
index 03af90e..8a79ab0 100644
--- a/test/IDE/print_clang_swift_name.swift
+++ b/test/IDE/print_clang_swift_name.swift
@@ -12,75 +12,79 @@
class Test : NSObject {
// "Factory methods" that we'd rather have as initializers.
- @available(*, unavailable, renamed: "init()", message: "Not available in Swift")
- class func a() -> Self
@available(*, unavailable, message: "superseded by import of -[NSObject init]")
convenience init()
+ @available(*, unavailable, renamed: "init()", message: "Not available in Swift")
+ class func a() -> Self
+ convenience init(dummyParam: ())
@available(*, unavailable, renamed: "init(dummyParam:)", message: "Not available in Swift")
class func b() -> Self
- convenience init(dummyParam: ())
+ convenience init(cc x: Any)
@available(*, unavailable, renamed: "init(cc:)", message: "Not available in Swift")
class func c(_ x: Any) -> Self
- convenience init(cc x: Any)
+ convenience init(_ x: Any)
@available(*, unavailable, renamed: "init(_:)", message: "Not available in Swift")
class func d(_ x: Any) -> Self
- convenience init(_ x: Any)
+ convenience init(aa a: Any, _ b: Any, cc c: Any)
@available(*, unavailable, renamed: "init(aa:_:cc:)", message: "Not available in Swift")
class func e(_ a: Any, e b: Any, e c: Any) -> Self
- convenience init(aa a: Any, _ b: Any, cc c: Any)
+ /*not inherited*/ init(fixedType: ())
@available(*, unavailable, renamed: "init(fixedType:)", message: "Not available in Swift")
class func f() -> Test
- /*not inherited*/ init(fixedType: ())
// Would-be initializers.
class func zz() -> Self
- class func yy(aa x: Any) -> Self
- class func xx(_ x: Any, bb xx: Any) -> Self
@available(swift, obsoleted: 3, renamed: "zz()")
class func testZ() -> Self
+ class func yy(aa x: Any) -> Self
+ @available(*, unavailable, renamed: "yy(aa:)", message: "Not available in Swift")
+ class func testY(_ x: Any) -> Self
+ class func xx(_ x: Any, bb xx: Any) -> Self
+ @available(*, unavailable, renamed: "xx(_:bb:)", message: "Not available in Swift")
+ class func testX(_ x: Any, xx: Any) -> Self
init()
}
class TestError : NSObject {
// Factory methods with NSError.
+ convenience init(error: ()) throws
@available(*, unavailable, renamed: "init(error:)", message: "Not available in Swift")
class func err1() throws -> Self
- convenience init(error: ()) throws
+ convenience init(aa x: Any?, error: ()) throws
@available(*, unavailable, renamed: "init(aa:error:)", message: "Not available in Swift")
class func err2(_ x: Any?) throws -> Self
- convenience init(aa x: Any?, error: ()) throws
+ convenience init(aa x: Any?, error: (), block: @escaping () -> Void) throws
@available(*, unavailable, renamed: "init(aa:error:block:)", message: "Not available in Swift")
class func err3(_ x: Any?, callback block: @escaping () -> Void) throws -> Self
- convenience init(aa x: Any?, error: (), block: @escaping () -> Void) throws
+ convenience init(error: (), block: @escaping () -> Void) throws
@available(*, unavailable, renamed: "init(error:block:)", message: "Not available in Swift")
class func err4(callback block: @escaping () -> Void) throws -> Self
- convenience init(error: (), block: @escaping () -> Void) throws
+ convenience init(aa x: Any?) throws
@available(*, unavailable, renamed: "init(aa:)", message: "Not available in Swift")
class func err5(_ x: Any?) throws -> Self
- convenience init(aa x: Any?) throws
+ convenience init(aa x: Any?, block: @escaping () -> Void) throws
@available(*, unavailable, renamed: "init(aa:block:)", message: "Not available in Swift")
class func err6(_ x: Any?, callback block: @escaping () -> Void) throws -> Self
- convenience init(aa x: Any?, block: @escaping () -> Void) throws
+ convenience init(block: @escaping () -> Void) throws
@available(*, unavailable, renamed: "init(block:)", message: "Not available in Swift")
class func err7(callback block: @escaping () -> Void) throws -> Self
- convenience init(block: @escaping () -> Void) throws
// Would-be initializers.
class func ww(_ x: Any?) throws -> Self
- class func w2(_ x: Any?, error: ()) throws -> Self
- class func vv() throws -> Self
- class func v2(error: ()) throws -> Self
@available(swift, obsoleted: 3, renamed: "ww(_:)")
class func testW(_ x: Any?) throws -> Self
+ class func w2(_ x: Any?, error: ()) throws -> Self
@available(swift, obsoleted: 3, renamed: "w2(_:error:)")
class func testW2(_ x: Any?) throws -> Self
+ class func vv() throws -> Self
@available(swift, obsoleted: 3, renamed: "vv()")
class func testV() throws -> Self
+ class func v2(error: ()) throws -> Self
@available(swift, obsoleted: 3, renamed: "v2(error:)")
class func testV2() throws -> Self
init()
diff --git a/test/IDE/print_omit_needless_words.swift b/test/IDE/print_omit_needless_words.swift
index da2c7b6..0bb9e08 100644
--- a/test/IDE/print_omit_needless_words.swift
+++ b/test/IDE/print_omit_needless_words.swift
@@ -261,25 +261,37 @@
// CHECK-OMIT-NEEDLESS-WORDS: func addDoodle(_: ABCDoodle)
// Protocols as contexts
-// CHECK-OMIT-NEEDLESS-WORDS: protocol OMWLanding {
+// CHECK-OMIT-NEEDLESS-WORDS-LABEL: protocol OMWLanding {
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func flip()
// Verify that we get the Swift name from the original declaration.
-// CHECK-OMIT-NEEDLESS-WORDS: protocol OMWWiggle
+// CHECK-OMIT-NEEDLESS-WORDS-LABEL: protocol OMWWiggle
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func joinSub()
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func wiggle1()
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: @available(swift, obsoleted: 3, renamed: "wiggle1()")
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func conflicting1()
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: var wiggleProp1: Int { get }
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: @available(swift, obsoleted: 3, renamed: "wiggleProp1")
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: var conflictingProp1: Int { get }
-// CHECK-OMIT-NEEDLESS-WORDS: protocol OMWWaggle
+// CHECK-OMIT-NEEDLESS-WORDS-LABEL: protocol OMWWaggle
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func waggle1()
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: @available(swift, obsoleted: 3, renamed: "waggle1()")
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func conflicting1()
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: var waggleProp1: Int { get }
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: @available(swift, obsoleted: 3, renamed: "waggleProp1")
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: var conflictingProp1: Int { get }
-// CHECK-OMIT-NEEDLESS-WORDS: class OMWSuper
+// CHECK-OMIT-NEEDLESS-WORDS-LABEL: class OMWSuper
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func jump()
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: @available(swift, obsoleted: 3, renamed: "jump()")
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func jumpSuper()
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: var wiggleProp1: Int { get }
-// CHECK-OMIT-NEEDLESS-WORDS: class OMWSub
+// CHECK-OMIT-NEEDLESS-WORDS-LABEL: class OMWSub
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func jump()
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: @available(swift, obsoleted: 3, renamed: "jump()")
+// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func jumpSuper()
// CHECK-OMIT-NEEDLESS-WORDS-NEXT: func joinSub()
// CHECK-OMIT-NEEDLESS-WORDS-DIAGS: inconsistent Swift name for Objective-C method 'conflicting1' in 'OMWSub' ('waggle1()' in 'OMWWaggle' vs. 'wiggle1()' in 'OMWWiggle')
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
index 33aa335..f463328 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftSourceDocInfo.cpp
@@ -1341,7 +1341,7 @@
ASTInvok->applyTo(CompInvok);
RangeInfo Result;
Result.RangeKind = Lang.getUIDForRangeKind(Info.Kind);
- Result.RangeContent = Info.Content;
+ Result.RangeContent = Info.Content.str();
switch (Info.Kind) {
case RangeKind::SingleExpression: {
SmallString<64> SS;