arphaman created this revision.
arphaman added reviewers: erik.pilkington, aaron.ballman.
Herald added subscribers: ributzka, jkorous.
Herald added a project: clang.
arphaman requested review of this revision.

The `swift_attr` attribute is a generic annotation attribute that's not used by 
clang, but is used by the Swift compiler. The Swift compiler can use these 
annotations to provide various syntactic and semantic sugars for the imported 
Objective-C API declarations.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D92354

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/AST/attr-swift_attr.m
  clang/test/SemaObjC/validate-attr-swift_attr.m


Index: clang/test/SemaObjC/validate-attr-swift_attr.m
===================================================================
--- /dev/null
+++ clang/test/SemaObjC/validate-attr-swift_attr.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+// expected-error@+1 {{'swift_attr' attribute takes one argument}}
+__attribute__((swift_attr))
+@interface I
+@end
+
+// expected-error@+1 {{'swift_attr' attribute requires a string}}
+__attribute__((swift_attr(1)))
+@interface J
+@end
Index: clang/test/AST/attr-swift_attr.m
===================================================================
--- /dev/null
+++ clang/test/AST/attr-swift_attr.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
+
+__attribute__((swift_attr("@actor")))
+@interface View
+@end
+
+// CHECK: InterfaceDecl {{.*}} View
+// CHECK-NEXT: SwiftAttrAttr {{.*}} "@actor"
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -5607,6 +5607,16 @@
   D->addAttr(::new (S.Context) ObjCPreciseLifetimeAttr(S.Context, AL));
 }
 
+static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  // Make sure that there is a string literal as the annotation's single
+  // argument.
+  StringRef Str;
+  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
+    return;
+
+  D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
+}
+
 static void handleSwiftBridge(Sema &S, Decl *D, const ParsedAttr &AL) {
   // Make sure that there is a string literal as the annotation's single
   // argument.
@@ -7941,6 +7951,9 @@
     break;
 
   // Swift attributes.
+  case ParsedAttr::AT_SwiftAttr:
+    handleSwiftAttrAttr(S, D, AL);
+    break;
   case ParsedAttr::AT_SwiftBridge:
     handleSwiftBridge(S, D, AL);
     break;
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -3628,6 +3628,18 @@
   }];
 }
 
+def SwiftAttrDocs : Documentation {
+  let Category = SwiftDocs;
+  let Heading = "swift_attr";
+  let Content = [{
+The ``swift_attr`` provides a Swift-specific annotation for the declaration
+to which the attribute appertains to. This kind of annotation is ignored by
+clang as it doesn't have any semantic meaning in languages supported by clang.
+The Swift compiler can interpret these annotations according to its own rules
+when importing C or Objective-C declarations.
+}];
+}
+
 def SwiftBridgeDocs : Documentation {
   let Category = SwiftDocs;
   let Heading = "swift_bridge";
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -2149,6 +2149,12 @@
   let ASTNode = 0;
 }
 
+def SwiftAttr : InheritableAttr {
+  let Spellings = [Clang<"swift_attr">];
+  let Args = [StringArgument<"Attribute">];
+  let Documentation = [SwiftAttrDocs];
+}
+
 def SwiftBridge : InheritableAttr {
   let Spellings = [GNU<"swift_bridge">];
   let Args = [StringArgument<"SwiftType">];


Index: clang/test/SemaObjC/validate-attr-swift_attr.m
===================================================================
--- /dev/null
+++ clang/test/SemaObjC/validate-attr-swift_attr.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+// expected-error@+1 {{'swift_attr' attribute takes one argument}}
+__attribute__((swift_attr))
+@interface I
+@end
+
+// expected-error@+1 {{'swift_attr' attribute requires a string}}
+__attribute__((swift_attr(1)))
+@interface J
+@end
Index: clang/test/AST/attr-swift_attr.m
===================================================================
--- /dev/null
+++ clang/test/AST/attr-swift_attr.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
+
+__attribute__((swift_attr("@actor")))
+@interface View
+@end
+
+// CHECK: InterfaceDecl {{.*}} View
+// CHECK-NEXT: SwiftAttrAttr {{.*}} "@actor"
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -5607,6 +5607,16 @@
   D->addAttr(::new (S.Context) ObjCPreciseLifetimeAttr(S.Context, AL));
 }
 
+static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  // Make sure that there is a string literal as the annotation's single
+  // argument.
+  StringRef Str;
+  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
+    return;
+
+  D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
+}
+
 static void handleSwiftBridge(Sema &S, Decl *D, const ParsedAttr &AL) {
   // Make sure that there is a string literal as the annotation's single
   // argument.
@@ -7941,6 +7951,9 @@
     break;
 
   // Swift attributes.
+  case ParsedAttr::AT_SwiftAttr:
+    handleSwiftAttrAttr(S, D, AL);
+    break;
   case ParsedAttr::AT_SwiftBridge:
     handleSwiftBridge(S, D, AL);
     break;
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -3628,6 +3628,18 @@
   }];
 }
 
+def SwiftAttrDocs : Documentation {
+  let Category = SwiftDocs;
+  let Heading = "swift_attr";
+  let Content = [{
+The ``swift_attr`` provides a Swift-specific annotation for the declaration
+to which the attribute appertains to. This kind of annotation is ignored by
+clang as it doesn't have any semantic meaning in languages supported by clang.
+The Swift compiler can interpret these annotations according to its own rules
+when importing C or Objective-C declarations.
+}];
+}
+
 def SwiftBridgeDocs : Documentation {
   let Category = SwiftDocs;
   let Heading = "swift_bridge";
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -2149,6 +2149,12 @@
   let ASTNode = 0;
 }
 
+def SwiftAttr : InheritableAttr {
+  let Spellings = [Clang<"swift_attr">];
+  let Args = [StringArgument<"Attribute">];
+  let Documentation = [SwiftAttrDocs];
+}
+
 def SwiftBridge : InheritableAttr {
   let Spellings = [GNU<"swift_bridge">];
   let Args = [StringArgument<"SwiftType">];
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to