[cfe-commits] r89532 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseTemplate.cpp test/CXX/temp/temp.param/p2.cpp
Douglas Gregor
dgregor at apple.com
Fri Nov 20 18:07:56 PST 2009
Author: dgregor
Date: Fri Nov 20 20:07:55 2009
New Revision: 89532
URL: http://llvm.org/viewvc/llvm-project?rev=89532&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/test/CXX/temp/temp.param/p2.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=89532&r1=89531&r2=89532&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Nov 20 20:07:55 2009
@@ -1353,6 +1353,7 @@
SourceLocation &RAngleLoc);
bool ParseTemplateParameterList(unsigned Depth,
TemplateParameterList &TemplateParams);
+ bool isStartOfTemplateTypeParameter();
DeclPtrTy ParseTemplateParameter(unsigned Depth, unsigned Position);
DeclPtrTy ParseTypeParameter(unsigned Depth, unsigned Position);
DeclPtrTy ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=89532&r1=89531&r2=89532&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Fri Nov 20 20:07:55 2009
@@ -333,6 +333,40 @@
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 @@
/// '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);
Modified: cfe/trunk/test/CXX/temp/temp.param/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p2.cpp?rev=89532&r1=89531&r2=89532&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.param/p2.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.param/p2.cpp Fri Nov 20 20:07:55 2009
@@ -8,7 +8,8 @@
// typename followed by aqualified-id denotes the type in a non-type
// parameter-declaration.
-// FIXME: template<typename T, typename T::type Value> struct Y;
+template<typename T, typename T::type Value> struct Y0;
+template<typename T, typename X<T>::type Value> struct Y1;
// A storage class shall not be specified in a template-parameter declaration.
template<static int Value> struct Z; // FIXME: expect an error
More information about the cfe-commits
mailing list