r196629 - ObjectiveC. Continuing implementation of objc_bridge_related
Fariborz Jahanian
fjahanian at apple.com
Fri Dec 6 16:34:23 PST 2013
Author: fjahanian
Date: Fri Dec 6 18:34:23 2013
New Revision: 196629
URL: http://llvm.org/viewvc/llvm-project?rev=196629&view=rev
Log:
ObjectiveC. Continuing implementation of objc_bridge_related
attribute in sema and issuing a variety of diagnostics lazily
for misuse of this attribute (and what to do) when converting
from CF types to ObjectiveC types (and vice versa).
// rdar://15499111
Added:
cfe/trunk/test/SemaObjC/arc-objcbridge-related-attribute.m
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
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=196629&r1=196628&r2=196629&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Dec 6 18:34:23 2013
@@ -2468,6 +2468,23 @@ def warn_objc_invalid_bridge : Warning<
def warn_objc_invalid_bridge_to_cf : Warning<
"%0 cannot bridge to %1">, InGroup<ObjCBridge>;
+// objc_bridge_related attribute diagnostics.
+def err_objc_bridged_related_invalid_class : Error<
+ "could not find ObjectiveC 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">;
+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">;
+
// Function Parameter Semantic Analysis.
def err_param_with_void_type : Error<"argument may not have 'void' type">;
def err_void_only_param : Error<
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=196629&r1=196628&r2=196629&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Dec 6 18:34:23 2013
@@ -6908,6 +6908,17 @@ public:
void CheckTollFreeBridgeCast(QualType castType, Expr *castExpr);
+ bool checkObjCBridgeRelatedComponents(SourceLocation Loc,
+ QualType DestType, QualType SrcType,
+ ObjCInterfaceDecl *&RelatedClass,
+ ObjCMethodDecl *&ClassMethod,
+ ObjCMethodDecl *&InstanceMethod,
+ TypedefNameDecl *&TDNDecl,
+ bool CfToNs);
+
+ bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
+ QualType DestType, QualType SrcType);
+
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
/// \brief Check whether the given new method is a valid override of the
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=196629&r1=196628&r2=196629&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Dec 6 18:34:23 2013
@@ -10639,6 +10639,9 @@ bool Sema::DiagnoseAssignmentResult(Assi
MayHaveConvFixit = true;
break;
case IncompatiblePointer:
+ if (getLangOpts().ObjC1 &&
+ CheckObjCBridgeRelatedConversions(Loc, DstType, SrcType))
+ return false;
MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint, IsNSString);
DiagKind =
(Action == AA_Passing_CFAudited ?
@@ -10718,6 +10721,9 @@ bool Sema::DiagnoseAssignmentResult(Assi
DiagKind = diag::err_arc_weak_unavailable_assign;
break;
case Incompatible:
+ if (getLangOpts().ObjC1 &&
+ CheckObjCBridgeRelatedConversions(Loc, DstType, SrcType))
+ return true;
DiagKind = diag::err_typecheck_convert_incompatible;
ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this);
MayHaveConvFixit = true;
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=196629&r1=196628&r2=196629&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Dec 6 18:34:23 2013
@@ -3341,6 +3341,120 @@ void Sema::CheckTollFreeBridgeCast(QualT
}
}
+
+bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
+ QualType DestType, QualType SrcType,
+ ObjCInterfaceDecl *&RelatedClass,
+ ObjCMethodDecl *&ClassMethod,
+ ObjCMethodDecl *&InstanceMethod,
+ 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
+ << 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
+ << SrcType << DestType;
+ 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 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;
+ }
+ T = TDNDecl->getUnderlyingType();
+ }
+ return false;
+}
+
+bool
+Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
+ QualType DestType, QualType SrcType) {
+ ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
+ ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
+ bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
+ bool NsToCf = (rhsExprACTC == ACTC_retainable && lhsExprACTC == ACTC_coreFoundation);
+ if (!CfToNs && !NsToCf)
+ return false;
+
+ ObjCInterfaceDecl *RelatedClass;
+ ObjCMethodDecl *ClassMethod = 0;
+ ObjCMethodDecl *InstanceMethod = 0;
+ TypedefNameDecl *TDNDecl = 0;
+ if (!checkObjCBridgeRelatedComponents(Loc, DestType, SrcType, RelatedClass,
+ ClassMethod, InstanceMethod, TDNDecl, CfToNs))
+ return false;
+
+ if (CfToNs) {
+ // Implicit conversion from CF to ObjC object is needed.
+ if (ClassMethod)
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << ClassMethod->getSelector() << 0;
+ else
+ Diag(Loc, diag::err_objc_bridged_related_unknown_method)
+ << SrcType << DestType << RelatedClass->getName() << 0;
+ Diag(RelatedClass->getLocStart(), diag::note_declared_at);
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
+ else {
+ // Implicit conversion from ObjC type to CF object is needed.
+ if (InstanceMethod)
+ Diag(Loc, diag::err_objc_bridged_related_known_method)
+ << SrcType << DestType << InstanceMethod->getSelector() << 1;
+ else
+ Diag(Loc, diag::err_objc_bridged_related_unknown_method)
+ << SrcType << DestType << RelatedClass->getName() << 1;
+ Diag(RelatedClass->getLocStart(), diag::note_declared_at);
+ Diag(TDNDecl->getLocStart(), diag::note_declared_at);
+ }
+
+ return true;
+}
+
Sema::ARCConversionResult
Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
Expr *&castExpr, CheckedConversionKind CCK,
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=196629&r1=196628&r2=196629&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Dec 6 18:34:23 2013
@@ -6482,6 +6482,9 @@ bool InitializationSequence::Diagnose(Se
case FK_ConversionFailed: {
QualType FromType = Args[0]->getType();
+ if (S.getLangOpts().ObjC1)
+ S.CheckObjCBridgeRelatedConversions(Kind.getLocation(),
+ DestType, FromType);
PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed)
<< (int)Entity.getKind()
<< DestType
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=196629&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-objcbridge-related-attribute.m (added)
+++ cfe/trunk/test/SemaObjC/arc-objcbridge-related-attribute.m Fri Dec 6 18:34:23 2013
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -verify -fobjc-arc -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}} \
+ // expected-error {{implicit conversion of C pointer type 'CGColorRef' (aka 'struct CGColor *') to Objective-C pointer type 'NSColor *' 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 'CGColorRef' (aka 'struct CGColor *') into ARC}}
+ textField.backgroundColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *__strong', use 'colorWithCGColor:' method for this conversion}} \
+ // expected-error {{implicit conversion of C pointer type 'CGColorRef' (aka 'struct CGColor *') to Objective-C pointer type 'NSColor *' 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 'CGColorRef' (aka 'struct CGColor *') into ARC}}
+ return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *', use 'colorWithCGColor:' method for this conversion}} \
+ // expected-error {{implicit conversion of C pointer type 'CGColorRef' (aka 'struct CGColor *') to Objective-C pointer type 'NSColor *' 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 'CGColorRef' (aka 'struct CGColor *') into ARC}}
+}
+
+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}} \
+ // expected-error {{implicit conversion of C pointer type 'CGColorRef1' (aka 'struct CGColor1 *') to Objective-C pointer type 'NSColor *' 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 'CGColorRef1' (aka 'struct CGColor1 *') into ARC}}
+ textField.backgroundColor = newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') must be explicitly converted to 'NSColor *__strong', define and then use a singular class method in NSColor for this conversion}} \
+ // expected-error {{implicit conversion of C pointer type 'CGColorRef1' (aka 'struct CGColor1 *') to Objective-C pointer type 'NSColor *' 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 'CGColorRef1' (aka 'struct CGColor1 *') into ARC}}
+ 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}} \
+ // expected-error {{implicit conversion of C pointer type 'CGColorRef1' (aka 'struct CGColor1 *') to Objective-C pointer type 'NSColor *' 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 'CGColorRef1' (aka 'struct CGColor1 *') into ARC}}
+}
+
+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}} \
+ // expected-error {{implicit conversion of Objective-C pointer type 'NSColor *' to C pointer type 'CGColorRef' (aka 'struct CGColor *') requires a bridged cast}} \
+ // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CGColorRef' (aka 'struct CGColor *')}}
+ return textField.backgroundColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'), use 'CGColor' method for this conversion}} \
+ // expected-error {{implicit conversion of Objective-C pointer type 'NSColor *' to C pointer type 'CGColorRef' (aka 'struct CGColor *') requires a bridged cast}} \
+ // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CGColorRef' (aka 'struct CGColor *')}}
+}
+
+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}} \
+ // expected-error {{implicit conversion of Objective-C pointer type 'NSColor *' to C pointer type 'CGColorRef2' (aka 'struct CGColor2 *') requires a bridged cast}} \
+ // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CGColorRef2' (aka 'struct CGColor2 *')}}
+ 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}} \
+ // expected-error {{implicit conversion of Objective-C pointer type 'NSColor *' to C pointer type 'CGColorRef2' (aka 'struct CGColor2 *') requires a bridged cast}} \
+ // expected-note {{use __bridge to convert directly (no change in ownership)}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CGColorRef2' (aka 'struct CGColor2 *')}}
+}
Added: 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=196629&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/check-objcbridge-related-attribute-lookup.m (added)
+++ cfe/trunk/test/SemaObjC/check-objcbridge-related-attribute-lookup.m Fri Dec 6 18:34:23 2013
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -verify -Wno-objc-root-class %s
+// rdar://15499111
+
+typedef struct __attribute__((objc_bridge_related(NSColor,colorXWithCGColor:,CXGColor))) CGColor *CGColorRef; // expected-note 2 {{declared here}}
+
+typedef struct __attribute__((objc_bridge_related(XNSColor,colorWithCGColor:,CGColor))) CGColor1 *CGColorRef1; // expected-note 2 {{declared here}}
+
+typedef struct __attribute__((objc_bridge_related(PNsColor,colorWithCGColor:,CGColor))) CGColor2 *CGColorRef2; // expected-note 2 {{declared here}}
+
+ at interface NSColor
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+ at end
+
+ at interface NSTextField
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+ at end
+
+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}} \
+ // 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}} \
+ // 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 *'}} \
+ // 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 *')}} \
+ // 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 *'}} \
+ // 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 *')}} \
+ // expected-warning {{incompatible pointer types assigning to 'CGColorRef2' (aka 'struct CGColor2 *') from 'NSColor *'}}
+}
+
Added: cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m?rev=196629&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m (added)
+++ cfe/trunk/test/SemaObjC/objcbridge-related-attribute.m Fri Dec 6 18:34:23 2013
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c -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 *', 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}}
+}
+
+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 {{'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}}
+}
Added: cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm?rev=196629&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm (added)
+++ cfe/trunk/test/SemaObjCXX/objcbridge-related-attribute.mm Fri Dec 6 18:34:23 2013
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -x objective-c++ -verify -Wno-objc-root-class %s
+// rdar://15499111
+typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef; // expected-note 6 {{declared here}}
+
+ at interface NSColor // expected-note 6 {{declared here}}
++ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
+- (CGColorRef)CGColor;
+ at end
+
+ at interface NSTextField
+- (void)setBackgroundColor:(NSColor *)color;
+- (NSColor *)backgroundColor;
+ at end
+
+
+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}} \
+ // 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}} \
+ // 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}} \
+ // 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}}\
+ // 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