instantiate-expr-2.cpp revision b4f9090cc19ca3502fd895def9769d9c5a5a06c2
10760636d458c860beeb77a63049e91e614b4be31Douglas Gregor// RUN: clang -fsyntax-only %s 20760636d458c860beeb77a63049e91e614b4be31Douglas Gregortypedef char one_byte; 30760636d458c860beeb77a63049e91e614b4be31Douglas Gregortypedef char (&two_bytes)[2]; 40760636d458c860beeb77a63049e91e614b4be31Douglas Gregortypedef char (&four_bytes)[4]; 50760636d458c860beeb77a63049e91e614b4be31Douglas Gregortypedef char (&eight_bytes)[8]; 60760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 70760636d458c860beeb77a63049e91e614b4be31Douglas Gregortemplate<int N> struct A { }; 80760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 90760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N1 { 100760636d458c860beeb77a63049e91e614b4be31Douglas Gregor struct X { }; 110760636d458c860beeb77a63049e91e614b4be31Douglas Gregor} 120760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 130760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N2 { 140760636d458c860beeb77a63049e91e614b4be31Douglas Gregor struct Y { }; 150760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 160760636d458c860beeb77a63049e91e614b4be31Douglas Gregor two_bytes operator+(Y, Y); 170760636d458c860beeb77a63049e91e614b4be31Douglas Gregor} 180760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 190760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N3 { 200760636d458c860beeb77a63049e91e614b4be31Douglas Gregor struct Z { }; 210760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 220760636d458c860beeb77a63049e91e614b4be31Douglas Gregor eight_bytes operator+(Z, Z); 230760636d458c860beeb77a63049e91e614b4be31Douglas Gregor} 240760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 250760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N4 { 260760636d458c860beeb77a63049e91e614b4be31Douglas Gregor one_byte operator+(N1::X, N2::Y); 270760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 280760636d458c860beeb77a63049e91e614b4be31Douglas Gregor template<typename T, typename U> 290760636d458c860beeb77a63049e91e614b4be31Douglas Gregor struct BinOpOverload { 300760636d458c860beeb77a63049e91e614b4be31Douglas Gregor typedef A<sizeof(T() + U())> type; 310760636d458c860beeb77a63049e91e614b4be31Douglas Gregor }; 320760636d458c860beeb77a63049e91e614b4be31Douglas Gregor} 330760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 340760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N1 { 350760636d458c860beeb77a63049e91e614b4be31Douglas Gregor four_bytes operator+(X, X); 360760636d458c860beeb77a63049e91e614b4be31Douglas Gregor} 370760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 380760636d458c860beeb77a63049e91e614b4be31Douglas Gregornamespace N3 { 390760636d458c860beeb77a63049e91e614b4be31Douglas Gregor eight_bytes operator+(Z, Z); // redeclaration 400760636d458c860beeb77a63049e91e614b4be31Douglas Gregor} 410760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 420760636d458c860beeb77a63049e91e614b4be31Douglas Gregorvoid test_bin_op_overload(A<1> *a1, A<2> *a2, A<4> *a4, A<8> *a8) { 430760636d458c860beeb77a63049e91e614b4be31Douglas Gregor typedef N4::BinOpOverload<N1::X, N2::Y>::type XY; 440760636d458c860beeb77a63049e91e614b4be31Douglas Gregor XY *xy = a1; 450760636d458c860beeb77a63049e91e614b4be31Douglas Gregor typedef N4::BinOpOverload<N1::X, N1::X>::type XX; 460760636d458c860beeb77a63049e91e614b4be31Douglas Gregor XX *xx = a4; 470760636d458c860beeb77a63049e91e614b4be31Douglas Gregor typedef N4::BinOpOverload<N2::Y, N2::Y>::type YY; 480760636d458c860beeb77a63049e91e614b4be31Douglas Gregor YY *yy = a2; 490760636d458c860beeb77a63049e91e614b4be31Douglas Gregor typedef N4::BinOpOverload<N3::Z, N3::Z>::type ZZ; 500760636d458c860beeb77a63049e91e614b4be31Douglas Gregor ZZ *zz = a8; 510760636d458c860beeb77a63049e91e614b4be31Douglas Gregor} 520760636d458c860beeb77a63049e91e614b4be31Douglas Gregor 53c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregornamespace N3 { 54c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor eight_bytes operator-(::N3::Z); 55c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor} 56c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor 57c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregornamespace N4 { 58c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor template<typename T> 59c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor struct UnaryOpOverload { 60c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor typedef A<sizeof(-T())> type; 61c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor }; 62c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor} 63c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor 64c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregorvoid test_unary_op_overload(A<8> *a8) { 65c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor typedef N4::UnaryOpOverload<N3::Z>::type UZ; 66c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor UZ *uz = a8; 67c78182dea4396fba411d2526a1386ca994eee6c0Douglas Gregor} 688a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif 698a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif/* 708a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greifnamespace N5 { 718a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif template<int I> 728a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif struct Lookup { 738a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif enum { val = I, more = val + 1 }; 748a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif }; 758a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif 768a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif template<bool B> 778a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif struct Cond { 788a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif enum Junk { is = B ? Lookup<B>::more : Lookup<Lookup<B+1>::more>::val }; 798a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif }; 808a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif 818a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif enum { resultT = Cond<true>::is, 828a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif resultF = Cond<false>::is }; 838a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif} 848a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif*/ 858a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif 868a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greifnamespace N6 { 87b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif // non-typedependent 888a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif template<int I> 89b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif struct Lookup {}; 908a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif 918a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif template<bool B, typename T, typename E> 928a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif struct Cond { 938a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif typedef Lookup<B ? sizeof(T) : sizeof(E)> True; 948a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif typedef Lookup<!B ? sizeof(T) : sizeof(E)> False; 958a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif }; 968a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif 978a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif typedef Cond<true, int, char>::True True; 9876368bbd3f5a8433a863798727e41af9afbf598dGabor Greif typedef Cond<true, int, char>::False False; 9976368bbd3f5a8433a863798727e41af9afbf598dGabor Greif 10076368bbd3f5a8433a863798727e41af9afbf598dGabor Greif // check that we have the right types 10176368bbd3f5a8433a863798727e41af9afbf598dGabor Greif Lookup<1> const &L1(False()); 10276368bbd3f5a8433a863798727e41af9afbf598dGabor Greif Lookup<sizeof(int)> const &L2(True()); 1038a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif} 1048a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif 1058a0659c213ac62a4dcaa7d25c7c3825212bc763dGabor Greif 106b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greifnamespace N7 { 107b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif // type dependent 108b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif template<int I> 109b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif struct Lookup {}; 110b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif 111b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif template<bool B, typename T, typename E> 112b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif struct Cond { 113b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif T foo() { return B ? T() : E(); } 114b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif typedef Lookup<sizeof(B ? T() : E())> Type; 115b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif }; 116b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif 117b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif //Cond<true, int*, double> C; // Errors 118b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif //int V(C.foo()); // Errors 119b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif //typedef Cond<true, int*, double>::Type Type; // Errors + CRASHES! 120b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif typedef Cond<true, int, double>::Type Type; 121b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif} 122b4f9090cc19ca3502fd895def9769d9c5a5a06c2Gabor Greif 123