[Sema] SPI info on a wrapped property should propagate to the backing storage

This commit is contained in:
Alexis Laferrière
2020-07-15 13:15:26 -07:00
parent 7573a640ed
commit 47e4e29362
2 changed files with 49 additions and 1 deletions

View File

@@ -2053,7 +2053,15 @@ SPIGroupsRequest::evaluate(Evaluator &evaluator, const Decl *decl) const {
for (auto spi : attr->getSPIGroups())
spiGroups.insert(spi);
auto &ctx = decl->getASTContext();
// Backing storage for a wrapped property gets the SPI groups from the
// original property.
if (auto varDecl = dyn_cast<VarDecl>(decl))
if (auto originalDecl = varDecl->getOriginalWrappedProperty()) {
auto originalSPIs = originalDecl->getSPIGroups();
spiGroups.insert(originalSPIs.begin(), originalSPIs.end());
}
// If there is no local SPI information, look at the context.
if (spiGroups.empty()) {
// Then in the extended nominal type.
@@ -2073,6 +2081,7 @@ SPIGroupsRequest::evaluate(Evaluator &evaluator, const Decl *decl) const {
}
}
auto &ctx = decl->getASTContext();
return ctx.AllocateCopy(spiGroups.getArrayRef());
}

View File

@@ -88,6 +88,45 @@ private class PrivateClassLocal {}
// CHECK-PUBLIC-NOT: extensionSPIMethod
}
@propertyWrapper
public struct Wrapper<T> {
public var value: T
public var wrappedValue: T {
get { value }
set { value = newValue }
}
}
@propertyWrapper
public struct WrapperWithInitialValue<T> {
private var value: T
public var wrappedValue: T {
get { value }
set { value = newValue }
}
public var projectedValue: Wrapper<T> {
get { Wrapper(value: value) }
set { value = newValue.value }
}
}
public class SomeClass {
}
public struct PublicStruct {
@_spi(S) @Wrapper public var spiWrappedSimple: SomeClass
// CHECK-PRIVATE: @_spi(S) @{{.*}}.Wrapper public var spiWrappedSimple: {{.*}}.SomeClass
// CHECK-PUBLIC-NOT: spiWrappedSimple
@_spi(S) @WrapperWithInitialValue public var spiWrappedDefault: SomeClass
// CHECK-PRIVATE: @_spi(S) @{{.*}}.WrapperWithInitialValue @_projectedValueProperty($spiWrappedDefault) public var spiWrappedDefault: {{.*}}.SomeClass
// CHECK-PRIVATE: @_spi(S) public var $spiWrappedDefault: {{.*}}.Wrapper<{{.*}}.SomeClass>
// CHECK-PUBLIC-NOT: spiWrappedDefault
}
@_spi(LocalSPI) public protocol SPIProto3 {
// CHECK-PRIVATE: @_spi(LocalSPI) public protocol SPIProto3
// CHECK-PUBLIC-NOT: SPIProto3