diff options
-rw-r--r-- | clang/lib/Lex/PPCaching.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 33 | ||||
-rw-r--r-- | clang/test/SemaTemplate/default-arguments.cpp | 3 |
3 files changed, 20 insertions, 18 deletions
diff --git a/clang/lib/Lex/PPCaching.cpp b/clang/lib/Lex/PPCaching.cpp index c3f0eeab584..7c3780ffc0a 100644 --- a/clang/lib/Lex/PPCaching.cpp +++ b/clang/lib/Lex/PPCaching.cpp @@ -109,6 +109,4 @@ void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) { return; } } - - assert(0&&"Didn't find the first token represented by the annotation token!"); } diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index b5063ee44b6..16b1c800800 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -823,15 +823,13 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { // A template-argument for a template template-parameter shall be the name // of a class template or a template alias, expressed as id-expression. // - // We perform some tentative parsing at this point, to determine whether - // we have an id-expression that refers to a class template or template - // alias. The grammar we tentatively parse is: + // We parse an id-expression that refers to a class template or template + // alias. The grammar we parse is: // // nested-name-specifier[opt] template[opt] identifier // // followed by a token that terminates a template argument, such as ',', // '>', or (in some cases) '>>'. - TentativeParsingAction TPA(*this); CXXScopeSpec SS; // nested-name-specifier, if present ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, /*EnteringContext=*/false); @@ -854,10 +852,8 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { TemplateTy Template = Actions.ActOnDependentTemplateName(TemplateLoc, SS, Name, /*ObjectType=*/0); - if (Template.get()) { - TPA.Commit(); + if (Template.get()) return ParsedTemplateArgument(SS, Template, Name.StartLocation); - } } } } else if (Tok.is(tok::identifier)) { @@ -875,16 +871,12 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) { // We have an id-expression that refers to a class template or // (C++0x) template alias. - TPA.Commit(); return ParsedTemplateArgument(SS, Template, Name.StartLocation); } } } - // We don't have a template template argument; revert everything we have - // tentatively parsed. - TPA.Revert(); - + // We don't have a template template argument. return ParsedTemplateArgument(); } @@ -912,10 +904,19 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() { } // Try to parse a template template argument. - ParsedTemplateArgument TemplateTemplateArgument - = ParseTemplateTemplateArgument(); - if (!TemplateTemplateArgument.isInvalid()) - return TemplateTemplateArgument; + { + TentativeParsingAction TPA(*this); + + ParsedTemplateArgument TemplateTemplateArgument + = ParseTemplateTemplateArgument(); + if (!TemplateTemplateArgument.isInvalid()) { + TPA.Commit(); + return TemplateTemplateArgument; + } + + // Revert this tentative parse to parse a non-type template argument. + TPA.Revert(); + } // Parse a non-type template argument. SourceLocation Loc = Tok.getLocation(); diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp index e082693aa52..0247ddc0ef2 100644 --- a/clang/test/SemaTemplate/default-arguments.cpp +++ b/clang/test/SemaTemplate/default-arguments.cpp @@ -118,3 +118,6 @@ template<typename T, X6<int> x6a; X6<long> x6b; // expected-note{{while checking a default template argument}} X6<long, X5b> x6c; + + +template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}} |