Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Index / Core / index-dependent-source.cpp
blobeabec29a1fd7b30e1635ac7efba0892d88011cc8
1 // XFAIL: target={{.*}}-aix{{.*}}
2 // RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
4 int invalid;
6 class Base {
7 void baseFunction();
9 int baseField;
11 static void staticBaseFunction();
14 template<typename T>
15 class BaseTemplate {
16 public:
17 T baseTemplateFunction();
19 T baseTemplateField;
21 static T baseTemplateVariable;
24 template<typename T, typename S>
25 class TemplateClass: public Base , public BaseTemplate<T> {
26 public:
27 ~TemplateClass();
29 T function() { }
31 static void staticFunction() { }
33 T field;
35 static T variable;
37 struct Struct { };
39 enum Enum { EnumValue };
41 using TypeAlias = S;
42 typedef T Typedef;
44 void overload1(const T &);
45 void overload1(const S &);
48 template<typename T, typename S>
49 void indexSimpleDependentDeclarations(const TemplateClass<T, S> &object) {
50 // Valid instance members:
51 object.function();
52 // CHECK: [[@LINE-1]]:10 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
53 object.field;
54 // CHECK: [[@LINE-1]]:10 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 1
55 object.baseFunction();
56 // CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseFunction | c:@S@Base@F@baseFunction# | __ZN4Base12baseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1
57 object.baseField;
58 // CHECK: [[@LINE-1]]:10 | field/C++ | baseField | c:@S@Base@FI@baseField | <no-cgname> | Ref,RelCont | rel: 1
59 object.baseTemplateFunction();
60 // CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
61 object.baseTemplateField;
62 // CHECK: [[@LINE-1]]:10 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 1
64 // Invalid instance members:
65 object.variable;
66 // CHECK-NOT: [[@LINE-1]]:10
67 object.staticFunction();
68 // CHECK-NOT: [[@LINE-1]]:10
69 object.Struct;
70 // CHECK-NOT: [[@LINE-1]]:10
71 object.EnumValue;
72 // CHECK-NOT: [[@LINE-1]]:10
74 // Valid static members:
75 TemplateClass<T, S>::staticFunction();
76 // 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
77 TemplateClass<T, S>::variable;
78 // CHECK: [[@LINE-1]]:24 | static-property/C++ | variable | c:@ST>2#T#T@TemplateClass@variable | __ZN13TemplateClass8variableE | Ref,RelCont | rel: 1
79 TemplateClass<T, S>::staticBaseFunction();
80 // CHECK: [[@LINE-1]]:24 | static-method/C++ | staticBaseFunction | c:@S@Base@F@staticBaseFunction#S | __ZN4Base18staticBaseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1
81 TemplateClass<T, S>::baseTemplateVariable;
82 // CHECK: [[@LINE-1]]:24 | static-property/C++ | baseTemplateVariable | c:@ST>1#T@BaseTemplate@baseTemplateVariable | __ZN12BaseTemplate20baseTemplateVariableE | Ref,RelCont | rel: 1
83 TemplateClass<T, S>::EnumValue;
84 // CHECK: [[@LINE-1]]:24 | enumerator/C | EnumValue | c:@ST>2#T#T@TemplateClass@E@Enum@EnumValue | <no-cgname> | Ref,RelCont | rel: 1
85 TemplateClass<T, S>::Struct();
86 // CHECK: [[@LINE-1]]:24 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
88 // Invalid static members:
89 TemplateClass<T, S>::field;
90 // CHECK-NOT: [[@LINE-1]]:24
91 TemplateClass<T, S>::function();
92 // CHECK-NOT: [[@LINE-1]]:24
94 // Valid type names:
95 typename TemplateClass<T, S>::Struct Val;
96 // CHECK: [[@LINE-1]]:33 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,RelCont | rel: 1
97 typename TemplateClass<T, S>::Enum EnumVal;
98 // CHECK: [[@LINE-1]]:33 | enum/C | Enum | c:@ST>2#T#T@TemplateClass@E@Enum | <no-cgname> | Ref,RelCont | rel: 1
99 typename TemplateClass<T, S>::TypeAlias Val2;
100 // CHECK: [[@LINE-1]]:33 | type-alias/C++ | TypeAlias | c:@ST>2#T#T@TemplateClass@TypeAlias | <no-cgname> | Ref,RelCont | rel: 1
101 typename TemplateClass<T, S>::Typedef Val3;
102 // 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
104 // Invalid type names:
105 typename TemplateClass<T, S>::field Val4;
106 // CHECK-NOT: [[@LINE-1]]:33
107 typename TemplateClass<T, S>::staticFunction Val5;
108 // CHECK-NOT: [[@LINE-1]]:33
111 object.invalid;
112 // CHECK-NOT: [[@LINE-1]]:10
113 TemplateClass<T, S>::invalid;
114 // CHECK-NOT: [[@LINE-1]]:24
117 template<typename T, typename S, typename Y>
118 void indexDependentOverloads(const TemplateClass<T, S> &object) {
119 object.overload1(T());
120 // CHECK-NOT: [[@LINE-1]]
121 object.overload1(S());
122 // CHECK-NOT: [[@LINE-1]]
123 object.overload1(Y());
124 // CHECK-NOT: [[@LINE-1]]
127 template<typename T> struct UndefinedTemplateClass;
129 template<typename T>
130 void undefinedTemplateLookup(UndefinedTemplateClass<T> &x) {
131 // Shouldn't crash!
132 x.lookup;
133 typename UndefinedTemplateClass<T>::Type y;
136 template<typename T>
137 struct UserOfUndefinedTemplateClass: UndefinedTemplateClass<T> { };
139 template<typename T>
140 void undefinedTemplateLookup2(UserOfUndefinedTemplateClass<T> &x) {
141 // Shouldn't crash!
142 x.lookup;
143 typename UserOfUndefinedTemplateClass<T>::Type y;
146 template<typename T> struct Dropper;
148 template<typename T> struct Trait;
150 template<typename T>
151 struct Recurse : Trait<typename Dropper<T>::Type> { };
153 template<typename T>
154 struct Trait : Recurse<T> {
157 template<typename T>
158 void infiniteTraitRecursion(Trait<T> &t) {
159 // Shouldn't crash!
160 t.lookup;
163 template <typename T>
164 struct UsingA {
165 // 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
166 typedef int Type;
167 // CHECK: [[@LINE+1]]:15 | static-method/C++ | func | c:@ST>1#T@UsingA@F@func#S | <no-cgname> | Decl,RelChild | rel: 1
168 static void func();
169 // CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator() | c:@ST>1#T@UsingA@F@operator()#I# | <no-cgname> | Decl,RelChild | rel: 1
170 void operator()(int);
171 // 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
172 void operator+(const UsingA &);
175 template <typename T>
176 struct OtherUsing {};
178 template <typename T>
179 struct UsingB : public UsingA<T> {
180 // 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
181 // CHECK: [[@LINE+1]]:20 | struct(Gen)/C++ | OtherUsing | c:@ST>1#T@OtherUsing | <no-cgname> | Ref,RelCont | rel: 1
182 typedef typename OtherUsing<T>::Type TypeB;
183 // 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
184 // CHECK: [[@LINE+1]]:18 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
185 using typename UsingA<T>::Type;
186 // 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
187 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
188 using UsingA<T>::func;
190 // 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
191 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
192 using UsingA<T>::operator();
193 // 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
194 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
195 using UsingA<T>::operator+;
198 template <typename T>
199 struct UsingC : public UsingB<T> {
200 static void test() {
201 // 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
202 // CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
203 typename UsingB<T>::TypeB value1;
204 // 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
205 // CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
206 typename UsingB<T>::Type value2;
207 // 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
208 // CHECK: [[@LINE+1]]:5 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
209 UsingB<T>::func();
213 template <typename T>
214 struct UsingD {
215 // CHECK: [[@LINE+1]]:8 | instance-method/C++ | foo | c:@ST>1#T@UsingD@F@foo#t0.0# | <no-cgname> | Decl,RelChild | rel: 1
216 void foo(T);
219 template <typename T, typename U>
220 struct UsingE : public UsingD<T>, public UsingD<U> {
221 // 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
222 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1
223 using UsingD<T>::foo;
224 // 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
225 // CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1
226 using UsingD<U>::foo;
229 template <typename T> void foo();
230 // CHECK: [[@LINE-1]]:28 | function/C | foo | c:@FT@>1#Tfoo#v# | <no-cgname> | Decl | rel: 0
231 template <typename T> void bar() {
232 foo<T>();
233 // CHECK: [[@LINE-1]]:3 | function/C | foo | c:@FT@>1#Tfoo#v# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
236 struct Foo {
237 template <typename T> void bar();
238 // CHECK: [[@LINE-1]]:30 | instance-method/C++ | bar | c:@S@Foo@FT@>1#Tbar#v# | <no-cgname> | Decl,RelChild | rel: 1
240 template <typename T> void baz(Foo f) {
241 f.bar<T>();
242 // CHECK: [[@LINE-1]]:5 | instance-method/C++ | bar | c:@S@Foo@FT@>1#Tbar#v# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1