@@ -128,71 +128,200 @@ enum class CursorInfoKind {
128128 StmtStart,
129129};
130130
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.
131136struct ResolvedCursorInfo {
137+ protected:
132138 CursorInfoKind Kind = CursorInfoKind::Invalid;
133139 SourceFile *SF = nullptr ;
134140 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;
158141
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:
159179 ResolvedCursorInfo () = default ;
160180 ResolvedCursorInfo (SourceFile *SF) : SF(SF) {}
161181
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; }
163188
164189 friend bool operator ==(const ResolvedCursorInfo &lhs,
165190 const ResolvedCursorInfo &rhs) {
166191 return lhs.SF == rhs.SF &&
167192 lhs.Loc .getOpaquePointerValue () == rhs.Loc .getOpaquePointerValue ();
168193 }
169194
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" );
173211 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 ;
180261 }
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" );
182276 Kind = CursorInfoKind::ModuleRef;
183- this -> Mod = Mod;
277+ ModuleRefInfo. Mod = Mod;
184278 }
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;
188284 }
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" );
190296 Kind = CursorInfoKind::ExprStart;
191- this -> TrailingExpr = TrailingExpr;
297+ ExprStartInfo. TrailingExpr = TrailingExpr;
192298 }
193299
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+ }
196325};
197326
198327void simple_display (llvm::raw_ostream &out, const ResolvedCursorInfo &info);
0 commit comments