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