[cfe-commits] r84737 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGBlocks.h lib/CodeGen/CodeGenFunction.h

Mike Stump mrs at apple.com
Tue Oct 20 20:49:15 PDT 2009


Author: mrs
Date: Tue Oct 20 22:49:08 2009
New Revision: 84737

URL: http://llvm.org/viewvc/llvm-project?rev=84737&view=rev
Log:
Prep work to always preallocate BlockDeclRefExprs so that we can
generate the debug information for the first parameter to the block
invoke functions.  WIP.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/CodeGen/CGBlocks.cpp
    cfe/trunk/lib/CodeGen/CGBlocks.h
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Oct 20 22:49:08 2009
@@ -409,11 +409,10 @@
 
   /// This gets the struct used to keep track of pointer to blocks, complete
   /// with captured variables.
-  QualType getBlockParmType();
+  QualType getBlockParmType(llvm::SmallVector<const Expr *, 8> &BDRDs);
 
-  /// This completes a type created by getBlockParmType.
-  void completeBlockParmType(QualType Ty,
-                         llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls);
+  /// This builds the struct used for __block variables.
+  QualType BuildByRefType(QualType Ty);
 
   /// getLValueReferenceType - Return the uniqued reference to the type for an
   /// lvalue reference to the specified type.

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Oct 20 22:49:08 2009
@@ -2741,7 +2741,22 @@
   BlockDescriptorType = Rec->getDecl();
 }
 
-QualType ASTContext::getBlockParmType() {
+QualType ASTContext::BuildByRefType(QualType Ty) {
+  //  type = struct __Block_byref_1_done {
+  //    void *__isa;
+  //    struct __Block_byref_1_done *__forwarding;
+  //    unsigned int __flags;
+  //    unsigned int __size;
+  //    int done;
+  //  } *
+
+  // FIXME: Build up reference type.
+  return getPointerType(VoidPtrTy);
+}
+
+
+QualType ASTContext::getBlockParmType(
+  llvm::SmallVector<const Expr *, 8> &BlockDeclRefDecls) {
   // FIXME: Move up
   static int UniqueBlockParmTypeID = 0;
   char Name[36];
@@ -2749,30 +2764,6 @@
   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,
@@ -2790,19 +2781,35 @@
   };
 
   for (size_t i = 0; i < 5; ++i) {
-    FieldDecl *Field = FieldDecl::Create(*this,
-                                         T,
-                                         SourceLocation(),
+    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);
+                                         /*BitWidth=*/0, /*Mutable=*/false);
+    T->addDecl(Field);
+  }
+
+  for (size_t i = 0; i < BlockDeclRefDecls.size(); ++i) {
+    const Expr *E = BlockDeclRefDecls[i];
+    const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E);
+    clang::IdentifierInfo *Name = 0;
+    if (BDRE) {
+      const ValueDecl *D = BDRE->getDecl();
+      Name = &Idents.get(D->getName());
+    }
+    QualType FieldType = E->getType();
+
+    if (BDRE && BDRE->isByRef())
+      FieldType = BuildByRefType(FieldType);
+
+    FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
+                                         Name, FieldType, /*DInfo=*/0,
+                                         /*BitWidth=*/0, /*Mutable=*/false);
     T->addDecl(Field);
   }
 
   T->completeDefinition(*this);
+
+  return getPointerType(getTagDeclType(T));
 }
 
 void ASTContext::setObjCFastEnumerationStateType(QualType T) {

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue Oct 20 22:49:08 2009
@@ -80,22 +80,48 @@
     if (*I)
       CollectBlockDeclRefInfo(*I, Info);
 
+  // We want to ensure we walk down into block literals so we can find
+  // all nested BlockDeclRefExprs.
+  if (const BlockExpr *BE = dyn_cast<BlockExpr>(S))
+    CollectBlockDeclRefInfo(BE->getBody(), Info);
+
   if (const BlockDeclRefExpr *DE = dyn_cast<BlockDeclRefExpr>(S)) {
     // FIXME: Handle enums.
     if (isa<FunctionDecl>(DE->getDecl()))
       return;
 
-    if (DE->isByRef())
-      Info.ByRefDeclRefs.push_back(DE);
-    else
-      Info.ByCopyDeclRefs.push_back(DE);
+    Info.DeclRefs.push_back(DE);
   }
 }
 
 /// CanBlockBeGlobal - Given a BlockInfo struct, determines if a block can be
 /// declared as a global variable instead of on the stack.
 static bool CanBlockBeGlobal(const CodeGenFunction::BlockInfo &Info) {
-  return Info.ByRefDeclRefs.empty() && Info.ByCopyDeclRefs.empty();
+  return Info.DeclRefs.empty();
+}
+
+/// AllocateAllBlockDeclRefs - Preallocate all nested BlockDeclRefExprs to
+/// ensure we can generate the debug information for the parameter for the block
+/// invoke function.
+static void AllocateAllBlockDeclRefs(const CodeGenFunction::BlockInfo &Info,
+                                     CodeGenFunction *CGF) {
+  // Always allocate self, as it is often handy in the debugger, even if there
+  // is no codegen in the block that uses it.  This is also useful to always do
+  // this as if we didn't, we'd have to figure out all code that uses a self
+  // pointer, including implicit uses.
+  if (const ObjCMethodDecl *OMD
+      = dyn_cast_or_null<ObjCMethodDecl>(CGF->CurFuncDecl)) {
+    ImplicitParamDecl *SelfDecl = OMD->getSelfDecl();
+    BlockDeclRefExpr *BDRE = new (CGF->getContext())
+      BlockDeclRefExpr(SelfDecl,
+                       SelfDecl->getType(), SourceLocation(), false);
+    CGF->AllocateBlockDecl(BDRE);
+  }
+
+  // FIXME: Also always forward the this pointer in C++ as well.
+
+  for (size_t i = 0; i < Info.DeclRefs.size(); ++i)
+    CGF->AllocateBlockDecl(Info.DeclRefs[i]);
 }
 
 // FIXME: Push most into CGM, passing down a few bits, like current function
@@ -159,7 +185,8 @@
 
     if (subBlockDeclRefDecls.size() == 0) {
       // __descriptor
-      Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize, 0, 0);
+      Elts[4] = BuildDescriptorBlockDecl(subBlockHasCopyDispose, subBlockSize,
+                                         0, 0);
 
       // Optimize to being a global block.
       Elts[0] = CGM.getNSConcreteGlobalBlock();
@@ -269,7 +296,7 @@
             llvm::Value *BlockLiteral = LoadBlockStruct();
 
             Loc = Builder.CreateGEP(BlockLiteral,
-                                    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
                                                            offset),
                                     "block.literal");
             Ty = llvm::PointerType::get(Ty, 0);
@@ -447,24 +474,32 @@
   return EmitCall(FnInfo, Func, Args);
 }
 
-llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
+uint64_t CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) {
   const ValueDecl *VD = E->getDecl();
-  
   uint64_t &offset = BlockDecls[VD];
 
-
   // See if we have already allocated an offset for this variable.
-  if (offset == 0) {
-    // Don't run the expensive check, unless we have to.
-    if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType()))
-      BlockHasCopyDispose = true;
-    // if not, allocate one now.
-    offset = getBlockOffset(E);
-  }
+  if (offset)
+    return offset;
+
+  // Don't run the expensive check, unless we have to.
+  if (!BlockHasCopyDispose && BlockRequiresCopying(E->getType()))
+    BlockHasCopyDispose = true;
+
+  // if not, allocate one now.
+  offset = getBlockOffset(E);
+
+  return offset;
+}
+
+llvm::Value *CodeGenFunction::GetAddrOfBlockDecl(const BlockDeclRefExpr *E) {
+  const ValueDecl *VD = E->getDecl();
+  uint64_t offset = AllocateBlockDecl(E);
+  
 
   llvm::Value *BlockLiteral = LoadBlockStruct();
   llvm::Value *V = Builder.CreateGEP(BlockLiteral,
-                                  llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
+                       llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
                                                          offset),
                                      "block.literal");
   if (E->isByRef()) {
@@ -633,12 +668,19 @@
 
   FunctionArgList Args;
 
+  CurFuncDecl = OuterFuncDecl;
+
   const BlockDecl *BD = BExpr->getBlockDecl();
 
-  IdentifierInfo *II
-    = &CGM.getContext().Idents.get(".block_descriptor");
+  IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
+
+  // Allocate all BlockDeclRefDecls, so we can calculate the the
+  // right ParmTy below.
+  // FIXME: Resolve testsuite problems, then enable.
+  if (0)
+    AllocateAllBlockDeclRefs(Info, this);
 
-  QualType ParmTy = getContext().getBlockParmType();
+  QualType ParmTy = getContext().getBlockParmType(BlockDeclRefDecls);
   // FIXME: This leaks
   ImplicitParamDecl *SelfDecl =
     ImplicitParamDecl::Create(getContext(), 0,
@@ -708,22 +750,6 @@
 
   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);
@@ -781,11 +807,13 @@
   FunctionArgList Args;
   // FIXME: This leaks
   ImplicitParamDecl *Dst =
-    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
                               getContext().getPointerType(getContext().VoidTy));
   Args.push_back(std::make_pair(Dst, Dst->getType()));
   ImplicitParamDecl *Src =
-    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
                               getContext().getPointerType(getContext().VoidTy));
   Args.push_back(std::make_pair(Src, Src->getType()));
 
@@ -866,7 +894,8 @@
   FunctionArgList Args;
   // FIXME: This leaks
   ImplicitParamDecl *Src =
-    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
                               getContext().getPointerType(getContext().VoidTy));
 
   Args.push_back(std::make_pair(Src, Src->getType()));
@@ -945,13 +974,15 @@
   FunctionArgList Args;
   // FIXME: This leaks
   ImplicitParamDecl *Dst =
-    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
                               getContext().getPointerType(getContext().VoidTy));
   Args.push_back(std::make_pair(Dst, Dst->getType()));
 
   // FIXME: This leaks
   ImplicitParamDecl *Src =
-    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
                               getContext().getPointerType(getContext().VoidTy));
   Args.push_back(std::make_pair(Src, Src->getType()));
 
@@ -1014,7 +1045,8 @@
   FunctionArgList Args;
   // FIXME: This leaks
   ImplicitParamDecl *Src =
-    ImplicitParamDecl::Create(getContext(), 0, SourceLocation(), 0,
+    ImplicitParamDecl::Create(getContext(), 0,
+                              SourceLocation(), 0,
                               getContext().getPointerType(getContext().VoidTy));
 
   Args.push_back(std::make_pair(Src, Src->getType()));

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.h (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.h Tue Oct 20 22:49:08 2009
@@ -165,11 +165,7 @@
 
     /// ByCopyDeclRefs - Variables from parent scopes that have been imported
     /// into this block.
-    llvm::SmallVector<const BlockDeclRefExpr *, 8> ByCopyDeclRefs;
-
-    // ByRefDeclRefs - __block variables from parent scopes that have been
-    // imported into this block.
-    llvm::SmallVector<const BlockDeclRefExpr *, 8> ByRefDeclRefs;
+    llvm::SmallVector<const BlockDeclRefExpr *, 8> DeclRefs;
 
     BlockInfo(const llvm::Type *blt, const char *n)
       : BlockLiteralTy(blt), Name(n) {

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=84737&r1=84736&r2=84737&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Oct 20 22:49:08 2009
@@ -356,6 +356,7 @@
   void BlockForwardSelf();
   llvm::Value *LoadBlockStruct();
 
+  uint64_t AllocateBlockDecl(const BlockDeclRefExpr *E);
   llvm::Value *GetAddrOfBlockDecl(const BlockDeclRefExpr *E);
   const llvm::Type *BuildByRefType(const ValueDecl *D);
 





More information about the cfe-commits mailing list