forked from OSchip/llvm-project
Patch to do more rewrite of __block variables.
Still WIP. llvm-svn: 91977
This commit is contained in:
parent
4e26c0e52b
commit
02e07737a9
|
@ -324,7 +324,7 @@ namespace {
|
||||||
// Block specific rewrite rules.
|
// Block specific rewrite rules.
|
||||||
void RewriteBlockCall(CallExpr *Exp);
|
void RewriteBlockCall(CallExpr *Exp);
|
||||||
void RewriteBlockPointerDecl(NamedDecl *VD);
|
void RewriteBlockPointerDecl(NamedDecl *VD);
|
||||||
void RewriteByRefVar(NamedDecl *VD);
|
void RewriteByRefVar(VarDecl *VD);
|
||||||
Stmt *RewriteBlockDeclRefExpr(BlockDeclRefExpr *VD);
|
Stmt *RewriteBlockDeclRefExpr(BlockDeclRefExpr *VD);
|
||||||
void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
|
void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
|
||||||
|
|
||||||
|
@ -577,6 +577,8 @@ void RewriteObjC::Initialize(ASTContext &context) {
|
||||||
Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
|
Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
|
||||||
Preamble += "#define __attribute__(X)\n";
|
Preamble += "#define __attribute__(X)\n";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Preamble += "#define __block\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3732,8 +3734,8 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
|
||||||
E = BlockByRefDecls.end(); I != E; ++I) {
|
E = BlockByRefDecls.end(); I != E; ++I) {
|
||||||
S += " ";
|
S += " ";
|
||||||
std::string Name = (*I)->getNameAsString();
|
std::string Name = (*I)->getNameAsString();
|
||||||
Context->getPointerType((*I)->getType()).getAsStringInternal(Name,
|
std::string TypeString = "struct __Block_byref_" + Name + " *";
|
||||||
Context->PrintingPolicy);
|
Name = TypeString + Name;
|
||||||
S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
|
S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
|
||||||
}
|
}
|
||||||
// Next, emit a declaration for all "by copy" declarations.
|
// Next, emit a declaration for all "by copy" declarations.
|
||||||
|
@ -3859,10 +3861,10 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
|
||||||
S += "struct __block_impl *";
|
S += "struct __block_impl *";
|
||||||
Constructor += ", void *" + ArgName;
|
Constructor += ", void *" + ArgName;
|
||||||
} else {
|
} else {
|
||||||
Context->getPointerType((*I)->getType()).getAsStringInternal(FieldName,
|
std::string TypeString = "struct __Block_byref_" + FieldName;
|
||||||
Context->PrintingPolicy);
|
TypeString += " *";
|
||||||
Context->getPointerType((*I)->getType()).getAsStringInternal(ArgName,
|
FieldName = TypeString + FieldName;
|
||||||
Context->PrintingPolicy);
|
ArgName = TypeString + ArgName;
|
||||||
Constructor += ", " + ArgName;
|
Constructor += ", " + ArgName;
|
||||||
}
|
}
|
||||||
S += FieldName + "; // by ref\n";
|
S += FieldName + "; // by ref\n";
|
||||||
|
@ -3897,7 +3899,7 @@ std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag,
|
||||||
Constructor += Name + " = (struct __block_impl *)_";
|
Constructor += Name + " = (struct __block_impl *)_";
|
||||||
else
|
else
|
||||||
Constructor += Name + " = _";
|
Constructor += Name + " = _";
|
||||||
Constructor += Name + ";\n";
|
Constructor += Name + "->__forwarding;\n";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Finish writing the constructor.
|
// Finish writing the constructor.
|
||||||
|
@ -4162,6 +4164,8 @@ void RewriteObjC::RewriteBlockCall(CallExpr *Exp) {
|
||||||
//}
|
//}
|
||||||
Stmt *RewriteObjC::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) {
|
Stmt *RewriteObjC::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) {
|
||||||
// FIXME: Add more elaborate code generation required by the ABI.
|
// FIXME: Add more elaborate code generation required by the ABI.
|
||||||
|
// That is, must generate BYREFVAR->__forwarding->BYREFVAR for each
|
||||||
|
// BDRE where BYREFVAR is name of the variable.
|
||||||
Expr *DerefExpr = new (Context) UnaryOperator(BDRE, UnaryOperator::Deref,
|
Expr *DerefExpr = new (Context) UnaryOperator(BDRE, UnaryOperator::Deref,
|
||||||
Context->getPointerType(BDRE->getType()),
|
Context->getPointerType(BDRE->getType()),
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
|
@ -4322,7 +4326,78 @@ void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RewriteObjC::RewriteByRefVar(NamedDecl *ND) {
|
/// RewriteByRefVar - For each __block typex ND variable this routine transforms
|
||||||
|
/// the declaration into:
|
||||||
|
/// struct __Block_byref_ND {
|
||||||
|
/// void *__isa; // NULL for everything except __weak pointers
|
||||||
|
/// 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
|
||||||
|
/// typex ND;
|
||||||
|
/// };
|
||||||
|
///
|
||||||
|
/// It then replaces declaration of ND variable with:
|
||||||
|
/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag,
|
||||||
|
/// __size=sizeof(struct __Block_byref_ND),
|
||||||
|
/// ND=initializer-if-any};
|
||||||
|
///
|
||||||
|
///
|
||||||
|
void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
|
||||||
|
SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
|
||||||
|
const char *startBuf = SM->getCharacterData(DeclLoc);
|
||||||
|
const char *endBuf = SM->getCharacterData(ND->getLocEnd());
|
||||||
|
std::string Name(ND->getNameAsString());
|
||||||
|
std::string ByrefType = "struct __Block_byref_";
|
||||||
|
ByrefType += Name;
|
||||||
|
ByrefType += " {\n";
|
||||||
|
ByrefType += " void *__isa;\n";
|
||||||
|
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);
|
||||||
|
ByrefType += " " + Name + ";\n";
|
||||||
|
ByrefType += "};\n";
|
||||||
|
// Insert this type in global scope. It is needed by helper function.
|
||||||
|
assert(CurFunctionDef && "RewriteByRefVar - CurFunctionDef is null");
|
||||||
|
SourceLocation FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
|
||||||
|
InsertText(FunLocStart, ByrefType.c_str(), ByrefType.size());
|
||||||
|
|
||||||
|
// struct __Block_byref_ND ND =
|
||||||
|
// {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND),
|
||||||
|
// initializer-if-any};
|
||||||
|
bool hasInit = (ND->getInit() != 0);
|
||||||
|
Name = ND->getNameAsString();
|
||||||
|
ByrefType = "struct __Block_byref_" + Name;
|
||||||
|
if (!hasInit) {
|
||||||
|
ByrefType += " " + Name + " = ";
|
||||||
|
ByrefType += "{0, &" + Name + ", ";
|
||||||
|
// FIXME. Compute the flag.
|
||||||
|
ByrefType += "0, ";
|
||||||
|
ByrefType += "sizeof(struct __Block_byref_" + Name + ")";
|
||||||
|
ByrefType += "};\n";
|
||||||
|
ReplaceText(DeclLoc, endBuf-startBuf+Name.size(),
|
||||||
|
ByrefType.c_str(), ByrefType.size());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SourceLocation startLoc = ND->getInit()->getLocStart();
|
||||||
|
ByrefType += " " + Name;
|
||||||
|
ReplaceText(DeclLoc, endBuf-startBuf,
|
||||||
|
ByrefType.c_str(), ByrefType.size());
|
||||||
|
ByrefType = " = {0, &" + Name + ", ";
|
||||||
|
// FIXME. Compute the flag.
|
||||||
|
ByrefType += "0, ";
|
||||||
|
ByrefType += "sizeof(struct __Block_byref_" + Name + "), ";
|
||||||
|
InsertText(startLoc, ByrefType.c_str(), ByrefType.size());
|
||||||
|
#if 0
|
||||||
|
ByrefType = "};\n";
|
||||||
|
SourceLocation endLoc = ND->getInit()->getLocEnd();
|
||||||
|
InsertText(startLoc, ByrefType.c_str(), ByrefType.size());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4671,8 +4746,9 @@ Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
|
||||||
RewriteBlockPointerDecl(ND);
|
RewriteBlockPointerDecl(ND);
|
||||||
else if (ND->getType()->isFunctionPointerType())
|
else if (ND->getType()->isFunctionPointerType())
|
||||||
CheckFunctionPointerDecl(ND->getType(), ND);
|
CheckFunctionPointerDecl(ND->getType(), ND);
|
||||||
if (ND->hasAttr<BlocksAttr>())
|
if (VarDecl *VD = dyn_cast<VarDecl>(SD))
|
||||||
RewriteByRefVar(ND);
|
if (VD->hasAttr<BlocksAttr>())
|
||||||
|
RewriteByRefVar(VD);
|
||||||
}
|
}
|
||||||
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
|
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(SD)) {
|
||||||
if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
|
if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
|
||||||
|
|
Loading…
Reference in New Issue