Clang Project

clang_source_code/test/Index/Core/index-dependent-source.cpp
1// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
2
3int invalid;
4
5class Base {
6  void baseFunction();
7
8  int baseField;
9
10  static void staticBaseFunction();
11};
12
13template<typename T>
14class BaseTemplate {
15public:
16  T baseTemplateFunction();
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() { }
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# | <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
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: 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#T@UsingA1t0.0# | <no-cgname> | Decl,RelChild | rel: 1
171  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: 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
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: 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
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: 1
215  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: 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