diff options
Diffstat (limited to 'clang/test')
22 files changed, 501 insertions, 10 deletions
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp new file mode 100644 index 00000000000..5fc0fe0411c --- /dev/null +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p2-0x.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +struct A { }; +template<typename T> using X = A; // expected-note {{declared here}} +struct X<int>* p2; // expected-error {{elaborated type refers to a type alias template}} + + +template<typename T> using Id = T; // expected-note {{declared here}} +template<template<typename> class F> +struct Y { + struct F<int> i; // expected-error {{elaborated type refers to a type alias template}} +}; +template struct Y<Id>; // expected-note {{requested here}} diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp index 10184a058f1..8b278bf2a22 100644 --- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp +++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp @@ -1,10 +1,9 @@ // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s -// FIXME: when clang supports alias-declarations. -#if 0 using X = struct { // ok }; -#endif +template<typename T> using Y = struct { // expected-error {{can not be defined in a type alias template}} +}; class K { virtual ~K(); diff --git a/clang/test/CXX/temp/temp.decls/p3.cpp b/clang/test/CXX/temp/temp.decls/p3.cpp new file mode 100644 index 00000000000..21c82e6f227 --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/p3.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<typename T> using A = int; +template<typename T> using A<T*> = char; // expected-error {{partial specialization of alias templates is not permitted}} +template<> using A<char> = char; // expected-error {{explicit specialization of alias templates is not permitted}} +template using A<char> = char; // expected-error {{explicit instantiation of alias templates is not permitted}} +// Best guess as to what the user was trying to do: missing template<>. +using A<char> = char; // expected-error {{partial specialization of alias templates is not permitted}} diff --git a/clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp new file mode 100644 index 00000000000..80079b33a53 --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<typename T> using U = T; + +// The name of the alias template is a template-name. +U<char> x; +void f(U<int>); +typedef U<U<U<U<int>>>> I; diff --git a/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp b/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp new file mode 100644 index 00000000000..e145727a8dd --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp @@ -0,0 +1,45 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<typename T> using U = T; + +using I = U<U<U<U<int>>>>; +using I = int; + +template<typename A, typename B> using Fst = A; +template<typename A, typename B> using Snd = B; + +using I = Fst<Snd<char,int>,double>; + +namespace StdExample { + // Prerequisites for example. + template<class T, class A> struct vector { /* ... */ }; + + + template<class T> struct Alloc {}; + template<class T> using Vec = vector<T, Alloc<T>>; + Vec<int> v; + + template<class T> + void process(Vec<T>& v) // expected-note {{previous definition is here}} + { /* ... */ } + + template<class T> + void process(vector<T, Alloc<T>>& w) // expected-error {{redefinition of 'process'}} + { /* ... */ } + + template<template<class> class TT> + void f(TT<int>); // expected-note {{candidate template ignored}} + + template<template<class,class> class TT> + void g(TT<int, Alloc<int>>); + + int h() { + f(v); // expected-error {{no matching function for call to 'f'}} + g(v); // OK: TT = vector + } + + + // v's type is same as vector<int, Alloc<int>>. + using VTest = vector<int, Alloc<int>>; + using VTest = decltype(v); +} diff --git a/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp b/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp new file mode 100644 index 00000000000..2e9e55cdcb6 --- /dev/null +++ b/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +// The example given in the standard (this is rejected for other reasons anyway). +template<class T> struct A; +template<class T> using B = typename A<T>::U; // expected-error {{no type named 'U' in 'A<T>'}} +template<class T> struct A { + typedef B<T> U; // expected-note {{in instantiation of template type alias 'B' requested here}} +}; +B<short> b; + +template<typename T> using U = int; +// FIXME: This is illegal, but probably only because CWG1044 missed this paragraph. +template<typename T> using U = U<T>; diff --git a/clang/test/CXX/temp/temp.param/p10-0x.cpp b/clang/test/CXX/temp/temp.param/p10-0x.cpp new file mode 100644 index 00000000000..bc7e616fb13 --- /dev/null +++ b/clang/test/CXX/temp/temp.param/p10-0x.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +template<typename> struct Y1; +template<typename, int> struct Y2; + +template<class T1, class T2 = int> using B2 = T1; +template<class T1 = int, class T2> using B2 = T1; + +template<template<class> class F, template<class> class G = Y1> using B2t = F<G<int>>; +template<template<class> class F = Y2, template<class> class G> using B2t = F<G<int>>; + +template<int N, int M = 5> using B2n = Y2<int, N + M>; +template<int N = 5, int M> using B2n = Y2<int, N + M>; diff --git a/clang/test/CXX/temp/temp.param/p11-0x.cpp b/clang/test/CXX/temp/temp.param/p11-0x.cpp index 0bf4341cf8d..10a44380c8d 100644 --- a/clang/test/CXX/temp/temp.param/p11-0x.cpp +++ b/clang/test/CXX/temp/temp.param/p11-0x.cpp @@ -1,29 +1,48 @@ // RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s -// If a template-parameter of a class template has a default -// template-argument, each subsequent template-parameter shall either -// have a default template-argument supplied or be a template -// parameter pack. +// If a template-parameter of a class template or alias template has a default +// template-argument, each subsequent template-parameter shall either have a +// default template-argument supplied or be a template parameter pack. template<typename> struct vector; +template<typename T = int, typename> struct X3t; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<typename T = int, typename> using A3t = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<int V = 0, int> struct X3nt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<int V = 0, int> using A3nt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<template<class> class M = vector, template<class> class> struct X3tt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} +template<template<class> class M = vector, template<class> class> using A3tt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}} + template<typename T = int, typename ...Types> struct X2t; +template<typename T = int, typename ...Types> using A2t = X2t<T, Types...>; template<int V = 0, int ...Values> struct X2nt; +template<int V = 0, int ...Values> using A2nt = X2nt<V, Values...>; template<template<class> class M = vector, template<class> class... Metas> struct X2tt; +template<template<class> class M = vector, template<class> class... Metas> + using A2tt = X2tt<M, Metas...>; -// If a template-parameter of a primary class template is a template -// parameter pack, it shall be the last template-parameter . +// If a template-parameter of a primary class template or alias template is a +// template parameter pack, it shall be the last template-parameter. template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}} int After> struct X0t; +template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}} + int After> +using A0t = int; template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}} int After> struct X0nt; +template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}} + int After> +using A0nt = int; template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}} int After> struct X0tt; +template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}} + int After> +using A0tt = int; // [ Note: These are not requirements for function templates or class // template partial specializations because template arguments can be diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp new file mode 100644 index 00000000000..1d1d350cf33 --- /dev/null +++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +// Examples from CWG1056. +namespace Example1 { + template<class T> struct A; + template<class T> using B = A<T>; + + template<class T> struct A { + struct C {}; + B<T>::C bc; // ok, B<T> is the current instantiation. + }; + + template<class T> struct A<A<T>> { + struct C {}; + B<B<T>>::C bc; // ok, B<B<T>> is the current instantiation. + }; + + template<class T> struct A<A<A<T>>> { + struct C {}; + B<B<T>>::C bc; // expected-error {{missing 'typename'}} + }; +} + +namespace Example2 { + template<class T> struct A { + void g(); + }; + template<class T> using B = A<T>; + template<class T> void B<T>::g() {} // ok. +} diff --git a/clang/test/CXX/temp/temp.type/p1-0x.cpp b/clang/test/CXX/temp/temp.type/p1-0x.cpp new file mode 100644 index 00000000000..c22af22f986 --- /dev/null +++ b/clang/test/CXX/temp/temp.type/p1-0x.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +namespace Old { + template<template<class> class TT> struct X { }; + template<class> struct Y { }; + template<class T> using Z = Y<T>; + X<Y> y; + X<Z> z; + + using SameType = decltype(y); // expected-note {{here}} + using SameType = decltype(z); // expected-error {{different types}} +} + +namespace New { + template<class T> struct X { }; + template<class> struct Y { }; + template<class T> using Z = Y<T>; + X<Y<int>> y; + X<Z<int>> z; + + using SameType = decltype(y); + using SameType = decltype(z); // ok +} diff --git a/clang/test/CodeGenCXX/mangle-alias-template.cpp b/clang/test/CodeGenCXX/mangle-alias-template.cpp new file mode 100644 index 00000000000..2020a0a584e --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-alias-template.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +template<typename T> struct alloc {}; +template<typename T> using Alloc = alloc<T>; +template<typename T, typename A = Alloc<T>> struct vector {}; + +template<typename T> using Vec = vector<T>; + +template<typename T> void f(Vec<T> v); +template<typename T> void g(T); + +template<template<typename> class F> void h(F<int>); + +// CHECK: define void @_Z1zv( +void z() { + vector<int> VI; + f(VI); + // CHECK: call void @_Z1fIiEv6vectorIT_5allocIS1_EE( + + Vec<double> VD; + g(VD); + // CHECK: call void @_Z1gI6vectorId5allocIdEEEvT_( + + h<Vec>(VI); + // CHECK: call void @_Z1hI3VecEvT_IiE( + + Alloc<int> AC; + h(AC); + // CHECK: call void @_Z1hI5allocEvT_IiE( + + h<Alloc>(AC); + // CHECK: call void @_Z1hI5AllocEvT_IiE( + + Vec<char> VC; + g<Vec<char>>(VC); + // CHECK: call void @_Z1gI6vectorIc5allocIcEEEvT_( + + Vec<Vec<int>> VVI; + g(VVI); + // CHECK: call void @_Z1gI6vectorIS0_Ii5allocIiEES1_IS3_EEEvT_( +} diff --git a/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp b/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp new file mode 100644 index 00000000000..2132eff5e51 --- /dev/null +++ b/clang/test/CodeGenCXX/mangle-unnameable-conversions.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++0x -triple x86_64-apple-darwin10 -emit-llvm -o - %s | FileCheck %s + +template<typename T> using id = T; +struct S { + template<typename T, int N> + operator id<T[N]>&(); + template<typename T, typename U> + operator id<T (U::*)()>() const; +}; + +void f() { + int (&a)[42] = S(); // CHECK: @_ZN1ScvRAT0__T_IiLi42EEEv( + char (S::*fp)() = S(); // CHECK: @_ZNK1ScvMT0_FT_vEIcS_EEv( +}; diff --git a/clang/test/Lexer/has_feature_cxx0x.cpp b/clang/test/Lexer/has_feature_cxx0x.cpp index 57949e30177..57354f866ec 100644 --- a/clang/test/Lexer/has_feature_cxx0x.cpp +++ b/clang/test/Lexer/has_feature_cxx0x.cpp @@ -155,3 +155,12 @@ int no_override_control(); // CHECK-0X: has_override_control // CHECK-NO-0X: no_override_control + +#if __has_feature(cxx_alias_templates) +int has_alias_templates(); +#else +int no_alias_templates(); +#endif + +// CHECK-0X: has_alias_templates +// CHECK-NO-0X: no_alias_templates diff --git a/clang/test/PCH/cxx-alias-decl.cpp b/clang/test/PCH/cxx-alias-decl.cpp new file mode 100644 index 00000000000..e30311c58b7 --- /dev/null +++ b/clang/test/PCH/cxx-alias-decl.cpp @@ -0,0 +1,20 @@ +// Test this without pch. +// RUN: %clang_cc1 -x c++ -std=c++0x -include %S/cxx-alias-decl.h -fsyntax-only -emit-llvm -o - %s + +// Test with pch. +// RUN: %clang_cc1 -x c++ -std=c++0x -emit-pch -o %t %S/cxx-alias-decl.h +// RUN: %clang_cc1 -x c++ -std=c++0x -include-pch %t -fsyntax-only -emit-llvm -o - %s + +template struct T<S>; +C<A>::A<char> a; + +using T1 = decltype(a); +using T1 = D<int, char>; + +using T2 = B<A>; +using T2 = S; + +using A = int; +template<typename U> using B = S; +template<typename U> using C = T<U>; +template<typename U, typename V> using D = typename T<U>::template A<V>; diff --git a/clang/test/PCH/cxx-alias-decl.h b/clang/test/PCH/cxx-alias-decl.h new file mode 100644 index 00000000000..26bc716b08a --- /dev/null +++ b/clang/test/PCH/cxx-alias-decl.h @@ -0,0 +1,11 @@ +// Header for PCH test cxx-alias-decl.cpp + +struct S {}; +template<typename U> struct T { + template<typename V> using A = T<V>; +}; + +using A = int; +template<typename U> using B = S; +template<typename U> using C = T<U>; +template<typename U, typename V> using D = typename T<U>::template A<V>; diff --git a/clang/test/SemaCXX/alias-template.cpp b/clang/test/SemaCXX/alias-template.cpp new file mode 100644 index 00000000000..f29a9327dab --- /dev/null +++ b/clang/test/SemaCXX/alias-template.cpp @@ -0,0 +1,147 @@ +// RUN: %clang_cc1 -verify -std=c++0x %s + +namespace RedeclAliasTypedef { + template<typename U> using T = int; + template<typename U> using T = int; + template<typename U> using T = T<U>; +} + +namespace IllegalTypeIds { + template<typename U> using A = void(int n = 0); // expected-error {{default arguments can only be specified for parameters in a function declaration}} + template<typename U> using B = inline void(int n); // expected-error {{type name does not allow function specifier}} + template<typename U> using C = virtual void(int n); // expected-error {{type name does not allow function specifier}} + template<typename U> using D = explicit void(int n); // expected-error {{type name does not allow function specifier}} + template<typename U> using E = void(int n) throw(); // expected-error {{exception specifications are not allowed in type aliases}} + // FIXME: this is illegal; we incorrectly accept it for typedefs too. + template<typename U> using F = void(*)(int n) &&; // expected-err + template<typename U> using G = __thread void(int n); // expected-error {{type name does not allow storage class to be specified}} + + template<typename U> using H = void(int n); // ok + template<typename U> using I = void(int n) &&; // ok +} + +namespace IllegalSyntax { + template<typename Z> using ::T = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + template<typename Z> using operator int = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + template<typename Z> using typename U = void; // expected-error {{name defined in alias declaration must be an identifier}} + template<typename Z> using typename ::V = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} + template<typename Z> using typename ::operator bool = void(int n); // expected-error {{name defined in alias declaration must be an identifier}} +} + +namespace VariableLengthArrays { + template<typename Z> using T = int[42]; // ok + + int n = 32; + template<typename Z> using T = int[n]; // expected-error {{variable length array declaration not allowed at file scope}} + + const int m = 42; + template<typename Z> using U = int[m]; // expected-note {{previous definition}} + template<typename Z> using U = int[42]; // ok + template<typename Z> using U = int; // expected-error {{type alias template redefinition with different types ('int' vs 'int [42]')}} +} + +namespace RedeclFunc { + int f(int, char**); + template<typename Z> using T = int; + T<char> f(int, char **); // ok +} + +namespace LookupFilter { + namespace N { template<typename U> using S = int; } + using namespace N; + template<typename U> using S = S<U>*; // ok +} + +namespace InFunctions { + template<typename...T> struct S0 { + template<typename Z> using U = T*; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} + U<char> u; + }; + + template<typename Z> using T1 = int; + template<typename Z> using T2 = int[-1]; // expected-error {{array size is negative}} + template<typename...T> struct S3 { // expected-note {{template parameter is declared here}} + template<typename Z> using T = int; // expected-error {{declaration of 'T' shadows template parameter}} + }; + template<typename Z> using Z = Z; +} + +namespace ClassNameRedecl { + class C0 { + // FIXME: this diagnostic is pretty poor + template<typename U> using C0 = int; // expected-error {{name defined in alias declaration must be an identifier}} + }; + class C1 { + // FIXME: this diagnostic is pretty poor + template<typename U> using C1 = C1; // expected-error {{name defined in alias declaration must be an identifier}} + }; + class C2 { + template<typename U> using C0 = C1; // ok + }; + template<typename...T> class C3 { + template<typename U> using f = T; // expected-error {{declaration type contains unexpanded parameter pack 'T'}} + }; + template<typename T> class C4 { // expected-note {{template parameter is declared here}} + template<typename U> using T = int; // expected-error {{declaration of 'T' shadows template parameter}} + }; + class C5 { + class c; // expected-note {{previous definition}} + template<typename U> using c = int; // expected-error {{redefinition of 'c' as different kind of symbol}} + class d; // expected-note {{previous definition}} + template<typename U> using d = d; // expected-error {{redefinition of 'd' as different kind of symbol}} + }; + class C6 { + class c { template<typename U> using C6 = int; }; // ok + }; +} + +class CtorDtorName { + template<typename T> using X = CtorDtorName; + X<int>(); // expected-error {{expected member name}} + ~X<int>(); // expected-error {{destructor cannot be declared using a type alias}} +}; + +namespace TagName { + template<typename Z> using S = struct { int n; }; // expected-error {{can not be defined}} + template<typename Z> using T = class { int n; }; // expected-error {{can not be defined}} + template<typename Z> using U = enum { a, b, c }; // expected-error {{can not be defined}} + template<typename Z> using V = struct V { int n; }; // expected-error {{redefinition of 'V' as different kind of symbol}} \ + expected-error {{'TagName::V' can not be defined in a type alias template}} \ + expected-note {{previous definition is here}} +} + +namespace StdExample { + template<typename T, typename U> struct pair; + + template<typename T> using handler_t = void (*)(T); + extern handler_t<int> ignore; + extern void (*ignore)(int); + // FIXME: we recover as if cell is an undeclared variable. the diagnostics are terrible! + template<typename T> using cell = pair<T*, cell<T>*>; // expected-error {{use of undeclared identifier 'cell'}} \ + expected-error {{'T' does not refer to a value}} \ + expected-note {{declared here}} \ + expected-error {{expected ';' after alias declaration}} +} + +namespace Access { + class C0 { + template<typename Z> using U = int; // expected-note {{declared private here}} + }; + C0::U<int> v; // expected-error {{'U' is a private member}} + class C1 { + public: + template<typename Z> using U = int; + }; + C1::U<int> w; // ok +} + +namespace VoidArg { + template<typename Z> using V = void; + V<int> f(int); // ok + V<char> g(V<double>); // expected-error {{empty parameter list defined with a type alias of 'void' not allowed}} +} + +namespace Curried { + template<typename T, typename U> struct S; + template<typename T> template<typename U> using SS = S<T, U>; // expected-error {{extraneous template parameter list in alias template declaration}} +} diff --git a/clang/test/SemaCXX/attr-cxx0x.cpp b/clang/test/SemaCXX/attr-cxx0x.cpp index 40fe0e01c2e..725f0182db5 100644 --- a/clang/test/SemaCXX/attr-cxx0x.cpp +++ b/clang/test/SemaCXX/attr-cxx0x.cpp @@ -9,8 +9,13 @@ struct align_member { int member [[align(8)]]; }; +typedef char align_typedef [[align(8)]]; +template<typename T> using align_alias_template = align_typedef; + static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong"); static_assert(alignof(align_small) == 1, "j's alignment is wrong"); static_assert(alignof(align_multiple) == 8, "l's alignment is wrong"); static_assert(alignof(align_member) == 8, "quuux's alignment is wrong"); static_assert(sizeof(align_member) == 8, "quuux's size is wrong"); +static_assert(alignof(align_typedef) == 8, "typedef's alignment is wrong"); +static_assert(alignof(align_alias_template<int>) == 8, "alias template's alignment is wrong"); diff --git a/clang/test/SemaCXX/dependent-types.cpp b/clang/test/SemaCXX/dependent-types.cpp index d9b53230c99..053e79bb698 100644 --- a/clang/test/SemaCXX/dependent-types.cpp +++ b/clang/test/SemaCXX/dependent-types.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s +// RUN: %clang_cc1 -fsyntax-only -pedantic -verify -std=c++0x %s + +template<typename T> using U = int &; template<typename T, int Size> void f() { T x1; @@ -7,4 +9,5 @@ template<typename T, int Size> void f() { T x4[]; // expected-error{{needs an explicit size or an initializer}} T x5[Size]; int x6[Size]; + U<T> x7; // expected-error{{declaration of reference variable 'x7' requires an initializer}} } diff --git a/clang/test/SemaCXX/redeclared-alias-template.cpp b/clang/test/SemaCXX/redeclared-alias-template.cpp new file mode 100644 index 00000000000..b368fcfe550 --- /dev/null +++ b/clang/test/SemaCXX/redeclared-alias-template.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +template<typename T> using A = int; // expected-note 2{{previous}} +template<typename T> using A = char; // expected-error {{type alias template redefinition with different types ('char' vs 'int')}} +template<typename T1, typename T2> using A = T1; // expected-error {{too many template parameters in template redeclaration}} + +template<typename T1, typename T2> using B = T1; // expected-note {{previous}} +template<typename T2, typename T1> using B = T1; // expected-error {{type alias template redefinition with different types}} + + +template<typename> struct S; +template<template<typename> class F> using FInt = F<int>; +template<typename X> using SXRInt = FInt<S<X>::template R>; +template<typename X> using SXRInt = typename S<X>::template R<int>; // ok, redeclaration. + +template<template<typename> class> struct TT; + +namespace FilterLookup { + TT<A> f(); // expected-note {{previous declaration is here}} + + template<typename> using A = int; + TT<A> f(); // expected-error {{functions that differ only in their return type cannot be overloaded}} +} diff --git a/clang/test/SemaTemplate/alias-church-numerals.cpp b/clang/test/SemaTemplate/alias-church-numerals.cpp new file mode 100644 index 00000000000..751cac73ae0 --- /dev/null +++ b/clang/test/SemaTemplate/alias-church-numerals.cpp @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s + +template<template<template<typename> class, typename> class T, template<typename> class V> struct PartialApply { + template<typename W> using R = T<V, W>; +}; + +template<typename T> using Id = T; +template<template<typename> class, typename X> using Zero = X; +template<template<template<typename> class, typename> class N, template<typename> class F, typename X> using Succ = F<N<F,X>>; + +template<template<typename> class F, typename X> using One = Succ<Zero, F, X>; +template<template<typename> class F, typename X> using Two = Succ<One, F, X>; + +template<template<template<typename> class, typename> class A, + template<template<typename> class, typename> class B, + template<typename> class F, + typename X> using Add = A<F, B<F, X>>; + +template<template<template<typename> class, typename> class A, + template<template<typename> class, typename> class B, + template<typename> class F, + typename X> using Mul = A<PartialApply<B,F>::template R, X>; + +template<template<typename> class F, typename X> using Four = Add<Two, Two, F, X>; +template<template<typename> class F, typename X> using Sixteen = Mul<Four, Four, F, X>; +template<template<typename> class F, typename X> using TwoHundredAndFiftySix = Mul<Sixteen, Sixteen, F, X>; + +template<typename T, T N> struct Const { static const T value = N; }; +template<typename A> struct IncrementHelper; +template<typename T, T N> struct IncrementHelper<Const<T, N>> { using Result = Const<T, N+1>; }; +template<typename A> using Increment = typename IncrementHelper<A>::Result; + +using Arr = int[TwoHundredAndFiftySix<Increment, Const<int, 0>>::value]; +using Arr = int[256]; diff --git a/clang/test/SemaTemplate/alias-nested-nontag.cpp b/clang/test/SemaTemplate/alias-nested-nontag.cpp new file mode 100644 index 00000000000..1bb5ce336f9 --- /dev/null +++ b/clang/test/SemaTemplate/alias-nested-nontag.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +template<typename T> using Id = T; // expected-note {{type alias template 'Id' declared here}} +struct U { static Id<int> V; }; +Id<int> ::U::V; // expected-error {{type 'Id<int>' (aka 'int') cannot be used prior to '::' because it has no members}} \ + expected-error {{C++ requires a type specifier}} diff --git a/clang/test/SemaTemplate/alias-template-template-param.cpp b/clang/test/SemaTemplate/alias-template-template-param.cpp new file mode 100644 index 00000000000..a847b0672a2 --- /dev/null +++ b/clang/test/SemaTemplate/alias-template-template-param.cpp @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s + +template<template<typename> class D> using C = D<int>; + +// Substitution of the alias template transforms the TemplateSpecializationType +// 'D<int>' into the DependentTemplateSpecializationType 'T::template U<int>'. +template<typename T> void f(C<T::template U>); |