Skip to content

Commit a22a02f

Browse files
committed
[FOLD] don't annotate types as id-expressions
1 parent 3f8d7e0 commit a22a02f

File tree

4 files changed

+47
-34
lines changed

4 files changed

+47
-34
lines changed

clang/include/clang/Parse/Parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,6 +1907,7 @@ class Parser : public CodeCompletionHandler {
19071907
}
19081908

19091909
bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less);
1910+
bool isMissingTemplateKeywordBeforeScope();
19101911
void checkPotentialAngleBracket(ExprResult &PotentialTemplateName);
19111912
bool checkPotentialAngleBracketDelimiter(const AngleBracketTracker::Loc &,
19121913
const Token &OpToken);

clang/lib/Parse/ParseTemplate.cpp

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1779,6 +1779,36 @@ void Parser::checkPotentialAngleBracket(ExprResult &PotentialTemplateName) {
17791779
Priority);
17801780
}
17811781

1782+
bool Parser::isMissingTemplateKeywordBeforeScope() {
1783+
assert(Tok.is(tok::coloncolon));
1784+
Sema::DisableTypoCorrectionRAII DTC(Actions);
1785+
ColonProtectionRAIIObject ColonProtection(*this);
1786+
1787+
SourceLocation StartLoc = Tok.getLocation();
1788+
if (TryAnnotateTypeOrScopeToken())
1789+
return true;
1790+
if (Tok.isSimpleTypeSpecifier(getLangOpts()))
1791+
return false;
1792+
CXXScopeSpec SS;
1793+
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1794+
/*ObjectHasErrors=*/false,
1795+
/*EnteringContext=*/false);
1796+
ExprResult Result = tryParseCXXIdExpression(SS, /*isAddressOfOperand=*/false);
1797+
1798+
if (PP.isBacktrackEnabled())
1799+
PP.RevertCachedTokens(1);
1800+
else
1801+
PP.EnterToken(Tok, /*IsReinject=*/true);
1802+
1803+
SourceLocation EndLoc = Tok.getLocation();
1804+
Tok.setLocation(StartLoc);
1805+
Tok.setKind(tok::annot_primary_expr);
1806+
setExprAnnotation(Tok, Result);
1807+
Tok.setAnnotationEndLoc(EndLoc);
1808+
PP.AnnotateCachedTokens(Tok);
1809+
return Result.isInvalid();
1810+
}
1811+
17821812
bool Parser::checkPotentialAngleBracketDelimiter(
17831813
const AngleBracketTracker::Loc &LAngle, const Token &OpToken) {
17841814
// If a comma in an expression context is followed by a type that can be a
@@ -1802,36 +1832,14 @@ bool Parser::checkPotentialAngleBracketDelimiter(
18021832
return true;
18031833
}
18041834

1805-
if (OpToken.is(tok::greater) && Tok.is(tok::coloncolon)) {
1806-
Sema::DisableTypoCorrectionRAII DTC(Actions);
1807-
1808-
SourceLocation StartLoc = Tok.getLocation();
1809-
CXXScopeSpec SS;
1810-
ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
1811-
/*ObjectHasErrors=*/false,
1812-
/*EnteringContext=*/false);
1813-
ExprResult Result =
1814-
tryParseCXXIdExpression(SS, /*isAddressOfOperand=*/false);
1815-
1816-
if (PP.isBacktrackEnabled())
1817-
PP.RevertCachedTokens(1);
1818-
else
1819-
PP.EnterToken(Tok, /*IsReinject=*/true);
1820-
1821-
SourceLocation EndLoc = Tok.getLocation();
1822-
Tok.setLocation(StartLoc);
1823-
Tok.setKind(tok::annot_primary_expr);
1824-
setExprAnnotation(Tok, Result);
1825-
Tok.setAnnotationEndLoc(EndLoc);
1826-
PP.AnnotateCachedTokens(Tok);
1827-
1828-
if (Result.isInvalid()) {
1829-
Actions.diagnoseExprIntendedAsTemplateName(
1830-
getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1831-
OpToken.getLocation());
1832-
AngleBrackets.clear(*this);
1833-
return true;
1834-
}
1835+
if (OpToken.is(tok::greater) && Tok.is(tok::coloncolon) &&
1836+
!NextToken().isOneOf(tok::kw_new, tok::kw_delete) &&
1837+
isMissingTemplateKeywordBeforeScope()) {
1838+
Actions.diagnoseExprIntendedAsTemplateName(
1839+
getCurScope(), LAngle.TemplateName, LAngle.LessLoc,
1840+
OpToken.getLocation());
1841+
AngleBrackets.clear(*this);
1842+
return true;
18351843
}
18361844

18371845
// After a '>' (etc), we're no longer potentially in a construct that's

clang/lib/Sema/SemaCXXScopeSpec.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,13 +685,15 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
685685
if (ErrorRecoveryLookup)
686686
return true;
687687

688+
#if 0
688689
// If we didn't find anything during our lookup, try again with
689690
// ordinary name lookup, which can help us produce better error
690691
// messages.
691692
if (Found.empty()) {
692693
Found.clear(LookupOrdinaryName);
693694
LookupName(Found, S);
694695
}
696+
#endif
695697

696698
// In Microsoft mode, if we are within a templated function and we can't
697699
// resolve Identifier, then extend the SS with Identifier. This will have
@@ -733,6 +735,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
733735
}
734736
}
735737

738+
#if 1
736739
if (!Found.empty()) {
737740
if (TypeDecl *TD = Found.getAsSingle<TypeDecl>()) {
738741
Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace)
@@ -754,6 +757,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
754757
else
755758
Diag(IdInfo.IdentifierLoc, diag::err_undeclared_var_use)
756759
<< IdInfo.Identifier;
760+
#endif
757761

758762
return true;
759763
}

clang/test/SemaCXX/nested-name-spec.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify -fblocks %s
1+
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify -fblocks %s
22
namespace A {
33
struct C {
44
static int cx;
@@ -109,7 +109,7 @@ void A2::CC::NC::m(); // expected-error{{out-of-line declaration of a member mus
109109

110110
namespace E {
111111
int X = 5;
112-
112+
113113
namespace Nested {
114114
enum E {
115115
X = 0
@@ -143,7 +143,7 @@ Operators::operator bool() {
143143

144144
namespace A {
145145
void g(int&); // expected-note{{type of 1st parameter of member declaration does not match definition ('int &' vs 'const int &')}}
146-
}
146+
}
147147

148148
void A::f() {} // expected-error-re{{out-of-line definition of 'f' does not match any declaration in namespace 'A'{{$}}}}
149149

@@ -458,7 +458,7 @@ namespace A {
458458
class B {
459459
typedef C D; // expected-error{{unknown type name 'C'}}
460460
A::D::F;
461-
// expected-error@-1{{'PR30619::A::B::D' (aka 'int') is not a class, namespace, or enumeration}}
461+
// expected-error@-1{{no member named 'D' in namespace 'PR30619::A'}}
462462
};
463463
}
464464
}

0 commit comments

Comments
 (0)