forked from OSchip/llvm-project
104 lines
3.8 KiB
C++
104 lines
3.8 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
|
|
|
|
// The nested-name-specifier of a qualified declarator-id shall not begin with a decltype-specifier.
|
|
class foo {
|
|
static int i;
|
|
void func();
|
|
};
|
|
|
|
int decltype(foo())::i; // expected-error{{'decltype' cannot be used to name a declaration}}
|
|
void decltype(foo())::func() { // expected-error{{'decltype' cannot be used to name a declaration}}
|
|
}
|
|
|
|
|
|
template<typename T>
|
|
class tfoo {
|
|
static int i;
|
|
void func();
|
|
};
|
|
|
|
template<typename T>
|
|
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}}
|
|
template<typename T>
|
|
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}}
|
|
}
|
|
|
|
// An init-declarator named with a qualified-id can refer to an element of the
|
|
// inline namespace set of the named namespace.
|
|
namespace inline_namespaces {
|
|
namespace N {
|
|
inline namespace M {
|
|
void f(); // expected-note {{possible target}}
|
|
void g();
|
|
extern int m, n;
|
|
struct S; struct T;
|
|
enum E : int; enum F : int;
|
|
template<typename T> void ft(); // expected-note {{here}}
|
|
template<typename T> void gt(); // expected-note {{here}}
|
|
template<typename T> extern int mt; // expected-note {{here}} expected-warning {{extension}}
|
|
template<typename T> extern int nt; // expected-note {{here}} expected-warning {{extension}}
|
|
template<typename T> struct U; // expected-note {{here}}
|
|
template<typename T> struct V; // expected-note {{here}}
|
|
}
|
|
|
|
// When named by unqualified-id, we do *not* look in the inline namespace
|
|
// set.
|
|
void f() {} // expected-note {{possible target}}
|
|
int m;
|
|
struct S {};
|
|
enum E : int {};
|
|
|
|
static_assert(&f != &M::f, ""); // expected-error {{reference to overloaded function could not be resolved}}
|
|
static_assert(&m != &M::m, "");
|
|
typedef S X; // expected-note {{previous}}
|
|
typedef M::S X; // expected-error {{different type}}
|
|
typedef E Y; // expected-note {{previous}}
|
|
typedef M::E Y; // expected-error {{different type}}
|
|
|
|
// When named by (unqualified) template-id, we do look in the inline
|
|
// namespace set. See [namespace.def]p8, [temp.explicit]p3,
|
|
// [temp.expl.spec]p2.
|
|
//
|
|
// This is not explicitly specified for partial specializations, but
|
|
// that is just a language defect.
|
|
template<> void ft<int>() {}
|
|
template void ft<char>(); // expected-error {{undefined}}
|
|
|
|
template<typename T> int mt<T*>; // expected-warning {{extension}}
|
|
template<> int mt<int>; // expected-warning {{extension}}
|
|
template int mt<int*>;
|
|
template int mt<char>; // expected-error {{undefined}}
|
|
|
|
template<typename T> struct U<T*> {};
|
|
template<> struct U<int> {};
|
|
template struct U<int*>;
|
|
template struct U<char>; // expected-error {{undefined}}
|
|
}
|
|
|
|
// When named by qualified-id, we *do* look in the inline namespace set.
|
|
void N::g() {}
|
|
int N::n;
|
|
struct N::T {};
|
|
enum N::F : int {};
|
|
|
|
static_assert(&N::g == &N::M::g, "");
|
|
static_assert(&N::n == &N::M::n, "");
|
|
typedef N::T X;
|
|
typedef N::M::T X;
|
|
typedef N::F Y;
|
|
typedef N::M::F Y;
|
|
|
|
template<> void N::gt<int>() {}
|
|
template void N::gt<char>(); // expected-error {{undefined}}
|
|
|
|
template<typename T> int N::nt<T*>; // expected-warning {{extension}}
|
|
template<> int N::nt<int>; // expected-warning {{extension}}
|
|
template int N::nt<int*>;
|
|
template int N::nt<char>; // expected-error {{undefined}}
|
|
|
|
template<typename T> struct N::V<T*> {};
|
|
template<> struct N::V<int> {};
|
|
template struct N::V<int*>;
|
|
template struct N::V<char>; // expected-error {{undefined}}
|
|
}
|