diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-10 19:49:53 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-10 19:49:53 +0000 |
commit | dba326363c4453525dc650242dfa7be97cd53c06 (patch) | |
tree | 876d917c279fdbbd6a3d2d5af81f2713e4a6f70a /clang/lib/Parse/ParseTemplate.cpp | |
parent | da1a632a87e6a25e2f59c470fd8365e284e488ea (diff) | |
download | bcm5719-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.cpp | 57 |
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; |