Skip to content

Commit 2b8a1cc

Browse files
committed
[AST] Store owning Decl/DeclContext on CustomAttr
Introduce CustomAttrOwner that can store either a Decl for an attached attribute, or a DeclContext for e.g a type or closure attribute. Store this on CustomAttr such that we can query it from the name lookup requests.
1 parent 7cf780b commit 2b8a1cc

21 files changed

+133
-99
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -852,10 +852,11 @@ BridgedCDeclAttr BridgedCDeclAttr_createParsed(BridgedASTContext cContext,
852852
BridgedStringRef cName,
853853
bool underscored);
854854

855-
SWIFT_NAME(
856-
"BridgedCustomAttr.createParsed(_:atLoc:type:initContext:argumentList:)")
855+
SWIFT_NAME("BridgedCustomAttr.createParsed(atLoc:type:declContext:initContext:"
856+
"argumentList:)")
857857
BridgedCustomAttr BridgedCustomAttr_createParsed(
858-
BridgedASTContext cContext, swift::SourceLoc atLoc, BridgedTypeRepr cType,
858+
swift::SourceLoc atLoc, BridgedTypeRepr cType,
859+
BridgedDeclContext cDeclContext,
859860
BridgedNullableCustomAttributeInitializer cInitContext,
860861
BridgedNullableArgumentList cArgumentList);
861862

include/swift/AST/Attr.h

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class GenericFunctionType;
6868
class LazyConformanceLoader;
6969
class LazyMemberLoader;
7070
class ModuleDecl;
71+
class NominalTypeDecl;
7172
class PatternBindingInitializer;
7273
class TrailingWhereClause;
7374
class TypeExpr;
@@ -2272,34 +2273,63 @@ class ClangImporterSynthesizedTypeAttr : public DeclAttribute {
22722273
}
22732274
};
22742275

2276+
/// The owning decl for a given custom attribute, or a DeclContext for a
2277+
/// custom attribute in e.g a closure or inheritance clause.
2278+
class CustomAttrOwner final {
2279+
llvm::PointerUnion<Decl *, DeclContext *> Owner;
2280+
2281+
public:
2282+
CustomAttrOwner() : Owner(nullptr) {}
2283+
CustomAttrOwner(Decl *D) : Owner(D) {}
2284+
CustomAttrOwner(DeclContext *DC) : Owner(DC) {}
2285+
2286+
/// If the owner is a declaration, returns it, \c nullptr otherwise.
2287+
Decl *getAsDecl() const { return Owner.dyn_cast<Decl *>(); }
2288+
2289+
/// Retrieve the DeclContext for the CustomAttr.
2290+
DeclContext *getDeclContext() const;
2291+
};
2292+
22752293
/// Defines a custom attribute.
22762294
class CustomAttr final : public DeclAttribute {
22772295
TypeExpr *typeExpr;
22782296
ArgumentList *argList;
2297+
CustomAttrOwner owner;
22792298
CustomAttributeInitializer *initContext;
22802299
Expr *semanticInit = nullptr;
22812300

22822301
mutable unsigned isArgUnsafeBit : 1;
22832302

22842303
CustomAttr(SourceLoc atLoc, SourceRange range, TypeExpr *type,
2285-
CustomAttributeInitializer *initContext, ArgumentList *argList,
2286-
bool implicit);
2304+
CustomAttrOwner owner, CustomAttributeInitializer *initContext,
2305+
ArgumentList *argList, bool implicit);
22872306

22882307
public:
22892308
static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeExpr *type,
2290-
bool implicit = false) {
2291-
return create(ctx, atLoc, type, /*initContext*/ nullptr,
2309+
CustomAttrOwner owner, bool implicit = false) {
2310+
return create(ctx, atLoc, type, owner, /*initContext*/ nullptr,
22922311
/*argList*/ nullptr, implicit);
22932312
}
22942313

22952314
static CustomAttr *create(ASTContext &ctx, SourceLoc atLoc, TypeExpr *type,
2315+
CustomAttrOwner owner,
22962316
CustomAttributeInitializer *initContext,
22972317
ArgumentList *argList, bool implicit = false);
22982318

22992319
TypeExpr *getTypeExpr() const { return typeExpr; }
23002320
TypeRepr *getTypeRepr() const;
23012321
Type getType() const;
23022322

2323+
/// Retrieve the Decl or DeclContext owner for the attribute.
2324+
CustomAttrOwner getOwner() const { return owner; }
2325+
void setOwner(CustomAttrOwner newOwner) { owner = newOwner; }
2326+
2327+
ASTContext &getASTContext() const;
2328+
2329+
/// Retrieve the NominalTypeDecl the CustomAttr refers to, or \c nullptr if
2330+
/// it doesn't refer to one (which can be the case for e.g macro attrs).
2331+
NominalTypeDecl *getNominalDecl() const;
2332+
23032333
/// Destructure an attribute's type repr for a macro reference.
23042334
///
23052335
/// For a 1-level member type repr whose base and member are both identifier
@@ -2336,7 +2366,8 @@ class CustomAttr final : public DeclAttribute {
23362366
CustomAttr *clone(ASTContext &ctx) const {
23372367
assert(argList == nullptr &&
23382368
"Cannot clone custom attribute with an argument list");
2339-
return create(ctx, AtLoc, getTypeExpr(), initContext, argList, isImplicit());
2369+
return create(ctx, AtLoc, getTypeExpr(), owner, initContext, argList,
2370+
isImplicit());
23402371
}
23412372

23422373
bool canClone() const { return argList == nullptr; }

include/swift/AST/NameLookupRequests.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -350,19 +350,18 @@ class TypeDeclsFromWhereClauseRequest :
350350

351351
/// Request the nominal type declaration to which the given custom
352352
/// attribute refers.
353-
class CustomAttrNominalRequest :
354-
public SimpleRequest<CustomAttrNominalRequest,
355-
NominalTypeDecl *(CustomAttr *, DeclContext *),
356-
RequestFlags::Cached> {
353+
class CustomAttrNominalRequest
354+
: public SimpleRequest<CustomAttrNominalRequest,
355+
NominalTypeDecl *(CustomAttr *),
356+
RequestFlags::Cached> {
357357
public:
358358
using SimpleRequest::SimpleRequest;
359359

360360
private:
361361
friend SimpleRequest;
362362

363363
// Evaluation.
364-
NominalTypeDecl *
365-
evaluate(Evaluator &evaluator, CustomAttr *attr, DeclContext *dc) const;
364+
NominalTypeDecl *evaluate(Evaluator &evaluator, CustomAttr *attr) const;
366365

367366
public:
368367
// Caching

include/swift/AST/NameLookupTypeIDZone.def

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ SWIFT_REQUEST(NameLookup, AnyObjectLookupRequest,
1919
QualifiedLookupResult(const DeclContext *, DeclName, NLOptions),
2020
Uncached, NoLocationInfo)
2121
SWIFT_REQUEST(NameLookup, CustomAttrNominalRequest,
22-
NominalTypeDecl *(CustomAttr *, DeclContext *), Cached,
23-
NoLocationInfo)
22+
NominalTypeDecl *(CustomAttr *), Cached, NoLocationInfo)
2423
SWIFT_REQUEST(NameLookup, DirectLookupRequest,
2524
TinyPtrVector<ValueDecl *>(DirectLookupDescriptor), Uncached,
2625
NoLocationInfo)

lib/AST/Attr.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3053,16 +3053,26 @@ bool ImplementsAttr::isEquivalent(const ImplementsAttr *other,
30533053
&& getProtocol(DC) == other->getProtocol(DC);
30543054
}
30553055

3056+
DeclContext *CustomAttrOwner::getDeclContext() const {
3057+
ASSERT(!Owner.isNull());
3058+
if (auto *D = getAsDecl())
3059+
return D->getDeclContext();
3060+
3061+
return Owner.dyn_cast<DeclContext *>();
3062+
}
3063+
30563064
CustomAttr::CustomAttr(SourceLoc atLoc, SourceRange range, TypeExpr *type,
3065+
CustomAttrOwner owner,
30573066
CustomAttributeInitializer *initContext,
30583067
ArgumentList *argList, bool implicit)
30593068
: DeclAttribute(DeclAttrKind::Custom, atLoc, range, implicit),
3060-
typeExpr(type), argList(argList), initContext(initContext) {
3069+
typeExpr(type), argList(argList), owner(owner), initContext(initContext) {
30613070
assert(type);
30623071
isArgUnsafeBit = false;
30633072
}
30643073

30653074
CustomAttr *CustomAttr::create(ASTContext &ctx, SourceLoc atLoc, TypeExpr *type,
3075+
CustomAttrOwner owner,
30663076
CustomAttributeInitializer *initContext,
30673077
ArgumentList *argList, bool implicit) {
30683078
assert(type);
@@ -3071,7 +3081,7 @@ CustomAttr *CustomAttr::create(ASTContext &ctx, SourceLoc atLoc, TypeExpr *type,
30713081
range.End = argList->getEndLoc();
30723082

30733083
return new (ctx)
3074-
CustomAttr(atLoc, range, type, initContext, argList, implicit);
3084+
CustomAttr(atLoc, range, type, owner, initContext, argList, implicit);
30753085
}
30763086

30773087
std::pair<UnqualifiedIdentTypeRepr *, DeclRefTypeRepr *>
@@ -3091,6 +3101,16 @@ CustomAttr::destructureMacroRef() {
30913101
return {nullptr, nullptr};
30923102
}
30933103

3104+
ASTContext &CustomAttr::getASTContext() const {
3105+
return getOwner().getDeclContext()->getASTContext();
3106+
}
3107+
3108+
NominalTypeDecl *CustomAttr::getNominalDecl() const {
3109+
auto &eval = getASTContext().evaluator;
3110+
auto *mutThis = const_cast<CustomAttr *>(this);
3111+
return evaluateOrDefault(eval, CustomAttrNominalRequest{mutThis}, nullptr);
3112+
}
3113+
30943114
TypeRepr *CustomAttr::getTypeRepr() const { return typeExpr->getTypeRepr(); }
30953115
Type CustomAttr::getType() const { return typeExpr->getInstanceType(); }
30963116

lib/AST/Bridging/DeclAttributeBridging.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,12 +197,15 @@ BridgedCDeclAttr BridgedCDeclAttr_createParsed(BridgedASTContext cContext,
197197
}
198198

199199
BridgedCustomAttr BridgedCustomAttr_createParsed(
200-
BridgedASTContext cContext, SourceLoc atLoc, BridgedTypeRepr cType,
200+
SourceLoc atLoc, BridgedTypeRepr cType, BridgedDeclContext cDeclContext,
201201
BridgedNullableCustomAttributeInitializer cInitContext,
202202
BridgedNullableArgumentList cArgumentList) {
203-
ASTContext &context = cContext.unbridged();
203+
DeclContext *DC = cDeclContext.unbridged();
204+
ASTContext &context = DC->getASTContext();
205+
// Note we set a DeclContext as the owner, which we'll change to the attached
206+
// Decl if necessary when attaching the attributes.
204207
return CustomAttr::create(
205-
context, atLoc, new (context) TypeExpr(cType.unbridged()),
208+
context, atLoc, new (context) TypeExpr(cType.unbridged()), /*owner*/ DC,
206209
cInitContext.unbridged(), cArgumentList.unbridged());
207210
}
208211

lib/AST/Decl.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ void Decl::attachParsedAttrs(DeclAttributes attrs) {
442442
attr->setOriginalDeclaration(this);
443443
for (auto attr : attrs.getAttributes<ABIAttr, /*AllowInvalid=*/true>())
444444
recordABIAttr(attr);
445+
for (auto *attr : attrs.getAttributes<CustomAttr>())
446+
attr->setOwner(this);
445447

446448
// @implementation requires an explicit @objc attribute, but
447449
// @_objcImplementation didn't. Insert one if necessary.
@@ -573,8 +575,7 @@ Type Decl::getResolvedCustomAttrType(CustomAttr *attr) const {
573575
return ty;
574576

575577
auto dc = getDeclContext();
576-
auto *nominal = evaluateOrDefault(
577-
getASTContext().evaluator, CustomAttrNominalRequest{attr, dc}, nullptr);
578+
auto *nominal = attr->getNominalDecl();
578579
if (!nominal)
579580
return Type();
580581

@@ -8703,11 +8704,7 @@ VarDecl::getAttachedPropertyWrapperTypeInfo(unsigned i) const {
87038704
if (i >= attrs.size())
87048705
return PropertyWrapperTypeInfo();
87058706

8706-
auto attr = attrs[i];
8707-
auto dc = getDeclContext();
8708-
ASTContext &ctx = getASTContext();
8709-
nominal = evaluateOrDefault(
8710-
ctx.evaluator, CustomAttrNominalRequest{attr, dc}, nullptr);
8707+
nominal = attrs[i]->getNominalDecl();
87118708
}
87128709

87138710
if (!nominal)

lib/AST/NameLookup.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3971,9 +3971,11 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
39713971
parsedGenericParams->getRAngleLoc());
39723972
}
39733973

3974-
NominalTypeDecl *
3975-
CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
3976-
CustomAttr *attr, DeclContext *dc) const {
3974+
NominalTypeDecl *CustomAttrNominalRequest::evaluate(Evaluator &evaluator,
3975+
CustomAttr *attr) const {
3976+
auto owner = attr->getOwner();
3977+
auto *dc = owner.getDeclContext();
3978+
39773979
// Look for names at module scope, so we don't trigger name lookup for
39783980
// nested scopes. At this point, we're looking to see whether there are
39793981
// any suitable macros.

lib/ASTGen/Sources/ASTGen/DeclAttrs.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2285,9 +2285,9 @@ extension ASTGenVisitor {
22852285
}
22862286

22872287
return .createParsed(
2288-
self.ctx,
22892288
atLoc: self.generateSourceLoc(node.atSign),
22902289
type: type,
2290+
declContext: declContext,
22912291
initContext: initContext.asNullable,
22922292
argumentList: argList.asNullable
22932293
)

lib/ClangImporter/ClangImporter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6262,8 +6262,8 @@ void cloneImportedAttributes(ValueDecl *fromDecl, ValueDecl* toDecl) {
62626262
case DeclAttrKind::Custom: {
62636263
CustomAttr *cAttr = cast<CustomAttr>(attr);
62646264
attrs.add(CustomAttr::create(context, SourceLoc(), cAttr->getTypeExpr(),
6265-
cAttr->getInitContext(), cAttr->getArgs(),
6266-
true));
6265+
/*owner*/ toDecl, cAttr->getInitContext(),
6266+
cAttr->getArgs(), /*implicit*/ true));
62676267
break;
62686268
}
62696269
case DeclAttrKind::DiscardableResult: {

0 commit comments

Comments
 (0)