diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseExprCXX.cpp | 25 | ||||
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 1 |
3 files changed, 32 insertions, 1 deletions
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index 1588b69bda..0a909f626f 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -307,6 +307,31 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, 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; } } diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 8b9142ce9b..c87ddad4e9 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -971,12 +971,17 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() { /// \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; diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index b4f9c3df8b..8ff637f2d1 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -175,6 +175,7 @@ bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II, 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; |