Skip to content

Commit 500f34c

Browse files
committed
[ast] Allow for VarDecls to have a Parent back pointer that points at a different var decl.
I did not wire anything up to it. This is in preparation for fixing issues around SILGenPattern fallthrough emission and bad rename/edit all in scope of case stmt var decls. Specifically, I am going to ensure that we can get from any VarDecl in the following to any other VarDecl: switch x { case .a(let v1, let v2), .b(let v1, let v2): ... fallthrough case .c(let v1, let v2), .d(let v1, let v2): ... } This will be done by: 1. Pointing the var decls in .d at the corresponding var decls in .c. 2. Pointing the var decls in .c at the corresponding var decls in .b. 3. Pointing the var decls in .b at the corresponding var decls in .a. 4. Pointing the var decls in .a at the case stmt. Recognizing that we are asking for the next VarDecl, but have a case stmt, we check if we have a fallthrough case stmt (which I am going to add in a subsequent commit). If so, follow down the fallthrough case stmts until you find a fallthrough case stmt that doesn't fallthrough itself and then return the corresponding var decl in the last case label item in that var decl (in the above .d). I also put in some asserts to make sure that we never try to vend a parent value that is a nullptr. rdar://47467128
1 parent 87cf549 commit 500f34c

File tree

2 files changed

+40
-17
lines changed

2 files changed

+40
-17
lines changed

include/swift/AST/Decl.h

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4577,7 +4577,7 @@ class VarDecl : public AbstractStorageDecl {
45774577
};
45784578

45794579
protected:
4580-
llvm::PointerUnion<PatternBindingDecl*, Stmt*> ParentPattern;
4580+
PointerUnion3<PatternBindingDecl *, Stmt *, VarDecl *> Parent;
45814581

45824582
VarDecl(DeclKind Kind, bool IsStatic, Specifier Sp, bool IsCaptureList,
45834583
SourceLoc NameLoc, Identifier Name, DeclContext *DC)
@@ -4648,12 +4648,15 @@ class VarDecl : public AbstractStorageDecl {
46484648
/// Return the parent pattern binding that may provide an initializer for this
46494649
/// VarDecl. This returns null if there is none associated with the VarDecl.
46504650
PatternBindingDecl *getParentPatternBinding() const {
4651-
return ParentPattern.dyn_cast<PatternBindingDecl *>();
4651+
if (!Parent)
4652+
return nullptr;
4653+
return Parent.dyn_cast<PatternBindingDecl *>();
46524654
}
46534655
void setParentPatternBinding(PatternBindingDecl *PBD) {
4654-
ParentPattern = PBD;
4656+
assert(PBD);
4657+
Parent = PBD;
46554658
}
4656-
4659+
46574660
/// Return the Pattern involved in initializing this VarDecl. However, recall
46584661
/// that the Pattern may be involved in initializing more than just this one
46594662
/// vardecl. For example, if this is a VarDecl for "x", the pattern may be
@@ -4668,10 +4671,28 @@ class VarDecl : public AbstractStorageDecl {
46684671
/// Return the statement that owns the pattern associated with this VarDecl,
46694672
/// if one exists.
46704673
Stmt *getParentPatternStmt() const {
4671-
return ParentPattern.dyn_cast<Stmt*>();
4674+
if (!Parent)
4675+
return nullptr;
4676+
return Parent.dyn_cast<Stmt *>();
4677+
}
4678+
void setParentPatternStmt(Stmt *s) {
4679+
assert(s);
4680+
Parent = s;
46724681
}
4673-
void setParentPatternStmt(Stmt *S) {
4674-
ParentPattern = S;
4682+
4683+
/// Returns the var decl that this var decl is an implicit reference to if
4684+
/// such a var decl exists.
4685+
VarDecl *getParentVarDecl() const {
4686+
if (!Parent)
4687+
return nullptr;
4688+
return Parent.dyn_cast<VarDecl *>();
4689+
}
4690+
4691+
/// Set \p v to be the pattern produced VarDecl that is the parent of this
4692+
/// var decl.
4693+
void setParentVarDecl(VarDecl *v) {
4694+
assert(v);
4695+
Parent = v;
46754696
}
46764697

46774698
/// True if the global stored property requires lazy initialization.

include/swift/Basic/LLVM.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ namespace llvm {
4343
template<typename T> class TinyPtrVector;
4444
template<typename T> class Optional;
4545
template <typename PT1, typename PT2> class PointerUnion;
46+
template <typename PT1, typename PT2, typename PT3> class PointerUnion3;
4647
class SmallBitVector;
4748

4849
// Other common classes.
@@ -62,22 +63,23 @@ namespace swift {
6263
using llvm::cast_or_null;
6364

6465
// Containers.
66+
using llvm::ArrayRef;
67+
using llvm::MutableArrayRef;
6568
using llvm::None;
6669
using llvm::Optional;
67-
using llvm::SmallPtrSetImpl;
70+
using llvm::PointerUnion;
71+
using llvm::PointerUnion3;
72+
using llvm::SmallBitVector;
6873
using llvm::SmallPtrSet;
74+
using llvm::SmallPtrSetImpl;
75+
using llvm::SmallSetVector;
6976
using llvm::SmallString;
70-
using llvm::StringRef;
71-
using llvm::StringLiteral;
72-
using llvm::Twine;
73-
using llvm::SmallVectorImpl;
7477
using llvm::SmallVector;
75-
using llvm::ArrayRef;
76-
using llvm::MutableArrayRef;
78+
using llvm::SmallVectorImpl;
79+
using llvm::StringLiteral;
80+
using llvm::StringRef;
7781
using llvm::TinyPtrVector;
78-
using llvm::PointerUnion;
79-
using llvm::SmallSetVector;
80-
using llvm::SmallBitVector;
82+
using llvm::Twine;
8183

8284
// Other common classes.
8385
using llvm::APFloat;

0 commit comments

Comments
 (0)