[Objective-C]. This patch extends objc_bridge attribute to support objc_bridge(id).
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 11 Dec 2014 22:56:26 +0000 (22:56 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 11 Dec 2014 22:56:26 +0000 (22:56 +0000)
This means that a pointer to the struct type to which the attribute appertains
is a CF type (and therefore an Objective-C object of some type), but not of any
specific class. rdar://19157264

llvm-svn: 224072

clang/lib/Lex/PPMacroExpansion.cpp
clang/lib/Sema/SemaExprObjC.cpp
clang/test/SemaObjC/objcbridge-attribute-arc.m

index b402a93..d9a7f39 100644 (file)
@@ -912,6 +912,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
       .Case("objc_dictionary_literals", LangOpts.ObjC2)
       .Case("objc_boxed_expressions", LangOpts.ObjC2)
       .Case("arc_cf_code_audited", true)
+      .Case("objc_bridge_id", LangOpts.ObjC2)
       // C11 features
       .Case("c_alignas", LangOpts.C11)
       .Case("c_alignof", LangOpts.C11)
index eeee352..79f7d92 100644 (file)
@@ -3404,6 +3404,9 @@ static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr,
     if (TB *ObjCBAttr = getObjCBridgeAttr<TB>(TD)) {
       if (IdentifierInfo *Parm = ObjCBAttr->getBridgedType()) {
         HadTheAttribute = true;
+        if (Parm->isStr("id"))
+          return true;
+        
         NamedDecl *Target = nullptr;
         // Check for an existing type with this name.
         LookupResult R(S, DeclarationName(Parm), SourceLocation(),
index ee2bf07..ab8cab8 100644 (file)
@@ -221,3 +221,19 @@ void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2
   (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}}
   (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
 }
+
+// rdar://19157264
+#if __has_feature(objc_bridge_id)
+typedef struct __attribute__((objc_bridge(id))) __CFFoo *CFFooRef;
+#endif
+
+id convert(CFFooRef obj) {
+  (void)(NSError *)obj; // expected-error {{cast of C pointer type 'CFFooRef' (aka 'struct __CFFoo *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
+                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFFooRef' (aka 'struct __CFFoo *') into ARC}}
+  (void) (__bridge NSError *)obj;
+  (void) (id)obj;       // expected-error {{cast of C pointer type 'CFFooRef' (aka 'struct __CFFoo *') to Objective-C pointer type 'id' requires a bridged cast}} \
+                        // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+                        // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFFooRef' (aka 'struct __CFFoo *') into ARC}}
+  return (__bridge id)obj;
+}