1 // RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s 2 3 int invalid; 4 5 class Base { 6 void baseFunction(); 7 8 int baseField; 9 10 static void staticBaseFunction(); 11 }; 12 13 template<typename T> 14 class BaseTemplate { 15 public: 16 T baseTemplateFunction(); 17 18 T baseTemplateField; 19 20 static T baseTemplateVariable; 21 }; 22 23 template<typename T, typename S> 24 class TemplateClass: public Base , public BaseTemplate<T> { 25 public: 26 ~TemplateClass(); 27 28 T function() { } 29 30 static void staticFunction() { } 31 32 T field; 33 34 static T variable; 35 36 struct Struct { }; 37 38 enum Enum { EnumValue }; 39 40 using TypeAlias = S; 41 typedef T Typedef; 42 43 void overload1(const T &); 44 void overload1(const S &); 45 }; 46 47 template<typename T, typename S> 48 void indexSimpleDependentDeclarations(const TemplateClass<T, S> &object) { 49 // Valid instance members: 50 object.function(); 51 // CHECK: [[@LINE-1]]:10 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1 52 object.field; 53 // CHECK: [[@LINE-1]]:10 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 1 54 object.baseFunction(); 55 // CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseFunction | c:@S@Base@F@baseFunction# | __ZN4Base12baseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1 56 object.baseField; 57 // CHECK: [[@LINE-1]]:10 | field/C++ | baseField | c:@S@Base@FI@baseField | <no-cgname> | Ref,RelCont | rel: 1 58 object.baseTemplateFunction(); 59 // CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1 60 object.baseTemplateField; 61 // CHECK: [[@LINE-1]]:10 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 1 62 63 // Invalid instance members: 64 object.variable; 65 // CHECK-NOT: [[@LINE-1]]:10 66 object.staticFunction(); 67 // CHECK-NOT: [[@LINE-1]]:10 68 object.Struct; 69 // CHECK-NOT: [[@LINE-1]]:10 70 object.EnumValue; 71 // CHECK-NOT: [[@LINE-1]]:10 72 73 // Valid static members: 74 TemplateClass<T, S>::staticFunction(); 75 // CHECK: [[@LINE-1]]:24 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1 76 TemplateClass<T, S>::variable; 77 // CHECK: [[@LINE-1]]:24 | static-property/C++ | variable | c:@ST>2#T#T@TemplateClass@variable | __ZN13TemplateClass8variableE | Ref,RelCont | rel: 1 78 TemplateClass<T, S>::staticBaseFunction(); 79 // CHECK: [[@LINE-1]]:24 | static-method/C++ | staticBaseFunction | c:@S@Base@F@staticBaseFunction#S | __ZN4Base18staticBaseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1 80 TemplateClass<T, S>::baseTemplateVariable; 81 // CHECK: [[@LINE-1]]:24 | static-property/C++ | baseTemplateVariable | c:@ST>1#T@BaseTemplate@baseTemplateVariable | __ZN12BaseTemplate20baseTemplateVariableE | Ref,RelCont | rel: 1 82 TemplateClass<T, S>::EnumValue; 83 // CHECK: [[@LINE-1]]:24 | enumerator/C | EnumValue | c:@ST>2#T#T@TemplateClass@E@Enum@EnumValue | <no-cgname> | Ref,RelCont | rel: 1 84 TemplateClass<T, S>::Struct(); 85 // CHECK: [[@LINE-1]]:24 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1 86 87 // Invalid static members: 88 TemplateClass<T, S>::field; 89 // CHECK-NOT: [[@LINE-1]]:24 90 TemplateClass<T, S>::function(); 91 // CHECK-NOT: [[@LINE-1]]:24 92 93 // Valid type names: 94 typename TemplateClass<T, S>::Struct Val; 95 // CHECK: [[@LINE-1]]:33 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,RelCont | rel: 1 96 typename TemplateClass<T, S>::Enum EnumVal; 97 // CHECK: [[@LINE-1]]:33 | enum/C | Enum | c:@ST>2#T#T@TemplateClass@E@Enum | <no-cgname> | Ref,RelCont | rel: 1 98 typename TemplateClass<T, S>::TypeAlias Val2; 99 // CHECK: [[@LINE-1]]:33 | type-alias/C++ | TypeAlias | c:@ST>2#T#T@TemplateClass@TypeAlias | <no-cgname> | Ref,RelCont | rel: 1 100 typename TemplateClass<T, S>::Typedef Val3; 101 // CHECK: [[@LINE-1]]:33 | type-alias/C | Typedef | c:{{.*}}index-dependent-source.cpp@ST>2#T#T@TemplateClass@T@Typedef | <no-cgname> | Ref,RelCont | rel: 1 102 103 // Invalid type names: 104 typename TemplateClass<T, S>::field Val4; 105 // CHECK-NOT: [[@LINE-1]]:33 106 typename TemplateClass<T, S>::staticFunction Val5; 107 // CHECK-NOT: [[@LINE-1]]:33 108 109 110 object.invalid; 111 // CHECK-NOT: [[@LINE-1]]:10 112 TemplateClass<T, S>::invalid; 113 // CHECK-NOT: [[@LINE-1]]:24 114 } 115 116 template<typename T, typename S, typename Y> 117 void indexDependentOverloads(const TemplateClass<T, S> &object) { 118 object.overload1(T()); 119 // CHECK-NOT: [[@LINE-1]] 120 object.overload1(S()); 121 // CHECK-NOT: [[@LINE-1]] 122 object.overload1(Y()); 123 // CHECK-NOT: [[@LINE-1]] 124 } 125 126 template<typename T> struct UndefinedTemplateClass; 127 128 template<typename T> 129 void undefinedTemplateLookup(UndefinedTemplateClass<T> &x) { 130 // Shouldn't crash! 131 x.lookup; 132 typename UndefinedTemplateClass<T>::Type y; 133 } 134 135 template<typename T> 136 struct UserOfUndefinedTemplateClass: UndefinedTemplateClass<T> { }; 137 138 template<typename T> 139 void undefinedTemplateLookup2(UserOfUndefinedTemplateClass<T> &x) { 140 // Shouldn't crash! 141 x.lookup; 142 typename UserOfUndefinedTemplateClass<T>::Type y; 143 } 144 145 template<typename T> struct Dropper; 146 147 template<typename T> struct Trait; 148 149 template<typename T> 150 struct Recurse : Trait<typename Dropper<T>::Type> { }; 151 152 template<typename T> 153 struct Trait : Recurse<T> { 154 }; 155 156 template<typename T> 157 void infiniteTraitRecursion(Trait<T> &t) { 158 // Shouldn't crash! 159 t.lookup; 160 } 161 162 template <typename T> 163 struct UsingA { 164 // CHECK: [[@LINE+1]]:15 | type-alias/C | Type | c:index-dependent-source.cpp@ST>1#T@UsingA@T@Type | <no-cgname> | Def,RelChild | rel: 1 165 typedef int Type; 166 // CHECK: [[@LINE+1]]:15 | static-method/C++ | func | c:@ST>1#T@UsingA@F@func#S | <no-cgname> | Decl,RelChild | rel: 1 167 static void func(); 168 // CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator() | c:@ST>1#T@UsingA@F@operator()#I# | <no-cgname> | Decl,RelChild | rel: 1 169 void operator()(int); 170 // CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator+ | c:@ST>1#T@UsingA@F@operator+#&1>@ST>1#[email protected]# | <no-cgname> | Decl,RelChild | rel: 1 171 void operator+(const UsingA &); 172 }; 173 174 template <typename T> 175 struct OtherUsing {}; 176 177 template <typename T> 178 struct UsingB : public UsingA<T> { 179 // CHECK: [[@LINE+2]]:40 | type-alias/C | TypeB | c:index-dependent-source.cpp@ST>1#T@UsingB@T@TypeB | <no-cgname> | Def,RelChild | rel: 1 180 // CHECK: [[@LINE+1]]:20 | struct(Gen)/C++ | OtherUsing | c:@ST>1#T@OtherUsing | <no-cgname> | Ref,RelCont | rel: 1 181 typedef typename OtherUsing<T>::Type TypeB; 182 // CHECK: [[@LINE+2]]:29 | using/using-typename(Gen)/C++ | Type | c:index-dependent-source.cpp@ST>1#T@UsingB@UUT@UsingA<T>::Type | <no-cgname> | Decl,RelChild | rel: 1 183 // CHECK: [[@LINE+1]]:18 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1 184 using typename UsingA<T>::Type; 185 // CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | func | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::func | <no-cgname> | Decl,RelChild | rel: 1 186 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1 187 using UsingA<T>::func; 188 189 // CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | operator() | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::operator() | <no-cgname> | Decl,RelChild | rel: 1 190 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1 191 using UsingA<T>::operator(); 192 // CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | operator+ | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::operator+ | <no-cgname> | Decl,RelChild | rel: 1 193 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1 194 using UsingA<T>::operator+; 195 }; 196 197 template <typename T> 198 struct UsingC : public UsingB<T> { 199 static void test() { 200 // CHECK: [[@LINE+2]]:25 | type-alias/C | TypeB | c:index-dependent-source.cpp@ST>1#T@UsingB@T@TypeB | <no-cgname> | Ref,RelCont | rel: 1 201 // CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1 202 typename UsingB<T>::TypeB value1; 203 // CHECK: [[@LINE+2]]:25 | using/using-typename(Gen)/C++ | Type | c:index-dependent-source.cpp@ST>1#T@UsingB@UUT@UsingA<T>::Type | <no-cgname> | Ref,RelCont | rel: 1 204 // CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1 205 typename UsingB<T>::Type value2; 206 // CHECK: [[@LINE+2]]:16 | using/using-value(Gen)/C++ | func | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::func | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1 207 // CHECK: [[@LINE+1]]:5 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1 208 UsingB<T>::func(); 209 } 210 }; 211 212 template <typename T> 213 struct UsingD { 214 // CHECK: [[@LINE+1]]:8 | instance-method/C++ | foo | c:@ST>1#T@UsingD@F@foo#t0.0# | <no-cgname> | Decl,RelChild | rel: 1 215 void foo(T); 216 }; 217 218 template <typename T, typename U> 219 struct UsingE : public UsingD<T>, public UsingD<U> { 220 // CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | foo | c:index-dependent-source.cpp@ST>2#T#T@UsingE@UUV@UsingD<T>::foo | <no-cgname> | Decl,RelChild | rel: 1 221 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1 222 using UsingD<T>::foo; 223 // CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | foo | c:index-dependent-source.cpp@ST>2#T#T@UsingE@UUV@UsingD<U>::foo | <no-cgname> | Decl,RelChild | rel: 1 224 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1 225 using UsingD<U>::foo; 226 }; 227 228 template <typename T> void foo(); 229 // CHECK: [[@LINE-1]]:28 | function/C | foo | c:@FT@>1#Tfoo#v# | <no-cgname> | Decl | rel: 0 230 template <typename T> void bar() { 231 foo<T>(); 232 // CHECK: [[@LINE-1]]:3 | function/C | foo | c:@FT@>1#Tfoo#v# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1 233 } 234