r194633 - ObjectiveC ARC. Introduce a new attribute, 'objc_bridge'

Fariborz Jahanian fjahanian at apple.com
Wed Nov 13 15:59:17 PST 2013


Author: fjahanian
Date: Wed Nov 13 17:59:17 2013
New Revision: 194633

URL: http://llvm.org/viewvc/llvm-project?rev=194633&view=rev
Log:
ObjectiveC ARC. Introduce a new attribute, 'objc_bridge'
that teaches the compiler about a subset of toll-free 
bridging semantics. This is wip. // rdar://15454846

Added:
    cfe/trunk/test/SemaObjC/objcbridge-attribute.m
Modified:
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=194633&r1=194632&r2=194633&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Nov 13 17:59:17 2013
@@ -542,6 +542,12 @@ def NSBridged : InheritableAttr {
   let Args = [IdentifierArgument<"BridgedType", 1>];
 }
 
+def ObjCBridge : InheritableAttr {
+  let Spellings = [GNU<"objc_bridge">];
+  let Subjects = [Record];
+  let Args = [IdentifierArgument<"BridgedType", 1>];
+}
+
 def NSReturnsRetained : InheritableAttr {
   let Spellings = [GNU<"ns_returns_retained">];
   let Subjects = [ObjCMethod, Function];

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=194633&r1=194632&r2=194633&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Nov 13 17:59:17 2013
@@ -2435,8 +2435,18 @@ def warn_objc_requires_super_protocol :
 def note_protocol_decl : Note<
   "protocol is declared here">;
 
+// objc_bridge attribute diagnostics.
 def err_ns_bridged_not_interface : Error<
   "parameter of 'ns_bridged' attribute does not name an Objective-C class">;
+def err_objc_bridge_not_id : Error<
+  "parameter of 'objc_bridge' attribute must be a single name of an Objective-C class">;
+def err_objc_bridge_attribute : Error<
+  "'objc_bridge' attribute must be put on a typedef only">;
+def err_objc_bridge_not_cftype : Error<
+  "'objc_bridge' attribute must be applied to definition of CF types">;
+  
+def err_objc_bridge_not_pointertype : Error<
+  "'objc_bridge' attribute must be applied to a pointer type">;
 
 // Function Parameter Semantic Analysis.
 def err_param_with_void_type : Error<"argument may not have 'void' type">;

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=194633&r1=194632&r2=194633&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Nov 13 17:59:17 2013
@@ -207,6 +207,12 @@ static inline bool isCFStringType(QualTy
   return RD->getIdentifier() == &Ctx.Idents.get("__CFString");
 }
 
+static inline bool isCFRefType(TypedefNameDecl *TD, ASTContext &Ctx) {
+  StringRef TDName = TD->getIdentifier()->getName();
+  return ((TDName.startswith("CF") || TDName.startswith("CG")) &&
+          (TDName.rfind("Ref") != StringRef::npos));
+}
+
 static unsigned getNumAttributeArgs(const AttributeList &Attr) {
   // FIXME: Include the type in the argument list.
   return Attr.getNumArgs() + Attr.hasParsedType();
@@ -4389,6 +4395,50 @@ static void handleNSBridgedAttr(Sema &S,
                            Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleObjCBridgeAttr(Sema &S, Scope *Sc, Decl *D,
+                                const AttributeList &Attr) {
+  if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+    QualType T = TD->getUnderlyingType();
+    if (T->isPointerType()) {
+      T = T->getPointeeType();
+      if (T->isRecordType()) {
+        RecordDecl *RD = T->getAs<RecordType>()->getDecl();
+        if (!RD || RD->isUnion()) {
+          S.Diag(D->getLocStart(), diag::err_attribute_wrong_decl_type)
+          << Attr.getRange() << Attr.getName() << ExpectedStruct;
+          return;
+        }
+      }
+    } else {
+      S.Diag(TD->getLocStart(), diag::err_objc_bridge_not_pointertype);
+      return;
+    }
+    // Check for T being a CFType goes here.
+    if (!isCFRefType(TD, S.Context)) {
+      S.Diag(TD->getLocStart(), diag::err_objc_bridge_not_cftype);
+      return;
+    }
+  }
+  else {
+    S.Diag(D->getLocStart(), diag::err_objc_bridge_attribute);
+    return;
+  }
+  
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id);
+    return;
+  }
+  IdentifierLoc *Parm = Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : 0;
+  if (!Parm) {
+    S.Diag(D->getLocStart(), diag::err_objc_bridge_not_id);
+    return;
+  }
+  
+  D->addAttr(::new (S.Context)
+             ObjCBridgeAttr(Attr.getRange(), S.Context, Parm ? Parm->Ident : 0,
+                           Attr.getAttributeSpellingListIndex()));
+}
+
 static void handleObjCOwnershipAttr(Sema &S, Decl *D,
                                     const AttributeList &Attr) {
   if (hasDeclarator(D)) return;
@@ -4675,6 +4725,9 @@ static void ProcessDeclAttribute(Sema &S
       
   case AttributeList::AT_NSBridged:
     handleNSBridgedAttr(S, scope, D, Attr); break;
+      
+  case AttributeList::AT_ObjCBridge:
+    handleObjCBridgeAttr(S, scope, D, Attr); break;
 
   case AttributeList::AT_CFAuditedTransfer:
   case AttributeList::AT_CFUnknownTransfer:

Added: cfe/trunk/test/SemaObjC/objcbridge-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objcbridge-attribute.m?rev=194633&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/objcbridge-attribute.m (added)
+++ cfe/trunk/test/SemaObjC/objcbridge-attribute.m Wed Nov 13 17:59:17 2013
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://15454846
+
+typedef struct CGColor * __attribute__ ((objc_bridge(NSError))) CGColorRef;
+
+typedef struct CGColor * __attribute__((objc_bridge(12))) CFMyColorRef; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
+
+typedef struct S1 *  __attribute__ ((objc_bridge)) CGColorRef1; // expected-error {{parameter of 'objc_bridge' attribute must be a single name of an Objective-C class}}
+
+typedef void *  __attribute__ ((objc_bridge(NSString))) CGColorRef2; 
+
+typedef void * CFTypeRef __attribute__ ((objc_bridge(NSError)));
+
+typedef struct CGColor * __attribute__((objc_bridge(NSString, NSError))) CGColorRefNoNSObject;// expected-error {{use of undeclared identifier 'NSError'}}
+
+typedef struct CGColor __attribute__((objc_bridge(NSError))) CGColorRefNoNSObject2; // expected-error {{'objc_bridge' attribute must be applied to a pointer type}}
+
+typedef struct __attribute__((objc_bridge(NSError))) CFColor * CFColorRefNoNSObject; // expected-error {{'objc_bridge' attribute must be put on a typedef only}}
+
+typedef struct __attribute__((objc_bridge(NSError))) CFColor * CFColorRefNoNSObject1;
+
+typedef union CFUColor * __attribute__((objc_bridge(NSError))) CFColorRefNoNSObject2; // expected-error {{'objc_bridge' attribute only applies to structs}}
+
+ at interface I
+{
+   __attribute__((objc_bridge(NSError))) void * color; // expected-error {{'objc_bridge' attribute must be put on a typedef only}}
+
+}
+ at end





More information about the cfe-commits mailing list