Mark non-foreign entry points of @objc dynamic methods in generic classes dynamically_replaceable

```
class Generic<T> {
  @objc dynamic func method() {}
}

extension Generic {
  @_dynamicReplacement(for:method())
  func replacement() {}
}
```

The standard mechanism of using Objective-C categories for dynamically
replacing @objc methods in generic classes does not work.

Instead we mark the native entry point as replaceable.

Because this affects all @objc methods in generic classes (whether there
is a replacement or not) by making the native entry point
`[dynamically_replaceable]` (regardless of optimization mode) we guard this by
the -enable-implicit-dynamic flag because we are late in the release cycle.

* Replace isNativeDynamic and isObjcDynamic by calls to shouldUse*Dispatch and
  shouldUse*Replacement
  This disambiguates between which dispatch method we should use at call
  sites and how these methods should  implement dynamic function
  replacement.

* Don't emit the method entry for @_dynamicReplacement(for:) of generic class
  methods
  There is not way to call this entry point since we can't generate an
  objective-c category for generic classes.

rdar://63679357
This commit is contained in:
Arnold Schwaighofer
2020-06-03 07:27:26 -07:00
parent 8f0569dea2
commit 825a2a259b
31 changed files with 298 additions and 43 deletions

View File

@@ -152,6 +152,9 @@ static bool readOptionsBlock(llvm::BitstreamCursor &cursor,
case options_block::ARE_PRIVATE_IMPORTS_ENABLED:
extendedInfo.setPrivateImportsEnabled(true);
break;
case options_block::IS_IMPLICIT_DYNAMIC_ENABLED:
extendedInfo.setImplicitDynamicEnabled(true);
break;
case options_block::RESILIENCE_STRATEGY:
unsigned Strategy;
options_block::ResilienceStrategyLayout::readRecord(scratch, Strategy);