From 10f2c10b830a395f00d9f59194507a9d6ad21f03 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Thu, 10 Sep 2009 01:32:12 +0000 Subject: [PATCH] Make the forwarding member of block byref structs be a pointer to the block byref struct itself. llvm-svn: 81423 --- clang/lib/CodeGen/CGDecl.cpp | 17 +++++++++++++---- clang/test/CodeGen/blocks-seq.c | 14 ++++++-------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index ec8f626df5c6..5abe31e25272 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -223,8 +223,11 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const ValueDecl *D) { std::vector Types(needsCopyDispose*2+5); const llvm::PointerType *PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::getInt8Ty(VMContext)); + + llvm::PATypeHolder ByRefTypeHolder = llvm::OpaqueType::get(VMContext); + Types[0] = PtrToInt8Ty; - Types[1] = PtrToInt8Ty; + Types[1] = llvm::PointerType::getUnqual(ByRefTypeHolder); Types[2] = llvm::Type::getInt32Ty(VMContext); Types[3] = llvm::Type::getInt32Ty(VMContext); if (needsCopyDispose) { @@ -235,7 +238,14 @@ const llvm::Type *CodeGenFunction::BuildByRefType(const ValueDecl *D) { assert((Align <= unsigned(Target.getPointerAlign(0))/8) && "Can't align more than pointer yet"); Types[needsCopyDispose*2 + 4] = LTy; - return llvm::StructType::get(VMContext, Types, false); + + const llvm::Type *T = llvm::StructType::get(VMContext, Types, false); + + cast(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 @@ -413,8 +423,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) { V = Builder.CreateIntToPtr(V, PtrToInt8Ty, "isa"); Builder.CreateStore(V, isa_field); - V = Builder.CreateBitCast(DeclPtr, PtrToInt8Ty, "forwarding"); - Builder.CreateStore(V, forwarding_field); + Builder.CreateStore(DeclPtr, forwarding_field); V = llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), flags); Builder.CreateStore(V, flags_field); diff --git a/clang/test/CodeGen/blocks-seq.c b/clang/test/CodeGen/blocks-seq.c index eac2acd3dd6f..3ff241e3f6e3 100644 --- a/clang/test/CodeGen/blocks-seq.c +++ b/clang/test/CodeGen/blocks-seq.c @@ -2,14 +2,12 @@ // 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: grep '%7 = call i32 (...)\* @rhs()' %t | count 1 && -// RUN: grep '%8 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 && -// RUN: grep '%9 = bitcast i8\*\* %8 to %0\*\*' %t | count 1 && -// RUN: grep '%10 = load %0\*\* %9' %t | count 1 && -// RUN: grep '%12 = call i32 (...)\* @rhs()' %t | count 1 && -// RUN: grep '%13 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 && -// RUN: grep '%14 = bitcast i8\*\* %13 to %0\*\*' %t | count 1 && -// RUN: grep '%15 = load %0\*\* %14' %t | count 1 +// RUN: grep '%6 = call i32 (...)\* @rhs()' %t | count 1 && +// RUN: grep '%7 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 && +// RUN: grep '%8 = load %0\*\* %7' %t | count 1 && +// RUN: grep '%10 = call i32 (...)\* @rhs()' %t | count 1 && +// RUN: grep '%11 = getelementptr inbounds %0\* %1, i32 0, i32 1' %t | count 1 && +// RUN: grep '%12 = load %0\*\* %11' %t | count 1 int rhs();