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:
parent
04c685b5e4
commit
381edf5759
|
@ -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">;
|
||||
|
|
|
@ -6898,7 +6898,7 @@ public:
|
|||
|
||||
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
||||
QualType DestType, QualType SrcType,
|
||||
Expr *SrcExpr);
|
||||
Expr *&SrcExpr);
|
||||
|
||||
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue