Skip to content

Commit ac2e8fc

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 (cherry picked from commit 500f34c)
1 parent a9ed8bb commit ac2e8fc

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
@@ -4579,7 +4579,7 @@ class VarDecl : public AbstractStorageDecl {
45794579
};
45804580

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

45844584
VarDecl(DeclKind Kind, bool IsStatic, Specifier Sp, bool IsCaptureList,
45854585
SourceLoc NameLoc, Identifier Name, DeclContext *DC)
@@ -4650,12 +4650,15 @@ class VarDecl : public AbstractStorageDecl {
46504650
/// Return the parent pattern binding that may provide an initializer for this
46514651
/// VarDecl. This returns null if there is none associated with the VarDecl.
46524652
PatternBindingDecl *getParentPatternBinding() const {
4653-
return ParentPattern.dyn_cast<PatternBindingDecl *>();
4653+
if (!Parent)
4654+
return nullptr;
4655+
return Parent.dyn_cast<PatternBindingDecl *>();
46544656
}
46554657
void setParentPatternBinding(PatternBindingDecl *PBD) {
4656-
ParentPattern = PBD;
4658+
assert(PBD);
4659+
Parent = PBD;
46574660
}
4658-
4661+
46594662
/// Return the Pattern involved in initializing this VarDecl. However, recall
46604663
/// that the Pattern may be involved in initializing more than just this one
46614664
/// vardecl. For example, if this is a VarDecl for "x", the pattern may be
@@ -4670,10 +4673,28 @@ class VarDecl : public AbstractStorageDecl {
46704673
/// Return the statement that owns the pattern associated with this VarDecl,
46714674
/// if one exists.
46724675
Stmt *getParentPatternStmt() const {
4673-
return ParentPattern.dyn_cast<Stmt*>();
4676+
if (!Parent)
4677+
return nullptr;
4678+
return Parent.dyn_cast<Stmt *>();
4679+
}
4680+
void setParentPatternStmt(Stmt *s) {
4681+
assert(s);
4682+
Parent = s;
46744683
}
4675-
void setParentPatternStmt(Stmt *S) {
4676-
ParentPattern = S;
4684+
4685+
/// Returns the var decl that this var decl is an implicit reference to if
4686+
/// such a var decl exists.
4687+
VarDecl *getParentVarDecl() const {
4688+
if (!Parent)
4689+
return nullptr;
4690+
return Parent.dyn_cast<VarDecl *>();
4691+
}
4692+
4693+
/// Set \p v to be the pattern produced VarDecl that is the parent of this
4694+
/// var decl.
4695+
void setParentVarDecl(VarDecl *v) {
4696+
assert(v);
4697+
Parent = v;
46774698
}
46784699

46794700
/// 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)