plotfi created this revision.
plotfi added a reviewer: arphaman.
Herald added a reviewer: aaron.ballman.
Herald added a project: All.
plotfi requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

This is just experimental for the time being. Posting to phab to get some 
comments.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128249

Files:
  clang/include/clang/Basic/Attr.td
  clang/include/clang/Basic/AttrDocs.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/AST/attr-swift_bridge.m

Index: clang/test/AST/attr-swift_bridge.m
===================================================================
--- clang/test/AST/attr-swift_bridge.m
+++ clang/test/AST/attr-swift_bridge.m
@@ -1,11 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
 
-struct __attribute__((__swift_bridge__("BridgedS"))) S;
-// CHECK: RecordDecl {{.*}} struct S
-// CHECK: SwiftBridgeAttr {{.*}} "BridgedS"
+int XXXX;
 
-struct S {
-};
-
-// CHECK: RecordDecl {{.*}} struct S definition
-// CHECK: SwiftBridgeAttr {{.*}} Inherited "BridgedS"
+struct __attribute__((__clone_attrs_from__(XXXX))) S;
\ No newline at end of file
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -3300,6 +3300,37 @@
   D->addAttr(::new (S.Context) MinVectorWidthAttr(S.Context, AL, VecWidth));
 }
 
+static void handleCloneAttrsFrom(Sema &S, Decl *D, const ParsedAttr &AL) {
+
+  if (AL.getNumArgs() != 1) {
+    S.Diag(D->getLocation(), diag::err_attribute_clone_attrs_from_arg_not_named_decl) << 0;
+    return;
+  }
+
+  Expr *E = AL.getArgAsExpr(0);
+  SourceLocation Loc = E->getExprLoc();
+
+  auto *DRE = dyn_cast<DeclRefExpr>(E);
+  if (!DRE) {
+    S.Diag(Loc, diag::err_attribute_clone_attrs_from_arg_not_named_decl) << 0;
+    return;
+  }
+
+  if (DRE->hasQualifier())
+    S.Diag(Loc, diag::warn_clone_attrs_from_ext);
+
+  NamedDecl *ND = dyn_cast<NamedDecl>(DRE->getDecl());
+  if (!ND) {
+    DeclarationNameInfo NI = DRE->getNameInfo();
+    S.Diag(Loc, diag::err_attribute_clone_attrs_from_arg_not_named_decl)
+        << 1 << NI.getName();
+    return;
+  }
+
+  ND->addAttr(::new (S.Context) CloneAttrsFromAttr(S.Context, AL, ND));
+  D->addAttr(::new (S.Context) CloneAttrsFromAttr(S.Context, AL, ND));
+}
+
 static void handleCleanupAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   Expr *E = AL.getArgAsExpr(0);
   SourceLocation Loc = E->getExprLoc();
@@ -8486,6 +8517,10 @@
     handleSwiftAsyncError(S, D, AL);
     break;
 
+  case ParsedAttr::AT_CloneAttrsFrom:
+    handleCloneAttrsFrom(S, D, AL);
+    break;
+
   // XRay attributes.
   case ParsedAttr::AT_XRayLogArgs:
     handleXRayLogArgsAttr(S, D, AL);
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4091,6 +4091,12 @@
   "'sentinel' parameter 1 less than zero">;
 def err_attribute_sentinel_not_zero_or_one : Error<
   "'sentinel' parameter 2 not 0 or 1">;
+def err_attribute_clone_attrs_from_arg_not_named_decl : Error<
+  "'clone_attrs_from' argument %select{|%1 |%1 }0is not a %select{||single }0named decl">;
+def warn_clone_attrs_from_ext : Warning<
+  "Clang does not allow the 'clone_attrs_from' attribute argument to be anything other "
+  "than a simple identifier">,
+  InGroup<GccCompat>;
 def warn_cleanup_ext : Warning<
   "GCC does not allow the 'cleanup' attribute argument to be anything other "
   "than a simple identifier">,
Index: clang/include/clang/Basic/AttrDocs.td
===================================================================
--- clang/include/clang/Basic/AttrDocs.td
+++ clang/include/clang/Basic/AttrDocs.td
@@ -4186,6 +4186,15 @@
   }];
 }
 
+def CloneAttrsFromDocs : Documentation {
+  let Category = DocCatDecl;
+  let Heading = "clone_attrs_from";
+  let Content = [{
+The ``clone_attrs_from`` attribute indicates that the declaration to which the
+attribute appertains contains the same attributes as another named decl.
+  }];
+}
+
 def OMPDeclareSimdDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "#pragma omp declare simd";
Index: clang/include/clang/Basic/Attr.td
===================================================================
--- clang/include/clang/Basic/Attr.td
+++ clang/include/clang/Basic/Attr.td
@@ -2414,6 +2414,14 @@
   let SimpleHandler = 1;
 }
 
+def CloneAttrsFrom : InheritableAttr {
+  let Spellings = [GNU<"clone_attrs_from">];
+  let Args = [DeclArgument<Named, "from">];
+  let Subjects = SubjectList<[Tag, TypedefName],
+                             ErrorDiag>;
+  let Documentation = [CloneAttrsFromDocs];
+}
+
 def NoDeref : TypeAttr {
   let Spellings = [Clang<"noderef">];
   let Documentation = [NoDerefDocs];
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to