summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-02-10 19:49:53 +0000
committerDouglas Gregor <dgregor@apple.com>2009-02-10 19:49:53 +0000
commitdba326363c4453525dc650242dfa7be97cd53c06 (patch)
tree876d917c279fdbbd6a3d2d5af81f2713e4a6f70a /clang/lib/Parse/ParseTemplate.cpp
parentda1a632a87e6a25e2f59c470fd8365e284e488ea (diff)
downloadbcm5719-llvm-dba326363c4453525dc650242dfa7be97cd53c06.tar.gz
bcm5719-llvm-dba326363c4453525dc650242dfa7be97cd53c06.zip
Implement parsing, semantic analysis and ASTs for default template
arguments. This commit covers checking and merging default template arguments from previous declarations, but it does not cover the actual use of default template arguments when naming class template specializations. llvm-svn: 64229
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