diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-06-04 07:30:15 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-06-04 07:30:15 +0000 |
commit | 71b209dea626d50d3c5ff943de123c84ce64718f (patch) | |
tree | bf71fe905ad88b139ce2f9484bceff059ca43766 /clang | |
parent | 878bdccea6e659692076d131edf690721d883103 (diff) | |
download | bcm5719-llvm-71b209dea626d50d3c5ff943de123c84ce64718f.tar.gz bcm5719-llvm-71b209dea626d50d3c5ff943de123c84ce64718f.zip |
Properly disambiguate between an elaborated-type-specifier and a
type-parameter within a template parameter list. Found by inspection.
llvm-svn: 105462
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 33 | ||||
-rw-r--r-- | clang/test/CXX/temp/temp.param/p2.cpp | 5 |
2 files changed, 36 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index c87ddad4e9b..5d248f1d774 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -341,8 +341,37 @@ Parser::ParseTemplateParameterList(unsigned Depth, /// \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.is(tok::kw_class)) { + // "class" may be the start of an elaborated-type-specifier or a + // type-parameter. Per C++ [temp.param]p3, we prefer the type-parameter. + switch (NextToken().getKind()) { + case tok::equal: + case tok::comma: + case tok::greater: + case tok::greatergreater: + case tok::ellipsis: + return true; + + case tok::identifier: + // This may be either a type-parameter or an elaborated-type-specifier. + // We have to look further. + break; + + default: + return false; + } + + switch (GetLookAheadToken(2).getKind()) { + case tok::equal: + case tok::comma: + case tok::greater: + case tok::greatergreater: + return true; + + default: + return false; + } + } if (Tok.isNot(tok::kw_typename)) return false; diff --git a/clang/test/CXX/temp/temp.param/p2.cpp b/clang/test/CXX/temp/temp.param/p2.cpp index 41868c5c1ac..fed6e9c266b 100644 --- a/clang/test/CXX/temp/temp.param/p2.cpp +++ b/clang/test/CXX/temp/temp.param/p2.cpp @@ -14,4 +14,9 @@ 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 +// Make sure that we properly disambiguate non-type template parameters that +// start with 'class'. +class X1 { }; +template<class X1 *xptr> struct Y2 { }; + // FIXME: add the example from p2 |