Skip to content

Commit ac218c2

Browse files
authored
Merge pull request swiftlang#65453 from rintaro/macros-expandexpr-request-rdar108530760
[Macros] Requestify MacroExpansionExpr expansion
2 parents 32811ba + 35db928 commit ac218c2

File tree

8 files changed

+126
-61
lines changed

8 files changed

+126
-61
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3930,6 +3930,26 @@ class ExpandMacroExpansionDeclRequest
39303930
void noteCycleStep(DiagnosticEngine &diags) const;
39313931
};
39323932

3933+
/// Expand a 'MacroExpansionExpr',
3934+
class ExpandMacroExpansionExprRequest
3935+
: public SimpleRequest<ExpandMacroExpansionExprRequest,
3936+
Optional<unsigned>(MacroExpansionExpr *),
3937+
RequestFlags::Cached> {
3938+
public:
3939+
using SimpleRequest::SimpleRequest;
3940+
3941+
private:
3942+
friend SimpleRequest;
3943+
3944+
Optional<unsigned>
3945+
evaluate(Evaluator &evaluator, MacroExpansionExpr *mee) const;
3946+
3947+
public:
3948+
bool isCached() const { return true; }
3949+
void diagnoseCycle(DiagnosticEngine &diags) const;
3950+
void noteCycleStep(DiagnosticEngine &diags) const;
3951+
};
3952+
39333953
/// Expand all accessor macros attached to the given declaration.
39343954
///
39353955
/// Produces the set of macro expansion buffer IDs.

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,9 @@ SWIFT_REQUEST(TypeChecker, ExternalMacroDefinitionRequest,
439439
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionDeclRequest,
440440
ArrayRef<Decl *>(MacroExpansionDecl *),
441441
Cached, NoLocationInfo)
442+
SWIFT_REQUEST(TypeChecker, ExpandMacroExpansionExprRequest,
443+
ArrayRef<Decl *>(MacroExpansionExpr *),
444+
Cached, NoLocationInfo)
442445
SWIFT_REQUEST(TypeChecker, ExpandMemberAttributeMacros,
443446
ArrayRef<unsigned>(Decl *),
444447
Cached, NoLocationInfo)

lib/AST/TypeCheckRequests.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,6 +1833,22 @@ void ExpandMacroExpansionDeclRequest::noteCycleStep(DiagnosticEngine &diags) con
18331833
decl->getMacroName().getFullName());
18341834
}
18351835

1836+
void ExpandMacroExpansionExprRequest::diagnoseCycle(DiagnosticEngine &diags) const {
1837+
auto expr = std::get<0>(getStorage());
1838+
diags.diagnose(expr->getStartLoc(),
1839+
diag::macro_expand_circular_reference,
1840+
"freestanding",
1841+
expr->getMacroName().getFullName());
1842+
}
1843+
1844+
void ExpandMacroExpansionExprRequest::noteCycleStep(DiagnosticEngine &diags) const {
1845+
auto expr = std::get<0>(getStorage());
1846+
diags.diagnose(expr->getStartLoc(),
1847+
diag::macro_expand_circular_reference_through,
1848+
"freestanding",
1849+
expr->getMacroName().getFullName());
1850+
}
1851+
18361852
void ExpandAccessorMacros::diagnoseCycle(DiagnosticEngine &diags) const {
18371853
auto decl = std::get<0>(getStorage());
18381854
diags.diagnose(decl->getLoc(),

lib/Refactoring/Refactoring.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8622,11 +8622,9 @@ bool RefactoringActionAddAsyncWrapper::performChange() {
86228622
/// expression.
86238623
static Optional<unsigned> getMacroExpansionBuffer(
86248624
SourceManager &sourceMgr, MacroExpansionExpr *expansion) {
8625-
if (auto rewritten = expansion->getRewritten()) {
8626-
return sourceMgr.findBufferContainingLoc(rewritten->getStartLoc());
8627-
}
8628-
8629-
return None;
8625+
return evaluateOrDefault(
8626+
expansion->getDeclContext()->getASTContext().evaluator,
8627+
ExpandMacroExpansionExprRequest{expansion}, {});
86308628
}
86318629

86328630
/// Retrieve the macro expansion buffer for the given macro expansion

lib/Sema/CSApply.cpp

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,13 +2937,14 @@ namespace {
29372937

29382938
auto macro = cast<MacroDecl>(overload.choice.getDecl());
29392939
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
2940-
if (auto newExpr = expandMacroExpr(dc, expr, macroRef, expandedType)) {
2941-
auto expansion = new (ctx) MacroExpansionExpr(
2942-
dc, expr->getStartLoc(), DeclNameRef(macro->getName()),
2943-
DeclNameLoc(expr->getLoc()), SourceLoc(), { }, SourceLoc(),
2944-
nullptr, MacroRole::Expression, /*isImplicit=*/true, expandedType);
2945-
expansion->setMacroRef(macroRef);
2946-
expansion->setRewritten(newExpr);
2940+
auto expansion = new (ctx) MacroExpansionExpr(
2941+
dc, expr->getStartLoc(), DeclNameRef(macro->getName()),
2942+
DeclNameLoc(expr->getLoc()), SourceLoc(), {}, SourceLoc(), nullptr,
2943+
MacroRole::Expression, /*isImplicit=*/true, expandedType);
2944+
expansion->setMacroRef(macroRef);
2945+
(void)evaluateOrDefault(
2946+
ctx.evaluator, ExpandMacroExpansionExprRequest{expansion}, None);
2947+
if (expansion->getRewritten()) {
29472948
cs.cacheExprTypes(expansion);
29482949
return expansion;
29492950
}
@@ -5386,23 +5387,11 @@ namespace {
53865387
auto macro = cast<MacroDecl>(overload.choice.getDecl());
53875388
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
53885389
E->setMacroRef(macroRef);
5390+
E->setType(expandedType);
53895391

53905392
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
5391-
if (macro->getMacroRoles().contains(MacroRole::Expression)) {
5392-
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
5393-
E->setRewritten(newExpr);
5394-
}
5395-
}
5396-
// For a non-expression macro, expand it as a declaration.
5397-
else if (macro->getMacroRoles().contains(MacroRole::Declaration) ||
5398-
macro->getMacroRoles().contains(MacroRole::CodeItem)) {
5399-
if (!E->getSubstituteDecl()) {
5400-
auto *med = E->createSubstituteDecl();
5401-
TypeChecker::typeCheckDecl(med);
5402-
}
5403-
}
5404-
// Other macro roles may also be encountered here, as they use
5405-
// `MacroExpansionExpr` for resolution. In those cases, do not expand.
5393+
(void)evaluateOrDefault(cs.getASTContext().evaluator,
5394+
ExpandMacroExpansionExprRequest{E}, None);
54065395
}
54075396

54085397
cs.cacheExprTypes(E);

lib/Sema/TypeCheckMacros.cpp

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,35 @@ static std::string adjustMacroExpansionBufferName(StringRef name) {
456456
return result;
457457
}
458458

459+
Optional<unsigned>
460+
ExpandMacroExpansionExprRequest::evaluate(Evaluator &evaluator,
461+
MacroExpansionExpr *mee) const {
462+
ConcreteDeclRef macroRef = mee->getMacroRef();
463+
assert(macroRef && isa<MacroDecl>(macroRef.getDecl()) &&
464+
"MacroRef should be set before expansion");
465+
466+
auto *macro = cast<MacroDecl>(macroRef.getDecl());
467+
if (macro->getMacroRoles().contains(MacroRole::Expression)) {
468+
return expandMacroExpr(mee);
469+
}
470+
// For a non-expression macro, expand it as a declaration.
471+
else if (macro->getMacroRoles().contains(MacroRole::Declaration) ||
472+
macro->getMacroRoles().contains(MacroRole::CodeItem)) {
473+
if (!mee->getSubstituteDecl()) {
474+
auto *med = mee->createSubstituteDecl();
475+
TypeChecker::typeCheckDecl(med);
476+
}
477+
// Return the expanded buffer ID.
478+
return evaluateOrDefault(
479+
evaluator, ExpandMacroExpansionDeclRequest(mee->getSubstituteDecl()),
480+
None);
481+
}
482+
483+
// Other macro roles may also be encountered here, as they use
484+
// `MacroExpansionExpr` for resolution. In those cases, do not expand.
485+
return None;
486+
}
487+
459488
ArrayRef<unsigned> ExpandMemberAttributeMacros::evaluate(Evaluator &evaluator,
460489
Decl *decl) const {
461490
if (decl->isImplicit())
@@ -666,22 +695,24 @@ static std::string expandMacroDefinition(
666695
return expandedResult;
667696
}
668697

669-
Expr *swift::expandMacroExpr(
670-
DeclContext *dc, Expr *expr, ConcreteDeclRef macroRef, Type expandedType
671-
) {
698+
Optional<unsigned>
699+
swift::expandMacroExpr(MacroExpansionExpr *mee) {
700+
DeclContext *dc = mee->getDeclContext();
672701
ASTContext &ctx = dc->getASTContext();
673702
SourceManager &sourceMgr = ctx.SourceMgr;
703+
ConcreteDeclRef macroRef = mee->getMacroRef();
704+
Type expandedType = mee->getType();
674705

675706
auto moduleDecl = dc->getParentModule();
676-
auto sourceFile = moduleDecl->getSourceFileContainingLocation(expr->getLoc());
707+
auto sourceFile = moduleDecl->getSourceFileContainingLocation(mee->getLoc());
677708
if (!sourceFile)
678-
return nullptr;
709+
return None;
679710

680711
MacroDecl *macro = cast<MacroDecl>(macroRef.getDecl());
681712

682713
if (isFromExpansionOfMacro(sourceFile, macro, MacroRole::Expression)) {
683-
ctx.Diags.diagnose(expr->getLoc(), diag::macro_recursive, macro->getName());
684-
return nullptr;
714+
ctx.Diags.diagnose(mee->getLoc(), diag::macro_recursive, macro->getName());
715+
return None;
685716
}
686717

687718
// Evaluate the macro.
@@ -690,34 +721,33 @@ Expr *swift::expandMacroExpr(
690721
/// The discriminator used for the macro.
691722
LazyValue<std::string> discriminator([&]() -> std::string {
692723
#if SWIFT_SWIFT_PARSER
693-
if (auto expansionExpr = dyn_cast<MacroExpansionExpr>(expr)) {
694-
Mangle::ASTMangler mangler;
695-
return mangler.mangleMacroExpansion(expansionExpr);
696-
}
697-
#endif
724+
Mangle::ASTMangler mangler;
725+
return mangler.mangleMacroExpansion(mee);
726+
#else
698727
return "";
728+
#endif
699729
});
700730

701731
auto macroDef = macro->getDefinition();
702732
switch (macroDef.kind) {
703733
case MacroDefinition::Kind::Undefined:
704734
case MacroDefinition::Kind::Invalid:
705735
// Already diagnosed as an error elsewhere.
706-
return nullptr;
736+
return None;
707737

708738
case MacroDefinition::Kind::Builtin: {
709739
switch (macroDef.getBuiltinKind()) {
710740
case BuiltinMacroKind::ExternalMacro:
711741
ctx.Diags.diagnose(
712-
expr->getLoc(), diag::external_macro_outside_macro_definition);
713-
return nullptr;
742+
mee->getLoc(), diag::external_macro_outside_macro_definition);
743+
return None;
714744
}
715745
}
716746

717747
case MacroDefinition::Kind::Expanded: {
718748
// Expand the definition with the given arguments.
719749
auto result = expandMacroDefinition(
720-
macroDef.getExpanded(), macro, expr->getArgs());
750+
macroDef.getExpanded(), macro, mee->getArgs());
721751
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
722752
result, adjustMacroExpansionBufferName(*discriminator));
723753
break;
@@ -732,41 +762,41 @@ Expr *swift::expandMacroExpr(
732762
auto externalDef = evaluateOrDefault(ctx.evaluator, request, None);
733763
if (!externalDef) {
734764
ctx.Diags.diagnose(
735-
expr->getLoc(), diag::external_macro_not_found,
765+
mee->getLoc(), diag::external_macro_not_found,
736766
external.moduleName.str(),
737767
external.macroTypeName.str(),
738768
macro->getName()
739769
);
740770
macro->diagnose(diag::decl_declared_here, macro->getName());
741-
return nullptr;
771+
return None;
742772
}
743773

744774
#if SWIFT_SWIFT_PARSER
745-
PrettyStackTraceExpr debugStack(ctx, "expanding macro", expr);
775+
PrettyStackTraceExpr debugStack(ctx, "expanding macro", mee);
746776

747777
// Builtin macros are handled via ASTGen.
748778
auto astGenSourceFile = sourceFile->exportedSourceFile;
749779
if (!astGenSourceFile)
750-
return nullptr;
780+
return None;
751781

752782
const char *evaluatedSourceAddress;
753783
ptrdiff_t evaluatedSourceLength;
754784
swift_ASTGen_expandFreestandingMacro(
755785
&ctx.Diags, externalDef->opaqueHandle,
756786
static_cast<uint32_t>(externalDef->kind), discriminator->data(),
757787
discriminator->size(), astGenSourceFile,
758-
expr->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
788+
mee->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
759789
&evaluatedSourceLength);
760790
if (!evaluatedSourceAddress)
761-
return nullptr;
791+
return None;
762792
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
763793
{evaluatedSourceAddress, (size_t)evaluatedSourceLength},
764794
adjustMacroExpansionBufferName(*discriminator));
765795
free((void *)evaluatedSourceAddress);
766796
break;
767797
#else
768-
ctx.Diags.diagnose(expr->getLoc(), diag::macro_unsupported);
769-
return nullptr;
798+
ctx.Diags.diagnose(mee->getLoc(), diag::macro_unsupported);
799+
return None;
770800
#endif
771801
}
772802
}
@@ -787,9 +817,9 @@ Expr *swift::expandMacroExpr(
787817
GeneratedSourceInfo sourceInfo{
788818
GeneratedSourceInfo::ExpressionMacroExpansion,
789819
Lexer::getCharSourceRangeFromSourceRange(
790-
sourceMgr, expr->getSourceRange()),
820+
sourceMgr, mee->getSourceRange()),
791821
macroBufferRange,
792-
ASTNode(expr).getOpaqueValue(),
822+
ASTNode(mee).getOpaqueValue(),
793823
dc
794824
};
795825
sourceMgr.setGeneratedSourceInfo(macroBufferID, sourceInfo);
@@ -807,7 +837,7 @@ Expr *swift::expandMacroExpr(
807837
if (topLevelItems.size() != 1) {
808838
ctx.Diags.diagnose(
809839
macroBufferRange.getStart(), diag::expected_macro_expansion_expr);
810-
return nullptr;
840+
return macroBufferID;
811841
}
812842

813843
auto codeItem = topLevelItems.front();
@@ -817,7 +847,7 @@ Expr *swift::expandMacroExpr(
817847
if (!expandedExpr) {
818848
ctx.Diags.diagnose(
819849
macroBufferRange.getStart(), diag::expected_macro_expansion_expr);
820-
return nullptr;
850+
return macroBufferID;
821851
}
822852

823853
// Type-check the expanded expression.
@@ -834,12 +864,15 @@ Expr *swift::expandMacroExpr(
834864
Type realExpandedType = TypeChecker::typeCheckExpression(
835865
expandedExpr, dc, contextualType);
836866
if (!realExpandedType)
837-
return nullptr;
867+
return macroBufferID;
838868

839869
assert((expandedType->isEqual(realExpandedType) ||
840870
realExpandedType->hasError()) &&
841871
"Type checking changed the result type?");
842-
return expandedExpr;
872+
873+
mee->setRewritten(expandedExpr);
874+
875+
return macroBufferID;
843876
}
844877

845878
/// Expands the given macro expansion declaration.

lib/Sema/TypeCheckMacros.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,15 @@ namespace swift {
2929
class CustomAttr;
3030
class Expr;
3131
class MacroDecl;
32+
class MacroExpansionExpr;
3233
class MacroExpansionDecl;
3334
class TypeRepr;
3435

3536
/// Expands the given macro expression and type-check the result with
3637
/// the given expanded type.
3738
///
38-
/// \returns the type-checked replacement expression, or NULL if the
39-
// macro could not be expanded.
40-
Expr *expandMacroExpr(
41-
DeclContext *dc, Expr *expr, ConcreteDeclRef macroRef, Type expandedType);
39+
/// \returns Expansion buffer ID if expansion succeeded, \p None if failed.
40+
Optional<unsigned> expandMacroExpr(MacroExpansionExpr *mee);
4241

4342
/// Expands the given macro expansion declaration.
4443
///

test/SourceKit/Macros/macro_basic.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition"
5656

5757
#anonymousTypes { "hello" }
5858

59+
// This should fails to typecheck because `#assert("foo")` is expanded to `assert("foo")`, but `assert(_:)` expects 'Bool' argument
60+
@freestanding(expression) macro assert(_: String) = #externalMacro(module: "MacroDefinition", type: "AssertMacro")
61+
#assert("foobar")
62+
5963
// REQUIRES: swift_swift_parser, executable_test, shell
6064

6165
// RUN: %empty-directory(%t)
@@ -265,3 +269,6 @@ macro anonymousTypes(_: () -> String) = #externalMacro(module: "MacroDefinition"
265269
// RUN: %sourcekitd-test -req=format -line=23 -length=1 %s | %FileCheck -check-prefix=FORMATTED %s
266270
// FORMATTED: " var x: Int"
267271

272+
//##-- Expansion on "fails to typecheck" macro expression
273+
// RUN: %sourcekitd-test -req=refactoring.expand.macro -pos=61:2 %s -- ${COMPILER_ARGS[@]} | %FileCheck -check-prefix=ERRONEOUS_EXPAND %s
274+
// ERRONEOUS_EXPAND: 61:1-61:18 (@__swiftmacro_9MacroUser6assertfMf_.swift) "assert("foobar")"

0 commit comments

Comments
 (0)