xref: /aosp_15_r20/external/clang/test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2*67e74705SXin Li 
3*67e74705SXin Li // The nested-name-specifier of a qualified declarator-id shall not begin with a decltype-specifier.
4*67e74705SXin Li class foo {
5*67e74705SXin Li   static int i;
6*67e74705SXin Li   void func();
7*67e74705SXin Li };
8*67e74705SXin Li 
9*67e74705SXin Li int decltype(foo())::i; // expected-error{{'decltype' cannot be used to name a declaration}}
foo()10*67e74705SXin Li void decltype(foo())::func() { // expected-error{{'decltype' cannot be used to name a declaration}}
11*67e74705SXin Li }
12*67e74705SXin Li 
13*67e74705SXin Li 
14*67e74705SXin Li template<typename T>
15*67e74705SXin Li class tfoo {
16*67e74705SXin Li   static int i;
17*67e74705SXin Li   void func();
18*67e74705SXin Li };
19*67e74705SXin Li 
20*67e74705SXin Li template<typename T>
21*67e74705SXin Li int decltype(tfoo<T>())::i; // expected-error{{nested name specifier 'decltype(tfoo<T>())::' for declaration does not refer into a class, class template or class template partial specialization}}
22*67e74705SXin Li template<typename T>
func()23*67e74705SXin Li void decltype(tfoo<T>())::func() { // expected-error{{nested name specifier 'decltype(tfoo<T>())::' for declaration does not refer into a class, class template or class template partial specialization}}
24*67e74705SXin Li }
25*67e74705SXin Li 
26*67e74705SXin Li // An init-declarator named with a qualified-id can refer to an element of the
27*67e74705SXin Li // inline namespace set of the named namespace.
28*67e74705SXin Li namespace inline_namespaces {
29*67e74705SXin Li   namespace N {
30*67e74705SXin Li     inline namespace M {
31*67e74705SXin Li       void f(); // expected-note {{possible target}}
32*67e74705SXin Li       void g();
33*67e74705SXin Li       extern int m; // expected-note {{candidate}}
34*67e74705SXin Li       extern int n;
35*67e74705SXin Li       struct S; // expected-note {{candidate}}
36*67e74705SXin Li       struct T;
37*67e74705SXin Li       enum E : int; // expected-note {{candidate}}
38*67e74705SXin Li       enum F : int;
39*67e74705SXin Li       template<typename T> void ft(); // expected-note {{here}}
40*67e74705SXin Li       template<typename T> void gt(); // expected-note {{here}}
41*67e74705SXin Li       template<typename T> extern int mt; // expected-note {{here}} expected-warning {{extension}}
42*67e74705SXin Li       template<typename T> extern int nt; // expected-note {{here}} expected-warning {{extension}}
43*67e74705SXin Li       template<typename T> struct U; // expected-note {{here}}
44*67e74705SXin Li       template<typename T> struct V; // expected-note {{here}}
45*67e74705SXin Li     }
46*67e74705SXin Li 
47*67e74705SXin Li     // When named by unqualified-id, we do *not* look in the inline namespace
48*67e74705SXin Li     // set.
f()49*67e74705SXin Li     void f() {} // expected-note {{possible target}}
50*67e74705SXin Li     int m; // expected-note {{candidate}}
51*67e74705SXin Li     struct S {}; // expected-note {{candidate}}
52*67e74705SXin Li     enum E : int {}; // expected-note {{candidate}}
53*67e74705SXin Li 
54*67e74705SXin Li     static_assert(&f != &M::f, ""); // expected-error {{reference to overloaded function could not be resolved}}
55*67e74705SXin Li     static_assert(&m != &M::m, ""); // expected-error {{ambiguous}}
56*67e74705SXin Li     typedef S X; // expected-error {{ambiguous}}
57*67e74705SXin Li     typedef E Y; // expected-error {{ambiguous}}
58*67e74705SXin Li 
59*67e74705SXin Li     // When named by (unqualified) template-id, we do look in the inline
60*67e74705SXin Li     // namespace set.  See [namespace.def]p8, [temp.explicit]p3,
61*67e74705SXin Li     // [temp.expl.spec]p2.
62*67e74705SXin Li     //
63*67e74705SXin Li     // This is not explicitly specified for partial specializations, but
64*67e74705SXin Li     // that is just a language defect.
ft()65*67e74705SXin Li     template<> void ft<int>() {}
66*67e74705SXin Li     template void ft<char>(); // expected-error {{undefined}}
67*67e74705SXin Li 
68*67e74705SXin Li     template<typename T> int mt<T*>;
69*67e74705SXin Li     template<> int mt<int>;
70*67e74705SXin Li     template int mt<int*>;
71*67e74705SXin Li     template int mt<char>; // expected-error {{undefined}}
72*67e74705SXin Li 
73*67e74705SXin Li     template<typename T> struct U<T*> {};
74*67e74705SXin Li     template<> struct U<int> {};
75*67e74705SXin Li     template struct U<int*>;
76*67e74705SXin Li     template struct U<char>; // expected-error {{undefined}}
77*67e74705SXin Li   }
78*67e74705SXin Li 
79*67e74705SXin Li   // When named by qualified-id, we *do* look in the inline namespace set.
g()80*67e74705SXin Li   void N::g() {}
81*67e74705SXin Li   int N::n;
82*67e74705SXin Li   struct N::T {};
83*67e74705SXin Li   enum N::F : int {};
84*67e74705SXin Li 
85*67e74705SXin Li   static_assert(&N::g == &N::M::g, "");
86*67e74705SXin Li   static_assert(&N::n == &N::M::n, "");
87*67e74705SXin Li   typedef N::T X;
88*67e74705SXin Li   typedef N::M::T X;
89*67e74705SXin Li   typedef N::F Y;
90*67e74705SXin Li   typedef N::M::F Y;
91*67e74705SXin Li 
gt()92*67e74705SXin Li   template<> void N::gt<int>() {}
93*67e74705SXin Li   template void N::gt<char>(); // expected-error {{undefined}}
94*67e74705SXin Li 
95*67e74705SXin Li   template<typename T> int N::nt<T*>;
96*67e74705SXin Li   template<> int N::nt<int>;
97*67e74705SXin Li   template int N::nt<int*>;
98*67e74705SXin Li   template int N::nt<char>; // expected-error {{undefined}}
99*67e74705SXin Li 
100*67e74705SXin Li   template<typename T> struct N::V<T*> {};
101*67e74705SXin Li   template<> struct N::V<int> {};
102*67e74705SXin Li   template struct N::V<int*>;
103*67e74705SXin Li   template struct N::V<char>; // expected-error {{undefined}}
104*67e74705SXin Li }
105