Skip to content

[AST] A couple of PatternBindingInitializer cleanups #70591

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 18, 2024
25 changes: 17 additions & 8 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "swift/AST/GenericParamKey.h"
#include "swift/AST/IfConfigClause.h"
#include "swift/AST/Import.h"
#include "swift/AST/Initializer.h"
#include "swift/AST/LayoutConstraint.h"
#include "swift/AST/LifetimeAnnotation.h"
#include "swift/AST/ReferenceCounting.h"
Expand Down Expand Up @@ -1962,7 +1963,7 @@ class PatternBindingEntry {
IsFromDebugger = 1 << 2,
};
/// The initializer context used for this pattern binding entry.
llvm::PointerIntPair<DeclContext *, 3, OptionSet<PatternFlags>>
llvm::PointerIntPair<PatternBindingInitializer *, 3, OptionSet<PatternFlags>>
InitContextAndFlags;

/// Values captured by this initializer.
Expand Down Expand Up @@ -2003,7 +2004,7 @@ class PatternBindingEntry {
public:
/// \p E is the initializer as parsed.
PatternBindingEntry(Pattern *P, SourceLoc EqualLoc, Expr *E,
DeclContext *InitContext)
PatternBindingInitializer *InitContext)
: PatternAndFlags(P, {}),
InitExpr({E, {E, InitializerStatus::NotChecked}, EqualLoc}),
InitContextAndFlags({InitContext, llvm::None}) {}
Expand Down Expand Up @@ -2107,12 +2108,14 @@ class PatternBindingEntry {
VarDecl *getAnchoringVarDecl() const;

// Retrieve the declaration context for the initializer.
DeclContext *getInitContext() const {
PatternBindingInitializer *getInitContext() const {
return InitContextAndFlags.getPointer();
}

/// Override the initializer context.
void setInitContext(DeclContext *dc) { InitContextAndFlags.setPointer(dc); }
void setInitContext(PatternBindingInitializer *init) {
InitContextAndFlags.setPointer(init);
}

SourceLoc getStartLoc() const;

Expand Down Expand Up @@ -2310,18 +2313,24 @@ class PatternBindingDecl final : public Decl,
Pattern *getPattern(unsigned i) const {
return getPatternList()[i].getPattern();
}

void setPattern(unsigned i, Pattern *Pat, DeclContext *InitContext,
bool isFullyValidated = false);

void setPattern(unsigned i, Pattern *P, bool isFullyValidated = false);

bool isFullyValidated(unsigned i) const {
return getPatternList()[i].isFullyValidated();
}

DeclContext *getInitContext(unsigned i) const {
PatternBindingInitializer *getInitContext(unsigned i) const {
return getPatternList()[i].getInitContext();
}

void setInitContext(unsigned i, PatternBindingInitializer *init) {
if (init) {
init->setBinding(this, i);
}
getMutablePatternList()[i].setInitContext(init);
}

CaptureInfo getCaptureInfo(unsigned i) const {
return getPatternList()[i].getCaptureInfo();
}
Expand Down
4 changes: 0 additions & 4 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ namespace swift {
class Initializer;
class ClassDecl;
class SerializedAbstractClosureExpr;
class SerializedPatternBindingInitializer;
class SerializedDefaultArgumentInitializer;
class SerializedTopLevelCodeDecl;
class StructDecl;
class AccessorDecl;
Expand Down Expand Up @@ -115,8 +113,6 @@ enum class DeclContextKind : unsigned {
/// \see SerializedLocalDeclContext.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is out of date. Is DeclContextKind::SerializedLocal also dead now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah looks like we can probably just rip out SerializedLocalDeclContext at this point, I'll do that in a follow-up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enum class LocalDeclContextKind : uint8_t {
AbstractClosure,
PatternBindingInitializer,
DefaultArgumentInitializer,
TopLevelCodeDecl
};

Expand Down
79 changes: 11 additions & 68 deletions include/swift/AST/Initializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
#define SWIFT_INITIALIZER_H

#include "swift/AST/DeclContext.h"
#include "swift/AST/Decl.h"

namespace swift {
class ParamDecl;
class PatternBindingDecl;

enum class InitializerKind : uint8_t {
Expand Down Expand Up @@ -76,28 +76,25 @@ class PatternBindingInitializer : public Initializer {
// created lazily for 'self' lookup from lazy property initializer
ParamDecl *SelfParam;

friend class ASTContext; // calls reset on unused contexts
// Sets itself as the parent.
friend class PatternBindingDecl;

void reset(DeclContext *parent) {
setParent(parent);
Binding = nullptr;
SelfParam = nullptr;
}
void setBinding(PatternBindingDecl *binding, unsigned bindingIndex);

public:
explicit PatternBindingInitializer(DeclContext *parent)
: Initializer(InitializerKind::PatternBinding, parent),
Binding(nullptr), SelfParam(nullptr) {
SpareBits = 0;
}


void setBinding(PatternBindingDecl *binding, unsigned bindingIndex) {
setParent(binding->getDeclContext());
Binding = binding;
SpareBits = bindingIndex;
public:
static PatternBindingInitializer *create(DeclContext *parent) {
return new (parent->getASTContext()) PatternBindingInitializer(parent);
}


static PatternBindingInitializer *createDeserialized(PatternBindingDecl *PBD,
unsigned index);

PatternBindingDecl *getBinding() const { return Binding; }

unsigned getBindingIndex() const { return SpareBits; }
Expand All @@ -119,37 +116,6 @@ class PatternBindingInitializer : public Initializer {
}
};

/// SerializedPatternBindingInitializer - This represents what was originally a
/// PatternBindingInitializer during serialization. It is preserved as a special
/// class only to maintain the correct AST structure and remangling after
/// deserialization.
class SerializedPatternBindingInitializer : public SerializedLocalDeclContext {
PatternBindingDecl *Binding;

public:
SerializedPatternBindingInitializer(PatternBindingDecl *Binding,
unsigned bindingIndex)
: SerializedLocalDeclContext(LocalDeclContextKind::PatternBindingInitializer,
Binding->getDeclContext()),
Binding(Binding) {
SpareBits = bindingIndex;
}

PatternBindingDecl *getBinding() const {
return Binding;
}

unsigned getBindingIndex() const { return SpareBits; }


static bool classof(const DeclContext *DC) {
if (auto LDC = dyn_cast<SerializedLocalDeclContext>(DC))
return LDC->getLocalDeclContextKind() ==
LocalDeclContextKind::PatternBindingInitializer;
return false;
}
};

/// A default argument expression. The parent context is the function
/// (possibly a closure) for which this is a default argument.
class DefaultArgumentInitializer : public Initializer {
Expand All @@ -176,29 +142,6 @@ class DefaultArgumentInitializer : public Initializer {
}
};

/// SerializedDefaultArgumentInitializer - This represents what was originally a
/// DefaultArgumentInitializer during serialization. It is preserved only to
/// maintain the correct AST structure and remangling after deserialization.
class SerializedDefaultArgumentInitializer : public SerializedLocalDeclContext {
const unsigned Index;
public:
SerializedDefaultArgumentInitializer(unsigned Index, DeclContext *Parent)
: SerializedLocalDeclContext(LocalDeclContextKind::DefaultArgumentInitializer,
Parent),
Index(Index) {}

unsigned getIndex() const {
return Index;
}

static bool classof(const DeclContext *DC) {
if (auto LDC = dyn_cast<SerializedLocalDeclContext>(DC))
return LDC->getLocalDeclContextKind() ==
LocalDeclContextKind::DefaultArgumentInitializer;
return false;
}
};

/// A property wrapper initialization expression. The parent context is the
/// function or closure which owns the property wrapper.
class PropertyWrapperInitializer : public Initializer {
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Sema/SyntacticElementTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class SyntacticElementTarget {
/// Form a target for the initialization of a pattern binding entry from
/// an expression.
static SyntacticElementTarget
forInitialization(Expr *initializer, DeclContext *dc, Type patternType,
forInitialization(Expr *initializer, Type patternType,
PatternBindingDecl *patternBinding,
unsigned patternBindingIndex, bool bindPatternVarsOneWay);

Expand Down
3 changes: 1 addition & 2 deletions lib/AST/ASTBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,7 @@ bool BridgedDeclContext_isLocalContext(BridgedDeclContext cDeclContext) {

BridgedPatternBindingInitializer
BridgedPatternBindingInitializer_create(BridgedDeclContext cDeclContext) {
auto *dc = cDeclContext.unbridged();
return new (dc->getASTContext()) PatternBindingInitializer(dc);
return PatternBindingInitializer::create(cDeclContext.unbridged());
}

BridgedDeclContext BridgedPatternBindingInitializer_asDeclContext(
Expand Down
16 changes: 0 additions & 16 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2323,22 +2323,6 @@ void ASTMangler::appendContext(const DeclContext *ctx, StringRef useModuleName)
case LocalDeclContextKind::AbstractClosure:
appendClosureEntity(cast<SerializedAbstractClosureExpr>(local));
return;
case LocalDeclContextKind::DefaultArgumentInitializer: {
auto argInit = cast<SerializedDefaultArgumentInitializer>(local);
appendDefaultArgumentEntity(ctx->getParent(), argInit->getIndex());
return;
}
case LocalDeclContextKind::PatternBindingInitializer: {
auto patternInit = cast<SerializedPatternBindingInitializer>(local);
if (auto var = findFirstVariable(patternInit->getBinding())) {
appendInitializerEntity(var.value());
} else {
// This is incorrect in that it does not produce a /unique/ mangling,
// but it will at least produce a /valid/ mangling.
appendContext(ctx->getParent(), useModuleName);
}
return;
}
case LocalDeclContextKind::TopLevelCodeDecl:
return appendContext(local->getParent(), useModuleName);
}
Expand Down
4 changes: 1 addition & 3 deletions lib/AST/ASTScopeLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,7 @@ bool BraceStmtScope::lookupLocalsOrMembers(DeclConsumer consumer) const {
bool PatternEntryInitializerScope::lookupLocalsOrMembers(
DeclConsumer consumer) const {
// 'self' is available within the pattern initializer of a 'lazy' variable.
auto *initContext = dyn_cast_or_null<PatternBindingInitializer>(
decl->getInitContext(0));
if (initContext) {
if (auto *initContext = decl->getInitContext(0)) {
if (auto *selfParam = initContext->getImplicitSelfDecl()) {
return consumer.consume({selfParam});
}
Expand Down
2 changes: 1 addition & 1 deletion lib/AST/ASTWalker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,

for (auto idx : range(PBD->getNumPatternEntries())) {
if (Pattern *Pat = doIt(PBD->getPattern(idx)))
PBD->setPattern(idx, Pat, PBD->getInitContext(idx));
PBD->setPattern(idx, Pat);
else
return true;

Expand Down
39 changes: 27 additions & 12 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1924,21 +1924,19 @@ PatternBindingDecl::create(ASTContext &Ctx, SourceLoc StaticLoc,
PBD->getTrailingObjects<PatternBindingEntry>());

for (auto idx : range(PBD->getNumPatternEntries())) {
auto *initContext =
cast_or_null<PatternBindingInitializer>(PBD->getInitContext(idx));
auto *initContext = PBD->getInitContext(idx);

// FIXME: We ought to reconsider this since it won't recontextualize any
// closures/decls present in the initialization expr. This currently should
// only affect implicit code though.
if (!initContext && !Parent->isLocalContext())
initContext = new (Ctx) PatternBindingInitializer(Parent);

if (initContext)
initContext->setBinding(PBD, idx);
initContext = PatternBindingInitializer::create(Parent);

// We need to call setPattern to ensure the VarDecls in the pattern have
// the PatternBindingDecl set as their parent, and to setup the context.
PBD->setPattern(idx, PBD->getPattern(idx), initContext);
// the PatternBindingDecl set as their parent. We also need to call
// setInitContext to setup the context.
PBD->setPattern(idx, PBD->getPattern(idx));
PBD->setInitContext(idx, initContext);
}
return PBD;
}
Expand All @@ -1961,6 +1959,14 @@ PatternBindingDecl *PatternBindingDecl::createDeserialized(
return PBD;
}

PatternBindingInitializer *
PatternBindingInitializer::createDeserialized(PatternBindingDecl *PBD,
unsigned index) {
auto *init = PatternBindingInitializer::create(PBD->getDeclContext());
init->setBinding(PBD, index);
return init;
}

ParamDecl *PatternBindingInitializer::getImplicitSelfDecl() const {
if (SelfParam)
return SelfParam;
Expand Down Expand Up @@ -1996,6 +2002,18 @@ ParamDecl *PatternBindingInitializer::getImplicitSelfDecl() const {
return SelfParam;
}

void PatternBindingInitializer::setBinding(PatternBindingDecl *binding,
unsigned bindingIndex) {
assert(binding);
assert(!Binding || Binding == binding &&
"Cannot change the binding after the fact");
assert(!Binding || SpareBits == bindingIndex &&
"Cannot change the binding index after the fact");
setParent(binding->getDeclContext());
Binding = binding;
SpareBits = bindingIndex;
}

VarDecl *PatternBindingInitializer::getInitializedLazyVar() const {
if (auto binding = getBinding()) {
if (auto var = binding->getSingleVar()) {
Expand Down Expand Up @@ -2224,12 +2242,10 @@ PatternBindingDecl::getCheckedPatternBindingEntry(unsigned i) const {
}

void PatternBindingDecl::setPattern(unsigned i, Pattern *P,
DeclContext *InitContext,
bool isFullyValidated) {
auto PatternList = getMutablePatternList();
PatternList[i].setPattern(P);
PatternList[i].setInitContext(InitContext);


// Make sure that any VarDecl's contained within the pattern know about this
// PatternBindingDecl as their parent.
if (P) {
Expand All @@ -2243,7 +2259,6 @@ void PatternBindingDecl::setPattern(unsigned i, Pattern *P,
}
}


VarDecl *PatternBindingDecl::getSingleVar() const {
if (getNumPatternEntries() == 1)
return getPatternList()[0].getPattern()->getSingleVar();
Expand Down
11 changes: 0 additions & 11 deletions lib/AST/DeclContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,17 +824,6 @@ unsigned DeclContext::printContext(raw_ostream &OS, const unsigned indent,
OS << " closure : " << serializedClosure->getType();
break;
}
case LocalDeclContextKind::DefaultArgumentInitializer: {
auto init = cast<SerializedDefaultArgumentInitializer>(local);
OS << "DefaultArgument index=" << init->getIndex();
break;
}
case LocalDeclContextKind::PatternBindingInitializer: {
auto init = cast<SerializedPatternBindingInitializer>(local);
OS << " PatternBinding 0x" << (void*) init->getBinding()
<< " #" << init->getBindingIndex();
break;
}
case LocalDeclContextKind::TopLevelCodeDecl:
OS << " TopLevelCode";
break;
Expand Down
Loading