Implement parsing of function parameter packs and non-type template
parameter packs (C++0x [dcl.fct]p13), including disambiguation between
unnamed function parameter packs and varargs (C++0x [dcl.fct]p14) for
cases like
void f(T...)
where T may or may not contain unexpanded parameter packs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122520 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 53cccc0..f627b2c 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2819,7 +2819,7 @@
/// [C++] declarator-id
///
/// declarator-id: [C++ 8]
-/// id-expression
+/// '...'[opt] id-expression
/// '::'[opt] nested-name-specifier[opt] type-name
///
/// id-expression: [C++ 5.1]
@@ -2849,6 +2849,21 @@
DeclScopeObj.EnterDeclaratorScope();
}
+ // C++0x [dcl.fct]p14:
+ // There is a syntactic ambiguity when an ellipsis occurs at the end
+ // of a parameter-declaration-clause without a preceding comma. In
+ // this case, the ellipsis is parsed as part of the
+ // abstract-declarator if the type of the parameter names a template
+ // parameter pack that has not been expanded; otherwise, it is parsed
+ // as part of the parameter-declaration-clause.
+ if (Tok.is(tok::ellipsis) &&
+ !((D.getContext() == Declarator::PrototypeContext ||
+ D.getContext() == Declarator::BlockLiteralContext) &&
+ getCurScope()->getTemplateParamParent() &&
+ NextToken().is(tok::r_paren) &&
+ !Actions.containsUnexpandedParameterPacks(D)))
+ D.setEllipsisLoc(ConsumeToken());
+
if (Tok.is(tok::identifier) || Tok.is(tok::kw_operator) ||
Tok.is(tok::annot_template_id) || Tok.is(tok::tilde)) {
// We found something that indicates the start of an unqualified-id.