243 lines · cpp
1// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s2 3int invalid;4 5class Base {6 void baseFunction() const;7 8 int baseField;9 10 static void staticBaseFunction();11};12 13template<typename T>14class BaseTemplate {15public:16 T baseTemplateFunction() const;17 18 T baseTemplateField;19 20 static T baseTemplateVariable;21};22 23template<typename T, typename S>24class TemplateClass: public Base , public BaseTemplate<T> {25public:26 ~TemplateClass();27 28 T function() const { }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 47template<typename T, typename S>48void 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#1 | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 152 object.field;53// CHECK: [[@LINE-1]]:10 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 154 object.baseFunction();55// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseFunction | c:@S@Base@F@baseFunction#1 | __ZNK4Base12baseFunctionEv | Ref,Call,RelCall,RelCont | rel: 156 object.baseField;57// CHECK: [[@LINE-1]]:10 | field/C++ | baseField | c:@S@Base@FI@baseField | <no-cgname> | Ref,RelCont | rel: 158 object.baseTemplateFunction();59// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction#1 | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 160 object.baseTemplateField;61// CHECK: [[@LINE-1]]:10 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 162 63 // Static members (these are still valid to access via an instance):64 object.variable;65// CHECK: [[@LINE-1]]:10 | static-property/C++ | variable | c:@ST>2#T#T@TemplateClass@variable | __ZN13TemplateClass8variableE | Ref,RelCont | rel: 166 object.staticFunction();67// CHECK: [[@LINE-1]]:10 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 168 object.Struct;69// CHECK: [[@LINE-1]]:10 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,RelCont | rel: 170 object.EnumValue;71// CHECK: [[@LINE-1]]:10 | enumerator/C | EnumValue | c:@ST>2#T#T@TemplateClass@E@Enum@EnumValue | <no-cgname> | Ref,RelCont | rel: 172 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: 176 TemplateClass<T, S>::variable;77// CHECK: [[@LINE-1]]:24 | static-property/C++ | variable | c:@ST>2#T#T@TemplateClass@variable | __ZN13TemplateClass8variableE | Ref,RelCont | rel: 178 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: 180 TemplateClass<T, S>::baseTemplateVariable;81// CHECK: [[@LINE-1]]:24 | static-property/C++ | baseTemplateVariable | c:@ST>1#T@BaseTemplate@baseTemplateVariable | __ZN12BaseTemplate20baseTemplateVariableE | Ref,RelCont | rel: 182 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: 184 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: 186 87 // Invalid static members:88 TemplateClass<T, S>::field;89// CHECK-NOT: [[@LINE-1]]:2490 TemplateClass<T, S>::function();91// CHECK-NOT: [[@LINE-1]]:2492 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: 196 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: 198 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: 1100 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: 1102 103 // Invalid type names:104 typename TemplateClass<T, S>::field Val4;105// CHECK-NOT: [[@LINE-1]]:33106 typename TemplateClass<T, S>::staticFunction Val5;107// CHECK-NOT: [[@LINE-1]]:33108 109 110 object.invalid;111// CHECK-NOT: [[@LINE-1]]:10112 TemplateClass<T, S>::invalid;113// CHECK-NOT: [[@LINE-1]]:24114}115 116template<typename T, typename S, typename Y>117void 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 126template<typename T> struct UndefinedTemplateClass;127 128template<typename T>129void undefinedTemplateLookup(UndefinedTemplateClass<T> &x) {130// Shouldn't crash!131 x.lookup;132 typename UndefinedTemplateClass<T>::Type y;133}134 135template<typename T>136struct UserOfUndefinedTemplateClass: UndefinedTemplateClass<T> { };137 138template<typename T>139void undefinedTemplateLookup2(UserOfUndefinedTemplateClass<T> &x) {140// Shouldn't crash!141 x.lookup;142 typename UserOfUndefinedTemplateClass<T>::Type y;143}144 145template<typename T> struct Dropper;146 147template<typename T> struct Trait;148 149template<typename T>150struct Recurse : Trait<typename Dropper<T>::Type> { };151 152template<typename T>153struct Trait : Recurse<T> {154};155 156template<typename T>157void infiniteTraitRecursion(Trait<T> &t) {158// Shouldn't crash!159 t.lookup;160}161 162template <typename T>163struct 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: 1165 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: 1167 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: 1169 void operator()(int);170// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator+ | c:@ST>1#T@UsingA@F@operator+#&1>@ST>1#T@UsingA1t0.0# | <no-cgname> | Decl,RelChild | rel: 1171 void operator+(const UsingA &);172};173 174template <typename T>175struct OtherUsing {};176 177template <typename T>178struct 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: 1180// CHECK: [[@LINE+1]]:20 | struct(Gen)/C++ | OtherUsing | c:@ST>1#T@OtherUsing | <no-cgname> | Ref,RelCont | rel: 1181 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: 1183// CHECK: [[@LINE+1]]:18 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1184 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: 1186// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1187 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: 1190// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1191 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: 1193// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1194 using UsingA<T>::operator+;195};196 197template <typename T>198struct 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: 1201// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1202 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: 1204// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1205 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: 1207// CHECK: [[@LINE+1]]:5 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1208 UsingB<T>::func();209 }210};211 212template <typename T>213struct UsingD {214// CHECK: [[@LINE+1]]:8 | instance-method/C++ | foo | c:@ST>1#T@UsingD@F@foo#t0.0# | <no-cgname> | Decl,RelChild | rel: 1215 void foo(T);216};217 218template <typename T, typename U>219struct 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: 1221// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1222 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: 1224// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1225 using UsingD<U>::foo;226};227 228template <typename T> void foo();229// CHECK: [[@LINE-1]]:28 | function/C | foo | c:@FT@>1#Tfoo#v# | <no-cgname> | Decl | rel: 0230template <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: 1233}234 235struct Foo {236 template <typename T> void bar();237 // CHECK: [[@LINE-1]]:30 | instance-method/C++ | bar | c:@S@Foo@FT@>1#Tbar#v# | <no-cgname> | Decl,RelChild | rel: 1238};239template <typename T> void baz(Foo f) {240 f.bar<T>();241 // CHECK: [[@LINE-1]]:5 | instance-method/C++ | bar | c:@S@Foo@FT@>1#Tbar#v# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1242}243