Skip to content

Commit d2db9bd

Browse files
authored
[clang][APINotes] Add support for the SwiftEscapable attribute (#115866)
This is similar to SwiftCopyable. Also fix missing SwiftCopyable dump for TagInfo.
1 parent 5c2a133 commit d2db9bd

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
@@ -724,6 +724,11 @@ class TagInfo : public CommonTypeInfo {
724724
LLVM_PREFERRED_TYPE(bool)
725725
unsigned SwiftCopyable : 1;
726726

727+
LLVM_PREFERRED_TYPE(bool)
728+
unsigned SwiftEscapableSpecified : 1;
729+
LLVM_PREFERRED_TYPE(bool)
730+
unsigned SwiftEscapable : 1;
731+
727732
public:
728733
std::optional<std::string> SwiftImportAs;
729734
std::optional<std::string> SwiftRetainOp;
@@ -736,7 +741,8 @@ class TagInfo : public CommonTypeInfo {
736741

737742
TagInfo()
738743
: HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false),
739-
SwiftCopyable(false) {}
744+
SwiftCopyable(false), SwiftEscapableSpecified(false),
745+
SwiftEscapable(false) {}
740746

741747
std::optional<bool> isFlagEnum() const {
742748
if (HasFlagEnum)
@@ -757,6 +763,16 @@ class TagInfo : public CommonTypeInfo {
757763
SwiftCopyable = Value.value_or(false);
758764
}
759765

766+
std::optional<bool> isSwiftEscapable() const {
767+
return SwiftEscapableSpecified ? std::optional<bool>(SwiftEscapable)
768+
: std::nullopt;
769+
}
770+
771+
void setSwiftEscapable(std::optional<bool> Value) {
772+
SwiftEscapableSpecified = Value.has_value();
773+
SwiftEscapable = Value.value_or(false);
774+
}
775+
760776
TagInfo &operator|=(const TagInfo &RHS) {
761777
static_cast<CommonTypeInfo &>(*this) |= RHS;
762778

@@ -779,6 +795,9 @@ class TagInfo : public CommonTypeInfo {
779795
if (!SwiftCopyableSpecified)
780796
setSwiftCopyable(RHS.isSwiftCopyable());
781797

798+
if (!SwiftEscapableSpecified)
799+
setSwiftEscapable(RHS.isSwiftEscapable());
800+
782801
return *this;
783802
}
784803

@@ -795,6 +814,7 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
795814
LHS.SwiftConformance == RHS.SwiftConformance &&
796815
LHS.isFlagEnum() == RHS.isFlagEnum() &&
797816
LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&
817+
LHS.isSwiftEscapable() == RHS.isSwiftEscapable() &&
798818
LHS.EnumExtensibility == RHS.EnumExtensibility;
799819
}
800820

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
@@ -1266,11 +1266,13 @@ class CommonTypeTableInfo
12661266
class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
12671267
public:
12681268
unsigned getUnversionedInfoSize(const TagInfo &TI) {
1269+
// clang-format off
12691270
return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) +
12701271
2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
12711272
2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
12721273
2 + (TI.SwiftConformance ? TI.SwiftConformance->size() : 0) +
1273-
2 + getCommonTypeInfoSize(TI);
1274+
3 + getCommonTypeInfoSize(TI);
1275+
// clang-format on
12741276
}
12751277

12761278
void emitUnversionedInfo(raw_ostream &OS, const TagInfo &TI) {
@@ -1289,7 +1291,12 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
12891291
writer.write<uint8_t>(Flags);
12901292

12911293
if (auto Copyable = TI.isSwiftCopyable())
1292-
writer.write<uint8_t>(*Copyable ? kSwiftCopyable : kSwiftNonCopyable);
1294+
writer.write<uint8_t>(*Copyable ? kSwiftConforms : kSwiftDoesNotConform);
1295+
else
1296+
writer.write<uint8_t>(0);
1297+
1298+
if (auto Escapable = TI.isSwiftEscapable())
1299+
writer.write<uint8_t>(*Escapable ? kSwiftConforms : kSwiftDoesNotConform);
12931300
else
12941301
writer.write<uint8_t>(0);
12951302

clang/lib/APINotes/APINotesYAMLCompiler.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@ struct Tag {
459459
std::optional<bool> FlagEnum;
460460
std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
461461
std::optional<bool> SwiftCopyable;
462+
std::optional<bool> SwiftEscapable;
462463
FunctionsSeq Methods;
463464
FieldsSeq Fields;
464465

@@ -498,6 +499,7 @@ template <> struct MappingTraits<Tag> {
498499
IO.mapOptional("FlagEnum", T.FlagEnum);
499500
IO.mapOptional("EnumKind", T.EnumConvenienceKind);
500501
IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
502+
IO.mapOptional("SwiftEscapable", T.SwiftEscapable);
501503
IO.mapOptional("Methods", T.Methods);
502504
IO.mapOptional("Fields", T.Fields);
503505
IO.mapOptional("Tags", T.Tags);
@@ -983,6 +985,8 @@ class YAMLConverter {
983985

984986
if (T.SwiftCopyable)
985987
TI.setSwiftCopyable(T.SwiftCopyable);
988+
if (T.SwiftEscapable)
989+
TI.setSwiftEscapable(T.SwiftEscapable);
986990

987991
if (T.EnumConvenienceKind) {
988992
if (T.EnumExtensibility) {

clang/lib/Sema/SemaAPINotes.cpp

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

650+
if (auto Escapable = Info.isSwiftEscapable()) {
651+
D->addAttr(SwiftAttrAttr::Create(S.Context,
652+
*Escapable ? "Escapable" : "~Escapable"));
653+
}
654+
650655
if (auto Extensibility = Info.EnumExtensibility) {
651656
using api_notes::EnumExtensibilityKind;
652657
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)