Prep work to always preallocate BlockDeclRefExprs so that we can
generate the debug information for the first parameter to the block
invoke functions.  WIP.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84737 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 8855cba..673229c 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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) {