diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 7b51c375b1e..61953727283 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -3095,6 +3095,9 @@ public: /// isGetterOrSetter - Determine whether this is a getter or a setter vs. /// a normal function. bool isGetterOrSetter() const { return isGetter() || isSetter(); } + bool isDidSetWillSet() const { + return getAccessorKind() == IsDidSet || getAccessorKind() == IsWillSet; + } bool isAccessor() const { return getAccessorKind() != NotAccessor; } /// Creates the implicit 'DynamicSelf' generic parameter. diff --git a/lib/IRGen/ClassMetadataLayout.h b/lib/IRGen/ClassMetadataLayout.h index 360b3db8050..3749193c953 100644 --- a/lib/IRGen/ClassMetadataLayout.h +++ b/lib/IRGen/ClassMetadataLayout.h @@ -210,7 +210,7 @@ private: void maybeAddMethod(FuncDecl *fn, ResilienceExpansion explosionLevel, unsigned uncurryLevel) { // Ignore getters and setters. This is probably wrong! - if (fn->isGetterOrSetter()) + if (fn->isAccessor()) return; // If the method overrides something, we don't need a new entry. diff --git a/lib/IRGen/GenClass.cpp b/lib/IRGen/GenClass.cpp index 5f129a9c88a..5e7f8225eed 100644 --- a/lib/IRGen/GenClass.cpp +++ b/lib/IRGen/GenClass.cpp @@ -1083,7 +1083,7 @@ namespace { // getters and setters funcdecls will be handled by their parent // var/subscript. - if (method->isGetterOrSetter()) return; + if (method->isAccessor()) return; llvm::Constant *entry = emitObjCMethodDescriptor(IGM, method); if (!method->isStatic()) { diff --git a/lib/IRGen/GenObjC.cpp b/lib/IRGen/GenObjC.cpp index c09f1275970..12c12cdc522 100644 --- a/lib/IRGen/GenObjC.cpp +++ b/lib/IRGen/GenObjC.cpp @@ -1171,7 +1171,7 @@ irgen::emitObjCSubscriptMethodDescriptors(IRGenModule &IGM, bool irgen::requiresObjCMethodDescriptor(FuncDecl *method) { // Property accessors should be generated alongside the property. - if (method->isGetterOrSetter()) + if (method->isAccessor()) return false; // We don't export generic methods or subclasses to IRGen yet. diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index b0c46ada865..9e018ef2e97 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -243,7 +243,7 @@ namespace { } void visitFunc(FuncDecl *func) { - if (func->isGetterOrSetter()) + if (func->isAccessor()) // FIXME: To be implemented. return; diff --git a/lib/IRGen/IRGenDebugInfo.cpp b/lib/IRGen/IRGenDebugInfo.cpp index c4d6eda98aa..b26e36fbcc7 100644 --- a/lib/IRGen/IRGenDebugInfo.cpp +++ b/lib/IRGen/IRGenDebugInfo.cpp @@ -366,11 +366,19 @@ llvm::DIFile IRGenDebugInfo::getOrCreateFile(const char *Filename) { StringRef IRGenDebugInfo::getName(const FuncDecl &FD) { // Getters and Setters are anonymous functions, so we forge a name // using its parent declaration. - if (FD.isGetterOrSetter()) + if (FD.isAccessor()) if (ValueDecl *VD = FD.getAccessorStorageDecl()) { + const char *Kind; + switch (FD.getAccessorKind()) { + case FuncDecl::NotAccessor: assert(0 && "we know this is an accessor"); + case FuncDecl::IsGetter: Kind = ".get"; break; + case FuncDecl::IsSetter: Kind = ".set"; break; + case FuncDecl::IsWillSet: Kind = ".willset"; break; + case FuncDecl::IsDidSet: Kind = ".didset"; break; + } + SmallVector Buf; - StringRef Name = (VD->getName().str() + - Twine(FD.isGetter() ? ".get":".set")).toStringRef(Buf); + StringRef Name = (VD->getName().str() +Twine(Kind)).toStringRef(Buf); return BumpAllocatedString(Name); } diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index f0e76e684ae..4378323514f 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -800,7 +800,10 @@ public: // FIXME: Or if it's an ObjC method. Extension methods on classes will // hopefully become dynamically dispatched too. if (auto *fd = dyn_cast(e->getDecl())) { - if (isa(fd->getDeclContext()) || fd->isObjC()) { + if (fd->isObjC() || + (isa(fd->getDeclContext()) && + // didSet and willSet methods can always be directly dispatched. + !fd->isDidSetWillSet())) { ApplyExpr *thisCallSite = callSites.back(); callSites.pop_back(); setSelfParam(gen.emitRValue(thisCallSite->getArg()), thisCallSite);