]> granicus.if.org Git - clang/commitdiff
modern objc translator: Allow writing of multiple
authorFariborz Jahanian <fjahanian@apple.com>
Tue, 24 Apr 2012 19:38:45 +0000 (19:38 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Tue, 24 Apr 2012 19:38:45 +0000 (19:38 +0000)
declaration of __block variables on same lines
with initializers. // rdsr://7547630

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155473 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Rewrite/RewriteModernObjC.cpp
test/Rewriter/rewrite-modern-block.mm

index d9b6c223ce71913e5f76afdfd9a9d335fcffb37e..9cefa5ed2d76581240715fdfad79d1cfcac578a7 100644 (file)
@@ -337,7 +337,7 @@ namespace {
     
     // Block specific rewrite rules.
     void RewriteBlockPointerDecl(NamedDecl *VD);
-    void RewriteByRefVar(VarDecl *VD, bool firstDecl);
+    void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl);
     Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
     Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
     void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
@@ -4742,7 +4742,8 @@ std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
 ///                               ND=initializer-if-any};
 ///
 ///
-void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl) {
+void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl,
+                                        bool lastDecl) {
   int flag = 0;
   int isa = 0;
   SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
@@ -4836,6 +4837,20 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl) {
     ByrefType += utostr(flag);
   }
   
+  if (!firstDecl) {
+    // In multiple __block declarations, and for all but 1st declaration,
+    // find location of the separating comma. This would be start location
+    // where new text is to be inserted.
+    DeclLoc = ND->getLocation();
+    const char *startDeclBuf = SM->getCharacterData(DeclLoc);
+    const char *commaBuf = startDeclBuf;
+    while (*commaBuf != ',')
+      commaBuf--;
+    assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','");
+    DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf);
+    startBuf = commaBuf;
+  }
+  
   if (!hasInit) {
     ByrefType += "};\n";
     unsigned nameSize = Name.size();
@@ -4843,19 +4858,6 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl) {
     // part of the declaration.
     if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
       nameSize = 1;
-    if (!firstDecl) {
-      // In multiple __block declarations, and for all but 1st declaration,
-      // find location of the separating comma. This would be start location
-      // where new text is to be inserted.
-      DeclLoc = ND->getLocation();
-      const char *startDeclBuf = SM->getCharacterData(DeclLoc);
-      const char *commaBuf = startDeclBuf;
-      while (*commaBuf != ',')
-        commaBuf--;
-      assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','");
-      DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf);
-      startBuf = commaBuf;
-    }
     ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
   }
   else {
@@ -4869,22 +4871,16 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl) {
     startLoc = SM->getExpansionLoc(startLoc);
     endBuf = SM->getCharacterData(startLoc);
     ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
-    
-    // Complete the newly synthesized compound expression by inserting a right
-    // curly brace before the end of the declaration.
-    // FIXME: This approach avoids rewriting the initializer expression. It
-    // also assumes there is only one declarator. For example, the following
-    // isn't currently supported by this routine (in general):
-    // 
-    // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
-    //
-    const char *startInitializerBuf = SM->getCharacterData(startLoc);
-    const char *semiBuf = strchr(startInitializerBuf, ';');
-    assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
-    SourceLocation semiLoc =
-      startLoc.getLocWithOffset(semiBuf-startInitializerBuf);
 
-    InsertText(semiLoc, "}");
+    const char separator = lastDecl ? ';' : ',';
+    const char *startInitializerBuf = SM->getCharacterData(startLoc);
+    const char *separatorBuf = strchr(startInitializerBuf, separator);
+    assert((*separatorBuf == separator) && 
+           "RewriteByRefVar: can't find ';' or ','");
+    SourceLocation separatorLoc =
+      startLoc.getLocWithOffset(separatorBuf-startInitializerBuf);
+    
+    InsertText(separatorLoc, lastDecl ? "}" : "};\n");
   }
   return;
 }
@@ -5322,7 +5318,7 @@ Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
             assert(!BlockByRefDeclNo.count(ND) &&
               "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
             BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
-            RewriteByRefVar(VD, (DI == DS->decl_begin()));
+            RewriteByRefVar(VD, (DI == DS->decl_begin()), ((DI+1) == DE));
           }
           else           
             RewriteTypeOfDecl(VD);
index 86cf07e033081c0103c089a6bc6b41ed53633cd0..cd4d653825c4e312ddfbdfcec5a971f8b7b128e3 100644 (file)
@@ -33,3 +33,13 @@ int radar7547630() {
   __block void (^B)(), (^BB)();
 }
 
+// rewriting multiple __block decls on wintin same decl stmt
+// with initializers.
+void  rdar7547630(const char *keybuf, const char *valuebuf) {
+  __block int BI1 = 1, BI2 = 2;
+
+  double __block BYREFVAR = 1.34, BYREFVAR_NO_INIT, BYREFVAR2 = 1.37;
+
+  __block const char *keys = keybuf, *values = valuebuf, *novalues;
+}
+