From: Argyrios Kyrtzidis Date: Thu, 16 Feb 2012 17:31:07 +0000 (+0000) Subject: Add fixits for ARC casting errors for implicit conversions as well. rdar://10289283 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ae1b4af84ed0200c1040837ed62762557fbce5a7;p=clang Add fixits for ARC casting errors for implicit conversions as well. rdar://10289283 Also fix the fixit (oh the irony) when it uses CFBridgingRetain/CFBridgingRelease; they are supposed to be calls with the casted expression as parameter, they should not be inserted into the cast like the __bridge keywords. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150705 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index 497b2ec5f5..133c2d3de9 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1889,6 +1889,68 @@ KnownName(Sema &S, const char *name) { return S.LookupName(R, S.TUScope, false); } +static void addFixitForObjCARCConversion(Sema &S, + DiagnosticBuilder &DiagB, + Sema::CheckedConversionKind CCK, + SourceLocation afterLParen, + QualType castType, + Expr *castExpr, + const char *bridgeKeyword, + const char *CFBridgeName) { + // We handle C-style and implicit casts here. + switch (CCK) { + case Sema::CCK_ImplicitConversion: + case Sema::CCK_CStyleCast: + break; + case Sema::CCK_FunctionalCast: + case Sema::CCK_OtherCast: + return; + } + + if (CFBridgeName) { + Expr *castedE = castExpr; + if (CStyleCastExpr *CCE = dyn_cast(castedE)) + castedE = CCE->getSubExpr(); + castedE = castedE->IgnoreImpCasts(); + SourceRange range = castedE->getSourceRange(); + if (isa(castedE)) { + DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(), + CFBridgeName)); + } else { + std::string namePlusParen = CFBridgeName; + namePlusParen += "("; + DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(), + namePlusParen)); + DiagB.AddFixItHint(FixItHint::CreateInsertion( + S.PP.getLocForEndOfToken(range.getEnd()), + ")")); + } + return; + } + + if (CCK == Sema::CCK_CStyleCast) { + DiagB.AddFixItHint(FixItHint::CreateInsertion(afterLParen, bridgeKeyword)); + } else { + std::string castCode = "("; + castCode += bridgeKeyword; + castCode += castType.getAsString(); + castCode += ")"; + Expr *castedE = castExpr->IgnoreImpCasts(); + SourceRange range = castedE->getSourceRange(); + if (isa(castedE)) { + DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(), + castCode)); + } else { + castCode += "("; + DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(), + castCode)); + DiagB.AddFixItHint(FixItHint::CreateInsertion( + S.PP.getLocForEndOfToken(range.getEnd()), + ")")); + } + } +} + static void diagnoseObjCARCConversion(Sema &S, SourceRange castRange, QualType castType, ARCConversionTypeClass castACTC, @@ -1934,14 +1996,18 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, << castRange << castExpr->getSourceRange(); bool br = KnownName(S, "CFBridgingRelease"); - S.Diag(noteLoc, diag::note_arc_bridge) - << (CCK != Sema::CCK_CStyleCast ? FixItHint() : - FixItHint::CreateInsertion(afterLParen, "__bridge ")); - S.Diag(noteLoc, diag::note_arc_bridge_transfer) - << castExprType << br - << (CCK != Sema::CCK_CStyleCast ? FixItHint() : - FixItHint::CreateInsertion(afterLParen, - br ? "CFBridgingRelease " : "__bridge_transfer ")); + { + DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge); + addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, + castType, castExpr, "__bridge ", 0); + } + { + DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge_transfer) + << castExprType << br; + addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, + castType, castExpr, "__bridge_transfer ", + br ? "CFBridgingRelease" : 0); + } return; } @@ -1958,14 +2024,18 @@ diagnoseObjCARCConversion(Sema &S, SourceRange castRange, << castRange << castExpr->getSourceRange(); - S.Diag(noteLoc, diag::note_arc_bridge) - << (CCK != Sema::CCK_CStyleCast ? FixItHint() : - FixItHint::CreateInsertion(afterLParen, "__bridge ")); - S.Diag(noteLoc, diag::note_arc_bridge_retained) - << castType << br - << (CCK != Sema::CCK_CStyleCast ? FixItHint() : - FixItHint::CreateInsertion(afterLParen, - br ? "CFBridgingRetain " : "__bridge_retained")); + { + DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge); + addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, + castType, castExpr, "__bridge ", 0); + } + { + DiagnosticBuilder DiagB = S.Diag(noteLoc, diag::note_arc_bridge_retained) + << castType << br; + addFixitForObjCARCConversion(S, DiagB, CCK, afterLParen, + castType, castExpr, "__bridge_retained ", + br ? "CFBridgingRetain" : 0); + } return; }