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/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 64c4c31..d20f294 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1211,11 +1211,29 @@
}
}
+/// ParseBlockId - Parse a block-id, which roughly looks like int (int x).
+///
+/// [clang] block-id:
+/// [clang] specifier-qualifier-list block-declarator
+///
+void Parser::ParseBlockId() {
+ // Parse the specifier-qualifier-list piece.
+ DeclSpec DS;
+ ParseSpecifierQualifierList(DS);
+
+ // Parse the block-declarator.
+ Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
+ ParseDeclarator(DeclaratorInfo);
+ // Inform sema that we are starting a block.
+ Actions.ActOnBlockArguments(DeclaratorInfo, CurScope);
+}
+
/// ParseBlockLiteralExpression - Parse a block literal, which roughly looks
/// like ^(int x){ return x+1; }
///
/// block-literal:
/// [clang] '^' block-args[opt] compound-statement
+/// [clang] '^' block-id compound-statement
/// [clang] block-args:
/// [clang] '(' parameter-list ')'
///
@@ -1235,7 +1253,7 @@
// Parse the return type if present.
DeclSpec DS;
- Declarator ParamInfo(DS, Declarator::PrototypeContext);
+ Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
// If this block has arguments, parse them. There is no ambiguity here with
// the expression case, because the expression case requires a parameter list.
@@ -1244,20 +1262,24 @@
// Parse the pieces after the identifier as if we had "int(...)".
ParamInfo.SetIdentifier(0, CaretLoc);
if (ParamInfo.getInvalidType()) {
- // If there was an error parsing the arguments, they may have tried to use
- // ^(x+y) which requires an argument list. Just skip the whole block
- // literal.
+ // If there was an error parsing the arguments, they may have
+ // tried to use ^(x+y) which requires an argument list. Just
+ // skip the whole block literal.
return ExprError();
}
+ // Inform sema that we are starting a block.
+ Actions.ActOnBlockArguments(ParamInfo, CurScope);
+ } else if (! Tok.is(tok::l_brace)) {
+ ParseBlockId();
} else {
// Otherwise, pretend we saw (void).
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
0, 0, 0, CaretLoc,
ParamInfo));
+ // Inform sema that we are starting a block.
+ Actions.ActOnBlockArguments(ParamInfo, CurScope);
}
- // Inform sema that we are starting a block.
- Actions.ActOnBlockArguments(ParamInfo);
OwningExprResult Result(Actions, true);
if (Tok.is(tok::l_brace)) {