Home | History | Annotate | Download | only in dcl.meaning
      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