diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2118,6 +2118,12 @@ let ASTNode = 0; } +def SwiftBridgedTypedef : Attr { + let Spellings = [GNU<"swift_bridged_typedef">]; + let Subjects = SubjectList<[TypedefName], ErrorDiag, "typedefs">; + let Documentation = [SwiftBridgedTypedefDocs]; +} + def SwiftObjCMembers : Attr { let Spellings = [GNU<"swift_objc_members">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3381,6 +3381,15 @@ }]; } +def SwiftBridgedTypedefDocs : Documentation { + let Content = [{ +The ``swift_bridged_typedef`` attribute indicates that when the typedef to which +the attribute appertains is imported into Swift, it should refer to the bridged +Swift type (e.g. Swift's ``String``) rather than the Objective-C type as written +(e.g. ``NSString``). + }]; +} + def SwiftObjCMembersDocs : Documentation { let Content = [{ The ``swift_objc_members`` attribute maps to the ``@objcMembers`` Swift diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7539,6 +7539,9 @@ break; // Swift attributes. + case ParsedAttr::AT_SwiftBridgedTypedef: + handleSimpleAttribute(S, D, AL); + break; case ParsedAttr::AT_SwiftError: handleSwiftError(S, D, AL); break; diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -146,6 +146,7 @@ // CHECK-NEXT: Section (SubjectMatchRule_function, SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property) // CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member) // CHECK-NEXT: SpeculativeLoadHardening (SubjectMatchRule_function, SubjectMatchRule_objc_method) +// CHECK-NEXT: SwiftBridgedTypedef (SubjectMatchRule_type_alias) // CHECK-NEXT: SwiftContext (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: SwiftError (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: SwiftErrorResult (SubjectMatchRule_variable_is_parameter) diff --git a/clang/test/SemaObjC/attr-swift_bridged_typedef.m b/clang/test/SemaObjC/attr-swift_bridged_typedef.m new file mode 100644 --- /dev/null +++ b/clang/test/SemaObjC/attr-swift_bridged_typedef.m @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -verify -fsyntax-only %s + +@interface NSString +@end + +typedef NSString *NSStringAlias __attribute__((__swift_bridged_typedef__)); + +struct __attribute__((swift_bridged_typedef)) S {}; +// expected-error@-1 {{'swift_bridged_typedef' attribute only applies to typedefs}}