summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Parse/ParseTemplate.cpp')
-rw-r--r--clang/lib/Parse/ParseTemplate.cpp57
1 files changed, 36 insertions, 21 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 25aea352242..d17d2445351 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -228,8 +228,10 @@ Parser::DeclTy *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
// Grab a default type id (if given).
if(Tok.is(tok::equal)) {
SourceLocation EqualLoc = ConsumeToken();
+ SourceLocation DefaultLoc = Tok.getLocation();
if (TypeTy *DefaultType = ParseTypeName())
- Actions.ActOnTypeParameterDefault(TypeParam, DefaultType);
+ Actions.ActOnTypeParameterDefault(TypeParam, EqualLoc, DefaultLoc,
+ DefaultType);
}
return TypeParam;
@@ -277,18 +279,6 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
return 0;
}
- // Get the a default value, if given.
- // FIXME: I think that the results of this block need to be passed to the
- // act-on call, so we can assemble the parameter correctly.
- OwningExprResult DefaultExpr(Actions);
- if(Tok.is(tok::equal)) {
- ConsumeToken();
- DefaultExpr = ParseCXXIdExpression();
- if(DefaultExpr.isInvalid()) {
- return 0;
- }
- }
-
TemplateParamsTy *ParamList =
Actions.ActOnTemplateParameterList(Depth, SourceLocation(),
TemplateLoc, LAngleLoc,
@@ -296,9 +286,23 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
TemplateParams.size(),
RAngleLoc);
- return Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
- ParamList, ParamName,
- NameLoc, Depth, Position);
+ Parser::DeclTy * Param
+ = Actions.ActOnTemplateTemplateParameter(CurScope, TemplateLoc,
+ ParamList, ParamName,
+ NameLoc, Depth, Position);
+
+ // Get the a default value, if given.
+ if (Tok.is(tok::equal)) {
+ SourceLocation EqualLoc = ConsumeToken();
+ OwningExprResult DefaultExpr = ParseCXXIdExpression();
+ if (DefaultExpr.isInvalid())
+ return Param;
+ else if (Param)
+ Actions.ActOnTemplateTemplateParameterDefault(Param, EqualLoc,
+ move(DefaultExpr));
+ }
+
+ return Param;
}
/// ParseNonTypeTemplateParameter - Handle the parsing of non-type
@@ -341,12 +345,23 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
DeclTy *Param = Actions.ActOnNonTypeTemplateParameter(CurScope, ParamDecl,
Depth, Position);
- // Is there a default value? Parsing this can be fairly annoying because
- // we have to stop on the first non-nested (paren'd) '>' as the closure
- // for the template parameter list. Or a ','.
+ // If there is a default value, parse it.
if (Tok.is(tok::equal)) {
- // TODO: Implement default non-type values.
- SkipUntil(tok::comma, tok::greater, true, true);
+ SourceLocation EqualLoc = ConsumeToken();
+
+ // C++ [temp.param]p15:
+ // When parsing a default template-argument for a non-type
+ // template-parameter, the first non-nested > is taken as the
+ // end of the template-parameter-list rather than a greater-than
+ // operator.
+ GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
+
+ OwningExprResult DefaultArg = ParseAssignmentExpression();
+ if (DefaultArg.isInvalid())
+ SkipUntil(tok::comma, tok::greater, true, true);
+ else if (Param)
+ Actions.ActOnNonTypeTemplateParameterDefault(Param, EqualLoc,
+ move(DefaultArg));
}
return Param;
OpenPOWER on IntegriCloud