forked from OSchip/llvm-project
Objective-C. After providing a fix-it for a
cstring, converted to NSString, produce the matching AST for it. This also required some refactoring of the previous code. // rdar://14106083 llvm-svn: 197605
This commit is contained in:
parent
afa854c15e
commit
283bf89506
|
@ -6902,9 +6902,7 @@ public:
|
|||
QualType DestType, QualType SrcType,
|
||||
Expr *&SrcExpr);
|
||||
|
||||
StringLiteral * ConversionToObjCStringLiteralCheck(QualType DstType,
|
||||
Expr *SrcExpr, FixItHint &Hint,
|
||||
bool &IsNSString);
|
||||
bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr);
|
||||
|
||||
bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall);
|
||||
|
||||
|
|
|
@ -6613,8 +6613,9 @@ Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS,
|
|||
CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
|
||||
DiagnoseCFAudited);
|
||||
if (getLangOpts().ObjC1 &&
|
||||
CheckObjCBridgeRelatedConversions(E->getLocStart(),
|
||||
LHSType, E->getType(), E)) {
|
||||
(CheckObjCBridgeRelatedConversions(E->getLocStart(),
|
||||
LHSType, E->getType(), E) ||
|
||||
ConversionToObjCStringLiteralCheck(LHSType, E))) {
|
||||
RHS = Owned(E);
|
||||
return Compatible;
|
||||
}
|
||||
|
@ -10587,39 +10588,37 @@ ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
|
|||
return Owned(new (Context) GNUNullExpr(Ty, TokenLoc));
|
||||
}
|
||||
|
||||
StringLiteral *
|
||||
Sema::ConversionToObjCStringLiteralCheck(QualType DstType,
|
||||
Expr *SrcExpr, FixItHint &Hint,
|
||||
bool &IsNSString) {
|
||||
bool
|
||||
Sema::ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&Exp) {
|
||||
if (!getLangOpts().ObjC1)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
const ObjCObjectPointerType *PT = DstType->getAs<ObjCObjectPointerType>();
|
||||
if (!PT)
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
// Check if the destination is of type 'id'.
|
||||
if (!PT->isObjCIdType()) {
|
||||
// Check if the destination is the 'NSString' interface.
|
||||
const ObjCInterfaceDecl *ID = PT->getInterfaceDecl();
|
||||
if (!ID || !ID->getIdentifier()->isStr("NSString"))
|
||||
return 0;
|
||||
IsNSString = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Ignore any parens, implicit casts (should only be
|
||||
// array-to-pointer decays), and not-so-opaque values. The last is
|
||||
// important for making this trigger for property assignments.
|
||||
SrcExpr = SrcExpr->IgnoreParenImpCasts();
|
||||
Expr *SrcExpr = Exp->IgnoreParenImpCasts();
|
||||
if (OpaqueValueExpr *OV = dyn_cast<OpaqueValueExpr>(SrcExpr))
|
||||
if (OV->getSourceExpr())
|
||||
SrcExpr = OV->getSourceExpr()->IgnoreParenImpCasts();
|
||||
|
||||
StringLiteral *SL = dyn_cast<StringLiteral>(SrcExpr);
|
||||
if (!SL || !SL->isAscii())
|
||||
return 0;
|
||||
Hint = FixItHint::CreateInsertion(SL->getLocStart(), "@");
|
||||
return SL;
|
||||
return false;
|
||||
Diag(SL->getLocStart(), diag::err_missing_atsign_prefix)
|
||||
<< FixItHint::CreateInsertion(SL->getLocStart(), "@");
|
||||
Exp = BuildObjCStringLiteral(SL->getLocStart(), SL).take();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
||||
|
@ -10638,7 +10637,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
ConversionFixItGenerator ConvHints;
|
||||
bool MayHaveConvFixit = false;
|
||||
bool MayHaveFunctionDiff = false;
|
||||
bool IsNSString = false;
|
||||
|
||||
switch (ConvTy) {
|
||||
case Compatible:
|
||||
|
@ -10656,7 +10654,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
MayHaveConvFixit = true;
|
||||
break;
|
||||
case IncompatiblePointer:
|
||||
ConversionToObjCStringLiteralCheck(DstType, SrcExpr, Hint, IsNSString);
|
||||
DiagKind =
|
||||
(Action == AA_Passing_CFAudited ?
|
||||
diag::err_arc_typecheck_convert_incompatible_pointer :
|
||||
|
@ -10670,8 +10667,6 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
|
|||
SrcType = SrcType.getUnqualifiedType();
|
||||
DstType = DstType.getUnqualifiedType();
|
||||
}
|
||||
else if (IsNSString && !Hint.isNull())
|
||||
DiagKind = diag::err_missing_atsign_prefix;
|
||||
MayHaveConvFixit = true;
|
||||
break;
|
||||
case IncompatiblePointerSign:
|
||||
|
|
|
@ -3615,13 +3615,9 @@ Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
|
|||
// Do not issue bridge cast" diagnostic when implicit casting a cstring
|
||||
// to 'NSString *'. Let caller issue a normal mismatched diagnostic with
|
||||
// suitable fix-it.
|
||||
if (castACTC == ACTC_retainable && exprACTC == ACTC_none) {
|
||||
bool IsNSString = false;
|
||||
FixItHint Hint;
|
||||
if (ConversionToObjCStringLiteralCheck(
|
||||
castType, castExpr, Hint, IsNSString) && IsNSString)
|
||||
return ACR_okay;
|
||||
}
|
||||
if (castACTC == ACTC_retainable && exprACTC == ACTC_none &&
|
||||
ConversionToObjCStringLiteralCheck(castType, castExpr))
|
||||
return ACR_okay;
|
||||
|
||||
// Do not issue "bridge cast" diagnostic when implicit casting
|
||||
// a retainable object to a CF type parameter belonging to an audited
|
||||
|
|
|
@ -4462,11 +4462,14 @@ 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 (S.getLangOpts().ObjC1) {
|
||||
if (S.CheckObjCBridgeRelatedConversions(Initializer->getLocStart(),
|
||||
DestType, Initializer->getType(),
|
||||
Initializer) ||
|
||||
S.ConversionToObjCStringLiteralCheck(DestType, Initializer))
|
||||
Args[0] = Initializer;
|
||||
|
||||
}
|
||||
if (!isa<InitListExpr>(Initializer))
|
||||
SourceType = Initializer->getType();
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ id foo(int x) {
|
|||
title = @"bar";
|
||||
break;
|
||||
default:
|
||||
title = "@baz";
|
||||
title = @"baz";
|
||||
break;
|
||||
}
|
||||
return title;
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
@class NSString;
|
||||
|
||||
@interface Test
|
||||
- (void)test:(NSString *)string; // expected-note{{passing argument to parameter 'string' here}}
|
||||
- (void)test:(NSString *)string;
|
||||
|
||||
@property (copy) NSString *property;
|
||||
@end
|
||||
|
||||
void g(NSString *a); // expected-note{{passing argument to parameter 'a' here}}
|
||||
void g(NSString *a);
|
||||
void h(id a);
|
||||
|
||||
void f(Test *t) {
|
||||
|
|
|
@ -18,20 +18,20 @@ void foo() {
|
|||
@class NSString;
|
||||
|
||||
@interface Test
|
||||
- (void)test:(NSString *)string; // expected-note{{passing argument to parameter 'string' here}}
|
||||
- (void)test:(NSString *)string;
|
||||
|
||||
@property (copy) NSString *property;
|
||||
@end
|
||||
|
||||
void g(NSString *a); // expected-note{{passing argument to parameter 'a' here}}
|
||||
void h(id a); // expected-note 2{{passing argument to parameter 'a' here}}
|
||||
void g(NSString *a);
|
||||
void h(id a);
|
||||
|
||||
void f(Test *t) {
|
||||
NSString *a = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
|
||||
id b = "Foo"; // expected-warning {{incompatible pointer types initializing 'id' with an expression of type 'char [4]'}}
|
||||
id b = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
|
||||
g("Foo"); // expected-error {{string literal must be prefixed by '@'}}
|
||||
h("Foo"); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'id'}}
|
||||
h(("Foo")); // expected-warning{{incompatible pointer types passing 'char [4]' to parameter of type 'id'}}
|
||||
h("Foo"); // expected-error {{string literal must be prefixed by '@'}}
|
||||
h(("Foo")); // expected-error {{string literal must be prefixed by '@'}}
|
||||
[t test:"Foo"]; // expected-error {{string literal must be prefixed by '@'}}
|
||||
t.property = "Foo"; // expected-error {{string literal must be prefixed by '@'}}
|
||||
|
||||
|
|
|
@ -24,5 +24,3 @@ void _rdar_12584554_A (volatile const void * object, volatile const void * selec
|
|||
// CHECK: Number FIX-ITs = 0
|
||||
// CHECK: fix-its.m:7:77: note: expanded from macro '_rdar_12584554_B'
|
||||
// CHECK: Number FIX-ITs = 0
|
||||
// CHECK: fix-its.m:5:172: note: passing argument to parameter 'msgFormat' here
|
||||
// CHECK: Number FIX-ITs = 0
|
||||
|
|
Loading…
Reference in New Issue