From 9496790211a6c4c398c55bfd8cac370a4ef4c835 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Wed, 21 Oct 2009 18:16:27 +0000 Subject: [PATCH] Complete out debug info generation for captured __block variables. WIP. llvm-svn: 84768 --- clang/include/clang/AST/ASTContext.h | 5 +- clang/lib/AST/ASTContext.cpp | 70 +++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 3ab2a0b1eae6..5730aaa8e4b7 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -412,7 +412,10 @@ public: QualType getBlockParmType(llvm::SmallVector &BDRDs); /// This builds the struct used for __block variables. - QualType BuildByRefType(QualType Ty); + QualType BuildByRefType(const char *DeclName, QualType Ty); + + /// Returns true iff we need copy/dispose helpers for the given type. + bool BlockRequiresCopying(QualType Ty); /// getLValueReferenceType - Return the uniqued reference to the type for an /// lvalue reference to the specified type. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 673229cd6b58..4a0df6bf0277 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2741,17 +2741,72 @@ void ASTContext::setBlockDescriptorType(QualType T) { BlockDescriptorType = Rec->getDecl(); } -QualType ASTContext::BuildByRefType(QualType Ty) { - // type = struct __Block_byref_1_done { +bool ASTContext::BlockRequiresCopying(QualType Ty) { + if (Ty->isBlockPointerType()) + return true; + if (isObjCNSObjectType(Ty)) + return true; + if (Ty->isObjCObjectPointerType()) + return true; + return false; +} + +QualType ASTContext::BuildByRefType(const char *DeclName, QualType Ty) { + // type = struct __Block_byref_1_X { // void *__isa; - // struct __Block_byref_1_done *__forwarding; + // struct __Block_byref_1_X *__forwarding; // unsigned int __flags; // unsigned int __size; - // int done; + // void *__copy_helper; + // void *__destroy_helper; + // int X; // } * - // FIXME: Build up reference type. - return getPointerType(VoidPtrTy); + bool HasCopyAndDispose = BlockRequiresCopying(Ty); + + // FIXME: Move up + static int UniqueBlockByRefTypeID = 0; + char Name[36]; + sprintf(Name, "__Block_byref_%d_%s", ++UniqueBlockByRefTypeID, DeclName); + RecordDecl *T; + T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(), + &Idents.get(Name)); + T->startDefinition(); + QualType Int32Ty = IntTy; + assert(getIntWidth(IntTy) == 32 && "non-32bit int not supported"); + QualType FieldTypes[] = { + getPointerType(VoidPtrTy), + getPointerType(getTagDeclType(T)), + Int32Ty, + Int32Ty, + getPointerType(VoidPtrTy), + getPointerType(VoidPtrTy), + Ty + }; + + const char *FieldNames[] = { + "__isa", + "__forwarding", + "__flags", + "__size", + "__copy_helper", + "__destroy_helper", + DeclName, + }; + + for (size_t i = 0; i < 7; ++i) { + if (!HasCopyAndDispose && i >=4 && i <= 5) + continue; + 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); + + return getPointerType(getTagDeclType(T)); } @@ -2799,7 +2854,8 @@ QualType ASTContext::getBlockParmType( QualType FieldType = E->getType(); if (BDRE && BDRE->isByRef()) - FieldType = BuildByRefType(FieldType); + FieldType = BuildByRefType(BDRE->getDecl()->getNameAsCString(), + FieldType); FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(), Name, FieldType, /*DInfo=*/0,