[API notes] Allow SwiftConformsTo on Typedefs
SwiftConformsTo specifies an additional conformance that should be applied on import. Allow this on typedefs, because those can be imported as wrapper types.
This commit is contained in:
parent
a02444fb69
commit
2b37471f72
@ -141,6 +141,9 @@ class CommonTypeInfo : public CommonEntityInfo {
|
||||
/// The NS error domain for this type.
|
||||
std::optional<std::string> NSErrorDomain;
|
||||
|
||||
/// The Swift protocol that this type should be automatically conformed to.
|
||||
std::optional<std::string> SwiftConformance;
|
||||
|
||||
public:
|
||||
CommonTypeInfo() {}
|
||||
|
||||
@ -165,6 +168,14 @@ public:
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string> getSwiftConformance() const {
|
||||
return SwiftConformance;
|
||||
}
|
||||
|
||||
void setSwiftConformance(std::optional<std::string> conformance) {
|
||||
SwiftConformance = conformance;
|
||||
}
|
||||
|
||||
friend bool operator==(const CommonTypeInfo &, const CommonTypeInfo &);
|
||||
|
||||
CommonTypeInfo &operator|=(const CommonTypeInfo &RHS) {
|
||||
@ -175,6 +186,8 @@ public:
|
||||
setSwiftBridge(RHS.getSwiftBridge());
|
||||
if (!NSErrorDomain)
|
||||
setNSErrorDomain(RHS.getNSErrorDomain());
|
||||
if (SwiftConformance)
|
||||
setSwiftConformance(RHS.getSwiftConformance());
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -185,7 +198,8 @@ public:
|
||||
inline bool operator==(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
|
||||
return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
|
||||
LHS.SwiftBridge == RHS.SwiftBridge &&
|
||||
LHS.NSErrorDomain == RHS.NSErrorDomain;
|
||||
LHS.NSErrorDomain == RHS.NSErrorDomain &&
|
||||
LHS.SwiftConformance == RHS.SwiftConformance;
|
||||
}
|
||||
|
||||
inline bool operator!=(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
|
||||
@ -739,9 +753,6 @@ public:
|
||||
std::optional<std::string> SwiftReleaseOp;
|
||||
std::optional<std::string> SwiftDefaultOwnership;
|
||||
|
||||
/// The Swift protocol that this type should be automatically conformed to.
|
||||
std::optional<std::string> SwiftConformance;
|
||||
|
||||
std::optional<EnumExtensibilityKind> EnumExtensibility;
|
||||
|
||||
TagInfo()
|
||||
@ -790,9 +801,6 @@ public:
|
||||
if (!SwiftDefaultOwnership)
|
||||
SwiftDefaultOwnership = RHS.SwiftDefaultOwnership;
|
||||
|
||||
if (!SwiftConformance)
|
||||
SwiftConformance = RHS.SwiftConformance;
|
||||
|
||||
if (!HasFlagEnum)
|
||||
setFlagEnum(RHS.isFlagEnum());
|
||||
|
||||
@ -819,7 +827,6 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
|
||||
LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
|
||||
LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
|
||||
LHS.SwiftDefaultOwnership == RHS.SwiftDefaultOwnership &&
|
||||
LHS.SwiftConformance == RHS.SwiftConformance &&
|
||||
LHS.isFlagEnum() == RHS.isFlagEnum() &&
|
||||
LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&
|
||||
LHS.isSwiftEscapable() == RHS.isSwiftEscapable() &&
|
||||
|
@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0;
|
||||
/// API notes file minor version number.
|
||||
///
|
||||
/// When the format changes IN ANY WAY, this number should be incremented.
|
||||
const uint16_t VERSION_MINOR = 35; // SwiftDefaultOwnership
|
||||
const uint16_t VERSION_MINOR = 36; // Typedef SwiftConformsTo
|
||||
|
||||
const uint8_t kSwiftConforms = 1;
|
||||
const uint8_t kSwiftDoesNotConform = 2;
|
||||
|
@ -134,6 +134,13 @@ void ReadCommonTypeInfo(const uint8_t *&Data, CommonTypeInfo &Info) {
|
||||
reinterpret_cast<const char *>(Data), ErrorDomainLength - 1)));
|
||||
Data += ErrorDomainLength - 1;
|
||||
}
|
||||
|
||||
if (unsigned ConformanceLength =
|
||||
endian::readNext<uint16_t, llvm::endianness::little>(Data)) {
|
||||
Info.setSwiftConformance(std::string(reinterpret_cast<const char *>(Data),
|
||||
ConformanceLength - 1));
|
||||
Data += ConformanceLength - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to deserialize the on-disk identifier table.
|
||||
@ -629,12 +636,6 @@ public:
|
||||
reinterpret_cast<const char *>(Data), DefaultOwnershipLength - 1);
|
||||
Data += DefaultOwnershipLength - 1;
|
||||
}
|
||||
if (unsigned ConformanceLength =
|
||||
endian::readNext<uint16_t, llvm::endianness::little>(Data)) {
|
||||
Info.SwiftConformance = std::string(reinterpret_cast<const char *>(Data),
|
||||
ConformanceLength - 1);
|
||||
Data += ConformanceLength - 1;
|
||||
}
|
||||
|
||||
ReadCommonTypeInfo(Data, Info);
|
||||
return Info;
|
||||
|
@ -536,7 +536,8 @@ unsigned getCommonEntityInfoSize(const CommonEntityInfo &CEI) {
|
||||
// in on-disk hash tables.
|
||||
unsigned getCommonTypeInfoSize(const CommonTypeInfo &CTI) {
|
||||
return 2 + (CTI.getSwiftBridge() ? CTI.getSwiftBridge()->size() : 0) + 2 +
|
||||
(CTI.getNSErrorDomain() ? CTI.getNSErrorDomain()->size() : 0) +
|
||||
(CTI.getNSErrorDomain() ? CTI.getNSErrorDomain()->size() : 0) + 2 +
|
||||
(CTI.getSwiftConformance() ? CTI.getSwiftConformance()->size() : 0) +
|
||||
getCommonEntityInfoSize(CTI);
|
||||
}
|
||||
|
||||
@ -557,6 +558,12 @@ void emitCommonTypeInfo(raw_ostream &OS, const CommonTypeInfo &CTI) {
|
||||
} else {
|
||||
writer.write<uint16_t>(0);
|
||||
}
|
||||
if (auto conformance = CTI.getSwiftConformance()) {
|
||||
writer.write<uint16_t>(conformance->size() + 1);
|
||||
OS.write(conformance->c_str(), conformance->size());
|
||||
} else {
|
||||
writer.write<uint16_t>(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to serialize the on-disk Objective-C property table.
|
||||
@ -1274,7 +1281,6 @@ public:
|
||||
2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
|
||||
2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
|
||||
2 + (TI.SwiftDefaultOwnership ? TI.SwiftDefaultOwnership->size() : 0) +
|
||||
2 + (TI.SwiftConformance ? TI.SwiftConformance->size() : 0) +
|
||||
3 + getCommonTypeInfoSize(TI);
|
||||
// clang-format on
|
||||
}
|
||||
@ -1328,12 +1334,6 @@ public:
|
||||
} else {
|
||||
writer.write<uint16_t>(0);
|
||||
}
|
||||
if (auto Conformance = TI.SwiftConformance) {
|
||||
writer.write<uint16_t>(Conformance->size() + 1);
|
||||
OS.write(Conformance->c_str(), Conformance->size());
|
||||
} else {
|
||||
writer.write<uint16_t>(0);
|
||||
}
|
||||
|
||||
emitCommonTypeInfo(OS, TI);
|
||||
}
|
||||
|
@ -251,6 +251,7 @@ struct Class {
|
||||
std::optional<StringRef> NSErrorDomain;
|
||||
std::optional<bool> SwiftImportAsNonGeneric;
|
||||
std::optional<bool> SwiftObjCMembers;
|
||||
std::optional<std::string> SwiftConformance;
|
||||
MethodsSeq Methods;
|
||||
PropertiesSeq Properties;
|
||||
};
|
||||
@ -275,6 +276,7 @@ template <> struct MappingTraits<Class> {
|
||||
IO.mapOptional("NSErrorDomain", C.NSErrorDomain);
|
||||
IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);
|
||||
IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);
|
||||
IO.mapOptional("SwiftConformsTo", C.SwiftConformance);
|
||||
IO.mapOptional("Methods", C.Methods);
|
||||
IO.mapOptional("Properties", C.Properties);
|
||||
}
|
||||
@ -525,6 +527,7 @@ struct Typedef {
|
||||
std::optional<StringRef> SwiftBridge;
|
||||
std::optional<StringRef> NSErrorDomain;
|
||||
std::optional<SwiftNewTypeKind> SwiftType;
|
||||
std::optional<std::string> SwiftConformance;
|
||||
};
|
||||
|
||||
typedef std::vector<Typedef> TypedefsSeq;
|
||||
@ -553,6 +556,7 @@ template <> struct MappingTraits<Typedef> {
|
||||
IO.mapOptional("SwiftBridge", T.SwiftBridge);
|
||||
IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
|
||||
IO.mapOptional("SwiftWrapper", T.SwiftType);
|
||||
IO.mapOptional("SwiftConformsTo", T.SwiftConformance);
|
||||
}
|
||||
};
|
||||
} // namespace yaml
|
||||
@ -802,6 +806,8 @@ public:
|
||||
if (Common.SwiftBridge)
|
||||
Info.setSwiftBridge(std::string(*Common.SwiftBridge));
|
||||
Info.setNSErrorDomain(Common.NSErrorDomain);
|
||||
if (auto conformance = Common.SwiftConformance)
|
||||
Info.setSwiftConformance(conformance);
|
||||
}
|
||||
|
||||
// Translate from Method into ObjCMethodInfo and write it out.
|
||||
@ -990,8 +996,6 @@ public:
|
||||
TI.SwiftRetainOp = T.SwiftRetainOp;
|
||||
if (T.SwiftReleaseOp)
|
||||
TI.SwiftReleaseOp = T.SwiftReleaseOp;
|
||||
if (T.SwiftConformance)
|
||||
TI.SwiftConformance = T.SwiftConformance;
|
||||
if (T.SwiftDefaultOwnership)
|
||||
TI.SwiftDefaultOwnership = T.SwiftDefaultOwnership;
|
||||
|
||||
|
@ -336,6 +336,10 @@ static void ProcessAPINotes(Sema &S, Decl *D,
|
||||
});
|
||||
}
|
||||
|
||||
if (auto ConformsTo = Info.getSwiftConformance())
|
||||
D->addAttr(
|
||||
SwiftAttrAttr::Create(S.Context, "conforms_to:" + ConformsTo.value()));
|
||||
|
||||
ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info),
|
||||
Metadata);
|
||||
}
|
||||
@ -698,10 +702,6 @@ static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info,
|
||||
D->addAttr(SwiftAttrAttr::Create(
|
||||
S.Context, "returned_as_" + DefaultOwnership.value() + "_by_default"));
|
||||
|
||||
if (auto ConformsTo = Info.SwiftConformance)
|
||||
D->addAttr(
|
||||
SwiftAttrAttr::Create(S.Context, "conforms_to:" + ConformsTo.value()));
|
||||
|
||||
if (auto Copyable = Info.isSwiftCopyable()) {
|
||||
if (!*Copyable)
|
||||
D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable"));
|
||||
|
@ -26,3 +26,6 @@ Classes:
|
||||
- Name: scalarNewProperty
|
||||
PropertyKind: Instance
|
||||
Nullability: Scalar
|
||||
Typedefs:
|
||||
- Name: MyTypedef
|
||||
SwiftConformsTo: Swift.Equatable
|
||||
|
@ -39,3 +39,7 @@ Functions:
|
||||
SwiftReturnOwnership: unretained
|
||||
- Name: functionReturningFrt_returns_retained
|
||||
SwiftReturnOwnership: retained
|
||||
Typedefs:
|
||||
- Name: WrappedOptions
|
||||
SwiftWrapper: struct
|
||||
SwiftConformsTo: Swift.OptionSet
|
||||
|
@ -29,3 +29,5 @@ struct OpaqueRefCountedType; // redeclaration
|
||||
|
||||
inline void ORCRetain(struct OpaqueRefCountedType *x);
|
||||
inline void ORCRelease(struct OpaqueRefCountedType *x);
|
||||
|
||||
typedef unsigned WrappedOptions;
|
||||
|
@ -14,6 +14,7 @@
|
||||
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt__ | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT %s
|
||||
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt_returns_unretained | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT-UNRETAINED %s
|
||||
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt_returns_retained | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT-RETAINED %s
|
||||
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter WrappedOptions | FileCheck -check-prefix=CHECK-WRAPPED-OPTIONS %s
|
||||
|
||||
#include <SwiftImportAs.h>
|
||||
|
||||
@ -51,8 +52,8 @@
|
||||
// CHECK-OPAQUE-REF-COUNTED-NOT: SwiftAttrAttr {{.+}} <<invalid sloc>> "release:
|
||||
// CHECK-NON-COPYABLE: Dumping NonCopyableType:
|
||||
// CHECK-NON-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct NonCopyableType
|
||||
// CHECK-NON-COPYABLE: SwiftAttrAttr {{.+}} <<invalid sloc>> "conforms_to:MySwiftModule.MySwiftNonCopyableProtocol"
|
||||
// CHECK-NON-COPYABLE: SwiftAttrAttr {{.+}} <<invalid sloc>> "~Copyable"
|
||||
// CHECK-NON-COPYABLE: SwiftAttrAttr {{.+}} <<invalid sloc>> "conforms_to:MySwiftModule.MySwiftNonCopyableProtocol"
|
||||
|
||||
// CHECK-COPYABLE: Dumping CopyableType:
|
||||
// CHECK-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct CopyableType
|
||||
@ -91,3 +92,8 @@
|
||||
// CHECK-METHOD-RETURNING-FRT-RETAINED: Dumping ImmortalRefType::methodReturningFrt_returns_retained:
|
||||
// CHECK-METHOD-RETURNING-FRT-RETAINED: CXXMethodDecl {{.+}} imported in SwiftImportAs methodReturningFrt_returns_retained 'ImmortalRefType *()'
|
||||
// CHECK-METHOD-RETURNING-FRT-RETAINED: `-SwiftAttrAttr {{.+}} "returns_retained"
|
||||
|
||||
// CHECK-WRAPPED-OPTIONS: Dumping WrappedOptions
|
||||
// CHECK-WRAPPED-OPTIONS: TypedefDecl{{.*}}WrappedOptions 'unsigned int'
|
||||
// CHECK-WRAPPED-OPTIONS: SwiftNewTypeAttr {{.*}} swift_wrapper NK_Struct
|
||||
// CHECK-WRAPPED-OPTIONS: SwiftAttrAttr {{.*}} "conforms_to:Swift.OptionSet"
|
||||
|
@ -24,7 +24,7 @@ CHECK-NEXT: 25c26
|
||||
CHECK-NEXT: < Nullability: S
|
||||
CHECK-NEXT: ---
|
||||
CHECK-NEXT: > Nullability: Unspecified
|
||||
CHECK-NEXT: 28c29,30
|
||||
CHECK-NEXT: 28c29
|
||||
CHECK-NEXT: < Nullability: Scalar
|
||||
CHECK-NEXT: ---
|
||||
CHECK-NEXT: > Nullability: Unspecified
|
||||
|
Loading…
x
Reference in New Issue
Block a user