diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-21 02:07:55 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-21 02:07:55 +0000 |
commit | 98440b4ac17dc5f85ea3db683c1c1785449c17e1 (patch) | |
tree | a0aaf1a1e9cbcfc6f5c993f899ff64f12c7fcd0e /lib/Parse/ParseTemplate.cpp | |
parent | 78d722fb2b55e53914bc80046db65d113138b2a7 (diff) |
Implement C++ [temp.param]p2 correctly, looking ahead when we see a
"typename" parameter to distinguish between non-type and type template
parameters. Fixes the actual bug in PR5559.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89532 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 5be4ca82f7..e655dedab4 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -333,6 +333,40 @@ Parser::ParseTemplateParameterList(unsigned Depth, return true; } +/// \brief Determine whether the parser is at the start of a template +/// type parameter. +bool Parser::isStartOfTemplateTypeParameter() { + if (Tok.is(tok::kw_class)) + return true; + + if (Tok.isNot(tok::kw_typename)) + return false; + + // C++ [temp.param]p2: + // There is no semantic difference between class and typename in a + // template-parameter. typename followed by an unqualified-id + // names a template type parameter. typename followed by a + // qualified-id denotes the type in a non-type + // parameter-declaration. + Token Next = NextToken(); + + // If we have an identifier, skip over it. + if (Next.getKind() == tok::identifier) + Next = GetLookAheadToken(2); + + switch (Next.getKind()) { + case tok::equal: + case tok::comma: + case tok::greater: + case tok::greatergreater: + case tok::ellipsis: + return true; + + default: + return false; + } +} + /// ParseTemplateParameter - Parse a template-parameter (C++ [temp.param]). /// /// template-parameter: [C++ temp.param] @@ -348,12 +382,8 @@ Parser::ParseTemplateParameterList(unsigned Depth, /// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression Parser::DeclPtrTy Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { - if (Tok.is(tok::kw_class) || - (Tok.is(tok::kw_typename) && - // FIXME: Next token has not been annotated! - NextToken().isNot(tok::annot_typename))) { + if (isStartOfTemplateTypeParameter()) return ParseTypeParameter(Depth, Position); - } if (Tok.is(tok::kw_template)) return ParseTemplateTemplateParameter(Depth, Position); |