Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 2f52311

Browse files
committed
[AST] Incorrectly qualified unscoped enumeration as template actual parameter.
An unscoped enumeration used as template argument, should not have any qualified information about its enclosing scope, as its visibility is global. In the case of scoped enumerations, they must include information about their enclosing scope. Patch by Carlos Alberto Enciso! Differential Revision: https://reviews.llvm.org/D39239 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@321312 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent fcc28fd commit 2f52311

File tree

6 files changed

+36
-7
lines changed

6 files changed

+36
-7
lines changed

lib/AST/Decl.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1548,7 +1548,10 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
15481548
// enumerator is declared in the scope that immediately contains
15491549
// the enum-specifier. Each scoped enumerator is declared in the
15501550
// scope of the enumeration.
1551-
if (ED->isScoped() || ED->getIdentifier())
1551+
// For the case of unscoped enumerator, do not include in the qualified
1552+
// name any information about its enum enclosing scope, as is visibility
1553+
// is global.
1554+
if (ED->isScoped())
15521555
OS << *ED;
15531556
else
15541557
continue;

test/Modules/odr.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,6 @@ int x = f() + g();
1818
// expected-note@a.h:3 {{declaration of 'f' does not match}}
1919
// expected-note@a.h:1 {{definition has no member 'm'}}
2020

21-
// expected-error@b.h:5 {{'E::e2' from module 'b' is not present in definition of 'E' in module 'a'}}
21+
// expected-error@b.h:5 {{'e2' from module 'b' is not present in definition of 'E' in module 'a'}}
2222
// expected-error@b.h:3 {{'Y::f' from module 'b' is not present in definition of 'Y' in module 'a'}}
2323
// expected-error@b.h:2 {{'Y::m' from module 'b' is not present in definition of 'Y' in module 'a'}}

test/SemaCXX/return-noreturn.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ template <PR9412_MatchType type> int PR9412_t() {
143143
} // expected-warning {{control reaches end of non-void function}}
144144

145145
void PR9412_f() {
146-
PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<PR9412_MatchType::PR9412_Exact>' requested here}}
146+
PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<PR9412_Exact>' requested here}}
147147
}
148148

149149
struct NoReturn {

test/SemaTemplate/temp_arg_enum_printing.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ template <NamedEnum E>
1313
void foo();
1414

1515
void test() {
16-
// CHECK: template<> void foo<NamedEnumNS::NamedEnum::Val0>()
16+
// CHECK: template<> void foo<NamedEnumNS::Val0>()
1717
NamedEnumNS::foo<Val0>();
18-
// CHECK: template<> void foo<NamedEnumNS::NamedEnum::Val1>()
18+
// CHECK: template<> void foo<NamedEnumNS::Val1>()
1919
NamedEnumNS::foo<(NamedEnum)1>();
2020
// CHECK: template<> void foo<2>()
2121
NamedEnumNS::foo<(NamedEnum)2>();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang_cc1 -fsyntax-only -ast-print %s -std=c++11 | FileCheck %s
2+
3+
// Make sure that for template value arguments that are unscoped enumerators,
4+
// no qualified enum information is included in their name, as their visibility
5+
// is global. In the case of scoped enumerators, they must include information
6+
// about their enum enclosing scope.
7+
8+
enum E1 { e1 };
9+
template<E1 v> struct tmpl_1 {};
10+
// CHECK: template<> struct tmpl_1<e1>
11+
tmpl_1<E1::e1> TMPL_1; // Name must be 'e1'.
12+
13+
namespace nsp_1 { enum E2 { e2 }; }
14+
template<nsp_1::E2 v> struct tmpl_2 {};
15+
// CHECK: template<> struct tmpl_2<nsp_1::e2>
16+
tmpl_2<nsp_1::E2::e2> TMPL_2; // Name must be 'nsp_1::e2'.
17+
18+
enum class E3 { e3 };
19+
template<E3 v> struct tmpl_3 {};
20+
// CHECK: template<> struct tmpl_3<E3::e3>
21+
tmpl_3<E3::e3> TMPL_3; // Name must be 'E3::e3'.
22+
23+
namespace nsp_2 { enum class E4 { e4 }; }
24+
template<nsp_2::E4 v> struct tmpl_4 {};
25+
// CHECK: template<> struct tmpl_4<nsp_2::E4::e4>
26+
tmpl_4<nsp_2::E4::e4> TMPL_4; // Name must be 'nsp_2::E4::e4'.

unittests/AST/NamedDeclPrinterTest.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ TEST(NamedDeclPrinter, TestNamedEnum) {
143143
ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
144144
"enum X { A };",
145145
"A",
146-
"X::A"));
146+
"A"));
147147
}
148148

149149
TEST(NamedDeclPrinter, TestScopedNamedEnum) {
@@ -164,7 +164,7 @@ TEST(NamedDeclPrinter, TestClassWithUnscopedNamedEnum) {
164164
ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(
165165
"class X { enum Y { A }; };",
166166
"A",
167-
"X::Y::A"));
167+
"X::A"));
168168
}
169169

170170
TEST(NamedDeclPrinter, TestClassWithScopedNamedEnum) {

0 commit comments

Comments
 (0)