aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2012-04-24 18:16:20 +0000
committerFariborz Jahanian <fjahanian@apple.com>2012-04-24 18:16:20 +0000
commite6e96de44f0d6a533760f926f6534a3844b3fde6 (patch)
treed59485862ddcdaf5e28d82ee7e2087cc01841ac3
parent8247c4ed71c126b274d3123f7a97d0770deb9f4e (diff)
objc modern rewriter: allow translation of
multiple declaration of block variables (with no initializer) on the same line. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@155462 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Rewrite/RewriteModernObjC.cpp19
-rw-r--r--test/Rewriter/rewrite-modern-block.mm12
2 files changed, 28 insertions, 3 deletions
diff --git a/lib/Rewrite/RewriteModernObjC.cpp b/lib/Rewrite/RewriteModernObjC.cpp
index 4f70e4f216..d9b6c223ce 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);
+ void RewriteByRefVar(VarDecl *VD, bool firstDecl);
Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
@@ -4742,7 +4742,7 @@ std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
/// ND=initializer-if-any};
///
///
-void RewriteModernObjC::RewriteByRefVar(VarDecl *ND) {
+void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl) {
int flag = 0;
int isa = 0;
SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
@@ -4843,6 +4843,19 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND) {
// 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 {
@@ -5309,7 +5322,7 @@ Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
assert(!BlockByRefDeclNo.count(ND) &&
"RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
- RewriteByRefVar(VD);
+ RewriteByRefVar(VD, (DI == DS->decl_begin()));
}
else
RewriteTypeOfDecl(VD);
diff --git a/test/Rewriter/rewrite-modern-block.mm b/test/Rewriter/rewrite-modern-block.mm
index 8da723d319..86cf07e033 100644
--- a/test/Rewriter/rewrite-modern-block.mm
+++ b/test/Rewriter/rewrite-modern-block.mm
@@ -21,3 +21,15 @@ void y() {
int foo() {
__block int hello;
}
+
+// rdar://7547630
+// rewriting multiple __block decls on wintin same decl stmt.
+int radar7547630() {
+ __block int BI1, BI2;
+
+ __block float FLOAT1, FT2, FFFFFFFF3,
+ FFFXXX4;
+
+ __block void (^B)(), (^BB)();
+}
+