Skip to content

Commit 0358e1e

Browse files
committed
[AST] Consolidate attribute attachment logic
Introduce `DeclAttribute::attachToDecl` which is the now the main entry point for associating an attribute with a decl. Different attributes can implement `attachToDeclImpl` to add their custom logic. Move DifferentiableAttr, DerivativeAttr, CustomAttr, and ABIAttr over to this new logic.
1 parent 485dda2 commit 0358e1e

File tree

6 files changed

+91
-88
lines changed

6 files changed

+91
-88
lines changed

include/swift/AST/Attr.h

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,9 @@ class DeclAttribute : public AttributeBase {
619619
DeclAttrKind kind, SourceLoc atLoc,
620620
SourceLoc attrLoc);
621621

622+
/// Attaches the attribute to the given declaration.
623+
void attachToDecl(Decl *D);
624+
622625
/// Create a copy of this attribute.
623626
DeclAttribute *clone(ASTContext &ctx) const;
624627

@@ -629,6 +632,11 @@ class DeclAttribute : public AttributeBase {
629632
/// would have the same effect on \p attachedTo were they attached to it. A
630633
/// clone should always be equivalent to the original.
631634
bool isEquivalent(const DeclAttribute *other, Decl *attachedTo) const;
635+
636+
private:
637+
void attachToDeclImpl(Decl *D) {
638+
// Most attributes don't need any custom logic for this.
639+
}
632640
};
633641

634642
#define UNIMPLEMENTED_CLONE(AttrType) \
@@ -2292,6 +2300,8 @@ class CustomAttrOwner final {
22922300

22932301
/// Defines a custom attribute.
22942302
class CustomAttr final : public DeclAttribute {
2303+
friend class DeclAttribute;
2304+
22952305
TypeExpr *typeExpr;
22962306
ArgumentList *argList;
22972307
CustomAttrOwner owner;
@@ -2322,7 +2332,6 @@ class CustomAttr final : public DeclAttribute {
23222332

23232333
/// Retrieve the Decl or DeclContext owner for the attribute.
23242334
CustomAttrOwner getOwner() const { return owner; }
2325-
void setOwner(CustomAttrOwner newOwner);
23262335

23272336
ASTContext &getASTContext() const;
23282337

@@ -2377,10 +2386,11 @@ class CustomAttr final : public DeclAttribute {
23772386
void printCustomAttr(ASTPrinter &Printer, const PrintOptions &Options) const;
23782387

23792388
private:
2389+
void attachToDeclImpl(Decl *D);
2390+
23802391
friend class CustomAttrNominalRequest;
23812392
void resetTypeInformation(TypeExpr *repr);
23822393

2383-
private:
23842394
friend class CustomAttrTypeRequest;
23852395
void setType(Type ty);
23862396
};
@@ -2517,6 +2527,7 @@ class DifferentiableAttr final
25172527
ParsedAutoDiffParameter> {
25182528
friend TrailingObjects;
25192529
friend class DifferentiableAttributeTypeCheckRequest;
2530+
friend class DeclAttribute;
25202531

25212532
/// The declaration on which the `@differentiable` attribute is declared.
25222533
/// May not be a valid declaration for `@differentiable` attributes.
@@ -2576,11 +2587,9 @@ class DifferentiableAttr final
25762587

25772588
Decl *getOriginalDeclaration() const { return OriginalDeclaration; }
25782589

2579-
/// Sets the original declaration on which this attribute is declared.
2580-
/// Should only be used by parsing and deserialization.
2581-
void setOriginalDeclaration(Decl *originalDeclaration);
2582-
25832590
private:
2591+
void attachToDeclImpl(Decl *D);
2592+
25842593
/// Returns true if the given `@differentiable` attribute has been
25852594
/// type-checked.
25862595
bool hasBeenTypeChecked() const;
@@ -2695,6 +2704,7 @@ class DerivativeAttr final
26952704
private llvm::TrailingObjects<DerivativeAttr, ParsedAutoDiffParameter> {
26962705
friend TrailingObjects;
26972706
friend class DerivativeAttrOriginalDeclRequest;
2707+
friend class DeclAttribute;
26982708

26992709
/// The declaration on which the `@derivative` attribute is declared.
27002710
/// May not be a valid declaration for `@derivative` attributes.
@@ -2755,10 +2765,6 @@ class DerivativeAttr final
27552765

27562766
Decl *getOriginalDeclaration() const { return OriginalDeclaration; }
27572767

2758-
/// Sets the original declaration on which this attribute is declared.
2759-
/// Should only be used by parsing and deserialization.
2760-
void setOriginalDeclaration(Decl *originalDeclaration);
2761-
27622768
TypeRepr *getBaseTypeRepr() const { return BaseTypeRepr; }
27632769
DeclNameRefWithLoc getOriginalFunctionName() const {
27642770
return OriginalFunctionName;
@@ -2803,6 +2809,9 @@ class DerivativeAttr final
28032809
// Not properly implemented (very complex and not currently needed)
28042810
return false;
28052811
}
2812+
2813+
private:
2814+
void attachToDeclImpl(Decl *D);
28062815
};
28072816

28082817
/// The `@transpose(of:)` attribute registers a function as a transpose of
@@ -3538,6 +3547,8 @@ class AllowFeatureSuppressionAttr final
35383547

35393548
/// Defines the @abi attribute.
35403549
class ABIAttr : public DeclAttribute {
3550+
friend class DeclAttribute;
3551+
35413552
public:
35423553
ABIAttr(Decl *abiDecl, SourceLoc AtLoc, SourceRange Range, bool Implicit)
35433554
: DeclAttribute(DeclAttrKind::ABI, AtLoc, Range, Implicit),
@@ -3564,6 +3575,9 @@ class ABIAttr : public DeclAttribute {
35643575
// Unsupported: tricky to implement and unneeded.
35653576
return true;
35663577
}
3578+
3579+
private:
3580+
void attachToDeclImpl(Decl *D);
35673581
};
35683582

35693583
/// Defines a @nonexhaustive attribute.

include/swift/AST/Decl.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,12 +1054,6 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl>, public Swi
10541054
/// attribute macro expansion.
10551055
DeclAttributes getSemanticAttrs() const;
10561056

1057-
/// Register the relationship between \c this and \p attr->abiDecl , assuming
1058-
/// that \p attr is attached to \c this . This is necessary for
1059-
/// \c ABIRoleInfo::ABIRoleInfo() to determine that \c attr->abiDecl
1060-
/// is ABI-only and locate its API counterpart.
1061-
void recordABIAttr(ABIAttr *attr);
1062-
10631057
/// Set this declaration's attributes to the specified attribute list,
10641058
/// applying any post-processing logic appropriate for attributes parsed
10651059
/// from source code.

lib/AST/Attr.cpp

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,16 @@ bool DeclAttribute::canAttributeAppearOnDeclKind(DeclAttrKind DAK, DeclKind DK)
349349
llvm_unreachable("bad DeclKind");
350350
}
351351

352+
void DeclAttribute::attachToDecl(Decl *D) {
353+
ASSERT(D);
354+
switch (getKind()) {
355+
#define DECL_ATTR(_, CLASS, ...) \
356+
case DeclAttrKind::CLASS: \
357+
return static_cast<CLASS##Attr *>(this)->attachToDeclImpl(D);
358+
#include "swift/AST/DeclAttr.def"
359+
}
360+
}
361+
352362
// Ensure that every DeclAttribute subclass implements its own CloneAttr.
353363
static void checkDeclAttributeClones() {
354364
#define DECL_ATTR(_,CLASS,...) \
@@ -2460,6 +2470,35 @@ OriginallyDefinedInAttr *OriginallyDefinedInAttr::clone(ASTContext &C,
24602470
ManglingModuleName, LinkerModuleName, Platform, MovedVersion, implicit);
24612471
}
24622472

2473+
void ABIAttr::attachToDeclImpl(Decl *D) {
2474+
// Register the relationship between `D` and `abiDecl`. This is necessary for
2475+
// `ABIRoleInfo::ABIRoleInfo()` to determine that `abiDecl` is ABI-only and
2476+
// locate its API counterpart.
2477+
Decl *owner = D;
2478+
2479+
// The ABIAttr on a VarDecl ought to point to its PBD.
2480+
if (auto VD = dyn_cast<VarDecl>(owner)) {
2481+
if (auto PBD = VD->getParentPatternBinding())
2482+
owner = PBD;
2483+
}
2484+
2485+
auto record = [&](Decl *decl) {
2486+
auto &evaluator = owner->getASTContext().evaluator;
2487+
DeclABIRoleInfoRequest(decl).recordABIOnly(evaluator, owner);
2488+
};
2489+
2490+
if (auto abiPBD = dyn_cast<PatternBindingDecl>(abiDecl)) {
2491+
// Add to *every* VarDecl in the ABI PBD, even ones that don't properly
2492+
// match anything in the API PBD.
2493+
for (auto i : range(abiPBD->getNumPatternEntries())) {
2494+
abiPBD->getPattern(i)->forEachVariable(record);
2495+
}
2496+
return;
2497+
}
2498+
2499+
record(abiDecl);
2500+
}
2501+
24632502
bool AvailableAttr::isUnconditionallyUnavailable() const {
24642503
switch (getKind()) {
24652504
case Kind::Default:
@@ -2820,9 +2859,10 @@ DifferentiableAttr::create(AbstractFunctionDecl *original, bool implicit,
28202859
derivativeGenSig);
28212860
}
28222861

2823-
void DifferentiableAttr::setOriginalDeclaration(Decl *originalDeclaration) {
2824-
assert(originalDeclaration && "Original declaration must be non-null");
2825-
assert(!OriginalDeclaration &&
2862+
void DifferentiableAttr::attachToDeclImpl(Decl *originalDeclaration) {
2863+
// FIXME: This doesn't properly handle PatternBindingDecls with multiple
2864+
// VarDecls.
2865+
assert(!OriginalDeclaration || OriginalDeclaration == originalDeclaration &&
28262866
"Original declaration cannot have already been set");
28272867
OriginalDeclaration = originalDeclaration;
28282868
}
@@ -2930,9 +2970,10 @@ void DerivativeAttr::setOriginalFunctionResolver(
29302970
ResolverContextData = resolverContextData;
29312971
}
29322972

2933-
void DerivativeAttr::setOriginalDeclaration(Decl *originalDeclaration) {
2934-
assert(originalDeclaration && "Original declaration must be non-null");
2935-
assert(!OriginalDeclaration &&
2973+
void DerivativeAttr::attachToDeclImpl(Decl *originalDeclaration) {
2974+
// FIXME: This doesn't properly handle PatternBindingDecls with multiple
2975+
// VarDecls.
2976+
assert(!OriginalDeclaration || OriginalDeclaration == originalDeclaration &&
29362977
"Original declaration cannot have already been set");
29372978
OriginalDeclaration = originalDeclaration;
29382979
}
@@ -3084,14 +3125,14 @@ CustomAttr *CustomAttr::create(ASTContext &ctx, SourceLoc atLoc, TypeExpr *type,
30843125
CustomAttr(atLoc, range, type, owner, initContext, argList, implicit);
30853126
}
30863127

3087-
void CustomAttr::setOwner(CustomAttrOwner newOwner) {
3128+
void CustomAttr::attachToDeclImpl(Decl *D) {
30883129
// Prefer to set the parent PatternBindingDecl as the owner for a VarDecl,
30893130
// this ensures we can handle PBDs with multiple vars.
3090-
if (auto *VD = dyn_cast_or_null<VarDecl>(newOwner.getAsDecl())) {
3131+
if (auto *VD = dyn_cast<VarDecl>(D)) {
30913132
if (auto *PBD = VD->getParentPatternBinding())
3092-
newOwner = PBD;
3133+
D = PBD;
30933134
}
3094-
owner = newOwner;
3135+
owner = D;
30953136
}
30963137

30973138
std::pair<UnqualifiedIdentTypeRepr *, DeclRefTypeRepr *>

lib/AST/Decl.cpp

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -436,15 +436,6 @@ DeclAttributes Decl::getSemanticAttrs() const {
436436
void Decl::attachParsedAttrs(DeclAttributes attrs) {
437437
ASSERT(getAttrs().isEmpty() && "attaching when there are already attrs?");
438438

439-
for (auto *attr : attrs.getAttributes<DifferentiableAttr>())
440-
attr->setOriginalDeclaration(this);
441-
for (auto *attr : attrs.getAttributes<DerivativeAttr>())
442-
attr->setOriginalDeclaration(this);
443-
for (auto attr : attrs.getAttributes<ABIAttr, /*AllowInvalid=*/true>())
444-
recordABIAttr(attr);
445-
for (auto *attr : attrs.getAttributes<CustomAttr>())
446-
attr->setOwner(this);
447-
448439
// @implementation requires an explicit @objc attribute, but
449440
// @_objcImplementation didn't. Insert one if necessary.
450441
auto implAttr = attrs.getAttribute<ObjCImplementationAttr>();
@@ -458,6 +449,9 @@ void Decl::attachParsedAttrs(DeclAttributes attrs) {
458449
attrs.add(objcAttr);
459450
}
460451

452+
for (auto attr : attrs)
453+
attr->attachToDecl(this);
454+
461455
getAttrs() = attrs;
462456
}
463457

@@ -4740,33 +4734,6 @@ void ValueDecl::setRenamedDecl(const AvailableAttr *attr,
47404734
std::move(renameDecl));
47414735
}
47424736

4743-
void Decl::recordABIAttr(ABIAttr *attr) {
4744-
Decl *owner = this;
4745-
4746-
// The ABIAttr on a VarDecl ought to point to its PBD.
4747-
if (auto VD = dyn_cast<VarDecl>(owner)) {
4748-
if (auto PBD = VD->getParentPatternBinding()) {
4749-
owner = PBD;
4750-
}
4751-
}
4752-
4753-
auto record = [&](Decl *decl) {
4754-
auto &evaluator = owner->getASTContext().evaluator;
4755-
DeclABIRoleInfoRequest(decl).recordABIOnly(evaluator, owner);
4756-
};
4757-
4758-
if (auto abiPBD = dyn_cast<PatternBindingDecl>(attr->abiDecl)) {
4759-
// Add to *every* VarDecl in the ABI PBD, even ones that don't properly
4760-
// match anything in the API PBD.
4761-
for (auto i : range(abiPBD->getNumPatternEntries())) {
4762-
abiPBD->getPattern(i)->forEachVariable(record);
4763-
}
4764-
return;
4765-
}
4766-
4767-
record(attr->abiDecl);
4768-
}
4769-
47704737
void DeclABIRoleInfoRequest::recordABIOnly(Evaluator &evaluator,
47714738
Decl *counterpart) {
47724739
if (evaluator.hasCachedResult(*this))

lib/ClangImporter/ImportDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8926,7 +8926,7 @@ void ClangImporter::Implementation::importNontrivialAttribute(
89268926
for (auto attr : attrs) {
89278927
auto *newAttr = cached ? attr->clone(SwiftContext) : attr;
89288928
if (auto *CA = dyn_cast<CustomAttr>(newAttr))
8929-
CA->setOwner(MappedDecl);
8929+
CA->attachToDecl(MappedDecl);
89308930
MappedDecl->getAttrs().add(newAttr);
89318931
}
89328932
}

lib/Serialization/Deserialization.cpp

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,7 +3449,7 @@ class DeclDeserializer {
34493449
cast<ExtensionDecl *>(decl)->setInherited(inherited);
34503450
}
34513451

3452-
llvm::Error finishRecursiveAttrs(Decl *decl, DeclAttribute *attrs);
3452+
llvm::Error finishRecursiveAttrs();
34533453

34543454
public:
34553455
DeclDeserializer(ModuleFile &MF, Serialized<Decl *> &declOrOffset)
@@ -3476,9 +3476,13 @@ class DeclDeserializer {
34763476

34773477
if (DAttrs) {
34783478
decl->getAttrs().setRawAttributeChain(DAttrs);
3479-
// Wire up the correct owner for any CustomAttrs we deserialized.
3480-
for (auto *CA : decl->getAttrs().getAttributes<CustomAttr>())
3481-
CA->setOwner(decl);
3479+
// Wire up the attached decl.
3480+
for (auto *attr : decl->getAttrs())
3481+
attr->attachToDecl(decl);
3482+
3483+
// Wire up the indices for @differentiable.
3484+
for (auto *attr : decl->getAttrs().getAttributes<DifferentiableAttr>())
3485+
attr->setParameterIndices(diffAttrParamIndicesMap[attr]);
34823486
}
34833487

34843488
if (auto value = dyn_cast<ValueDecl>(decl)) {
@@ -6774,41 +6778,24 @@ llvm::Error DeclDeserializer::deserializeDeclCommon() {
67746778
}
67756779

67766780
/// Complete attributes that contain recursive references to the decl being
6777-
/// deserialized or to other decls. This method is called after \p decl is
6781+
/// deserialized or to other decls. This method is called after the decl is
67786782
/// created and stored into the \c ModuleFile::Decls table, so any cycles
67796783
/// between mutually-referencing decls will be broken.
67806784
///
67816785
/// Attributes handled here include:
67826786
///
6783-
/// \li \c \@differentiable
6784-
/// \li \c \@derivative
67856787
/// \li \c \@abi
6786-
llvm::Error DeclDeserializer::finishRecursiveAttrs(Decl *decl, DeclAttribute *attrs) {
6787-
DeclAttributes tempAttrs;
6788-
tempAttrs.setRawAttributeChain(attrs);
6789-
6790-
// @differentiable and @derivative
6791-
for (auto *attr : tempAttrs.getAttributes<DifferentiableAttr>()) {
6792-
auto *diffAttr = const_cast<DifferentiableAttr *>(attr);
6793-
diffAttr->setOriginalDeclaration(decl);
6794-
diffAttr->setParameterIndices(diffAttrParamIndicesMap[diffAttr]);
6795-
}
6796-
for (auto *attr : tempAttrs.getAttributes<DerivativeAttr>()) {
6797-
auto *derAttr = const_cast<DerivativeAttr *>(attr);
6798-
derAttr->setOriginalDeclaration(decl);
6799-
}
6800-
6788+
llvm::Error DeclDeserializer::finishRecursiveAttrs() {
68016789
// @abi
68026790
if (unresolvedABIAttr) {
68036791
auto abiDeclOrError = MF.getDeclChecked(unresolvedABIAttr->second);
68046792
if (!abiDeclOrError)
68056793
return abiDeclOrError.takeError();
68066794
unresolvedABIAttr->first->abiDecl = abiDeclOrError.get();
6807-
decl->recordABIAttr(unresolvedABIAttr->first);
68086795
}
68096796
if (ABIDeclCounterpartID != 0) {
68106797
// This decl is the `abiDecl` of an `ABIAttr`. Force the decl that `ABIAttr`
6811-
// belongs to so that `recordABIAttr()` will be called.
6798+
// belongs to so that `attachToDecl()` will be called.
68126799
auto counterpartOrError = MF.getDeclChecked(ABIDeclCounterpartID);
68136800
if (!counterpartOrError)
68146801
return counterpartOrError.takeError();
@@ -6865,7 +6852,7 @@ DeclDeserializer::getDeclCheckedImpl(
68656852
if (!declOrError) \
68666853
return declOrError; \
68676854
declOrOffset = declOrError.get(); \
6868-
if (auto finishError = finishRecursiveAttrs(declOrError.get(), DAttrs)) \
6855+
if (auto finishError = finishRecursiveAttrs()) \
68696856
return finishError; \
68706857
break; \
68716858
}

0 commit comments

Comments
 (0)