summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse/ParseTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-21 02:07:55 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-21 02:07:55 +0000
commit26aedb74601a04c37dfd593ebb3904cb8ad90ec0 (patch)
tree03b27d4369d27d265a96985cdea0e4194d9c2269 /clang/lib/Parse/ParseTemplate.cpp
parent4c83e2c253d0a8d763b52405173f3daa58fcd0a9 (diff)
downloadbcm5719-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.cpp40
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);
OpenPOWER on IntegriCloud