r196828 - Objective-C: Improve on various diagnostics related to

Fariborz Jahanian fjahanian at apple.com
Mon Dec 9 14:04:27 PST 2013


Author: fjahanian
Date: Mon Dec  9 16:04:26 2013
New Revision: 196828

URL: http://llvm.org/viewvc/llvm-project?rev=196828&view=rev
Log:
Objective-C: Improve on various diagnostics related to
use of objc_bridge_related attribute. // rdar://15499111


Added:
    cfe/trunk/test/SemaObjC/arc-objcbridge-related-attribute.m
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/SemaObjC/check-objcbridge-related-attribute-lookup.m
    cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m
    cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=196828&r1=196827&r2=196828&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Dec  9 16:04:26 2013
@@ -2468,20 +2468,15 @@ def warn_objc_invalid_bridge_to_cf : War
 
 // objc_bridge_related attribute diagnostics.
 def err_objc_bridged_related_invalid_class : Error<
-  "could not find ObjectiveC class %0 to convert %1 to %2">;
+  "could not find Objective-C class %0 to convert %1 to %2">;
 def err_objc_bridged_related_invalid_class_name : Error<
-  "%0 must be name of an ObjectiveC class to be able to convert %1 to %2">;
-def err_objc_bridged_related_class_method : Error<
-  "class method %0 for conversion of CF type %1 to an "
- "ObjectiveC object of type %2 not found">;
-def err_objc_bridged_related_instance_method : Error<
-  "instance method %0 for conversion of an ObjectiveC type %1 to a CF "
- "object  of type %2 not found">;
+  "%0 must be name of an Objective-C class to be able to convert %1 to %2">;
+ def err_objc_bridged_related_unknown_method : Error<
+ "you can't convert %0 to %1, without using an existing "
+ "%select{class|instance}2 method for this conversion">;
 def err_objc_bridged_related_known_method : Error<
- "%0 must be explicitly converted to %1, use %2 method for this conversion">;
-def err_objc_bridged_related_unknown_method : Error<
- "%0 must be explicitly converted to %1, define and then use "
- "%select{a singular class|an instance}3 method in %2 for this conversion">;
+ "%0 must be explicitly converted to %1; use %select{%objcclass2|%objcinstance2}3 "
+ "method for this conversion">;
   
 // Function Parameter Semantic Analysis.
 def err_param_with_void_type : Error<"argument may not have 'void' type">;

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=196828&r1=196827&r2=196828&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Dec  9 16:04:26 2013
@@ -3084,6 +3084,32 @@ static void addFixitForObjCARCConversion
   }
 }
 
+template <typename T>
+static inline T *getObjCBridgeAttr(const TypedefType *TD) {
+  TypedefNameDecl *TDNDecl = TD->getDecl();
+  QualType QT = TDNDecl->getUnderlyingType();
+  if (QT->isPointerType()) {
+    QT = QT->getPointeeType();
+    if (const RecordType *RT = QT->getAs<RecordType>())
+      if (RecordDecl *RD = RT->getDecl())
+        if (RD->hasAttr<T>())
+          return RD->getAttr<T>();
+  }
+  return 0;
+}
+
+static ObjCBridgeRelatedAttr *ObjCBridgeRelatedAttrFromType(QualType T,
+                                                            TypedefNameDecl *&TDNDecl) {
+  while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
+    TDNDecl = TD->getDecl();
+    if (ObjCBridgeRelatedAttr *ObjCBAttr =
+        getObjCBridgeAttr<ObjCBridgeRelatedAttr>(TD))
+      return ObjCBAttr;
+    T = TDNDecl->getUnderlyingType();
+  }
+  return 0;
+}
+
 static void
 diagnoseObjCARCConversion(Sema &S, SourceRange castRange,
                           QualType castType, ARCConversionTypeClass castACTC,
@@ -3098,6 +3124,12 @@ diagnoseObjCARCConversion(Sema &S, Sourc
     return;
 
   QualType castExprType = castExpr->getType();
+  TypedefNameDecl *TDNDecl = 0;
+  if ((castACTC == ACTC_coreFoundation &&  exprACTC == ACTC_retainable &&
+       ObjCBridgeRelatedAttrFromType(castType, TDNDecl)) ||
+      (exprACTC == ACTC_coreFoundation && castACTC == ACTC_retainable &&
+       ObjCBridgeRelatedAttrFromType(castExprType, TDNDecl)))
+    return;
   
   unsigned srcKind = 0;
   switch (exprACTC) {
@@ -3204,20 +3236,6 @@ diagnoseObjCARCConversion(Sema &S, Sourc
     << castRange << castExpr->getSourceRange();
 }
 
-template <typename T>
-static inline T *getObjCBridgeAttr(const TypedefType *TD) {
-  TypedefNameDecl *TDNDecl = TD->getDecl();
-  QualType QT = TDNDecl->getUnderlyingType();
-  if (QT->isPointerType()) {
-    QT = QT->getPointeeType();
-    if (const RecordType *RT = QT->getAs<RecordType>())
-      if (RecordDecl *RD = RT->getDecl())
-        if (RD->hasAttr<T>())
-          return RD->getAttr<T>();
-  }
-  return 0;
-}
-
 template <typename TB>
 static bool CheckObjCBridgeNSCast(Sema &S, QualType castType, Expr *castExpr) {
   QualType T = castExpr->getType();
@@ -3350,65 +3368,61 @@ bool Sema::checkObjCBridgeRelatedCompone
                                             TypedefNameDecl *&TDNDecl,
                                             bool CfToNs) {
   QualType T = CfToNs ? SrcType : DestType;
-  while (const TypedefType *TD = dyn_cast<TypedefType>(T.getTypePtr())) {
-    TDNDecl = TD->getDecl();
-    if (ObjCBridgeRelatedAttr *ObjCBAttr =
-          getObjCBridgeAttr<ObjCBridgeRelatedAttr>(TD)) {
-      IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();
-      IdentifierInfo *CMId = ObjCBAttr->getClassMethod();
-      IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();
-      if (!RCId)
-        return false;
-      NamedDecl *Target = 0;
-      // Check for an existing type with this name.
-      LookupResult R(*this, DeclarationName(RCId), SourceLocation(),
-                     Sema::LookupOrdinaryName);
-      if (!LookupName(R, TUScope)) {
-        Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
+  ObjCBridgeRelatedAttr *ObjCBAttr = ObjCBridgeRelatedAttrFromType(T, TDNDecl);
+  if (!ObjCBAttr)
+    return false;
+  
+  IdentifierInfo *RCId = ObjCBAttr->getRelatedClass();
+  IdentifierInfo *CMId = ObjCBAttr->getClassMethod();
+  IdentifierInfo *IMId = ObjCBAttr->getInstanceMethod();
+  if (!RCId)
+    return false;
+  NamedDecl *Target = 0;
+  // Check for an existing type with this name.
+  LookupResult R(*this, DeclarationName(RCId), SourceLocation(),
+                 Sema::LookupOrdinaryName);
+  if (!LookupName(R, TUScope)) {
+    Diag(Loc, diag::err_objc_bridged_related_invalid_class) << RCId
           << SrcType << DestType;
-        Diag(TDNDecl->getLocStart(), diag::note_declared_at);
-        return false;
-      }
-      Target = R.getFoundDecl();
-      if (Target && isa<ObjCInterfaceDecl>(Target))
-        RelatedClass = cast<ObjCInterfaceDecl>(Target);
-      else {
-        Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
+    Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+    return false;
+  }
+  Target = R.getFoundDecl();
+  if (Target && isa<ObjCInterfaceDecl>(Target))
+    RelatedClass = cast<ObjCInterfaceDecl>(Target);
+  else {
+    Diag(Loc, diag::err_objc_bridged_related_invalid_class_name) << RCId
           << SrcType << DestType;
-        Diag(TDNDecl->getLocStart(), diag::note_declared_at);
-        if (Target)
-          Diag(Target->getLocStart(), diag::note_declared_at);
-        return false;
-      }
+    Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+    if (Target)
+      Diag(Target->getLocStart(), diag::note_declared_at);
+    return false;
+  }
       
-      // Check for an existing class method with the given selector name.
-      if (CfToNs && CMId) {
-        Selector Sel = Context.Selectors.getUnarySelector(CMId);
-        ClassMethod = RelatedClass->lookupMethod(Sel, false);
-        if (!ClassMethod) {
-          Diag(Loc, diag::err_objc_bridged_related_class_method)
-            << Sel << SrcType << DestType;
-          Diag(TDNDecl->getLocStart(), diag::note_declared_at);
-          return false;
-        }
-      }
+  // Check for an existing class method with the given selector name.
+  if (CfToNs && CMId) {
+    Selector Sel = Context.Selectors.getUnarySelector(CMId);
+    ClassMethod = RelatedClass->lookupMethod(Sel, false);
+    if (!ClassMethod) {
+      Diag(Loc, diag::err_objc_bridged_related_known_method)
+            << SrcType << DestType << Sel << 0;
+      Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+      return false;
+    }
+  }
       
-      // Check for an existing instance method with the given selector name.
-      if (!CfToNs && IMId) {
-        Selector Sel = Context.Selectors.getNullarySelector(IMId);
-        InstanceMethod = RelatedClass->lookupMethod(Sel, true);
-        if (!InstanceMethod) {
-          Diag(Loc, diag::err_objc_bridged_related_instance_method)
-            << Sel << SrcType << DestType;
-          Diag(TDNDecl->getLocStart(), diag::note_declared_at);
-          return false;
-        }
-      }
-      return true;
+  // Check for an existing instance method with the given selector name.
+  if (!CfToNs && IMId) {
+    Selector Sel = Context.Selectors.getNullarySelector(IMId);
+    InstanceMethod = RelatedClass->lookupMethod(Sel, true);
+    if (!InstanceMethod) {
+      Diag(Loc, diag::err_objc_bridged_related_known_method)
+            << SrcType << DestType << Sel << 1;
+      Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+      return false;
     }
-    T = TDNDecl->getUnderlyingType();
   }
-  return false;
+  return true;
 }
 
 bool
@@ -3436,7 +3450,7 @@ Sema::CheckObjCBridgeRelatedConversions(
         << SrcType << DestType << ClassMethod->getSelector() << 0;
     else
       Diag(Loc, diag::err_objc_bridged_related_unknown_method)
-        << SrcType << DestType << RelatedClass->getName() << 0;
+        << SrcType << DestType << 0;
     Diag(RelatedClass->getLocStart(), diag::note_declared_at);
     Diag(TDNDecl->getLocStart(), diag::note_declared_at);
   }
@@ -3447,7 +3461,7 @@ Sema::CheckObjCBridgeRelatedConversions(
       << SrcType << DestType << InstanceMethod->getSelector() << 1;
     else
       Diag(Loc, diag::err_objc_bridged_related_unknown_method)
-      << SrcType << DestType << RelatedClass->getName() << 1;
+        << SrcType << DestType << 1;
     Diag(RelatedClass->getLocStart(), diag::note_declared_at);
     Diag(TDNDecl->getLocStart(), diag::note_declared_at);
   }

Added: cfe/trunk/test/SemaObjC/arc-objcbridge-related-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-objcbridge-related-attribute.m?rev=196828&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-objcbridge-related-attribute.m (added)
+++ cfe/trunk/test/SemaObjC/arc-objcbridge-related-attribute.m Mon Dec  9 16:04:26 2013
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -fobjc-arc -verify -Wno-objc-root-class %s
+// rdar://15499111
+
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 5 {{declared here}}
+typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor1))) CGColor1 *CGColorRef1; // expected-note 3 {{declared here}}
+typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColorRef2; // expected-note 2 {{declared here}}
+
+ at interface NSColor // expected-note 10 {{declared here}}
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+- (CGColorRef1)CGColor1;
+ at end
+
+ at interface NSTextField 
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+ at end
+
+void foo(NSColor*);
+
+NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
+  foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+  textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *__strong'; use '+colorWithCGColor:' method for this conversion}}
+  return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+}
+
+NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
+  foo(newColor); // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}}
+  textField.backgroundColor = newColor;  // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *__strong', without using an existing class method for this conversion}}
+  return newColor;  // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}}
+}
+
+CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
+  newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+  return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+}
+
+CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) {
+  newColor = textField.backgroundColor; // expected-error {{you can't convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *'), without using an existing instance method for this conversion}}
+  return textField.backgroundColor; // expected-error {{you can't convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *'), without using an existing instance method for this conversion}}
+}

Modified: cfe/trunk/test/SemaObjC/check-objcbridge-related-attribute-lookup.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/check-objcbridge-related-attribute-lookup.m?rev=196828&r1=196827&r2=196828&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/check-objcbridge-related-attribute-lookup.m (original)
+++ cfe/trunk/test/SemaObjC/check-objcbridge-related-attribute-lookup.m Mon Dec  9 16:04:26 2013
@@ -20,22 +20,22 @@ typedef struct __attribute__((objc_bridg
 typedef int PNsColor; // expected-note 2 {{declared here}}
 
 NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
- textField.backgroundColor = newColor; // expected-error {{class method 'colorXWithCGColor:' for conversion of CF type 'CGColorRef' (aka 'struct CGColor *') to an ObjectiveC object of type 'NSColor *' not found}} \
+ textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorXWithCGColor:' method for this conversion}} \
 					// expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef' (aka 'struct CGColor *')}}
- newColor = textField.backgroundColor; // expected-error {{instance method 'CXGColor' for conversion of an ObjectiveC type 'NSColor *' to a CF object  of type 'CGColorRef' (aka 'struct CGColor *') not found}} \
+ newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CXGColor' method for this conversion}} \
 					// expected-warning {{incompatible pointer types assigning to 'CGColorRef' (aka 'struct CGColor *') from 'NSColor *'}}
 }
 NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
- textField.backgroundColor = newColor; // expected-error {{could not find ObjectiveC class 'XNSColor' to convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *'}} \
+ textField.backgroundColor = newColor; // expected-error {{could not find Objective-C class 'XNSColor' to convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *'}} \
 				       // expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef1' (aka 'struct CGColor1 *')}}
- newColor = textField.backgroundColor ; // expected-error {{could not find ObjectiveC class 'XNSColor' to convert 'NSColor *' to 'CGColorRef1' (aka 'struct CGColor1 *')}} \
+ newColor = textField.backgroundColor ; // expected-error {{could not find Objective-C class 'XNSColor' to convert 'NSColor *' to 'CGColorRef1' (aka 'struct CGColor1 *')}} \
 					// expected-warning {{incompatible pointer types assigning to 'CGColorRef1' (aka 'struct CGColor1 *') from 'NSColor *'}}
 }
 
 NSColor * Test3(NSTextField *textField, CGColorRef2 newColor) {
- textField.backgroundColor = newColor; // expected-error {{'PNsColor' must be name of an ObjectiveC class to be able to convert 'CGColorRef2' (aka 'struct CGColor2 *') to 'NSColor *'}} \
+ textField.backgroundColor = newColor; // expected-error {{'PNsColor' must be name of an Objective-C class to be able to convert 'CGColorRef2' (aka 'struct CGColor2 *') to 'NSColor *'}} \
 					// expected-warning {{incompatible pointer types assigning to 'NSColor *' from 'CGColorRef2' (aka 'struct CGColor2 *')}}
- newColor = textField.backgroundColor; // expected-error {{'PNsColor' must be name of an ObjectiveC class to be able to convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *')}} \
+ newColor = textField.backgroundColor; // expected-error {{'PNsColor' must be name of an Objective-C class to be able to convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *')}} \
 					// expected-warning {{incompatible pointer types assigning to 'CGColorRef2' (aka 'struct CGColor2 *') from 'NSColor *'}}
 }
 

Modified: cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m?rev=196828&r1=196827&r2=196828&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m (original)
+++ cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m Mon Dec  9 16:04:26 2013
@@ -19,23 +19,23 @@ typedef struct __attribute__((objc_bridg
 void foo(NSColor*);
 
 NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
-  foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}}
-  textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}}
-  return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}}
+  foo(newColor); // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+  textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+  return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
 }
 
 NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
-  foo(newColor); // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *', define and then use a singular class method in NSColor for this conversion}}
-  textField.backgroundColor = newColor;  // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *', define and then use a singular class method in NSColor for this conversion}}
-  return newColor;  // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *', define and then use a singular class method in NSColor for this conversion}}
+  foo(newColor); // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}}
+  textField.backgroundColor = newColor;  // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}}
+  return newColor;  // expected-error {{you can't convert 'CGColorRef1' (aka 'struct CGColor1 *') to 'NSColor *', without using an existing class method for this conversion}}
 }
 
 CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
-  newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'), use 'CGColor' method for this conversion}}
-  return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'), use 'CGColor' method for this conversion}}
+  newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+  return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
 }
 
 CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) {
-  newColor = textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef2' (aka 'struct CGColor2 *'), define and then use an instance method in NSColor for this conversion}}
-  return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef2' (aka 'struct CGColor2 *'), define and then use an instance method in NSColor for this conversion}}
+  newColor = textField.backgroundColor; // expected-error {{you can't convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *'), without using an existing instance method for this conversion}}
+  return textField.backgroundColor; // expected-error {{you can't convert 'NSColor *' to 'CGColorRef2' (aka 'struct CGColor2 *'), without using an existing instance method for this conversion}}
 }

Modified: cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm?rev=196828&r1=196827&r2=196828&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm (original)
+++ cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm Mon Dec  9 16:04:26 2013
@@ -14,18 +14,18 @@ typedef struct __attribute__((objc_bridg
 
 
 NSColor *Test1(NSColor *nsColor, CGColorRef newColor) {
-  nsColor = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}}
-  NSColor *ns = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} \
+  nsColor = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+  NSColor *ns = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} \
 			  // expected-error {{cannot initialize a variable of type 'NSColor *' with an lvalue of type 'CGColorRef' (aka 'CGColor *')}}
-  return newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} \
+  return newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}} \
 		   // expected-error {{cannot initialize return object of type 'NSColor *' with an lvalue of type 'CGColorRef' (aka 'CGColor *')}}
 }
 
 CGColorRef Test2(NSColor *newColor, CGColorRef cgColor) {
-  cgColor = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'), use 'CGColor' method for this conversion}}
-  CGColorRef cg = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'), use 'CGColor' method for this conversion}} \
+  cgColor = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}}
+  CGColorRef cg = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}} \
 			    // expected-error {{cannot initialize a variable of type 'CGColorRef' (aka 'CGColor *') with an lvalue of type 'NSColor *'}}
-  return newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'), use 'CGColor' method for this conversion}}\
+  return newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}}\
 	    	   // expected-error {{cannot initialize return object of type 'CGColorRef' (aka 'CGColor *') with an lvalue of type 'NSColor *'}}
 }
 





More information about the cfe-commits mailing list