ObjectiveC. Further improvements of use

of objc_bridge_related attribute; eliminate
unnecessary diagnostics which is issued elsewhere,
fixit now produces a valid AST tree per convention.
This results in some simplification in handling of
this attribute as well. // rdar://15499111

llvm-svn: 197436
This commit is contained in:
Fariborz Jahanian 2013-12-16 22:54:37 +00:00
parent 04c685b5e4
commit 381edf5759
9 changed files with 63 additions and 52 deletions

View File

@ -2466,8 +2466,6 @@ def err_objc_bridged_related_invalid_class : Error<
"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 Objective-C class to be able to convert %1 to %2">;
def err_objc_bridged_related_unknown_method : Error<
"%0 cannot be directly converted to %1">;
def err_objc_bridged_related_known_method : Error<
"%0 must be explicitly converted to %1; use %select{%objcclass2|%objcinstance2}3 "
"method for this conversion">;

View File

@ -6898,7 +6898,7 @@ public:
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
QualType DestType, QualType SrcType,
Expr *SrcExpr);
Expr *&SrcExpr);
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);

View File

@ -6612,6 +6612,13 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS,
if (getLangOpts().ObjCAutoRefCount)
CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
DiagnoseCFAudited);
if (getLangOpts().ObjC1 &&
CheckObjCBridgeRelatedConversions(E->getLocStart(),
LHSType, E->getType(), E)) {
RHS = Owned(E);
return Compatible;
}
RHS = ImpCastExprToType(E, Ty, Kind);
}
return result;
@ -10648,9 +10655,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
MayHaveConvFixit = true;
break;
case IncompatiblePointer:
if (getLangOpts().ObjC1 &&
CheckObjCBridgeRelatedConversions(Loc, DstType, SrcType, SrcExpr))
return false;
MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint, IsNSString);
DiagKind =
(Action == AA_Passing_CFAudited ?
@ -10730,9 +10734,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
DiagKind = diag::err_arc_weak_unavailable_assign;
break;
case Incompatible:
if (getLangOpts().ObjC1 &&
CheckObjCBridgeRelatedConversions(Loc, DstType, SrcType, SrcExpr))
return true;
DiagKind = diag::err_typecheck_convert_incompatible;
ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this);
MayHaveConvFixit = true;

View File

@ -3431,7 +3431,7 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
bool
Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
QualType DestType, QualType SrcType,
Expr *SrcExpr) {
Expr *&SrcExpr) {
ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
@ -3460,12 +3460,20 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
<< SrcType << DestType << ClassMethod->getSelector() << false
<< FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
<< FixItHint::CreateInsertion(SrcExprEndLoc, "]");
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
QualType receiverType =
Context.getObjCInterfaceType(RelatedClass);
// Argument.
Expr *args[] = { SrcExpr };
ExprResult msg = BuildClassMessageImplicit(receiverType, false,
ClassMethod->getLocation(),
ClassMethod->getSelector(), ClassMethod,
MultiExprArg(args, 1));
SrcExpr = msg.take();
return true;
}
else
Diag(Loc, diag::err_objc_bridged_related_unknown_method)
<< SrcType << DestType;
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.
@ -3492,15 +3500,19 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
<< FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
<< FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
}
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
ExprResult msg =
BuildInstanceMessageImplicit(SrcExpr, SrcType,
InstanceMethod->getLocation(),
InstanceMethod->getSelector(),
InstanceMethod, None);
SrcExpr = msg.take();
return true;
}
else
Diag(Loc, diag::err_objc_bridged_related_unknown_method)
<< SrcType << DestType;
Diag(RelatedClass->getLocStart(), diag::note_declared_at);
Diag(TDNDecl->getLocStart(), diag::note_declared_at);
}
return true;
return false;
}
Sema::ARCConversionResult

View File

@ -4462,6 +4462,11 @@ void InitializationSequence::InitializeFrom(Sema &S,
Expr *Initializer = 0;
if (Args.size() == 1) {
Initializer = Args[0];
if (S.getLangOpts().ObjC1 &&
S.CheckObjCBridgeRelatedConversions(Initializer->getLocStart(),
DestType, Initializer->getType(),
Initializer))
Args[0] = Initializer;
if (!isa<InitListExpr>(Initializer))
SourceType = Initializer->getType();
}
@ -6482,9 +6487,6 @@ bool InitializationSequence::Diagnose(Sema &S,
case FK_ConversionFailed: {
QualType FromType = Args[0]->getType();
if (S.getLangOpts().ObjC1)
S.CheckObjCBridgeRelatedConversions(Kind.getLocation(),
DestType, FromType, Args[0]);
PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed)
<< (int)Entity.getKind()
<< DestType

View File

@ -1298,7 +1298,9 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
bool AllowObjCWritebackConversion
= getLangOpts().ObjCAutoRefCount &&
(Action == AA_Passing || Action == AA_Sending);
if (getLangOpts().ObjC1)
CheckObjCBridgeRelatedConversions(From->getLocStart(),
ToType, From->getType(), From);
ICS = clang::TryImplicitConversion(*this, From, ToType,
/*SuppressUserConversions=*/false,
AllowExplicit,

View File

@ -2,10 +2,10 @@
// 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}}
typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor1))) CGColor1 *CGColorRef1;
typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColorRef2;
@interface NSColor // expected-note 10 {{declared here}}
@interface NSColor // expected-note 5 {{declared here}}
+ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
- (CGColorRef)CGColor;
- (CGColorRef1)CGColor1;
@ -16,7 +16,7 @@ typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColor
- (NSColor *)backgroundColor;
@end
void foo(NSColor*);
void foo(NSColor*); // expected-note {{passing argument to parameter here}}
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}}
@ -25,9 +25,9 @@ NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
}
NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
foo(newColor); // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') cannot be directly converted to 'NSColor *'}}
textField.backgroundColor = newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') cannot be directly converted to 'NSColor *__strong'}}
return newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') cannot be directly converted to 'NSColor *'}}
foo(newColor); // expected-warning {{incompatible pointer types passing 'CGColorRef1' (aka 'struct CGColor1 *') to parameter of type 'NSColor *'}}
textField.backgroundColor = newColor; // expected-warning {{incompatible pointer types assigning to 'NSColor *__strong' from 'CGColorRef1' (aka 'struct CGColor1 *')}}
return newColor; // expected-warning {{incompatible pointer types returning 'CGColorRef1' (aka 'struct CGColor1 *') from a function with result type 'NSColor *'}}
}
CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
@ -36,6 +36,6 @@ CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
}
CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) {
newColor = textField.backgroundColor; // expected-error {{'NSColor *' cannot be directly converted to 'CGColorRef2' (aka 'struct CGColor2 *')}}
return textField.backgroundColor; // expected-error {{'NSColor *' cannot be directly converted to 'CGColorRef2' (aka 'struct CGColor2 *')}}
newColor = textField.backgroundColor; // expected-warning {{incompatible pointer types assigning}}
return textField.backgroundColor; // expected-warning {{incompatible pointer types returning}}
}

View File

@ -2,10 +2,10 @@
// 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}}
typedef struct __attribute__((objc_bridge_related(NSColor,,CGColor1))) CGColor1 *CGColorRef1;
typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColorRef2;
@interface NSColor // expected-note 10 {{declared here}}
@interface NSColor // expected-note 5 {{declared here}}
+ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
- (CGColorRef)CGColor;
- (CGColorRef1)CGColor1;
@ -16,7 +16,7 @@ typedef struct __attribute__((objc_bridge_related(NSColor,,))) CGColor2 *CGColor
- (NSColor *)backgroundColor;
@end
void foo(NSColor*);
void foo(NSColor*); // expected-note {{passing argument to parameter here}}
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}}
@ -25,9 +25,9 @@ NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
}
NSColor * Test2(NSTextField *textField, CGColorRef1 newColor) {
foo(newColor); // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') cannot be directly converted to 'NSColor *'}}
textField.backgroundColor = newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') cannot be directly converted to 'NSColor *'}}
return newColor; // expected-error {{'CGColorRef1' (aka 'struct CGColor1 *') cannot be directly converted to 'NSColor *'}}
foo(newColor); // expected-warning {{incompatible pointer types passing 'CGColorRef1'}}
textField.backgroundColor = newColor; // expected-warning {{incompatible pointer types assigning}}
return newColor; // expected-warning {{incompatible pointer types returning}}
}
CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
@ -36,6 +36,6 @@ CGColorRef Test3(NSTextField *textField, CGColorRef newColor) {
}
CGColorRef2 Test4(NSTextField *textField, CGColorRef2 newColor) {
newColor = textField.backgroundColor; // expected-error {{'NSColor *' cannot be directly converted to 'CGColorRef2' (aka 'struct CGColor2 *')}}
return textField.backgroundColor; // expected-error {{'NSColor *' cannot be directly converted to 'CGColorRef2' (aka 'struct CGColor2 *')}}
newColor = textField.backgroundColor; // expected-warning {{incompatible pointer types assigning}}
return textField.backgroundColor; // expected-warning {{incompatible pointer types returning}}
}

View File

@ -15,17 +15,13 @@ typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGCo
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 *')}}
NSColor *ns = 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}}
}
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 *'}}
CGColorRef cg = 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}}
}