126 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s2 3// The nested-name-specifier of a qualified declarator-id shall not begin with a decltype-specifier.4class foo {5 static int i;6 void func();7};8 9int decltype(foo())::i; // expected-error{{a 'decltype' specifier cannot be used in a declarative nested name specifier}}10void decltype(foo())::func() { // expected-error{{a 'decltype' specifier cannot be used in a declarative nested name specifier}}11}12 13 14template<typename T>15class tfoo {16 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 the27// 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 namespace48 // 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 inline60 // namespace set. See [namespace.def]p8, [temp.explicit]p3,61 // [temp.expl.spec]p2.62 //63 // This is not explicitly specified for partial specializations, but64 // 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 struct Q {};106 107 // Perversely, inline anonymous namespaces can cause an ostensibly108 // external-linkage declaration to acquire internal linkage when109 // redeclared with a qualified name.110 inline namespace {111 struct Q {} q;112 int f_in_inline();113 extern int v_in_inline;114 typedef int t_in_inline;115 }116 // FIXME: These "extra qualification" warnings are bogus: the qualification117 // changes the meaning of the program.118 int inline_namespaces::f_in_inline() { // expected-warning {{extra qualification}}119 // Finds <anon>::Q, not inline_namespaces::Q120 Q x = q;121 return 0;122 }123 int inline_namespaces::v_in_inline = // expected-warning {{extra qualification}}124 (Q(q), 0);125}126