Make the forwarding member of block byref structs be a pointer to the block byref struct itself.

llvm-svn: 81423
This commit is contained in:
Anders Carlsson 2009-09-10 01:32:12 +00:00
parent f6b2404a84
commit 10f2c10b83
2 changed files with 19 additions and 12 deletions

View File

@ -223,8 +223,11 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const ValueDecl *D) {
std::vector<const llvm::Type *> Types(needsCopyDispose*2+5); std::vector<const llvm::Type *> Types(needsCopyDispose*2+5);
const llvm::PointerType *PtrToInt8Ty const llvm::PointerType *PtrToInt8Ty
= llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext)); = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext));
llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(VMContext);
Types[0] = PtrToInt8Ty; Types[0] = PtrToInt8Ty;
Types[1] = PtrToInt8Ty; Types[1] = llvm::PointerType::getUnqual(ByRefTypeHolder);
Types[2] = llvm::Type::getInt32Ty(VMContext); Types[2] = llvm::Type::getInt32Ty(VMContext);
Types[3] = llvm::Type::getInt32Ty(VMContext); Types[3] = llvm::Type::getInt32Ty(VMContext);
if (needsCopyDispose) { if (needsCopyDispose) {
@ -235,7 +238,14 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const ValueDecl *D) {
assert((Align <= unsigned(Target.getPointerAlign(0))/8) assert((Align <= unsigned(Target.getPointerAlign(0))/8)
&& "Can't align more than pointer yet"); && "Can't align more than pointer yet");
Types[needsCopyDispose*2 + 4] = LTy; Types[needsCopyDispose*2 + 4] = LTy;
return llvm::StructType::get(VMContext, Types, false);
const llvm::Type *T = llvm::StructType::get(VMContext, Types, false);
cast<llvm::OpaqueType>(ByRefTypeHolder.get())->refineAbstractTypeTo(T);
CGM.getModule().addTypeName("struct.__block_byref_" + D->getNameAsString(),
ByRefTypeHolder.get());
return ByRefTypeHolder.get();
} }
/// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a /// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a
@ -413,8 +423,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "isa"); V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "isa");
Builder.CreateStore(V, isa_field); Builder.CreateStore(V, isa_field);
V = Builder.CreateBitCast(DeclPtr, PtrToInt8Ty, "forwarding"); Builder.CreateStore(DeclPtr, forwarding_field);
Builder.CreateStore(V, forwarding_field);
V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags); V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags);
Builder.CreateStore(V, flags_field); Builder.CreateStore(V, flags_field);

View File

@ -2,14 +2,12 @@
// builds with and without asserts. We need a better solution for this. // builds with and without asserts. We need a better solution for this.
// RUN: clang-cc -fblocks -triple x86_64-apple-darwin10 -emit-llvm-bc -o - %s | opt -strip | llvm-dis > %t && // RUN: clang-cc -fblocks -triple x86_64-apple-darwin10 -emit-llvm-bc -o - %s | opt -strip | llvm-dis > %t &&
// RUN: grep '%7 = call i32 (...)\* @rhs()' %t | count 1 && // RUN: grep '%6 = call i32 (...)\* @rhs()' %t | count 1 &&
// RUN: grep '%8 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 && // RUN: grep '%7 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 &&
// RUN: grep '%9 = bitcast i8\*\* %8 to %0\*\*' %t | count 1 && // RUN: grep '%8 = load %0\*\* %7' %t | count 1 &&
// RUN: grep '%10 = load %0\*\* %9' %t | count 1 && // RUN: grep '%10 = call i32 (...)\* @rhs()' %t | count 1 &&
// RUN: grep '%12 = call i32 (...)\* @rhs()' %t | count 1 && // RUN: grep '%11 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 &&
// RUN: grep '%13 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 && // RUN: grep '%12 = load %0\*\* %11' %t | count 1
// RUN: grep '%14 = bitcast i8\*\* %13 to %0\*\*' %t | count 1 &&
// RUN: grep '%15 = load %0\*\* %14' %t | count 1
int rhs(); int rhs();