Author: Gábor Horváth Date: 2024-11-12T21:34:56Z New Revision: d2db9bd708f1f1d4368e0b2d3870dd8c307c9895
URL: https://github.com/llvm/llvm-project/commit/d2db9bd708f1f1d4368e0b2d3870dd8c307c9895 DIFF: https://github.com/llvm/llvm-project/commit/d2db9bd708f1f1d4368e0b2d3870dd8c307c9895.diff LOG: [clang][APINotes] Add support for the SwiftEscapable attribute (#115866) This is similar to SwiftCopyable. Also fix missing SwiftCopyable dump for TagInfo. Added: Modified: clang/include/clang/APINotes/Types.h clang/lib/APINotes/APINotesFormat.h clang/lib/APINotes/APINotesReader.cpp clang/lib/APINotes/APINotesTypes.cpp clang/lib/APINotes/APINotesWriter.cpp clang/lib/APINotes/APINotesYAMLCompiler.cpp clang/lib/Sema/SemaAPINotes.cpp clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes clang/test/APINotes/Inputs/Headers/SwiftImportAs.h clang/test/APINotes/swift-import-as.cpp Removed: ################################################################################ diff --git a/clang/include/clang/APINotes/Types.h b/clang/include/clang/APINotes/Types.h index 6ad1c850701146..ff374ad3ada065 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,16 @@ 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 +795,9 @@ class TagInfo : public CommonTypeInfo { if (!SwiftCopyableSpecified) setSwiftCopyable(RHS.isSwiftCopyable()); + if (!SwiftEscapableSpecified) + setSwiftEscapable(RHS.isSwiftEscapable()); + return *this; } @@ -795,6 +814,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..45a344c13f470e 100644 --- a/clang/lib/APINotes/APINotesReader.cpp +++ b/clang/lib/APINotes/APINotesReader.cpp @@ -589,10 +589,12 @@ class TagTableInfo uint8_t Copyable = endian::readNext<uint8_t, llvm::endianness::little>(Data); - if (Copyable == kSwiftNonCopyable) - Info.setSwiftCopyable(std::optional(false)); - else if (Copyable == kSwiftCopyable) - Info.setSwiftCopyable(std::optional(true)); + if (Copyable == kSwiftConforms || Copyable == kSwiftDoesNotConform) + Info.setSwiftCopyable(std::optional(Copyable == kSwiftConforms)); + uint8_t Escapable = + endian::readNext<uint8_t, llvm::endianness::little>(Data); + if (Escapable == kSwiftConforms || Escapable == kSwiftDoesNotConform) + Info.setSwiftEscapable(std::optional(Escapable == kSwiftConforms)); 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..480e1190358d48 100644 --- a/clang/lib/APINotes/APINotesWriter.cpp +++ b/clang/lib/APINotes/APINotesWriter.cpp @@ -1266,11 +1266,13 @@ class CommonTypeTableInfo class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> { public: unsigned getUnversionedInfoSize(const TagInfo &TI) { + // clang-format off 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); + 3 + getCommonTypeInfoSize(TI); + // clang-format on } void emitUnversionedInfo(raw_ostream &OS, const TagInfo &TI) { @@ -1289,7 +1291,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..07d1326bf9a7c2 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -647,6 +647,11 @@ static void ProcessAPINotes(Sema &S, TagDecl *D, const api_notes::TagInfo &Info, D->addAttr(SwiftAttrAttr::Create(S.Context, "~Copyable")); } + if (auto Escapable = Info.isSwiftEscapable()) { + D->addAttr(SwiftAttrAttr::Create(S.Context, + *Escapable ? "Escapable" : "~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..c5171e2f287d28 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 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" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits