From 4fe261cb0a6420b103335acc1f6bcb7b72188184 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 24 Apr 2012 19:38:45 +0000 Subject: [PATCH] modern objc translator: Allow writing of multiple 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 | 58 +++++++++++++-------------- test/Rewriter/rewrite-modern-block.mm | 10 +++++ 2 files changed, 37 insertions(+), 31 deletions(-) diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp index d9b6c223ce..9cefa5ed2d 100644 --- a/lib/Rewrite/RewriteModernObjC.cpp +++ b/lib/Rewrite/RewriteModernObjC.cpp @@ -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); diff --git a/test/Rewriter/rewrite-modern-block.mm b/test/Rewriter/rewrite-modern-block.mm index 86cf07e033..cd4d653825 100644 --- a/test/Rewriter/rewrite-modern-block.mm +++ b/test/Rewriter/rewrite-modern-block.mm @@ -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; +} + -- 2.40.0