Friendly ping.
2013/7/15 Serge Pavlov <[email protected]> > Friendly ping. > > > 2013/7/8 Serge Pavlov <[email protected]> > >> Fixed placement of curly brace. >> >> Hi rsmith, >> >> http://llvm-reviews.chandlerc.com/D924 >> >> CHANGE SINCE LAST DIFF >> http://llvm-reviews.chandlerc.com/D924?vs=2311&id=2716#toc >> >> Files: >> include/clang/Parse/Parser.h >> lib/Parse/ParseDeclCXX.cpp >> lib/Parse/ParseTemplate.cpp >> lib/Parse/Parser.cpp >> test/Parser/cxx-template-argument.cpp >> test/SemaCXX/class.cpp >> >> Index: include/clang/Parse/Parser.h >> =================================================================== >> --- include/clang/Parse/Parser.h >> +++ include/clang/Parse/Parser.h >> @@ -764,6 +764,17 @@ >> /// point for skipping past a simple-declaration. >> void SkipMalformedDecl(); >> >> + /// \brief Discards tokens of template argument list, including >> closing '>'. >> + /// >> + /// The method tries to balance angle brackets pairs to skip nested >> template >> + /// references properly. As there is no guarantee that the brackets are >> + /// balanced, skipping will stop at points that most likely outside the >> + /// discarded argument list. The method assumes that opening '<' is >> already >> + /// read. >> + /// >> + /// \returns true if closing '>' is found, false otherwise. >> + bool SkipTemplateArguments(); >> + >> private: >> >> >> //===--------------------------------------------------------------------===// >> // Lexing and parsing of C++ inline methods. >> Index: lib/Parse/ParseDeclCXX.cpp >> =================================================================== >> --- lib/Parse/ParseDeclCXX.cpp >> +++ lib/Parse/ParseDeclCXX.cpp >> @@ -918,8 +918,10 @@ >> << Id; >> } >> >> - if (!Template) >> + if (!Template) { >> + SkipTemplateArguments(); >> return true; >> + } >> >> // Form the template name >> UnqualifiedId TemplateName; >> Index: lib/Parse/ParseTemplate.cpp >> =================================================================== >> --- lib/Parse/ParseTemplate.cpp >> +++ lib/Parse/ParseTemplate.cpp >> @@ -680,6 +680,8 @@ >> /// \param RAngleLoc the location of the consumed '>'. >> /// >> /// \param ConsumeLastToken if true, the '>' is not consumed. >> +/// >> +/// \returns true, if current token does not start with '>', false >> otherwise. >> bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, >> bool ConsumeLastToken) { >> // What will be left once we've consumed the '>'. >> Index: lib/Parse/Parser.cpp >> =================================================================== >> --- lib/Parse/Parser.cpp >> +++ lib/Parse/Parser.cpp >> @@ -347,6 +347,46 @@ >> } >> } >> >> +// Skip template arguments >> +bool Parser::SkipTemplateArguments() { >> + unsigned NestingLevel = 1; >> + SourceLocation GreaterThanLoc; >> + tok::TokenKind SpecDelimiters[] = { >> + tok::less, tok::greater, tok::greatergreater, tok::greaterequal, >> + tok::greatergreaterequal, tok::greatergreatergreater}; >> + >> + if (Tok.is(tok::less)) >> + ConsumeToken(); >> + if (Tok.is(tok::semi)) >> + return false; >> + >> + while (Tok.isNot(tok::eof) && Tok.isNot(tok::semi)) { >> + if (SkipUntil(SpecDelimiters, /*StopAtSemi*/true, >> /*DontConsume*/true)) { >> + switch(Tok.getKind()) { >> + case tok::less: >> + ConsumeToken(); >> + ++NestingLevel; >> + break; >> + >> + case tok::greater: >> + case tok::greatergreater: >> + case tok::greaterequal: >> + case tok::greatergreaterequal: >> + case tok::greatergreatergreater: >> + ParseGreaterThanInTemplateList(GreaterThanLoc, true); >> + if (--NestingLevel == 0) >> + return true; >> + break; >> + >> + default: >> + return false; >> + } >> + } >> + } >> + >> + return false; >> +} >> + >> >> >> //===----------------------------------------------------------------------===// >> // Scope manipulation >> >> >> //===----------------------------------------------------------------------===// >> Index: test/Parser/cxx-template-argument.cpp >> =================================================================== >> --- test/Parser/cxx-template-argument.cpp >> +++ test/Parser/cxx-template-argument.cpp >> @@ -42,3 +42,59 @@ >> new C(); // expected-error {{requires template arguments}} >> } >> } >> + >> +// Don't emit spurious messages >> +namespace pr16225add { >> + >> + template<class T1, typename T2> struct Known { }; // expected-note 3 >> {{template is declared here}} >> + template<class T1, typename T2> struct X; >> + >> + template<class T1, typename T2> struct foo : >> + UnknownBase<T1,T2> // expected-error {{unknown template name >> 'UnknownBase'}} >> + { }; >> + >> + template<class T1, typename T2> struct foo2 : >> + UnknownBase<T1,T2>, // expected-error {{unknown template name >> 'UnknownBase'}} >> + Known<T1> // expected-error {{too few template arguments for class >> template 'Known'}} >> + { }; >> + >> + template<class T1, typename T2> struct foo3 : >> + UnknownBase<T1,T2,ABC<T2,T1> > // expected-error {{unknown template >> name 'UnknownBase'}} >> + { }; >> + >> + template<class T1, typename T2> struct foo4 : >> + UnknownBase<T1,ABC<T2> >, // expected-error {{unknown template name >> 'UnknownBase'}} >> + Known<T1> // expected-error {{too few template arguments for class >> template 'Known'}} >> + { }; >> + >> + template<class T1, typename T2> struct foo5 : >> + UnknownBase<T1,T2,ABC<T2,T1>> // expected-error {{unknown template >> name 'UnknownBase'}} \ >> + // expected-error {{use '> >'}} >> + { }; >> + >> + template<class T1, typename T2> struct foo6 : >> + UnknownBase<T1,ABC<T2>>, // expected-error {{unknown template name >> 'UnknownBase'}} \ >> + // expected-error {{use '> >'}} >> + Known<T1> // expected-error {{too few template arguments for class >> template 'Known'}} >> + { }; >> + >> + template<class T1, typename T2, int N> struct foo7 : >> + UnknownBase<T1,T2,(N>1)> // expected-error {{unknown template name >> 'UnknownBase'}} >> + { }; >> + >> + template<class T1, typename T2> struct foo8 : >> + UnknownBase<X<int,int>,X<int,int>> // expected-error {{unknown >> template name 'UnknownBase'}} \ >> + // expected-error {{use '> >'}} >> + { }; >> + >> + template<class T1, typename T2> struct foo9 : >> + UnknownBase<Known<int>,X<int,int>> // expected-error {{unknown >> template name 'UnknownBase'}} \ >> + // expected-error {{use '> >'}} >> + { }; >> + >> + template<class T1, typename T2> struct foo10 : >> + UnknownBase<Known<int>,X<int,X<int>>> // expected-error {{unknown >> template name 'UnknownBase'}} \ >> + // expected-error {{use '> >'}} >> + { }; >> + >> +} >> Index: test/SemaCXX/class.cpp >> =================================================================== >> --- test/SemaCXX/class.cpp >> +++ test/SemaCXX/class.cpp >> @@ -126,12 +126,8 @@ >> >> // Don't crash on this bogus code. >> namespace pr6629 { >> - // TODO: most of these errors are spurious >> template<class T1, class T2> struct foo : >> - bogus<foo<T1,T2> > // expected-error {{unknown template name >> 'bogus'}} \ >> - // BOGUS expected-error {{expected '{' after base >> class list}} \ >> - // BOGUS expected-error {{expected ';' after >> struct}} \ >> - // BOGUS expected-error {{expected >> unqualified-id}} >> + bogus<foo<T1,T2> > // expected-error {{unknown template name >> 'bogus'}} >> { }; >> >> template<> struct foo<unknown,unknown> { // expected-error >> {{undeclared identifier 'unknown'}} >> > > > > -- > Thanks, > --Serge > -- Thanks, --Serge
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
