forked from OSchip/llvm-project
Objective-C. Provide fixit's for objc_bride_related
attributed CF to ObjC type conversions. // rdar://15499111 llvm-svn: 196935
This commit is contained in:
parent
9653eb5759
commit
db76577f43
|
@ -6922,7 +6922,8 @@ public:
|
|||
bool CfToNs);
|
||||
|
||||
bool CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
||||
QualType DestType, QualType SrcType);
|
||||
QualType DestType, QualType SrcType,
|
||||
Expr *SrcExpr);
|
||||
|
||||
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
|
||||
|
||||
|
|
|
@ -10640,7 +10640,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
break;
|
||||
case IncompatiblePointer:
|
||||
if (getLangOpts().ObjC1 &&
|
||||
CheckObjCBridgeRelatedConversions(Loc, DstType, SrcType))
|
||||
CheckObjCBridgeRelatedConversions(Loc, DstType, SrcType, SrcExpr))
|
||||
return false;
|
||||
MakeObjCStringLiteralFixItHint(*this, DstType, SrcExpr, Hint, IsNSString);
|
||||
DiagKind =
|
||||
|
@ -10722,7 +10722,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
break;
|
||||
case Incompatible:
|
||||
if (getLangOpts().ObjC1 &&
|
||||
CheckObjCBridgeRelatedConversions(Loc, DstType, SrcType))
|
||||
CheckObjCBridgeRelatedConversions(Loc, DstType, SrcType, SrcExpr))
|
||||
return true;
|
||||
DiagKind = diag::err_typecheck_convert_incompatible;
|
||||
ConvHints.tryToFixConversion(SrcExpr, SrcType, DstType, *this);
|
||||
|
|
|
@ -3427,7 +3427,8 @@ bool Sema::checkObjCBridgeRelatedComponents(SourceLocation Loc,
|
|||
|
||||
bool
|
||||
Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
||||
QualType DestType, QualType SrcType) {
|
||||
QualType DestType, QualType SrcType,
|
||||
Expr *SrcExpr) {
|
||||
ARCConversionTypeClass rhsExprACTC = classifyTypeForARCConversion(SrcType);
|
||||
ARCConversionTypeClass lhsExprACTC = classifyTypeForARCConversion(DestType);
|
||||
bool CfToNs = (rhsExprACTC == ACTC_coreFoundation && lhsExprACTC == ACTC_retainable);
|
||||
|
@ -3445,9 +3446,18 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
|||
|
||||
if (CfToNs) {
|
||||
// Implicit conversion from CF to ObjC object is needed.
|
||||
if (ClassMethod)
|
||||
if (ClassMethod) {
|
||||
std::string ExpressionString = "[";
|
||||
ExpressionString += RelatedClass->getNameAsString();
|
||||
ExpressionString += " ";
|
||||
ExpressionString += ClassMethod->getSelector().getAsString();
|
||||
SourceLocation SrcExprEndLoc = PP.getLocForEndOfToken(SrcExpr->getLocEnd());
|
||||
// Provide a fixit: [RelatedClass ClassMethod SrcExpr]
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << ClassMethod->getSelector() << 0;
|
||||
<< SrcType << DestType << ClassMethod->getSelector() << 0
|
||||
<< FixItHint::CreateInsertion(SrcExpr->getLocStart(), ExpressionString)
|
||||
<< FixItHint::CreateInsertion(SrcExprEndLoc, "]");
|
||||
}
|
||||
else
|
||||
Diag(Loc, diag::err_objc_bridged_related_unknown_method)
|
||||
<< SrcType << DestType << 0;
|
||||
|
@ -3456,9 +3466,18 @@ Sema::CheckObjCBridgeRelatedConversions(SourceLocation Loc,
|
|||
}
|
||||
else {
|
||||
// Implicit conversion from ObjC type to CF object is needed.
|
||||
if (InstanceMethod)
|
||||
if (InstanceMethod) {
|
||||
// Provide a fixit: [ObjectExpr InstanceMethod];
|
||||
std::string ExpressionString = " ";
|
||||
ExpressionString += InstanceMethod->getSelector().getAsString();
|
||||
ExpressionString += "]";
|
||||
SourceLocation SrcExprEndLoc = PP.getLocForEndOfToken(SrcExpr->getLocEnd());
|
||||
|
||||
Diag(Loc, diag::err_objc_bridged_related_known_method)
|
||||
<< SrcType << DestType << InstanceMethod->getSelector() << 1;
|
||||
<< SrcType << DestType << InstanceMethod->getSelector() << 1
|
||||
<< FixItHint::CreateInsertion(SrcExpr->getLocStart(), "[")
|
||||
<< FixItHint::CreateInsertion(SrcExprEndLoc, ExpressionString);
|
||||
}
|
||||
else
|
||||
Diag(Loc, diag::err_objc_bridged_related_unknown_method)
|
||||
<< SrcType << DestType << 1;
|
||||
|
|
|
@ -6484,7 +6484,7 @@ bool InitializationSequence::Diagnose(Sema &S,
|
|||
QualType FromType = Args[0]->getType();
|
||||
if (S.getLangOpts().ObjC1)
|
||||
S.CheckObjCBridgeRelatedConversions(Kind.getLocation(),
|
||||
DestType, FromType);
|
||||
DestType, FromType, Args[0]);
|
||||
PartialDiagnostic PDiag = S.PDiag(diag::err_init_conversion_failed)
|
||||
<< (int)Entity.getKind()
|
||||
<< DestType
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// Objective-C recovery
|
||||
// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -fdiagnostics-parseable-fixits -x objective-c %s 2>&1 | FileCheck %s
|
||||
// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-arc -fdiagnostics-parseable-fixits -x objective-c %s 2>&1 | FileCheck %s
|
||||
// RUN: not %clang_cc1 -triple x86_64-apple-darwin10 -fdiagnostics-parseable-fixits -x objective-c++ %s 2>&1 | FileCheck %s
|
||||
// rdar://15499111
|
||||
|
||||
typedef struct __attribute__((objc_bridge_related(NSColor,colorWithCGColor:,CGColor))) CGColor *CGColorRef;
|
||||
|
||||
@interface NSColor
|
||||
+ (NSColor *)colorWithCGColor:(CGColorRef)cgColor;
|
||||
- (CGColorRef)CGColor;
|
||||
@end
|
||||
|
||||
@interface NSTextField
|
||||
- (void)setBackgroundColor:(NSColor *)color;
|
||||
- (NSColor *)backgroundColor;
|
||||
@end
|
||||
|
||||
NSColor * Test1(NSTextField *textField, CGColorRef newColor) {
|
||||
textField.backgroundColor = newColor;
|
||||
return newColor;
|
||||
}
|
||||
|
||||
CGColorRef Test2(NSTextField *textField, CGColorRef newColor) {
|
||||
newColor = textField.backgroundColor; // [textField.backgroundColor CGColor]
|
||||
return textField.backgroundColor;
|
||||
}
|
||||
// CHECK: {20:30-20:30}:"[NSColor colorWithCGColor:"
|
||||
// CHECK: {20:38-20:38}:"]"
|
||||
// CHECK: {21:9-21:9}:"[NSColor colorWithCGColor:"
|
||||
// CHECK: {21:17-21:17}:"]"
|
||||
// CHECK: {25:13-25:13}:"["
|
||||
// CHECK: {25:38-25:38}:" CGColor]"
|
||||
// CHECK: {26:9-26:9}:"["
|
||||
// CHECK: {26:34-26:34}:" CGColor]"
|
Loading…
Reference in New Issue