aboutsummaryrefslogtreecommitdiff
path: root/lib/Frontend/RewriteObjC.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2010-01-04 19:50:07 +0000
committerFariborz Jahanian <fjahanian@apple.com>2010-01-04 19:50:07 +0000
commitf381cc90d6cfa0966ddf791db57a6ed6c2462b5d (patch)
tree659cd14db5f16b3aa67555ac1c12207fe1adb934 /lib/Frontend/RewriteObjC.cpp
parent1733c35f44b3a044997ad98f10fbf3b3e1827841 (diff)
More rewriting of __block declared objective-c/block pointers.
This is wip. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@92501 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/RewriteObjC.cpp')
-rw-r--r--lib/Frontend/RewriteObjC.cpp61
1 files changed, 45 insertions, 16 deletions
diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp
index c3474728a6..835c931bd3 100644
--- a/lib/Frontend/RewriteObjC.cpp
+++ b/lib/Frontend/RewriteObjC.cpp
@@ -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());