Skip to content

Commit 73a82e6

Browse files
committed
[Macros] Requestify MacroExpansionExpr expansion
The request returns the expanded buffer ID even if it failed to typecheck the expanded buffer. This makes refactoring 'Expand Macro' work regardless of the typechecking results. rdar://108530760
1 parent d90134c commit 73a82e6

File tree

8 files changed

+99
-44
lines changed

8 files changed

+99
-44
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: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2937,13 +2937,13 @@ 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(),
2943+
nullptr, MacroRole::Expression, /*isImplicit=*/true, expandedType);
2944+
expansion->setMacroRef(macroRef);
2945+
(void)evaluateOrDefault(ctx.evaluator, ExpandMacroExpansionExprRequest {expansion}, None);
2946+
if (expansion->getRewritten()) {
29472947
cs.cacheExprTypes(expansion);
29482948
return expansion;
29492949
}
@@ -5386,12 +5386,12 @@ namespace {
53865386
auto macro = cast<MacroDecl>(overload.choice.getDecl());
53875387
ConcreteDeclRef macroRef = resolveConcreteDeclRef(macro, locator);
53885388
E->setMacroRef(macroRef);
5389+
E->setType(expandedType);
53895390

53905391
if (!cs.Options.contains(ConstraintSystemFlags::DisableMacroExpansions)) {
53915392
if (macro->getMacroRoles().contains(MacroRole::Expression)) {
5392-
if (auto newExpr = expandMacroExpr(dc, E, macroRef, expandedType)) {
5393-
E->setRewritten(newExpr);
5394-
}
5393+
(void)evaluateOrDefault(cs.getASTContext().evaluator,
5394+
ExpandMacroExpansionExprRequest {E}, None);
53955395
}
53965396
// For a non-expression macro, expand it as a declaration.
53975397
else if (macro->getMacroRoles().contains(MacroRole::Declaration) ||

lib/Sema/TypeCheckMacros.cpp

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

459+
Optional<unsigned>
460+
ExpandMacroExpansionExprRequest::evaluate(Evaluator &evaluator,
461+
MacroExpansionExpr *mee) const {
462+
assert(mee->getMacroRef() && "MacroRef should be set before expansion");
463+
return expandMacroExpr(mee);
464+
}
465+
459466
ArrayRef<unsigned> ExpandMemberAttributeMacros::evaluate(Evaluator &evaluator,
460467
Decl *decl) const {
461468
if (decl->isImplicit())
@@ -666,22 +673,24 @@ static std::string expandMacroDefinition(
666673
return expandedResult;
667674
}
668675

669-
Expr *swift::expandMacroExpr(
670-
DeclContext *dc, Expr *expr, ConcreteDeclRef macroRef, Type expandedType
671-
) {
676+
Optional<unsigned>
677+
swift::expandMacroExpr(MacroExpansionExpr *mee) {
678+
DeclContext *dc = mee->getDeclContext();
672679
ASTContext &ctx = dc->getASTContext();
673680
SourceManager &sourceMgr = ctx.SourceMgr;
681+
ConcreteDeclRef macroRef = mee->getMacroRef();
682+
Type expandedType = mee->getType();
674683

675684
auto moduleDecl = dc->getParentModule();
676-
auto sourceFile = moduleDecl->getSourceFileContainingLocation(expr->getLoc());
685+
auto sourceFile = moduleDecl->getSourceFileContainingLocation(mee->getLoc());
677686
if (!sourceFile)
678-
return nullptr;
687+
return None;
679688

680689
MacroDecl *macro = cast<MacroDecl>(macroRef.getDecl());
681690

682691
if (isFromExpansionOfMacro(sourceFile, macro, MacroRole::Expression)) {
683-
ctx.Diags.diagnose(expr->getLoc(), diag::macro_recursive, macro->getName());
684-
return nullptr;
692+
ctx.Diags.diagnose(mee->getLoc(), diag::macro_recursive, macro->getName());
693+
return None;
685694
}
686695

687696
// Evaluate the macro.
@@ -690,7 +699,7 @@ Expr *swift::expandMacroExpr(
690699
/// The discriminator used for the macro.
691700
LazyValue<std::string> discriminator([&]() -> std::string {
692701
#if SWIFT_SWIFT_PARSER
693-
if (auto expansionExpr = dyn_cast<MacroExpansionExpr>(expr)) {
702+
if (auto expansionExpr = dyn_cast<MacroExpansionExpr>(mee)) {
694703
Mangle::ASTMangler mangler;
695704
return mangler.mangleMacroExpansion(expansionExpr);
696705
}
@@ -703,21 +712,21 @@ Expr *swift::expandMacroExpr(
703712
case MacroDefinition::Kind::Undefined:
704713
case MacroDefinition::Kind::Invalid:
705714
// Already diagnosed as an error elsewhere.
706-
return nullptr;
715+
return None;
707716

708717
case MacroDefinition::Kind::Builtin: {
709718
switch (macroDef.getBuiltinKind()) {
710719
case BuiltinMacroKind::ExternalMacro:
711720
ctx.Diags.diagnose(
712-
expr->getLoc(), diag::external_macro_outside_macro_definition);
713-
return nullptr;
721+
mee->getLoc(), diag::external_macro_outside_macro_definition);
722+
return None;
714723
}
715724
}
716725

717726
case MacroDefinition::Kind::Expanded: {
718727
// Expand the definition with the given arguments.
719728
auto result = expandMacroDefinition(
720-
macroDef.getExpanded(), macro, expr->getArgs());
729+
macroDef.getExpanded(), macro, mee->getArgs());
721730
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
722731
result, adjustMacroExpansionBufferName(*discriminator));
723732
break;
@@ -732,41 +741,41 @@ Expr *swift::expandMacroExpr(
732741
auto externalDef = evaluateOrDefault(ctx.evaluator, request, None);
733742
if (!externalDef) {
734743
ctx.Diags.diagnose(
735-
expr->getLoc(), diag::external_macro_not_found,
744+
mee->getLoc(), diag::external_macro_not_found,
736745
external.moduleName.str(),
737746
external.macroTypeName.str(),
738747
macro->getName()
739748
);
740749
macro->diagnose(diag::decl_declared_here, macro->getName());
741-
return nullptr;
750+
return None;
742751
}
743752

744753
#if SWIFT_SWIFT_PARSER
745-
PrettyStackTraceExpr debugStack(ctx, "expanding macro", expr);
754+
PrettyStackTraceExpr debugStack(ctx, "expanding macro", mee);
746755

747756
// Builtin macros are handled via ASTGen.
748757
auto astGenSourceFile = sourceFile->exportedSourceFile;
749758
if (!astGenSourceFile)
750-
return nullptr;
759+
return None;
751760

752761
const char *evaluatedSourceAddress;
753762
ptrdiff_t evaluatedSourceLength;
754763
swift_ASTGen_expandFreestandingMacro(
755764
&ctx.Diags, externalDef->opaqueHandle,
756765
static_cast<uint32_t>(externalDef->kind), discriminator->data(),
757766
discriminator->size(), astGenSourceFile,
758-
expr->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
767+
mee->getStartLoc().getOpaquePointerValue(), &evaluatedSourceAddress,
759768
&evaluatedSourceLength);
760769
if (!evaluatedSourceAddress)
761-
return nullptr;
770+
return None;
762771
evaluatedSource = llvm::MemoryBuffer::getMemBufferCopy(
763772
{evaluatedSourceAddress, (size_t)evaluatedSourceLength},
764773
adjustMacroExpansionBufferName(*discriminator));
765774
free((void *)evaluatedSourceAddress);
766775
break;
767776
#else
768777
ctx.Diags.diagnose(expr->getLoc(), diag::macro_unsupported);
769-
return nullptr;
778+
return None;
770779
#endif
771780
}
772781
}
@@ -787,9 +796,9 @@ Expr *swift::expandMacroExpr(
787796
GeneratedSourceInfo sourceInfo{
788797
GeneratedSourceInfo::ExpressionMacroExpansion,
789798
Lexer::getCharSourceRangeFromSourceRange(
790-
sourceMgr, expr->getSourceRange()),
799+
sourceMgr, mee->getSourceRange()),
791800
macroBufferRange,
792-
ASTNode(expr).getOpaqueValue(),
801+
ASTNode(mee).getOpaqueValue(),
793802
dc
794803
};
795804
sourceMgr.setGeneratedSourceInfo(macroBufferID, sourceInfo);
@@ -807,7 +816,7 @@ Expr *swift::expandMacroExpr(
807816
if (topLevelItems.size() != 1) {
808817
ctx.Diags.diagnose(
809818
macroBufferRange.getStart(), diag::expected_macro_expansion_expr);
810-
return nullptr;
819+
return macroBufferID;
811820
}
812821

813822
auto codeItem = topLevelItems.front();
@@ -817,7 +826,7 @@ Expr *swift::expandMacroExpr(
817826
if (!expandedExpr) {
818827
ctx.Diags.diagnose(
819828
macroBufferRange.getStart(), diag::expected_macro_expansion_expr);
820-
return nullptr;
829+
return macroBufferID;
821830
}
822831

823832
// Type-check the expanded expression.
@@ -834,12 +843,15 @@ Expr *swift::expandMacroExpr(
834843
Type realExpandedType = TypeChecker::typeCheckExpression(
835844
expandedExpr, dc, contextualType);
836845
if (!realExpandedType)
837-
return nullptr;
846+
return macroBufferID;
838847

839848
assert((expandedType->isEqual(realExpandedType) ||
840849
realExpandedType->hasError()) &&
841850
"Type checking changed the result type?");
842-
return expandedExpr;
851+
852+
mee->setRewritten(expandedExpr);
853+
854+
return macroBufferID;
843855
}
844856

845857
/// 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=ERRNEOUS_EXPAND %s
274+
// ERRNEOUS_EXPAND: 61:1-61:18 (@__swiftmacro_9MacroUser6assertfMf_.swift) "assert("foobar")"

0 commit comments

Comments
 (0)