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