@@ -128,71 +128,200 @@ enum class CursorInfoKind {
128
128
StmtStart,
129
129
};
130
130
131
+ // / Base class of more specialized \c ResolvedCursorInfos that also represents
132
+ // / and \c Invalid cursor info.
133
+ // / Subclasses of \c ResolvedCursorInfo cannot add new stored properies because
134
+ // / \c ResolvedCursorInfo is being passed around as its base class and thus any
135
+ // / properties in subclasses would get lost.
131
136
struct ResolvedCursorInfo {
137
+ protected:
132
138
CursorInfoKind Kind = CursorInfoKind::Invalid;
133
139
SourceFile *SF = nullptr ;
134
140
SourceLoc Loc;
135
- ValueDecl *ValueD = nullptr ;
136
- TypeDecl *CtorTyRef = nullptr ;
137
- ExtensionDecl *ExtTyRef = nullptr ;
138
- // / Declarations that were shadowed by \c ValueD using a shorthand syntax that
139
- // / names both the newly declared variable and the referenced variable by the
140
- // / same identifier in the source text. This includes shorthand closure
141
- // / captures (`[foo]`) and shorthand if captures
142
- // / (`if let foo {`).
143
- // / Decls that are shadowed using shorthand syntax should be reported as
144
- // / additional cursor info results.
145
- SmallVector<ValueDecl *, 2 > ShorthandShadowedDecls;
146
- ModuleEntity Mod;
147
- bool IsRef = true ;
148
- bool IsKeywordArgument = false ;
149
- Type Ty;
150
- Type ContainerType;
151
- Stmt *TrailingStmt = nullptr ;
152
- Expr *TrailingExpr = nullptr ;
153
- // / It this is a ref, whether it is "dynamic". See \c ide::isDynamicRef.
154
- bool IsDynamic = false ;
155
- // / If this is a dynamic ref, the types of the base (multiple in the case of
156
- // / protocol composition).
157
- SmallVector<NominalTypeDecl *, 1 > ReceiverTypes;
158
141
142
+ // Technically, these structs could form a union (because only one of them is
143
+ // active at a time). But I had issues with C++ complaining about copy
144
+ // constructors and gave up. At the moment it's only wasting 3 words for non
145
+ // ValueRef data.
146
+ struct {
147
+ ValueDecl *ValueD = nullptr ;
148
+ TypeDecl *CtorTyRef = nullptr ;
149
+ ExtensionDecl *ExtTyRef = nullptr ;
150
+ bool IsRef = true ;
151
+ Type Ty;
152
+ Type ContainerType;
153
+ bool IsKeywordArgument = false ;
154
+ // / It this is a ref, whether it is "dynamic". See \c ide::isDynamicRef.
155
+ bool IsDynamic = false ;
156
+ // / If this is a dynamic ref, the types of the base (multiple in the case of
157
+ // / protocol composition).
158
+ SmallVector<NominalTypeDecl *> ReceiverTypes;
159
+ // / Declarations that were shadowed by \c ValueD using a shorthand syntax
160
+ // / that names both the newly declared variable and the referenced variable
161
+ // / by the same identifier in the source text. This includes shorthand
162
+ // / closure captures (`[foo]`) and shorthand if captures
163
+ // / (`if let foo {`).
164
+ // / Decls that are shadowed using shorthand syntax should be reported as
165
+ // / additional cursor info results.
166
+ SmallVector<ValueDecl *> ShorthandShadowedDecls;
167
+ } ValueRefInfo;
168
+ struct {
169
+ ModuleEntity Mod;
170
+ } ModuleRefInfo;
171
+ struct {
172
+ Expr *TrailingExpr = nullptr ;
173
+ } ExprStartInfo;
174
+ struct {
175
+ Stmt *TrailingStmt = nullptr ;
176
+ } StmtStartInfo;
177
+
178
+ public:
159
179
ResolvedCursorInfo () = default ;
160
180
ResolvedCursorInfo (SourceFile *SF) : SF(SF) {}
161
181
162
- ValueDecl *typeOrValue () { return CtorTyRef ? CtorTyRef : ValueD; }
182
+ CursorInfoKind getKind () const { return Kind; }
183
+
184
+ SourceFile *getSourceFile () const { return SF; }
185
+
186
+ SourceLoc getLoc () const { return Loc; }
187
+ void setLoc (SourceLoc Loc) { this ->Loc = Loc; }
163
188
164
189
friend bool operator ==(const ResolvedCursorInfo &lhs,
165
190
const ResolvedCursorInfo &rhs) {
166
191
return lhs.SF == rhs.SF &&
167
192
lhs.Loc .getOpaquePointerValue () == rhs.Loc .getOpaquePointerValue ();
168
193
}
169
194
170
- void setValueRef (ValueDecl *ValueD, TypeDecl *CtorTyRef,
171
- ExtensionDecl *ExtTyRef, bool IsRef,
172
- Type Ty, Type ContainerType) {
195
+ bool isValid () const { return !isInvalid (); }
196
+ bool isInvalid () const { return Kind == CursorInfoKind::Invalid; }
197
+ };
198
+
199
+ struct ResolvedValueRefCursorInfo : public ResolvedCursorInfo {
200
+ // IMPORTANT: Don't add stored properties here. See comment on
201
+ // ResolvedCursorInfo.
202
+
203
+ ResolvedValueRefCursorInfo () = default ;
204
+ explicit ResolvedValueRefCursorInfo (const ResolvedCursorInfo &Base,
205
+ ValueDecl *ValueD, TypeDecl *CtorTyRef,
206
+ ExtensionDecl *ExtTyRef, bool IsRef,
207
+ Type Ty, Type ContainerType)
208
+ : ResolvedCursorInfo(Base) {
209
+ assert (Base.getKind () == CursorInfoKind::Invalid &&
210
+ " Can only specialize from invalid" );
173
211
Kind = CursorInfoKind::ValueRef;
174
- this ->ValueD = ValueD;
175
- this ->CtorTyRef = CtorTyRef;
176
- this ->ExtTyRef = ExtTyRef;
177
- this ->IsRef = IsRef;
178
- this ->Ty = Ty;
179
- this ->ContainerType = ContainerType;
212
+ ValueRefInfo.ValueD = ValueD;
213
+ ValueRefInfo.CtorTyRef = CtorTyRef;
214
+ ValueRefInfo.ExtTyRef = ExtTyRef;
215
+ ValueRefInfo.IsRef = IsRef;
216
+ ValueRefInfo.Ty = Ty;
217
+ ValueRefInfo.ContainerType = ContainerType;
218
+ }
219
+
220
+ ValueDecl *getValueD () const { return ValueRefInfo.ValueD ; }
221
+ void setValueD (ValueDecl *ValueD) { ValueRefInfo.ValueD = ValueD; }
222
+
223
+ ExtensionDecl *getExtTyRef () const { return ValueRefInfo.ExtTyRef ; }
224
+
225
+ TypeDecl *getCtorTyRef () const { return ValueRefInfo.CtorTyRef ; }
226
+
227
+ bool isRef () const { return ValueRefInfo.IsRef ; }
228
+ void setIsRef (bool IsRef) { ValueRefInfo.IsRef = IsRef; }
229
+
230
+ Type getType () const { return ValueRefInfo.Ty ; }
231
+
232
+ Type getContainerType () const { return ValueRefInfo.ContainerType ; }
233
+ void setContainerType (Type Ty) { ValueRefInfo.ContainerType = Ty; }
234
+
235
+ bool isKeywordArgument () const { return ValueRefInfo.IsKeywordArgument ; }
236
+ void setIsKeywordArgument (bool IsKeywordArgument) {
237
+ ValueRefInfo.IsKeywordArgument = IsKeywordArgument;
238
+ }
239
+
240
+ bool isDynamic () const { return ValueRefInfo.IsDynamic ; }
241
+ void setIsDynamic (bool IsDynamic) { ValueRefInfo.IsDynamic = IsDynamic; }
242
+
243
+ ArrayRef<NominalTypeDecl *> getReceiverTypes () const {
244
+ return ValueRefInfo.ReceiverTypes ;
245
+ }
246
+ void setReceiverTypes (const SmallVector<NominalTypeDecl *> &ReceiverTypes) {
247
+ ValueRefInfo.ReceiverTypes = ReceiverTypes;
248
+ }
249
+
250
+ ArrayRef<ValueDecl *> getShorthandShadowedDecls () const {
251
+ return ValueRefInfo.ShorthandShadowedDecls ;
252
+ };
253
+ void setShorthandShadowedDecls (
254
+ const SmallVector<ValueDecl *> &ShorthandShadowedDecls) {
255
+ ValueRefInfo.ShorthandShadowedDecls = ShorthandShadowedDecls;
256
+ };
257
+
258
+ ValueDecl *typeOrValue () {
259
+ return ValueRefInfo.CtorTyRef ? ValueRefInfo.CtorTyRef
260
+ : ValueRefInfo.ValueD ;
180
261
}
181
- void setModuleRef (ModuleEntity Mod) {
262
+
263
+ static bool classof (const ResolvedCursorInfo *Info) {
264
+ return Info->getKind () == CursorInfoKind::ValueRef;
265
+ }
266
+ };
267
+
268
+ struct ResolvedModuleRefCursorInfo : public ResolvedCursorInfo {
269
+ // IMPORTANT: Don't add stored properties here. See comment on
270
+ // ResolvedCursorInfo.
271
+
272
+ ResolvedModuleRefCursorInfo (const ResolvedCursorInfo &Base, ModuleEntity Mod)
273
+ : ResolvedCursorInfo(Base) {
274
+ assert (Base.getKind () == CursorInfoKind::Invalid &&
275
+ " Can only specialize from invalid" );
182
276
Kind = CursorInfoKind::ModuleRef;
183
- this -> Mod = Mod;
277
+ ModuleRefInfo. Mod = Mod;
184
278
}
185
- void setTrailingStmt (Stmt *TrailingStmt) {
186
- Kind = CursorInfoKind::StmtStart;
187
- this ->TrailingStmt = TrailingStmt;
279
+
280
+ ModuleEntity getMod () const { return ModuleRefInfo.Mod ; }
281
+
282
+ static bool classof (const ResolvedCursorInfo *Info) {
283
+ return Info->getKind () == CursorInfoKind::ModuleRef;
188
284
}
189
- void setTrailingExpr (Expr* TrailingExpr) {
285
+ };
286
+
287
+ struct ResolvedExprStartCursorInfo : public ResolvedCursorInfo {
288
+ // IMPORTANT: Don't add stored properties here. See comment on
289
+ // ResolvedCursorInfo.
290
+
291
+ ResolvedExprStartCursorInfo (const ResolvedCursorInfo &Base,
292
+ Expr *TrailingExpr)
293
+ : ResolvedCursorInfo(Base) {
294
+ assert (Base.getKind () == CursorInfoKind::Invalid &&
295
+ " Can only specialize from invalid" );
190
296
Kind = CursorInfoKind::ExprStart;
191
- this -> TrailingExpr = TrailingExpr;
297
+ ExprStartInfo. TrailingExpr = TrailingExpr;
192
298
}
193
299
194
- bool isValid () const { return !isInvalid (); }
195
- bool isInvalid () const { return Kind == CursorInfoKind::Invalid; }
300
+ Expr *getTrailingExpr () const { return ExprStartInfo.TrailingExpr ; }
301
+
302
+ static bool classof (const ResolvedCursorInfo *Info) {
303
+ return Info->getKind () == CursorInfoKind::ExprStart;
304
+ }
305
+ };
306
+
307
+ struct ResolvedStmtStartCursorInfo : public ResolvedCursorInfo {
308
+ // IMPORTANT: Don't add stored properties here. See comment on
309
+ // ResolvedCursorInfo.
310
+
311
+ ResolvedStmtStartCursorInfo (const ResolvedCursorInfo &Base,
312
+ Stmt *TrailingStmt)
313
+ : ResolvedCursorInfo(Base) {
314
+ assert (Base.getKind () == CursorInfoKind::Invalid &&
315
+ " Can only specialize from invalid" );
316
+ Kind = CursorInfoKind::StmtStart;
317
+ StmtStartInfo.TrailingStmt = TrailingStmt;
318
+ }
319
+
320
+ Stmt *getTrailingStmt () const { return StmtStartInfo.TrailingStmt ; }
321
+
322
+ static bool classof (const ResolvedCursorInfo *Info) {
323
+ return Info->getKind () == CursorInfoKind::StmtStart;
324
+ }
196
325
};
197
326
198
327
void simple_display (llvm::raw_ostream &out, const ResolvedCursorInfo &info);
0 commit comments