[clang] [clang][APINotes] Add support for the SwiftEscapable attribute (PR #115866)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Nov 12 05:11:47 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Gábor Horváth (Xazax-hun)
<details>
<summary>Changes</summary>
This is similar to SwiftCopyable. Also fix missing SwiftCopyable dump for TagInfo.
---
Full diff: https://github.com/llvm/llvm-project/pull/115866.diff
10 Files Affected:
- (modified) clang/include/clang/APINotes/Types.h (+20-1)
- (modified) clang/lib/APINotes/APINotesFormat.h (+3-4)
- (modified) clang/lib/APINotes/APINotesReader.cpp (+8-2)
- (modified) clang/lib/APINotes/APINotesTypes.cpp (+4)
- (modified) clang/lib/APINotes/APINotesWriter.cpp (+11-6)
- (modified) clang/lib/APINotes/APINotesYAMLCompiler.cpp (+4)
- (modified) clang/lib/Sema/SemaAPINotes.cpp (+7)
- (modified) clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes (+4)
- (modified) clang/test/APINotes/Inputs/Headers/SwiftImportAs.h (+3)
- (modified) clang/test/APINotes/swift-import-as.cpp (+10)
``````````diff
diff --git a/clang/include/clang/APINotes/Types.h b/clang/include/clang/APINotes/Types.h
index 6ad1c850701146..a228c3c5b2770d 100644
--- a/clang/include/clang/APINotes/Types.h
+++ b/clang/include/clang/APINotes/Types.h
@@ -724,6 +724,11 @@ class TagInfo : public CommonTypeInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftCopyable : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned SwiftEscapableSpecified : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned SwiftEscapable : 1;
+
public:
std::optional<std::string> SwiftImportAs;
std::optional<std::string> SwiftRetainOp;
@@ -736,7 +741,8 @@ class TagInfo : public CommonTypeInfo {
TagInfo()
: HasFlagEnum(0), IsFlagEnum(0), SwiftCopyableSpecified(false),
- SwiftCopyable(false) {}
+ SwiftCopyable(false), SwiftEscapableSpecified(false),
+ SwiftEscapable(false) {}
std::optional<bool> isFlagEnum() const {
if (HasFlagEnum)
@@ -757,6 +763,15 @@ class TagInfo : public CommonTypeInfo {
SwiftCopyable = Value.value_or(false);
}
+ std::optional<bool> isSwiftEscapable() const {
+ return SwiftEscapableSpecified ? std::optional<bool>(SwiftEscapable)
+ : std::nullopt;
+ }
+ void setSwiftEscapable(std::optional<bool> Value) {
+ SwiftEscapableSpecified = Value.has_value();
+ SwiftEscapable = Value.value_or(false);
+ }
+
TagInfo &operator|=(const TagInfo &RHS) {
static_cast<CommonTypeInfo &>(*this) |= RHS;
@@ -779,6 +794,9 @@ class TagInfo : public CommonTypeInfo {
if (!SwiftCopyableSpecified)
setSwiftCopyable(RHS.isSwiftCopyable());
+ if (!SwiftEscapableSpecified)
+ setSwiftEscapable(RHS.isSwiftEscapable());
+
return *this;
}
@@ -795,6 +813,7 @@ inline bool operator==(const TagInfo &LHS, const TagInfo &RHS) {
LHS.SwiftConformance == RHS.SwiftConformance &&
LHS.isFlagEnum() == RHS.isFlagEnum() &&
LHS.isSwiftCopyable() == RHS.isSwiftCopyable() &&
+ LHS.isSwiftEscapable() == RHS.isSwiftEscapable() &&
LHS.EnumExtensibility == RHS.EnumExtensibility;
}
diff --git a/clang/lib/APINotes/APINotesFormat.h b/clang/lib/APINotes/APINotesFormat.h
index 4d1c698ae6310d..a03cef36294dbb 100644
--- a/clang/lib/APINotes/APINotesFormat.h
+++ b/clang/lib/APINotes/APINotesFormat.h
@@ -24,11 +24,10 @@ 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 =
- 32; // implicit parameter support (at position -1)
+const uint16_t VERSION_MINOR = 33; // SwiftEscapable
-const uint8_t kSwiftCopyable = 1;
-const uint8_t kSwiftNonCopyable = 2;
+const uint8_t kSwiftConforms = 1;
+const uint8_t kSwiftDoesNotConform = 2;
using IdentifierID = llvm::PointerEmbeddedInt<unsigned, 31>;
using IdentifierIDField = llvm::BCVBR<16>;
diff --git a/clang/lib/APINotes/APINotesReader.cpp b/clang/lib/APINotes/APINotesReader.cpp
index 0f8fa1355bfb0a..97b8654cbe6c9b 100644
--- a/clang/lib/APINotes/APINotesReader.cpp
+++ b/clang/lib/APINotes/APINotesReader.cpp
@@ -589,10 +589,16 @@ class TagTableInfo
uint8_t Copyable =
endian::readNext<uint8_t, llvm::endianness::little>(Data);
- if (Copyable == kSwiftNonCopyable)
+ if (Copyable == kSwiftDoesNotConform)
Info.setSwiftCopyable(std::optional(false));
- else if (Copyable == kSwiftCopyable)
+ else if (Copyable == kSwiftConforms)
Info.setSwiftCopyable(std::optional(true));
+ uint8_t Escapable =
+ endian::readNext<uint8_t, llvm::endianness::little>(Data);
+ if (Escapable == kSwiftDoesNotConform)
+ Info.setSwiftEscapable(std::optional(false));
+ else if (Escapable == kSwiftConforms)
+ Info.setSwiftEscapable(std::optional(true));
unsigned ImportAsLength =
endian::readNext<uint16_t, llvm::endianness::little>(Data);
diff --git a/clang/lib/APINotes/APINotesTypes.cpp b/clang/lib/APINotes/APINotesTypes.cpp
index b92faa0acc7482..d06277fa367274 100644
--- a/clang/lib/APINotes/APINotesTypes.cpp
+++ b/clang/lib/APINotes/APINotesTypes.cpp
@@ -104,6 +104,10 @@ LLVM_DUMP_METHOD void TagInfo::dump(llvm::raw_ostream &OS) {
if (EnumExtensibility)
OS << "Enum Extensibility: " << static_cast<long>(*EnumExtensibility)
<< ' ';
+ if (SwiftCopyableSpecified)
+ OS << (SwiftCopyable ? "[SwiftCopyable] " : "[~SwiftCopyable]");
+ if (SwiftEscapableSpecified)
+ OS << (SwiftEscapable ? "[SwiftEscapable] " : "[~SwiftEscapable]");
OS << '\n';
}
diff --git a/clang/lib/APINotes/APINotesWriter.cpp b/clang/lib/APINotes/APINotesWriter.cpp
index 3b8b3c80f7c086..4776f767ef6103 100644
--- a/clang/lib/APINotes/APINotesWriter.cpp
+++ b/clang/lib/APINotes/APINotesWriter.cpp
@@ -1266,11 +1266,11 @@ class CommonTypeTableInfo
class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
public:
unsigned getUnversionedInfoSize(const TagInfo &TI) {
- return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) +
- 2 + (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) +
- 2 + (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) +
- 2 + (TI.SwiftConformance ? TI.SwiftConformance->size() : 0) +
- 2 + getCommonTypeInfoSize(TI);
+ return 2 + (TI.SwiftImportAs ? TI.SwiftImportAs->size() : 0) + 2 +
+ (TI.SwiftRetainOp ? TI.SwiftRetainOp->size() : 0) + 2 +
+ (TI.SwiftReleaseOp ? TI.SwiftReleaseOp->size() : 0) + 2 +
+ (TI.SwiftConformance ? TI.SwiftConformance->size() : 0) + 3 +
+ getCommonTypeInfoSize(TI);
}
void emitUnversionedInfo(raw_ostream &OS, const TagInfo &TI) {
@@ -1289,7 +1289,12 @@ class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
writer.write<uint8_t>(Flags);
if (auto Copyable = TI.isSwiftCopyable())
- writer.write<uint8_t>(*Copyable ? kSwiftCopyable : kSwiftNonCopyable);
+ writer.write<uint8_t>(*Copyable ? kSwiftConforms : kSwiftDoesNotConform);
+ else
+ writer.write<uint8_t>(0);
+
+ if (auto Escapable = TI.isSwiftEscapable())
+ writer.write<uint8_t>(*Escapable ? kSwiftConforms : kSwiftDoesNotConform);
else
writer.write<uint8_t>(0);
diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp
index e3cb2b3f573886..0668dda910f2a8 100644
--- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp
+++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -459,6 +459,7 @@ struct Tag {
std::optional<bool> FlagEnum;
std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
std::optional<bool> SwiftCopyable;
+ std::optional<bool> SwiftEscapable;
FunctionsSeq Methods;
FieldsSeq Fields;
@@ -498,6 +499,7 @@ template <> struct MappingTraits<Tag> {
IO.mapOptional("FlagEnum", T.FlagEnum);
IO.mapOptional("EnumKind", T.EnumConvenienceKind);
IO.mapOptional("SwiftCopyable", T.SwiftCopyable);
+ IO.mapOptional("SwiftEscapable", T.SwiftEscapable);
IO.mapOptional("Methods", T.Methods);
IO.mapOptional("Fields", T.Fields);
IO.mapOptional("Tags", T.Tags);
@@ -983,6 +985,8 @@ class YAMLConverter {
if (T.SwiftCopyable)
TI.setSwiftCopyable(T.SwiftCopyable);
+ if (T.SwiftEscapable)
+ TI.setSwiftEscapable(T.SwiftEscapable);
if (T.EnumConvenienceKind) {
if (T.EnumExtensibility) {
diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp
index 5bb58d6c98be95..e73b4b360afead 100644
--- a/clang/lib/Sema/SemaAPINotes.cpp
+++ b/clang/lib/Sema/SemaAPINotes.cpp
@@ -647,6 +647,13 @@ static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info,
D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable"));
}
+ if (auto Escapable = Info.isSwiftEscapable()) {
+ if (*Escapable)
+ D->addAttr(SwiftAttrAttr::Create(S.Context, "Escapable"));
+ else
+ D->addAttr(SwiftAttrAttr::Create(S.Context, "~Escapable"));
+ }
+
if (auto Extensibility = Info.EnumExtensibility) {
using api_notes::EnumExtensibilityKind;
bool ShouldAddAttribute = (*Extensibility != EnumExtensibilityKind::None);
diff --git a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes
index f4f9c7a244e0a3..81fb160c66b638 100644
--- a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes
+++ b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes
@@ -13,3 +13,7 @@ Tags:
SwiftConformsTo: MySwiftModule.MySwiftNonCopyableProtocol
- Name: CopyableType
SwiftCopyable: true
+- Name: NonEscapableType
+ SwiftEscapable: false
+- Name: EscapableType
+ SwiftEscapable: true
\ No newline at end of file
diff --git a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h
index a8f6d0248eae40..f205cd3c6e7b71 100644
--- a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h
+++ b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h
@@ -7,3 +7,6 @@ inline void RCRelease(RefCountedType *x) { x->value--; }
struct NonCopyableType { int value; };
struct CopyableType { int value; };
+
+struct NonEscapableType { int value; };
+struct EscapableType { int value; };
diff --git a/clang/test/APINotes/swift-import-as.cpp b/clang/test/APINotes/swift-import-as.cpp
index 6457e1557618de..d0e7e31fc1d726 100644
--- a/clang/test/APINotes/swift-import-as.cpp
+++ b/clang/test/APINotes/swift-import-as.cpp
@@ -4,6 +4,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 RefCountedType | FileCheck -check-prefix=CHECK-REF-COUNTED %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 NonCopyableType | FileCheck -check-prefix=CHECK-NON-COPYABLE %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 CopyableType | FileCheck -check-prefix=CHECK-COPYABLE %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 NonEscapableType | FileCheck -check-prefix=CHECK-NON-ESCAPABLE %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 EscapableType | FileCheck -check-prefix=CHECK-ESCAPABLE %s
#include <SwiftImportAs.h>
@@ -26,3 +28,11 @@
// CHECK-COPYABLE: Dumping CopyableType:
// CHECK-COPYABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct CopyableType
// CHECK-COPYABLE-NOT: SwiftAttrAttr
+
+// CHECK-NON-ESCAPABLE: Dumping NonEscapableType:
+// CHECK-NON-ESCAPABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct NonEscapableType
+// CHECK-NON-ESCAPABLE: SwiftAttrAttr {{.+}} "~Escapable"
+
+// CHECK-ESCAPABLE: Dumping EscapableType:
+// CHECK-ESCAPABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct EscapableType
+// CHECK-ESCAPABLE: SwiftAttrAttr {{.+}} "Escapable"
``````````
</details>
https://github.com/llvm/llvm-project/pull/115866
More information about the cfe-commits
mailing list