Skip to content

Commit 7335550

Browse files
reject nested name specifier other than global namespace and add test
1 parent b811940 commit 7335550

File tree

2 files changed

+55
-19
lines changed

2 files changed

+55
-19
lines changed

clang/lib/Parse/ParseReflect.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,36 @@ ExprResult Parser::ParseCXXReflectExpression(SourceLocation DoubleCaretLoc) {
2121
EnterExpressionEvaluationContext Unevaluated(
2222
Actions, Sema::ExpressionEvaluationContext::Unevaluated);
2323

24+
CXXScopeSpec SS;
25+
if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/nullptr,
26+
/*ObjectHasErrors=*/false,
27+
/*EnteringContext=*/false)) {
28+
SkipUntil(tok::semi, StopAtSemi | StopBeforeMatch);
29+
return ExprError();
30+
}
31+
2432
SourceLocation OperandLoc = Tok.getLocation();
33+
TentativeParsingAction TPA(*this);
2534

26-
{
27-
TentativeParsingAction TPA(*this);
28-
// global namespace ::
29-
if (Tok.is(tok::coloncolon)) {
30-
ConsumeToken();
31-
TPA.Commit();
32-
Decl *TUDecl = Actions.getASTContext().getTranslationUnitDecl();
33-
return Actions.ActOnCXXReflectExpr(DoubleCaretLoc, SourceLocation(),
34-
TUDecl);
35-
}
36-
TPA.Revert();
35+
// Next, check for an unqualified-id.
36+
if (Tok.isOneOf(tok::identifier, tok::kw_operator, tok::kw_template,
37+
tok::tilde, tok::annot_template_id)) {
38+
// TODO(reflection) : support parsing for
39+
// - type-name::
40+
// - nested-name-specifier identifier ::
41+
// - namespace-name ::
42+
// - nested-name-specifier template_opt simple-template-id
43+
Diag(OperandLoc, diag::err_cannot_reflect_operand);
44+
return ExprError();
45+
} else if (SS.isValid() &&
46+
SS.getScopeRep().getKind() == NestedNameSpecifier::Kind::Global) {
47+
// global namespace ::.
48+
TPA.Commit();
49+
Decl *TUDecl = Actions.getASTContext().getTranslationUnitDecl();
50+
return Actions.ActOnCXXReflectExpr(DoubleCaretLoc, SourceLocation(),
51+
TUDecl);
3752
}
53+
TPA.Revert();
3854

3955
if (isCXXTypeId(TentativeCXXTypeIdContext::AsReflectionOperand)) {
4056
TypeResult TR = ParseTypeName(/*TypeOf=*/nullptr);

clang/test/Reflection/parsing-reflection.cpp

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
// RUN: %clang_cc1 %s -std=c++26 -freflection -fsyntax-only -verify
22

33
namespace a {
4-
struct T {};
4+
struct X {
5+
int y;
6+
bool operator==(const X& other)
7+
{
8+
return y == other.y;
9+
}
10+
};
11+
512
namespace b {
6-
struct U {};
7-
int x;
8-
}
13+
struct Y {};
14+
int x;
915
}
1016

17+
template<typename T>
18+
struct Z{
19+
template<typename U>
20+
using type = U;
21+
};
22+
23+
}
1124

1225
int main()
1326
{
@@ -30,11 +43,18 @@ int main()
3043
// Not supported yet.
3144
(void)^^a; // expected-error {{expected reflectable entity}}
3245
(void)^^a::; // expected-error {{expected reflectable entity}}
33-
(void)^^a::b::T; // expected-error {{expected reflectable entity}}
34-
(void)^^a::T::; // expected-error {{expected reflectable entity}}
46+
(void)^^a::b::X; // expected-error {{expected reflectable entity}}
47+
(void)^^a::X::; // expected-error {{expected reflectable entity}}
3548
(void)(^^a::b); // expected-error {{expected reflectable entity}}
3649
(void)^^a::b::; // expected-error {{expected reflectable entity}}
37-
(void)^^a::b::U; // expected-error {{expected reflectable entity}}
50+
(void)^^a::b::Y; // expected-error {{expected reflectable entity}}
3851
(void)^^a::b::x; // expected-error {{expected reflectable entity}}
39-
(void)^^a::b::U::; // expected-error {{expected reflectable entity}}
52+
(void)^^a::b::Y::; // expected-error {{expected reflectable entity}}
53+
(void)(^^::a::); // expected-error {{expected reflectable entity}}
54+
(void)(^^::a::X::operator==); // expected-error {{expected reflectable entity}}
55+
(void)(^^::a::X::~X()); // expected-error {{expected reflectable entity}}
56+
(void)(^^::a::Z<int>); // expected-error {{expected reflectable entity}}
57+
(void)(^^::a::Z<int>::template type<int>); // expected-error {{expected reflectable entity}}
58+
namespace c = a::b;
59+
(void)(^^c); // expected-error {{expected reflectable entity}}
4060
}

0 commit comments

Comments
 (0)