1f4a2713aSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -O1 -disable-llvm-optzns %s -o - | FileCheck %s 2f4a2713aSLionel Sambuc 3f4a2713aSLionel Sambuc namespace test1 { 4*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN5test11fIZNS_1gEvE1SEEvT_( f(T)5f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()6f4a2713aSLionel Sambuc inline void *g() { 7f4a2713aSLionel Sambuc struct S { 8f4a2713aSLionel Sambuc } s; 9f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<S>); 10f4a2713aSLionel Sambuc } h()11f4a2713aSLionel Sambuc void *h() { return g(); } 12f4a2713aSLionel Sambuc } 13f4a2713aSLionel Sambuc 14f4a2713aSLionel Sambuc namespace test2 { 15*0a6a1f1dSLionel Sambuc // CHECK-DAG: define internal void @_ZN5test21fIZNS_L1gEvE1SEEvT_( f(T)16f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()17f4a2713aSLionel Sambuc static inline void *g() { 18f4a2713aSLionel Sambuc struct S { 19f4a2713aSLionel Sambuc } s; 20f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<S>); 21f4a2713aSLionel Sambuc } h()22f4a2713aSLionel Sambuc void *h() { return g(); } 23f4a2713aSLionel Sambuc } 24f4a2713aSLionel Sambuc 25f4a2713aSLionel Sambuc namespace test3 { 26*0a6a1f1dSLionel Sambuc // CHECK-DAG: define internal void @_ZN5test31fIZNS_1gEvE1SEEvT_( f(T)27f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()28f4a2713aSLionel Sambuc void *g() { 29f4a2713aSLionel Sambuc struct S { 30f4a2713aSLionel Sambuc } s; 31f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<S>); 32f4a2713aSLionel Sambuc } h()33f4a2713aSLionel Sambuc void *h() { return g(); } 34f4a2713aSLionel Sambuc } 35f4a2713aSLionel Sambuc 36f4a2713aSLionel Sambuc namespace test4 { 37*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN5test41fIZNS_1gILi1EEEPvvE1SEEvT_( f(T)38f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()39f4a2713aSLionel Sambuc template <int N> inline void *g() { 40f4a2713aSLionel Sambuc struct S { 41f4a2713aSLionel Sambuc } s; 42f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<S>); 43f4a2713aSLionel Sambuc } 44f4a2713aSLionel Sambuc extern template void *g<1>(); 45f4a2713aSLionel Sambuc template void *g<1>(); 46f4a2713aSLionel Sambuc } 47f4a2713aSLionel Sambuc 48f4a2713aSLionel Sambuc namespace test5 { 49*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN5test51fIZNS_1gILi1EEEPvvE1SEEvT_( f(T)50f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()51f4a2713aSLionel Sambuc template <int N> inline void *g() { 52f4a2713aSLionel Sambuc struct S { 53f4a2713aSLionel Sambuc } s; 54f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<S>); 55f4a2713aSLionel Sambuc } 56f4a2713aSLionel Sambuc extern template void *g<1>(); h()57f4a2713aSLionel Sambuc void *h() { return g<1>(); } 58f4a2713aSLionel Sambuc } 59f4a2713aSLionel Sambuc 60f4a2713aSLionel Sambuc namespace test6 { 61*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN5test61fIZZNS_1gEvEN1S1hEvE1TEEvv( f()62f4a2713aSLionel Sambuc template <typename T> void f() {} 63f4a2713aSLionel Sambuc g()64f4a2713aSLionel Sambuc inline void *g() { 65f4a2713aSLionel Sambuc struct S { 66f4a2713aSLionel Sambuc void *h() { 67f4a2713aSLionel Sambuc struct T { 68f4a2713aSLionel Sambuc }; 69f4a2713aSLionel Sambuc return (void *)f<T>; 70f4a2713aSLionel Sambuc } 71f4a2713aSLionel Sambuc } s; 72f4a2713aSLionel Sambuc return s.h(); 73f4a2713aSLionel Sambuc } 74f4a2713aSLionel Sambuc h()75f4a2713aSLionel Sambuc void *h() { return g(); } 76f4a2713aSLionel Sambuc } 77f4a2713aSLionel Sambuc 78f4a2713aSLionel Sambuc namespace test7 { 79*0a6a1f1dSLionel Sambuc // CHECK-DAG: define internal void @_ZN5test71fIZZNS_1gEvEN1S1hEvE1TEEvv( f()80f4a2713aSLionel Sambuc template <typename T> void f() {} 81f4a2713aSLionel Sambuc g()82f4a2713aSLionel Sambuc void *g() { 83f4a2713aSLionel Sambuc struct S { 84f4a2713aSLionel Sambuc void *h() { 85f4a2713aSLionel Sambuc struct T { 86f4a2713aSLionel Sambuc }; 87f4a2713aSLionel Sambuc return (void *)f<T>; 88f4a2713aSLionel Sambuc } 89f4a2713aSLionel Sambuc } s; 90f4a2713aSLionel Sambuc return s.h(); 91f4a2713aSLionel Sambuc } 92f4a2713aSLionel Sambuc h()93f4a2713aSLionel Sambuc void *h() { return g(); } 94f4a2713aSLionel Sambuc } 95f4a2713aSLionel Sambuc 96f4a2713aSLionel Sambuc namespace test8 { 97*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN5test81fIZNS_1gEvE1SEEvT_( f(T)98f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()99f4a2713aSLionel Sambuc inline void *g() { 100f4a2713aSLionel Sambuc enum S { 101f4a2713aSLionel Sambuc }; 102f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<S>); 103f4a2713aSLionel Sambuc } h()104f4a2713aSLionel Sambuc void *h() { return g(); } 105f4a2713aSLionel Sambuc } 106f4a2713aSLionel Sambuc 107f4a2713aSLionel Sambuc namespace test9 { 108*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN5test91fIPZNS_1gEvE1SEEvT_( f(T)109f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()110f4a2713aSLionel Sambuc inline void *g() { 111f4a2713aSLionel Sambuc struct S { 112f4a2713aSLionel Sambuc } s; 113f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<S*>); 114f4a2713aSLionel Sambuc } h()115f4a2713aSLionel Sambuc void *h() { return g(); } 116f4a2713aSLionel Sambuc } 117f4a2713aSLionel Sambuc 118f4a2713aSLionel Sambuc namespace test10 { 119*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN6test101fIPFZNS_1gEvE1SvEEEvT_( f(T)120f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()121f4a2713aSLionel Sambuc inline void *g() { 122f4a2713aSLionel Sambuc struct S { 123f4a2713aSLionel Sambuc } s; 124f4a2713aSLionel Sambuc typedef S(*ftype)(); 125f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<ftype>); 126f4a2713aSLionel Sambuc } h()127f4a2713aSLionel Sambuc void *h() { return g(); } 128f4a2713aSLionel Sambuc } 129f4a2713aSLionel Sambuc 130f4a2713aSLionel Sambuc namespace test11 { 131*0a6a1f1dSLionel Sambuc // CHECK-DAG: define internal void @_ZN6test111fIPFZNS_1gEvE1SPNS_12_GLOBAL__N_11IEEEEvT_( 132f4a2713aSLionel Sambuc namespace { 133f4a2713aSLionel Sambuc struct I { 134f4a2713aSLionel Sambuc }; 135f4a2713aSLionel Sambuc } 136f4a2713aSLionel Sambuc f(T)137f4a2713aSLionel Sambuc template <typename T> void f(T) {} g()138f4a2713aSLionel Sambuc inline void *g() { 139f4a2713aSLionel Sambuc struct S { 140f4a2713aSLionel Sambuc }; 141f4a2713aSLionel Sambuc typedef S(*ftype)(I * x); 142f4a2713aSLionel Sambuc return reinterpret_cast<void *>(f<ftype>); 143f4a2713aSLionel Sambuc } h()144f4a2713aSLionel Sambuc void *h() { return g(); } 145f4a2713aSLionel Sambuc } 146f4a2713aSLionel Sambuc 147f4a2713aSLionel Sambuc namespace test12 { 148*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN6test123fooIZNS_3barIZNS_3zedEvE2S2EEPvvE2S1EEvv foo()149f4a2713aSLionel Sambuc template <typename T> void foo() {} bar()150f4a2713aSLionel Sambuc template <typename T> inline void *bar() { 151f4a2713aSLionel Sambuc enum S1 { 152f4a2713aSLionel Sambuc }; 153f4a2713aSLionel Sambuc return reinterpret_cast<void *>(foo<S1>); 154f4a2713aSLionel Sambuc } zed()155f4a2713aSLionel Sambuc inline void *zed() { 156f4a2713aSLionel Sambuc enum S2 { 157f4a2713aSLionel Sambuc }; 158f4a2713aSLionel Sambuc return reinterpret_cast<void *>(bar<S2>); 159f4a2713aSLionel Sambuc } h()160f4a2713aSLionel Sambuc void *h() { return zed(); } 161f4a2713aSLionel Sambuc } 162f4a2713aSLionel Sambuc 163f4a2713aSLionel Sambuc namespace test13 { 164*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZZN6test133fooEvEN1S3barEv( foo()165f4a2713aSLionel Sambuc inline void *foo() { 166f4a2713aSLionel Sambuc struct S { 167f4a2713aSLionel Sambuc static void bar() {} 168f4a2713aSLionel Sambuc }; 169f4a2713aSLionel Sambuc return (void *)S::bar; 170f4a2713aSLionel Sambuc } zed()171f4a2713aSLionel Sambuc void *zed() { return foo(); } 172f4a2713aSLionel Sambuc } 173f4a2713aSLionel Sambuc 174f4a2713aSLionel Sambuc namespace test14 { 175*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN6test143fooIZNS_1fEvE1SE3barILPS1_0EEEvv( 176f4a2713aSLionel Sambuc template <typename T> struct foo { bartest14::foo177f4a2713aSLionel Sambuc template <T *P> static void bar() {} gtest14::foo178f4a2713aSLionel Sambuc static void *g() { return (void *)bar<nullptr>; } 179f4a2713aSLionel Sambuc }; f()180f4a2713aSLionel Sambuc inline void *f() { 181f4a2713aSLionel Sambuc struct S { 182f4a2713aSLionel Sambuc }; 183f4a2713aSLionel Sambuc return foo<S>::g(); 184f4a2713aSLionel Sambuc } h()185f4a2713aSLionel Sambuc void h() { f(); } 186f4a2713aSLionel Sambuc } 187f4a2713aSLionel Sambuc 188f4a2713aSLionel Sambuc namespace test15 { 189*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN6test153zedIZNS_3fooIiEEPvvE3barEEvv( zed()190f4a2713aSLionel Sambuc template <class T> void zed() {} foo()191f4a2713aSLionel Sambuc template <class T> void *foo() { 192f4a2713aSLionel Sambuc class bar { 193f4a2713aSLionel Sambuc }; 194f4a2713aSLionel Sambuc return reinterpret_cast<void *>(zed<bar>); 195f4a2713aSLionel Sambuc } test()196f4a2713aSLionel Sambuc void test() { foo<int>(); } 197f4a2713aSLionel Sambuc } 198f4a2713aSLionel Sambuc 199f4a2713aSLionel Sambuc namespace test16 { 200*0a6a1f1dSLionel Sambuc // CHECK-DAG: define linkonce_odr void @_ZN6test163zedIZNS_3fooIiE3barEvE1SEEvv( zed()201f4a2713aSLionel Sambuc template <class T> void zed() {} 202f4a2713aSLionel Sambuc template <class T> struct foo { 203f4a2713aSLionel Sambuc static void *bar(); 204f4a2713aSLionel Sambuc }; bar()205f4a2713aSLionel Sambuc template <class T> void *foo<T>::bar() { 206f4a2713aSLionel Sambuc class S { 207f4a2713aSLionel Sambuc }; 208f4a2713aSLionel Sambuc return reinterpret_cast<void *>(zed<S>); 209f4a2713aSLionel Sambuc } test()210f4a2713aSLionel Sambuc void *test() { return foo<int>::bar(); } 211f4a2713aSLionel Sambuc } 212f4a2713aSLionel Sambuc 213f4a2713aSLionel Sambuc namespace test17 { 214f4a2713aSLionel Sambuc // CHECK-DAG: @_ZZN6test173fooILi42EEEPivE3bar = linkonce_odr 215*0a6a1f1dSLionel Sambuc // CHECK-DAG: define weak_odr i32* @_ZN6test173fooILi42EEEPiv( 216f4a2713aSLionel Sambuc template<int I> foo()217f4a2713aSLionel Sambuc int *foo() { 218f4a2713aSLionel Sambuc static int bar; 219f4a2713aSLionel Sambuc return &bar; 220f4a2713aSLionel Sambuc } 221f4a2713aSLionel Sambuc template int *foo<42>(); 222f4a2713aSLionel Sambuc } 223*0a6a1f1dSLionel Sambuc 224*0a6a1f1dSLionel Sambuc // PR18408 225*0a6a1f1dSLionel Sambuc namespace test18 { 226*0a6a1f1dSLionel Sambuc template<template<typename> class> struct A {}; 227*0a6a1f1dSLionel Sambuc struct B { template<typename> struct C; }; f(A<B::C>)228*0a6a1f1dSLionel Sambuc void f(A<B::C>) {} 229*0a6a1f1dSLionel Sambuc // CHECK-DAG: define void @_ZN6test181fENS_1AINS_1B1CEEE( 230*0a6a1f1dSLionel Sambuc } 231