Skip to content

Commit 5728735

Browse files
authored
Merge pull request #9596 from swiftlang/gaborh/apinotes-escapability
[clang][APINotes] Add support for the SwiftEscapable attribute (llvm#115866)
2 parents 03df845 + b53c768 commit 5728735

File tree

10 files changed

+69
-11
lines changed

10 files changed

+69
-11
lines changed

clang/include/clang/APINotes/Types.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,11 @@ class TagInfo : public CommonTypeInfo {
727727
LLVM_PREFERRED_TYPE(bool)
728728
unsigned SwiftCopyable : 1;
729729

730+
LLVM_PREFERRED_TYPE(bool)
731+
unsigned SwiftEscapableSpecified : 1;
732+
LLVM_PREFERRED_TYPE(bool)
733+
unsigned SwiftEscapable : 1;
734+
730735
public:
731736
std::optional<std::string> SwiftImportAs;
732737
std::optional<std::string> SwiftRetainOp;
@@ -739,7 +744,8 @@ class TagInfo : public CommonTypeInfo {
739744

740745
TagInfo()
741746
: HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false),
742-
SwiftCopyable(false) {}
747+
SwiftCopyable(false), SwiftEscapableSpecified(false),
748+
SwiftEscapable(false) {}
743749

744750
std::optional<bool> isFlagEnum() const {
745751
if (HasFlagEnum)
@@ -760,6 +766,16 @@ class TagInfo : public CommonTypeInfo {
760766
SwiftCopyable = Value.value_or(false);
761767
}
762768

769+
std::optional<bool> isSwiftEscapable() const {
770+
return SwiftEscapableSpecified ? std::optional<bool>(SwiftEscapable)
771+
: std::nullopt;
772+
}
773+
774+
void setSwiftEscapable(std::optional<bool> Value) {
775+
SwiftEscapableSpecified = Value.has_value();
776+
SwiftEscapable = Value.value_or(false);
777+
}
778+
763779
TagInfo &operator|=(const TagInfo &RHS) {
764780
static_cast<CommonTypeInfo &>(*this) |= RHS;
765781

@@ -782,6 +798,9 @@ class TagInfo : public CommonTypeInfo {
782798
if (!SwiftCopyableSpecified)
783799
setSwiftCopyable(RHS.isSwiftCopyable());
784800

801+
if (!SwiftEscapableSpecified)
802+
setSwiftEscapable(RHS.isSwiftEscapable());
803+
785804
return *this;
786805
}
787806

@@ -798,6 +817,7 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
798817
LHS.SwiftConformance == RHS.SwiftConformance &&
799818
LHS.isFlagEnum() == RHS.isFlagEnum() &&
800819
LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&
820+
LHS.isSwiftEscapable() == RHS.isSwiftEscapable() &&
801821
LHS.EnumExtensibility == RHS.EnumExtensibility;
802822
}
803823

clang/lib/APINotes/APINotesFormat.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,10 @@ 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 =
28-
32; // implicit parameter support (at position -1)
27+
const uint16_t VERSION_MINOR = 33; // SwiftEscapable
2928

30-
const uint8_t kSwiftCopyable = 1;
31-
const uint8_t kSwiftNonCopyable = 2;
29+
const uint8_t kSwiftConforms = 1;
30+
const uint8_t kSwiftDoesNotConform = 2;
3231

3332
using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
3433
using IdentifierIDField = llvm::BCVBR<16>;

clang/lib/APINotes/APINotesReader.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -589,10 +589,12 @@ class TagTableInfo
589589

590590
uint8_t Copyable =
591591
endian::readNext<uint8_t, llvm::endianness::little>(Data);
592-
if (Copyable == kSwiftNonCopyable)
593-
Info.setSwiftCopyable(std::optional(false));
594-
else if (Copyable == kSwiftCopyable)
595-
Info.setSwiftCopyable(std::optional(true));
592+
if (Copyable == kSwiftConforms || Copyable == kSwiftDoesNotConform)
593+
Info.setSwiftCopyable(std::optional(Copyable == kSwiftConforms));
594+
uint8_t Escapable =
595+
endian::readNext<uint8_t, llvm::endianness::little>(Data);
596+
if (Escapable == kSwiftConforms || Escapable == kSwiftDoesNotConform)
597+
Info.setSwiftEscapable(std::optional(Escapable == kSwiftConforms));
596598

597599
unsigned ImportAsLength =
598600
endian::readNext<uint16_t, llvm::endianness::little>(Data);

clang/lib/APINotes/APINotesTypes.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ LLVM_DUMP_METHOD void TagInfo::dump(llvm::raw_ostream &OS) {
104104
if (EnumExtensibility)
105105
OS << "Enum Extensibility: " << static_cast<long>(*EnumExtensibility)
106106
<< ' ';
107+
if (SwiftCopyableSpecified)
108+
OS << (SwiftCopyable ? "[SwiftCopyable] " : "[~SwiftCopyable]");
109+
if (SwiftEscapableSpecified)
110+
OS << (SwiftEscapable ? "[SwiftEscapable] " : "[~SwiftEscapable]");
107111
OS << '\n';
108112
}
109113

clang/lib/APINotes/APINotesWriter.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,11 +1283,13 @@ class CommonTypeTableInfo
12831283
class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
12841284
public:
12851285
unsigned getUnversionedInfoSize(const TagInfo &TI) {
1286+
// clang-format off
12861287
return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) +
12871288
2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
12881289
2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
12891290
2 + (TI.SwiftConformance ? TI.SwiftConformance->size() : 0) +
1290-
2 + getCommonTypeInfoSize(TI);
1291+
3 + getCommonTypeInfoSize(TI);
1292+
// clang-format on
12911293
}
12921294

12931295
void emitUnversionedInfo(raw_ostream &OS, const TagInfo &TI) {
@@ -1306,7 +1308,12 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
13061308
writer.write<uint8_t>(Flags);
13071309

13081310
if (auto Copyable = TI.isSwiftCopyable())
1309-
writer.write<uint8_t>(*Copyable ? kSwiftCopyable : kSwiftNonCopyable);
1311+
writer.write<uint8_t>(*Copyable ? kSwiftConforms : kSwiftDoesNotConform);
1312+
else
1313+
writer.write<uint8_t>(0);
1314+
1315+
if (auto Escapable = TI.isSwiftEscapable())
1316+
writer.write<uint8_t>(*Escapable ? kSwiftConforms : kSwiftDoesNotConform);
13101317
else
13111318
writer.write<uint8_t>(0);
13121319

clang/lib/APINotes/APINotesYAMLCompiler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ struct Tag {
572572
std::optional<bool> FlagEnum;
573573
std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
574574
std::optional<bool> SwiftCopyable;
575+
std::optional<bool> SwiftEscapable;
575576
FunctionsSeq Methods;
576577
FieldsSeq Fields;
577578

@@ -611,6 +612,7 @@ template <> struct MappingTraits<Tag> {
611612
IO.mapOptional("FlagEnum", T.FlagEnum);
612613
IO.mapOptional("EnumKind", T.EnumConvenienceKind);
613614
IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
615+
IO.mapOptional("SwiftEscapable", T.SwiftEscapable);
614616
IO.mapOptional("Methods", T.Methods);
615617
IO.mapOptional("Fields", T.Fields);
616618
IO.mapOptional("Tags", T.Tags);
@@ -1096,6 +1098,8 @@ class YAMLConverter {
10961098

10971099
if (T.SwiftCopyable)
10981100
TI.setSwiftCopyable(T.SwiftCopyable);
1101+
if (T.SwiftEscapable)
1102+
TI.setSwiftEscapable(T.SwiftEscapable);
10991103

11001104
if (T.EnumConvenienceKind) {
11011105
if (T.EnumExtensibility) {

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,11 @@ static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info,
649649
D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable"));
650650
}
651651

652+
if (auto Escapable = Info.isSwiftEscapable()) {
653+
D->addAttr(SwiftAttrAttr::Create(S.Context,
654+
*Escapable ? "Escapable" : "~Escapable"));
655+
}
656+
652657
if (auto Extensibility = Info.EnumExtensibility) {
653658
using api_notes::EnumExtensibilityKind;
654659
bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ Tags:
1313
SwiftConformsTo: MySwiftModule.MySwiftNonCopyableProtocol
1414
- Name: CopyableType
1515
SwiftCopyable: true
16+
- Name: NonEscapableType
17+
SwiftEscapable: false
18+
- Name: EscapableType
19+
SwiftEscapable: true

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ inline void RCRelease(RefCountedType *x) { x->value--; }
77

88
struct NonCopyableType { int value; };
99
struct CopyableType { int value; };
10+
11+
struct NonEscapableType { int value; };
12+
struct EscapableType { int value; };

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
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
55
// 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
66
// 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
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 NonEscapableType | FileCheck -check-prefix=CHECK-NON-ESCAPABLE %s
8+
// 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 EscapableType | FileCheck -check-prefix=CHECK-ESCAPABLE %s
79

810
#include <SwiftImportAs.h>
911

@@ -26,3 +28,11 @@
2628
// CHECK-COPYABLE: Dumping CopyableType:
2729
// CHECK-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct CopyableType
2830
// CHECK-COPYABLE-NOT: SwiftAttrAttr
31+
32+
// CHECK-NON-ESCAPABLE: Dumping NonEscapableType:
33+
// CHECK-NON-ESCAPABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct NonEscapableType
34+
// CHECK-NON-ESCAPABLE: SwiftAttrAttr {{.+}} "~Escapable"
35+
36+
// CHECK-ESCAPABLE: Dumping EscapableType:
37+
// CHECK-ESCAPABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct EscapableType
38+
// CHECK-ESCAPABLE: SwiftAttrAttr {{.+}} "Escapable"

0 commit comments

Comments
 (0)