Skip to content

Commit 8f5a1c0

Browse files
committed
[APINotes] Add support for SWIFT_RETURED_AS_UNRETAINED
1 parent d90cac9 commit 8f5a1c0

File tree

8 files changed

+42
-0
lines changed

8 files changed

+42
-0
lines changed

clang/include/clang/APINotes/Types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,7 @@ class TagInfo : public CommonTypeInfo {
737737
std::optional<std::string> SwiftImportAs;
738738
std::optional<std::string> SwiftRetainOp;
739739
std::optional<std::string> SwiftReleaseOp;
740+
std::optional<std::string> SwiftDefaultOwnership;
740741

741742
/// The Swift protocol that this type should be automatically conformed to.
742743
std::optional<std::string> SwiftConformance;
@@ -786,6 +787,8 @@ class TagInfo : public CommonTypeInfo {
786787
SwiftRetainOp = RHS.SwiftRetainOp;
787788
if (!SwiftReleaseOp)
788789
SwiftReleaseOp = RHS.SwiftReleaseOp;
790+
if (!SwiftDefaultOwnership)
791+
SwiftDefaultOwnership = RHS.SwiftDefaultOwnership;
789792

790793
if (!SwiftConformance)
791794
SwiftConformance = RHS.SwiftConformance;
@@ -815,6 +818,7 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
815818
LHS.SwiftImportAs == RHS.SwiftImportAs &&
816819
LHS.SwiftRetainOp == RHS.SwiftRetainOp &&
817820
LHS.SwiftReleaseOp == RHS.SwiftReleaseOp &&
821+
LHS.SwiftDefaultOwnership == RHS.SwiftDefaultOwnership &&
818822
LHS.SwiftConformance == RHS.SwiftConformance &&
819823
LHS.isFlagEnum() == RHS.isFlagEnum() &&
820824
LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&

clang/lib/APINotes/APINotesReader.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,13 @@ class TagTableInfo
624624
ReleaseOpLength - 1);
625625
Data += ReleaseOpLength - 1;
626626
}
627+
unsigned DefaultOwnershipLength =
628+
endian::readNext<uint16_t, llvm::endianness::little>(Data);
629+
if (DefaultOwnershipLength > 0) {
630+
Info.SwiftDefaultOwnership = std::string(
631+
reinterpret_cast<const char *>(Data), DefaultOwnershipLength - 1);
632+
Data += DefaultOwnershipLength - 1;
633+
}
627634
if (unsigned ConformanceLength =
628635
endian::readNext<uint16_t, llvm::endianness::little>(Data)) {
629636
Info.SwiftConformance = std::string(reinterpret_cast<const char *>(Data),

clang/lib/APINotes/APINotesWriter.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,7 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
12741274
return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) +
12751275
2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
12761276
2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
1277+
2 + (TI.SwiftDefaultOwnership ? TI.SwiftDefaultOwnership->size() : 0) +
12771278
2 + (TI.SwiftConformance ? TI.SwiftConformance->size() : 0) +
12781279
3 + getCommonTypeInfoSize(TI);
12791280
// clang-format on
@@ -1322,6 +1323,12 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
13221323
} else {
13231324
writer.write<uint16_t>(0);
13241325
}
1326+
if (auto DefaultOwnership = TI.SwiftDefaultOwnership) {
1327+
writer.write<uint16_t>(DefaultOwnership->size() + 1);
1328+
OS.write(DefaultOwnership->c_str(), DefaultOwnership->size());
1329+
} else {
1330+
writer.write<uint16_t>(0);
1331+
}
13251332
if (auto Conformance = TI.SwiftConformance) {
13261333
writer.write<uint16_t>(Conformance->size() + 1);
13271334
OS.write(Conformance->c_str(), Conformance->size());

clang/lib/APINotes/APINotesYAMLCompiler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,7 @@ struct Tag {
460460
std::optional<std::string> SwiftImportAs;
461461
std::optional<std::string> SwiftRetainOp;
462462
std::optional<std::string> SwiftReleaseOp;
463+
std::optional<std::string> SwiftDefaultOwnership;
463464
std::optional<std::string> SwiftConformance;
464465
std::optional<EnumExtensibilityKind> EnumExtensibility;
465466
std::optional<bool> FlagEnum;
@@ -500,6 +501,7 @@ template <> struct MappingTraits<Tag> {
500501
IO.mapOptional("SwiftImportAs", T.SwiftImportAs);
501502
IO.mapOptional("SwiftReleaseOp", T.SwiftReleaseOp);
502503
IO.mapOptional("SwiftRetainOp", T.SwiftRetainOp);
504+
IO.mapOptional("SwiftDefaultOwnership", T.SwiftDefaultOwnership);
503505
IO.mapOptional("SwiftConformsTo", T.SwiftConformance);
504506
IO.mapOptional("EnumExtensibility", T.EnumExtensibility);
505507
IO.mapOptional("FlagEnum", T.FlagEnum);
@@ -990,6 +992,8 @@ class YAMLConverter {
990992
TI.SwiftReleaseOp = T.SwiftReleaseOp;
991993
if (T.SwiftConformance)
992994
TI.SwiftConformance = T.SwiftConformance;
995+
if (T.SwiftDefaultOwnership)
996+
TI.SwiftDefaultOwnership = T.SwiftDefaultOwnership;
993997

994998
if (T.SwiftCopyable)
995999
TI.setSwiftCopyable(T.SwiftCopyable);

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,9 @@ static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info,
643643
if (auto ReleaseOp = Info.SwiftReleaseOp)
644644
D->addAttr(
645645
SwiftAttrAttr::Create(S.Context, "release:" + ReleaseOp.value()));
646+
if (auto DefaultOwnership = Info.SwiftDefaultOwnership)
647+
D->addAttr(SwiftAttrAttr::Create(
648+
S.Context, "returned_as_" + DefaultOwnership.value() + "_by_default"));
646649

647650
if (auto ConformsTo = Info.SwiftConformance)
648651
D->addAttr(

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ Tags:
1414
SwiftReleaseOp: RCRelease
1515
SwiftRetainOp: RCRetain
1616
SwiftConformsTo: MySwiftModule.MySwiftRefCountedProtocol
17+
- Name: RefCountedTypeWithDefaultConvention
18+
SwiftImportAs: reference
19+
SwiftReleaseOp: release
20+
SwiftRetainOp: retain
21+
SwiftDefaultOwnership: unretained
1722
- Name: NonCopyableType
1823
SwiftCopyable: false
1924
SwiftConformsTo: MySwiftModule.MySwiftNonCopyableProtocol

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

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

2020
struct NonEscapableType { int value; };
2121
struct EscapableType { int value; };
22+
23+
struct RefCountedTypeWithDefaultConvention {};
24+
inline void retain(RefCountedType *x) {}
25+
inline void release(RefCountedType *x) {}

clang/test/APINotes/swift-import-as.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++
33
// 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 ImmortalRefType | FileCheck -check-prefix=CHECK-IMMORTAL %s
44
// 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 RefCountedType | FileCheck -check-prefix=CHECK-REF-COUNTED %s
5+
// 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 RefCountedTypeWithDefaultConvention | FileCheck -check-prefix=CHECK-REF-COUNTED-DEFAULT %s
56
// 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 NonCopyableType | FileCheck -check-prefix=CHECK-NON-COPYABLE %s
67
// 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 CopyableType | FileCheck -check-prefix=CHECK-COPYABLE %s
78
// 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 NonEscapableType | FileCheck -check-prefix=CHECK-NON-ESCAPABLE %s
@@ -26,6 +27,13 @@
2627
// CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <<invalid sloc>> "release:RCRelease"
2728
// CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <<invalid sloc>> "conforms_to:MySwiftModule.MySwiftRefCountedProtocol"
2829

30+
// CHECK-REF-COUNTED-DEFAULT: Dumping RefCountedTypeWithDefaultConvention:
31+
// CHECK-REF-COUNTED-DEFAULT-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct RefCountedTypeWithDefaultConvention
32+
// CHECK-REF-COUNTED-DEFAULT: SwiftAttrAttr {{.+}} <<invalid sloc>> "import_reference"
33+
// CHECK-REF-COUNTED-DEFAULT: SwiftAttrAttr {{.+}} <<invalid sloc>> "retain:retain"
34+
// CHECK-REF-COUNTED-DEFAULT: SwiftAttrAttr {{.+}} <<invalid sloc>> "release:release"
35+
// CHECK-REF-COUNTED-DEFAULT: SwiftAttrAttr {{.+}} <<invalid sloc>> "returned_as_unretained_by_default"
36+
2937
// CHECK-NON-COPYABLE: Dumping NonCopyableType:
3038
// CHECK-NON-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct NonCopyableType
3139
// CHECK-NON-COPYABLE: SwiftAttrAttr {{.+}} <<invalid sloc>> "conforms_to:MySwiftModule.MySwiftNonCopyableProtocol"

0 commit comments

Comments
 (0)