llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Hunter Baker (literally-anything) <details> <summary>Changes</summary> This adds support for applying arbitrary Swift attributes to declarations using apinotes. For example: ```yaml # 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" ``` This fixes several cases where you would still need to modify the module headers to apply Swift attributes. --- Full diff: https://github.com/llvm/llvm-project/pull/180382.diff 12 Files Affected: - (modified) clang/docs/APINotes.rst (+20) - (modified) clang/include/clang/APINotes/Types.h (+9-1) - (modified) clang/lib/APINotes/APINotesFormat.h (+1-1) - (modified) clang/lib/APINotes/APINotesReader.cpp (+19) - (modified) clang/lib/APINotes/APINotesTypes.cpp (+7) - (modified) clang/lib/APINotes/APINotesWriter.cpp (+22-1) - (modified) clang/lib/APINotes/APINotesYAMLCompiler.cpp (+34) - (modified) clang/lib/Sema/SemaAPINotes.cpp (+5) - (added) clang/test/APINotes/Inputs/Headers/SwiftAttributes.apinotes (+24) - (added) clang/test/APINotes/Inputs/Headers/SwiftAttributes.h (+11) - (modified) clang/test/APINotes/Inputs/Headers/module.modulemap (+4) - (added) clang/test/APINotes/swift-attributes.cpp (+35) ``````````diff 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 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" `````````` </details> https://github.com/llvm/llvm-project/pull/180382 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
