[cfe-commits] r104409 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/dependent-base-classes.cpp test/SemaTemplate/dependent-template-recover.cpp
Douglas Gregor
dgregor at apple.com
Fri May 21 16:43:39 PDT 2010
Author: dgregor
Date: Fri May 21 18:43:39 2010
New Revision: 104409
URL: http://llvm.org/viewvc/llvm-project?rev=104409&view=rev
Log:
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.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp
cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri May 21 18:43:39 2010
@@ -1463,7 +1463,7 @@
SourceLocation TemplateKWLoc = SourceLocation(),
bool AllowTypeAnnotation = true);
void AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS = 0);
- bool IsTemplateArgumentList();
+ bool IsTemplateArgumentList(unsigned Skip = 0);
bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs);
ParsedTemplateArgument ParseTemplateTemplateArgument();
ParsedTemplateArgument ParseTemplateArgument();
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Fri May 21 18:43:39 2010
@@ -307,6 +307,31 @@
SourceLocation(), false))
return true;
continue;
+ }
+
+ if (MemberOfUnknownSpecialization && (ObjectType || SS.isSet()) &&
+ IsTemplateArgumentList(1)) {
+ // We have something like t::getAs<T>, where getAs is a
+ // member of an unknown specialization. However, this will only
+ // parse correctly as a template, so suggest the keyword 'template'
+ // before 'getAs' and treat this as a dependent template name.
+ Diag(Tok.getLocation(), diag::err_missing_dependent_template_keyword)
+ << II.getName()
+ << FixItHint::CreateInsertion(Tok.getLocation(), "template ");
+
+ Template = Actions.ActOnDependentTemplateName(Tok.getLocation(), SS,
+ TemplateName, ObjectType,
+ EnteringContext);
+ if (!Template.get())
+ return true;
+
+ // Consume the identifier.
+ ConsumeToken();
+ if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name, &SS,
+ TemplateName, SourceLocation(), false))
+ return true;
+
+ continue;
}
}
Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Fri May 21 18:43:39 2010
@@ -971,12 +971,17 @@
/// \brief Determine whether the current tokens can only be parsed as a
/// template argument list (starting with the '<') and never as a '<'
/// expression.
-bool Parser::IsTemplateArgumentList() {
+bool Parser::IsTemplateArgumentList(unsigned Skip) {
struct AlwaysRevertAction : TentativeParsingAction {
AlwaysRevertAction(Parser &P) : TentativeParsingAction(P) { }
~AlwaysRevertAction() { Revert(); }
} Tentative(*this);
+ while (Skip) {
+ ConsumeToken();
+ --Skip;
+ }
+
// '<'
if (!Tok.is(tok::less))
return false;
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri May 21 18:43:39 2010
@@ -175,6 +175,7 @@
TemplateNameKind &SuggestedKind) {
// We can't recover unless there's a dependent scope specifier preceding the
// template name.
+ // FIXME: Typo correction?
if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) ||
computeDeclContext(*SS))
return false;
Modified: cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-base-classes.cpp Fri May 21 18:43:39 2010
@@ -6,7 +6,7 @@
};
template<typename T, typename U>
-struct X1 : T::apply<U> { }; // expected-error{{missing 'template' keyword prior to dependent template name 'T::apply'}}
+struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
template<typename T>
struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}
Modified: cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp?rev=104409&r1=104408&r2=104409&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp (original)
+++ cfe/trunk/test/SemaTemplate/dependent-template-recover.cpp Fri May 21 18:43:39 2010
@@ -8,6 +8,9 @@
t->operator+<U const, 1>(); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}}
t->f1<int const, 2>(); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}}
+ T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+ t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+
// FIXME: We can't recover from these yet
(*t).f2<N>(); // expected-error{{expected expression}}
(*t).f2<0>(); // expected-error{{expected expression}}
More information about the cfe-commits
mailing list