Skip to content

Commit da5ea3c

Browse files
authored
Merge pull request #11050 from DougGregor/api-notes-conforms-to-on-typedefs
2 parents 67b2730 + 01b28c4 commit da5ea3c

File tree

12 files changed

+75
-31
lines changed

12 files changed

+75
-31
lines changed

clang/include/clang/APINotes/Types.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ class CommonTypeInfo : public CommonEntityInfo {
141141
/// The NS error domain for this type.
142142
std::optional<std::string> NSErrorDomain;
143143

144+
/// The Swift protocol that this type should be automatically conformed to.
145+
std::optional<std::string> SwiftConformance;
146+
144147
public:
145148
CommonTypeInfo() {}
146149

@@ -165,6 +168,14 @@ class CommonTypeInfo : public CommonEntityInfo {
165168
: std::nullopt;
166169
}
167170

171+
std::optional<std::string> getSwiftConformance() const {
172+
return SwiftConformance;
173+
}
174+
175+
void setSwiftConformance(std::optional<std::string> conformance) {
176+
SwiftConformance = conformance;
177+
}
178+
168179
friend bool operator==(const CommonTypeInfo &, const CommonTypeInfo &);
169180

170181
CommonTypeInfo &operator|=(const CommonTypeInfo &RHS) {
@@ -175,6 +186,8 @@ class CommonTypeInfo : public CommonEntityInfo {
175186
setSwiftBridge(RHS.getSwiftBridge());
176187
if (!NSErrorDomain)
177188
setNSErrorDomain(RHS.getNSErrorDomain());
189+
if (SwiftConformance)
190+
setSwiftConformance(RHS.getSwiftConformance());
178191

179192
return *this;
180193
}
@@ -185,7 +198,8 @@ class CommonTypeInfo : public CommonEntityInfo {
185198
inline bool operator==(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
186199
return static_cast<const CommonEntityInfo &>(LHS) == RHS &&
187200
LHS.SwiftBridge == RHS.SwiftBridge &&
188-
LHS.NSErrorDomain == RHS.NSErrorDomain;
201+
LHS.NSErrorDomain == RHS.NSErrorDomain &&
202+
LHS.SwiftConformance == RHS.SwiftConformance;
189203
}
190204

191205
inline bool operator!=(const CommonTypeInfo &LHS, const CommonTypeInfo &RHS) {
@@ -824,9 +838,6 @@ class TagInfo : public CommonTypeInfo {
824838
std::optional<std::string> SwiftRetainOp;
825839
std::optional<std::string> SwiftReleaseOp;
826840

827-
/// The Swift protocol that this type should be automatically conformed to.
828-
std::optional<std::string> SwiftConformance;
829-
830841
std::optional<EnumExtensibilityKind> EnumExtensibility;
831842

832843
TagInfo()
@@ -873,9 +884,6 @@ class TagInfo : public CommonTypeInfo {
873884
if (!SwiftReleaseOp)
874885
SwiftReleaseOp = RHS.SwiftReleaseOp;
875886

876-
if (!SwiftConformance)
877-
SwiftConformance = RHS.SwiftConformance;
878-
879887
if (!HasFlagEnum)
880888
setFlagEnum(RHS.isFlagEnum());
881889

@@ -901,7 +909,6 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
901909
LHS.SwiftImportAs == RHS.SwiftImportAs &&
902910
LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
903911
LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
904-
LHS.SwiftConformance == RHS.SwiftConformance &&
905912
LHS.isFlagEnum() == RHS.isFlagEnum() &&
906913
LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&
907914
LHS.isSwiftEscapable() == RHS.isSwiftEscapable() &&

clang/lib/APINotes/APINotesFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0;
2424
/// API notes file minor version number.
2525
///
2626
/// When the format changes IN ANY WAY, this number should be incremented.
27-
const uint16_t VERSION_MINOR = 35; // BoundsSafety
27+
const uint16_t VERSION_MINOR = 36; // Typedef SwiftConformsTo
2828

2929
const uint8_t kSwiftConforms = 1;
3030
const uint8_t kSwiftDoesNotConform = 2;

clang/lib/APINotes/APINotesReader.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ void ReadCommonTypeInfo(const uint8_t *&Data, CommonTypeInfo &Info) {
136136
reinterpret_cast<const char *>(Data), ErrorDomainLength - 1)));
137137
Data += ErrorDomainLength - 1;
138138
}
139+
140+
if (unsigned ConformanceLength =
141+
endian::readNext<uint16_t, llvm::endianness::little>(Data)) {
142+
Info.setSwiftConformance(std::string(reinterpret_cast<const char *>(Data),
143+
ConformanceLength - 1));
144+
Data += ConformanceLength - 1;
145+
}
139146
}
140147

141148
/// Used to deserialize the on-disk identifier table.
@@ -663,12 +670,6 @@ class TagTableInfo
663670
ReleaseOpLength - 1);
664671
Data += ReleaseOpLength - 1;
665672
}
666-
if (unsigned ConformanceLength =
667-
endian::readNext<uint16_t, llvm::endianness::little>(Data)) {
668-
Info.SwiftConformance = std::string(reinterpret_cast<const char *>(Data),
669-
ConformanceLength - 1);
670-
Data += ConformanceLength - 1;
671-
}
672673

673674
ReadCommonTypeInfo(Data, Info);
674675
return Info;

clang/lib/APINotes/APINotesWriter.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,8 @@ unsigned getCommonEntityInfoSize(const CommonEntityInfo &CEI) {
553553
// in on-disk hash tables.
554554
unsigned getCommonTypeInfoSize(const CommonTypeInfo &CTI) {
555555
return 2 + (CTI.getSwiftBridge() ? CTI.getSwiftBridge()->size() : 0) + 2 +
556-
(CTI.getNSErrorDomain() ? CTI.getNSErrorDomain()->size() : 0) +
556+
(CTI.getNSErrorDomain() ? CTI.getNSErrorDomain()->size() : 0) + 2 +
557+
(CTI.getSwiftConformance() ? CTI.getSwiftConformance()->size() : 0) +
557558
getCommonEntityInfoSize(CTI);
558559
}
559560

@@ -574,6 +575,12 @@ void emitCommonTypeInfo(raw_ostream &OS, const CommonTypeInfo &CTI) {
574575
} else {
575576
writer.write<uint16_t>(0);
576577
}
578+
if (auto conformance = CTI.getSwiftConformance()) {
579+
writer.write<uint16_t>(conformance->size() + 1);
580+
OS.write(conformance->c_str(), conformance->size());
581+
} else {
582+
writer.write<uint16_t>(0);
583+
}
577584
}
578585

579586
/// Used to serialize the on-disk Objective-C property table.
@@ -1341,7 +1348,6 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
13411348
return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) +
13421349
2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
13431350
2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
1344-
2 + (TI.SwiftConformance ? TI.SwiftConformance->size() : 0) +
13451351
3 + getCommonTypeInfoSize(TI);
13461352
// clang-format on
13471353
}
@@ -1389,12 +1395,6 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
13891395
} else {
13901396
writer.write<uint16_t>(0);
13911397
}
1392-
if (auto Conformance = TI.SwiftConformance) {
1393-
writer.write<uint16_t>(Conformance->size() + 1);
1394-
OS.write(Conformance->c_str(), Conformance->size());
1395-
} else {
1396-
writer.write<uint16_t>(0);
1397-
}
13981398

13991399
emitCommonTypeInfo(OS, TI);
14001400
}

clang/lib/APINotes/APINotesYAMLCompiler.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ struct Class {
413413
std::optional<StringRef> NSErrorDomain;
414414
std::optional<bool> SwiftImportAsNonGeneric;
415415
std::optional<bool> SwiftObjCMembers;
416+
std::optional<std::string> SwiftConformance;
416417
MethodsSeq Methods;
417418
PropertiesSeq Properties;
418419
};
@@ -437,6 +438,7 @@ template <> struct MappingTraits<Class> {
437438
IO.mapOptional("NSErrorDomain", C.NSErrorDomain);
438439
IO.mapOptional("SwiftImportAsNonGeneric", C.SwiftImportAsNonGeneric);
439440
IO.mapOptional("SwiftObjCMembers", C.SwiftObjCMembers);
441+
IO.mapOptional("SwiftConformsTo", C.SwiftConformance);
440442
IO.mapOptional("Methods", C.Methods);
441443
IO.mapOptional("Properties", C.Properties);
442444
}
@@ -691,6 +693,7 @@ struct Typedef {
691693
std::optional<StringRef> SwiftBridge;
692694
std::optional<StringRef> NSErrorDomain;
693695
std::optional<SwiftNewTypeKind> SwiftType;
696+
std::optional<std::string> SwiftConformance;
694697
};
695698

696699
typedef std::vector<Typedef> TypedefsSeq;
@@ -719,6 +722,7 @@ template <> struct MappingTraits<Typedef> {
719722
IO.mapOptional("SwiftBridge", T.SwiftBridge);
720723
IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
721724
IO.mapOptional("SwiftWrapper", T.SwiftType);
725+
IO.mapOptional("SwiftConformsTo", T.SwiftConformance);
722726
}
723727
};
724728
} // namespace yaml
@@ -977,6 +981,8 @@ class YAMLConverter {
977981
if (Common.SwiftBridge)
978982
Info.setSwiftBridge(std::string(*Common.SwiftBridge));
979983
Info.setNSErrorDomain(Common.NSErrorDomain);
984+
if (auto conformance = Common.SwiftConformance)
985+
Info.setSwiftConformance(conformance);
980986
}
981987

982988
// Translate from Method into ObjCMethodInfo and write it out.
@@ -1174,8 +1180,6 @@ class YAMLConverter {
11741180
TI.SwiftRetainOp = T.SwiftRetainOp;
11751181
if (T.SwiftReleaseOp)
11761182
TI.SwiftReleaseOp = T.SwiftReleaseOp;
1177-
if (T.SwiftConformance)
1178-
TI.SwiftConformance = T.SwiftConformance;
11791183

11801184
if (T.SwiftCopyable)
11811185
TI.setSwiftCopyable(T.SwiftCopyable);

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,10 @@ static void ProcessAPINotes(Sema &S, Decl *D,
338338
});
339339
}
340340

341+
if (auto ConformsTo = Info.getSwiftConformance())
342+
D->addAttr(
343+
SwiftAttrAttr::Create(S.Context, "conforms_to:" + ConformsTo.value()));
344+
341345
ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(Info),
342346
Metadata);
343347
}
@@ -776,10 +780,6 @@ static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info,
776780
D->addAttr(
777781
SwiftAttrAttr::Create(S.Context, "release:" + ReleaseOp.value()));
778782

779-
if (auto ConformsTo = Info.SwiftConformance)
780-
D->addAttr(
781-
SwiftAttrAttr::Create(S.Context, "conforms_to:" + ConformsTo.value()));
782-
783783
if (auto Copyable = Info.isSwiftCopyable()) {
784784
if (!*Copyable)
785785
D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable"));

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19085,6 +19085,10 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
1908519085
// record.
1908619086
AddPushedVisibilityAttribute(New);
1908719087

19088+
// If this is not a definition, process API notes for it now.
19089+
if (TUK != TagUseKind::Definition)
19090+
ProcessAPINotes(New);
19091+
1908819092
if (isMemberSpecialization && !New->isInvalidDecl())
1908919093
CompleteMemberSpecialization(New, Previous);
1909019094

clang/test/APINotes/Inputs/Frameworks/Simple.framework/Headers/Simple.apinotes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ Classes:
2626
- Name: scalarNewProperty
2727
PropertyKind: Instance
2828
Nullability: Scalar
29+
Typedefs:
30+
- Name: MyTypedef
31+
SwiftConformsTo: Swift.Equatable

clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Tags:
1414
SwiftReleaseOp: RCRelease
1515
SwiftRetainOp: RCRetain
1616
SwiftConformsTo: MySwiftModule.MySwiftRefCountedProtocol
17+
- Name: OpaqueRefCountedType
18+
SwiftImportAs: reference
19+
SwiftReleaseOp: ORCRelease
20+
SwiftRetainOp: ORCRetain
1721
- Name: NonCopyableType
1822
SwiftCopyable: false
1923
SwiftConformsTo: MySwiftModule.MySwiftNonCopyableProtocol

clang/test/APINotes/Inputs/Headers/SwiftImportAs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,9 @@ struct CopyableType { int value; };
1919

2020
struct NonEscapableType { int value; };
2121
struct EscapableType { int value; };
22+
23+
struct OpaqueRefCountedType;
24+
struct OpaqueRefCountedType; // redeclaration
25+
26+
inline void ORCRetain(struct OpaqueRefCountedType *x);
27+
inline void ORCRelease(struct OpaqueRefCountedType *x);

0 commit comments

Comments
 (0)