modern objc translator: Allow writing of multiple

declaration of __block variables on same lines
with initializers. // rdsr://7547630

llvm-svn: 155473
This commit is contained in:
Fariborz Jahanian 2012-04-24 19:38:45 +00:00
parent 2d14d8aca1
commit 847713a998
2 changed files with 37 additions and 31 deletions

View 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,13 +4837,6 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl) {
ByrefType += utostr(flag);
}
if (!hasInit) {
ByrefType += "};\n";
unsigned nameSize = Name.size();
// for block or function pointer declaration. Name is aleady
// 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
@ -4856,6 +4850,14 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl) {
DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf);
startBuf = commaBuf;
}
if (!hasInit) {
ByrefType += "};\n";
unsigned nameSize = Name.size();
// for block or function pointer declaration. Name is aleady
// part of the declaration.
if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
nameSize = 1;
ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
}
else {
@ -4870,21 +4872,15 @@ void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl) {
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 separator = lastDecl ? ';' : ',';
const char *startInitializerBuf = SM->getCharacterData(startLoc);
const char *semiBuf = strchr(startInitializerBuf, ';');
assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
SourceLocation semiLoc =
startLoc.getLocWithOffset(semiBuf-startInitializerBuf);
const char *separatorBuf = strchr(startInitializerBuf, separator);
assert((*separatorBuf == separator) &&
"RewriteByRefVar: can't find ';' or ','");
SourceLocation separatorLoc =
startLoc.getLocWithOffset(separatorBuf-startInitializerBuf);
InsertText(semiLoc, "}");
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);

View 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;
}