Skip to content

Commit 336af60

Browse files
authored
Merge pull request swiftlang#63154 from hborla/type-check-attached-macro-args
2 parents fa845d8 + 09287a1 commit 336af60

13 files changed

+142
-62
lines changed

include/swift/AST/MacroDeclaration.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ bool macroIntroducedNameRequiresArgument(MacroIntroducedDeclNameKind kind);
6666
StringRef getMacroIntroducedDeclNameString(
6767
MacroIntroducedDeclNameKind kind);
6868

69+
class CustomAttr;
70+
71+
/// Perform lookup to determine whether the given custom attribute refers to
72+
/// a macro declaration, and populate the \c macros vector with the lookup
73+
/// results that are attached macros.
74+
void findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc,
75+
llvm::TinyPtrVector<ValueDecl *> &macros);
76+
6977
class MacroIntroducedDeclName {
7078
public:
7179
using Kind = MacroIntroducedDeclNameKind;

include/swift/AST/TypeCheckRequests.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3128,6 +3128,24 @@ class CheckRedeclarationRequest
31283128
evaluator::SideEffect) const;
31293129
};
31303130

3131+
/// Resolve a given custom attribute to an attached macro declaration.
3132+
class ResolveAttachedMacroRequest
3133+
: public SimpleRequest<ResolveAttachedMacroRequest,
3134+
MacroDecl *(CustomAttr *, DeclContext *),
3135+
RequestFlags::Cached> {
3136+
public:
3137+
using SimpleRequest::SimpleRequest;
3138+
3139+
private:
3140+
friend SimpleRequest;
3141+
3142+
MacroDecl *
3143+
evaluate(Evaluator &evaluator, CustomAttr *attr, DeclContext *dc) const;
3144+
3145+
public:
3146+
bool isCached() const { return true; }
3147+
};
3148+
31313149
class ResolveTypeEraserTypeRequest
31323150
: public SimpleRequest<ResolveTypeEraserTypeRequest,
31333151
Type (ProtocolDecl *, TypeEraserAttr *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,9 @@ SWIFT_REQUEST(TypeChecker, PreCheckResultBuilderRequest,
340340
SWIFT_REQUEST(TypeChecker, ResolveImplicitMemberRequest,
341341
evaluator::SideEffect(NominalTypeDecl *, ImplicitMemberAction),
342342
Uncached, NoLocationInfo)
343+
SWIFT_REQUEST(TypeChecker, ResolveAttachedMacroRequest,
344+
MacroDecl *(CustomAttr *, DeclContext *),
345+
Cached, NoLocationInfo)
343346
SWIFT_REQUEST(TypeChecker, ResolveTypeEraserTypeRequest,
344347
Type(ProtocolDecl *, TypeEraserAttr *),
345348
SeparatelyCached, NoLocationInfo)

lib/AST/Attr.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,15 +2351,12 @@ bool CustomAttr::isAttachedMacro(const Decl *decl) const {
23512351
auto &ctx = decl->getASTContext();
23522352
auto *dc = decl->getInnermostDeclContext();
23532353

2354-
auto attrDecl = evaluateOrDefault(
2354+
auto *macroDecl = evaluateOrDefault(
23552355
ctx.evaluator,
2356-
CustomAttrDeclRequest{const_cast<CustomAttr *>(this), dc},
2356+
ResolveAttachedMacroRequest{const_cast<CustomAttr *>(this), dc},
23572357
nullptr);
23582358

2359-
if (!attrDecl)
2360-
return false;
2361-
2362-
return attrDecl.dyn_cast<MacroDecl *>();
2359+
return macroDecl != nullptr;
23632360
}
23642361

23652362
DeclarationAttr::DeclarationAttr(SourceLoc atLoc, SourceRange range,

lib/AST/NameLookup.cpp

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "swift/AST/ImportCache.h"
2727
#include "swift/AST/Initializer.h"
2828
#include "swift/AST/LazyResolver.h"
29+
#include "swift/AST/MacroDeclaration.h"
2930
#include "swift/AST/ModuleNameLookup.h"
3031
#include "swift/AST/NameLookupRequests.h"
3132
#include "swift/AST/ParameterList.h"
@@ -3040,17 +3041,15 @@ GenericParamListRequest::evaluate(Evaluator &evaluator, GenericContext *value) c
30403041
parsedGenericParams->getRAngleLoc());
30413042
}
30423043

3043-
/// Perform lookup to determine whether the given custom attribute refers to
3044-
/// a macro declaration, and return that macro declaration.
3045-
static MacroDecl *findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc) {
3044+
void swift::findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc,
3045+
llvm::TinyPtrVector<ValueDecl *> &macros) {
30463046
auto *identTypeRepr = dyn_cast_or_null<IdentTypeRepr>(attr->getTypeRepr());
30473047
if (!identTypeRepr)
3048-
return nullptr;
3048+
return;
30493049

30503050
// Look for macros at module scope. They can only occur at module scope, and
30513051
// we need to be sure not to trigger name lookup into type contexts along
30523052
// the way.
3053-
llvm::TinyPtrVector<MacroDecl *> macros;
30543053
auto moduleScopeDC = dc->getModuleScopeContext();
30553054
ASTContext &ctx = moduleScopeDC->getASTContext();
30563055
UnqualifiedLookupDescriptor descriptor(
@@ -3064,22 +3063,6 @@ static MacroDecl *findMacroForCustomAttr(CustomAttr *attr, DeclContext *dc) {
30643063
if (isAttachedMacro(macro->getMacroRoles()))
30653064
macros.push_back(macro);
30663065
}
3067-
3068-
if (macros.empty())
3069-
return nullptr;
3070-
3071-
if (macros.size() > 1) {
3072-
ctx.Diags.diagnose(attr->getLocation(), diag::ambiguous_macro_reference,
3073-
identTypeRepr->getNameRef().getFullName());
3074-
3075-
for (auto macro : macros) {
3076-
macro->diagnose(
3077-
diag::kind_declname_declared_here, macro->getDescriptiveKind(),
3078-
macro->getName());
3079-
}
3080-
}
3081-
3082-
return macros.front();
30833066
}
30843067

30853068
MacroOrNominalTypeDecl
@@ -3088,8 +3071,10 @@ CustomAttrDeclRequest::evaluate(Evaluator &evaluator,
30883071
// Look for names at module scope, so we don't trigger name lookup for
30893072
// nested scopes. At this point, we're looking to see whether there are
30903073
// any suitable macros.
3091-
if (auto macro = findMacroForCustomAttr(attr, dc))
3092-
return macro;
3074+
llvm::TinyPtrVector<ValueDecl *> macros;
3075+
findMacroForCustomAttr(attr, dc, macros);
3076+
if (!macros.empty())
3077+
return nullptr;
30933078

30943079
// Find the types referenced by the custom attribute.
30953080
auto &ctx = dc->getASTContext();

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3590,7 +3590,7 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
35903590
if (auto macro = dyn_cast<MacroDecl>(decl)) {
35913591
// Macro can only be used in an expansion. If we end up here, it's
35923592
// because we found a macro but are missing the leading '#'.
3593-
if (!locator->isForMacroExpansion()) {
3593+
if (!(locator->isForMacroExpansion() || locator->getAnchor().isImplicit())) {
35943594
// Record a fix here
35953595
(void)recordFix(MacroMissingPound::create(*this, macro, locator));
35963596
}

lib/Sema/TypeCheckAttr.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3558,19 +3558,20 @@ void AttributeChecker::visitCustomAttr(CustomAttr *attr) {
35583558
auto found = evaluateOrDefault(
35593559
Ctx.evaluator, CustomAttrDeclRequest{attr, dc}, nullptr);
35603560

3561-
// FIXME: deal with macros.
35623561
NominalTypeDecl *nominal = nullptr;
35633562
if (found) {
3564-
// FIXME: Do full checking of the macro arguments here by turning it into
3565-
// a macro expansion expression (?).
3566-
if (found.is<MacroDecl *>())
3567-
return;
3568-
35693563
nominal = found.dyn_cast<NominalTypeDecl *>();
35703564
}
35713565

3572-
// Diagnose errors.
35733566
if (!found) {
3567+
// Try resolving an attached macro attribute.
3568+
auto *macro = evaluateOrDefault(
3569+
Ctx.evaluator, ResolveAttachedMacroRequest{attr, dc}, nullptr);
3570+
if (macro || !attr->isValid())
3571+
return;
3572+
3573+
// Diagnose errors.
3574+
35743575
auto typeRepr = attr->getTypeRepr();
35753576

35763577
auto type = TypeResolution::forInterface(dc, TypeResolverContext::CustomAttr,

lib/Sema/TypeCheckMacros.cpp

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -318,18 +318,14 @@ bool ExpandMemberAttributeMacros::evaluate(Evaluator &evaluator,
318318
auto parentAttrs = parentDecl->getSemanticAttrs();
319319
for (auto customAttrConst: parentAttrs.getAttributes<CustomAttr>()) {
320320
auto customAttr = const_cast<CustomAttr *>(customAttrConst);
321-
auto customAttrDecl = evaluateOrDefault(
321+
auto *macroDecl = evaluateOrDefault(
322322
evaluator,
323-
CustomAttrDeclRequest{
323+
ResolveAttachedMacroRequest{
324324
customAttr,
325325
parentDecl->getInnermostDeclContext()
326326
},
327327
nullptr);
328328

329-
if (!customAttrDecl)
330-
continue;
331-
332-
auto macroDecl = customAttrDecl.dyn_cast<MacroDecl *>();
333329
if (!macroDecl)
334330
continue;
335331

@@ -364,10 +360,9 @@ static bool isFromExpansionOfMacro(SourceFile *sourceFile, MacroDecl *macro) {
364360
} else if (auto *macroAttr = sourceFile->getAttachedMacroAttribute()) {
365361
auto *decl = expansion.dyn_cast<Decl *>();
366362
auto &ctx = decl->getASTContext();
367-
auto attrDecl = evaluateOrDefault(ctx.evaluator,
368-
CustomAttrDeclRequest{macroAttr, decl->getDeclContext()},
363+
auto *macroDecl = evaluateOrDefault(ctx.evaluator,
364+
ResolveAttachedMacroRequest{macroAttr, decl->getDeclContext()},
369365
nullptr);
370-
auto *macroDecl = attrDecl.dyn_cast<MacroDecl *>();
371366
if (!macroDecl)
372367
return false;
373368

@@ -1086,3 +1081,43 @@ bool swift::expandAttributes(CustomAttr *attr, MacroDecl *macro, Decl *member) {
10861081

10871082
return addedAttributes;
10881083
}
1084+
1085+
MacroDecl *
1086+
ResolveAttachedMacroRequest::evaluate(Evaluator &evaluator,
1087+
CustomAttr *attr,
1088+
DeclContext *dc) const {
1089+
auto &ctx = dc->getASTContext();
1090+
llvm::TinyPtrVector<ValueDecl *> macros;
1091+
findMacroForCustomAttr(attr, dc, macros);
1092+
1093+
if (macros.empty())
1094+
return nullptr;
1095+
1096+
// Extract macro arguments from the attribute, or create an empty list.
1097+
ArgumentList *attrArgs;
1098+
if (attr->hasArgs()) {
1099+
attrArgs = attr->getArgs();
1100+
} else {
1101+
attrArgs = ArgumentList::createImplicit(ctx, {});
1102+
}
1103+
1104+
// Form an `OverloadedDeclRefExpr` with the filtered lookup result above
1105+
// to ensure @freestanding macros are not considered in overload resolution.
1106+
FunctionRefKind functionRefKind = FunctionRefKind::SingleApply;
1107+
auto *identTypeRepr = dyn_cast<IdentTypeRepr>(attr->getTypeRepr());
1108+
auto macroRefExpr = new (ctx) OverloadedDeclRefExpr(
1109+
macros, identTypeRepr->getNameLoc(), functionRefKind,
1110+
/*implicit*/true);
1111+
auto *call = CallExpr::createImplicit(ctx, macroRefExpr, attrArgs);
1112+
1113+
Expr *result = call;
1114+
TypeChecker::typeCheckExpression(result, dc);
1115+
1116+
if (auto *fn = dyn_cast<DeclRefExpr>(call->getFn()))
1117+
if (auto *macro = dyn_cast<MacroDecl>(fn->getDecl()))
1118+
return macro;
1119+
1120+
// If we couldn't resolve a macro decl, the attribute is invalid.
1121+
attr->setInvalid();
1122+
return nullptr;
1123+
}

lib/Sema/TypeCheckStorage.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,17 +3443,14 @@ StorageImplInfoRequest::evaluate(Evaluator &evaluator,
34433443
// Check for an accessor macro.
34443444
for (auto customAttrConst : storage->getSemanticAttrs().getAttributes<CustomAttr>()) {
34453445
auto customAttr = const_cast<CustomAttr *>(customAttrConst);
3446-
auto decl = evaluateOrDefault(
3446+
auto *macro = evaluateOrDefault(
34473447
evaluator,
3448-
CustomAttrDeclRequest{
3448+
ResolveAttachedMacroRequest{
34493449
customAttr,
34503450
storage->getInnermostDeclContext()
34513451
},
34523452
nullptr);
3453-
if (!decl)
3454-
continue;
34553453

3456-
auto macro = decl.dyn_cast<MacroDecl *>();
34573454
if (!macro)
34583455
continue;
34593456

lib/Sema/TypeCheckTypeWrapper.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ static void getTypeWrappers(NominalTypeDecl *decl,
124124
for (auto *attr : decl->getAttrs().getAttributes<CustomAttr>()) {
125125
auto *mutableAttr = const_cast<CustomAttr *>(attr);
126126
auto found = evaluateOrDefault(
127-
ctx.evaluator, CustomAttrDeclRequest{mutableAttr, decl}, nullptr);
127+
ctx.evaluator,
128+
CustomAttrDeclRequest{mutableAttr, decl->getDeclContext()},
129+
nullptr);
128130

129131
if (!found)
130132
continue;

0 commit comments

Comments
 (0)