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 | 26aedb74601a04c37dfd593ebb3904cb8ad90ec0 (patch) | |
tree | 03b27d4369d27d265a96985cdea0e4194d9c2269 /clang/lib/Parse/ParseTemplate.cpp | |
parent | 4c83e2c253d0a8d763b52405173f3daa58fcd0a9 (diff) | |
download | bcm5719-llvm-26aedb74601a04c37dfd593ebb3904cb8ad90ec0.tar.gz bcm5719-llvm-26aedb74601a04c37dfd593ebb3904cb8ad90ec0.zip |
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.
llvm-svn: 89532
Diffstat (limited to 'clang/lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 5be4ca82f72..e655dedab43 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/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); |