Add support for blocks with explicit return types.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63784 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 6671037..3ee6e52 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4179,12 +4179,36 @@
   PushDeclContext(BlockScope, BSI->TheDecl);
 }
 
-void Sema::ActOnBlockArguments(Declarator &ParamInfo) {
+void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
+  assert(ParamInfo.getIdentifier() == 0 && "block-id should have no identifier!");
+
+  if (ParamInfo.getNumTypeObjects() == 0
+      || ParamInfo.getTypeObject(0).Kind != DeclaratorChunk::Function) {
+    QualType T = GetTypeForDeclarator(ParamInfo, CurScope);
+
+    // The type is entirely optional as well, if none, use DependentTy.
+    if (T.isNull())
+      T = Context.DependentTy;
+
+    // The parameter list is optional, if there was none, assume ().
+    if (!T->isFunctionType())
+      T = Context.getFunctionType(T, NULL, 0, 0, 0);
+
+    CurBlock->hasPrototype = true;
+    CurBlock->isVariadic = false;
+    Type *RetTy = T.getTypePtr()->getAsFunctionType()->getResultType()
+      .getTypePtr();
+
+    if (!RetTy->isDependentType())
+      CurBlock->ReturnType = RetTy;
+    return;
+  }
+
   // Analyze arguments to block.
   assert(ParamInfo.getTypeObject(0).Kind == DeclaratorChunk::Function &&
          "Not a function declarator!");
   DeclaratorChunk::FunctionTypeInfo &FTI = ParamInfo.getTypeObject(0).Fun;
-  
+ 
   CurBlock->hasPrototype = FTI.hasPrototype;
   CurBlock->isVariadic = true;
   
@@ -4200,6 +4224,13 @@
     for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
       CurBlock->Params.push_back((ParmVarDecl *)FTI.ArgInfo[i].Param);
     CurBlock->isVariadic = FTI.isVariadic;
+    QualType T = GetTypeForDeclarator (ParamInfo, CurScope);
+
+    Type* RetTy = T.getTypePtr()->getAsFunctionType()->getResultType()
+      .getTypePtr();
+
+    if (!RetTy->isDependentType())
+      CurBlock->ReturnType = RetTy;
   }
   CurBlock->TheDecl->setArgs(&CurBlock->Params[0], CurBlock->Params.size());