Initialize block's imported variable(s) in

block's synthesized constructor initalizer list.
Fixes radar 8240371.

llvm-svn: 109698
This commit is contained in:
Fariborz Jahanian 2010-07-28 23:27:30 +00:00
parent 89eb5def01
commit e6a4e3933d
2 changed files with 54 additions and 24 deletions

View File

@ -4309,7 +4309,41 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
S += FieldName + "; // by ref\n";
}
// Finish writing the constructor.
Constructor += ", int flags=0) {\n";
Constructor += ", int flags=0)";
// Initialize all "by copy" arguments.
bool firsTime = true;
for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
std::string Name = (*I)->getNameAsString();
if (firsTime) {
Constructor += " : ";
firsTime = false;
}
else
Constructor += ", ";
if (isTopLevelBlockPointerType((*I)->getType()))
Constructor += Name + "((struct __block_impl *)_" + Name + ")";
else
Constructor += Name + "(_" + Name + ")";
}
// Initialize all "by ref" arguments.
for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
std::string Name = (*I)->getNameAsString();
if (firsTime) {
Constructor += " : ";
firsTime = false;
}
else
Constructor += ", ";
if (isTopLevelBlockPointerType((*I)->getType()))
Constructor += Name + "((struct __block_impl *)_"
+ Name + "->__forwarding)";
else
Constructor += Name + "(_" + Name + "->__forwarding)";
}
Constructor += " {\n";
if (GlobalVarDecl)
Constructor += " impl.isa = &_NSConcreteGlobalBlock;\n";
else
@ -4317,29 +4351,6 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
Constructor += " impl.Flags = flags;\n impl.FuncPtr = fp;\n";
Constructor += " Desc = desc;\n";
// Initialize all "by copy" arguments.
for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByCopyDecls.begin(),
E = BlockByCopyDecls.end(); I != E; ++I) {
std::string Name = (*I)->getNameAsString();
Constructor += " ";
if (isTopLevelBlockPointerType((*I)->getType()))
Constructor += Name + " = (struct __block_impl *)_";
else
Constructor += Name + " = _";
Constructor += Name + ";\n";
}
// Initialize all "by ref" arguments.
for (llvm::SmallVector<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
std::string Name = (*I)->getNameAsString();
Constructor += " ";
if (isTopLevelBlockPointerType((*I)->getType()))
Constructor += Name + " = (struct __block_impl *)_";
else
Constructor += Name + " = _";
Constructor += Name + "->__forwarding;\n";
}
} else {
// Finish writing the constructor.
Constructor += ", int flags=0) {\n";

View File

@ -0,0 +1,19 @@
// RUN: %clang_cc1 -x objective-c++ -Wno-return-type -fblocks -fms-extensions -rewrite-objc %s -o %t-rw.cpp
// RUN: %clang_cc1 -fsyntax-only -fblocks -Wno-address-of-temporary -D"SEL=void*" -D"__declspec(X)=" %t-rw.cpp
// rdar:// 8243071
void x(int y) {}
void f() {
const int bar = 3;
int baz = 4;
__block int bab = 4;
__block const int bas = 5;
void (^b)() = ^{
x(bar);
x(baz);
x(bab);
x(bas);
b();
};
b();
}