1cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// The nested-name-specifier of a qualified declarator-id shall not begin with a decltype-specifier.
4cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class foo {
5cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static int i;
6cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void func();
7cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)};
8cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
9cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)int decltype(foo())::i; // expected-error{{'decltype' cannot be used to name a declaration}}
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void decltype(foo())::func() { // expected-error{{'decltype' cannot be used to name a declaration}}
11cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
13cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)template<typename T>
15cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class tfoo {
16cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static int i;
17  void func();
18};
19
20template<typename T>
21int 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}}
22template<typename T>
23void 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.
28namespace 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