[cfe-commits] r84590 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/Frontend/PCHBitCodes.h lib/AST/ASTContext.cpp lib/CodeGen/CGBlocks.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp

Mike Stump mrs at apple.com
Mon Oct 19 19:12:23 PDT 2009


Author: mrs
Date: Mon Oct 19 21:12:22 2009
New Revision: 84590

URL: http://llvm.org/viewvc/llvm-project?rev=84590&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=84590&r1=84589&r2=84590&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Oct 19 21:12:22 2009
@@ -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);

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=84590&r1=84589&r2=84590&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Mon Oct 19 21:12:22 2009
@@ -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.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=84590&r1=84589&r2=84590&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Mon Oct 19 21:12:22 2009
@@ -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");

Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=84590&r1=84589&r2=84590&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Mon Oct 19 21:12:22 2009
@@ -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);

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=84590&r1=84589&r2=84590&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Mon Oct 19 21:12:22 2009
@@ -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

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=84590&r1=84589&r2=84590&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Mon Oct 19 21:12:22 2009
@@ -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





More information about the cfe-commits mailing list