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/SemaType.cpp b/lib/Sema/SemaType.cpp
index 9d78d0a..e6d1833 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -251,9 +251,20 @@
   return Result;
 }
 
-/// GetTypeForDeclarator - Convert the type for the specified declarator to Type
-/// instances. Skip the outermost Skip type objects.
+/// GetTypeForDeclarator - Convert the type for the specified
+/// declarator to Type instances. Skip the outermost Skip type
+/// objects.
 QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) {
+  bool OmittedReturnType = false;
+
+  if (D.getContext() == Declarator::BlockLiteralContext
+      && Skip == 0
+      && !D.getDeclSpec().hasTypeSpecifier()
+      && (D.getNumTypeObjects() == 0
+          || (D.getNumTypeObjects() == 1
+              && D.getTypeObject(0).Kind == DeclaratorChunk::Function)))
+    OmittedReturnType = true;
+
   // long long is a C99 feature.
   if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x &&
       D.getDeclSpec().getTypeSpecWidth() == DeclSpec::TSW_longlong)
@@ -265,9 +276,16 @@
   switch (D.getKind()) {
   case Declarator::DK_Abstract:
   case Declarator::DK_Normal:
-  case Declarator::DK_Operator:
-    T = ConvertDeclSpecToType(D.getDeclSpec());
+  case Declarator::DK_Operator: {
+    const DeclSpec& DS = D.getDeclSpec();
+    if (OmittedReturnType)
+      // We default to a dependent type initially.  Can be modified by
+      // the first return statement.
+      T = Context.DependentTy;
+    else
+      T = ConvertDeclSpecToType(DS);
     break;
+  }
 
   case Declarator::DK_Constructor:
   case Declarator::DK_Destructor:
@@ -279,8 +297,9 @@
     break;
   }
 
-  // Walk the DeclTypeInfo, building the recursive type as we go.  DeclTypeInfos
-  // are ordered from the identifier out, which is opposite of what we want :).
+  // Walk the DeclTypeInfo, building the recursive type as we go.
+  // DeclTypeInfos are ordered from the identifier out, which is
+  // opposite of what we want :).
   for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) {
     DeclaratorChunk &DeclType = D.getTypeObject(e-i-1+Skip);
     switch (DeclType.Kind) {