Author: jrose
Date: Wed Jun  6 20:10:31 2012
New Revision: 158130

URL: http://llvm.org/viewvc/llvm-project?rev=158130&view=rev
Log:
Insert a space if necessary when suggesting CFBridgingRetain/Release.

This was a problem for people who write 'return(result);'

Also fix ARCMT's corresponding code, though there's no test case for this
because implicit casts like this are rejected by the migrator for being
ambiguous, and explicit casts have no problem.

<rdar://problem/11577346>

Modified:
    cfe/trunk/include/clang/Lex/Lexer.h
    cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/test/SemaObjC/arc-bridged-cast.m

Modified: cfe/trunk/include/clang/Lex/Lexer.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Lexer.h?rev=158130&r1=158129&r2=158130&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Lexer.h (original)
+++ cfe/trunk/include/clang/Lex/Lexer.h Wed Jun  6 20:10:31 2012
@@ -541,6 +541,9 @@
                                          const LangOptions &LangOpts,
                                          bool 
SkipTrailingWhitespaceAndNewLine);
 
+  /// \brief Returns true if the given character could appear in an identifier.
+  static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts);
+
 private:
 
   /// getCharAndSizeSlowNoWarn - Same as getCharAndSizeSlow, but never emits a

Modified: cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp?rev=158130&r1=158129&r2=158130&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransUnbridgedCasts.cpp Wed Jun  6 20:10:31 2012
@@ -37,6 +37,7 @@
 #include "clang/Analysis/DomainSpecific/CocoaConventions.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "clang/AST/ParentMap.h"
+#include "clang/Lex/Lexer.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
 
@@ -229,20 +230,26 @@
       }
     } else {
       assert(Kind == OBC_BridgeTransfer || Kind == OBC_BridgeRetained);
-      StringRef cfBridging;
+      SmallString<32> BridgeCall;
+
+      Expr *WrapE = E->getSubExpr();
+      SourceLocation InsertLoc = WrapE->getLocStart();
+
+      SourceManager &SM = Pass.Ctx.getSourceManager();
+      char PrevChar = *SM.getCharacterData(InsertLoc.getLocWithOffset(-1));
+      if (Lexer::isIdentifierBodyChar(PrevChar, Pass.Ctx.getLangOpts()))
+        BridgeCall += ' ';
+
       if (Kind == OBC_BridgeTransfer)
-        cfBridging = "CFBridgingRelease";
+        BridgeCall += "CFBridgingRelease";
       else
-        cfBridging = "CFBridgingRetain";
+        BridgeCall += "CFBridgingRetain";
 
-      Expr *WrapE = E->getSubExpr();
-      SourceLocation insertLoc = WrapE->getLocStart();
       if (isa<ParenExpr>(WrapE)) {
-        TA.insert(insertLoc, cfBridging);
+        TA.insert(InsertLoc, BridgeCall);
       } else {
-        std::string withParens = cfBridging;
-        withParens += '(';
-        TA.insert(insertLoc, withParens);
+        BridgeCall += '(';
+        TA.insert(InsertLoc, BridgeCall);
         TA.insertAfterToken(WrapE->getLocEnd(), ")");
       }
     }

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=158130&r1=158129&r2=158130&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Wed Jun  6 20:10:31 2012
@@ -1124,6 +1124,11 @@
     true : false;
 }
 
+// Allow external clients to make use of CharInfo.
+bool Lexer::isIdentifierBodyChar(char c, const LangOptions &LangOpts) {
+  return isIdentifierBody(c) || (c == '$' && LangOpts.DollarIdents);
+}
+
 
 
//===----------------------------------------------------------------------===//
 // Diagnostics forwarding code.

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=158130&r1=158129&r2=158130&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Jun  6 20:10:31 2012
@@ -2820,14 +2820,23 @@
       castedE = CCE->getSubExpr();
     castedE = castedE->IgnoreImpCasts();
     SourceRange range = castedE->getSourceRange();
+
+    SmallString<32> BridgeCall;
+
+    SourceManager &SM = S.getSourceManager();
+    char PrevChar = 
*SM.getCharacterData(range.getBegin().getLocWithOffset(-1));
+    if (Lexer::isIdentifierBodyChar(PrevChar, S.getLangOpts()))
+      BridgeCall += ' ';
+
+    BridgeCall += CFBridgeName;
+
     if (isa<ParenExpr>(castedE)) {
       DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
-                         CFBridgeName));
+                         BridgeCall));
     } else {
-      std::string namePlusParen = CFBridgeName;
-      namePlusParen += "(";
+      BridgeCall += '(';
       DiagB.AddFixItHint(FixItHint::CreateInsertion(range.getBegin(),
-                                                    namePlusParen));
+                                                    BridgeCall));
       DiagB.AddFixItHint(FixItHint::CreateInsertion(
                                        
S.PP.getLocForEndOfToken(range.getEnd()),
                                        ")"));

Modified: cfe/trunk/test/SemaObjC/arc-bridged-cast.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-bridged-cast.m?rev=158130&r1=158129&r2=158130&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-bridged-cast.m (original)
+++ cfe/trunk/test/SemaObjC/arc-bridged-cast.m Wed Jun  6 20:10:31 2012
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc 
-fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc 
-fblocks -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 typedef const void *CFTypeRef;
 CFTypeRef CFBridgingRetain(id X);
@@ -32,13 +33,35 @@
 
   // rdar://problem/9629566 - temporary workaround
   CFTypeRef cf5 = (__bridge_retain CFTypeRef)CreateSomething(); // 
expected-error {{unknown cast annotation __bridge_retain; did you mean 
__bridge_retained?}}
+  // CHECK: fix-it:"{{.*}}":{35:20-35:35}:"__bridge_retained"
 }
 
-void fixits() {
+CFTypeRef fixits() {
   id obj1 = (id)CFCreateSomething(); // expected-error{{cast of C pointer type 
'CFTypeRef' (aka 'const void *') to Objective-C pointer type 'id' requires a 
bridged cast}} \
   // expected-note{{use __bridge to convert directly (no change in 
ownership)}} \
   // expected-note{{use CFBridgingRelease call to transfer ownership of a +1 
'CFTypeRef' (aka 'const void *') into ARC}}
+  // CHECK: fix-it:"{{.*}}":{40:14-40:14}:"__bridge "
+  // CHECK: fix-it:"{{.*}}":{40:17-40:17}:"CFBridgingRelease("
+  // CHECK: fix-it:"{{.*}}":{40:36-40:36}:")"
+
   CFTypeRef cf1 = (CFTypeRef)CreateSomething(); // expected-error{{cast of 
Objective-C pointer type 'id' to C pointer type 'CFTypeRef' (aka 'const void 
*') requires a bridged cast}} \
   // expected-note{{use __bridge to convert directly (no change in 
ownership)}} \
   // expected-note{{use CFBridgingRetain call to make an ARC object available 
as a +1 'CFTypeRef' (aka 'const void *')}}
+  // CHECK: fix-it:"{{.*}}":{47:20-47:20}:"__bridge "
+  // CHECK: fix-it:"{{.*}}":{47:30-47:30}:"CFBridgingRetain("
+  // CHECK: fix-it:"{{.*}}":{47:47-47:47}:")"
+
+  return (obj1); // expected-error{{implicit conversion of Objective-C pointer 
type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged 
cast}} \
+  // expected-note{{use __bridge to convert directly (no change in 
ownership)}} \
+  // expected-note{{use CFBridgingRetain call to make an ARC object available 
as a +1 'CFTypeRef' (aka 'const void *')}}
+  // CHECK: fix-it:"{{.*}}":{54:10-54:10}:"(__bridge CFTypeRef)"
+  // CHECK: fix-it:"{{.*}}":{54:10-54:10}:"CFBridgingRetain"
+}
+
+CFTypeRef fixitsWithSpace(id obj) {
+  return(obj); // expected-error{{implicit conversion of Objective-C pointer 
type 'id' to C pointer type 'CFTypeRef' (aka 'const void *') requires a bridged 
cast}} \
+  // expected-note{{use __bridge to convert directly (no change in 
ownership)}} \
+  // expected-note{{use CFBridgingRetain call to make an ARC object available 
as a +1 'CFTypeRef' (aka 'const void *')}}
+  // CHECK: fix-it:"{{.*}}":{62:9-62:9}:"(__bridge CFTypeRef)"
+  // CHECK: fix-it:"{{.*}}":{62:9-62:9}:" CFBridgingRetain"
 }


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to