1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2
3// Fun things you can do with inline namespaces:
4
5inline 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.
20void 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
32template <> class C<float> {};
33template <typename T> class C<T&> {};
34
35template class C<double>;
36
37
38// As well as all the fun with ADL.
39
40namespace 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
56void 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.
65struct Distinct {};
66inline namespace Over {
67  void over(Distinct);
68}
69void over(int);
70
71void foo3() {
72  Distinct d;
73  ::over(d);
74}
75
76// Don't forget to do correct lookup for redeclarations.
77namespace 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.
102namespace 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