[PATCH] Avoid spurious error messages if parent template class cannot be instantiated

Serge Pavlov sepavloff at gmail.com
Sun Aug 4 19:44:53 PDT 2013


Friendly ping.


2013/7/19 Serge Pavlov <sepavloff at gmail.com>

> 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
>



-- 
Thanks,
--Serge
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130805/90bcef1f/attachment.html>


More information about the cfe-commits mailing list