1 | // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s |
2 | |
3 | // Fun things you can do with inline namespaces: |
4 | |
5 | inline namespace X { |
6 | void f1(); // expected-note {{'f1' declared here}} |
7 | |
8 | inline namespace Y { |
9 | void f2(); |
10 | |
11 | template <typename T> class C {}; |
12 | } |
13 | |
14 | // Specialize and partially specialize somewhere else. |
15 | template <> class C<int> {}; |
16 | template <typename T> class C<T*> {}; |
17 | } |
18 | |
19 | // Qualified and unqualified lookup as if member of enclosing NS. |
20 | void foo1() { |
21 | f1(); |
22 | ::f1(); |
23 | X::f1(); |
24 | Y::f1(); // expected-error {{no member named 'f1' in namespace 'X::Y'; did you mean simply 'f1'?}} |
25 | |
26 | f2(); |
27 | ::f2(); |
28 | X::f2(); |
29 | Y::f2(); |
30 | } |
31 | |
32 | template <> class C<float> {}; |
33 | template <typename T> class C<T&> {}; |
34 | |
35 | template class C<double>; |
36 | |
37 | |
38 | // As well as all the fun with ADL. |
39 | |
40 | namespace ADL { |
41 | struct Outer {}; |
42 | |
43 | inline namespace IL { |
44 | struct Inner {}; |
45 | |
46 | void fo(Outer); |
47 | } |
48 | |
49 | void fi(Inner); |
50 | |
51 | inline namespace IL2 { |
52 | void fi2(Inner); |
53 | } |
54 | } |
55 | |
56 | void foo2() { |
57 | ADL::Outer o; |
58 | ADL::Inner i; |
59 | fo(o); |
60 | fi(i); |
61 | fi2(i); |
62 | } |
63 | |
64 | // Let's not forget overload sets. |
65 | struct Distinct {}; |
66 | inline namespace Over { |
67 | void over(Distinct); |
68 | } |
69 | void over(int); |
70 | |
71 | void foo3() { |
72 | Distinct d; |
73 | ::over(d); |
74 | } |
75 | |
76 | // Don't forget to do correct lookup for redeclarations. |
77 | namespace redecl { inline namespace n1 { |
78 | |
79 | template <class Tp> class allocator; |
80 | |
81 | template <> |
82 | class allocator<void> |
83 | { |
84 | public: |
85 | typedef const void* const_pointer; |
86 | }; |
87 | |
88 | template <class Tp> |
89 | class allocator |
90 | { |
91 | public: |
92 | typedef Tp& reference; |
93 | |
94 | void allocate(allocator<void>::const_pointer = 0); |
95 | }; |
96 | |
97 | } } |
98 | |
99 | // Normal redeclarations (not for explicit instantiations or |
100 | // specializations) are distinct in an inline namespace vs. not in an |
101 | // inline namespace. |
102 | namespace redecl2 { |
103 | inline namespace n1 { |
104 | void f(int) { } |
105 | struct X1 { }; |
106 | template<typename T> void f(T) { } |
107 | template<typename T> struct X2 { }; |
108 | int i = 71; |
109 | enum E { e }; |
110 | } |
111 | |
112 | void f(int) { } |
113 | struct X1 { }; |
114 | template<typename T> void f(T) { } |
115 | template<typename T> struct X2 { }; |
116 | int i = 71; |
117 | enum E { e }; |
118 | } |
119 | |