PP.EnterToken(DigraphToken);
}
+// Check for '<::' which should be '< ::' instead of '[:' when following
+// a template name.
+void Parser::CheckForTemplateAndDigraph(Token &Next, ParsedType ObjectType,
+ bool EnteringContext,
+ IdentifierInfo &II, CXXScopeSpec &SS) {
+ if (!Next.is(tok::l_square) || !Next.getLength() == 2)
+ return;
+
+ Token SecondToken = GetLookAheadToken(2);
+ if (!SecondToken.is(tok::colon) || !AreTokensAdjacent(PP, Next, SecondToken))
+ return;
+
+ TemplateTy Template;
+ UnqualifiedId TemplateName;
+ TemplateName.setIdentifier(&II, Tok.getLocation());
+ bool MemberOfUnknownSpecialization;
+ if (!Actions.isTemplateName(getCurScope(), SS, /*hasTemplateKeyword=*/false,
+ TemplateName, ObjectType, EnteringContext,
+ Template, MemberOfUnknownSpecialization))
+ return;
+
+ FixDigraph(*this, PP, Next, SecondToken, tok::kw_template,
+ /*AtDigraph*/false);
+}
+
/// \brief Parse global scope or nested-name-specifier if present.
///
/// Parses a C++ global scope specifier ('::') or nested-name-specifier (which
continue;
}
- // Check for '<::' which should be '< ::' instead of '[:' when following
- // a template name.
- if (Next.is(tok::l_square) && Next.getLength() == 2) {
- Token SecondToken = GetLookAheadToken(2);
- if (SecondToken.is(tok::colon) &&
- AreTokensAdjacent(PP, Next, SecondToken)) {
- TemplateTy Template;
- UnqualifiedId TemplateName;
- TemplateName.setIdentifier(&II, Tok.getLocation());
- bool MemberOfUnknownSpecialization;
- if (Actions.isTemplateName(getCurScope(), SS,
- /*hasTemplateKeyword=*/false,
- TemplateName,
- ObjectType,
- EnteringContext,
- Template,
- MemberOfUnknownSpecialization)) {
- FixDigraph(*this, PP, Next, SecondToken, tok::kw_template,
- /*AtDigraph*/false);
- }
- }
- }
+ CheckForTemplateAndDigraph(Next, ObjectType, EnteringContext, II, SS);
// nested-name-specifier:
// type-name '<'
CXXScopeSpec SS;
IdentifierInfo *Name = Tok.getIdentifierInfo();
SourceLocation NameLoc = Tok.getLocation();
+
+ if (getLang().CPlusPlus)
+ CheckForTemplateAndDigraph(Next, ParsedType(),
+ /*EnteringContext=*/false, *Name, SS);
+
Sema::NameClassification Classification
= Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next);
switch (Classification.getKind()) {
test1::A LCC B> e; // expected-error{{found '<::' after a template name which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?}}
(void)static_cast LCC c>(&x); // expected-error{{found '<::' after a static_cast which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?}}
}
+
+template <class T> class D {};
+template <class T> void E() {};
+class F {};
+
+void test3() {
+ ::D<::F> A1; // expected-error{{found '<::' after a template name which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?}}
+ D<::F> A2; // expected-error{{found '<::' after a template name which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?}}
+ ::E<::F>(); // expected-error{{found '<::' after a template name which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?}}
+ E<::F>(); // expected-error{{found '<::' after a template name which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?}}
+
+ ::D< ::F> A3;
+ D< ::F> A4;
+ ::E< ::F>();
+ E< ::F>();
+}