1abea951c34876a5374d0e3678c7989b225c5c895Anders Carlsson// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s 254dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregortemplate<typename T, typename U> 354dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregorstruct X0 { 454dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregor void f(T x, U y) { 5d7e2705961bacb9df5d9119403c01c9b04aff97fDouglas Gregor (void)(x + y); // expected-error{{invalid operands}} 654dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregor } 754dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregor}; 854dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregor 954dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregorstruct X1 { }; 1054dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregor 1154dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregortemplate struct X0<int, float>; 1254dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregortemplate struct X0<int*, int>; 1354dabfca850ca9e60e9ffb60003529f868d4d127Douglas Gregortemplate struct X0<int X1::*, int>; // expected-note{{instantiation of}} 14e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregor 15e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregortemplate<typename T> 16e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregorstruct X2 { 17e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregor void f(T); 18e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregor 19e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregor T g(T x, T y) { 20b9f1b8d877541e76390cd3807c2dcff2f950360aDouglas Gregor /* DeclStmt */; 21b9f1b8d877541e76390cd3807c2dcff2f950360aDouglas Gregor T *xp = &x, &yr = y; // expected-error{{pointer to a reference}} 22e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregor /* NullStmt */; 23e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregor } 24e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregor}; 25e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregor 26e7a18c88b77523cf1085d239fd373770ba5791f1Douglas Gregortemplate struct X2<int>; 27b9f1b8d877541e76390cd3807c2dcff2f950360aDouglas Gregortemplate struct X2<int&>; // expected-note{{instantiation of}} 28137fa562caedf11df4bb10f2657651a785769ca7Anders Carlsson 29137fa562caedf11df4bb10f2657651a785769ca7Anders Carlssontemplate<typename T> 30137fa562caedf11df4bb10f2657651a785769ca7Anders Carlssonstruct X3 { 31137fa562caedf11df4bb10f2657651a785769ca7Anders Carlsson void f(T) { 32137fa562caedf11df4bb10f2657651a785769ca7Anders Carlsson Label: 33137fa562caedf11df4bb10f2657651a785769ca7Anders Carlsson T x; 34137fa562caedf11df4bb10f2657651a785769ca7Anders Carlsson goto Label; 35137fa562caedf11df4bb10f2657651a785769ca7Anders Carlsson } 36137fa562caedf11df4bb10f2657651a785769ca7Anders Carlsson}; 37137fa562caedf11df4bb10f2657651a785769ca7Anders Carlsson 38137fa562caedf11df4bb10f2657651a785769ca7Anders Carlssontemplate struct X3<int>; 3903d77760a5db7990724b6901cea958a673ce0b39Anders Carlsson 4003d77760a5db7990724b6901cea958a673ce0b39Anders Carlssontemplate <typename T> struct X4 { 4103d77760a5db7990724b6901cea958a673ce0b39Anders Carlsson T f() const { 42184aa4e6ded190bfb3bbe207040467f8d7e28a04Chris Lattner return; // expected-error{{non-void function 'f' should return a value}} 4303d77760a5db7990724b6901cea958a673ce0b39Anders Carlsson } 4403d77760a5db7990724b6901cea958a673ce0b39Anders Carlsson 4503d77760a5db7990724b6901cea958a673ce0b39Anders Carlsson T g() const { 46184aa4e6ded190bfb3bbe207040467f8d7e28a04Chris Lattner return 1; // expected-error{{void function 'g' should not return a value}} 4703d77760a5db7990724b6901cea958a673ce0b39Anders Carlsson } 4803d77760a5db7990724b6901cea958a673ce0b39Anders Carlsson}; 4903d77760a5db7990724b6901cea958a673ce0b39Anders Carlsson 50f3e7ce4bd9837cdab6a096235922865f95467d3dDouglas Gregortemplate struct X4<void>; // expected-note{{in instantiation of}} 51f3e7ce4bd9837cdab6a096235922865f95467d3dDouglas Gregortemplate struct X4<int>; // expected-note{{in instantiation of}} 52e2c31ff0bc622e6fd7d47d7e08b53840f3be6c89Douglas Gregor 53d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregorstruct Incomplete; // expected-note 2{{forward declaration}} 54e2c31ff0bc622e6fd7d47d7e08b53840f3be6c89Douglas Gregor 55e2c31ff0bc622e6fd7d47d7e08b53840f3be6c89Douglas Gregortemplate<typename T> struct X5 { 56e2c31ff0bc622e6fd7d47d7e08b53840f3be6c89Douglas Gregor T f() { } // expected-error{{incomplete result type}} 57e2c31ff0bc622e6fd7d47d7e08b53840f3be6c89Douglas Gregor}; 58e2c31ff0bc622e6fd7d47d7e08b53840f3be6c89Douglas Gregorvoid test_X5(X5<Incomplete> x5); // okay! 59e2c31ff0bc622e6fd7d47d7e08b53840f3be6c89Douglas Gregor 60e2c31ff0bc622e6fd7d47d7e08b53840f3be6c89Douglas Gregortemplate struct X5<Incomplete>; // expected-note{{instantiation}} 61d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor 62d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregortemplate<typename T, typename U, typename V> struct X6 { 63d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor U f(T t, U u, V v) { 64d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor // IfStmt 65d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor if (t > 0) 66d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor return u; 6749f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor else { 6849f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor if (t < 0) 6918ef5e28a9a2677f8b1dce1fb2638d66e0a1621fDouglas Gregor return v; // expected-error{{cannot initialize return object of type}} 7049f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor } 7149f25ecf7ff358039ce4c9254b867f32110e660eDouglas Gregor 72e06274d5c5c6b2decc9f217a8913b28f846bfcfaDouglas Gregor if (T x = t) { 73e06274d5c5c6b2decc9f217a8913b28f846bfcfaDouglas Gregor t = x; 74e06274d5c5c6b2decc9f217a8913b28f846bfcfaDouglas Gregor } 757114cbab7eb6e8b714eb22f014327daf2c741c08John McCall return v; // expected-error{{cannot initialize return object of type}} 76d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor } 77d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor}; 78d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor 79d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregorstruct ConvertibleToInt { 80d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor operator int() const; 81d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor}; 82d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregor 83d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregortemplate struct X6<ConvertibleToInt, float, char>; 84d06f6ca61062f85926eb9d409eb3d4f8afcf93c7Douglas Gregortemplate struct X6<bool, int, int*>; // expected-note{{instantiation}} 850712d29123215e00b9e5b3c89746c90d9624830fAnders Carlsson 860712d29123215e00b9e5b3c89746c90d9624830fAnders Carlssontemplate <typename T> struct X7 { 870712d29123215e00b9e5b3c89746c90d9624830fAnders Carlsson void f() { 880712d29123215e00b9e5b3c89746c90d9624830fAnders Carlsson void *v = this; 890712d29123215e00b9e5b3c89746c90d9624830fAnders Carlsson } 900712d29123215e00b9e5b3c89746c90d9624830fAnders Carlsson}; 910712d29123215e00b9e5b3c89746c90d9624830fAnders Carlsson 920712d29123215e00b9e5b3c89746c90d9624830fAnders Carlssontemplate struct X7<int>; 934a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor 944a2e2041edc63db687677325e113b39b9d123c40Douglas Gregortemplate<typename T> struct While0 { 954a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor void f(T t) { 964a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor while (t) { 974a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor } 984a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor 994a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor while (T t2 = T()) ; 1004a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor } 1014a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor}; 1024a2e2041edc63db687677325e113b39b9d123c40Douglas Gregor 1034a2e2041edc63db687677325e113b39b9d123c40Douglas Gregortemplate struct While0<float>; 1049f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor 1059f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregortemplate<typename T> struct Do0 { 1069f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor void f(T t) { 1079f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor do { 1089f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor } while (t); // expected-error{{not contextually}} 1099f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor } 1109f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor}; 1119f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregor 1129f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregorstruct NotConvertibleToBool { }; 1139f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregortemplate struct Do0<ConvertibleToInt>; 1149f3ca2a7747bd47f14d7693f333103fac29a24d2Douglas Gregortemplate struct Do0<NotConvertibleToBool>; // expected-note{{instantiation}} 1155831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor 1165831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregortemplate<typename T> struct For0 { 1175831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor void f(T f, T l) { 1185831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor for (; f != l; ++f) { 119861ce3178c70cfb0fa50baf685e1ad363538eaa9Douglas Gregor if (*f) 120861ce3178c70cfb0fa50baf685e1ad363538eaa9Douglas Gregor continue; 121861ce3178c70cfb0fa50baf685e1ad363538eaa9Douglas Gregor else if (*f == 17) 122861ce3178c70cfb0fa50baf685e1ad363538eaa9Douglas Gregor break; 1235831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor } 1245831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor } 1255831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor}; 1265831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregor 1275831c6a1efc47e6a19d82fe3dd25b5b8fef6979dDouglas Gregortemplate struct For0<int*>; 128ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson 129ffce2df6ae280d354d51371282a579df1eb86876Anders Carlssontemplate<typename T> struct Member0 { 130ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson void f(T t) { 131ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson t; 132ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson t.f; 133ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson t->f; 134ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson 135ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson T* tp; 136ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson tp.f; // expected-error{{member reference base type 'T *' is not a structure or union}} 137ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson tp->f; 138ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson 139ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson this->f; 1404e579922ada4e19618710878c32543322f86c9c8Anders Carlsson this.f; // expected-error{{member reference base type 'Member0<T> *' is not a structure or union}} 141ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson } 142ffce2df6ae280d354d51371282a579df1eb86876Anders Carlsson}; 143dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor 144dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregortemplate<typename T, typename U> struct Switch0 { 145dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor U f(T value, U v0, U v1, U v2) { 146dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor switch (value) { 147dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor case 0: return v0; 148dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor 149dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor case 1: return v1; 150dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor 151dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor case 2: // fall through 152dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor 153dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor default: 154dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor return v2; 155dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor } 156dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor } 157dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor}; 158dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor 159dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregortemplate struct Switch0<int, float>; 160dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor 161dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregortemplate<typename T, int I1, int I2> struct Switch1 { 162dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor T f(T x, T y, T z) { 163dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor switch (x) { 164dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor case I1: return y; // expected-note{{previous}} 165dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor case I2: return z; // expected-error{{duplicate}} 166dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor default: return x; 167dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor } 168dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor } 169dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor}; 170dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregor 171dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregortemplate struct Switch1<int, 1, 2>; 172dbb26db1d426fb6caaaf1b4fa47b46d1947c12c9Douglas Gregortemplate struct Switch1<int, 2, 2>; // expected-note{{instantiation}} 1735f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor 1745f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregortemplate<typename T> struct IndirectGoto0 { 1755f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor void f(T x) { 1765f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor // FIXME: crummy error message below 1775f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor goto *x; // expected-error{{incompatible}} 17876658235f9e350eab68bfbb4e88d0be2ad48e102Douglas Gregor 17976658235f9e350eab68bfbb4e88d0be2ad48e102Douglas Gregor prior: 180632c9d26925f9aa8179607956c83ee348930b6d7Chris Lattner T prior_label; 1817114cbab7eb6e8b714eb22f014327daf2c741c08John McCall prior_label = &&prior; // expected-error{{assigning to 'int'}} 18276658235f9e350eab68bfbb4e88d0be2ad48e102Douglas Gregor 183632c9d26925f9aa8179607956c83ee348930b6d7Chris Lattner T later_label; 1847114cbab7eb6e8b714eb22f014327daf2c741c08John McCall later_label = &&later; // expected-error{{assigning to 'int'}} 18576658235f9e350eab68bfbb4e88d0be2ad48e102Douglas Gregor 18676658235f9e350eab68bfbb4e88d0be2ad48e102Douglas Gregor later: 18776658235f9e350eab68bfbb4e88d0be2ad48e102Douglas Gregor (void)(1+1); 1885f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor } 1895f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor}; 1905f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregor 1915f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregortemplate struct IndirectGoto0<void*>; 1925f1b9e689fa5c101512aef99225f2afea1673449Douglas Gregortemplate struct IndirectGoto0<int>; // expected-note{{instantiation}} 193d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor 194d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregortemplate<typename T> struct TryCatch0 { 195d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor void f() { 196d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor try { 197ecd7b04ae7764179d40ee4e3e49c99d1fbcb4effDouglas Gregor } catch (T t) { // expected-error{{incomplete type}} \ 198d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor // expected-error{{abstract class}} 199d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor } catch (...) { 200d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor } 201d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor } 202d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor}; 203d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor 204d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregorstruct Abstract { 205d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor virtual void foo() = 0; // expected-note{{pure virtual}} 206d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor}; 207d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregor 208d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregortemplate struct TryCatch0<int>; // okay 209d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregortemplate struct TryCatch0<Incomplete*>; // expected-note{{instantiation}} 210d308e6201afd3a8a198c52ba034d35ed19d4bafeDouglas Gregortemplate struct TryCatch0<Abstract>; // expected-note{{instantiation}} 21131a08752eda39ca17154538e2f2587f8d339a1faAnders Carlsson 21231a08752eda39ca17154538e2f2587f8d339a1faAnders Carlsson// PR4383 21331a08752eda39ca17154538e2f2587f8d339a1faAnders Carlssontemplate<typename T> struct X; 21431a08752eda39ca17154538e2f2587f8d339a1faAnders Carlssontemplate<typename T> struct Y : public X<T> { 21531a08752eda39ca17154538e2f2587f8d339a1faAnders Carlsson Y& x() { return *this; } 21631a08752eda39ca17154538e2f2587f8d339a1faAnders Carlsson}; 217069ace5adc444a159003c29e85e166cee491ad39John McCall 218069ace5adc444a159003c29e85e166cee491ad39John McCall// Make sure our assertions don't get too uppity. 219069ace5adc444a159003c29e85e166cee491ad39John McCallnamespace test0 { 220069ace5adc444a159003c29e85e166cee491ad39John McCall template <class T> class A { void foo(T array[10]); }; 221069ace5adc444a159003c29e85e166cee491ad39John McCall template class A<int>; 222069ace5adc444a159003c29e85e166cee491ad39John McCall} 223f7d72f5a4a3f0e610d77c6779ca3c21920a14bc7Douglas Gregor 224f7d72f5a4a3f0e610d77c6779ca3c21920a14bc7Douglas Gregornamespace PR7016 { 225f7d72f5a4a3f0e610d77c6779ca3c21920a14bc7Douglas Gregor template<typename T> void f() { T x = x; } 226f7d72f5a4a3f0e610d77c6779ca3c21920a14bc7Douglas Gregor template void f<int>(); 227f7d72f5a4a3f0e610d77c6779ca3c21920a14bc7Douglas Gregor} 228c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor 229c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregornamespace PR9880 { 230c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor struct lua_State; 231c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor struct no_tag { char a; }; // (A) 232c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor struct yes_tag { long a; long b; }; // (A) 233c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor 234c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor template <typename T> 235c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor struct HasIndexMetamethod { 236c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor template <typename U> 237c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor static no_tag check(...); 238c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor template <typename U> 239c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor static yes_tag check(char[sizeof(&U::luaIndex)]); 240c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor enum { value = sizeof(check<T>(0)) == sizeof(yes_tag) }; 241c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor }; 242c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor 243c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor class SomeClass { 244c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor public: 245c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor int luaIndex(lua_State* L); 246c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor }; 247c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor 248c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor int i = HasIndexMetamethod<SomeClass>::value; 249c056c1792eac0717640f1f48b3739cc9a98ee413Douglas Gregor} 250