@@ -1950,7 +1950,7 @@ SourceRange IfConfigDecl::getSourceRange() const {
1950
1950
}
1951
1951
1952
1952
static bool isPolymorphic (const AbstractStorageDecl *storage) {
1953
- if (storage->isObjCDynamic ())
1953
+ if (storage->shouldUseObjCDispatch ())
1954
1954
return true ;
1955
1955
1956
1956
@@ -2083,7 +2083,7 @@ getDirectReadWriteAccessStrategy(const AbstractStorageDecl *storage) {
2083
2083
return AccessStrategy::getStorage ();
2084
2084
case ReadWriteImplKind::Stored: {
2085
2085
// If the storage isDynamic (and not @objc) use the accessors.
2086
- if (storage->isNativeDynamic ())
2086
+ if (storage->shouldUseNativeDynamicDispatch ())
2087
2087
return AccessStrategy::getMaterializeToTemporary (
2088
2088
getOpaqueReadAccessStrategy (storage, false ),
2089
2089
getOpaqueWriteAccessStrategy (storage, false ));
@@ -2168,7 +2168,7 @@ AbstractStorageDecl::getAccessStrategy(AccessSemantics semantics,
2168
2168
if (isPolymorphic (this ))
2169
2169
return getOpaqueAccessStrategy (this , accessKind, /* dispatch*/ true );
2170
2170
2171
- if (isNativeDynamic ())
2171
+ if (shouldUseNativeDynamicDispatch ())
2172
2172
return getOpaqueAccessStrategy (this , accessKind, /* dispatch*/ false );
2173
2173
2174
2174
// If the storage is resilient from the given module and resilience
@@ -2926,6 +2926,59 @@ bool ValueDecl::isDynamic() const {
2926
2926
getAttrs ().hasAttribute <DynamicAttr>());
2927
2927
}
2928
2928
2929
+ bool ValueDecl::isObjCDynamicInGenericClass () const {
2930
+ if (!isObjCDynamic ())
2931
+ return false ;
2932
+
2933
+ auto *DC = this ->getDeclContext ();
2934
+ auto *classDecl = DC->getSelfClassDecl ();
2935
+ if (!classDecl)
2936
+ return false ;
2937
+
2938
+ return classDecl->isGenericContext () && !classDecl->usesObjCGenericsModel ();
2939
+ }
2940
+
2941
+ bool ValueDecl::shouldUseObjCMethodReplacement () const {
2942
+ if (isNativeDynamic ())
2943
+ return false ;
2944
+
2945
+ if (getModuleContext ()->isImplicitDynamicEnabled () &&
2946
+ isObjCDynamicInGenericClass ())
2947
+ return false ;
2948
+
2949
+ return isObjCDynamic ();
2950
+ }
2951
+
2952
+ bool ValueDecl::shouldUseNativeMethodReplacement () const {
2953
+ if (isNativeDynamic ())
2954
+ return true ;
2955
+
2956
+ if (!isObjCDynamicInGenericClass ())
2957
+ return false ;
2958
+
2959
+ auto *replacedDecl = getDynamicallyReplacedDecl ();
2960
+ if (replacedDecl)
2961
+ return false ;
2962
+
2963
+ return getModuleContext ()->isImplicitDynamicEnabled ();
2964
+ }
2965
+
2966
+ bool ValueDecl::isNativeMethodReplacement () const {
2967
+ // Is this a @_dynamicReplacement(for:) that use the native dynamic function
2968
+ // replacement mechanism.
2969
+ auto *replacedDecl = getDynamicallyReplacedDecl ();
2970
+ if (!replacedDecl)
2971
+ return false ;
2972
+
2973
+ if (isNativeDynamic ())
2974
+ return true ;
2975
+
2976
+ if (isObjCDynamicInGenericClass ())
2977
+ return replacedDecl->getModuleContext ()->isImplicitDynamicEnabled ();
2978
+
2979
+ return false ;
2980
+ }
2981
+
2929
2982
void ValueDecl::setIsDynamic (bool value) {
2930
2983
assert (!LazySemanticInfo.isDynamicComputed ||
2931
2984
LazySemanticInfo.isDynamic == value);
@@ -5143,7 +5196,7 @@ bool AbstractStorageDecl::hasDidSetOrWillSetDynamicReplacement() const {
5143
5196
5144
5197
bool AbstractStorageDecl::hasAnyNativeDynamicAccessors () const {
5145
5198
for (auto accessor : getAllAccessors ()) {
5146
- if (accessor->isNativeDynamic ())
5199
+ if (accessor->shouldUseNativeDynamicDispatch ())
5147
5200
return true ;
5148
5201
}
5149
5202
return false ;
0 commit comments