[clang] cdedc81 - [APINotes] Support annotating safety of APIs (#157506)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 15 03:30:34 PDT 2025
Author: Gábor Horváth
Date: 2025-09-15T12:30:29+02:00
New Revision: cdedc81c33649e97f053ca9eb346e3db6664bd7e
URL: https://github.com/llvm/llvm-project/commit/cdedc81c33649e97f053ca9eb346e3db6664bd7e
DIFF: https://github.com/llvm/llvm-project/commit/cdedc81c33649e97f053ca9eb346e3db6664bd7e.diff
LOG: [APINotes] Support annotating safety of APIs (#157506)
Added:
Modified:
clang/docs/APINotes.rst
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/docs/APINotes.rst b/clang/docs/APINotes.rst
index dec4b186ff72f..e142cfa62e5a2 100644
--- a/clang/docs/APINotes.rst
+++ b/clang/docs/APINotes.rst
@@ -229,6 +229,20 @@ declaration kind), all of which are optional:
- Name: vector
SwiftConformsTo: Cxx.CxxSequence
+:SwiftSafety:
+
+ Import a declaration as ``@safe`` or ``@unsafe`` to Swift.
+
+ ::
+
+ Tags:
+ - Name: UnsafeType
+ SwiftSafety: unsafe
+ - Name: span
+ Methods:
+ - Name: size
+ SwiftSafety: safe
+
:Availability, AvailabilityMsg:
A value of "nonswift" is equivalent to ``NS_SWIFT_UNAVAILABLE``. A value of
diff --git a/clang/include/clang/APINotes/Types.h b/clang/include/clang/APINotes/Types.h
index 71625715bda19..fb2b91a3e1750 100644
--- a/clang/include/clang/APINotes/Types.h
+++ b/clang/include/clang/APINotes/Types.h
@@ -46,6 +46,8 @@ enum class SwiftNewTypeKind {
Enum,
};
+enum class SwiftSafetyKind { Unspecified, Safe, Unsafe, None };
+
/// Describes API notes data for any entity.
///
/// This is used as the base of all API notes.
@@ -71,13 +73,19 @@ class CommonEntityInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned SwiftPrivate : 1;
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned SwiftSafetyAudited : 1;
+
+ LLVM_PREFERRED_TYPE(SwiftSafetyKind)
+ unsigned SwiftSafety : 2;
+
public:
/// Swift name of this entity.
std::string SwiftName;
CommonEntityInfo()
: Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
- SwiftPrivate(0) {}
+ SwiftPrivate(0), SwiftSafetyAudited(0), SwiftSafety(0) {}
std::optional<bool> isSwiftPrivate() const {
return SwiftPrivateSpecified ? std::optional<bool>(SwiftPrivate)
@@ -89,6 +97,17 @@ class CommonEntityInfo {
SwiftPrivate = Private.value_or(0);
}
+ std::optional<SwiftSafetyKind> getSwiftSafety() const {
+ return SwiftSafetyAudited ? std::optional<SwiftSafetyKind>(
+ static_cast<SwiftSafetyKind>(SwiftSafety))
+ : std::nullopt;
+ }
+
+ void setSwiftSafety(SwiftSafetyKind Safety) {
+ SwiftSafetyAudited = 1;
+ SwiftSafety = static_cast<unsigned>(Safety);
+ }
+
friend bool operator==(const CommonEntityInfo &, const CommonEntityInfo &);
CommonEntityInfo &operator|=(const CommonEntityInfo &RHS) {
@@ -108,6 +127,9 @@ class CommonEntityInfo {
if (!SwiftPrivateSpecified)
setSwiftPrivate(RHS.isSwiftPrivate());
+ if (!SwiftSafetyAudited && RHS.SwiftSafetyAudited)
+ setSwiftSafety(*RHS.getSwiftSafety());
+
if (SwiftName.empty())
SwiftName = RHS.SwiftName;
@@ -123,7 +145,9 @@ inline bool operator==(const CommonEntityInfo &LHS,
LHS.Unavailable == RHS.Unavailable &&
LHS.UnavailableInSwift == RHS.UnavailableInSwift &&
LHS.SwiftPrivateSpecified == RHS.SwiftPrivateSpecified &&
- LHS.SwiftPrivate == RHS.SwiftPrivate && LHS.SwiftName == RHS.SwiftName;
+ LHS.SwiftPrivate == RHS.SwiftPrivate &&
+ LHS.SwiftSafetyAudited == RHS.SwiftSafetyAudited &&
+ LHS.SwiftSafety == RHS.SwiftSafety && LHS.SwiftName == RHS.SwiftName;
}
inline bool operator!=(const CommonEntityInfo &LHS,
diff --git a/clang/lib/APINotes/APINotesFormat.h b/clang/lib/APINotes/APINotesFormat.h
index 69d180e7b3eb5..bb423ccb2bfaf 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 = 37; // SwiftDestroyOp
+const uint16_t VERSION_MINOR = 38; // SwiftSafety
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 573356f97ff73..7f9bb5f12cda7 100644
--- a/clang/lib/APINotes/APINotesReader.cpp
+++ b/clang/lib/APINotes/APINotesReader.cpp
@@ -94,11 +94,14 @@ class VersionedTableInfo {
/// Read serialized CommonEntityInfo.
void ReadCommonEntityInfo(const uint8_t *&Data, CommonEntityInfo &Info) {
- uint8_t UnavailableBits = *Data++;
- Info.Unavailable = (UnavailableBits >> 1) & 0x01;
- Info.UnavailableInSwift = UnavailableBits & 0x01;
- if ((UnavailableBits >> 2) & 0x01)
- Info.setSwiftPrivate(static_cast<bool>((UnavailableBits >> 3) & 0x01));
+ uint8_t EncodedBits = *Data++;
+ Info.Unavailable = (EncodedBits >> 1) & 0x01;
+ Info.UnavailableInSwift = EncodedBits & 0x01;
+ if ((EncodedBits >> 2) & 0x01)
+ Info.setSwiftPrivate(static_cast<bool>((EncodedBits >> 3) & 0x01));
+ if ((EncodedBits >> 4) & 0x01)
+ Info.setSwiftSafety(
+ static_cast<SwiftSafetyKind>((EncodedBits >> 5) & 0x03));
unsigned MsgLength =
endian::readNext<uint16_t, llvm::endianness::little>(Data);
diff --git a/clang/lib/APINotes/APINotesTypes.cpp b/clang/lib/APINotes/APINotesTypes.cpp
index f726faa832bcc..bff4be104c6c8 100644
--- a/clang/lib/APINotes/APINotesTypes.cpp
+++ b/clang/lib/APINotes/APINotesTypes.cpp
@@ -18,6 +18,21 @@ LLVM_DUMP_METHOD void CommonEntityInfo::dump(llvm::raw_ostream &OS) const {
OS << "[UnavailableInSwift] ";
if (SwiftPrivateSpecified)
OS << (SwiftPrivate ? "[SwiftPrivate] " : "");
+ if (SwiftSafetyAudited) {
+ switch (*getSwiftSafety()) {
+ case SwiftSafetyKind::Safe:
+ OS << "[Safe] ";
+ break;
+ case SwiftSafetyKind::Unsafe:
+ OS << "[Unsafe] ";
+ break;
+ case SwiftSafetyKind::Unspecified:
+ OS << "[Unspecified] ";
+ break;
+ case SwiftSafetyKind::None:
+ break;
+ }
+ }
if (!SwiftName.empty())
OS << "Swift Name: " << SwiftName << ' ';
OS << '\n';
diff --git a/clang/lib/APINotes/APINotesWriter.cpp b/clang/lib/APINotes/APINotesWriter.cpp
index cf88d118d0979..47ed93a567c0e 100644
--- a/clang/lib/APINotes/APINotesWriter.cpp
+++ b/clang/lib/APINotes/APINotesWriter.cpp
@@ -507,6 +507,12 @@ void emitCommonEntityInfo(raw_ostream &OS, const CommonEntityInfo &CEI) {
llvm::support::endian::Writer writer(OS, llvm::endianness::little);
uint8_t payload = 0;
+ if (auto safety = CEI.getSwiftSafety()) {
+ payload = static_cast<unsigned>(*safety);
+ payload <<= 1;
+ payload |= 0x01;
+ }
+ payload <<= 2;
if (auto swiftPrivate = CEI.isSwiftPrivate()) {
payload |= 0x01;
if (*swiftPrivate)
diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp
index a91a1eea03d81..8e91d48b4ba62 100644
--- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp
+++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -29,6 +29,18 @@
using namespace clang;
using namespace api_notes;
+namespace llvm {
+namespace yaml {
+template <> struct ScalarEnumerationTraits<SwiftSafetyKind> {
+ static void enumeration(IO &IO, SwiftSafetyKind &SK) {
+ IO.enumCase(SK, "unspecified", SwiftSafetyKind::Unspecified);
+ IO.enumCase(SK, "safe", SwiftSafetyKind::Safe);
+ IO.enumCase(SK, "unsafe", SwiftSafetyKind::Unsafe);
+ }
+};
+} // namespace yaml
+} // namespace llvm
+
namespace {
enum class APIAvailability {
Available = 0,
@@ -163,6 +175,7 @@ struct Method {
bool Required = false;
StringRef ResultType;
StringRef SwiftReturnOwnership;
+ SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
typedef std::vector<Method> MethodsSeq;
@@ -199,6 +212,7 @@ template <> struct MappingTraits<Method> {
IO.mapOptional("ResultType", M.ResultType, StringRef(""));
IO.mapOptional("SwiftReturnOwnership", M.SwiftReturnOwnership,
StringRef(""));
+ IO.mapOptional("SwiftSafety", M.SafetyKind, SwiftSafetyKind::None);
}
};
} // namespace yaml
@@ -214,6 +228,7 @@ struct Property {
StringRef SwiftName;
std::optional<bool> SwiftImportAsAccessors;
StringRef Type;
+ SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
typedef std::vector<Property> PropertiesSeq;
@@ -235,6 +250,7 @@ template <> struct MappingTraits<Property> {
IO.mapOptional("SwiftName", P.SwiftName, StringRef(""));
IO.mapOptional("SwiftImportAsAccessors", P.SwiftImportAsAccessors);
IO.mapOptional("Type", P.Type, StringRef(""));
+ IO.mapOptional("SwiftSafety", P.SafetyKind, SwiftSafetyKind::None);
}
};
} // namespace yaml
@@ -254,6 +270,7 @@ struct Class {
std::optional<std::string> SwiftConformance;
MethodsSeq Methods;
PropertiesSeq Properties;
+ SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
typedef std::vector<Class> ClassesSeq;
@@ -279,6 +296,7 @@ template <> struct MappingTraits<Class> {
IO.mapOptional("SwiftConformsTo", C.SwiftConformance);
IO.mapOptional("Methods", C.Methods);
IO.mapOptional("Properties", C.Properties);
+ IO.mapOptional("SwiftSafety", C.SafetyKind, SwiftSafetyKind::None);
}
};
} // namespace yaml
@@ -297,6 +315,7 @@ struct Function {
StringRef Type;
StringRef ResultType;
StringRef SwiftReturnOwnership;
+ SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
typedef std::vector<Function> FunctionsSeq;
@@ -321,6 +340,7 @@ template <> struct MappingTraits<Function> {
IO.mapOptional("ResultType", F.ResultType, StringRef(""));
IO.mapOptional("SwiftReturnOwnership", F.SwiftReturnOwnership,
StringRef(""));
+ IO.mapOptional("SwiftSafety", F.SafetyKind, SwiftSafetyKind::None);
}
};
} // namespace yaml
@@ -334,6 +354,7 @@ struct GlobalVariable {
std::optional<bool> SwiftPrivate;
StringRef SwiftName;
StringRef Type;
+ SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
typedef std::vector<GlobalVariable> GlobalVariablesSeq;
@@ -353,6 +374,7 @@ template <> struct MappingTraits<GlobalVariable> {
IO.mapOptional("SwiftPrivate", GV.SwiftPrivate);
IO.mapOptional("SwiftName", GV.SwiftName, StringRef(""));
IO.mapOptional("Type", GV.Type, StringRef(""));
+ IO.mapOptional("SwiftSafety", GV.SafetyKind, SwiftSafetyKind::None);
}
};
} // namespace yaml
@@ -364,6 +386,7 @@ struct EnumConstant {
AvailabilityItem Availability;
std::optional<bool> SwiftPrivate;
StringRef SwiftName;
+ SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
typedef std::vector<EnumConstant> EnumConstantsSeq;
@@ -381,6 +404,7 @@ template <> struct MappingTraits<EnumConstant> {
IO.mapOptional("AvailabilityMsg", EC.Availability.Msg, StringRef(""));
IO.mapOptional("SwiftPrivate", EC.SwiftPrivate);
IO.mapOptional("SwiftName", EC.SwiftName, StringRef(""));
+ IO.mapOptional("SwiftSafety", EC.SafetyKind, SwiftSafetyKind::None);
}
};
} // namespace yaml
@@ -424,6 +448,7 @@ struct Field {
std::optional<bool> SwiftPrivate;
StringRef SwiftName;
StringRef Type;
+ SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
typedef std::vector<Field> FieldsSeq;
@@ -443,6 +468,7 @@ template <> struct MappingTraits<Field> {
IO.mapOptional("SwiftPrivate", F.SwiftPrivate);
IO.mapOptional("SwiftName", F.SwiftName, StringRef(""));
IO.mapOptional("Type", F.Type, StringRef(""));
+ IO.mapOptional("SwiftSafety", F.SafetyKind, SwiftSafetyKind::None);
}
};
} // namespace yaml
@@ -470,6 +496,7 @@ struct Tag {
std::optional<EnumConvenienceAliasKind> EnumConvenienceKind;
std::optional<bool> SwiftCopyable;
std::optional<bool> SwiftEscapable;
+ SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
FunctionsSeq Methods;
FieldsSeq Fields;
@@ -515,6 +542,7 @@ template <> struct MappingTraits<Tag> {
IO.mapOptional("Methods", T.Methods);
IO.mapOptional("Fields", T.Fields);
IO.mapOptional("Tags", T.Tags);
+ IO.mapOptional("SwiftSafety", T.SafetyKind, SwiftSafetyKind::None);
}
};
} // namespace yaml
@@ -530,6 +558,7 @@ struct Typedef {
std::optional<StringRef> NSErrorDomain;
std::optional<SwiftNewTypeKind> SwiftType;
std::optional<std::string> SwiftConformance;
+ const SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
typedef std::vector<Typedef> TypedefsSeq;
@@ -602,6 +631,7 @@ struct Namespace {
StringRef SwiftName;
std::optional<bool> SwiftPrivate;
TopLevelItems Items;
+ const SwiftSafetyKind SafetyKind = SwiftSafetyKind::None;
};
} // namespace
@@ -797,6 +827,8 @@ class YAMLConverter {
StringRef APIName) {
convertAvailability(Common.Availability, Info, APIName);
Info.setSwiftPrivate(Common.SwiftPrivate);
+ if (Common.SafetyKind != SwiftSafetyKind::None)
+ Info.setSwiftSafety(Common.SafetyKind);
Info.SwiftName = std::string(Common.SwiftName);
}
@@ -956,6 +988,8 @@ class YAMLConverter {
void convertFunction(const Function &Function, FuncOrMethodInfo &FI) {
convertAvailability(Function.Availability, FI, Function.Name);
FI.setSwiftPrivate(Function.SwiftPrivate);
+ if (Function.SafetyKind != SwiftSafetyKind::None)
+ FI.setSwiftSafety(Function.SafetyKind);
FI.SwiftName = std::string(Function.SwiftName);
std::optional<ParamInfo> This;
convertParams(Function.Params, FI, This);
diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp
index 4cc1b76264340..99a29add8211d 100644
--- a/clang/lib/Sema/SemaAPINotes.cpp
+++ b/clang/lib/Sema/SemaAPINotes.cpp
@@ -13,6 +13,7 @@
#include "CheckExprLifetime.h"
#include "TypeLocBuilder.h"
#include "clang/APINotes/APINotesReader.h"
+#include "clang/APINotes/Types.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
@@ -291,6 +292,29 @@ static void ProcessAPINotes(Sema &S, Decl *D,
});
}
+ // swift_safety
+ if (auto SafetyKind = Info.getSwiftSafety()) {
+ bool Addition = *SafetyKind != api_notes::SwiftSafetyKind::Unspecified;
+ handleAPINotedAttribute<SwiftAttrAttr>(
+ S, D, Addition, Metadata,
+ [&] {
+ return SwiftAttrAttr::Create(
+ S.Context, *SafetyKind == api_notes::SwiftSafetyKind::Safe
+ ? "safe"
+ : "unsafe");
+ },
+ [](const Decl *D) {
+ return llvm::find_if(D->attrs(), [](const Attr *attr) {
+ if (const auto *swiftAttr = dyn_cast<SwiftAttrAttr>(attr)) {
+ if (swiftAttr->getAttribute() == "safe" ||
+ swiftAttr->getAttribute() == "unsafe")
+ return true;
+ }
+ return false;
+ });
+ });
+ }
+
// swift_name
if (!Info.SwiftName.empty()) {
handleAPINotedAttribute<SwiftNameAttr>(
diff --git a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes
index 15c806842d08f..7e9cac32df3a5 100644
--- a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes
+++ b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes
@@ -35,6 +35,14 @@ Tags:
- Name: NoncopyableWithDestroyType
SwiftCopyable: false
SwiftDestroyOp: NCDDestroy
+- Name: ImportAsUnsafeStruct
+ SwiftSafety: unsafe
+- Name: StructWithUnsafeMethod
+ Methods:
+ - Name: ImportAsUnsafeMethod
+ SwiftSafety: unsafe
+ - Name: ImportAsUnsafeMethodActuallySafe
+ SwiftSafety: safe
Functions:
- Name: functionReturningFrt__
@@ -42,7 +50,20 @@ Functions:
SwiftReturnOwnership: unretained
- Name: functionReturningFrt_returns_retained
SwiftReturnOwnership: retained
+ - Name: ImportAsUnsafe
+ SwiftSafety: unsafe
+ - Name: ImportAsUnsafeAlreadyAnnotated
+ SwiftSafety: unspecified
Typedefs:
- Name: WrappedOptions
SwiftWrapper: struct
SwiftConformsTo: Swift.OptionSet
+SwiftVersions:
+ - Version: 3.0
+ Functions:
+ - Name: ImportAsUnsafeVersioned
+ SwiftSafety: unsafe
+ - Version: 6.0
+ Functions:
+ - Name: ImportAsUnsafeVersioned
+ SwiftSafety: safe
diff --git a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h
index 978b4fbbb3b00..272e3865ab2ba 100644
--- a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h
+++ b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h
@@ -36,3 +36,14 @@ struct NoncopyableWithDestroyType {
};
void NCDDestroy(NoncopyableWithDestroyType instance);
+
+void ImportAsUnsafe();
+struct ImportAsUnsafeStruct {
+};
+struct StructWithUnsafeMethod {
+ void ImportAsUnsafeMethod();
+ void ImportAsUnsafeMethodActuallySafe();
+};
+
+void ImportAsUnsafeAlreadyAnnotated() __attribute__((swift_attr("unsafe")));
+void ImportAsUnsafeVersioned();
diff --git a/clang/test/APINotes/swift-import-as.cpp b/clang/test/APINotes/swift-import-as.cpp
index f5d08df7c6a1b..20d38b5a0968d 100644
--- a/clang/test/APINotes/swift-import-as.cpp
+++ b/clang/test/APINotes/swift-import-as.cpp
@@ -16,6 +16,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 methodReturningFrt_returns_retained | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT-RETAINED %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 WrappedOptions | FileCheck -check-prefix=CHECK-WRAPPED-OPTIONS %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 NoncopyableWithDestroyType | FileCheck -check-prefix=CHECK-NONCOPYABLE-WITH-DESTROY %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 ImportAsUnsafe | FileCheck -check-prefix=CHECK-IMPORT-AS-UNSAFE %s
#include <SwiftImportAs.h>
@@ -103,3 +104,32 @@
// CHECK-NONCOPYABLE-WITH-DESTROY: RecordDecl {{.*}}struct NoncopyableWithDestroyType
// CHECK-NONCOPYABLE-WITH-DESTROY: SwiftAttrAttr {{.+}} "destroy:NCDDestroy"
// CHECK-NONCOPYABLE-WITH-DESTROY: SwiftAttrAttr {{.+}} "~Copyable"
+
+// CHECK-IMPORT-AS-UNSAFE: Dumping ImportAsUnsafe:
+// CHECK-IMPORT-AS-UNSAFE: FunctionDecl {{.+}} ImportAsUnsafe
+// CHECK-IMPORT-AS-UNSAFE: SwiftAttrAttr {{.+}} "unsafe"
+
+// CHECK-IMPORT-AS-UNSAFE: Dumping ImportAsUnsafeStruct:
+// CHECK-IMPORT-AS-UNSAFE: CXXRecordDecl {{.+}} ImportAsUnsafeStruct
+// CHECK-IMPORT-AS-UNSAFE: SwiftAttrAttr {{.+}} "unsafe"
+
+// CHECK-IMPORT-AS-UNSAFE: Dumping StructWithUnsafeMethod::ImportAsUnsafeMethod:
+// CHECK-IMPORT-AS-UNSAFE: CXXMethodDecl {{.+}} ImportAsUnsafeMethod
+// CHECK-IMPORT-AS-UNSAFE: SwiftAttrAttr {{.+}} "unsafe"
+
+// CHECK-IMPORT-AS-UNSAFE: Dumping StructWithUnsafeMethod::ImportAsUnsafeMethodActuallySafe:
+// CHECK-IMPORT-AS-UNSAFE: CXXMethodDecl {{.+}} ImportAsUnsafeMethodActuallySafe
+// CHECK-IMPORT-AS-UNSAFE: SwiftAttrAttr {{.+}} "safe"
+
+// CHECK-IMPORT-AS-UNSAFE: Dumping ImportAsUnsafeAlreadyAnnotated:
+// CHECK-IMPORT-AS-UNSAFE: FunctionDecl {{.+}} ImportAsUnsafeAlreadyAnnotated
+// CHECK-IMPORT-AS-UNSAFE: SwiftVersionedAdditionAttr {{.+}} IsReplacedByActive
+// CHECK-IMPORT-AS-UNSAFE: SwiftAttrAttr {{.+}} "unsafe"
+// CHECK-IMPORT-AS-UNSAFE-EMPTY:
+
+// CHECK-IMPORT-AS-UNSAFE: Dumping ImportAsUnsafeVersioned:
+// CHECK-IMPORT-AS-UNSAFE: FunctionDecl {{.+}} ImportAsUnsafeVersioned
+// CHECK-IMPORT-AS-UNSAFE: SwiftVersionedAdditionAttr {{.+}} 3.0
+// CHECK-IMPORT-AS-UNSAFE: SwiftAttrAttr {{.+}} "unsafe"
+// CHECK-IMPORT-AS-UNSAFE: SwiftVersionedAdditionAttr {{.+}} 6.0
+// CHECK-IMPORT-AS-UNSAFE: SwiftAttrAttr {{.+}} "safe"
More information about the cfe-commits
mailing list