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
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
