From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- .../temp.decls/temp.class/temp.mem.class/p1.cpp | 27 ++++ .../temp.decls/temp.class/temp.mem.enum/p1.cpp | 152 +++++++++++++++++++++ .../temp.class/temp.mem.func/p1-retmem.cpp | 28 ++++ .../temp.decls/temp.class/temp.mem.func/p1.cpp | 100 ++++++++++++++ .../temp.decls/temp.class/temp.mem.func/p1inst.cpp | 17 +++ .../temp.decls/temp.class/temp.mem.func/pr5056.cpp | 17 +++ .../temp.decls/temp.class/temp.static/p1-inst.cpp | 28 ++++ .../temp/temp.decls/temp.class/temp.static/p1.cpp | 26 ++++ 8 files changed, 395 insertions(+) create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp create mode 100644 clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp (limited to 'clang/test/CXX/temp/temp.decls/temp.class') diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp new file mode 100644 index 0000000..b65e1d0 --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template +struct X0 { + struct Inner; +}; + +template +struct X0::Inner { + T x; + U y; + + void f() { x = y; } // expected-error{{incompatible}} +}; + + +void test(int i, float f) { + X0::Inner inner; + inner.x = 5; + inner.y = 3.4; + inner.f(); + + X0::Inner inner2; + inner2.x = &i; + inner2.y = &f; + inner2.f(); // expected-note{{instantiation}} +} diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp new file mode 100644 index 0000000..f8cc009 --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp @@ -0,0 +1,152 @@ +// RUN: %clang_cc1 -std=c++11 -verify %s + +template struct A { + enum E : T; // expected-note {{here}} + E v; + E f() { return A::e1; } // expected-error {{no member named 'e1' in 'A'}} + E g() { return E::e1; } + E h(); +}; + +A a; +A::E a0 = A().v; +int n = A::E::e1; // expected-error {{implicit instantiation of undefined member}} + +template enum A::E : T { e1, e2 }; + +// FIXME: Now that A::E is defined, we are supposed to inject its enumerators +// into the already-instantiated class A. This seems like a really bad idea, +// though, so we don't implement that, but what we do implement is inconsistent. +// +// Either do as the standard says, or only include enumerators lexically defined +// within the class in its scope. +A::E a1 = A::e1; // expected-error {{no member named 'e1' in 'A'}} + +A::E a2 = A::e2; + +template typename A::E A::h() { return e2; } +A::E a3 = A().h(); + + +template struct B { + enum class E; + E v; + E f() { return E::e1; } + E g(); +}; + +B b; +B::E b0 = B().v; + +template enum class B::E { e1, e2 }; +B::E b1 = B::E::e1; + +B::E b2 = B::E::e2; + +template typename B::E B::g() { return e2; } +B::E b3 = B().g(); + + +// Enumeration members of class templates can be explicitly specialized. For +// unscoped enumerations, specializations must be defined before the primary +// template is, since otherwise the primary template will be implicitly +// instantiated when we parse the nested name specifier. +template<> enum A::E : long long { e3, e4 }; // expected-error {{explicit specialization of 'E' after instantiation}} expected-note {{first required here}} + +template<> enum class B::E { e3, e4 }; +B::E b4 = B::E::e4; + +B::E b5; +template<> enum class B::E { e5 }; +void fb5() { b5 = decltype(b5)::e5; } +B::E b6 = B::E::e5; + + +template struct C { + enum class E : T; +}; + +template<> enum class C::E : long long { e3, e4 }; +C::E c0 = C::E::e3; + +C::E c1; +template<> enum class C::E : long { e5 }; +void fc1() { c1 = decltype(c1)::e5; } +C::E c2 = C::E::e5; + +template<> enum class C::E : int { e6 }; +template enum class C::E : T { e0 }; +C::E c3 = C::E::e6; +C::E c4 = C::E::e0; // expected-error {{no member named 'e0' in 'C::E'}} + + +// Enumeration members can't be partially-specialized. +template enum class B::E { e5, e6 }; // expected-error {{nested name specifier for a declaration cannot depend on a template parameter}} + + +// Explicit specializations can be forward-declared. +template +struct D { + enum class E { e1 }; +}; +template<> enum class D::E; +D::E d1 = D::E::e1; // expected-error {{incomplete type 'D::E'}} +template<> enum class D::E { e2 }; +D::E d2 = D::E::e2; +D::E d3 = D::E::e1; // expected-note {{first required here}} +D::E d4 = D::E::e2; // expected-error {{no member named 'e2'}} +template<> enum class D::E { e3 }; // expected-error {{explicit specialization of 'E' after instantiation}} + +template<> enum class D::E; +struct F { + // Per C++11 [class.friend]p3, these friend declarations have no effect. + // Only classes and functions can be friends. + template friend enum D::E; + template<> friend enum D::E; + + template<> friend enum D::E { e3 }; // expected-error {{cannot define a type in a friend declaration}} + +private: + static const int n = 1; // expected-note {{private here}} +}; +template<> enum class D::E { + e = F::n // expected-error {{private member}} +}; + +class Access { + friend class X; + + template + class Priv { + friend class X; + + enum class E : T; + }; + + class S { + typedef int N; // expected-note {{here}} + static const int k = 3; // expected-note {{here}} + + friend class Priv; + }; + + static const int k = 5; +}; + +template<> enum class Access::Priv::E + : Access::S::N { // expected-error {{private member}} + a = Access::k, // ok + b = Access::S::k // expected-error {{private member}} +}; + +template enum class Access::Priv::E : T { + c = Access::k, + d = Access::S::k +}; + +class X { + Access::Priv::E a = Access::Priv::E::a; + Access::Priv::E c = Access::Priv::E::d; + // FIXME: We should see an access error for this enumerator. + Access::Priv::E b = Access::Priv::E::d; +}; diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp new file mode 100644 index 0000000..4c05c62 --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +template struct X1 { }; + +template +struct X0 { + typedef int size_type; + typedef T value_type; + + size_type f0() const; + value_type *f1(); + X1 f2(); +}; + +template +typename X0::size_type X0::f0() const { + return 0; +} + +template +typename X0::value_type *X0::f1() { + return 0; +}; + +template +X1::value_type*> X0::f2() { + return 0; +}; diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp new file mode 100644 index 0000000..1764563 --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp @@ -0,0 +1,100 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +template // expected-note{{previous template}} +class X0 { +public: + typedef int size_type; + + X0(int); + ~X0(); + + void f0(const T&, const U&); + + T& operator[](int i) const; + + void f1(size_type) const; + void f2(size_type) const; + void f3(size_type) const; + void f4() ; + + operator T*() const; + + T value; +}; + +template +void X0::f0(const T&, const U&) { // expected-note{{previous definition}} +} + +template +X& X0::operator[](int i) const { + (void)i; + return value; +} + +template +void X0::f1(int) const { } + +template +void X0::f2(size_type) const { } + +template // expected-error{{too many template parameters}} +void X0::f3(size_type) const { +} + +template +void X0::f4() { } // expected-error{{does not refer}} + +// FIXME: error message should probably say, "redefinition of 'X0::f0'" +// rather than just "redefinition of 'f0'" +template +void X0::f0(const T&, const U&) { // expected-error{{redefinition}} +} + +// Test out-of-line constructors, destructors +template +X0::X0(int x) : value(x) { } + +template +X0::~X0() { } + +// Test out-of-line conversion functions. +template +X0::operator T*() const { + return &value; +} + +namespace N { template class A {void a();}; } +namespace N { template void A::a() {} } + +// PR5566 +template +struct X1 { + template + struct B { void f(); }; +}; + +template +template +void X1::template B::f() { } + +// PR5527 +template