blob: ea1e0af21a6d1c6f2d20d0ce032a39a0df38f035 [file] [log] [blame]
Daniel Dunbard7d5f022009-03-24 02:24:46 +00001// RUN: clang-cc -fsyntax-only %s
Douglas Gregor940bd832009-03-13 21:04:12 +00002typedef char one_byte;
3typedef char (&two_bytes)[2];
4typedef char (&four_bytes)[4];
5typedef char (&eight_bytes)[8];
6
7template<int N> struct A { };
8
9namespace N1 {
10 struct X { };
11}
12
13namespace N2 {
14 struct Y { };
15
16 two_bytes operator+(Y, Y);
17}
18
19namespace N3 {
20 struct Z { };
21
22 eight_bytes operator+(Z, Z);
23}
24
25namespace N4 {
26 one_byte operator+(N1::X, N2::Y);
27
28 template<typename T, typename U>
29 struct BinOpOverload {
30 typedef A<sizeof(T() + U())> type;
31 };
32}
33
34namespace N1 {
35 four_bytes operator+(X, X);
36}
37
38namespace N3 {
39 eight_bytes operator+(Z, Z); // redeclaration
40}
41
42void test_bin_op_overload(A<1> *a1, A<2> *a2, A<4> *a4, A<8> *a8) {
43 typedef N4::BinOpOverload<N1::X, N2::Y>::type XY;
44 XY *xy = a1;
45 typedef N4::BinOpOverload<N1::X, N1::X>::type XX;
46 XX *xx = a4;
47 typedef N4::BinOpOverload<N2::Y, N2::Y>::type YY;
48 YY *yy = a2;
49 typedef N4::BinOpOverload<N3::Z, N3::Z>::type ZZ;
50 ZZ *zz = a8;
51}
52
Douglas Gregorbc736fc2009-03-13 23:49:33 +000053namespace N3 {
54 eight_bytes operator-(::N3::Z);
55}
56
57namespace N4 {
58 template<typename T>
59 struct UnaryOpOverload {
60 typedef A<sizeof(-T())> type;
61 };
62}
63
64void test_unary_op_overload(A<8> *a8) {
65 typedef N4::UnaryOpOverload<N3::Z>::type UZ;
66 UZ *uz = a8;
67}
Gabor Greif087edcf2009-03-18 00:55:04 +000068
69/*
70namespace N5 {
71 template<int I>
72 struct Lookup {
73 enum { val = I, more = val + 1 };
74 };
75
76 template<bool B>
77 struct Cond {
78 enum Junk { is = B ? Lookup<B>::more : Lookup<Lookup<B+1>::more>::val };
79 };
80
81 enum { resultT = Cond<true>::is,
82 resultF = Cond<false>::is };
83}
84*/
85
86namespace N6 {
Gabor Greifa88620c2009-03-18 20:26:44 +000087 // non-typedependent
Gabor Greif087edcf2009-03-18 00:55:04 +000088 template<int I>
Gabor Greifa88620c2009-03-18 20:26:44 +000089 struct Lookup {};
Gabor Greif087edcf2009-03-18 00:55:04 +000090
91 template<bool B, typename T, typename E>
92 struct Cond {
93 typedef Lookup<B ? sizeof(T) : sizeof(E)> True;
94 typedef Lookup<!B ? sizeof(T) : sizeof(E)> False;
95 };
96
97 typedef Cond<true, int, char>::True True;
Gabor Greif6c473c82009-03-18 01:16:08 +000098 typedef Cond<true, int, char>::False False;
99
100 // check that we have the right types
101 Lookup<1> const &L1(False());
102 Lookup<sizeof(int)> const &L2(True());
Gabor Greif087edcf2009-03-18 00:55:04 +0000103}
104
105
Gabor Greifa88620c2009-03-18 20:26:44 +0000106namespace N7 {
107 // type dependent
108 template<int I>
109 struct Lookup {};
110
111 template<bool B, typename T, typename E>
112 struct Cond {
113 T foo() { return B ? T() : E(); }
114 typedef Lookup<sizeof(B ? T() : E())> Type;
115 };
116
117 //Cond<true, int*, double> C; // Errors
118 //int V(C.foo()); // Errors
119 //typedef Cond<true, int*, double>::Type Type; // Errors + CRASHES!
120 typedef Cond<true, int, double>::Type Type;
121}
122
Douglas Gregor1eee0e72009-05-14 21:06:31 +0000123#if 0
124// FIXME: Unable to handle general declaration references at this point.
125template<typename T, unsigned long N> struct IntegralConstant { };
126
127template<typename T>
128struct X0 {
129 void f(T x, IntegralConstant<T, sizeof(x)>);
130};
131
132void test_X0(X0<int> x, IntegralConstant<int, sizeof(int)> ic) {
133 x.f(ic);
134}
135#endif