More rewriting of __block declared objective-c/block pointers.

This is wip.

llvm-svn: 92501
This commit is contained in:
Fariborz Jahanian 2010-01-04 19:50:07 +00:00
parent 51af7f628c
commit d6cba5065f
1 changed files with 45 additions and 16 deletions

View File

@ -347,7 +347,7 @@ namespace {
void RewriteBlockCall(CallExpr *Exp);
void RewriteBlockPointerDecl(NamedDecl *VD);
void RewriteByRefVar(VarDecl *VD);
Stmt *RewriteBlockDeclRefExpr(BlockDeclRefExpr *VD);
Stmt *RewriteBlockDeclRefExpr(Expr *VD);
void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
@ -4192,29 +4192,40 @@ void RewriteObjC::RewriteBlockCall(CallExpr *Exp) {
// i = 77;
// };
//}
Stmt *RewriteObjC::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) {
Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) {
// Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR
// for each BDRE where BYREFVAR is name of the variable.
// for each DeclRefExp where BYREFVAR is name of the variable.
ValueDecl *VD;
bool isArrow = true;
if (BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(DeclRefExp))
VD = BDRE->getDecl();
else {
VD = cast<DeclRefExpr>(DeclRefExp)->getDecl();
isArrow = false;
}
FieldDecl *FD = FieldDecl::Create(*Context, 0, SourceLocation(),
&Context->Idents.get("__forwarding"),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true);
MemberExpr *ME = new (Context) MemberExpr(BDRE, true, FD, SourceLocation(),
MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
FD, SourceLocation(),
FD->getType());
const char *Name = BDRE->getDecl()->getNameAsCString();
const char *Name = VD->getNameAsCString();
FD = FieldDecl::Create(*Context, 0, SourceLocation(),
&Context->Idents.get(Name),
Context->VoidPtrTy, 0,
/*BitWidth=*/0, /*Mutable=*/true);
ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
BDRE->getType());
DeclRefExp->getType());
// Need parens to enforce precedence.
ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
ME);
ReplaceStmt(BDRE, PE);
ReplaceStmt(DeclRefExp, PE);
return PE;
}
@ -4376,8 +4387,8 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
/// struct __Block_byref_ND *__forwarding;
/// int32_t __flags;
/// int32_t __size;
/// void *__ByrefKeepFuncPtr; // Only if variable is __block ObjC object
/// void *__ByrefDestroyFuncPtr; // Only if variable is __block ObjC object
/// void *__copy_helper; // Only if variable is __block ObjC object
/// void *__destroy_helper; // Only if variable is __block ObjC object
/// typex ND;
/// };
///
@ -4401,9 +4412,15 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
ByrefType += " struct __Block_byref_" + Name + " *__forwarding;\n";
ByrefType += " int __flags;\n";
ByrefType += " int __size;\n";
// FIXME. Add void *__ByrefKeepFuncPtr; void *__ByrefDestroyFuncPtr;
// if needed.
ND->getType().getAsStringInternal(Name, Context->PrintingPolicy);
// Add void *__copy_helper; void *__destroy_helper; if needed.
QualType Ty = ND->getType();
bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty);
if (HasCopyAndDispose) {
ByrefType += " void *__copy_helper;\n";
ByrefType += " void *__destroy_helper;\n";
}
Ty.getAsStringInternal(Name, Context->PrintingPolicy);
ByrefType += " " + Name + ";\n";
ByrefType += "};\n";
// Insert this type in global scope. It is needed by helper function.
@ -4420,8 +4437,11 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
if (!hasInit) {
ByrefType += " " + Name + " = ";
ByrefType += "{0, &" + Name + ", ";
// FIXME. Compute the flag.
ByrefType += "0, ";
unsigned flag = 0;
if (HasCopyAndDispose)
flag |= BLOCK_HAS_COPY_DISPOSE;
ByrefType += utostr(flag);
ByrefType += ", ";
ByrefType += "sizeof(struct __Block_byref_" + Name + ")";
ByrefType += "};\n";
ReplaceText(DeclLoc, endBuf-startBuf+Name.size(),
@ -4433,8 +4453,11 @@ void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
ReplaceText(DeclLoc, endBuf-startBuf,
ByrefType.c_str(), ByrefType.size());
ByrefType = " = {0, &" + Name + ", ";
// FIXME. Compute the flag.
ByrefType += "0, ";
unsigned flag = 0;
if (HasCopyAndDispose)
flag |= BLOCK_HAS_COPY_DISPOSE;
ByrefType += utostr(flag);
ByrefType += ", ";
ByrefType += "sizeof(struct __Block_byref_" + Name + "), ";
InsertText(startLoc, ByrefType.c_str(), ByrefType.size());
@ -4829,6 +4852,12 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
if (BDRE->isByRef())
return RewriteBlockDeclRefExpr(BDRE);
}
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
ValueDecl *VD = DRE->getDecl();
if (VD->hasAttr<BlocksAttr>())
return RewriteBlockDeclRefExpr(DRE);
}
if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
if (CE->getCallee()->getType()->isBlockPointerType()) {
Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());