forked from OSchip/llvm-project
Block C++ code gen. Adds support for block reference argument
types. Executable test will be added to LLVM test suite. (radar 8041962). llvm-svn: 105347
This commit is contained in:
parent
6a7f9f5c8f
commit
d1b378e08d
|
@ -296,8 +296,11 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
|
|||
const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
|
||||
QualType Ty = E->getType();
|
||||
if (BDRE && BDRE->isByRef()) {
|
||||
Types[i+BlockFields] = llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0);
|
||||
} else
|
||||
Types[i+BlockFields] =
|
||||
llvm::PointerType::get(BuildByRefType(BDRE->getDecl()), 0);
|
||||
} else if (BDRE && BDRE->getDecl()->getType()->isReferenceType()) {
|
||||
Types[i+BlockFields] = llvm::PointerType::get(ConvertType(Ty), 0);
|
||||
} else
|
||||
Types[i+BlockFields] = ConvertType(Ty);
|
||||
}
|
||||
|
||||
|
@ -359,8 +362,13 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) {
|
|||
continue;
|
||||
} else {
|
||||
E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD),
|
||||
VD->getType(),
|
||||
SourceLocation());
|
||||
VD->getType().getNonReferenceType(),
|
||||
SourceLocation());
|
||||
if (VD->getType()->isReferenceType())
|
||||
E = new (getContext())
|
||||
UnaryOperator(const_cast<Expr*>(E), UnaryOperator::AddrOf,
|
||||
getContext().getPointerType(E->getType()),
|
||||
SourceLocation());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -629,6 +637,8 @@ llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const ValueDecl *VD,
|
|||
|
||||
Ty = llvm::PointerType::get(Ty, 0);
|
||||
V = Builder.CreateBitCast(V, Ty);
|
||||
if (VD->getType()->isReferenceType())
|
||||
V = Builder.CreateLoad(V, "tmp");
|
||||
}
|
||||
return V;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang_cc1 -fblocks %s -emit-llvm -o %t
|
||||
// rdar: // 8041962
|
||||
|
||||
extern "C" int printf(const char*, ...);
|
||||
|
||||
struct ST {
|
||||
int filler;
|
||||
int referrer;
|
||||
};
|
||||
|
||||
void OUTER_BLOCK(void (^fixer)(ST& ref)) {
|
||||
ST ref = {2, 100};
|
||||
fixer(ref);
|
||||
}
|
||||
|
||||
void INNER_BLOCK(int (^largeDo) ()) {
|
||||
printf("%d\n", largeDo());
|
||||
}
|
||||
|
||||
void scan() {
|
||||
OUTER_BLOCK(^(ST &ref) {
|
||||
INNER_BLOCK(^() { return ref.referrer + ref.filler; });
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
int main() {
|
||||
scan();
|
||||
}
|
Loading…
Reference in New Issue