Skip to content

Commit d67e3a9

Browse files
committed
Merge remote-tracking branch 'origin/master' into master-rebranch
2 parents e2b9754 + c4ee7ec commit d67e3a9

File tree

7 files changed

+67
-72
lines changed

7 files changed

+67
-72
lines changed

include/swift/AST/Module.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ class ModuleDecl : public DeclContext, public TypeDecl {
193193

194194
/// This is a convenience function that writes the entire name, in forward
195195
/// order, to \p out.
196-
void printForward(raw_ostream &out) const;
196+
void printForward(raw_ostream &out, StringRef delim = ".") const;
197197
};
198198

199199
private:

lib/AST/ASTVerifier.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2362,6 +2362,14 @@ class Verifier : public ASTWalker {
23622362
}
23632363
}
23642364

2365+
if (VD->isFinal() != VD->getAttrs().hasAttribute<FinalAttr>()) {
2366+
Out << "decl should be final iff it has FinalAttr, but isFinal() = "
2367+
<< VD->isFinal() << " and hasAttribute<FinalAttr>() = "
2368+
<< VD->getAttrs().hasAttribute<FinalAttr>() << "\n";
2369+
VD->dump(Out);
2370+
abort();
2371+
}
2372+
23652373
verifyCheckedBase(VD);
23662374
}
23672375

lib/AST/Attr.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,8 +1073,15 @@ const AvailableAttr *AvailableAttr::isUnavailable(const Decl *D) {
10731073
return attr;
10741074

10751075
// If D is an extension member, check if the extension is unavailable.
1076-
if (auto ext = dyn_cast<ExtensionDecl>(D->getDeclContext()))
1077-
return AvailableAttr::isUnavailable(ext);
1076+
//
1077+
// Skip decls imported from Clang, they could be associated to the wrong
1078+
// extension and inherit undesired unavailability. The ClangImporter
1079+
// associates Objective-C protocol members to the first category where the
1080+
// protocol is directly or indirectly adopted, no matter its availability
1081+
// and the availability of other categories. rdar://problem/53956555
1082+
if (!D->getClangNode())
1083+
if (auto ext = dyn_cast<ExtensionDecl>(D->getDeclContext()))
1084+
return AvailableAttr::isUnavailable(ext);
10781085

10791086
return nullptr;
10801087
}

lib/AST/Module.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,11 +1207,12 @@ ModuleDecl::ReverseFullNameIterator::operator++() {
12071207
}
12081208

12091209
void
1210-
ModuleDecl::ReverseFullNameIterator::printForward(raw_ostream &out) const {
1210+
ModuleDecl::ReverseFullNameIterator::printForward(raw_ostream &out,
1211+
StringRef delim) const {
12111212
SmallVector<StringRef, 8> elements(*this, {});
12121213
swift::interleave(swift::reversed(elements),
12131214
[&out](StringRef next) { out << next; },
1214-
[&out] { out << '.'; });
1215+
[&out, delim] { out << delim; });
12151216
}
12161217

12171218
void

lib/Serialization/Serialization.cpp

Lines changed: 19 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -459,36 +459,6 @@ static bool shouldSerializeAsLocalContext(const DeclContext *DC) {
459459
!isa<SubscriptDecl>(DC);
460460
}
461461

462-
static const Decl *getDeclForContext(const DeclContext *DC) {
463-
switch (DC->getContextKind()) {
464-
case DeclContextKind::Module:
465-
// Use a null decl to represent the module.
466-
return nullptr;
467-
case DeclContextKind::FileUnit:
468-
return getDeclForContext(DC->getParent());
469-
case DeclContextKind::SerializedLocal:
470-
llvm_unreachable("Serialized local contexts should only come from deserialization");
471-
case DeclContextKind::Initializer:
472-
case DeclContextKind::AbstractClosureExpr:
473-
// FIXME: What about default functions?
474-
llvm_unreachable("shouldn't serialize decls from anonymous closures");
475-
case DeclContextKind::GenericTypeDecl:
476-
return cast<GenericTypeDecl>(DC);
477-
case DeclContextKind::ExtensionDecl:
478-
return cast<ExtensionDecl>(DC);
479-
case DeclContextKind::TopLevelCodeDecl:
480-
llvm_unreachable("shouldn't serialize the main module");
481-
case DeclContextKind::AbstractFunctionDecl:
482-
return cast<AbstractFunctionDecl>(DC);
483-
case DeclContextKind::SubscriptDecl:
484-
return cast<SubscriptDecl>(DC);
485-
case DeclContextKind::EnumElementDecl:
486-
return cast<EnumElementDecl>(DC);
487-
}
488-
489-
llvm_unreachable("Unhandled DeclContextKind in switch.");
490-
}
491-
492462
namespace {
493463
struct Accessors {
494464
uint8_t OpaqueReadOwnership;
@@ -634,7 +604,7 @@ DeclContextID Serializer::addDeclContextRef(const DeclContext *DC) {
634604
if (shouldSerializeAsLocalContext(DC))
635605
addLocalDeclContextRef(DC);
636606
else
637-
addDeclRef(getDeclForContext(DC));
607+
addDeclRef(DC->getAsDecl());
638608

639609
auto &id = DeclContextIDs[DC];
640610
if (id)
@@ -1023,23 +993,19 @@ void Serializer::writeHeader(const SerializationOptions &options) {
1023993
}
1024994
}
1025995

1026-
using ImportPathBlob = llvm::SmallString<64>;
1027996
static void flattenImportPath(const ModuleDecl::ImportedModule &import,
1028-
ImportPathBlob &out) {
1029-
SmallVector<StringRef, 4> reverseSubmoduleNames(
1030-
import.second->getReverseFullModuleName(), {});
1031-
1032-
interleave(reverseSubmoduleNames.rbegin(), reverseSubmoduleNames.rend(),
1033-
[&out](StringRef next) { out.append(next); },
1034-
[&out] { out.push_back('\0'); });
997+
SmallVectorImpl<char> &out) {
998+
llvm::raw_svector_ostream outStream(out);
999+
import.second->getReverseFullModuleName().printForward(outStream,
1000+
StringRef("\0", 1));
10351001

10361002
if (import.first.empty())
10371003
return;
10381004

1039-
out.push_back('\0');
1005+
outStream << '\0';
10401006
assert(import.first.size() == 1 && "can only handle top-level decl imports");
10411007
auto accessPathElem = import.first.front();
1042-
out.append(accessPathElem.first.str());
1008+
outStream << accessPathElem.first.str();
10431009
}
10441010

10451011
uint64_t getRawModTimeOrHash(const SerializationOptions::FileDependency &dep) {
@@ -1152,7 +1118,7 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
11521118
continue;
11531119
}
11541120

1155-
ImportPathBlob importPath;
1121+
SmallString<64> importPath;
11561122
flattenImportPath(import, importPath);
11571123

11581124
serialization::ImportControl stableImportControl;
@@ -1538,7 +1504,7 @@ Serializer::writeConformance(ProtocolConformanceRef conformanceRef,
15381504
switch (conformance->getKind()) {
15391505
case ProtocolConformanceKind::Normal: {
15401506
auto normal = cast<NormalProtocolConformance>(conformance);
1541-
if (!isDeclXRef(getDeclForContext(normal->getDeclContext()))
1507+
if (!isDeclXRef(normal->getDeclContext()->getAsDecl())
15421508
&& !isa<ClangModuleUnit>(normal->getDeclContext()
15431509
->getModuleScopeContext())) {
15441510
// A normal conformance in this module file.
@@ -2006,12 +1972,6 @@ static void verifyAttrSerializable(const KIND ## Decl *D) {\
20061972
static void verifyAttrSerializable(const Decl *D) {}
20071973
#endif
20081974

2009-
static inline unsigned getOptionalOrZero(const llvm::Optional<unsigned> &X) {
2010-
if (X.hasValue())
2011-
return X.getValue();
2012-
return 0;
2013-
}
2014-
20151975
bool Serializer::isDeclXRef(const Decl *D) const {
20161976
const DeclContext *topLevel = D->getDeclContext()->getModuleScopeContext();
20171977
if (topLevel->getParentModule() != M)
@@ -2046,7 +2006,7 @@ void Serializer::writeDeclContext(const DeclContext *DC) {
20462006
case DeclContextKind::GenericTypeDecl:
20472007
case DeclContextKind::ExtensionDecl:
20482008
case DeclContextKind::EnumElementDecl:
2049-
declOrDeclContextID = addDeclRef(getDeclForContext(DC));
2009+
declOrDeclContextID = addDeclRef(DC->getAsDecl());
20502010
isDecl = true;
20512011
break;
20522012

@@ -2416,8 +2376,8 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
24162376
if (X##_Val.hasValue()) {\
24172377
const auto &Y = X##_Val.getValue();\
24182378
X##_Major = Y.getMajor();\
2419-
X##_Minor = getOptionalOrZero(Y.getMinor());\
2420-
X##_Subminor = getOptionalOrZero(Y.getSubminor());\
2379+
X##_Minor = Y.getMinor().getValueOr(0);\
2380+
X##_Subminor = Y.getSubminor().getValueOr(0);\
24212381
X##_HasMinor = Y.getMinor().hasValue();\
24222382
X##_HasSubminor = Y.getSubminor().hasValue();\
24232383
}
@@ -2848,13 +2808,6 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
28482808
for (auto Attr : D->getAttrs())
28492809
writeDeclAttribute(Attr);
28502810

2851-
if (auto VD = dyn_cast<ValueDecl>(D)) {
2852-
// Hack: synthesize a 'final' attribute if finality was inferred.
2853-
if (VD->isFinal() && !D->getAttrs().hasAttribute<FinalAttr>())
2854-
writeDeclAttribute(
2855-
new (D->getASTContext()) FinalAttr(/*Implicit=*/false));
2856-
}
2857-
28582811
if (auto *value = dyn_cast<ValueDecl>(D))
28592812
writeDiscriminatorsIfNeeded(value);
28602813

@@ -2935,8 +2888,7 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
29352888

29362889
// Reverse the list, and write the parameter lists, from outermost
29372890
// to innermost.
2938-
std::reverse(allGenericParams.begin(), allGenericParams.end());
2939-
for (auto *genericParams : allGenericParams)
2891+
for (auto *genericParams : swift::reversed(allGenericParams))
29402892
writeGenericParams(genericParams);
29412893

29422894
writeMembers(id, extension->getMembers(), isClassExtension);
@@ -5035,7 +4987,7 @@ void swift::serializeToBuffers(
50354987
std::unique_ptr<llvm::MemoryBuffer> *moduleDocBuffer,
50364988
const SILModule *M) {
50374989

5038-
assert(options.OutputPath && options.OutputPath[0] != '\0');
4990+
assert(!StringRef::withNullAsEmpty(options.OutputPath).empty());
50394991
{
50404992
SharedTimer timer("Serialization, swiftmodule, to buffer");
50414993
llvm::SmallString<1024> buf;
@@ -5054,7 +5006,7 @@ void swift::serializeToBuffers(
50545006
std::move(buf), options.OutputPath);
50555007
}
50565008

5057-
if (options.DocOutputPath && options.DocOutputPath[0] != '\0') {
5009+
if (!StringRef::withNullAsEmpty(options.DocOutputPath).empty()) {
50585010
SharedTimer timer("Serialization, swiftdoc, to buffer");
50595011
llvm::SmallString<1024> buf;
50605012
llvm::raw_svector_ostream stream(buf);
@@ -5074,12 +5026,12 @@ void swift::serializeToBuffers(
50745026
void swift::serialize(ModuleOrSourceFile DC,
50755027
const SerializationOptions &options,
50765028
const SILModule *M) {
5077-
assert(options.OutputPath && options.OutputPath[0] != '\0');
5029+
assert(!StringRef::withNullAsEmpty(options.OutputPath).empty());
50785030

5079-
if (strcmp("-", options.OutputPath) == 0) {
5031+
if (StringRef(options.OutputPath) == "-") {
50805032
// Special-case writing to stdout.
50815033
Serializer::writeToStream(llvm::outs(), DC, M, options);
5082-
assert(!options.DocOutputPath || options.DocOutputPath[0] == '\0');
5034+
assert(StringRef::withNullAsEmpty(options.DocOutputPath).empty());
50835035
return;
50845036
}
50855037

@@ -5093,7 +5045,7 @@ void swift::serialize(ModuleOrSourceFile DC,
50935045
if (hadError)
50945046
return;
50955047

5096-
if (options.DocOutputPath && options.DocOutputPath[0] != '\0') {
5048+
if (!StringRef::withNullAsEmpty(options.DocOutputPath).empty()) {
50975049
(void)withOutputFile(getContext(DC).Diags,
50985050
options.DocOutputPath,
50995051
[&](raw_ostream &out) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#import <Foundation/Foundation.h>
2+
3+
@interface SharedInterface
4+
@end
5+
6+
@protocol SharedProtocol <NSObject>
7+
+ (NSInteger)foo;
8+
@end
9+
10+
// ClangImporter imports the first category as the extension parent of
11+
// SharedInterface.foo, making foo unavailable on macOS when the extension
12+
// unavailability is inherited by its members.
13+
API_UNAVAILABLE(macos)
14+
@interface SharedInterface (IOSCategory) <SharedProtocol>
15+
@end
16+
17+
API_UNAVAILABLE(ios)
18+
@interface SharedInterface (MacOSCategory) <SharedProtocol>
19+
@end
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend -typecheck %s -import-objc-header %S/Inputs/availability_platform_categories.h
2+
3+
// REQUIRES: OS=macos
4+
5+
// Test when a function is associated to an Objective-C category with the
6+
// wrong unavailability. rdar://problem/53956555
7+
8+
print(SharedInterface.foo())

0 commit comments

Comments
 (0)