[PATCH] Avoid spurious error messages if parent template class cannot be instantiated
Serge Pavlov
sepavloff at gmail.com
Thu Jul 18 21:02:02 PDT 2013
Friendly ping.
2013/7/15 Serge Pavlov <sepavloff at gmail.com>
> Friendly ping.
>
>
> 2013/7/8 Serge Pavlov <sepavloff at gmail.com>
>
>> 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130719/685dab6d/attachment.html>
More information about the cfe-commits
mailing list