Commit Graph

8 Commits

Author SHA1 Message Date
Richard Smith beda951d78 Make tentative parsing to detect template-argument-lists less aggressive
(and less wrong).

It's not correct to assume that X<something, Type> is always a
template-id; there are a few cases where the comma takes us into a
non-expression syntactic context in which 'Type' might be permissible.
Stop doing that.

This slightly regresses our error recovery on the cases where the
construct is intended to be a template-id. We typically do still manage
to diagnose a missing 'template' keyword, but we realize this too late
to properly recover from the error.

This fixes a regression introduced by r360308.

llvm-svn: 360827
2019-05-15 23:36:14 +00:00
Richard Smith b23c5e8c3d [c++20] Implement P0846R0: allow (ADL-only) calls to template-ids whose
template name is not visible to unqualified lookup.

In order to support this without a severe degradation in our ability to
diagnose typos in template names, this change significantly restructures
the way we handle template-id-shaped syntax for which lookup of the
template name finds nothing.

Instead of eagerly diagnosing an undeclared template name, we now form a
placeholder template-name representing a name that is known to not find
any templates. When the parser sees such a name, it attempts to
disambiguate whether we have a less-than comparison or a template-id.
Any diagnostics or typo-correction for the name are delayed until its
point of use.

The upshot should be a small improvement of our diagostic quality
overall: we now take more syntactic context into account when trying to
resolve an undeclared identifier on the left hand side of a '<'. In
fact, this works well enough that the backwards-compatible portion (for
an undeclared identifier rather than a lookup that finds functions but
no function templates) is enabled in all language modes.

llvm-svn: 360308
2019-05-09 03:31:27 +00:00
Richard Smith c2dead4d9a Diagnose missing 'template' keywords in contexts where a comma is not a
binary operator.

Factor out the checking for a comma within potential angle brackets and
also call it from contexts where we parse a comma-separated list of
arguments or initializers.

llvm-svn: 335699
2018-06-27 01:32:04 +00:00
Richard Smith bf5bcf2c15 Diagnose missing 'template' keywords in more cases.
We track when we see a name-shaped expression followed by a '<' token
and parse the '<' as a comparison. Then:

 * if we see a token sequence that cannot possibly be an expression but
   can be a template argument (in particular, a type-id) that follows
   either a ',' or the '<', diagnose that the '<' was supposed to start
   a template argument list, and
 * if we see '>()', diagnose that the '<' was supposed to start a
   template argument list.

This only changes the diagnostic for error cases, and in practice
appears to catch the most common cases where a missing 'template'
keyword leads to parse errors within a template.

Differential Revision: https://reviews.llvm.org/D48571

llvm-svn: 335687
2018-06-26 23:20:26 +00:00
Richard Smith 17c59472e8 Improve error recovery for missing 'template' keyword in contexts where the
template is valid with or without it (with different meanings).

If we see "dependent.x<...", and what follows the '<' is a valid expression,
we must parse the '<' as a comparison rather than a template angle bracket.
When we later come to instantiate, if we find that the LHS of the '<' actually
names an overload set containing function templates, produce a diagnostic
suggesting that the 'template' keyword was missed rather than producing a
mysterious diagnostic saying that the function must be called (and pointing
at what looks to already be a function call!).

llvm-svn: 304852
2017-06-07 00:29:44 +00:00
Douglas Gregor 23648d7e3b When constructing source-location information for a
DependentTemplateSpecializationType during tree transformation, retain
the NestedNameSpecifierLoc as it was used to translate the template
name, rather than reconstructing it from the template name.

Fixes PR9401.

llvm-svn: 127015
2011-03-04 18:53:13 +00:00
Douglas Gregor 20c38a7c58 Improve recovery when we see a dependent template name that is missing
the required "template" keyword, using the same heuristics we do for
dependent template names in member access expressions, e.g.,

test/SemaTemplate/dependent-template-recover.cpp:11:8: error: use 'template'
      keyword to treat 'getAs' as a dependent template name
    T::getAs<U>();
       ^
       template 

Fixes PR5404.

llvm-svn: 104409
2010-05-21 23:43:39 +00:00
Douglas Gregor 786123dc48 Improve parser recovery when we encounter a dependent template name
that is missing the 'template' keyword, e.g., 

  t->getAs<T>()

where getAs is a member of an unknown specialization. C++ requires
that we treat "getAs" as a value, but that would fail to parse since T
is the name of a type. We would then fail at the '>', since a type
cannot be followed by a '>'.

This is a very common error for C++ programmers to make, especially
since GCC occasionally allows it when it shouldn't (as does Visual
C++). So, when we are in this case, we use tentative parsing to see if
the tokens starting at "<" can only be parsed as a template argument
list. If so, we produce a diagnostic with a fix-it that states that
the 'template' keyword is needed:

test/SemaTemplate/dependent-template-recover.cpp:5:8: error: 'template' keyword
      is required to treat 'getAs' as a dependent template name
    t->getAs<T>();
       ^
       template 

This is just a start of this patch; I'd like to apply the same
approach to everywhere that a template-id with dependent template name
can be parsed.

llvm-svn: 104406
2010-05-21 23:18:07 +00:00