[cfe-commits] r126255 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGBlocks.h lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGDecl.cpp lib/CodeGen/CodeGenModule.h

John McCall rjmccall at apple.com
Tue Feb 22 14:38:33 PST 2011


Author: rjmccall
Date: Tue Feb 22 16:38:33 2011
New Revision: 126255

URL: http://llvm.org/viewvc/llvm-project?rev=126255&view=rev
Log:
Emit the structure layout of the block literal parameter to a block
invocation function into the debug info.  Rather than faking up a class,
which is tricky because of the custom layout we do, we just emit a struct
directly from the layout information we've already got.

Also, don't emit an unnecessarily parameter alloca for this "variable".


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/CGDebugInfo.cpp
    cfe/trunk/lib/CodeGen/CGDebugInfo.h
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Feb 22 16:38:33 2011
@@ -552,11 +552,6 @@
     return cudaConfigureCallDecl;
   }
 
-  /// This gets the struct used to keep track of pointer to blocks, complete
-  /// with captured variables.
-  QualType getBlockParmType(bool BlockHasCopyDispose,
-                            llvm::SmallVectorImpl<const Expr *> &Layout) const;
-
   /// This builds the struct used for __block variables.
   QualType BuildByRefType(llvm::StringRef DeclName, QualType Ty) const;
 
@@ -1526,7 +1521,6 @@
 
   /// \brief A counter used to uniquely identify "blocks".
   mutable unsigned int UniqueBlockByRefTypeID;
-  mutable unsigned int UniqueBlockParmTypeID;
   
   friend class DeclContext;
   friend class DeclarationNameTable;

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Feb 22 16:38:33 2011
@@ -205,7 +205,7 @@
   DeclarationNames(*this),
   ExternalSource(0), Listener(0), PrintingPolicy(LOpts),
   LastSDM(0, 0),
-  UniqueBlockByRefTypeID(0), UniqueBlockParmTypeID(0) {
+  UniqueBlockByRefTypeID(0) {
   ObjCIdRedefinitionType = QualType();
   ObjCClassRedefinitionType = QualType();
   ObjCSelRedefinitionType = QualType();    
@@ -3619,78 +3619,6 @@
   return getPointerType(getTagDeclType(T));
 }
 
-
-QualType ASTContext::getBlockParmType(
-  bool BlockHasCopyDispose,
-  llvm::SmallVectorImpl<const Expr *> &Layout) const {
-
-  // FIXME: Move up
-  llvm::SmallString<36> Name;
-  llvm::raw_svector_ostream(Name) << "__block_literal_"
-                                  << ++UniqueBlockParmTypeID;
-  RecordDecl *T;
-  T = CreateRecordDecl(*this, TTK_Struct, TUDecl, SourceLocation(),
-                       &Idents.get(Name.str()));
-  T->startDefinition();
-  QualType FieldTypes[] = {
-    getPointerType(VoidPtrTy),
-    IntTy,
-    IntTy,
-    getPointerType(VoidPtrTy),
-    (BlockHasCopyDispose ?
-     getPointerType(getBlockDescriptorExtendedType()) :
-     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], /*TInfo=*/0,
-                                         /*BitWidth=*/0, /*Mutable=*/false);
-    Field->setAccess(AS_public);
-    T->addDecl(Field);
-  }
-
-  for (unsigned i = 0; i < Layout.size(); ++i) {
-    const Expr *E = Layout[i];
-
-    QualType FieldType = E->getType();
-    IdentifierInfo *FieldName = 0;
-    if (isa<CXXThisExpr>(E)) {
-      FieldName = &Idents.get("this");
-    } else if (const BlockDeclRefExpr *BDRE = dyn_cast<BlockDeclRefExpr>(E)) {
-      const ValueDecl *D = BDRE->getDecl();
-      FieldName = D->getIdentifier();
-      if (BDRE->isByRef())
-        FieldType = BuildByRefType(D->getName(), FieldType);
-    } else {
-      // Padding.
-      assert(isa<ConstantArrayType>(FieldType) &&
-             isa<DeclRefExpr>(E) &&
-             !cast<DeclRefExpr>(E)->getDecl()->getDeclName() &&
-             "doesn't match characteristics of padding decl");
-    }
-
-    FieldDecl *Field = FieldDecl::Create(*this, T, SourceLocation(),
-                                         FieldName, FieldType, /*TInfo=*/0,
-                                         /*BitWidth=*/0, /*Mutable=*/false);
-    Field->setAccess(AS_public);
-    T->addDecl(Field);
-  }
-
-  T->completeDefinition();
-
-  return getPointerType(getTagDeclType(T));
-}
-
 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=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Tue Feb 22 16:38:33 2011
@@ -895,12 +895,9 @@
   QualType selfTy = getContext().VoidPtrTy;
   IdentifierInfo *II = &CGM.getContext().Idents.get(".block_descriptor");
 
-  // FIXME: this leaks, and we only need it very temporarily.
-  ImplicitParamDecl *selfDecl =
-    ImplicitParamDecl::Create(getContext(),
-                              const_cast<BlockDecl*>(blockDecl),
-                              SourceLocation(), II, selfTy);
-  args.push_back(std::make_pair(selfDecl, selfTy));
+  ImplicitParamDecl selfDecl(const_cast<BlockDecl*>(blockDecl),
+                             SourceLocation(), II, selfTy);
+  args.push_back(std::make_pair(&selfDecl, selfTy));
 
   // Now add the rest of the parameters.
   for (BlockDecl::param_const_iterator i = blockDecl->param_begin(),
@@ -928,12 +925,11 @@
                 blockInfo.getBlockExpr()->getBody()->getLocEnd());
   CurFuncDecl = outerFnDecl; // StartFunction sets this to blockDecl
 
-  // Okay.  Undo some of what StartFunction did.  We really don't need
-  // an alloca for the block address;  in theory we could remove it,
-  // but that might do unpleasant things to debug info.
-  llvm::AllocaInst *blockAddrAlloca
-    = cast<llvm::AllocaInst>(LocalDeclMap[selfDecl]);
-  llvm::Value *blockAddr = Builder.CreateLoad(blockAddrAlloca);
+  // Okay.  Undo some of what StartFunction did.
+  
+  // Pull the 'self' reference out of the local decl map.
+  llvm::Value *blockAddr = LocalDeclMap[&selfDecl];
+  LocalDeclMap.erase(&selfDecl);
   BlockPointer = Builder.CreateBitCast(blockAddr,
                                        blockInfo.StructureType->getPointerTo(),
                                        "block");
@@ -1010,7 +1006,7 @@
         continue;
       }
 
-      DI->EmitDeclareOfBlockDeclRefVariable(variable, blockAddrAlloca,
+      DI->EmitDeclareOfBlockDeclRefVariable(variable, BlockPointer,
                                             Builder, blockInfo);
     }
   }

Modified: cfe/trunk/lib/CodeGen/CGBlocks.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.h?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.h (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.h Tue Feb 22 16:38:33 2011
@@ -177,7 +177,6 @@
   const BlockExpr *Block;
   CharUnits BlockSize;
   CharUnits BlockAlign;
-  llvm::SmallVector<const Expr*, 8> BlockLayout;
 
   const Capture &getCapture(const VarDecl *var) const {
     llvm::DenseMap<const VarDecl*, Capture>::const_iterator

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Feb 22 16:38:33 2011
@@ -430,7 +430,7 @@
     llvm::DIFile DefUnit = getOrCreateFile(RD->getLocation());
     unsigned Line = getLineNumber(RD->getLocation());
     llvm::DIDescriptor FDContext =
-      getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()));
+      getContextDescriptor(cast<Decl>(RD->getDeclContext()));
 
     if (RD->isStruct())
       return DBuilder.createStructType(FDContext, RD->getName(), DefUnit,
@@ -571,53 +571,63 @@
   return DbgTy;
 }
 
+llvm::DIType CGDebugInfo::createFieldType(llvm::StringRef name,
+                                          QualType type,
+                                          Expr *bitWidth,
+                                          SourceLocation loc,
+                                          AccessSpecifier AS,
+                                          uint64_t offsetInBits,
+                                          llvm::DIFile tunit) {
+  llvm::DIType debugType = getOrCreateType(type, tunit);
+
+  // Get the location for the field.
+  llvm::DIFile file = getOrCreateFile(loc);
+  unsigned line = getLineNumber(loc);
+
+  uint64_t sizeInBits = 0;
+  unsigned alignInBits = 0;
+  if (!type->isIncompleteArrayType()) {
+    llvm::tie(sizeInBits, alignInBits) = CGM.getContext().getTypeInfo(type);
+
+    if (bitWidth)
+      sizeInBits = bitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
+  }
+
+  unsigned flags = 0;
+  if (AS == clang::AS_private)
+    flags |= llvm::DIDescriptor::FlagPrivate;
+  else if (AS == clang::AS_protected)
+    flags |= llvm::DIDescriptor::FlagProtected;
+
+  return DBuilder.createMemberType(name, file, line, sizeInBits, alignInBits,
+                                   offsetInBits, flags, debugType);
+}
+
 /// CollectRecordFields - A helper function to collect debug info for
 /// record fields. This is used while creating debug info entry for a Record.
 void CGDebugInfo::
-CollectRecordFields(const RecordDecl *RD, llvm::DIFile Unit,
-                    llvm::SmallVectorImpl<llvm::Value *> &EltTys) {
-  unsigned FieldNo = 0;
-  const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
-  for (RecordDecl::field_iterator I = RD->field_begin(),
-                                  E = RD->field_end();
-       I != E; ++I, ++FieldNo) {
-    FieldDecl *Field = *I;
-    llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
-    llvm::StringRef FieldName = Field->getName();
-
-    // Ignore unnamed fields. Do not ignore unnamed records.
-    if (FieldName.empty() && !isa<RecordType>(Field->getType()))
-      continue;
-
-    // Get the location for the field.
-    llvm::DIFile FieldDefUnit = getOrCreateFile(Field->getLocation());
-    unsigned FieldLine = getLineNumber(Field->getLocation());
-    QualType FType = Field->getType();
-    uint64_t FieldSize = 0;
-    unsigned FieldAlign = 0;
-    if (!FType->isIncompleteArrayType()) {
+CollectRecordFields(const RecordDecl *record, llvm::DIFile tunit,
+                    llvm::SmallVectorImpl<llvm::Value *> &elements) {
+  unsigned fieldNo = 0;
+  const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(record);
+  for (RecordDecl::field_iterator I = record->field_begin(),
+                                  E = record->field_end();
+       I != E; ++I, ++fieldNo) {
+    FieldDecl *field = *I;
 
-      // Bit size, align and offset of the type.
-      FieldSize = CGM.getContext().getTypeSize(FType);
-      Expr *BitWidth = Field->getBitWidth();
-      if (BitWidth)
-        FieldSize = BitWidth->EvaluateAsInt(CGM.getContext()).getZExtValue();
-      FieldAlign =  CGM.getContext().getTypeAlign(FType);
-    }
+    llvm::StringRef name = field->getName();
+    QualType type = field->getType();
 
-    uint64_t FieldOffset = RL.getFieldOffset(FieldNo);
+    // Ignore unnamed fields unless they're anonymous structs/unions.
+    if (name.empty() && !type->isRecordType())
+      continue;
 
-    unsigned Flags = 0;
-    AccessSpecifier Access = I->getAccess();
-    if (Access == clang::AS_private)
-      Flags |= llvm::DIDescriptor::FlagPrivate;
-    else if (Access == clang::AS_protected)
-      Flags |= llvm::DIDescriptor::FlagProtected;
+    llvm::DIType fieldType
+      = createFieldType(name, type, field->getBitWidth(),
+                        field->getLocation(), field->getAccess(),
+                        layout.getFieldOffset(fieldNo), tunit);
 
-    FieldTy = DBuilder.createMemberType(FieldName, FieldDefUnit,
-                                        FieldLine, FieldSize, FieldAlign,
-                                        FieldOffset, Flags, FieldTy);
-    EltTys.push_back(FieldTy);
+    elements.push_back(fieldType);
   }
 }
 
@@ -902,7 +912,7 @@
   // may refer to the forward decl if the struct is recursive) and replace all
   // uses of the forward declaration with the final definition.
   llvm::DIDescriptor FDContext =
-    getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()));
+    getContextDescriptor(cast<Decl>(RD->getDeclContext()));
 
   // If this is just a forward declaration, construct an appropriately
   // marked node and just return it.
@@ -994,7 +1004,7 @@
     RegionMap.erase(RI);
 
   llvm::DIDescriptor RDContext =  
-    getContextDescriptor(dyn_cast<Decl>(RD->getDeclContext()));
+    getContextDescriptor(cast<Decl>(RD->getDeclContext()));
   llvm::StringRef RDName = RD->getName();
   uint64_t Size = CGM.getContext().getTypeSize(Ty);
   uint64_t Align = CGM.getContext().getTypeAlign(Ty);
@@ -1329,7 +1339,7 @@
     Align = CGM.getContext().getTypeAlign(ED->getTypeForDecl());
   }
   llvm::DIDescriptor EnumContext = 
-    getContextDescriptor(dyn_cast<Decl>(ED->getDeclContext()));
+    getContextDescriptor(cast<Decl>(ED->getDeclContext()));
   llvm::DIType DbgTy = 
     DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit, Line,
                                    Size, Align, EltArray);
@@ -1827,33 +1837,34 @@
   
   // If VD is an anonymous union then Storage represents value for
   // all union fields.
-  if (const RecordType *RT = dyn_cast<RecordType>(VD->getType()))
-    if (const RecordDecl *RD = dyn_cast<RecordDecl>(RT->getDecl()))
-      if (RD->isUnion()) {
-        for (RecordDecl::field_iterator I = RD->field_begin(),
-               E = RD->field_end();
-             I != E; ++I) {
-          FieldDecl *Field = *I;
-          llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
-          llvm::StringRef FieldName = Field->getName();
+  if (const RecordType *RT = dyn_cast<RecordType>(VD->getType())) {
+    const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
+    if (RD->isUnion()) {
+      for (RecordDecl::field_iterator I = RD->field_begin(),
+             E = RD->field_end();
+           I != E; ++I) {
+        FieldDecl *Field = *I;
+        llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
+        llvm::StringRef FieldName = Field->getName();
           
-          // Ignore unnamed fields. Do not ignore unnamed records.
-          if (FieldName.empty() && !isa<RecordType>(Field->getType()))
-            continue;
+        // Ignore unnamed fields. Do not ignore unnamed records.
+        if (FieldName.empty() && !isa<RecordType>(Field->getType()))
+          continue;
           
-          // Use VarDecl's Tag, Scope and Line number.
-          llvm::DIVariable D =
-            DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope),
-                                         FieldName, Unit, Line, FieldTy, 
-                                         CGM.getLangOptions().Optimize, Flags);
+        // Use VarDecl's Tag, Scope and Line number.
+        llvm::DIVariable D =
+          DBuilder.createLocalVariable(Tag, llvm::DIDescriptor(Scope),
+                                       FieldName, Unit, Line, FieldTy, 
+                                       CGM.getLangOptions().Optimize, Flags);
           
-          // Insert an llvm.dbg.declare into the current block.
-          llvm::Instruction *Call =
-            DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());
+        // Insert an llvm.dbg.declare into the current block.
+        llvm::Instruction *Call =
+          DBuilder.insertDeclare(Storage, D, Builder.GetInsertBlock());
           
-          Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
-        }
+        Call->setDebugLoc(llvm::DebugLoc::get(Line, Column, Scope));
       }
+    }
+  }
 }
 
 /// EmitDeclare - Emit local variable declaration debug info.
@@ -1887,7 +1898,6 @@
 
   llvm::SmallVector<llvm::Value *, 9> addr;
   const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(CGM.getLLVMContext());
-  addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpDeref));
   addr.push_back(llvm::ConstantInt::get(Int64Ty, llvm::DIBuilder::OpPlus));
   addr.push_back(llvm::ConstantInt::get(Int64Ty, offset.getQuantity()));
   if (isByRef) {
@@ -1936,7 +1946,146 @@
   EmitDeclare(VD, llvm::dwarf::DW_TAG_arg_variable, AI, Builder);
 }
 
+namespace {
+  struct BlockLayoutChunk {
+    uint64_t OffsetInBits;
+    const BlockDecl::Capture *Capture;
+  };
+  bool operator<(const BlockLayoutChunk &l, const BlockLayoutChunk &r) {
+    return l.OffsetInBits < r.OffsetInBits;
+  }
+}
+
+void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
+                                                       llvm::Value *addr,
+                                                       CGBuilderTy &Builder) {
+  ASTContext &C = CGM.getContext();
+  const BlockDecl *blockDecl = block.getBlockDecl();
+
+  // Collect some general information about the block's location.
+  SourceLocation loc = blockDecl->getCaretLocation();
+  llvm::DIFile tunit = getOrCreateFile(loc);
+  unsigned line = getLineNumber(loc);
+  unsigned column = getColumnNumber(loc);
+  
+  // Build the debug-info type for the block literal.
+  llvm::DIDescriptor enclosingContext =  
+    getContextDescriptor(cast<Decl>(blockDecl->getDeclContext()));
+
+  const llvm::StructLayout *blockLayout =
+    CGM.getTargetData().getStructLayout(block.StructureType);
+
+  llvm::SmallVector<llvm::Value*, 16> fields;
+  fields.push_back(createFieldType("__isa", C.VoidPtrTy, 0, loc, AS_public,
+                                   blockLayout->getElementOffsetInBits(0),
+                                   tunit));
+  fields.push_back(createFieldType("__flags", C.IntTy, 0, loc, AS_public,
+                                   blockLayout->getElementOffsetInBits(1),
+                                   tunit));
+  fields.push_back(createFieldType("__reserved", C.IntTy, 0, loc, AS_public,
+                                   blockLayout->getElementOffsetInBits(2),
+                                   tunit));
+  fields.push_back(createFieldType("__FuncPtr", C.VoidPtrTy, 0, loc, AS_public,
+                                   blockLayout->getElementOffsetInBits(3),
+                                   tunit));
+  fields.push_back(createFieldType("__descriptor",
+                                   C.getPointerType(block.NeedsCopyDispose ?
+                                        C.getBlockDescriptorExtendedType() :
+                                        C.getBlockDescriptorType()),
+                                   0, loc, AS_public,
+                                   blockLayout->getElementOffsetInBits(4),
+                                   tunit));
+
+  // We want to sort the captures by offset, not because DWARF
+  // requires this, but because we're paranoid about debuggers.
+  llvm::SmallVector<BlockLayoutChunk, 8> chunks;
+
+  // 'this' capture.
+  if (blockDecl->capturesCXXThis()) {
+    BlockLayoutChunk chunk;
+    chunk.OffsetInBits =
+      blockLayout->getElementOffsetInBits(block.CXXThisIndex);
+    chunk.Capture = 0;
+    chunks.push_back(chunk);
+  }
+
+  // Variable captures.
+  for (BlockDecl::capture_const_iterator
+         i = blockDecl->capture_begin(), e = blockDecl->capture_end();
+       i != e; ++i) {
+    const BlockDecl::Capture &capture = *i;
+    const VarDecl *variable = capture.getVariable();
+    const CGBlockInfo::Capture &captureInfo = block.getCapture(variable);
+
+    // Ignore constant captures.
+    if (captureInfo.isConstant())
+      continue;
+
+    BlockLayoutChunk chunk;
+    chunk.OffsetInBits =
+      blockLayout->getElementOffsetInBits(captureInfo.getIndex());
+    chunk.Capture = &capture;
+    chunks.push_back(chunk);
+  }
+
+  // Sort by offset.
+  llvm::array_pod_sort(chunks.begin(), chunks.end());
+
+  for (llvm::SmallVectorImpl<BlockLayoutChunk>::iterator
+         i = chunks.begin(), e = chunks.end(); i != e; ++i) {
+    uint64_t offsetInBits = i->OffsetInBits;
+    const BlockDecl::Capture *capture = i->Capture;
+
+    // If we have a null capture, this must be the C++ 'this' capture.
+    if (!capture) {
+      const CXXMethodDecl *method =
+        cast<CXXMethodDecl>(blockDecl->getNonClosureContext());
+      QualType type = method->getThisType(C);
 
+      fields.push_back(createFieldType("this", type, 0, loc, AS_public,
+                                       offsetInBits, tunit));
+      continue;
+    }
+
+    const VarDecl *variable = capture->getVariable();
+    QualType type = (capture->isByRef() ? C.VoidPtrTy : variable->getType());
+    llvm::StringRef name = variable->getName();
+    fields.push_back(createFieldType(name, type, 0, loc, AS_public,
+                                     offsetInBits, tunit));
+  }
+
+  llvm::SmallString<36> typeName;
+  llvm::raw_svector_ostream(typeName)
+    << "__block_literal_" << CGM.getUniqueBlockCount();
+
+  llvm::DIArray fieldsArray =
+    DBuilder.getOrCreateArray(fields.data(), fields.size());
+
+  llvm::DIType type =
+    DBuilder.createStructType(tunit, typeName.str(), tunit, line,
+                              CGM.getContext().toBits(block.BlockSize),
+                              CGM.getContext().toBits(block.BlockAlign),
+                              0, fieldsArray);
+  type = DBuilder.createPointerType(type, CGM.PointerWidthInBits);
+
+  // Get overall information about the block.
+  unsigned flags = llvm::DIDescriptor::FlagArtificial;
+  llvm::MDNode *scope = RegionStack.back();
+  llvm::StringRef name = ".block_descriptor";
+
+  // Create the descriptor for the parameter.
+  llvm::DIVariable debugVar =
+    DBuilder.createLocalVariable(llvm::dwarf::DW_TAG_arg_variable,
+                                 llvm::DIDescriptor(scope), 
+                                 name, tunit, line, type, 
+                                 CGM.getLangOptions().Optimize, flags);
+    
+  // Insert an llvm.dbg.value into the current block.
+  llvm::Instruction *declare =
+    DBuilder.insertDbgValueIntrinsic(addr, 0, debugVar,
+                                     Builder.GetInsertBlock());
+  declare->setDebugLoc(llvm::DebugLoc::get(line, column, scope));
+}
 
 /// EmitGlobalVariable - Emit information about a global variable.
 void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Tue Feb 22 16:38:33 2011
@@ -123,7 +123,10 @@
                        llvm::SmallVectorImpl<llvm::Value *> &EltTys,
                        llvm::DIType RecordTy);
 
-
+  llvm::DIType createFieldType(llvm::StringRef name, QualType type,
+                               Expr *bitWidth, SourceLocation loc,
+                               AccessSpecifier AS, uint64_t offsetInBits,
+                               llvm::DIFile tunit);
   void CollectRecordFields(const RecordDecl *Decl, llvm::DIFile F,
                            llvm::SmallVectorImpl<llvm::Value *> &E);
 
@@ -180,6 +183,13 @@
   void EmitDeclareOfArgVariable(const VarDecl *Decl, llvm::Value *AI,
                                 CGBuilderTy &Builder);
 
+  /// EmitDeclareOfBlockLiteralArgVariable - Emit call to
+  /// llvm.dbg.declare for the block-literal argument to a block
+  /// invocation function.
+  void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
+                                            llvm::Value *addr,
+                                            CGBuilderTy &Builder);
+
   /// EmitGlobalVariable - Emit information about a global variable.
   void EmitGlobalVariable(llvm::GlobalVariable *GV, const VarDecl *Decl);
 

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Tue Feb 22 16:38:33 2011
@@ -1004,6 +1004,24 @@
   // FIXME: Why isn't ImplicitParamDecl a ParmVarDecl?
   assert((isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)) &&
          "Invalid argument to EmitParmDecl");
+
+  Arg->setName(D.getName());
+
+  // Use better IR generation for certain implicit parameters.
+  if (isa<ImplicitParamDecl>(D)) {
+    // The only implicit argument a block has is its literal.
+    if (BlockInfo) {
+      LocalDeclMap[&D] = Arg;
+
+      if (CGDebugInfo *DI = getDebugInfo()) {
+        DI->setLocation(D.getLocation());
+        DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, Arg, Builder);
+      }
+
+      return;
+    }
+  }
+
   QualType Ty = D.getType();
 
   llvm::Value *DeclPtr;
@@ -1020,7 +1038,6 @@
                       getContext().getDeclAlign(&D).getQuantity(), Ty,
                       CGM.getTBAAInfo(Ty));
   }
-  Arg->setName(D.getName());
 
   llvm::Value *&DMEntry = LocalDeclMap[&D];
   assert(DMEntry == 0 && "Decl already exists in localdeclmap!");

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=126255&r1=126254&r2=126255&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Feb 22 16:38:33 2011
@@ -389,8 +389,8 @@
                                           unsigned Align,
                                           const VarDecl *variable);
 
-  /// getGlobalUniqueCount - Fetches the global unique block count.
-  int getGlobalUniqueCount() { return ++Block.GlobalUniqueCount; }
+  /// getUniqueBlockCount - Fetches the global unique block count.
+  int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; }
 
   /// getBlockDescriptorType - Fetches the type of a generic block
   /// descriptor.





More information about the cfe-commits mailing list