summaryrefslogtreecommitdiff
path: root/clang/test/CXX/dcl.dcl/basic.namespace
diff options
context:
space:
mode:
authorZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
committerZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
commit222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch)
tree7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CXX/dcl.dcl/basic.namespace
parent3d206f03985b50beacae843d880bccdc91a9f424 (diff)
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CXX/dcl.dcl/basic.namespace')
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp93
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp42
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp9
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp24
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp13
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp118
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp110
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp34
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp91
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp163
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp76
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp46
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp213
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp12
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp8
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp15
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp98
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp141
-rw-r--r--clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp15
19 files changed, 1321 insertions, 0 deletions
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
new file mode 100644
index 0000000..069ca0a
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
@@ -0,0 +1,93 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+
+// C++'0x [namespace.memdef] p3:
+// Every name first declared in a namespace is a member of that namespace. If
+// a friend declaration in a non-local class first declares a class or
+// function the friend class or function is a member of the innermost
+// enclosing namespace.
+
+namespace N {
+ struct S0 {
+ friend struct F0;
+ friend void f0(int);
+ struct F0 member_func();
+ };
+ struct F0 { };
+ F0 f0() { return S0().member_func(); }
+}
+N::F0 f0_var = N::f0();
+
+// Ensure we can handle attaching friend declarations to an enclosing namespace
+// with multiple contexts.
+namespace N { struct S1 { struct IS1; }; }
+namespace N {
+ struct S1::IS1 {
+ friend struct F1;
+ friend void f1(int);
+ struct F1 member_func();
+ };
+ struct F1 { };
+ F1 f1() { return S1::IS1().member_func(); }
+}
+N::F1 f1_var = N::f1();
+
+// The name of the friend is not found by unqualified lookup (3.4.1) or by
+// qualified lookup (3.4.3) until a matching declaration is provided in that
+// namespace scope (either before or after the class definition granting
+// friendship). If a friend function is called, its name may be found by the
+// name lookup that considers functions from namespaces and classes
+// associated with the types of the function arguments (3.4.2). If the name
+// in a friend declaration is neither qualified nor a template-id and the
+// declaration is a function or an elaborated-type-specifier, the lookup to
+// determine whether the entity has been previously declared shall not
+// consider any scopes outside the innermost enclosing namespace.
+
+template<typename T> struct X0 { };
+struct X1 { };
+
+struct Y {
+ template<typename T> union X0;
+ template<typename T> friend union X0;
+
+ union X1;
+ friend union X1;
+};
+
+namespace N {
+ namespace M {
+ template<typename T> class X;
+ }
+}
+
+namespace N3 {
+ class Y {
+ template<typename T> friend class N::M::X;
+ };
+}
+
+// FIXME: Woefully inadequate for testing
+
+// Friends declared as template-ids aren't subject to the restriction
+// on innermost namespaces.
+// rdar://problem/8552377
+namespace test5 {
+ template <class T> void f(T);
+ namespace ns {
+ class A {
+ friend void f<int>(int);
+ static void foo(); // expected-note 2 {{declared private here}}
+ };
+
+ // Note that this happens without instantiation.
+ template <class T> void f(T) {
+ A::foo(); // expected-error {{'foo' is a private member of 'test5::ns::A'}}
+ }
+ }
+
+ template <class T> void f(T) {
+ ns::A::foo(); // expected-error {{'foo' is a private member of 'test5::ns::A'}}
+ }
+
+ template void f<int>(int);
+ template void f<long>(long); //expected-note {{instantiation}}
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp
new file mode 100644
index 0000000..b4ec585
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.unnamed/p1.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm-only -verify %s
+
+// This lame little test was ripped straight from the standard.
+namespace {
+ int i; // expected-note {{candidate}}
+}
+void test0() { i++; }
+
+namespace A {
+ namespace {
+ int i; // expected-note {{candidate}}
+ int j;
+ }
+ void test1() { i++; }
+}
+
+using namespace A;
+
+void test2() {
+ i++; // expected-error {{reference to 'i' is ambiguous}}
+ A::i++;
+ j++;
+}
+
+
+// Test that all anonymous namespaces in a translation unit are
+// considered the same context.
+namespace {
+ class Test3 {}; // expected-note {{previous definition}}
+}
+namespace {
+ class Test3 {}; // expected-error {{redefinition of 'Test3'}}
+}
+
+namespace test4 {
+ namespace {
+ class Test4 {}; // expected-note {{previous definition}}
+ }
+ namespace {
+ class Test4 {}; // expected-error {{redefinition of 'Test4'}}
+ }
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp
new file mode 100644
index 0000000..6ffa873
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p1.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 -pedantic %s
+
+// Intentionally compiled as C++03 to test the extension warning.
+
+namespace a {} // original
+namespace a {} // ext
+inline namespace b {} // inline original expected-warning {{inline namespaces are}}
+inline namespace b {} // inline ext expected-warning {{inline namespaces are}}
+inline namespace {} // inline unnamed expected-warning {{inline namespaces are}}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp
new file mode 100644
index 0000000..411c16c
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR8430
+namespace N {
+ class A { };
+}
+
+namespace M { }
+
+using namespace M;
+
+namespace N {
+ namespace M {
+ }
+}
+
+namespace M {
+ namespace N {
+ }
+}
+
+namespace N {
+ A *getA();
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
new file mode 100644
index 0000000..98d12f9
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p7.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+namespace NIL {} // expected-note {{previous definition}}
+inline namespace NIL {} // expected-error {{cannot be reopened as inline}}
+inline namespace IL {} // expected-note {{previous definition}}
+namespace IL {} // expected-warning{{inline namespace cannot be re-opened as a non-inline namespace}}
+
+namespace {} // expected-note {{previous definition}}
+inline namespace {} // expected-error {{cannot be reopened as inline}}
+namespace X {
+ inline namespace {} // expected-note {{previous definition}}
+ namespace {} // expected-error {{cannot be reopened as non-inline}}
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
new file mode 100644
index 0000000..3bc4856
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp
@@ -0,0 +1,118 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Fun things you can do with inline namespaces:
+
+inline namespace X {
+ void f1();
+
+ inline namespace Y {
+ void f2();
+
+ template <typename T> class C {};
+ }
+
+ // Specialize and partially specialize somewhere else.
+ template <> class C<int> {};
+ template <typename T> class C<T*> {};
+}
+
+// Qualified and unqualified lookup as if member of enclosing NS.
+void foo1() {
+ f1();
+ ::f1();
+ X::f1();
+ Y::f1(); // expected-error {{no member named 'f1' in namespace 'X::Y'}}
+
+ f2();
+ ::f2();
+ X::f2();
+ Y::f2();
+}
+
+template <> class C<float> {};
+template <typename T> class C<T&> {};
+
+template class C<double>;
+
+
+// As well as all the fun with ADL.
+
+namespace ADL {
+ struct Outer {};
+
+ inline namespace IL {
+ struct Inner {};
+
+ void fo(Outer);
+ }
+
+ void fi(Inner);
+
+ inline namespace IL2 {
+ void fi2(Inner);
+ }
+}
+
+void foo2() {
+ ADL::Outer o;
+ ADL::Inner i;
+ fo(o);
+ fi(i);
+ fi2(i);
+}
+
+// Let's not forget overload sets.
+struct Distinct {};
+inline namespace Over {
+ void over(Distinct);
+}
+void over(int);
+
+void foo3() {
+ Distinct d;
+ ::over(d);
+}
+
+// Don't forget to do correct lookup for redeclarations.
+namespace redecl { inline namespace n1 {
+
+ template <class Tp> class allocator;
+
+ template <>
+ class allocator<void>
+ {
+ public:
+ typedef const void* const_pointer;
+ };
+
+ template <class Tp>
+ class allocator
+ {
+ public:
+ typedef Tp& reference;
+
+ void allocate(allocator<void>::const_pointer = 0);
+ };
+
+} }
+
+// Normal redeclarations (not for explicit instantiations or
+// specializations) are distinct in an inline namespace vs. not in an
+// inline namespace.
+namespace redecl2 {
+ inline namespace n1 {
+ void f(int) { }
+ struct X1 { };
+ template<typename T> void f(T) { }
+ template<typename T> struct X2 { };
+ int i = 71;
+ enum E { e };
+ }
+
+ void f(int) { }
+ struct X1 { };
+ template<typename T> void f(T) { }
+ template<typename T> struct X2 { };
+ int i = 71;
+ enum E { e };
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
new file mode 100644
index 0000000..bf30ee7
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
@@ -0,0 +1,110 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// We have to avoid ADL for this test.
+
+template <unsigned N> class test {};
+
+class foo {}; // expected-note {{candidate}}
+test<0> foo(foo); // expected-note {{candidate}}
+
+namespace Test0 {
+ class foo { int x; };
+ test<1> foo(class foo);
+
+ namespace A {
+ test<2> foo(class ::foo); // expected-note {{candidate}} \
+ // expected-note{{passing argument to parameter here}}
+
+ void test0() {
+ using ::foo;
+
+ class foo a;
+ test<0> _ = (foo)(a);
+ }
+
+ void test1() {
+ using Test0::foo;
+
+ class foo a;
+ test<1> _ = (foo)(a);
+ };
+
+ void test2() {
+ class ::foo a;
+
+ // Argument-dependent lookup is ambiguous between B:: and ::.
+ test<0> _0 = foo(a); // expected-error {{call to 'foo' is ambiguous}}
+
+ // But basic unqualified lookup is not.
+ test<2> _1 = (foo)(a);
+
+ class Test0::foo b;
+ test<2> _2 = (foo)(b); // expected-error {{no viable conversion from 'class Test0::foo' to 'class ::foo'}}
+ }
+ }
+}
+
+namespace Test1 {
+ namespace A {
+ class a {};
+ }
+
+ namespace B {
+ typedef class {} b;
+ }
+
+ namespace C {
+ int c(); // expected-note {{target of using declaration}}
+ }
+
+ namespace D {
+ using typename A::a;
+ using typename B::b;
+ using typename C::c; // expected-error {{'typename' keyword used on a non-type}}
+
+ a _1 = A::a();
+ b _2 = B::b();
+ }
+}
+
+namespace test2 {
+ class A {
+ protected:
+ operator int();
+ operator bool();
+ };
+
+ class B : private A {
+ protected:
+ using A::operator int; // expected-note {{declared protected here}}
+ public:
+ using A::operator bool;
+ };
+
+ int test() {
+ bool b = B();
+ return B(); // expected-error {{'operator int' is a protected member of 'test2::B'}}
+ }
+}
+
+namespace test3 {
+ class A {
+ public:
+ ~A();
+ };
+
+ class B {
+ friend class C;
+ private:
+ operator A*();
+ };
+
+ class C : public B {
+ public:
+ using B::operator A*;
+ };
+
+ void test() {
+ delete C();
+ }
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
new file mode 100644
index 0000000..546c4a4
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p10.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+ namespace ns0 {
+ class tag;
+ int tag();
+ }
+
+ namespace ns1 {
+ using ns0::tag;
+ }
+
+ namespace ns2 {
+ using ns0::tag;
+ }
+
+ using ns1::tag;
+ using ns2::tag;
+}
+
+// PR 5752
+namespace test1 {
+ namespace ns {
+ void foo();
+ }
+
+ using ns::foo;
+ void foo(int);
+
+ namespace ns {
+ using test1::foo;
+ }
+}
+
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
new file mode 100644
index 0000000..c7966ce
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
@@ -0,0 +1,91 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p11:
+// If a function declaration in namespace scope or block scope has
+// the same name and the same parameter types as a function
+// introduced by a using-declaration, the program is
+// ill-formed. [Note: two using-declarations may introduce functions
+// with the same name and the same parameter types. If, for a call
+// to an unqualified function name, function overload resolution
+// selects the functions introduced by such using-declarations, the
+// function call is ill-formed.
+
+namespace test0 {
+ namespace ns { void foo(); } // expected-note {{target of using declaration}}
+ int foo(void); // expected-note {{conflicting declaration}}
+ using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+}
+
+namespace test1 {
+ namespace ns { void foo(); } // expected-note {{target of using declaration}}
+ using ns::foo; //expected-note {{using declaration}}
+ int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+}
+
+namespace test2 {
+ namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+ void test0() {
+ int foo(void); // expected-note {{conflicting declaration}}
+ using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+ }
+
+ void test1() {
+ using ns::foo; //expected-note {{using declaration}}
+ int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+ }
+}
+
+namespace test3 {
+ namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+ class Test0 {
+ void test() {
+ int foo(void); // expected-note {{conflicting declaration}}
+ using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+ }
+ };
+
+ class Test1 {
+ void test() {
+ using ns::foo; //expected-note {{using declaration}}
+ int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+ }
+ };
+}
+
+namespace test4 {
+ namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
+ template <typename> class Test0 {
+ void test() {
+ int foo(void); // expected-note {{conflicting declaration}}
+ using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
+ }
+ };
+
+ template <typename> class Test1 {
+ void test() {
+ using ns::foo; //expected-note {{using declaration}}
+ int foo(void); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+ }
+ };
+}
+
+// FIXME: we should be able to diagnose both of these, but we can't.
+namespace test5 {
+ namespace ns { void foo(int); }
+ template <typename T> class Test0 {
+ void test() {
+ int foo(T);
+ using ns::foo;
+ }
+ };
+
+ template <typename T> class Test1 {
+ void test() {
+ using ns::foo;
+ int foo(T);
+ }
+ };
+
+ template class Test0<int>;
+ template class Test1<int>;
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
new file mode 100644
index 0000000..cc28bf6
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -0,0 +1,163 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p12:
+// When a using-declaration brings names from a base class into a
+// derived class scope, member functions in the derived class
+// override and/or hide member functions with the same name and
+// parameter types in a base class (rather than conflicting).
+
+template <unsigned n> struct Opaque {};
+template <unsigned n> void expect(Opaque<n> _) {}
+
+// PR5727
+// This just shouldn't crash.
+namespace test0 {
+ template<typename> struct RefPtr { };
+ template<typename> struct PtrHash {
+ static void f() { }
+ };
+ template<typename T> struct PtrHash<RefPtr<T> > : PtrHash<T*> {
+ using PtrHash<T*>::f;
+ static void f() { f(); }
+ };
+}
+
+// Simple hiding.
+namespace test1 {
+ struct Base {
+ Opaque<0> foo(Opaque<0>);
+ Opaque<0> foo(Opaque<1>);
+ Opaque<0> foo(Opaque<2>);
+ };
+
+ // using before decls
+ struct Test0 : Base {
+ using Base::foo;
+ Opaque<1> foo(Opaque<1>);
+ Opaque<1> foo(Opaque<3>);
+
+ void test0() { Opaque<0> _ = foo(Opaque<0>()); }
+ void test1() { Opaque<1> _ = foo(Opaque<1>()); }
+ void test2() { Opaque<0> _ = foo(Opaque<2>()); }
+ void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+ };
+
+ // using after decls
+ struct Test1 : Base {
+ Opaque<1> foo(Opaque<1>);
+ Opaque<1> foo(Opaque<3>);
+ using Base::foo;
+
+ void test0() { Opaque<0> _ = foo(Opaque<0>()); }
+ void test1() { Opaque<1> _ = foo(Opaque<1>()); }
+ void test2() { Opaque<0> _ = foo(Opaque<2>()); }
+ void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+ };
+
+ // using between decls
+ struct Test2 : Base {
+ Opaque<1> foo(Opaque<0>);
+ using Base::foo;
+ Opaque<1> foo(Opaque<2>);
+ Opaque<1> foo(Opaque<3>);
+
+ void test0() { Opaque<1> _ = foo(Opaque<0>()); }
+ void test1() { Opaque<0> _ = foo(Opaque<1>()); }
+ void test2() { Opaque<1> _ = foo(Opaque<2>()); }
+ void test3() { Opaque<1> _ = foo(Opaque<3>()); }
+ };
+}
+
+// Crazy dependent hiding.
+namespace test2 {
+ struct Base {
+ void foo(int);
+ };
+
+ template <typename T> struct Derived1 : Base {
+ using Base::foo;
+ void foo(T);
+
+ void testUnresolved(int i) { foo(i); }
+ };
+
+ void test0(int i) {
+ Derived1<int> d1;
+ d1.foo(i);
+ d1.testUnresolved(i);
+ }
+
+ // Same thing, except with the order of members reversed.
+ template <typename T> struct Derived2 : Base {
+ void foo(T);
+ using Base::foo;
+
+ void testUnresolved(int i) { foo(i); }
+ };
+
+ void test1(int i) {
+ Derived2<int> d2;
+ d2.foo(i);
+ d2.testUnresolved(i);
+ }
+}
+
+// Hiding of member templates.
+namespace test3 {
+ struct Base {
+ template <class T> Opaque<0> foo() { return Opaque<0>(); }
+ template <int n> Opaque<1> foo() { return Opaque<1>(); }
+ };
+
+ struct Derived1 : Base {
+ using Base::foo;
+ template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
+ };
+
+ struct Derived2 : Base {
+ template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'n'}}
+ using Base::foo;
+ };
+
+ struct Derived3 : Base {
+ using Base::foo;
+ template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
+ };
+
+ struct Derived4 : Base {
+ template <class T> Opaque<3> foo() { return Opaque<3>(); } // expected-note {{invalid explicitly-specified argument for template parameter 'T'}}
+ using Base::foo;
+ };
+
+ void test() {
+ expect<0>(Base().foo<int>());
+ expect<1>(Base().foo<0>());
+ expect<0>(Derived1().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
+ expect<2>(Derived1().foo<0>());
+ expect<0>(Derived2().foo<int>()); // expected-error {{no matching member function for call to 'foo'}}
+ expect<2>(Derived2().foo<0>());
+ expect<3>(Derived3().foo<int>());
+ expect<1>(Derived3().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
+ expect<3>(Derived4().foo<int>());
+ expect<1>(Derived4().foo<0>()); // expected-error {{no matching member function for call to 'foo'}}
+ }
+}
+
+// PR7384: access control for member templates.
+namespace test4 {
+ class Base {
+ protected:
+ template<typename T> void foo(T);
+ template<typename T> void bar(T); // expected-note {{declared protected here}}
+ };
+
+ struct Derived : Base {
+ using Base::foo;
+ };
+
+ void test() {
+ Derived d;
+ d.foo<int>(3);
+ d.bar<int>(3); // expected-error {{'bar' is a protected member}}
+ }
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
new file mode 100644
index 0000000..dd44bfc
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p13.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p3:
+// For the purpose of overload resolution, the functions which are
+// introduced by a using-declaration into a derived class will be
+// treated as though they were members of the derived class. In
+// particular, the implicit this parameter shall be treated as if it
+// were a pointer to the derived class rather than to the base
+// class. This has no effect on the type of the function, and in all
+// other respects the function remains a member of the base class.
+
+namespace test0 {
+ struct Opaque0 {};
+ struct Opaque1 {};
+
+ struct Base {
+ Opaque0 test0(int*);
+ Opaque0 test1(const int*);
+ Opaque0 test2(int*);
+ Opaque0 test3(int*) const;
+ };
+
+ struct Derived : Base {
+ using Base::test0;
+ Opaque1 test0(const int*);
+
+ using Base::test1;
+ Opaque1 test1(int*);
+
+ using Base::test2;
+ Opaque1 test2(int*) const;
+
+ using Base::test3;
+ Opaque1 test3(int*);
+ };
+
+ void test0() {
+ Opaque0 a = Derived().test0((int*) 0);
+ Opaque1 b = Derived().test0((const int*) 0);
+ }
+
+ void test1() {
+ Opaque1 a = Derived().test1((int*) 0);
+ Opaque0 b = Derived().test1((const int*) 0);
+ }
+
+ void test2() {
+ Opaque0 a = ((Derived*) 0)->test2((int*) 0);
+ Opaque1 b = ((const Derived*) 0)->test2((int*) 0);
+ }
+
+ void test3() {
+ Opaque1 a = ((Derived*) 0)->test3((int*) 0);
+ Opaque0 b = ((const Derived*) 0)->test3((int*) 0);
+ }
+}
+
+// Typedef redeclaration.
+namespace rdar8018262 {
+ typedef void (*fp)();
+
+ namespace N {
+ typedef void (*fp)();
+ }
+
+ using N::fp;
+
+ fp fp_1;
+}
+
+// Things to test:
+// member operators
+// conversion operators
+// call operators
+// call-surrogate conversion operators
+// everything, but in dependent contexts
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp
new file mode 100644
index 0000000..f61437e
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p3-cxx0x.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// C++0x N2914.
+
+struct B {
+ void f(char);
+ void g(char);
+ enum E { e };
+ union { int x; };
+};
+
+class C {
+ int g();
+};
+
+class D2 : public B {
+ using B::f;
+ using B::e;
+ using B::x;
+ using C::g; // expected-error{{using declaration refers into 'C::', which is not a base class of 'D2'}}
+};
+
+namespace test1 {
+ struct Base {
+ int foo();
+ };
+
+ struct Unrelated {
+ int foo();
+ };
+
+ struct Subclass : Base {
+ };
+
+ namespace InnerNS {
+ int foo();
+ }
+
+ // We should be able to diagnose these without instantiation.
+ template <class T> struct C : Base {
+ using InnerNS::foo; // expected-error {{not a class}}
+ using Base::bar; // expected-error {{no member named 'bar'}}
+ using Unrelated::foo; // expected-error {{not a base class}}
+ using C::foo; // expected-error {{refers to its own class}}
+ using Subclass::foo; // expected-error {{not a base class}}
+ };
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
new file mode 100644
index 0000000..a43d9e0
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p4.cpp
@@ -0,0 +1,213 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++03 [namespace.udecl]p4:
+// A using-declaration used as a member-declaration shall refer to a
+// member of a base class of the class being defined, shall refer to
+// a member of an anonymous union that is a member of a base class
+// of the class being defined, or shall refer to an enumerator for
+// an enumeration type that is a member of a base class of the class
+// being defined.
+
+// There is no directly analogous paragraph in C++0x, and the feature
+// works sufficiently differently there that it needs a separate test.
+
+namespace test0 {
+ namespace NonClass {
+ typedef int type;
+ struct hiding {};
+ int hiding;
+ static union { double union_member; };
+ enum tagname { enumerator };
+ }
+
+ class Test0 {
+ using NonClass::type; // expected-error {{not a class}}
+ using NonClass::hiding; // expected-error {{not a class}}
+ using NonClass::union_member; // expected-error {{not a class}}
+ using NonClass::enumerator; // expected-error {{not a class}}
+ };
+}
+
+struct Opaque0 {};
+
+namespace test1 {
+ struct A {
+ typedef int type;
+ struct hiding {}; // expected-note {{previous use is here}}
+ Opaque0 hiding;
+ union { double union_member; };
+ enum tagname { enumerator };
+ };
+
+ struct B : A {
+ using A::type;
+ using A::hiding;
+ using A::union_member;
+ using A::enumerator;
+ using A::tagname;
+
+ void test0() {
+ type t = 0;
+ }
+
+ void test1() {
+ typedef struct A::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ union hiding _; // expected-error {{tag type that does not match previous}}
+ }
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+}
+
+namespace test2 {
+ struct A {
+ typedef int type;
+ struct hiding {}; // expected-note {{previous use is here}}
+ int hiding;
+ union { double union_member; };
+ enum tagname { enumerator };
+ };
+
+ template <class T> struct B : A {
+ using A::type;
+ using A::hiding;
+ using A::union_member;
+ using A::enumerator;
+ using A::tagname;
+
+ void test0() {
+ type t = 0;
+ }
+
+ void test1() {
+ typedef struct A::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ union hiding _; // expected-error {{tag type that does not match previous}}
+ }
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+}
+
+namespace test3 {
+ struct hiding {};
+
+ template <class T> struct A {
+ typedef int type; // expected-note {{target of using declaration}}
+ struct hiding {};
+ Opaque0 hiding; // expected-note {{target of using declaration}}
+ union { double union_member; }; // expected-note {{target of using declaration}}
+ enum tagname { enumerator }; // expected-note 2 {{target of using declaration}}
+ };
+
+ template <class T> struct B : A<T> {
+ using A<T>::type; // expected-error {{dependent using declaration resolved to type without 'typename'}}
+ using A<T>::hiding;
+ using A<T>::union_member;
+ using A<T>::enumerator;
+ using A<T>::tagname; // expected-error {{dependent using declaration resolved to type without 'typename'}}
+
+ // FIXME: re-enable these when the various bugs involving tags are fixed
+#if 0
+ void test1() {
+ typedef struct A<T>::hiding local;
+ struct hiding _ = local();
+ }
+
+ void test2() {
+ typedef struct A<T>::hiding local;
+ union hiding _ = local();
+ }
+#endif
+
+ void test3() {
+ char array[sizeof(union_member) == sizeof(double) ? 1 : -1];
+ }
+
+#if 0
+ void test4() {
+ enum tagname _ = enumerator;
+ }
+#endif
+
+ void test5() {
+ Opaque0 _ = hiding;
+ }
+ };
+
+ template struct B<int>; // expected-note {{in instantiation}}
+
+ template <class T> struct C : A<T> {
+ using typename A<T>::type;
+ using typename A<T>::hiding; // expected-note {{declared here}} \
+ // expected-error {{'typename' keyword used on a non-type}}
+ using typename A<T>::union_member; // expected-error {{'typename' keyword used on a non-type}}
+ using typename A<T>::enumerator; // expected-error {{'typename' keyword used on a non-type}}
+
+ void test6() {
+ type t = 0;
+ }
+
+ void test7() {
+ Opaque0 _ = hiding; // expected-error {{does not refer to a value}}
+ }
+ };
+
+ template struct C<int>; // expected-note {{in instantiation}}
+}
+
+namespace test4 {
+ struct Base {
+ int foo();
+ };
+
+ struct Unrelated {
+ int foo();
+ };
+
+ struct Subclass : Base {
+ };
+
+ namespace InnerNS {
+ int foo();
+ }
+
+ // We should be able to diagnose these without instantiation.
+ template <class T> struct C : Base {
+ using InnerNS::foo; // expected-error {{not a class}}
+ using Base::bar; // expected-error {{no member named 'bar'}}
+ using Unrelated::foo; // expected-error {{not a base class}}
+ using C::foo; // legal in C++03
+ using Subclass::foo; // legal in C++03
+
+ int bar(); //expected-note {{target of using declaration}}
+ using C::bar; // expected-error {{refers to its own class}}
+ };
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp
new file mode 100644
index 0000000..edaa975
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p5-cxx0x.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// C++0x N2914.
+
+struct A {
+ template<class T> void f(T);
+ template<class T> struct X { };
+};
+
+struct B : A {
+ using A::f<double>; // expected-error{{using declaration can not refer to a template specialization}}
+ using A::X<int>; // expected-error{{using declaration can not refer to a template specialization}}
+};
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp
new file mode 100644
index 0000000..c4b8849
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p6-cxx0x.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// C++0x N2914.
+
+namespace A {
+ namespace B { }
+}
+
+using A::B; // expected-error{{using declaration can not refer to namespace}}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
new file mode 100644
index 0000000..78b5a41
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8-cxx0x.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// C++0x N2914.
+
+struct X {
+ int i;
+ static int a;
+};
+
+using X::i; // expected-error{{using declaration can not refer to class member}}
+using X::s; // expected-error{{using declaration can not refer to class member}}
+
+void f() {
+ using X::i; // expected-error{{using declaration can not refer to class member}}
+ using X::s; // expected-error{{using declaration can not refer to class member}}
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
new file mode 100644
index 0000000..4660971
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p8.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct Opaque0 {};
+struct Opaque1 {};
+
+// Redeclarations are okay in a namespace.
+namespace test0 {
+ namespace ns {
+ void foo(Opaque0); // expected-note 2 {{candidate function}}
+ }
+
+ using ns::foo;
+ using ns::foo;
+
+ void test0() {
+ foo(Opaque1()); // expected-error {{no matching function for call}}
+ }
+
+ namespace ns {
+ void foo(Opaque1);
+ }
+
+ void test1() {
+ foo(Opaque1()); // expected-error {{no matching function for call}}
+ }
+
+ using ns::foo;
+
+ void test2() {
+ foo(Opaque1());
+ }
+
+ using ns::foo;
+}
+
+// Make sure we handle transparent contexts the same way.
+namespace test1 {
+ namespace ns {
+ void foo(Opaque0); // expected-note 2 {{candidate function}}
+ }
+
+ extern "C++" {
+ using ns::foo;
+ }
+
+ void test0() {
+ foo(Opaque1()); // expected-error {{no matching function for call}}
+ }
+
+ namespace ns {
+ void foo(Opaque1);
+ }
+
+ void test1() {
+ foo(Opaque1()); // expected-error {{no matching function for call}}
+ }
+
+ extern "C++" {
+ using ns::foo;
+ }
+
+ void test2() {
+ foo(Opaque1());
+ }
+}
+
+// Make sure we detect invalid redeclarations that can't be detected
+// until template instantiation.
+namespace test2 {
+ template <class T> struct Base {
+ typedef Base type;
+ void foo();
+ };
+
+ template <class T> struct Derived : Base<T> {
+ // These are invalid redeclarations, detectable only after
+ // instantiation.
+ using Base<T>::foo; // expected-note {{previous using decl}}
+ using Base<T>::type::foo; //expected-error {{redeclaration of using decl}}
+ };
+
+ template struct Derived<int>; // expected-note {{in instantiation of template class}}
+}
+
+// Redeclarations are okay in a function.
+namespace test3 {
+ namespace N {
+ int f(int);
+ typedef int type;
+ }
+
+ void g() {
+ using N::f;
+ using N::f;
+ using N::type;
+ using N::type;
+ }
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp
new file mode 100644
index 0000000..20a19ab
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p1.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// (this actually occurs before paragraph 1)
+namespace test0 {
+ namespace A {}
+ class B {
+ using namespace A; // expected-error {{'using namespace' is not allowed in classes}}
+ };
+}
+
+
+struct opaque0 {};
+struct opaque1 {};
+
+// Test that names appear as if in deepest common ancestor.
+namespace test1 {
+ namespace A {
+ namespace B {
+ opaque0 foo(); // expected-note {{candidate}}
+ }
+ }
+
+ namespace C {
+ opaque1 foo(); // expected-note {{candidate}}
+
+ opaque1 test() {
+ using namespace A::B;
+ return foo(); // C::foo
+ }
+ }
+
+ opaque1 test() {
+ using namespace A::B;
+ using namespace C;
+ return foo(); // expected-error {{call to 'foo' is ambiguous}}
+ }
+}
+
+// Same thing, but with the directives in namespaces.
+namespace test2 {
+ namespace A {
+ namespace B {
+ opaque0 foo(); // expected-note {{candidate}}
+ }
+ }
+
+ namespace C {
+ opaque1 foo(); // expected-note {{candidate}}
+
+ namespace test {
+ using namespace A::B;
+
+ opaque1 test() {
+ return foo(); // C::foo
+ }
+ }
+ }
+
+ namespace test {
+ using namespace A::B;
+ using namespace C;
+
+ opaque1 test() {
+ return foo(); // expected-error {{call to 'foo' is ambiguous}}
+ }
+ }
+}
+
+// Transitivity.
+namespace test3 {
+ namespace A {
+ namespace B {
+ opaque0 foo();
+ }
+ }
+ namespace C {
+ using namespace A;
+ }
+
+ opaque0 test0() {
+ using namespace C;
+ using namespace B;
+ return foo();
+ }
+
+ namespace D {
+ using namespace C;
+ }
+ namespace A {
+ opaque1 foo();
+ }
+
+ opaque1 test1() {
+ using namespace D;
+ return foo();
+ }
+}
+
+// Transitivity acts like synthetic using directives.
+namespace test4 {
+ namespace A {
+ namespace B {
+ opaque0 foo(); // expected-note {{candidate}}
+ }
+ }
+
+ namespace C {
+ using namespace A::B;
+ }
+
+ opaque1 foo(); // expected-note {{candidate}}
+
+ namespace A {
+ namespace D {
+ using namespace C;
+ }
+
+ opaque0 test() {
+ using namespace D;
+ return foo();
+ }
+ }
+
+ opaque0 test() {
+ using namespace A::D;
+ return foo(); // expected-error {{call to 'foo' is ambiguous}}
+ }
+}
+
+// Bug: using directives should be followed when parsing default
+// arguments in scoped declarations.
+class test5 {
+ int inc(int x);
+};
+namespace Test5 {
+ int default_x = 0;
+}
+using namespace Test5;
+int test5::inc(int x = default_x) {
+ return x+1;
+}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp
new file mode 100644
index 0000000..4cb91cd
--- /dev/null
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udir/p6.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// <rdar://problem/8296180>
+typedef int pid_t;
+namespace ns {
+ typedef int pid_t;
+}
+using namespace ns;
+pid_t x;
+
+struct A { };
+namespace ns {
+ typedef ::A A;
+}
+A a;