diff options
-rw-r--r-- | include/clang/AST/ASTContext.h | 20 | ||||
-rw-r--r-- | include/clang/Frontend/PCHBitCodes.h | 4 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 57 | ||||
-rw-r--r-- | lib/CodeGen/CGBlocks.cpp | 9 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 1 |
6 files changed, 86 insertions, 8 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 5730aaa8e4..c3ac2ea82d 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -147,6 +147,9 @@ class ASTContext { /// \brief Type for the Block descriptor for Blocks CodeGen. RecordDecl *BlockDescriptorType; + /// \brief Type for the Block descriptor for Blocks CodeGen. + RecordDecl *BlockDescriptorExtendedType; + /// \brief Keeps track of all declaration attributes. /// /// Since so few decls have attrs, we keep them in a hash map instead of @@ -407,9 +410,24 @@ public: return QualType(); } + /// This gets the struct used to keep track of the extended descriptor for + /// pointer to blocks. + QualType getBlockDescriptorExtendedType(); + + // Set the type for a Block descriptor extended type. + void setBlockDescriptorExtendedType(QualType T); + /// Get the BlockDescriptorExtendedType type, or NULL if it hasn't yet been + /// built. + QualType getRawBlockdescriptorExtendedType() { + if (BlockDescriptorExtendedType) + return getTagDeclType(BlockDescriptorExtendedType); + return QualType(); + } + /// This gets the struct used to keep track of pointer to blocks, complete /// with captured variables. - QualType getBlockParmType(llvm::SmallVector<const Expr *, 8> &BDRDs); + QualType getBlockParmType(bool BlockHasCopyDispose, + llvm::SmallVector<const Expr *, 8> &BDRDs); /// This builds the struct used for __block variables. QualType BuildByRefType(const char *DeclName, QualType Ty); diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index dcabcb3187..d83a020ecf 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -438,7 +438,9 @@ namespace clang { /// \brief Objective-C "Class" redefinition type SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 11, /// \brief Block descriptor type for Blocks CodeGen - SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12 + SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12, + /// \brief Block extedned descriptor type for Blocks CodeGen + SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13 }; /// \brief Record codes for each kind of declaration. diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 42a6704d8a..442714a5a6 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -40,7 +40,8 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, bool FreeMem, unsigned size_reserve) : GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0), - sigjmp_bufDecl(0), BlockDescriptorType(0), SourceMgr(SM), LangOpts(LOpts), + sigjmp_bufDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0), + SourceMgr(SM), LangOpts(LOpts), LoadedExternalComments(false), FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels), BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) { @@ -2714,7 +2715,7 @@ QualType ASTContext::getBlockDescriptorType() { const char *FieldNames[] = { "reserved", - "Size", + "Size" }; for (size_t i = 0; i < 2; ++i) { @@ -2741,6 +2742,53 @@ void ASTContext::setBlockDescriptorType(QualType T) { BlockDescriptorType = Rec->getDecl(); } +QualType ASTContext::getBlockDescriptorExtendedType() { + if (BlockDescriptorExtendedType) + return getTagDeclType(BlockDescriptorExtendedType); + + RecordDecl *T; + // FIXME: Needs the FlagAppleBlock bit. + T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + &Idents.get("__block_descriptor_withcopydispose")); + + QualType FieldTypes[] = { + UnsignedLongTy, + UnsignedLongTy, + getPointerType(VoidPtrTy), + getPointerType(VoidPtrTy) + }; + + const char *FieldNames[] = { + "reserved", + "Size", + "CopyFuncPtr", + "DestroyFuncPtr" + }; + + for (size_t i = 0; i < 4; ++i) { + FieldDecl *Field = FieldDecl::Create(*this, + T, + SourceLocation(), + &Idents.get(FieldNames[i]), + FieldTypes[i], /*DInfo=*/0, + /*BitWidth=*/0, + /*Mutable=*/false); + T->addDecl(Field); + } + + T->completeDefinition(*this); + + BlockDescriptorExtendedType = T; + + return getTagDeclType(BlockDescriptorExtendedType); +} + +void ASTContext::setBlockDescriptorExtendedType(QualType T) { + const RecordType *Rec = T->getAs<RecordType>(); + assert(Rec && "Invalid BlockDescriptorType"); + BlockDescriptorExtendedType = Rec->getDecl(); +} + bool ASTContext::BlockRequiresCopying(QualType Ty) { if (Ty->isBlockPointerType()) return true; @@ -2811,6 +2859,7 @@ QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) { QualType ASTContext::getBlockParmType( + bool BlockHasCopyDispose, llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) { // FIXME: Move up static int UniqueBlockParmTypeID = 0; @@ -2824,7 +2873,9 @@ QualType ASTContext::getBlockParmType( IntTy, IntTy, getPointerType(VoidPtrTy), - getPointerType(getBlockDescriptorType()), + (BlockHasCopyDispose ? + getPointerType(getBlockDescriptorExtendedType()) : + getPointerType(getBlockDescriptorType())) }; const char *FieldNames[] = { diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 26b19e56bc..dc4db4ac2c 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -486,8 +486,10 @@ uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { return offset; // Don't run the expensive check, unless we have to. - if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType())) - BlockHasCopyDispose = true; + if (!BlockHasCopyDispose) + if (E->isByRef() + || BlockRequiresCopying(E->getType())) + BlockHasCopyDispose = true; // if not, allocate one now. offset = getBlockOffset(E); @@ -680,7 +682,8 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, // Allocate all BlockDeclRefDecls, so we can calculate the right ParmTy below. AllocateAllBlockDeclRefs(Info, this); - QualType ParmTy = getContext().getBlockParmType(BlockDeclRefDecls); + QualType ParmTy = getContext().getBlockParmType(BlockHasCopyDispose, + BlockDeclRefDecls); // FIXME: This leaks ImplicitParamDecl *SelfDecl = ImplicitParamDecl::Create(getContext(), 0, diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 82e5033dd8..c02959f2cc 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -1591,6 +1591,9 @@ void PCHReader::InitializeContext(ASTContext &Ctx) { Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef); if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_DESCRIPTOR]) Context->setBlockDescriptorType(GetType(String)); + if (unsigned String + = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR]) + Context->setBlockDescriptorExtendedType(GetType(String)); } /// \brief Retrieve the name of the original source file name diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index c2530472f2..c98080a38b 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -1988,6 +1988,7 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls, AddTypeRef(Context.ObjCIdRedefinitionType, Record); AddTypeRef(Context.ObjCClassRedefinitionType, Record); AddTypeRef(Context.getRawBlockdescriptorType(), Record); + AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record); Stream.EmitRecord(pch::SPECIAL_TYPES, Record); // Keep writing types and declarations until all types and |