]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CXX/dcl.decl/dcl.meaning/p1-0x.cpp
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / CXX / dcl.decl / dcl.meaning / p1-0x.cpp
1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2
3 // The nested-name-specifier of a qualified declarator-id shall not begin with a decltype-specifier.
4 class foo {
5   static int i;
6   void func();
7 };
8
9 int decltype(foo())::i; // expected-error{{'decltype' cannot be used to name a declaration}}
10 void decltype(foo())::func() { // expected-error{{'decltype' cannot be used to name a declaration}}
11 }
12
13
14 template<typename T>
15 class tfoo {
16   static int i;
17   void func();
18 };
19
20 template<typename T>
21 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 template<typename T>
23 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 }
25
26 // An init-declarator named with a qualified-id can refer to an element of the
27 // inline namespace set of the named namespace.
28 namespace inline_namespaces {
29   namespace N {
30     inline namespace M {
31       void f(); // expected-note {{possible target}}
32       void g();
33       extern int m; // expected-note {{candidate}}
34       extern int n;
35       struct S; // expected-note {{candidate}}
36       struct T;
37       enum E : int; // expected-note {{candidate}}
38       enum F : int;
39       template<typename T> void ft(); // expected-note {{here}}
40       template<typename T> void gt(); // expected-note {{here}}
41       template<typename T> extern int mt; // expected-note {{here}} expected-warning {{extension}}
42       template<typename T> extern int nt; // expected-note {{here}} expected-warning {{extension}}
43       template<typename T> struct U; // expected-note {{here}}
44       template<typename T> struct V; // expected-note {{here}}
45     }
46
47     // When named by unqualified-id, we do *not* look in the inline namespace
48     // set.
49     void f() {} // expected-note {{possible target}}
50     int m; // expected-note {{candidate}}
51     struct S {}; // expected-note {{candidate}}
52     enum E : int {}; // expected-note {{candidate}}
53
54     static_assert(&f != &M::f, ""); // expected-error {{reference to overloaded function could not be resolved}}
55     static_assert(&m != &M::m, ""); // expected-error {{ambiguous}}
56     typedef S X; // expected-error {{ambiguous}}
57     typedef E Y; // expected-error {{ambiguous}}
58
59     // When named by (unqualified) template-id, we do look in the inline
60     // namespace set.  See [namespace.def]p8, [temp.explicit]p3,
61     // [temp.expl.spec]p2.
62     //
63     // This is not explicitly specified for partial specializations, but
64     // that is just a language defect.
65     template<> void ft<int>() {}
66     template void ft<char>(); // expected-error {{undefined}}
67
68     template<typename T> int mt<T*>;
69     template<> int mt<int>;
70     template int mt<int*>;
71     template int mt<char>; // expected-error {{undefined}}
72
73     template<typename T> struct U<T*> {};
74     template<> struct U<int> {};
75     template struct U<int*>;
76     template struct U<char>; // expected-error {{undefined}}
77   }
78
79   // When named by qualified-id, we *do* look in the inline namespace set.
80   void N::g() {}
81   int N::n;
82   struct N::T {};
83   enum N::F : int {};
84
85   static_assert(&N::g == &N::M::g, "");
86   static_assert(&N::n == &N::M::n, "");
87   typedef N::T X;
88   typedef N::M::T X;
89   typedef N::F Y;
90   typedef N::M::F Y;
91
92   template<> void N::gt<int>() {}
93   template void N::gt<char>(); // expected-error {{undefined}}
94
95   template<typename T> int N::nt<T*>;
96   template<> int N::nt<int>;
97   template int N::nt<int*>;
98   template int N::nt<char>; // expected-error {{undefined}}
99
100   template<typename T> struct N::V<T*> {};
101   template<> struct N::V<int> {};
102   template struct N::V<int*>;
103   template struct N::V<char>; // expected-error {{undefined}}
104
105   struct Q {};
106
107   // Perversely, inline anonymous namespaces can cause an ostensibly
108   // external-linkage declaration to acquire internal linkage when
109   // redeclared with a qualified name.
110   inline namespace {
111     struct Q {} q;
112     int f_in_inline();
113     extern int v_in_inline;
114     typedef int t_in_inline;
115   }
116   // FIXME: These "extra qualification" warnings are bogus: the qualification
117   // changes the meaning of the program.
118   int inline_namespaces::f_in_inline() { // expected-warning {{extra qualification}}
119     // Finds <anon>::Q, not inline_namespaces::Q
120     Q x = q;
121     return 0;
122   }
123   int inline_namespaces::v_in_inline = // expected-warning {{extra qualification}}
124     (Q(q), 0);
125 }