https://github.com/literally-anything updated 
https://github.com/llvm/llvm-project/pull/180382

>From 30c34295d4726f44a84f131d6ee8e61ea1d485c3 Mon Sep 17 00:00:00 2001
From: Hunter Baker <[email protected]>
Date: Sat, 7 Feb 2026 20:35:31 -0500
Subject: [PATCH 1/3] [APINotes] Support adding arbitrary Swift attributes

---
 clang/include/clang/APINotes/Types.h          | 10 +++++-
 clang/lib/APINotes/APINotesFormat.h           |  2 +-
 clang/lib/APINotes/APINotesReader.cpp         | 19 ++++++++++
 clang/lib/APINotes/APINotesTypes.cpp          |  7 ++++
 clang/lib/APINotes/APINotesWriter.cpp         | 23 +++++++++++-
 clang/lib/APINotes/APINotesYAMLCompiler.cpp   | 34 ++++++++++++++++++
 clang/lib/Sema/SemaAPINotes.cpp               |  5 +++
 .../Inputs/Headers/SwiftAttributes.apinotes   | 24 +++++++++++++
 .../APINotes/Inputs/Headers/SwiftAttributes.h | 11 ++++++
 .../APINotes/Inputs/Headers/module.modulemap  |  4 +++
 clang/test/APINotes/swift-attributes.cpp      | 35 +++++++++++++++++++
 11 files changed, 171 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/APINotes/Inputs/Headers/SwiftAttributes.apinotes
 create mode 100644 clang/test/APINotes/Inputs/Headers/SwiftAttributes.h
 create mode 100644 clang/test/APINotes/swift-attributes.cpp

diff --git a/clang/include/clang/APINotes/Types.h 
b/clang/include/clang/APINotes/Types.h
index fb2b91a3e1750..ca5b35954d027 100644
--- a/clang/include/clang/APINotes/Types.h
+++ b/clang/include/clang/APINotes/Types.h
@@ -83,6 +83,9 @@ class CommonEntityInfo {
   /// Swift name of this entity.
   std::string SwiftName;
 
+  /// Swift attributes to apply to this entity.
+  std::vector<std::string> SwiftAttributes;
+
   CommonEntityInfo()
       : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
         SwiftPrivate(0), SwiftSafetyAudited(0), SwiftSafety(0) {}
@@ -133,6 +136,9 @@ class CommonEntityInfo {
     if (SwiftName.empty())
       SwiftName = RHS.SwiftName;
 
+    // Merge SwiftAttributes
+    SwiftAttributes.insert(SwiftAttributes.end(), RHS.SwiftAttributes.begin(), 
RHS.SwiftAttributes.end());
+
     return *this;
   }
 
@@ -147,7 +153,9 @@ inline bool operator==(const CommonEntityInfo &LHS,
          LHS.SwiftPrivateSpecified == RHS.SwiftPrivateSpecified &&
          LHS.SwiftPrivate == RHS.SwiftPrivate &&
          LHS.SwiftSafetyAudited == RHS.SwiftSafetyAudited &&
-         LHS.SwiftSafety == RHS.SwiftSafety && LHS.SwiftName == RHS.SwiftName;
+         LHS.SwiftSafety == RHS.SwiftSafety &&
+         LHS.SwiftName == RHS.SwiftName &&
+         LHS.SwiftAttributes == RHS.SwiftAttributes;
 }
 
 inline bool operator!=(const CommonEntityInfo &LHS,
diff --git a/clang/lib/APINotes/APINotesFormat.h 
b/clang/lib/APINotes/APINotesFormat.h
index bb423ccb2bfaf..db57c764dddb0 100644
--- a/clang/lib/APINotes/APINotesFormat.h
+++ b/clang/lib/APINotes/APINotesFormat.h
@@ -24,7 +24,7 @@ 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 = 38; // SwiftSafety
+const uint16_t VERSION_MINOR = 39; // SwiftAttributes
 
 const uint8_t kSwiftConforms = 1;
 const uint8_t kSwiftDoesNotConform = 2;
diff --git a/clang/lib/APINotes/APINotesReader.cpp 
b/clang/lib/APINotes/APINotesReader.cpp
index 7f9bb5f12cda7..97043460c2203 100644
--- a/clang/lib/APINotes/APINotesReader.cpp
+++ b/clang/lib/APINotes/APINotesReader.cpp
@@ -92,6 +92,16 @@ class VersionedTableInfo {
   }
 };
 
+/// Read serialized Attribute from a SwiftAttributes sequence.
+void ReadSwiftAttribute(const uint8_t *&Data, std::string &Attribute) {
+  unsigned AttributeLength =
+      endian::readNext<uint16_t, llvm::endianness::little>(Data);
+  Attribute =
+      std::string(reinterpret_cast<const char *>(Data),
+                  reinterpret_cast<const char *>(Data) + AttributeLength);
+  Data += AttributeLength;
+}
+
 /// Read serialized CommonEntityInfo.
 void ReadCommonEntityInfo(const uint8_t *&Data, CommonEntityInfo &Info) {
   uint8_t EncodedBits = *Data++;
@@ -116,6 +126,15 @@ void ReadCommonEntityInfo(const uint8_t *&Data, 
CommonEntityInfo &Info) {
       std::string(reinterpret_cast<const char *>(Data),
                   reinterpret_cast<const char *>(Data) + SwiftNameLength);
   Data += SwiftNameLength;
+
+  unsigned NumSwiftAttributes =
+      endian::readNext<uint16_t, llvm::endianness::little>(Data);
+  while (NumSwiftAttributes > 0) {
+    std::string Attribute;
+    ReadSwiftAttribute(Data, Attribute);
+    Info.SwiftAttributes.push_back(Attribute);
+    --NumSwiftAttributes;
+  }
 }
 
 /// Read serialized CommonTypeInfo.
diff --git a/clang/lib/APINotes/APINotesTypes.cpp 
b/clang/lib/APINotes/APINotesTypes.cpp
index bff4be104c6c8..2a6e620fa902a 100644
--- a/clang/lib/APINotes/APINotesTypes.cpp
+++ b/clang/lib/APINotes/APINotesTypes.cpp
@@ -35,6 +35,13 @@ LLVM_DUMP_METHOD void 
CommonEntityInfo::dump(llvm::raw_ostream &OS) const {
   }
   if (!SwiftName.empty())
     OS << "Swift Name: " << SwiftName << ' ';
+  if (!SwiftAttributes.empty()) {
+    OS << "Swift Attrs: [";
+    for (const std::string &attr : SwiftAttributes) {
+      OS << '\"' << attr << "\", ";
+    }
+    OS << "] ";
+  }
   OS << '\n';
 }
 
diff --git a/clang/lib/APINotes/APINotesWriter.cpp 
b/clang/lib/APINotes/APINotesWriter.cpp
index 47ed93a567c0e..82ffb65e39ec6 100644
--- a/clang/lib/APINotes/APINotesWriter.cpp
+++ b/clang/lib/APINotes/APINotesWriter.cpp
@@ -502,6 +502,13 @@ class VersionedTableInfo {
   }
 };
 
+/// Emit a serialized representation of the Attribute from the SwifrAttributes 
sequence.
+void emitSwiftAttribute(raw_ostream &OS, const std::string &Attribute) {
+  llvm::support::endian::Writer writer(OS, llvm::endianness::little);
+  writer.write<uint16_t>(Attribute.size());
+  OS.write(Attribute.c_str(), Attribute.size());
+}
+
 /// Emit a serialized representation of the common entity information.
 void emitCommonEntityInfo(raw_ostream &OS, const CommonEntityInfo &CEI) {
   llvm::support::endian::Writer writer(OS, llvm::endianness::little);
@@ -530,12 +537,26 @@ void emitCommonEntityInfo(raw_ostream &OS, const 
CommonEntityInfo &CEI) {
 
   writer.write<uint16_t>(CEI.SwiftName.size());
   OS.write(CEI.SwiftName.c_str(), CEI.SwiftName.size());
+
+  writer.write<uint16_t>(CEI.SwiftAttributes.size());
+  for (const auto &Attribute : CEI.SwiftAttributes)
+    emitSwiftAttribute(OS, Attribute);
+}
+
+/// Retrieve the serialized size of the given an Attribute in a 
SwiftAttributes sequence,
+/// for use in on-disk hash tables.
+unsigned getSwiftAttributeSize(const std::string &Attribute) {
+  return sizeof(uint16_t) + Attribute.size(); // length and contents
 }
 
 /// Retrieve the serialized size of the given CommonEntityInfo, for use in
 /// on-disk hash tables.
 unsigned getCommonEntityInfoSize(const CommonEntityInfo &CEI) {
-  return 5 + CEI.UnavailableMsg.size() + CEI.SwiftName.size();
+  unsigned size = 5 + CEI.UnavailableMsg.size() + CEI.SwiftName.size();
+  size += sizeof(uint16_t); // SwiftAttributes length
+  for (const auto &Attribute : CEI.SwiftAttributes)
+    size += getSwiftAttributeSize(Attribute);
+  return size;
 }
 
 // Retrieve the serialized size of the given CommonTypeInfo, for use
diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp 
b/clang/lib/APINotes/APINotesYAMLCompiler.cpp
index 3be528feb325e..8283e7ceef1e2 100644
--- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp
+++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -79,6 +79,10 @@ template <> struct ScalarEnumerationTraits<MethodKind> {
 } // namespace yaml
 } // namespace llvm
 
+namespace {
+typedef std::vector<StringRef> SwiftAttributeSeq;
+} // namespace
+
 namespace {
 struct Param {
   int Position;
@@ -176,6 +180,7 @@ struct Method {
   StringRef ResultType;
   StringRef SwiftReturnOwnership;
   SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
 };
 
 typedef std::vector<Method> MethodsSeq;
@@ -213,6 +218,7 @@ template <> struct MappingTraits<Method> {
     IO.mapOptional("SwiftReturnOwnership", M.SwiftReturnOwnership,
                    StringRef(""));
     IO.mapOptional("SwiftSafety", M.SafetyKind, SwiftSafetyKind::None);
+    IO.mapOptional("SwiftAttributes", M.SwiftAttributes, SwiftAttributeSeq());
   }
 };
 } // namespace yaml
@@ -229,6 +235,7 @@ struct Property {
   std::optional<bool> SwiftImportAsAccessors;
   StringRef Type;
   SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
 };
 
 typedef std::vector<Property> PropertiesSeq;
@@ -251,6 +258,7 @@ template <> struct MappingTraits<Property> {
     IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);
     IO.mapOptional("Type", P.Type, StringRef(""));
     IO.mapOptional("SwiftSafety", P.SafetyKind, SwiftSafetyKind::None);
+    IO.mapOptional("SwiftAttributes", P.SwiftAttributes, SwiftAttributeSeq());
   }
 };
 } // namespace yaml
@@ -271,6 +279,7 @@ struct Class {
   MethodsSeq Methods;
   PropertiesSeq Properties;
   SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
 };
 
 typedef std::vector<Class> ClassesSeq;
@@ -297,6 +306,7 @@ template <> struct MappingTraits<Class> {
     IO.mapOptional("Methods", C.Methods);
     IO.mapOptional("Properties", C.Properties);
     IO.mapOptional("SwiftSafety", C.SafetyKind, SwiftSafetyKind::None);
+    IO.mapOptional("SwiftAttributes", C.SwiftAttributes, SwiftAttributeSeq());
   }
 };
 } // namespace yaml
@@ -316,6 +326,7 @@ struct Function {
   StringRef ResultType;
   StringRef SwiftReturnOwnership;
   SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
 };
 
 typedef std::vector<Function> FunctionsSeq;
@@ -341,6 +352,7 @@ template <> struct MappingTraits<Function> {
     IO.mapOptional("SwiftReturnOwnership", F.SwiftReturnOwnership,
                    StringRef(""));
     IO.mapOptional("SwiftSafety", F.SafetyKind, SwiftSafetyKind::None);
+    IO.mapOptional("SwiftAttributes", F.SwiftAttributes, SwiftAttributeSeq());
   }
 };
 } // namespace yaml
@@ -355,6 +367,7 @@ struct GlobalVariable {
   StringRef SwiftName;
   StringRef Type;
   SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
 };
 
 typedef std::vector<GlobalVariable> GlobalVariablesSeq;
@@ -375,6 +388,7 @@ template <> struct MappingTraits<GlobalVariable> {
     IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));
     IO.mapOptional("Type", GV.Type, StringRef(""));
     IO.mapOptional("SwiftSafety", GV.SafetyKind, SwiftSafetyKind::None);
+    IO.mapOptional("SwiftAttributes", GV.SwiftAttributes, SwiftAttributeSeq());
   }
 };
 } // namespace yaml
@@ -449,6 +463,7 @@ struct Field {
   StringRef SwiftName;
   StringRef Type;
   SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
 };
 
 typedef std::vector<Field> FieldsSeq;
@@ -469,6 +484,7 @@ template <> struct MappingTraits<Field> {
     IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
     IO.mapOptional("Type", F.Type, StringRef(""));
     IO.mapOptional("SwiftSafety", F.SafetyKind, SwiftSafetyKind::None);
+    IO.mapOptional("SwiftAttributes", F.SwiftAttributes, SwiftAttributeSeq());
   }
 };
 } // namespace yaml
@@ -497,6 +513,7 @@ struct Tag {
   std::optional<bool> SwiftCopyable;
   std::optional<bool> SwiftEscapable;
   SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
   FunctionsSeq Methods;
   FieldsSeq Fields;
 
@@ -543,6 +560,7 @@ template <> struct MappingTraits<Tag> {
     IO.mapOptional("Fields", T.Fields);
     IO.mapOptional("Tags", T.Tags);
     IO.mapOptional("SwiftSafety", T.SafetyKind, SwiftSafetyKind::None);
+    IO.mapOptional("SwiftAttributes", T.SwiftAttributes, SwiftAttributeSeq());
   }
 };
 } // namespace yaml
@@ -559,6 +577,7 @@ struct Typedef {
   std::optional<SwiftNewTypeKind> SwiftType;
   std::optional<std::string> SwiftConformance;
   const SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
 };
 
 typedef std::vector<Typedef> TypedefsSeq;
@@ -588,6 +607,7 @@ template <> struct MappingTraits<Typedef> {
     IO.mapOptional("NSErrorDomain", T.NSErrorDomain);
     IO.mapOptional("SwiftWrapper", T.SwiftType);
     IO.mapOptional("SwiftConformsTo", T.SwiftConformance);
+    IO.mapOptional("SwiftAttributes", T.SwiftAttributes, SwiftAttributeSeq());
   }
 };
 } // namespace yaml
@@ -632,6 +652,7 @@ struct Namespace {
   std::optional<bool> SwiftPrivate;
   TopLevelItems Items;
   const SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
+  SwiftAttributeSeq SwiftAttributes;
 };
 } // namespace
 
@@ -647,6 +668,7 @@ template <> struct MappingTraits<Namespace> {
     IO.mapOptional("AvailabilityMsg", T.Availability.Msg, StringRef(""));
     IO.mapOptional("SwiftPrivate", T.SwiftPrivate);
     IO.mapOptional("SwiftName", T.SwiftName, StringRef(""));
+    IO.mapOptional("SwiftAttributes", T.SwiftAttributes, SwiftAttributeSeq());
     mapTopLevelItems(IO, T.Items);
   }
 };
@@ -777,6 +799,15 @@ class YAMLConverter {
     }
   }
 
+  void convertSwiftAttributes(const SwiftAttributeSeq &SwiftAttributes,
+                              CommonEntityInfo &OutInfo) {
+    // Convert StringRef attributes to std::vector<std::string> in 
CommonEntityInfo
+    OutInfo.SwiftAttributes.reserve(SwiftAttributes.size());
+    for (const StringRef &A : SwiftAttributes) {
+      OutInfo.SwiftAttributes.emplace_back(A);
+    }
+  }
+
   void convertParams(const ParamsSeq &Params, FunctionInfo &OutInfo,
                      std::optional<ParamInfo> &thisOrSelf) {
     for (const auto &P : Params) {
@@ -830,6 +861,7 @@ class YAMLConverter {
     if (Common.SafetyKind != SwiftSafetyKind::None)
       Info.setSwiftSafety(Common.SafetyKind);
     Info.SwiftName = std::string(Common.SwiftName);
+    convertSwiftAttributes(Common.SwiftAttributes, Info);
   }
 
   /// Convert the common parts of a type entity from YAML.
@@ -893,6 +925,7 @@ class YAMLConverter {
     convertAvailability(Entity.Availability, VI, Entity.Name);
     VI.setSwiftPrivate(Entity.SwiftPrivate);
     VI.SwiftName = std::string(Entity.SwiftName);
+    convertSwiftAttributes(Entity.SwiftAttributes, VI);
     if (Entity.Nullability)
       VI.setNullabilityAudited(*Entity.Nullability);
     VI.setType(std::string(Entity.Type));
@@ -991,6 +1024,7 @@ class YAMLConverter {
     if (Function.SafetyKind != SwiftSafetyKind::None)
       FI.setSwiftSafety(Function.SafetyKind);
     FI.SwiftName = std::string(Function.SwiftName);
+    convertSwiftAttributes(Function.SwiftAttributes, FI);
     std::optional<ParamInfo> This;
     convertParams(Function.Params, FI, This);
     if constexpr (std::is_same_v<FuncOrMethodInfo, CXXMethodInfo>)
diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp
index 059eb0dd767b7..bf18f12ee203e 100644
--- a/clang/lib/Sema/SemaAPINotes.cpp
+++ b/clang/lib/Sema/SemaAPINotes.cpp
@@ -335,6 +335,11 @@ static void ProcessAPINotes(Sema &S, Decl *D,
                             ASTAllocateString(S.Context, Info.SwiftName));
         });
   }
+
+  // swift_attr
+  for (const std::string& swiftAttrName : Info.SwiftAttributes) {
+    D->addAttr(SwiftAttrAttr::Create(S.Context, swiftAttrName));
+  }
 }
 
 static void ProcessAPINotes(Sema &S, Decl *D,
diff --git a/clang/test/APINotes/Inputs/Headers/SwiftAttributes.apinotes 
b/clang/test/APINotes/Inputs/Headers/SwiftAttributes.apinotes
new file mode 100644
index 0000000000000..926ff7c879433
--- /dev/null
+++ b/clang/test/APINotes/Inputs/Headers/SwiftAttributes.apinotes
@@ -0,0 +1,24 @@
+Name: SwiftAttributes
+Tags:
+- Name: IntWrapperStruct
+  SwiftAttributes: ["some Swift struct attribute"]
+  Fields:
+  - Name: value
+    SwiftAttributes: ["some Swift field attribute"]
+  Methods:
+  - Name: do_something
+    SwiftAttributes: ["some Swift struct method attribute"]
+- Name: some_ns
+  SwiftAttributes: ["some Swift namespace attribute"]
+Functions:
+- Name: some_operation
+  SwiftAttributes: [
+    "some Swift function attribute",
+    "some other Swift function attribute"
+  ]
+Globals:
+- Name: global_int
+  SwiftAttributes: ["some Swift global variable attribute"]
+Typedefs:
+- Name: int_typedef
+  SwiftAttributes: ["some Swift typedef attribute"]
diff --git a/clang/test/APINotes/Inputs/Headers/SwiftAttributes.h 
b/clang/test/APINotes/Inputs/Headers/SwiftAttributes.h
new file mode 100644
index 0000000000000..c251f0527c41e
--- /dev/null
+++ b/clang/test/APINotes/Inputs/Headers/SwiftAttributes.h
@@ -0,0 +1,11 @@
+struct IntWrapperStruct {
+  int value;
+
+  void do_something();
+};
+
+void some_operation(IntWrapperStruct &);
+
+int global_int = 123;
+
+typedef int int_typedef;
diff --git a/clang/test/APINotes/Inputs/Headers/module.modulemap 
b/clang/test/APINotes/Inputs/Headers/module.modulemap
index bedb7d505f794..2c0939277f4e3 100644
--- a/clang/test/APINotes/Inputs/Headers/module.modulemap
+++ b/clang/test/APINotes/Inputs/Headers/module.modulemap
@@ -61,3 +61,7 @@ module SwiftImportAs {
 module SwiftReturnOwnershipForObjC {
   header "SwiftReturnOwnershipForObjC.h"
 }
+
+module SwiftAttributes {
+  header "SwiftAttributes.h"
+}
diff --git a/clang/test/APINotes/swift-attributes.cpp 
b/clang/test/APINotes/swift-attributes.cpp
new file mode 100644
index 0000000000000..0d65336415604
--- /dev/null
+++ b/clang/test/APINotes/swift-attributes.cpp
@@ -0,0 +1,35 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/SwiftAttributes -fdisable-module-hash 
-fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks 
%s -x c++
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/SwiftAttributes -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump 
-ast-dump-filter IntWrapperStruct -x c++ | FileCheck 
--check-prefix=CHECK-STRUCT %s
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/SwiftAttributes -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump 
-ast-dump-filter IntWrapperStruct::value -x c++ | FileCheck 
--check-prefix=CHECK-FIELD %s
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/SwiftAttributes -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump 
-ast-dump-filter IntWrapperStruct::do_something -x c++ | FileCheck 
--check-prefix=CHECK-METHOD %s
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/SwiftAttributes -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump 
-ast-dump-filter some_operation -x c++ | FileCheck --check-prefix=CHECK-FUNC %s
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/SwiftAttributes -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump 
-ast-dump-filter global_int -x c++ | FileCheck --check-prefix=CHECK-VAR %s
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps 
-fmodules-cache-path=%t/ModulesCache/SwiftAttributes -fdisable-module-hash 
-fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump 
-ast-dump-filter int_typedef -x c++ | FileCheck --check-prefix=CHECK-TYPEDEF %s
+
+#include "SwiftAttributes.h"
+
+// CHECK-STRUCT: Dumping IntWrapperStruct:
+// CHECK-STRUCT-NEXT: CXXRecordDecl {{.+}} struct IntWrapperStruct
+// CHECK-STRUCT: SwiftAttrAttr {{.+}} <<invalid sloc>> "some Swift struct 
attribute"
+
+// CHECK-FIELD: Dumping IntWrapperStruct::value:
+// CHECK-FIELD-NEXT: FieldDecl {{.+}} value
+// CHECK-FIELD: SwiftAttrAttr {{.+}} <<invalid sloc>> "some Swift field 
attribute"
+
+// CHECK-METHOD: Dumping IntWrapperStruct::do_something:
+// CHECK-METHOD-NEXT: CXXMethodDecl {{.+}} do_something
+// CHECK-METHOD: SwiftAttrAttr {{.+}} <<invalid sloc>> "some Swift struct 
method attribute"
+
+// CHECK-FUNC: Dumping some_operation:
+// CHECK-FUNC-NEXT: FunctionDecl {{.+}} some_operation
+// CHECK-FUNC: SwiftAttrAttr {{.+}} <<invalid sloc>> "some Swift function 
attribute"
+// CHECK-FUNC: SwiftAttrAttr {{.+}} <<invalid sloc>> "some other Swift 
function attribute"
+
+// CHECK-VAR: Dumping global_int:
+// CHECK-VAR-NEXT: VarDecl {{.+}} global_int
+// CHECK-VAR: SwiftAttrAttr {{.+}} <<invalid sloc>> "some Swift global 
variable attribute"
+
+// CHECK-TYPEDEF: Dumping int_typedef:
+// CHECK-TYPEDEF-NEXT: TypedefDecl {{.+}} int_typedef
+// CHECK-TYPEDEF: SwiftAttrAttr {{.+}} <<invalid sloc>> "some Swift typedef 
attribute"

>From 5c20abb0b4a75f640a40deb22b6fee9d808c067a Mon Sep 17 00:00:00 2001
From: Hunter Baker <[email protected]>
Date: Sat, 7 Feb 2026 20:54:55 -0500
Subject: [PATCH 2/3] [APINotes] Document SwiftAttributes key

---
 clang/docs/APINotes.rst | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/clang/docs/APINotes.rst b/clang/docs/APINotes.rst
index e142cfa62e5a2..4909555476772 100644
--- a/clang/docs/APINotes.rst
+++ b/clang/docs/APINotes.rst
@@ -243,6 +243,26 @@ declaration kind), all of which are optional:
         - Name: size
           SwiftSafety: safe
 
+:SwiftAttributes:
+
+  Attach arbitrary Swift attributes to a declaration.
+  This is equivalent to applying the `swift_attr("")` attribute in the header.
+
+  ::
+
+    # Mark safe globals as nonisolated to make them accessible in Swift 6
+    Globals:
+    - Name: globalVariable
+      SwiftAttributes:
+      - "nonisolated(unsafe)"
+    
+    # Apply Swift macros to C declarations on import
+    Functions:
+    - Name: cFunction
+      SwiftAttributes:
+      - "@MyModule.GenerateWrapper"
+  
+
 :Availability, AvailabilityMsg:
 
   A value of "nonswift" is equivalent to ``NS_SWIFT_UNAVAILABLE``. A value of

>From 2fb5981f57ce41613d47a63ed458e31c49eebc0d Mon Sep 17 00:00:00 2001
From: Hunter Baker <[email protected]>
Date: Sat, 7 Feb 2026 21:22:11 -0500
Subject: [PATCH 3/3] [APINotes] Format SwiftAttributes changes

---
 clang/include/clang/APINotes/Types.h        | 6 +++---
 clang/lib/APINotes/APINotesWriter.cpp       | 7 ++++---
 clang/lib/APINotes/APINotesYAMLCompiler.cpp | 3 ++-
 clang/lib/Sema/SemaAPINotes.cpp             | 2 +-
 4 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/clang/include/clang/APINotes/Types.h 
b/clang/include/clang/APINotes/Types.h
index ca5b35954d027..152fa65e18f2b 100644
--- a/clang/include/clang/APINotes/Types.h
+++ b/clang/include/clang/APINotes/Types.h
@@ -137,7 +137,8 @@ class CommonEntityInfo {
       SwiftName = RHS.SwiftName;
 
     // Merge SwiftAttributes
-    SwiftAttributes.insert(SwiftAttributes.end(), RHS.SwiftAttributes.begin(), 
RHS.SwiftAttributes.end());
+    SwiftAttributes.insert(SwiftAttributes.end(), RHS.SwiftAttributes.begin(),
+                           RHS.SwiftAttributes.end());
 
     return *this;
   }
@@ -153,8 +154,7 @@ inline bool operator==(const CommonEntityInfo &LHS,
          LHS.SwiftPrivateSpecified == RHS.SwiftPrivateSpecified &&
          LHS.SwiftPrivate == RHS.SwiftPrivate &&
          LHS.SwiftSafetyAudited == RHS.SwiftSafetyAudited &&
-         LHS.SwiftSafety == RHS.SwiftSafety &&
-         LHS.SwiftName == RHS.SwiftName &&
+         LHS.SwiftSafety == RHS.SwiftSafety && LHS.SwiftName == RHS.SwiftName 
&&
          LHS.SwiftAttributes == RHS.SwiftAttributes;
 }
 
diff --git a/clang/lib/APINotes/APINotesWriter.cpp 
b/clang/lib/APINotes/APINotesWriter.cpp
index 82ffb65e39ec6..28a9f94996c10 100644
--- a/clang/lib/APINotes/APINotesWriter.cpp
+++ b/clang/lib/APINotes/APINotesWriter.cpp
@@ -502,7 +502,8 @@ class VersionedTableInfo {
   }
 };
 
-/// Emit a serialized representation of the Attribute from the SwifrAttributes 
sequence.
+/// Emit a serialized representation of the Attribute from the SwifrAttributes
+/// sequence.
 void emitSwiftAttribute(raw_ostream &OS, const std::string &Attribute) {
   llvm::support::endian::Writer writer(OS, llvm::endianness::little);
   writer.write<uint16_t>(Attribute.size());
@@ -543,8 +544,8 @@ void emitCommonEntityInfo(raw_ostream &OS, const 
CommonEntityInfo &CEI) {
     emitSwiftAttribute(OS, Attribute);
 }
 
-/// Retrieve the serialized size of the given an Attribute in a 
SwiftAttributes sequence,
-/// for use in on-disk hash tables.
+/// Retrieve the serialized size of the given an Attribute in a SwiftAttributes
+/// sequence, for use in on-disk hash tables.
 unsigned getSwiftAttributeSize(const std::string &Attribute) {
   return sizeof(uint16_t) + Attribute.size(); // length and contents
 }
diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp 
b/clang/lib/APINotes/APINotesYAMLCompiler.cpp
index 8283e7ceef1e2..17e85c8407b12 100644
--- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp
+++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -801,7 +801,8 @@ class YAMLConverter {
 
   void convertSwiftAttributes(const SwiftAttributeSeq &SwiftAttributes,
                               CommonEntityInfo &OutInfo) {
-    // Convert StringRef attributes to std::vector<std::string> in 
CommonEntityInfo
+    // Convert StringRef attributes to std::vector<std::string> in
+    // CommonEntityInfo
     OutInfo.SwiftAttributes.reserve(SwiftAttributes.size());
     for (const StringRef &A : SwiftAttributes) {
       OutInfo.SwiftAttributes.emplace_back(A);
diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp
index bf18f12ee203e..2d641f6e505cc 100644
--- a/clang/lib/Sema/SemaAPINotes.cpp
+++ b/clang/lib/Sema/SemaAPINotes.cpp
@@ -337,7 +337,7 @@ static void ProcessAPINotes(Sema &S, Decl *D,
   }
 
   // swift_attr
-  for (const std::string& swiftAttrName : Info.SwiftAttributes) {
+  for (const std::string &swiftAttrName : Info.SwiftAttributes) {
     D->addAttr(SwiftAttrAttr::Create(S.Context, swiftAttrName));
   }
 }

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to