Refine the type of the first parameter to block invoke functions.
WIP. I have yet to find the magic incantation to get the structure
type to be defined. If someone has a pointer, love to hear it.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84590 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 493d8ac..df480e9 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -144,6 +144,9 @@
/// \brief The type for the C sigjmp_buf type.
TypeDecl *sigjmp_bufDecl;
+ /// \brief Type for the Block descriptor for Blocks CodeGen.
+ RecordDecl *BlockDescriptorType;
+
/// \brief Keeps track of all declaration attributes.
///
/// Since so few decls have attrs, we keep them in a hash map instead of
@@ -391,6 +394,27 @@
/// of the specified type.
QualType getBlockPointerType(QualType T);
+ /// This gets the struct used to keep track of the descriptor for pointer to
+ /// blocks.
+ QualType getBlockDescriptorType();
+
+ // Set the type for a Block descriptor type.
+ void setBlockDescriptorType(QualType T);
+ /// Get the BlockDescriptorType type, or NULL if it hasn't yet been built.
+ QualType getRawBlockdescriptorType() {
+ if (BlockDescriptorType)
+ return getTagDeclType(BlockDescriptorType);
+ return QualType();
+ }
+
+ /// This gets the struct used to keep track of pointer to blocks, complete
+ /// with captured variables.
+ QualType getBlockParmType();
+
+ /// This completes a type created by getBlockParmType.
+ void completeBlockParmType(QualType Ty,
+ llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls);
+
/// getLValueReferenceType - Return the uniqued reference to the type for an
/// lvalue reference to the specified type.
QualType getLValueReferenceType(QualType T);
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index e4161fc..dcabcb3 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -436,7 +436,9 @@
/// \brief Objective-C "id" redefinition type
SPECIAL_TYPE_OBJC_ID_REDEFINITION = 10,
/// \brief Objective-C "Class" redefinition type
- SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 11
+ SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 11,
+ /// \brief Block descriptor type for Blocks CodeGen
+ SPECIAL_TYPE_BLOCK_DESCRIPTOR = 12
};
/// \brief Record codes for each kind of declaration.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index d96f5fb..98aef39 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -40,7 +40,7 @@
bool FreeMem, unsigned size_reserve) :
GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),
ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0),
- sigjmp_bufDecl(0), SourceMgr(SM), LangOpts(LOpts),
+ sigjmp_bufDecl(0), BlockDescriptorType(0), SourceMgr(SM), LangOpts(LOpts),
LoadedExternalComments(false), FreeMemory(FreeMem), Target(t),
Idents(idents), Selectors(sels),
BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
@@ -2692,6 +2692,113 @@
return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
}
+QualType ASTContext::getBlockDescriptorType() {
+ if (BlockDescriptorType)
+ return getTagDeclType(BlockDescriptorType);
+
+ RecordDecl *T;
+ // FIXME: Needs the FlagAppleBlock bit.
+ T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get("__block_descriptor"));
+
+ QualType FieldTypes[] = {
+ UnsignedLongTy,
+ UnsignedLongTy,
+ };
+
+ const char *FieldNames[] = {
+ "reserved",
+ "Size",
+ };
+
+ for (size_t i = 0; i < 2; ++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);
+
+ BlockDescriptorType = T;
+
+ return getTagDeclType(BlockDescriptorType);
+}
+
+void ASTContext::setBlockDescriptorType(QualType T) {
+ const RecordType *Rec = T->getAs<RecordType>();
+ assert(Rec && "Invalid BlockDescriptorType");
+ BlockDescriptorType = Rec->getDecl();
+}
+
+QualType ASTContext::getBlockParmType() {
+ // FIXME: Move up
+ static int UniqueBlockParmTypeID = 0;
+ char Name[36];
+ sprintf(Name, "__block_literal_%u", ++UniqueBlockParmTypeID);
+ RecordDecl *T;
+ T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get(Name));
+
+#define REV2
+#ifdef REV2
+ cast<TagDecl>(T)->startDefinition();
+#endif
+
+ return getPointerType(getTagDeclType(T));
+}
+
+void ASTContext::completeBlockParmType(QualType Ty,
+ llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
+ RecordDecl *PT = Ty->getPointeeType()->getAs<RecordType>()->getDecl();
+ llvm::StringRef Name = PT->getIdentifier()->getName();
+
+ RecordDecl *T;
+#ifdef REV2
+ T = PT;
+#else
+ T = RecordDecl::Create(*this, TagDecl::TK_struct, TUDecl, SourceLocation(),
+ &Idents.get(Name), SourceLocation(), PT);
+
+ cast<TagDecl>(T)->startDefinition();
+#endif
+
+ QualType FieldTypes[] = {
+ getPointerType(VoidPtrTy),
+ IntTy,
+ IntTy,
+ getPointerType(VoidPtrTy),
+ getPointerType(getBlockDescriptorType()),
+ };
+
+ const char *FieldNames[] = {
+ "__isa",
+ "__flags",
+ "__reserved",
+ "__FuncPtr",
+ "__descriptor"
+ };
+
+ for (size_t i = 0; i < 5; ++i) {
+ FieldDecl *Field = FieldDecl::Create(*this,
+ T,
+ SourceLocation(),
+ &Idents.get(FieldNames[i]),
+ FieldTypes[i], /*DInfo=*/0,
+ /*BitWidth=*/0,
+ /*Mutable=*/false);
+ // FIXME: Do this instead or addDecl?
+ // PushOnScopeChains(FieldTypes, S);
+ T->addDecl(Field);
+ }
+
+ T->completeDefinition(*this);
+}
+
void ASTContext::setObjCFastEnumerationStateType(QualType T) {
const RecordType *Rec = T->getAs<RecordType>();
assert(Rec && "Invalid ObjCFAstEnumerationStateType");
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 736425e..5998493 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -632,11 +632,15 @@
const BlockDecl *BD = BExpr->getBlockDecl();
+ IdentifierInfo *II
+ = &CGM.getContext().Idents.get(".block_descriptor");
+
+ QualType ParmTy = getContext().getBlockParmType();
// FIXME: This leaks
ImplicitParamDecl *SelfDecl =
ImplicitParamDecl::Create(getContext(), 0,
- SourceLocation(), 0,
- getContext().getPointerType(getContext().VoidTy));
+ SourceLocation(), II,
+ ParmTy);
Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));
BlockStructDecl = SelfDecl;
@@ -701,6 +705,22 @@
FinishFunction(cast<CompoundStmt>(BExpr->getBody())->getRBracLoc());
+ // And now finish off the type for the parameter, since now we know
+ // BlockDeclRefDecls is complete.
+ getContext().completeBlockParmType(ParmTy, BlockDeclRefDecls);
+
+#define REV2
+#ifdef REV2
+ TagDecl *TD = ParmTy->getPointeeType()->getAs<RecordType>()->getDecl();
+ CGM.UpdateCompletedType(TD);
+#else
+ TagDecl *TD = ParmTy->getPointeeType()->getAs<RecordType>()->getDecl();
+ TagDecl::redecl_iterator rdi = TD->redecls_begin();
+ ++rdi;
+ TD = *rdi;
+ CGM.UpdateCompletedType(TD);
+#endif
+
// The runtime needs a minimum alignment of a void *.
uint64_t MinAlign = getContext().getTypeAlign(getContext().VoidPtrTy) / 8;
BlockOffset = llvm::RoundUpToAlignment(BlockOffset, MinAlign);
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index ef73da7..82e5033 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -1589,6 +1589,8 @@
if (unsigned ObjCClassRedef
= SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])
Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef);
+ if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_DESCRIPTOR])
+ Context->setBlockDescriptorType(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 dbe1e99..c253047 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1987,6 +1987,7 @@
AddTypeRef(Context.getsigjmp_bufType(), Record);
AddTypeRef(Context.ObjCIdRedefinitionType, Record);
AddTypeRef(Context.ObjCClassRedefinitionType, Record);
+ AddTypeRef(Context.getRawBlockdescriptorType(), Record);
Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
// Keep writing types and declarations until all types and